fix unshelve notification test instability

The unshelve notification sample test shelve-offloads an instance, waits for
it state to change to SHELVED_OFFLOADED then unshelve the instance and matches
generated the unshelve notification with the stored sample. This test
intermittently fails as the host paramter of the instance doesn't match
sometimes. The reason is that the compute manager during shelve offloading
first sets the state of the instance then later sets the host of the instance.
So the test can start unshelving the instance before the host is cleaned by
the shelve offload code.

The test is updated to not just wait for the state change but also wait for
the change of the host attribute.

Change-Id: I459332de407187724fd2962effb7f3a34751f505
Closes-Bug: #1704423
This commit is contained in:
Balazs Gibizer 2017-07-14 18:18:33 +02:00
parent 57360fb72a
commit da57d17e6c
2 changed files with 25 additions and 9 deletions

View File

@ -218,22 +218,28 @@ class _IntegratedTestBase(test.TestCase):
class InstanceHelperMixin(object):
def _wait_for_state_change(self, admin_api, server, expected_status,
max_retries=10):
def _wait_for_server_parameter(self, admin_api, server, expected_params,
max_retries=10):
retry_count = 0
while True:
server = admin_api.get_server(server['id'])
if server['status'] == expected_status:
if all([server[attr] == expected_params[attr]
for attr in expected_params]):
break
retry_count += 1
if retry_count == max_retries:
self.fail('Wait for state change failed, '
'expected_status=%s, actual_status=%s'
% (expected_status, server['status']))
'expected_params=%s, server=%s'
% (expected_params, server))
time.sleep(0.5)
return server
def _wait_for_state_change(self, admin_api, server, expected_status,
max_retries=10):
return self._wait_for_server_parameter(
admin_api, server, {'status': expected_status}, max_retries)
def _build_minimal_create_server_request(self, api, name, image_uuid=None,
flavor_id=None, networks=None):
server = {}

View File

@ -456,8 +456,13 @@ class TestInstanceNotificationSample(
self._wait_for_state_change(self.api, server,
expected_status='SHELVED')
self.api.post_server_action(server['id'], {'shelveOffload': {}})
self._wait_for_state_change(self.api, server,
expected_status='SHELVED_OFFLOADED')
# we need to wait for the instance.host to become None as well before
# we can unshelve to make sure that the unshelve.start notification
# payload is stable as the compute manager first sets the instance
# state then a bit later sets the instance.host to None.
self._wait_for_server_parameter(self.api, server,
{'status': 'SHELVED_OFFLOADED',
'OS-EXT-SRV-ATTR:host': None})
self.assertEqual(4, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self._verify_notification(
@ -493,8 +498,13 @@ class TestInstanceNotificationSample(
# instance status to 'SHELVED_OFFLOADED'
self.flags(shelved_offload_time = 0)
self.api.post_server_action(server['id'], {'shelve': {}})
self._wait_for_state_change(self.api, server,
expected_status='SHELVED_OFFLOADED')
# we need to wait for the instance.host to become None as well before
# we can unshelve to make sure that the unshelve.start notification
# payload is stable as the compute manager first sets the instance
# state then a bit later sets the instance.host to None.
self._wait_for_server_parameter(self.api, server,
{'status': 'SHELVED_OFFLOADED',
'OS-EXT-SRV-ATTR:host': None})
post = {'unshelve': None}
self.api.post_server_action(server['id'], post)