1480
1459
response.content)
1483
class TestGetDetails(APITestCase):
1484
"""Tests for /api/2.0/machines/<machine>/?op=details."""
1486
def make_lshw_result(self, machine, script_result=0):
1487
return factory.make_NodeResult_for_commissioning(
1488
node=machine, name=LSHW_OUTPUT_NAME,
1489
script_result=script_result)
1491
def make_lldp_result(self, machine, script_result=0):
1492
return factory.make_NodeResult_for_commissioning(
1493
node=machine, name=LLDP_OUTPUT_NAME, script_result=script_result)
1495
def get_details(self, machine):
1496
url = reverse('machine_handler', args=[machine.system_id])
1497
response = self.client.get(url, {'op': 'details'})
1498
self.assertEqual(http.client.OK, response.status_code)
1499
self.assertEqual('application/bson', response['content-type'])
1500
return bson.BSON(response.content).decode()
1502
def test_GET_returns_empty_details_when_there_are_none(self):
1503
machine = factory.make_Node()
1504
self.assertDictEqual(
1505
{"lshw": None, "lldp": None},
1506
self.get_details(machine))
1508
def test_GET_returns_all_details(self):
1509
machine = factory.make_Node()
1510
lshw_result = self.make_lshw_result(machine)
1511
lldp_result = self.make_lldp_result(machine)
1512
self.assertDictEqual(
1513
{"lshw": lshw_result.data,
1514
"lldp": lldp_result.data},
1515
self.get_details(machine))
1517
def test_GET_returns_only_those_details_that_exist(self):
1518
machine = factory.make_Node()
1519
lshw_result = self.make_lshw_result(machine)
1520
self.assertDictEqual(
1521
{"lshw": lshw_result.data,
1523
self.get_details(machine))
1525
def test_GET_returns_not_found_when_machine_does_not_exist(self):
1526
url = reverse('machine_handler', args=['does-not-exist'])
1527
response = self.client.get(url, {'op': 'details'})
1528
self.assertEqual(http.client.NOT_FOUND, response.status_code)
1531
class TestMarkBroken(APITestCase):
1532
"""Tests for /api/2.0/machines/<machine>/?op=mark_broken"""
1534
def get_machine_uri(self, machine):
1535
"""Get the API URI for `machine`."""
1536
return reverse('machine_handler', args=[machine.system_id])
1538
def test_mark_broken_changes_status(self):
1539
machine = factory.make_Node(
1540
status=NODE_STATUS.COMMISSIONING, owner=self.logged_in_user)
1541
response = self.client.post(
1542
self.get_machine_uri(machine), {'op': 'mark_broken'})
1543
self.assertEqual(http.client.OK, response.status_code)
1544
self.assertEqual(NODE_STATUS.BROKEN, reload_object(machine).status)
1546
def test_mark_broken_updates_error_description(self):
1547
# 'error_description' parameter was renamed 'comment' for consistency
1548
# make sure this comment updates the machine's error_description
1549
machine = factory.make_Node(
1550
status=NODE_STATUS.COMMISSIONING, owner=self.logged_in_user)
1551
comment = factory.make_name('comment')
1552
response = self.client.post(
1553
self.get_machine_uri(machine),
1554
{'op': 'mark_broken', 'comment': comment})
1555
self.assertEqual(http.client.OK, response.status_code)
1556
machine = reload_object(machine)
1558
(NODE_STATUS.BROKEN, comment),
1559
(machine.status, machine.error_description)
1562
def test_mark_broken_updates_error_description_compatibility(self):
1563
# test old 'error_description' parameter is honored for compatibility
1564
machine = factory.make_Node(
1565
status=NODE_STATUS.COMMISSIONING, owner=self.logged_in_user)
1566
error_description = factory.make_name('error_description')
1567
response = self.client.post(
1568
self.get_machine_uri(machine),
1569
{'op': 'mark_broken', 'error_description': error_description})
1570
self.assertEqual(http.client.OK, response.status_code)
1571
machine = reload_object(machine)
1573
(NODE_STATUS.BROKEN, error_description),
1574
(machine.status, machine.error_description)
1577
def test_mark_broken_passes_comment(self):
1578
machine = factory.make_Node(
1579
status=NODE_STATUS.COMMISSIONING, owner=self.logged_in_user)
1580
machine_mark_broken = self.patch(node_module.Machine, 'mark_broken')
1581
comment = factory.make_name('comment')
1583
self.get_machine_uri(machine),
1584
{'op': 'mark_broken', 'comment': comment})
1586
machine_mark_broken,
1587
MockCalledOnceWith(self.logged_in_user, comment))
1589
def test_mark_broken_handles_missing_comment(self):
1590
machine = factory.make_Node(
1591
status=NODE_STATUS.COMMISSIONING, owner=self.logged_in_user)
1592
machine_mark_broken = self.patch(node_module.Machine, 'mark_broken')
1594
self.get_machine_uri(machine), {'op': 'mark_broken'})
1596
machine_mark_broken,
1597
MockCalledOnceWith(self.logged_in_user, None))
1599
def test_mark_broken_requires_ownership(self):
1600
machine = factory.make_Node(status=NODE_STATUS.COMMISSIONING)
1601
response = self.client.post(
1602
self.get_machine_uri(machine), {'op': 'mark_broken'})
1603
self.assertEqual(http.client.FORBIDDEN, response.status_code)
1605
def test_mark_broken_allowed_from_any_other_state(self):
1606
self.patch(node_module.Node, "_stop")
1607
for status, _ in NODE_STATUS_CHOICES:
1608
if status == NODE_STATUS.BROKEN:
1611
machine = factory.make_Node(
1612
status=status, owner=self.logged_in_user)
1613
response = self.client.post(
1614
self.get_machine_uri(machine), {'op': 'mark_broken'})
1616
response.status_code, Equals(http.client.OK), response)
1617
machine = reload_object(machine)
1618
self.expectThat(machine.status, Equals(NODE_STATUS.BROKEN))
1621
class TestMarkFixed(APITestCase):
1622
"""Tests for /api/2.0/machines/<machine>/?op=mark_fixed"""
1624
def get_machine_uri(self, machine):
1625
"""Get the API URI for `machine`."""
1626
return reverse('machine_handler', args=[machine.system_id])
1628
def test_mark_fixed_changes_status(self):
1630
machine = factory.make_Node(status=NODE_STATUS.BROKEN)
1631
response = self.client.post(
1632
self.get_machine_uri(machine), {'op': 'mark_fixed'})
1633
self.assertEqual(http.client.OK, response.status_code)
1634
self.assertEqual(NODE_STATUS.READY, reload_object(machine).status)
1636
def test_mark_fixed_requires_admin(self):
1637
machine = factory.make_Node(status=NODE_STATUS.BROKEN)
1638
response = self.client.post(
1639
self.get_machine_uri(machine), {'op': 'mark_fixed'})
1640
self.assertEqual(http.client.FORBIDDEN, response.status_code)
1642
def test_mark_fixed_passes_comment(self):
1644
machine = factory.make_Node(status=NODE_STATUS.BROKEN)
1645
machine_mark_fixed = self.patch(node_module.Machine, 'mark_fixed')
1646
comment = factory.make_name('comment')
1648
self.get_machine_uri(machine),
1649
{'op': 'mark_fixed', 'comment': comment})
1652
MockCalledOnceWith(self.logged_in_user, comment))
1654
def test_mark_fixed_handles_missing_comment(self):
1656
machine = factory.make_Node(status=NODE_STATUS.BROKEN)
1657
machine_mark_fixed = self.patch(node_module.Machine, 'mark_fixed')
1659
self.get_machine_uri(machine), {'op': 'mark_fixed'})
1662
MockCalledOnceWith(self.logged_in_user, None))
1665
1462
class TestPowerParameters(APITestCase):
1666
1463
def get_machine_uri(self, machine):
1667
1464
"""Get the API URI for `machine`."""