Browse Source

Add functional confirm_migration_error test

This test checks if allocations have been
successfully cleaned up upon the driver failing
during "confirm_migration".

NOTE(mriedem): The _wait_until_deleted helper method
is modified here to include the changes from patch
I4ced19bd9259f0b5a50b89dd5908abe35ca73894 in Rocky
otherwise the test fails.

Change-Id: I9d6478f492351b58aa87b8f56e907ee633d6d1c6
Related-bug: #1821594
(cherry picked from commit 873ac499c5)
(cherry picked from commit d7d7f11543)
(cherry picked from commit 01bfb7863c)
tags/17.0.11
Rodrigo Barbieri 4 months ago
parent
commit
944b24f462
2 changed files with 74 additions and 1 deletions
  1. 2
    1
      nova/tests/functional/integrated_helpers.py
  2. 72
    0
      nova/tests/functional/test_servers.py

+ 2
- 1
nova/tests/functional/integrated_helpers.py View File

@@ -270,10 +270,11 @@ class InstanceHelperMixin(object):
270 270
         return server
271 271
 
272 272
     def _wait_until_deleted(self, server):
273
+        initially_in_error = (server['status'] == 'ERROR')
273 274
         try:
274 275
             for i in range(40):
275 276
                 server = self.api.get_server(server['id'])
276
-                if server['status'] == 'ERROR':
277
+                if not initially_in_error and server['status'] == 'ERROR':
277 278
                     self.fail('Server went to error state instead of'
278 279
                               'disappearing.')
279 280
                 time.sleep(0.5)

+ 72
- 0
nova/tests/functional/test_servers.py View File

@@ -1849,6 +1849,78 @@ class ServerMovingTests(ProviderUsageBaseTestCase):
1849 1849
             new_flavor=new_flavor, source_rp_uuid=source_rp_uuid,
1850 1850
             dest_rp_uuid=dest_rp_uuid)
1851 1851
 
1852
+    def test_migration_confirm_resize_error(self):
1853
+        source_hostname = self.compute1.host
1854
+        dest_hostname = self.compute2.host
1855
+
1856
+        source_rp_uuid = self._get_provider_uuid_by_host(source_hostname)
1857
+        dest_rp_uuid = self._get_provider_uuid_by_host(dest_hostname)
1858
+
1859
+        server = self._boot_and_check_allocations(self.flavor1,
1860
+                                                  source_hostname)
1861
+
1862
+        self._move_and_check_allocations(
1863
+            server, request={'migrate': None}, old_flavor=self.flavor1,
1864
+            new_flavor=self.flavor1, source_rp_uuid=source_rp_uuid,
1865
+            dest_rp_uuid=dest_rp_uuid)
1866
+
1867
+        # Mock failure
1868
+        def fake_confirm_migration(context, migration, instance, network_info):
1869
+            raise exception.MigrationPreCheckError(
1870
+                reason='test_migration_confirm_resize_error')
1871
+
1872
+        with mock.patch('nova.virt.fake.FakeDriver.'
1873
+                        'confirm_migration',
1874
+                        side_effect=fake_confirm_migration):
1875
+
1876
+            # Confirm the migration/resize and check the usages
1877
+            post = {'confirmResize': None}
1878
+            self.api.post_server_action(
1879
+                server['id'], post, check_response_status=[204])
1880
+            server = self._wait_for_state_change(self.api, server, 'ERROR')
1881
+
1882
+        # After confirming and error, we should have an allocation only on the
1883
+        # destination host
1884
+        source_usages = self._get_provider_usages(source_rp_uuid)
1885
+        self.assertEqual({'VCPU': 0,
1886
+                          'MEMORY_MB': 0,
1887
+                          'DISK_GB': 0}, source_usages,
1888
+                          'Source host %s still has usage after the failed '
1889
+                          'migration_confirm' % source_hostname)
1890
+
1891
+        # Check that the server only allocates resource from the original host
1892
+        allocations = self._get_allocations_by_server_uuid(server['id'])
1893
+        self.assertEqual(1, len(allocations))
1894
+
1895
+        dest_allocation = allocations[dest_rp_uuid]['resources']
1896
+        self.assertFlavorMatchesAllocation(self.flavor1, dest_allocation)
1897
+
1898
+        dest_usages = self._get_provider_usages(dest_rp_uuid)
1899
+        self.assertFlavorMatchesAllocation(self.flavor1, dest_usages)
1900
+
1901
+        self._run_periodics()
1902
+
1903
+        # After confirming and error, we should have an allocation only on the
1904
+        # destination host
1905
+        source_usages = self._get_provider_usages(source_rp_uuid)
1906
+        self.assertEqual({'VCPU': 0,
1907
+                          'MEMORY_MB': 0,
1908
+                          'DISK_GB': 0}, source_usages,
1909
+                          'Source host %s still has usage after the failed '
1910
+                          'migration_confirm' % source_hostname)
1911
+
1912
+        # Check that the server only allocates resource from the original host
1913
+        allocations = self._get_allocations_by_server_uuid(server['id'])
1914
+        self.assertEqual(1, len(allocations))
1915
+
1916
+        dest_allocation = allocations[dest_rp_uuid]['resources']
1917
+        self.assertFlavorMatchesAllocation(self.flavor1, dest_allocation)
1918
+
1919
+        dest_usages = self._get_provider_usages(dest_rp_uuid)
1920
+        self.assertFlavorMatchesAllocation(self.flavor1, dest_usages)
1921
+
1922
+        self._delete_and_check_allocations(server)
1923
+
1852 1924
     def _test_resize_revert(self, dest_hostname):
1853 1925
         source_hostname = self._other_hostname(dest_hostname)
1854 1926
         source_rp_uuid = self._get_provider_uuid_by_host(source_hostname)

Loading…
Cancel
Save