From 63626a7bb9ffc84fabda224ec7f5b6fede2b4b64 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Mon, 25 Sep 2017 17:53:57 +0200 Subject: [PATCH] cover migration cases with functional tests As we found multiple bugs in the server moving cases this patch adds test to cover the migrate confirm and migrate revert cases as well. It seems that these two cases work as expected. Change-Id: I40a244601e1612a87bd41cd6ad652202035a1ce4 --- nova/tests/functional/test_servers.py | 191 +++++++++++++++++++------- 1 file changed, 140 insertions(+), 51 deletions(-) diff --git a/nova/tests/functional/test_servers.py b/nova/tests/functional/test_servers.py index d49fbaf201..5a857f363e 100644 --- a/nova/tests/functional/test_servers.py +++ b/nova/tests/functional/test_servers.py @@ -1773,6 +1773,48 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): self.compute2.manager.update_available_resource(ctx) LOG.info('Finished with periodics') + def _migrate_and_check_allocations(self, server, flavor, source_rp_uuid, + dest_rp_uuid): + request = { + 'migrate': None + } + self._move_and_check_allocations( + server, request=request, old_flavor=flavor, new_flavor=flavor, + source_rp_uuid=source_rp_uuid, dest_rp_uuid=dest_rp_uuid) + + def _move_and_check_allocations(self, server, request, old_flavor, + new_flavor, source_rp_uuid, dest_rp_uuid): + self.api.post_server_action(server['id'], request) + self._wait_for_state_change(self.api, server, 'VERIFY_RESIZE') + + def _check_allocation(): + source_usages = self._get_provider_usages(source_rp_uuid) + self.assertFlavorMatchesAllocation(old_flavor, source_usages) + dest_usages = self._get_provider_usages(dest_rp_uuid) + self.assertFlavorMatchesAllocation(new_flavor, dest_usages) + + # The instance should own the new_flavor allocation against the + # destination host created by the scheduler + allocations = self._get_allocations_by_server_uuid(server['id']) + self.assertEqual(1, len(allocations)) + dest_alloc = allocations[dest_rp_uuid]['resources'] + self.assertFlavorMatchesAllocation(new_flavor, dest_alloc) + + # The migration should own the old_flavor allocation against the + # source host created by conductor + migration_uuid = self.get_migration_uuid_for_instance(server['id']) + allocations = self._get_allocations_by_server_uuid(migration_uuid) + source_alloc = allocations[source_rp_uuid]['resources'] + self.assertFlavorMatchesAllocation(old_flavor, source_alloc) + + # OK, so the move operation has run, but we have not yet confirmed or + # reverted the move operation. Before we run periodics, make sure + # that we have allocations/usages on BOTH the source and the + # destination hosts. + _check_allocation() + self._run_periodics() + _check_allocation() + def test_resize_revert(self): self._test_resize_revert(dest_hostname='host1') @@ -1787,63 +1829,16 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): def _resize_and_check_allocations(self, server, old_flavor, new_flavor, source_rp_uuid, dest_rp_uuid): - # Resize the server and check usages in VERIFY_RESIZE state self.flags(allow_resize_to_same_host=False) resize_req = { 'resize': { 'flavorRef': new_flavor['id'] } } - self.api.post_server_action(server['id'], resize_req) - self._wait_for_state_change(self.api, server, 'VERIFY_RESIZE') - - # OK, so the resize operation has run, but we have not yet confirmed or - # reverted the resize operation. Before we run periodics, make sure - # that we have allocations/usages on BOTH the source and the - # destination hosts. - source_usages = self._get_provider_usages(source_rp_uuid) - self.assertFlavorMatchesAllocation(old_flavor, source_usages) - dest_usages = self._get_provider_usages(dest_rp_uuid) - self.assertFlavorMatchesAllocation(new_flavor, dest_usages) - - # The instance should own the new_flavor allocation against the - # destination host created by the scheduler - allocations = self._get_allocations_by_server_uuid(server['id']) - self.assertEqual(1, len(allocations)) - dest_alloc = allocations[dest_rp_uuid]['resources'] - self.assertFlavorMatchesAllocation(new_flavor, dest_alloc) - - # The migration should own the old_flavor allocation against the - # source host created by conductor - migration_uuid = self.get_migration_uuid_for_instance(server['id']) - allocations = self._get_allocations_by_server_uuid(migration_uuid) - source_alloc = allocations[source_rp_uuid]['resources'] - self.assertFlavorMatchesAllocation(old_flavor, source_alloc) - - self._run_periodics() - - # the original host expected to have the old resource usage - source_usages = self._get_provider_usages(source_rp_uuid) - self.assertFlavorMatchesAllocation(old_flavor, source_usages) - - # the dest host expected to have resource allocation based on - # the new flavor the server is resized to - dest_usages = self._get_provider_usages(dest_rp_uuid) - self.assertFlavorMatchesAllocation(new_flavor, dest_usages) - - # The instance should own the new_flavor allocation against the - # destination host - allocations = self._get_allocations_by_server_uuid(server['id']) - self.assertEqual(1, len(allocations)) - dest_allocation = allocations[dest_rp_uuid]['resources'] - self.assertFlavorMatchesAllocation(new_flavor, dest_allocation) - - # The migration should own the old_flavor allocation against the - # source host - migration_uuid = self.get_migration_uuid_for_instance(server['id']) - allocations = self._get_allocations_by_server_uuid(migration_uuid) - source_alloc = allocations[source_rp_uuid]['resources'] - self.assertFlavorMatchesAllocation(old_flavor, source_alloc) + self._move_and_check_allocations( + server, request=resize_req, old_flavor=old_flavor, + new_flavor=new_flavor, source_rp_uuid=source_rp_uuid, + dest_rp_uuid=dest_rp_uuid) def _test_resize_revert(self, dest_hostname): source_hostname = self._other_hostname(dest_hostname) @@ -3111,6 +3106,100 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): def test_resize_reschedule_uses_host_lists_not_enough_alts(self): self._test_resize_reschedule_uses_host_lists(fails=3, num_alts=1) + def test_migrate_confirm(self): + source_hostname = self.compute1.host + dest_hostname = self.compute2.host + source_rp_uuid = self._get_provider_uuid_by_host(source_hostname) + dest_rp_uuid = self._get_provider_uuid_by_host(dest_hostname) + + server = self._boot_and_check_allocations( + self.flavor1, source_hostname) + + self._migrate_and_check_allocations( + server, self.flavor1, source_rp_uuid, dest_rp_uuid) + + # Confirm the move and check the usages + post = {'confirmResize': None} + self.api.post_server_action( + server['id'], post, check_response_status=[204]) + self._wait_for_state_change(self.api, server, 'ACTIVE') + + def _check_allocation(): + allocations = self._get_allocations_by_server_uuid(server['id']) + + # and the server allocates only from the target host + self.assertEqual(1, len(allocations)) + + source_usages = self._get_provider_usages(source_rp_uuid) + dest_usages = self._get_provider_usages(dest_rp_uuid) + + # and the target host allocation should be according to the flavor + self.assertFlavorMatchesAllocation(self.flavor1, dest_usages) + self.assertEqual({'VCPU': 0, + 'MEMORY_MB': 0, + 'DISK_GB': 0}, source_usages, + 'The source host %s still has usages after the ' + 'resize has been confirmed' % source_hostname) + + # and the target host allocation should be according to the flavor + self.assertFlavorMatchesAllocation(self.flavor1, dest_usages) + + dest_allocation = allocations[dest_rp_uuid]['resources'] + self.assertFlavorMatchesAllocation(self.flavor1, dest_allocation) + + # After confirming, we should have an allocation only on the + # destination host + _check_allocation() + self._run_periodics() + + # Check we're still accurate after running the periodics + _check_allocation() + + self._delete_and_check_allocations(server) + + def test_migrate_revert(self): + source_hostname = self.compute1.host + dest_hostname = self.compute2.host + source_rp_uuid = self._get_provider_uuid_by_host(source_hostname) + dest_rp_uuid = self._get_provider_uuid_by_host(dest_hostname) + + server = self._boot_and_check_allocations( + self.flavor1, source_hostname) + + self._migrate_and_check_allocations( + server, self.flavor1, source_rp_uuid, dest_rp_uuid) + + # Revert the move and check the usages + post = {'revertResize': None} + self.api.post_server_action(server['id'], post) + self._wait_for_state_change(self.api, server, 'ACTIVE') + + def _check_allocation(): + source_usages = self._get_provider_usages(source_rp_uuid) + allocations = self._get_allocations_by_server_uuid(server['id']) + self.assertFlavorMatchesAllocation(self.flavor1, source_usages) + + dest_usages = self._get_provider_usages(dest_rp_uuid) + self.assertEqual({'VCPU': 0, + 'MEMORY_MB': 0, + 'DISK_GB': 0}, dest_usages, + 'Target host %s still has usage after the ' + 'resize has been reverted' % dest_hostname) + + # Check that the server only allocates resource from the original + # host + self.assertEqual(1, len(allocations)) + + source_allocation = allocations[source_rp_uuid]['resources'] + self.assertFlavorMatchesAllocation(self.flavor1, source_allocation) + + # the original host expected to have the old resource allocation + _check_allocation() + self._run_periodics() + _check_allocation() + + self._delete_and_check_allocations(server) + class ServerLiveMigrateForceAndAbort( integrated_helpers.ProviderUsageBaseTestCase):