Merge "Move HostNameWeigher to a common fixture"

This commit is contained in:
Zuul 2019-09-25 23:11:26 +00:00 committed by Gerrit Code Review
commit b2235e078e
10 changed files with 83 additions and 132 deletions

View File

@ -63,6 +63,7 @@ from nova.objects import service as service_obj
import nova.privsep
from nova import quota as nova_quota
from nova import rpc
from nova.scheduler import weights
from nova import service
from nova.tests.functional.api import client
from nova.tests.unit import fake_requests
@ -2166,3 +2167,52 @@ class OpenStackSDKFixture(fixtures.Fixture):
self.useFixture(fixtures.MockPatchObject(
service_description.ServiceDescription, '_make_proxy',
fake_make_proxy))
class HostNameWeigher(weights.BaseHostWeigher):
"""Weigher to make the scheduler host selection deterministic.
Note that this weigher is supposed to be used via
HostNameWeigherFixture and will fail to instantiate if used without that
fixture.
"""
def __init__(self):
self.weights = self.get_weights()
def get_weights(self):
raise NotImplemented()
def _weigh_object(self, host_state, weight_properties):
# Any unspecified host gets no weight.
return self.weights.get(host_state.host, 0)
class HostNameWeigherFixture(fixtures.Fixture):
"""Fixture to make the scheduler host selection deterministic.
Note that this fixture needs to be used before the scheduler service is
started as it changes the scheduler configuration.
"""
def __init__(self, weights=None):
"""Create the fixture
:param weights: A dict of weights keyed by host names. Defaulted to
{'host1': 100, 'host2': 50, 'host3': 10}"
"""
if weights:
self.weights = weights
else:
# default weights good for most of the functional tests
self.weights = {'host1': 100, 'host2': 50, 'host3': 10}
def setUp(self):
super(HostNameWeigherFixture, self).setUp()
# Make sure that when the scheduler instantiate the HostNameWeigher it
# is initialized with the weights that is configured in this fixture
self.useFixture(fixtures.MockPatchObject(
HostNameWeigher, 'get_weights', return_value=self.weights))
# Make sure that the scheduler loads the HostNameWeigher and only that
self.useFixture(ConfPatcher(
weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler'))

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import fixtures as func_fixtures
@ -20,13 +19,6 @@ from nova.tests.unit.image import fake as image_fake
from nova.tests.unit import policy_fixture
class HostNameWeigher(weights.BaseHostWeigher):
def _weigh_object(self, host_state, weight_properties):
"""Arbitrary preferring host1 over host3 over host2."""
weights = {'host1': 100, 'host2': 1, 'host3': 50}
return weights.get(host_state.host, 0)
class SchedulerOnlyChecksTargetTest(test.TestCase,
integrated_helpers.InstanceHelperMixin):
"""Regression test for bug 1702454 introduced in Newton.
@ -85,13 +77,13 @@ class SchedulerOnlyChecksTargetTest(test.TestCase,
# Define a very basic scheduler that only verifies if host is down.
self.flags(enabled_filters=['ComputeFilter'],
group='filter_scheduler')
# NOTE(sbauza): Use the above weigher so we are sure that
# NOTE(sbauza): Use the HostNameWeigherFixture so we are sure that
# we prefer first host1 for the boot request and forget about any
# other weigher.
# Host2 should only be preferred over host3 if and only if that's the
# only host we verify (as requested_destination does).
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture(
weights={'host1': 100, 'host2': 1, 'host3': 50}))
self.start_service('scheduler')
# Let's now start three compute nodes as we said above.

View File

@ -13,7 +13,6 @@
from nova.compute import manager as compute_manager
from nova import context as nova_context
from nova import objects
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import fixtures as func_fixtures
@ -22,13 +21,6 @@ from nova.tests.unit.image import fake as image_fake
from nova.tests.unit import policy_fixture
class HostNameWeigher(weights.BaseHostWeigher):
def _weigh_object(self, host_state, weight_properties):
"""Arbitrary preferring host1 over host2 over host3."""
weights = {'host1': 100, 'host2': 50, 'host3': 1}
return weights.get(host_state.host, 0)
class TestRequestSpecRetryReschedule(test.TestCase,
integrated_helpers.InstanceHelperMixin):
"""Regression test for bug 1718512 introduced in Newton.
@ -74,10 +66,9 @@ class TestRequestSpecRetryReschedule(test.TestCase,
self.admin_api.microversion = 'latest'
self.api.microversion = 'latest'
# Use our custom weigher defined above to make sure that we have
# a predictable scheduling sort order.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
# Use custom weigher to make sure that we have a predictable
# scheduling sort order.
self.useFixture(nova_fixtures.HostNameWeigherFixture())
self.start_service('scheduler')
# Let's now start three compute nodes as we said above.

View File

@ -11,7 +11,6 @@
# under the License.
from nova.scheduler import filter_scheduler
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import fixtures as func_fixtures
@ -20,13 +19,6 @@ from nova.tests.unit.image import fake as image_fake
from nova.tests.unit import policy_fixture
class HostNameWeigher(weights.BaseHostWeigher):
def _weigh_object(self, host_state, weight_properties):
"""Prefer host1 over host2."""
weights = {'host1': 100, 'host2': 1}
return weights.get(host_state.host, 0)
class AntiAffinityMultiCreateRequest(test.TestCase,
integrated_helpers.InstanceHelperMixin):
"""Regression test for bug 1781710 introduced in Rocky.
@ -68,9 +60,7 @@ class AntiAffinityMultiCreateRequest(test.TestCase,
self.admin_api.microversion = 'latest'
self.api.microversion = 'latest'
# Add our custom weigher.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
# disable late check on compute node to mimic devstack.
self.flags(disable_group_policy_check_upcall=True,
group='workarounds')

View File

@ -10,17 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova.scheduler import weights
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers
# Prefer host1 over host2 over host3
WEIGHT_MAP = {'host1': 100, 'host2': 50, 'host3': 25}
class HostNameWeigher(weights.BaseHostWeigher):
def _weigh_object(self, host_state, weight_properties):
return WEIGHT_MAP.get(host_state.host, 0)
class MultiCellEvacuateTestCase(integrated_helpers._IntegratedTestBase,
integrated_helpers.InstanceHelperMixin):
@ -46,9 +38,8 @@ class MultiCellEvacuateTestCase(integrated_helpers._IntegratedTestBase,
microversion = '2.11' # Need at least 2.11 for the force-down API
def setUp(self):
# Register our custom weigher for predictable scheduling results.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
# Register a custom weigher for predictable scheduling results.
self.useFixture(nova_fixtures.HostNameWeigherFixture())
super(MultiCellEvacuateTestCase, self).setUp()
def _setup_compute_service(self):

View File

@ -15,7 +15,6 @@ import mock
from nova.conductor import api as conductor_api
from nova import context as nova_context
from nova import objects
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import fixtures as func_fixtures
@ -23,14 +22,6 @@ from nova.tests.functional import integrated_helpers
from nova.tests.unit.image import fake as fake_image
class HostNameWeigher(weights.BaseHostWeigher):
# Prefer host1 over host2.
weights = {'host1': 100, 'host2': 50}
def _weigh_object(self, host_state, weight_properties):
return self.weights.get(host_state.host, 0)
class MissingReqSpecInstanceGroupUUIDTestCase(
test.TestCase, integrated_helpers.InstanceHelperMixin):
"""Regression recreate test for bug 1830747
@ -71,10 +62,9 @@ class MissingReqSpecInstanceGroupUUIDTestCase(
api_version='v2.1'))
self.api = api_fixture.admin_api
self.start_service('conductor')
# Use our custom weigher defined above to make sure that we have
# a predictable scheduling sort order.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
# Use a custom weigher to make sure that we have a predictable
# scheduling sort order.
self.useFixture(nova_fixtures.HostNameWeigherFixture())
self.start_service('scheduler')
# Start two computes, one where the server will be created and another
# where we'll cold migrate it.

View File

@ -16,21 +16,12 @@ from oslo_serialization import jsonutils
import nova.compute
from nova import exception
from nova.scheduler import weights
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers
from nova.tests.unit import fake_notifier
from nova.tests.unit.image import fake as fake_image
class HostNameWeigher(weights.BaseHostWeigher):
# Weigher to make the scheduler alternate host list deterministic
_weights = {'host1': 100, 'host2': 50, 'host3': 10}
def _weigh_object(self, host_state, weight_properties):
# Any undefined host gets no weight.
return self._weights.get(host_state.host, 0)
class RequestSpecImageSerializationFixture(fixtures.Fixture):
"""A fixture to temporary fix oslo.messaging bug #1529084 by serializing
datetime objects into strings in legacy dicts.
@ -61,10 +52,9 @@ class PinnedComputeRpcTests(integrated_helpers.ProviderUsageBaseTestCase):
compute_driver = 'fake.MediumFakeDriver'
def setUp(self):
# Use our custom weigher to make sure that we have
# a predictable host selection order during scheduling
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
# Use a custom weigher to make sure that we have a predictable host
# selection order during scheduling
self.useFixture(nova_fixtures.HostNameWeigherFixture())
super(PinnedComputeRpcTests, self).setUp()
fake_notifier.stub_notifier(self)

View File

@ -15,7 +15,6 @@ import time
from oslo_utils.fixture import uuidsentinel as uuids
import nova.conf
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional.api import client
@ -370,23 +369,15 @@ class TenantAggregateFilterTest(AggregateRequestFiltersTest):
self.assertEqual('host2', self._get_instance_host(server))
class HostNameWeigher(weights.BaseHostWeigher):
def _weigh_object(self, host_state, weight_properties):
"""Arbitrary preferring host1 over host2 over host3."""
weights = {'host1': 100, 'host2': 50, 'host3': 1}
return weights.get(host_state.host, 0)
class AvailabilityZoneFilterTest(AggregateRequestFiltersTest):
def setUp(self):
# Default to enabling the filter
self.flags(query_placement_for_availability_zone=True,
group='scheduler')
# Use our custom weigher defined above to make sure that we have
# a predictable scheduling sort order.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
# Use custom weigher to make sure that we have a predictable
# scheduling sort order.
self.useFixture(nova_fixtures.HostNameWeigherFixture())
# NOTE(danms): Do this before calling setUp() so that
# the scheduler service that is started sees the new value
@ -414,8 +405,7 @@ class IsolateAggregateFilterTest(AggregateRequestFiltersTest):
# aggregate filter were not in place otherwise it's not deterministic
# whether we're landing on host2 because of the filter or just by
# chance.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
super(IsolateAggregateFilterTest, self).setUp()
self.image_service = nova.tests.unit.image.fake.FakeImageService()
@ -673,8 +663,7 @@ class TestAggregateFiltersTogether(AggregateRequestFiltersTest):
# aggregate filter were not in place otherwise it's not deterministic
# whether we're landing on host2 because of the filter or just by
# chance.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
# NOTE(danms): Do this before calling setUp() so that
# the scheduler service that is started sees the new value
@ -923,8 +912,7 @@ class AggregateMultiTenancyIsolationColdMigrateTest(
# Add a custom weigher which will weigh host1, which will be in the
# admin project aggregate, higher than the other hosts which are in
# the non-admin project aggregate.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
self.start_service('scheduler')
for host in ('host1', 'host2', 'host3'):
@ -947,9 +935,9 @@ class AggregateMultiTenancyIsolationColdMigrateTest(
self.admin_api, 'tenant-aggregate')
# Add two compute hosts to the tenant aggregate. We exclude host1
# since that is weighed higher in HostNameWeigher and we want to
# ensure the scheduler properly filters out host1 before we even get
# to weighing the selected hosts.
# since that is weighed higher due to HostNameWeigherFixture and we
# want to ensure the scheduler properly filters out host1 before we
# even get to weighing the selected hosts.
for host in ('host2', 'host3'):
self._add_host_to_aggregate(self.admin_api, tenant_aggregate, host)

View File

@ -13,22 +13,12 @@
from oslo_serialization import jsonutils
from nova import conf
from nova.scheduler import weights
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers
CONF = conf.CONF
class HostNameWeigher(weights.BaseHostWeigher):
# JsonFilterTestCase creates host1 and host2. Prefer host1 to make the
# tests deterministic.
_weights = {'host1': 100, 'host2': 50}
def _weigh_object(self, host_state, weight_properties):
# Any undefined host gets no weight.
return self._weights.get(host_state.host, 0)
class JsonFilterTestCase(integrated_helpers.ProviderUsageBaseTestCase):
"""Functional tests for the JsonFilter scheduler filter."""
@ -46,8 +36,7 @@ class JsonFilterTestCase(integrated_helpers.ProviderUsageBaseTestCase):
# Use our custom weigher defined above to make sure that we have
# a predictable scheduling sort order during server create.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
super(JsonFilterTestCase, self).setUp()

View File

@ -41,7 +41,6 @@ from nova.network.neutronv2 import constants
from nova import objects
from nova.objects import block_device as block_device_obj
from nova.scheduler import utils
from nova.scheduler import weights
from nova import test
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional.api import client
@ -60,17 +59,6 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class AltHostWeigher(weights.BaseHostWeigher):
"""Used in the alternate host tests to return a pre-determined list of
hosts.
"""
def _weigh_object(self, host_state, weight_properties):
"""Return a defined order of hosts."""
weights = {"selection": 999, "alt_host1": 888, "alt_host2": 777,
"alt_host3": 666, "host1": 0, "host2": 0}
return weights.get(host_state.host, 0)
class ServersTestBase(integrated_helpers._IntegratedTestBase):
api_major_version = 'v2'
_force_delete_parameter = 'forceDelete'
@ -3194,8 +3182,10 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase):
{"name": "alt_host3", "uuid": uuid_alt3},
]
self.flags(weight_classes=[__name__ + '.AltHostWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture(
weights={
"selection": 999, "alt_host1": 888, "alt_host2": 777,
"alt_host3": 666, "host1": 0, "host2": 0}))
self.scheduler_service.stop()
self.scheduler_service = self.start_service('scheduler')
@ -6308,15 +6298,6 @@ class PortResourceRequestBasedSchedulingTest(
port_binding['pci_slot'])
class HostNameWeigher(weights.BaseHostWeigher):
# Weigher to make the scheduler alternate host list deterministic
_weights = {'host1': 100, 'host2': 50, 'host3': 10}
def _weigh_object(self, host_state, weight_properties):
# Any undefined host gets no weight.
return self._weights.get(host_state.host, 0)
class ServerMoveWithPortResourceRequestTest(
PortResourceRequestBasedSchedulingTestBase):
@ -6324,8 +6305,7 @@ class ServerMoveWithPortResourceRequestTest(
# Use our custom weigher defined above to make sure that we have
# a predictable host order in the alternate list returned by the
# scheduler for migration.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.useFixture(nova_fixtures.HostNameWeigherFixture())
super(ServerMoveWithPortResourceRequestTest, self).setUp()
self.compute2 = self._start_compute('host2')
self.compute2_rp_uuid = self._get_provider_uuid_by_host('host2')