diff --git a/nova/scheduler/base_scheduler.py b/nova/scheduler/base_scheduler.py index 35e5af035..e9c078b81 100644 --- a/nova/scheduler/base_scheduler.py +++ b/nova/scheduler/base_scheduler.py @@ -55,5 +55,17 @@ class BaseScheduler(abstract_scheduler.AbstractScheduler): scheduling objectives """ # NOTE(sirp): The default logic is the same as the NoopCostFunction - return [dict(weight=1, hostname=hostname, capabilities=capabilities) - for hostname, capabilities in hosts] + hosts = [dict(weight=1, hostname=hostname, capabilities=capabilities) + for hostname, capabilities in hosts] + + # NOTE(Vek): What we actually need to return is enough hosts + # for all the instances! + num_instances = request_spec.get('num_instances', 1) + instances = [] + while num_instances > len(hosts): + instances.extend(hosts) + num_instances -= len(hosts) + if num_instances > 0: + instances.extend(hosts[:num_instances]) + + return instances diff --git a/nova/tests/scheduler/test_abstract_scheduler.py b/nova/tests/scheduler/test_abstract_scheduler.py index aa97e2344..9bf128b13 100644 --- a/nova/tests/scheduler/test_abstract_scheduler.py +++ b/nova/tests/scheduler/test_abstract_scheduler.py @@ -26,6 +26,7 @@ from nova import test from nova.compute import api as compute_api from nova.scheduler import driver from nova.scheduler import abstract_scheduler +from nova.scheduler import base_scheduler from nova.scheduler import zone_manager @@ -65,6 +66,11 @@ class FakeAbstractScheduler(abstract_scheduler.AbstractScheduler): pass +class FakeBaseScheduler(base_scheduler.BaseScheduler): + # No need to stub anything at the moment + pass + + class FakeZoneManager(zone_manager.ZoneManager): def __init__(self): self.service_states = { @@ -365,3 +371,30 @@ class AbstractSchedulerTestCase(test.TestCase): self.assertEqual(fixture._decrypt_blob(test_data), json.dumps(test_data)) + + +class BaseSchedulerTestCase(test.TestCase): + """Test case for Base Scheduler.""" + + def test_weigh_hosts(self): + """ + Try to weigh a short list of hosts and make sure enough + entries for a larger number instances are returned. + """ + + sched = FakeBaseScheduler() + + # Fake out a list of hosts + zm = FakeZoneManager() + hostlist = [(host, services['compute']) + for host, services in zm.service_states.items() + if 'compute' in services] + + # Call weigh_hosts() + num_instances = len(hostlist) * 2 + len(hostlist) / 2 + instlist = sched.weigh_hosts('compute', + dict(num_instances=num_instances), + hostlist) + + # Should be enough entries to cover all instances + self.assertEqual(len(instlist), num_instances)