Fix instance actions testing

Somehow, the instance actions API was different in three places:

1. The actual API from a running system
2. The regular unit tests
3. The api_samples tests

This fixes the fake_instance_actions module to look like the database
model (which was the root of the problem) as well as the api_samples
and regular unit tests to properly confirm the actual behavior I
validated manually against a running system. This looks like it
changes the external API, but in fact, it makes things match what
the external API actually is.

Change-Id: I0c8ddff3e0819a65667617083dfaa74f7317cc05
This commit is contained in:
Dan Smith
2013-08-07 08:08:38 -07:00
parent bcd5e9cd58
commit 68288b9cd2
7 changed files with 66 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<instanceAction instance_uuid="b48316c5-71e8-45e4-9884-6c78055b9b13" user_id="789" start_time="2012-12-05 00:00:00.000000" request_id="req-3293a3f1-b44c-4609-b8d2-d81b105636b8" action="reboot" message="" project_id="147"> <instanceAction instance_uuid="b48316c5-71e8-45e4-9884-6c78055b9b13" user_id="789" start_time="2012-12-05T00:00:00.000000" request_id="req-3293a3f1-b44c-4609-b8d2-d81b105636b8" action="reboot" message="" project_id="147">
<events finish_time="2012-12-05 01:02:00.000000" start_time="2012-12-05 01:00:02.000000" traceback="" event="schedule" result="Success"/> <events finish_time="2012-12-05 01:02:00.000000" start_time="2012-12-05 01:00:02.000000" traceback="" event="schedule" result="Success"/>
<events finish_time="2012-12-05 01:04:00.000000" start_time="2012-12-05 01:03:00.000000" traceback="" event="compute_create" result="Success"/> <events finish_time="2012-12-05 01:04:00.000000" start_time="2012-12-05 01:03:00.000000" traceback="" event="compute_create" result="Success"/>
</instanceAction> </instanceAction>

View File

@@ -40,6 +40,11 @@ def format_action(action):
del(action['id']) del(action['id'])
if 'finish_time' in action: if 'finish_time' in action:
del(action['finish_time']) del(action['finish_time'])
if 'start_time' in action:
# NOTE(danms): Without WSGI above us, these will be just stringified
action['start_time'] = str(action['start_time'])
for event in action.get('events', []):
format_event(event)
return action return action
@@ -47,6 +52,12 @@ def format_event(event):
'''Remove keys that aren't serialized.''' '''Remove keys that aren't serialized.'''
if 'id' in event: if 'id' in event:
del(event['id']) del(event['id'])
if 'start_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified
event['start_time'] = str(event['start_time'])
if 'finish_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified
event['finish_time'] = str(event['finish_time'])
return event return event
@@ -121,8 +132,7 @@ class InstanceActionsTest(test.TestCase):
res_dict = self.controller.index(req, FAKE_UUID) res_dict = self.controller.index(req, FAKE_UUID)
for res in res_dict['instanceActions']: for res in res_dict['instanceActions']:
fake_action = self.fake_actions[FAKE_UUID][res['request_id']] fake_action = self.fake_actions[FAKE_UUID][res['request_id']]
fake_action = format_action(fake_action) self.assertEqual(format_action(fake_action), format_action(res))
self.assertEqual(fake_action, res)
def test_get_action_with_events_allowed(self): def test_get_action_with_events_allowed(self):
def fake_get_action(context, uuid, request_id): def fake_get_action(context, uuid, request_id):
@@ -149,7 +159,8 @@ class InstanceActionsTest(test.TestCase):
fake_events = [format_event(event) for event in fake_events] fake_events = [format_event(event) for event in fake_events]
fake_action = format_action(fake_action) fake_action = format_action(fake_action)
fake_action['events'] = fake_events fake_action['events'] = fake_events
self.assertEqual(fake_action, res_dict['instanceAction']) self.assertEqual(format_action(fake_action),
format_action(res_dict['instanceAction']))
def test_get_action_with_events_not_allowed(self): def test_get_action_with_events_not_allowed(self):
def fake_get_action(context, uuid, request_id): def fake_get_action(context, uuid, request_id):
@@ -170,8 +181,8 @@ class InstanceActionsTest(test.TestCase):
'/v2/123/servers/12/os-instance-actions/1') '/v2/123/servers/12/os-instance-actions/1')
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID) res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID] fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
fake_action = format_action(fake_action) self.assertEqual(format_action(fake_action),
self.assertEqual(fake_action, res_dict['instanceAction']) format_action(res_dict['instanceAction']))
def test_action_not_found(self): def test_action_not_found(self):
def fake_no_action(context, uuid, action_id): def fake_no_action(context, uuid, action_id):

View File

