From 5fe80b6339b8a514bb4c1aee1f2d47cd83be592d Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Wed, 29 Aug 2018 13:16:09 -0400 Subject: [PATCH] (Re)start caching scheduler after starting computes in tests This moves the scheduler restart logic from the heal_allocations tests into a more generic location (like restart_compute_service) so that we can re-use it in other functional tests that rely on the caching scheduler. There are a couple of other tests that don't need to restart the scheduler if we just move the start of the scheduler to after we start the computes. Change-Id: I7720fe4a3a0e537b7b356947317766597d4b47cf Related-Bug: #1781648 --- nova/test.py | 19 +++++++++++++++++++ .../regressions/test_bug_1671648.py | 5 ++++- .../regressions/test_bug_1741125.py | 3 +++ .../regressions/test_bug_1741307.py | 8 +++++--- nova/tests/functional/test_nova_manage.py | 10 ++-------- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/nova/test.py b/nova/test.py index 2d225737c079..92befa9c782e 100644 --- a/nova/test.py +++ b/nova/test.py @@ -435,6 +435,25 @@ class TestCase(testtools.TestCase): compute.manager._resource_tracker = None compute.start() + @staticmethod + def restart_scheduler_service(scheduler): + """Restart a scheduler service in a realistic way. + + Deals with resetting the host state cache in the case of using the + CachingScheduler driver. + + :param scheduler: The nova-scheduler service to be restarted. + """ + scheduler.stop() + if hasattr(scheduler.manager.driver, 'all_host_states'): + # On startup, the CachingScheduler runs a periodic task to pull + # the initial set of compute nodes out of the database which it + # then puts into a cache (hence the name of the driver). This can + # race with actually starting the compute services so we need to + # restart the scheduler to refresh the cache. + scheduler.manager.driver.all_host_states = None + scheduler.start() + def assertJsonEqual(self, expected, observed, message=''): """Asserts that 2 complex data structures are json equivalent. diff --git a/nova/tests/functional/regressions/test_bug_1671648.py b/nova/tests/functional/regressions/test_bug_1671648.py index a5b98425f985..c1c0653d7206 100644 --- a/nova/tests/functional/regressions/test_bug_1671648.py +++ b/nova/tests/functional/regressions/test_bug_1671648.py @@ -63,7 +63,6 @@ class TestRetryBetweenComputeNodeBuilds(test.TestCase): self.start_service('conductor') self.start_service('consoleauth') - self.start_service('scheduler') # We start two compute services because we're going to fake one # of them to fail the build so we can trigger the retry code. @@ -80,6 +79,10 @@ class TestRetryBetweenComputeNodeBuilds(test.TestCase): self.addCleanup(fake.restore_nodes) self.start_service('compute', host='host2') + # Start the scheduler after the compute nodes are created in the DB + # in the case of using the CachingScheduler. + self.start_service('scheduler') + self.useFixture(cast_as_call.CastAsCall(self)) self.image_id = self.admin_api.get_images()[0]['id'] diff --git a/nova/tests/functional/regressions/test_bug_1741125.py b/nova/tests/functional/regressions/test_bug_1741125.py index 276d2b0543f2..206a2eda685d 100644 --- a/nova/tests/functional/regressions/test_bug_1741125.py +++ b/nova/tests/functional/regressions/test_bug_1741125.py @@ -36,6 +36,9 @@ class TestServerResizeReschedule(integrated_helpers.ProviderUsageBaseTestCase): self.compute3 = self._start_compute(host='host3') self.compute4 = self._start_compute(host='host4') + # Restart the scheduler to reset the host state cache. + self.restart_scheduler_service(self.scheduler_service) + flavors = self.api.get_flavors() self.flavor1 = flavors[0] self.flavor2 = flavors[1] diff --git a/nova/tests/functional/regressions/test_bug_1741307.py b/nova/tests/functional/regressions/test_bug_1741307.py index df371c94fa6d..0041b95f7505 100644 --- a/nova/tests/functional/regressions/test_bug_1741307.py +++ b/nova/tests/functional/regressions/test_bug_1741307.py @@ -59,9 +59,6 @@ class TestResizeWithCachingScheduler(test.TestCase, self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset) self.start_service('conductor') - # Configure the CachingScheduler. - self.flags(driver='caching_scheduler', group='scheduler') - self.start_service('scheduler') # Create two compute nodes/services. for host in ('host1', 'host2'): @@ -69,6 +66,11 @@ class TestResizeWithCachingScheduler(test.TestCase, self.addCleanup(fake.restore_nodes) self.start_service('compute', host=host) + # Start the scheduler after the compute nodes are created in the DB + # in the case of using the CachingScheduler. + self.flags(driver='caching_scheduler', group='scheduler') + self.start_service('scheduler') + flavors = self.api.get_flavors() self.old_flavor = flavors[0] self.new_flavor = flavors[1] diff --git a/nova/tests/functional/test_nova_manage.py b/nova/tests/functional/test_nova_manage.py index d76eb3693db8..09ddbd16ab01 100644 --- a/nova/tests/functional/test_nova_manage.py +++ b/nova/tests/functional/test_nova_manage.py @@ -387,14 +387,8 @@ class TestNovaManagePlacementHealAllocations( self.flavor = self.api.get_flavors()[0] self.output = StringIO() self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.output)) - # On startup, the CachingScheduler runs a periodic task to pull the - # initial set of compute nodes out of the database which it then puts - # into a cache (hence the name of the driver). This can race with - # actually starting the compute services so we need to restart the - # scheduler to refresh the cache. - self.scheduler_service.stop() - self.scheduler_service.manager.driver.all_host_states = None - self.scheduler_service.start() + # Restart the scheduler to reset the host state cache. + self.restart_scheduler_service(self.scheduler_service) def _boot_and_assert_no_allocations(self, flavor, hostname): """Creates a server on the given host and asserts neither have usage