Fix 500 in test_resize_server_negative_invalid_state

In some case(such as, delete a confirmResize server), the
actions maybe have same instance_uuid and request_id. When
we record the event we should get the last created action,
otherwise, we would find the wrong action, and we can't find
the specific event using this wrong action id. Finally, raise
a 500 error due to the error of InstanceActionEventNotFound.

So, if more than one actions with same instance uuid and request
id are exists. we should choice the last created action id as
event record action id.

This change fixes this by sorting action by desc(created_at, id)
and get back the last created action.

Change-Id: Ie6efee14d4b4d25a73dc23f0649a56bfa724c492
Closes-Bug: #1741220
This commit is contained in:
Yikun Jiang 2018-01-04 17:50:54 +08:00 committed by Yikun Jiang (Kero)
parent d377fe700a
commit b933847cbb
2 changed files with 32 additions and 2 deletions

View File

@ -5805,6 +5805,7 @@ def _action_get_by_request_id(context, instance_uuid, request_id):
result = model_query(context, models.InstanceAction).\
filter_by(instance_uuid=instance_uuid).\
filter_by(request_id=request_id).\
order_by(desc("created_at"), desc("id")).\
first()
return result

View File

@ -3851,11 +3851,12 @@ class InstanceActionTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.ctxt = context.get_admin_context()
def _create_action_values(self, uuid, action='run_instance',
ctxt=None, extra=None):
ctxt=None, extra=None, instance_create=True):
if ctxt is None:
ctxt = self.ctxt
db.instance_create(ctxt, {'uuid': uuid})
if instance_create:
db.instance_create(ctxt, {'uuid': uuid})
utc_now = timeutils.utcnow()
values = {
@ -4060,6 +4061,34 @@ class InstanceActionTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.assertEqual('run_instance', action['action'])
self.assertEqual(self.ctxt.request_id, action['request_id'])
def test_instance_action_get_by_instance_and_action_by_order(self):
instance_uuid = uuidsentinel.uuid1
t1 = {
'created_at': timeutils.utcnow()
}
t2 = {
'created_at': timeutils.utcnow() + datetime.timedelta(seconds=5)
}
# Create a confirmResize action
action_values = self._create_action_values(
instance_uuid, action='confirmResize', extra=t1)
a1 = db.action_start(self.ctxt, action_values)
# Create a delete action with same instance uuid and req id
action_values = self._create_action_values(
instance_uuid, action='delete', extra=t2, instance_create=False)
a2 = db.action_start(self.ctxt, action_values)
self.assertEqual(a1['request_id'], a2['request_id'])
self.assertEqual(a1['instance_uuid'], a2['instance_uuid'])
self.assertTrue(a1['created_at'] < a2['created_at'])
action = db.action_get_by_request_id(self.ctxt, instance_uuid,
a1['request_id'])
# Only get the delete action(last created)
self.assertEqual(action['action'], a2['action'])
def test_instance_action_event_start(self):
"""Create an instance action event."""
uuid = uuidsentinel.uuid1