@@ -40,6 +40,11 @@ def format_action(action):
del(action['id']) del(action['id'])
if 'finish_time' in action: if 'finish_time' in action:
del(action['finish_time']) del(action['finish_time'])
if 'start_time' in action:
# NOTE(danms): Without WSGI above us, these will be just stringified
action['start_time'] = str(action['start_time'])
for event in action.get('events', []):
format_event(event)
return action return action
@@ -47,6 +52,12 @@ def format_event(event):
'''Remove keys that aren't serialized.''' '''Remove keys that aren't serialized.'''
if 'id' in event: if 'id' in event:
del(event['id']) del(event['id'])
if 'start_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified
event['start_time'] = str(event['start_time'])
if 'finish_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified
event['finish_time'] = str(event['finish_time'])
return event return event
@@ -124,8 +135,8 @@ class InstanceActionsTest(test.TestCase):
res_dict = self.controller.index(req, FAKE_UUID) res_dict = self.controller.index(req, FAKE_UUID)
for res in res_dict['instance_actions']: for res in res_dict['instance_actions']:
fake_action = self.fake_actions[FAKE_UUID][res['request_id']] fake_action = self.fake_actions[FAKE_UUID][res['request_id']]
fake_action = format_action(fake_action) self.assertEqual(format_action(fake_action),
self.assertEqual(fake_action, res) format_action(res))
def test_get_action_with_events_allowed(self): def test_get_action_with_events_allowed(self):
def fake_get_action(context, uuid, request_id): def fake_get_action(context, uuid, request_id):
@@ -150,9 +161,9 @@ class InstanceActionsTest(test.TestCase):
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID] fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
fake_events = self.fake_events[fake_action['id']] fake_events = self.fake_events[fake_action['id']]
fake_events = [format_event(event) for event in fake_events] fake_events = [format_event(event) for event in fake_events]
fake_action = format_action(fake_action)
fake_action['events'] = fake_events fake_action['events'] = fake_events
self.assertEqual(fake_action, res_dict['instance_action']) self.assertEqual(format_action(fake_action),
format_action(res_dict['instance_action']))
def test_get_action_with_events_not_allowed(self): def test_get_action_with_events_not_allowed(self):
def fake_get_action(context, uuid, request_id): def fake_get_action(context, uuid, request_id):
@@ -174,8 +185,8 @@ class InstanceActionsTest(test.TestCase):
'/servers/12/os-instance-actions/1') '/servers/12/os-instance-actions/1')
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID) res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID] fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
fake_action = format_action(fake_action) self.assertEqual(format_action(fake_action),
self.assertEqual(fake_action, res_dict['instance_action']) format_action(res_dict['instance_action']))
def test_action_not_found(self): def test_action_not_found(self):
def fake_no_action(context, uuid, action_id): def fake_no_action(context, uuid, action_id):

View File

@@ -25,6 +25,7 @@ from nova import db
from nova import exception from nova import exception
from nova.objects import base as objects_base from nova.objects import base as objects_base
from nova.objects import instance as instance_obj from nova.objects import instance as instance_obj
from nova.openstack.common import jsonutils
from nova.openstack.common import rpc from nova.openstack.common import rpc
from nova.openstack.common import timeutils from nova.openstack.common import timeutils
from nova.openstack.common import uuidutils from nova.openstack.common import uuidutils
@@ -992,7 +993,7 @@ class CellsTargetedMethodsTestCase(test.TestCase):
self.tgt_cell_name, self.tgt_cell_name,
'fake-uuid') 'fake-uuid')
result = response.value_or_raise() result = response.value_or_raise()
self.assertEqual([fake_act], result) self.assertEqual([jsonutils.to_primitive(fake_act)], result)
def test_action_get_by_request_id(self): def test_action_get_by_request_id(self):
fake_uuid = fake_instance_actions.FAKE_UUID fake_uuid = fake_instance_actions.FAKE_UUID
@@ -1007,7 +1008,7 @@ class CellsTargetedMethodsTestCase(test.TestCase):
response = self.src_msg_runner.action_get_by_request_id(self.ctxt, response = self.src_msg_runner.action_get_by_request_id(self.ctxt,
self.tgt_cell_name, 'fake-uuid', 'req-fake') self.tgt_cell_name, 'fake-uuid', 'req-fake')
result = response.value_or_raise() result = response.value_or_raise()
self.assertEqual(fake_act, result) self.assertEqual(jsonutils.to_primitive(fake_act), result)
def test_action_events_get(self): def test_action_events_get(self):
fake_action_id = fake_instance_actions.FAKE_ACTION_ID1 fake_action_id = fake_instance_actions.FAKE_ACTION_ID1
@@ -1022,7 +1023,7 @@ class CellsTargetedMethodsTestCase(test.TestCase):
self.tgt_cell_name, self.tgt_cell_name,
'fake-action') 'fake-action')
result = response.value_or_raise() result = response.value_or_raise()
self.assertEqual(fake_events, result) self.assertEqual(jsonutils.to_primitive(fake_events), result)
def test_validate_console_port(self): def test_validate_console_port(self):
instance_uuid = 'fake_instance_uuid' instance_uuid = 'fake_instance_uuid'

View File

