mirror of
https://github.com/gryf/openstack.git
synced 2025-12-17 03:20:25 +01:00
Added soft anti/affinity weight.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
Aggregate affinity
|
||||
==================
|
||||
|
||||
This series of patches add ability for creating aggregation of ironic nodes in
|
||||
This series of patches adds ability for creating aggregation of ironic nodes in
|
||||
Nova. This work is based on work of `Jay Pipes series`_ back ported to Ocata,
|
||||
with some additional fixes.
|
||||
|
||||
@@ -15,8 +15,9 @@ of two new policies:
|
||||
Note, that if openstackclient is used, it is needed to overwrite
|
||||
``OS_COMPUTE_API_VERSION`` environment variable to value ``2.43``.
|
||||
|
||||
Given, that we are working on devstack, and have available four Ironic nodes,
|
||||
basic flow to test it is as follows:
|
||||
Given, that we are working on devstack, and have available four Ironic nodes
|
||||
(it need to be changed in devstacks' ``local.conf`` by setting variable
|
||||
``IRONIC_VM_COUNT`` to ``4``), basic flow to test it is as follows:
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
@@ -41,7 +42,84 @@ basic flow to test it is as follows:
|
||||
--hint group=$(openstack server group list | grep group1 | awk '{print $2}') \
|
||||
instance2
|
||||
|
||||
this should place two ironic instances on two different `rack` aggregates.
|
||||
this should place two ironic instances on two different *rack* aggregates. In
|
||||
similar fashion it might be group created with policy ``aggregate-affinity``.
|
||||
|
||||
|
||||
Soft aggregate affinity
|
||||
=======================
|
||||
|
||||
This is similar feature to `soft (anti) affinity* feature`_ which was
|
||||
done for compute hosts. There are two new weight introduced:
|
||||
|
||||
* aggregate-soft-affinity
|
||||
* aggregate-soft-anti-affinity
|
||||
|
||||
and can be used for scattering instances between two aggregates within
|
||||
an instance group with two policies - to keep instances within an
|
||||
aggregate (affinity), or to spread them around on different aggregates.
|
||||
If there would be not possible to put an instance together on an
|
||||
aggregate (in case of affinity) or on different one (in case of
|
||||
anti-affinity), it will be placed in specified group anyway.
|
||||
|
||||
Simple usage is as follows, using environment described above in
|
||||
*aggregate-affinity* feature:
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ export OS_COMPUTE_API_VERSION=2.43
|
||||
$ openstack aggregate create rack1
|
||||
$ openstack aggregate create rack2
|
||||
$ openstack aggregate add host rack1 $(openstack baremetal node list|grep node-0|awk '{print $2}')
|
||||
$ openstack aggregate add host rack1 $(openstack baremetal node list|grep node-1|awk '{print $2}')
|
||||
$ openstack aggregate add host rack2 $(openstack baremetal node list|grep node-2|awk '{print $2}')
|
||||
$ openstack aggregate add host rack2 $(openstack baremetal node list|grep node-3|awk '{print $2}')
|
||||
$ openstack server group create --policy aggregate-soft-anti-affinity group1
|
||||
$ openstack server create \
|
||||
--image=$(openstack image list|grep x86_64-disk| awk '{print $2}') \
|
||||
--flavor=1 \
|
||||
--nic net-id=$(openstack network list |grep private | awk '{print $2}') \
|
||||
--hint group=$(openstack server group list | grep group1 | awk '{print $2}') \
|
||||
instance1
|
||||
$ openstack server create \
|
||||
--image=$(openstack image list|grep x86_64-disk| awk '{print $2}') \
|
||||
--flavor=1 \
|
||||
--nic net-id=$(openstack network list |grep private | awk '{print $2}') \
|
||||
--hint group=$(openstack server group list | grep group1 | awk '{print $2}') \
|
||||
instance2
|
||||
$ openstack server create \
|
||||
--image=$(openstack image list|grep x86_64-disk| awk '{print $2}') \
|
||||
--flavor=1 \
|
||||
--nic net-id=$(openstack network list |grep private | awk '{print $2}') \
|
||||
--hint group=$(openstack server group list | grep group1 | awk '{print $2}') \
|
||||
instance3
|
||||
|
||||
Unlike in ``aggregate-anti-affinity`` policy, creating ``instance3`` will
|
||||
pass, since regardless of not available aggregate with no group members, it
|
||||
will be placed in the group anyway on one of the available host within the
|
||||
group.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
As for soft aggregate (anti) affinity there is another limitation, which comes
|
||||
with how weights works right now in Nova. Because of `this commit`_ change of
|
||||
behaviour was introduced on how scheduler selects hosts. It's concerns all of
|
||||
affinity/anti-affinity weights, not only this particular newly added for
|
||||
aggregation.
|
||||
|
||||
That change introduce a blind selection of the host form a group of the weighed
|
||||
hosts, which are originally sorted from best fitting. For affinity weight it
|
||||
will always return full list of the hosts (since they are not a filters), which
|
||||
is ordered from best to worst hosts. There is a high chance, that ``nova.conf``
|
||||
will need to have a scheduler filter option ``host_subset_size`` set to ``1``,
|
||||
like:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[filter_scheduler]
|
||||
host_subset_size = 1
|
||||
|
||||
|
||||
Creation of instances in a bulk
|
||||
@@ -226,3 +304,5 @@ instances one by one, but not in the bulk.
|
||||
|
||||
|
||||
.. _Jay Pipes series: https://review.openstack.org/#/q/topic:bp/aggregate-affinity
|
||||
.. _this commit: https://review.openstack.org/#/c/19823/
|
||||
.. _soft (anti) affinity* feature: http://specs.openstack.org/openstack/nova-specs/specs/kilo/approved/soft-affinity-for-server-group.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0f820a60994586debef47a59ebf8d9eef225b69c Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Wed, 27 Dec 2017 13:51:25 +0100
|
||||
Subject: [PATCH 1/8] allow compute nodes to be associated with host agg
|
||||
Subject: [PATCH 1/9] allow compute nodes to be associated with host agg
|
||||
|
||||
This is basically an Ocata backport patch from Jay Pipes:
|
||||
https://review.openstack.org/#/c/526753
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From f5e23e436d341a44dafe5a18876cfcadc809b46b Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Mon, 8 Jan 2018 14:33:45 +0100
|
||||
Subject: [PATCH 2/8] Remove server group sched filter support caching
|
||||
Subject: [PATCH 2/9] Remove server group sched filter support caching
|
||||
|
||||
Backport of https://review.openstack.org/#/c/529200 by Jay Pipes to
|
||||
Ocata.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 69d0e023edfc2edc123fd5ed29b79ebbd3abe97f Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Wed, 10 Jan 2018 10:37:54 +0100
|
||||
Subject: [PATCH 3/8] get instance group's aggregate associations
|
||||
Subject: [PATCH 3/9] get instance group's aggregate associations
|
||||
|
||||
Ocata backport for patch from Jay Pipes:
|
||||
https://review.openstack.org/#/c/531243/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From f69827ff3502552a45a19a50ef2cfad30c41af2d Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Thu, 18 Jan 2018 09:17:04 +0100
|
||||
Subject: [PATCH 4/8] Support aggregate affinity filters
|
||||
Subject: [PATCH 4/9] Support aggregate affinity filters
|
||||
|
||||
Jay patch for two new policies: aggregate-affinity and
|
||||
aggregate-antiaffinity backported to Ocata.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9014195f11d981da4dc158ab9b9b6bb594c8ea0d Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Fri, 23 Feb 2018 07:26:05 +0100
|
||||
Subject: [PATCH 5/8] Added node field for InstanceGroup objects
|
||||
Subject: [PATCH 5/9] Added node field for InstanceGroup objects
|
||||
|
||||
Currently, there is only a way for getting the information which hosts
|
||||
belongs for certain instance group. By 'hosts' it means a hostname, on
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3e4ef01cb6f3fa5545cd3be31d84295d65f73fa7 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Fri, 23 Feb 2018 09:19:54 +0000
|
||||
Subject: [PATCH 6/8] Add ability to search aggregate map via ironic node as a
|
||||
Subject: [PATCH 6/9] Add ability to search aggregate map via ironic node as a
|
||||
key in HostManager
|
||||
|
||||
With this change now it will be possible for mapping nodes with aggregate.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6f8af77366402aca0555005abe469b29509d0eb3 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Fri, 23 Feb 2018 11:28:52 +0000
|
||||
Subject: [PATCH 7/8] Add nodes to group hosts to be checked against
|
||||
Subject: [PATCH 7/9] Add nodes to group hosts to be checked against
|
||||
aggregation
|
||||
|
||||
Currently, only hostnames (which origin from machine, on which compute service
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 72af3e6b58c3a732549b40fbb24067a41c7065ac Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Fri, 23 Feb 2018 11:37:16 +0000
|
||||
Subject: [PATCH 8/8] Fix for checking policies in non existing instance_group
|
||||
Subject: [PATCH 8/9] Fix for checking policies in non existing instance_group
|
||||
|
||||
---
|
||||
nova/scheduler/filters/affinity_filter.py | 2 +-
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
From 85c5a788ebe71089d06bc82a57a5a4b10dd72fe8 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Dobosz <roman.dobosz@intel.com>
|
||||
Date: Wed, 14 Mar 2018 14:01:55 +0100
|
||||
Subject: [PATCH 9/9] Added weight for aggregate soft (anti) affinity.
|
||||
|
||||
This is similar feature to soft (anti) affinity feature[1] which was
|
||||
done for compute hosts. In This commit we introducing two new weights:
|
||||
|
||||
- aggregate-soft-affinity
|
||||
- aggregate-soft-anti-affinity
|
||||
|
||||
which can be used for scattering instances between two aggregates within
|
||||
an instance group with two policies - to keep instances within an
|
||||
aggregate (affinity), or to spread them around on different aggregates.
|
||||
If there would be not possible to put an instance together on an
|
||||
aggregate (in case of affinity) or on different one (in case of
|
||||
anti-affinity), it will be placed in specified group anyway.
|
||||
|
||||
[1] http://specs.openstack.org/openstack/nova-specs/specs/kilo/approved/soft-affinity-for-server-group.html
|
||||
---
|
||||
.../api/openstack/compute/schemas/server_groups.py | 4 +-
|
||||
nova/compute/manager.py | 2 +-
|
||||
nova/conf/scheduler.py | 24 ++++
|
||||
nova/scheduler/utils.py | 6 +-
|
||||
nova/scheduler/weights/affinity.py | 66 +++++++++++
|
||||
.../scheduler/weights/test_weights_affinity.py | 123 +++++++++++++++++++++
|
||||
6 files changed, 222 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/nova/api/openstack/compute/schemas/server_groups.py b/nova/api/openstack/compute/schemas/server_groups.py
|
||||
index 4b274e3251..408a559d99 100644
|
||||
--- a/nova/api/openstack/compute/schemas/server_groups.py
|
||||
+++ b/nova/api/openstack/compute/schemas/server_groups.py
|
||||
@@ -47,4 +47,6 @@ policies['items'][0]['enum'].extend(['soft-anti-affinity', 'soft-affinity'])
|
||||
create_v243 = copy.deepcopy(create_v215)
|
||||
policies = create_v243['properties']['server_group']['properties']['policies']
|
||||
policies['items'][0]['enum'].extend(['aggregate-anti-affinity',
|
||||
- 'aggregate-affinity'])
|
||||
+ 'aggregate-affinity',
|
||||
+ 'aggregate-soft-anti-affinity',
|
||||
+ 'aggregate-soft-affinity'])
|
||||
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
|
||||
index 10ed9d3df0..8040d2fa7c 100644
|
||||
--- a/nova/compute/manager.py
|
||||
+++ b/nova/compute/manager.py
|
||||
@@ -1328,7 +1328,7 @@ class ComputeManager(manager.Manager):
|
||||
raise exception.RescheduledException(
|
||||
instance_uuid=instance.uuid,
|
||||
reason=msg)
|
||||
- else:
|
||||
+ elif 'aggregate-anti-affinity' == group_policy:
|
||||
group_aggs = group.get_aggregate_uuids(
|
||||
exclude=[instance.uuid])
|
||||
if not node_aggs.isdisjoint(group_aggs):
|
||||
diff --git a/nova/conf/scheduler.py b/nova/conf/scheduler.py
|
||||
index 6b69f9d1a2..710eebcad6 100644
|
||||
--- a/nova/conf/scheduler.py
|
||||
+++ b/nova/conf/scheduler.py
|
||||
@@ -462,6 +462,30 @@ Multiplier used for weighing hosts for group soft-anti-affinity.
|
||||
|
||||
Possible values:
|
||||
|
||||
+* An integer or float value, where the value corresponds to weight multiplier
|
||||
+ for hosts with group soft anti-affinity. Only a positive value are
|
||||
+ meaningful, as negative values would make this behave as a soft affinity
|
||||
+ weigher.
|
||||
+"""),
|
||||
+ cfg.FloatOpt("aggregate_soft_affinity_weight_multiplier",
|
||||
+ default=1.0,
|
||||
+ help="""
|
||||
+Multiplier used for weighing hosts for group soft-affinity.
|
||||
+
|
||||
+Possible values:
|
||||
+
|
||||
+* An integer or float value, where the value corresponds to weight multiplier
|
||||
+ for hosts with group soft affinity. Only a positive value are meaningful, as
|
||||
+ negative values would make this behave as a soft anti-affinity weigher.
|
||||
+"""),
|
||||
+ cfg.FloatOpt(
|
||||
+ "aggregate_soft_anti_affinity_weight_multiplier",
|
||||
+ default=1.0,
|
||||
+ help="""
|
||||
+Multiplier used for weighing hosts for group soft-anti-affinity.
|
||||
+
|
||||
+Possible values:
|
||||
+
|
||||
* An integer or float value, where the value corresponds to weight multiplier
|
||||
for hosts with group soft anti-affinity. Only a positive value are
|
||||
meaningful, as negative values would make this behave as a soft affinity
|
||||
diff --git a/nova/scheduler/utils.py b/nova/scheduler/utils.py
|
||||
index 57a306e07a..57f8cf343f 100644
|
||||
--- a/nova/scheduler/utils.py
|
||||
+++ b/nova/scheduler/utils.py
|
||||
@@ -311,7 +311,11 @@ def _get_group_details(context, instance_uuid, user_group_hosts=None):
|
||||
'aggregate-affinity': (
|
||||
_validate_filter, 'ServerGroupAggregateAffinityFilter'),
|
||||
'aggregate-anti-affinity': (
|
||||
- _validate_filter, 'ServerGroupAggregateAntiAffinityFilter')
|
||||
+ _validate_filter, 'ServerGroupAggregateAntiAffinityFilter'),
|
||||
+ 'aggregate-soft-affinity': (
|
||||
+ _validate_weigher, 'ServerGroupAggregateSoftAffinityWeigher'),
|
||||
+ 'aggregate-soft-anti-affinity': (
|
||||
+ _validate_weigher, 'ServerGroupAggregateSoftAntiAffinityWeigher')
|
||||
}
|
||||
|
||||
check_fn, class_name = checks[group_policy]
|
||||
diff --git a/nova/scheduler/weights/affinity.py b/nova/scheduler/weights/affinity.py
|
||||
index 1a9a277b86..9f98c9a510 100644
|
||||
--- a/nova/scheduler/weights/affinity.py
|
||||
+++ b/nova/scheduler/weights/affinity.py
|
||||
@@ -95,3 +95,69 @@ class ServerGroupSoftAntiAffinityWeigher(_SoftAffinityWeigherBase):
|
||||
weight = super(ServerGroupSoftAntiAffinityWeigher, self)._weigh_object(
|
||||
host_state, request_spec)
|
||||
return -1 * weight
|
||||
+
|
||||
+
|
||||
+class ServerGroupAggregateSoftAffinityWeigher(weights.BaseHostWeigher):
|
||||
+ """ServerGroupAggregateSoftAffinityWeigher implements the soft-affinity
|
||||
+ policy for server groups by preferring the aggregates that has more
|
||||
+ instances from the given group.
|
||||
+ """
|
||||
+
|
||||
+ POLICY_NAME = 'aggregate-soft-affinity'
|
||||
+ CONF = CONF.filter_scheduler.aggregate_soft_affinity_weight_multiplier
|
||||
+
|
||||
+ def _pre_checks(self, host_state, request_spec):
|
||||
+ if not (request_spec.instance_group and
|
||||
+ request_spec.instance_group.policies):
|
||||
+ return 0
|
||||
+
|
||||
+ policy = request_spec.instance_group.policies[0]
|
||||
+ if self.POLICY_NAME != policy:
|
||||
+ return 0
|
||||
+
|
||||
+ self.group_hosts = set(request_spec.instance_group.nodes +
|
||||
+ request_spec.instance_group.hosts)
|
||||
+
|
||||
+ if not self.group_hosts:
|
||||
+ # There are no members of the server group yet, so this host meets
|
||||
+ # the aggregate affinity (or anti-affinity) constraint
|
||||
+ return 0
|
||||
+
|
||||
+ return 1
|
||||
+
|
||||
+ def _weigh_object(self, host_state, request_spec):
|
||||
+ """Higher weights win."""
|
||||
+ if not self._pre_checks(host_state, request_spec):
|
||||
+ return 0
|
||||
+
|
||||
+ weight = []
|
||||
+ for aggregate in host_state.aggregates:
|
||||
+ aggregate_weight = 0
|
||||
+ for hostname in aggregate.hosts:
|
||||
+ if hostname in self.group_hosts:
|
||||
+ aggregate_weight += 1
|
||||
+ weight.append(aggregate_weight)
|
||||
+
|
||||
+ if not weight:
|
||||
+ return 0
|
||||
+
|
||||
+ return float(sum(weight)) / len(weight)
|
||||
+
|
||||
+ def weight_multiplier(self):
|
||||
+ """How weighted this weigher should be."""
|
||||
+ return self.CONF
|
||||
+
|
||||
+
|
||||
+class ServerGroupAggregateSoftAntiAffinityWeigher(
|
||||
+ ServerGroupAggregateSoftAffinityWeigher):
|
||||
+ """ServerGroupAggregateSoftAntiAffinityWeigher implements the
|
||||
+ soft-affinity policy for server groups by preferring the aggregates that
|
||||
+ has less instances from the given group.
|
||||
+ """
|
||||
+
|
||||
+ POLICY_NAME = 'aggregate-soft-anti-affinity'
|
||||
+ CONF = CONF.filter_scheduler.aggregate_soft_anti_affinity_weight_multiplier
|
||||
+
|
||||
+ def _weigh_object(self, host_state, request_spec):
|
||||
+ return -1 * super(ServerGroupAggregateSoftAntiAffinityWeigher,
|
||||
+ self)._weigh_object(host_state, request_spec)
|
||||
diff --git a/nova/tests/unit/scheduler/weights/test_weights_affinity.py b/nova/tests/unit/scheduler/weights/test_weights_affinity.py
|
||||
index 21dbc19c9f..f5b898228a 100644
|
||||
--- a/nova/tests/unit/scheduler/weights/test_weights_affinity.py
|
||||
+++ b/nova/tests/unit/scheduler/weights/test_weights_affinity.py
|
||||
@@ -157,3 +157,126 @@ class SoftAntiAffinityWeigherTestCase(SoftWeigherTestBase):
|
||||
expected_weight=0.0,
|
||||
expected_host='host2')
|
||||
self.assertEqual(1, mock_log.warning.call_count)
|
||||
+
|
||||
+
|
||||
+class _FakeAggregate(object):
|
||||
+ def __init__(self, hosts):
|
||||
+ self.hosts = hosts
|
||||
+
|
||||
+
|
||||
+class AggregateSoftWeigherTestBase(test.NoDBTestCase):
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ super(AggregateSoftWeigherTestBase, self).setUp()
|
||||
+ hosts = (('host1', 'iron1',
|
||||
+ {'aggregates': [_FakeAggregate(['iron1',
|
||||
+ 'iron2'])],
|
||||
+ 'instances': {'i1': mock.sentinel,
|
||||
+ 'i2': mock.sentinel}}),
|
||||
+ ('host1', 'iron2',
|
||||
+ {'aggregates': [_FakeAggregate(['iron1',
|
||||
+ 'iron2'])],
|
||||
+ 'instances': {'i3': mock.sentinel}}),
|
||||
+ ('host1', 'iron3',
|
||||
+ {'aggregates': [_FakeAggregate(['iron3',
|
||||
+ 'iron4'])],
|
||||
+ 'instances': {'i3': mock.sentinel}}),
|
||||
+ ('host1', 'iron4',
|
||||
+ {'aggregates': [_FakeAggregate(['iron3',
|
||||
+ 'iron4'])],
|
||||
+ 'instances': {'i3': mock.sentinel}}))
|
||||
+
|
||||
+ self.hs_list = []
|
||||
+ for host in hosts:
|
||||
+ self.hs_list.append(fakes.FakeHostState(*host))
|
||||
+
|
||||
+
|
||||
+class TestAggregateSoftAntiAffinityWeigher(AggregateSoftWeigherTestBase):
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ super(TestAggregateSoftAntiAffinityWeigher, self).setUp()
|
||||
+ self.weighers = [affinity.
|
||||
+ ServerGroupAggregateSoftAntiAffinityWeigher()]
|
||||
+ self.weight_handler = weights.HostWeightHandler()
|
||||
+
|
||||
+ def test_no_instances(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=[],
|
||||
+ nodes=[])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename,
|
||||
+ ('iron1', 'iron2', 'iron3', 'iron4'))
|
||||
+
|
||||
+ def test_instance_in_first_aggregate(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=['host1'],
|
||||
+ nodes=['iron1'])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename, ('iron3', 'iron4'))
|
||||
+
|
||||
+ def test_two_instances_in_first_aggregate(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=['host1'],
|
||||
+ nodes=['iron1', 'iron2'])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename, ('iron3', 'iron4'))
|
||||
+
|
||||
+
|
||||
+class TestAggregateSoftAffinityWeigher(AggregateSoftWeigherTestBase):
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ super(TestAggregateSoftAffinityWeigher, self).setUp()
|
||||
+ self.weight_handler = weights.HostWeightHandler()
|
||||
+ self.weighers = [affinity.ServerGroupAggregateSoftAffinityWeigher()]
|
||||
+
|
||||
+ def test_no_instances(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=[],
|
||||
+ nodes=[])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename,
|
||||
+ ('iron1', 'iron2', 'iron3', 'iron4'))
|
||||
+
|
||||
+ def test_instance_in_first_aggregate(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=['host1'],
|
||||
+ nodes=['iron1'])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename, ('iron1', 'iron2'))
|
||||
+
|
||||
+ def test_two_instances_in_first_aggregate(self):
|
||||
+
|
||||
+ ig = objects.InstanceGroup(policies=['aggregate-soft-anti-affinity'],
|
||||
+ hosts=['host1'],
|
||||
+ nodes=['iron1', 'iron2'])
|
||||
+
|
||||
+ req_spec = objects.RequestSpec(instance_group=ig)
|
||||
+
|
||||
+ res = self.weight_handler.get_weighed_objects(self.weighers,
|
||||
+ self.hs_list, req_spec)
|
||||
+ self.assertIn(res[0].obj.nodename, ('iron1', 'iron2'))
|
||||
--
|
||||
2.16.1
|
||||
|
||||
Reference in New Issue
Block a user