Merge "Add provision_updated_at to node's resource"
This commit is contained in:
commit
76e6305386
|
@ -52,7 +52,8 @@ class NodePatchType(types.JsonPatchType):
|
|||
defaults = types.JsonPatchType.internal_attrs()
|
||||
return defaults + ['/console_enabled', '/last_error',
|
||||
'/power_state', '/provision_state', '/reservation',
|
||||
'/target_power_state', '/target_provision_state']
|
||||
'/target_power_state', '/target_provision_state',
|
||||
'/provision_updated_at']
|
||||
|
||||
@staticmethod
|
||||
def mandatory_attrs():
|
||||
|
@ -95,6 +96,8 @@ class NodeStates(base.APIBase):
|
|||
|
||||
provision_state = wtypes.text
|
||||
|
||||
provision_updated_at = datetime.datetime
|
||||
|
||||
target_power_state = wtypes.text
|
||||
|
||||
target_provision_state = wtypes.text
|
||||
|
@ -105,7 +108,7 @@ class NodeStates(base.APIBase):
|
|||
def convert(cls, rpc_node):
|
||||
attr_list = ['console_enabled', 'last_error', 'power_state',
|
||||
'provision_state', 'target_power_state',
|
||||
'target_provision_state']
|
||||
'target_provision_state', 'provision_updated_at']
|
||||
states = NodeStates()
|
||||
for attr in attr_list:
|
||||
setattr(states, attr, getattr(rpc_node, attr))
|
||||
|
@ -274,6 +277,9 @@ class Node(base.APIBase):
|
|||
reservation = wsme.wsattr(wtypes.text, readonly=True)
|
||||
"The hostname of the conductor that holds an exclusive lock on the node."
|
||||
|
||||
provision_updated_at = datetime.datetime
|
||||
"The UTC date and time of the last provision state change"
|
||||
|
||||
maintenance = types.boolean
|
||||
"Indicates whether the node is in maintenance mode."
|
||||
|
||||
|
@ -362,7 +368,8 @@ class Node(base.APIBase):
|
|||
target_provision_state=ir_states.NOSTATE,
|
||||
reservation=None, driver='fake', driver_info={}, extra={},
|
||||
properties={'memory_mb': '1024', 'local_gb': '10',
|
||||
'cpus': '1'}, updated_at=time, created_at=time)
|
||||
'cpus': '1'}, updated_at=time, created_at=time,
|
||||
provision_updated_at=time)
|
||||
# NOTE(matty_dubs): The chassis_uuid getter() is based on the
|
||||
# _chassis_uuid variable:
|
||||
sample._chassis_uuid = 'edcad704-b2da-41d5-96d9-afd580ecfa12'
|
||||
|
|
|
@ -91,6 +91,9 @@ class TestListNodes(base.FunctionalTest):
|
|||
self.assertNotIn('reservation', data['nodes'][0])
|
||||
self.assertNotIn('maintenance', data['nodes'][0])
|
||||
self.assertNotIn('console_enabled', data['nodes'][0])
|
||||
self.assertNotIn('target_power_state', data['nodes'][0])
|
||||
self.assertNotIn('target_provision_state', data['nodes'][0])
|
||||
self.assertNotIn('provision_updated_at', data['nodes'][0])
|
||||
# never expose the chassis_id
|
||||
self.assertNotIn('chassis_id', data['nodes'][0])
|
||||
|
||||
|
@ -106,6 +109,10 @@ class TestListNodes(base.FunctionalTest):
|
|||
self.assertIn('chassis_uuid', data['nodes'][0])
|
||||
self.assertIn('reservation', data['nodes'][0])
|
||||
self.assertIn('maintenance', data['nodes'][0])
|
||||
self.assertIn('console_enabled', data['nodes'][0])
|
||||
self.assertIn('target_power_state', data['nodes'][0])
|
||||
self.assertIn('target_provision_state', data['nodes'][0])
|
||||
self.assertIn('provision_updated_at', data['nodes'][0])
|
||||
# never expose the chassis_id
|
||||
self.assertNotIn('chassis_id', data['nodes'][0])
|
||||
|
||||
|
@ -208,13 +215,17 @@ class TestListNodes(base.FunctionalTest):
|
|||
expect_errors=True)
|
||||
self.assertEqual(404, response.status_int)
|
||||
|
||||
def test_node_states(self):
|
||||
@mock.patch.object(timeutils, 'utcnow')
|
||||
def test_node_states(self, mock_utcnow):
|
||||
fake_state = 'fake-state'
|
||||
fake_error = 'fake-error'
|
||||
test_time = datetime.datetime(2000, 1, 1, 0, 0)
|
||||
mock_utcnow.return_value = test_time
|
||||
ndict = dbutils.get_test_node(power_state=fake_state,
|
||||
target_power_state=fake_state,
|
||||
provision_state=fake_state,
|
||||
target_provision_state=fake_state,
|
||||
provision_updated_at=test_time,
|
||||
last_error=fake_error)
|
||||
self.dbapi.create_node(ndict)
|
||||
data = self.get_json('/nodes/%s/states' % ndict['uuid'])
|
||||
|
@ -222,6 +233,9 @@ class TestListNodes(base.FunctionalTest):
|
|||
self.assertEqual(fake_state, data['target_power_state'])
|
||||
self.assertEqual(fake_state, data['provision_state'])
|
||||
self.assertEqual(fake_state, data['target_provision_state'])
|
||||
prov_up_at = timeutils.parse_isotime(
|
||||
data['provision_updated_at']).replace(tzinfo=None)
|
||||
self.assertEqual(test_time, prov_up_at)
|
||||
self.assertEqual(fake_error, data['last_error'])
|
||||
self.assertFalse(data['console_enabled'])
|
||||
|
||||
|
@ -606,6 +620,16 @@ class TestPatch(base.FunctionalTest):
|
|||
self.assertEqual(400, response.status_code)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
|
||||
def test_replace_provision_updated_at(self):
|
||||
test_time = '2000-01-01 00:00:00'
|
||||
response = self.patch_json('/nodes/%s' % self.node['uuid'],
|
||||
[{'path': '/provision_updated_at',
|
||||
'op': 'replace', 'value': test_time}],
|
||||
expect_errors=True)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(400, response.status_code)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
|
||||
|
||||
class TestPost(base.FunctionalTest):
|
||||
|
||||
|
|
Loading…
Reference in New Issue