Do not execute event of transitional lease
If the continuous execution of an event is called just after the lease creation is called, it can fail with the invalid lease status transition error from CREATING to STARTING. This patch adds a check before the event execution whether the lease status of the event is not transitional but stable and pend the execution to the next time if it is transitional. Change-Id: I033dd814d384131de8e7494d22cd42f1ea67112b Closes-Bug: #1820476
This commit is contained in:
parent
81f3ba9bb3
commit
bf57492926
@ -155,6 +155,10 @@ class ManagerService(service_utils.RPCServer):
|
||||
|
||||
LOG.info("Trying to execute events: %s", events)
|
||||
for event in events:
|
||||
if not status.LeaseStatus.is_stable(event['lease_id']):
|
||||
LOG.info("Skip event %s because the status of the lease %s "
|
||||
"is still transitional", event, event['lease_id'])
|
||||
continue
|
||||
db_api.event_update(event['id'],
|
||||
{'status': status.event.IN_PROGRESS})
|
||||
try:
|
||||
|
@ -168,6 +168,16 @@ class LeaseStatus(BaseStatus):
|
||||
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def is_stable(cls, lease_id):
|
||||
"""Check if the lease status is stable
|
||||
|
||||
:param lease_id: Lease ID
|
||||
:return: True if the status is in (PENDING, ACTIVE, TERMINATED, ERROR)
|
||||
"""
|
||||
lease = db_api.lease_get(lease_id)
|
||||
return (lease['status'] in cls.STABLE)
|
||||
|
||||
@classmethod
|
||||
def lease_status(cls, transition, result_in):
|
||||
"""Decorator for managing a lease status.
|
||||
|
@ -145,6 +145,7 @@ class ServiceTestCase(tests.TestCase):
|
||||
'resource_id': '111',
|
||||
'resource_type': 'virtual:instance',
|
||||
'status': 'FAKE PROGRESS'}],
|
||||
'status': status.LeaseStatus.PENDING,
|
||||
'start_date': datetime.datetime(2013, 12, 20, 13, 00),
|
||||
'end_date': datetime.datetime(2013, 12, 20, 15, 00),
|
||||
'trust_id': 'exxee111qwwwwe'}
|
||||
@ -231,8 +232,12 @@ class ServiceTestCase(tests.TestCase):
|
||||
def test_event_success(self):
|
||||
events = self.patch(self.db_api, 'event_get_all_sorted_by_filters')
|
||||
event_update = self.patch(self.db_api, 'event_update')
|
||||
events.return_value = [{'id': '111-222-333', 'time': self.good_date},
|
||||
{'id': '444-555-666', 'time': self.good_date}]
|
||||
events.return_value = [{'id': '111-222-333',
|
||||
'lease_id': 'lease_id1',
|
||||
'time': self.good_date},
|
||||
{'id': '444-555-666',
|
||||
'lease_id': 'lease_id2',
|
||||
'time': self.good_date}]
|
||||
self.patch(eventlet, 'spawn_n')
|
||||
|
||||
self.manager._event()
|
||||
@ -245,7 +250,9 @@ class ServiceTestCase(tests.TestCase):
|
||||
events = self.patch(self.db_api, 'event_get_all_sorted_by_filters')
|
||||
event_update = self.patch(self.db_api, 'event_update')
|
||||
self.patch(eventlet, 'spawn_n').side_effect = Exception
|
||||
events.return_value = [{'id': '111-222-333', 'time': self.good_date}]
|
||||
events.return_value = [{'id': '111-222-333',
|
||||
'lease_id': self.lease_id,
|
||||
'time': self.good_date}]
|
||||
|
||||
self.manager._event()
|
||||
|
||||
@ -253,6 +260,23 @@ class ServiceTestCase(tests.TestCase):
|
||||
mock.call('111-222-333', {'status': status.event.IN_PROGRESS}),
|
||||
mock.call('111-222-333', {'status': status.event.ERROR})])
|
||||
|
||||
def test_event_pass(self):
|
||||
events = self.patch(self.db_api, 'event_get_all_sorted_by_filters')
|
||||
events.return_value = [{'id': '111-222-333',
|
||||
'lease_id': self.lease_id,
|
||||
'time': self.good_date}]
|
||||
|
||||
self.lease_get = self.patch(self.db_api, 'lease_get')
|
||||
lease = self.lease.copy()
|
||||
lease.update({'status': status.LeaseStatus.CREATING})
|
||||
self.lease_get.return_value = lease
|
||||
|
||||
event_update = self.patch(self.db_api, 'event_update')
|
||||
|
||||
self.manager._event()
|
||||
|
||||
event_update.assert_not_called()
|
||||
|
||||
def test_exec_event_success(self):
|
||||
event = {'id': '111-222-333',
|
||||
'event_type': 'start_lease',
|
||||
|
@ -154,6 +154,21 @@ class LeaseStatusTestCase(tests.TestCase):
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_is_stable(self):
|
||||
lease_id = self.lease_id
|
||||
lease_pending = {'id': lease_id,
|
||||
'status': status.LeaseStatus.PENDING}
|
||||
lease_creating = {'id': lease_id,
|
||||
'status': status.LeaseStatus.CREATING}
|
||||
|
||||
self.patch(self.db_api, 'lease_get').return_value = lease_pending
|
||||
result = self.status.LeaseStatus.is_stable(lease_id)
|
||||
self.assertTrue(result)
|
||||
|
||||
self.patch(self.db_api, 'lease_get').return_value = lease_creating
|
||||
result = self.status.LeaseStatus.is_stable(lease_id)
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_lease_status(self):
|
||||
lease = {
|
||||
'status': status.LeaseStatus.PENDING
|
||||
|
Loading…
Reference in New Issue
Block a user