@@ -14,14 +14,16 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import datetime
from nova import db from nova import db
FAKE_UUID = 'b48316c5-71e8-45e4-9884-6c78055b9b13' FAKE_UUID = 'b48316c5-71e8-45e4-9884-6c78055b9b13'
FAKE_REQUEST_ID1 = 'req-3293a3f1-b44c-4609-b8d2-d81b105636b8' FAKE_REQUEST_ID1 = 'req-3293a3f1-b44c-4609-b8d2-d81b105636b8'
FAKE_REQUEST_ID2 = 'req-25517360-b757-47d3-be45-0e8d2a01b36a' FAKE_REQUEST_ID2 = 'req-25517360-b757-47d3-be45-0e8d2a01b36a'
FAKE_ACTION_ID1 = 'f811a359-0c98-4daa-87a4-2948d4c21b78' FAKE_ACTION_ID1 = 123
FAKE_ACTION_ID2 = '4e9594b5-4ac5-421c-ac60-2d802b11c798' FAKE_ACTION_ID2 = 456
FAKE_ACTIONS = { FAKE_ACTIONS = {
FAKE_UUID: { FAKE_UUID: {
@@ -31,8 +33,9 @@ FAKE_ACTIONS = {
'request_id': FAKE_REQUEST_ID1, 'request_id': FAKE_REQUEST_ID1,
'project_id': '147', 'project_id': '147',
'user_id': '789', 'user_id': '789',
'start_time': '2012-12-05 00:00:00.000000', 'start_time': datetime.datetime(
'finish_time': '', 2012, 12, 5, 0, 0, 0, 0),
'finish_time': None,
'message': '', 'message': '',
}, },
FAKE_REQUEST_ID2: {'id': FAKE_ACTION_ID2, FAKE_REQUEST_ID2: {'id': FAKE_ACTION_ID2,
@@ -41,33 +44,40 @@ FAKE_ACTIONS = {
'request_id': FAKE_REQUEST_ID2, 'request_id': FAKE_REQUEST_ID2,
'user_id': '789', 'user_id': '789',
'project_id': '842', 'project_id': '842',
'start_time': '2012-12-05 01:00:00.000000', 'start_time': datetime.datetime(
'finish_time': '', 2012, 12, 5, 1, 0, 0, 0),
'finish_time': None,
'message': '', 'message': '',
} }
} }
} }
FAKE_EVENTS = { FAKE_EVENTS = {
FAKE_ACTION_ID1: [{'id': '1', FAKE_ACTION_ID1: [{'id': 1,
'event': 'schedule', 'event': 'schedule',
'start_time': '2012-12-05 01:00:02.000000', 'start_time': datetime.datetime(
'finish_time': '2012-12-05 01:02:00.000000', 2012, 12, 5, 1, 0, 2, 0),
'finish_time': datetime.datetime(
2012, 12, 5, 1, 2, 0, 0),
'result': 'Success', 'result': 'Success',
'traceback': '', 'traceback': '',
}, },
{'id': '2', {'id': 2,
'event': 'compute_create', 'event': 'compute_create',
'start_time': '2012-12-05 01:03:00.000000', 'start_time': datetime.datetime(
'finish_time': '2012-12-05 01:04:00.000000', 2012, 12, 5, 1, 3, 0, 0),
'finish_time': datetime.datetime(
2012, 12, 5, 1, 4, 0, 0),
'result': 'Success', 'result': 'Success',
'traceback': '', 'traceback': '',
} }
], ],
FAKE_ACTION_ID2: [{'id': '3', FAKE_ACTION_ID2: [{'id': 3,
'event': 'schedule', 'event': 'schedule',
'start_time': '2012-12-05 03:00:00.000000', 'start_time': datetime.datetime(
'finish_time': '2012-12-05 03:02:00.000000', 2012, 12, 5, 3, 0, 0, 0),
'finish_time': datetime.datetime(
2012, 12, 5, 3, 2, 0, 0),
'result': 'Error', 'result': 'Error',
'traceback': '' 'traceback': ''
} }

View File

@@ -5,7 +5,7 @@
"request_id": "%(request_id)s", "request_id": "%(request_id)s",
"user_id": "%(integer_id)s", "user_id": "%(integer_id)s",
"project_id": "%(integer_id)s", "project_id": "%(integer_id)s",
"start_time": "%(start_time)s", "start_time": "%(timestamp)s",
"message": "", "message": "",
"events": [ "events": [
{ {

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<instanceAction action="%(action)s" instance_uuid="%(instance_uuid)s" request_id="%(request_id)s" user_id="%(integer_id)s" project_id="%(integer_id)s" start_time="%(start_time)s" message=""> <instanceAction action="%(action)s" instance_uuid="%(instance_uuid)s" request_id="%(request_id)s" user_id="%(integer_id)s" project_id="%(integer_id)s" start_time="%(timestamp)s" message="">
<events event="%(event)s" start_time="%(timestamp)s" finish_time="%(timestamp)s" result="%(result)s" traceback=""/> <events event="%(event)s" start_time="%(timestamp)s" finish_time="%(timestamp)s" result="%(result)s" traceback=""/>
<events event="%(event)s" start_time="%(timestamp)s" finish_time="%(timestamp)s" result="%(result)s" traceback=""/> <events event="%(event)s" start_time="%(timestamp)s" finish_time="%(timestamp)s" result="%(result)s" traceback=""/>
</instanceAction> </instanceAction>