]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add chance weigher to scheduler
authorStephen Mulcahy <stephen.mulcahy@hp.com>
Wed, 27 Nov 2013 10:26:03 +0000 (10:26 +0000)
committerStephen Mulcahy <stephen.mulcahy@hp.com>
Wed, 27 Nov 2013 14:20:13 +0000 (14:20 +0000)
Adds chance weigher to scheduler to allow distribution of requests
randomly between a number of volume managers.

Change-Id: I3f652caf200c406965b52b94cebb244d3bc1779a

cinder/scheduler/weights/chance.py [new file with mode: 0644]
cinder/tests/scheduler/test_capacity_weigher.py
cinder/tests/scheduler/test_chance_weigher.py [new file with mode: 0644]
setup.cfg

diff --git a/cinder/scheduler/weights/chance.py b/cinder/scheduler/weights/chance.py
new file mode 100644 (file)
index 0000000..4e79b79
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+"""
+Chance Weigher.  Assign random weights to hosts.
+
+Used to spread volumes randomly across a list of equally suitable hosts.
+"""
+
+
+import random
+
+from cinder.openstack.common.scheduler import weights
+
+
+class ChanceWeigher(weights.BaseHostWeigher):
+    def _weigh_object(self, host_state, weight_properties):
+        return random.random()
index 24b93cca781dd5219ac49a3c4b9975f0b38a3fa1..f76aaafbfdbac059e59355ddfe63a8630b9f5080 100644 (file)
@@ -20,6 +20,8 @@ import testtools
 
 from cinder import context
 from cinder.openstack.common.scheduler.weights import HostWeightHandler
+
+from cinder.scheduler.weights.capacity import CapacityWeigher
 from cinder import test
 from cinder.tests.scheduler import fakes
 from cinder.tests import utils as test_utils
@@ -30,12 +32,11 @@ class CapacityWeigherTestCase(test.TestCase):
         super(CapacityWeigherTestCase, self).setUp()
         self.host_manager = fakes.FakeHostManager()
         self.weight_handler = HostWeightHandler('cinder.scheduler.weights')
-        self.weight_classes = self.weight_handler.get_all_classes()
 
     def _get_weighed_host(self, hosts, weight_properties=None):
         if weight_properties is None:
             weight_properties = {}
-        return self.weight_handler.get_weighed_objects(self.weight_classes,
+        return self.weight_handler.get_weighed_objects([CapacityWeigher],
                                                        hosts,
                                                        weight_properties)[0]
 
diff --git a/cinder/tests/scheduler/test_chance_weigher.py b/cinder/tests/scheduler/test_chance_weigher.py
new file mode 100644 (file)
index 0000000..4c6b448
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+"""
+Tests For Chance Weigher.
+"""
+
+import random
+import testtools
+
+from oslo.config import cfg
+
+from cinder import context
+from cinder.scheduler import host_manager
+from cinder.scheduler.weights.chance import ChanceWeigher
+from cinder import test
+from cinder.tests import utils as test_utils
+
+
+class ChanceWeigherTestCase(test.TestCase):
+    def setUp(self):
+        super(ChanceWeigherTestCase, self).setUp()
+
+    def fake_random(self, reset=False):
+        if reset:
+            self.not_random_float = 0.0
+        else:
+            self.not_random_float += 1.0
+        return self.not_random_float
+
+    def test_chance_weigher(self):
+        # stub random.random() to verify the ChanceWeigher
+        # is using random.random() (repeated calls to weigh should
+        # return incrementing weights)
+        weigher = ChanceWeigher()
+        self.stubs.Set(random, 'random', self.fake_random)
+        self.fake_random(reset=True)
+        host_state = {'host': 'host.example.com', 'free_capacity_gb': 99999}
+        weight = weigher._weigh_object(host_state, None)
+        self.assertEquals(1.0, weight)
+        weight = weigher._weigh_object(host_state, None)
+        self.assertEquals(2.0, weight)
+        weight = weigher._weigh_object(host_state, None)
+        self.assertEquals(3.0, weight)
+
+    def test_host_manager_choosing_chance_weigher(self):
+        # ensure HostManager can load the ChanceWeigher
+        # via the entry points mechanism
+        hm = host_manager.HostManager()
+        weighers = hm._choose_host_weighers('ChanceWeigher')
+        self.assertEquals(1, len(weighers))
+        self.assertEquals(weighers[0], ChanceWeigher)
+
+    def test_use_of_chance_weigher_via_host_manager(self):
+        # ensure we don't lose any hosts when weighing with
+        # the ChanceWeigher
+        hm = host_manager.HostManager()
+        fake_hosts = [host_manager.HostState('fake_host%s' % x)
+                      for x in xrange(1, 5)]
+        weighed_hosts = hm.get_weighed_hosts(fake_hosts, {}, 'ChanceWeigher')
+        self.assertEquals(4, len(weighed_hosts))
index 8377c21c7e13f3750763bb883d83c3712cd8f239..883c56c3c5954075a048caf059c97f55f022f09a 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -47,6 +47,7 @@ cinder.scheduler.filters =
     RetryFilter = cinder.scheduler.filters.retry_filter:RetryFilter
 cinder.scheduler.weights =
     CapacityWeigher = cinder.scheduler.weights.capacity:CapacityWeigher
+    ChanceWeigher = cinder.scheduler.weights.chance:ChanceWeigher
 
 [build_sphinx]
 all_files = 1