Made _issue_novaclient_command() behave better.
Fixed a bunch of tests.
This commit is contained in:
@@ -162,32 +162,53 @@ def child_zone_helper(zone_list, func):
|
||||
_wrap_method(_process, func), zone_list)]
|
||||
|
||||
|
||||
def _issue_novaclient_command(nova, zone, collection, method_name, item_id):
|
||||
def _issue_novaclient_command(nova, zone, collection,
|
||||
method_name, *args, **kwargs):
|
||||
"""Use novaclient to issue command to a single child zone.
|
||||
One of these will be run in parallel for each child zone."""
|
||||
One of these will be run in parallel for each child zone.
|
||||
"""
|
||||
manager = getattr(nova, collection)
|
||||
result = None
|
||||
try:
|
||||
|
||||
# NOTE(comstud): This is not ideal, but we have to do this based on
|
||||
# how novaclient is implemented right now.
|
||||
# 'find' is special cased as novaclient requires kwargs for it to
|
||||
# filter on a 'get_all'.
|
||||
# Every other method first needs to do a 'get' on the first argument
|
||||
# passed, which should be a UUID. If it's 'get' itself that we want,
|
||||
# we just return the result. Otherwise, we next call the real method
|
||||
# that's wanted... passing other arguments that may or may not exist.
|
||||
if method_name in ['find', 'findall']:
|
||||
try:
|
||||
result = manager.get(item_id)
|
||||
except ValueError, e:
|
||||
result = manager.find(name=item_id)
|
||||
return getattr(manager, method_name)(**kwargs)
|
||||
except novaclient.NotFound:
|
||||
url = zone.api_url
|
||||
LOG.debug(_("%(collection)s.%(method_name)s didn't find "
|
||||
"anything matching '%(kwargs)s' on '%(url)s'" %
|
||||
locals()))
|
||||
return None
|
||||
|
||||
args = list(args)
|
||||
# pop off the UUID to look up
|
||||
item = args.pop(0)
|
||||
try:
|
||||
result = manager.get(item)
|
||||
except novaclient.NotFound:
|
||||
url = zone.api_url
|
||||
LOG.debug(_("%(collection)s '%(item_id)s' not found on '%(url)s'" %
|
||||
LOG.debug(_("%(collection)s '%(item)s' not found on '%(url)s'" %
|
||||
locals()))
|
||||
return None
|
||||
|
||||
if method_name.lower() not in ['get', 'find']:
|
||||
result = getattr(result, method_name)()
|
||||
if method_name.lower() != 'get':
|
||||
# if we're doing something other than 'get', call it passing args.
|
||||
result = getattr(result, method_name)(*args, **kwargs)
|
||||
return result
|
||||
|
||||
|
||||
def wrap_novaclient_function(f, collection, method_name, item_id):
|
||||
"""Appends collection, method_name and item_id to the incoming
|
||||
def wrap_novaclient_function(f, collection, method_name, *args, **kwargs):
|
||||
"""Appends collection, method_name and arguments to the incoming
|
||||
(nova, zone) call from child_zone_helper."""
|
||||
def inner(nova, zone):
|
||||
return f(nova, zone, collection, method_name, item_id)
|
||||
return f(nova, zone, collection, method_name, *args, **kwargs)
|
||||
|
||||
return inner
|
||||
|
||||
@@ -220,7 +241,7 @@ class reroute_compute(object):
|
||||
the wrapped method. (This ensures that zone-local code can
|
||||
continue to use integer IDs).
|
||||
|
||||
4. If the item was not found, we delgate the call to a child zone
|
||||
4. If the item was not found, we delegate the call to a child zone
|
||||
using the UUID.
|
||||
"""
|
||||
def __init__(self, method_name):
|
||||
|
||||
@@ -180,7 +180,7 @@ class ZoneAwareScheduler(driver.Scheduler):
|
||||
request_spec, kwargs)
|
||||
return None
|
||||
|
||||
num_instances = request_spec['num_instances']
|
||||
num_instances = request_spec.get('num_instances', 1)
|
||||
LOG.debug(_("Attemping to build %d instance%s") %
|
||||
(num_instances, "" if num_instances == 1 else "s"))
|
||||
|
||||
@@ -227,7 +227,7 @@ class ZoneAwareScheduler(driver.Scheduler):
|
||||
raise NotImplemented(_("Zone Aware Scheduler only understands "
|
||||
"Compute nodes (for now)"))
|
||||
|
||||
num_instances = request_spec['num_instances']
|
||||
num_instances = request_spec.get('num_instances', 1)
|
||||
instance_type = request_spec['instance_type']
|
||||
|
||||
weighted = []
|
||||
|
||||
@@ -122,15 +122,16 @@ class LeastCostSchedulerTestCase(test.TestCase):
|
||||
for hostname, caps in hosts]
|
||||
self.assertWeights(expected, num, request_spec, hosts)
|
||||
|
||||
def test_fill_first_cost_fn(self):
|
||||
def test_compute_fill_first_cost_fn(self):
|
||||
FLAGS.least_cost_scheduler_cost_functions = [
|
||||
'nova.scheduler.least_cost.fill_first_cost_fn',
|
||||
'nova.scheduler.least_cost.compute_fill_first_cost_fn',
|
||||
]
|
||||
FLAGS.fill_first_cost_fn_weight = 1
|
||||
FLAGS.compute_fill_first_cost_fn_weight = 1
|
||||
|
||||
num = 1
|
||||
request_spec = {}
|
||||
hosts = self.sched.filter_hosts(num, request_spec)
|
||||
instance_type = {'memory_mb': 1024}
|
||||
request_spec = {'instance_type': instance_type}
|
||||
hosts = self.sched.filter_hosts('compute', request_spec, None)
|
||||
|
||||
expected = []
|
||||
for idx, (hostname, caps) in enumerate(hosts):
|
||||
|
||||
@@ -55,29 +55,21 @@ def fake_zone_manager_service_states(num_hosts):
|
||||
|
||||
|
||||
class FakeZoneAwareScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
||||
def filter_hosts(self, num, specs):
|
||||
# NOTE(sirp): this is returning [(hostname, services)]
|
||||
return self.zone_manager.service_states.items()
|
||||
|
||||
def weigh_hosts(self, num, specs, hosts):
|
||||
fake_weight = 99
|
||||
weighted = []
|
||||
for hostname, caps in hosts:
|
||||
weighted.append(dict(weight=fake_weight, name=hostname))
|
||||
return weighted
|
||||
# No need to stub anything at the moment
|
||||
pass
|
||||
|
||||
|
||||
class FakeZoneManager(zone_manager.ZoneManager):
|
||||
def __init__(self):
|
||||
self.service_states = {
|
||||
'host1': {
|
||||
'compute': {'ram': 1000},
|
||||
'compute': {'host_memory_free': 1000*1024*1024},
|
||||
},
|
||||
'host2': {
|
||||
'compute': {'ram': 2000},
|
||||
'compute': {'host_memory_free': 2000*1024*1024},
|
||||
},
|
||||
'host3': {
|
||||
'compute': {'ram': 3000},
|
||||
'compute': {'host_memory_free': 3000*1024*1024},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -164,13 +156,17 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
|
||||
sched.set_zone_manager(zm)
|
||||
|
||||
fake_context = {}
|
||||
build_plan = sched.select(fake_context, {})
|
||||
build_plan = sched.select(fake_context,
|
||||
{'instance_type': {'memory_mb': 512},
|
||||
'num_instances': 4 })
|
||||
|
||||
self.assertEqual(15, len(build_plan))
|
||||
# 4 from local zones, 12 from remotes
|
||||
self.assertEqual(16, len(build_plan))
|
||||
|
||||
hostnames = [plan_item['name']
|
||||
for plan_item in build_plan if 'name' in plan_item]
|
||||
self.assertEqual(3, len(hostnames))
|
||||
hostnames = [plan_item['hostname']
|
||||
for plan_item in build_plan if 'hostname' in plan_item]
|
||||
# 4 local hosts
|
||||
self.assertEqual(4, len(hostnames))
|
||||
|
||||
def test_empty_zone_aware_scheduler(self):
|
||||
"""
|
||||
@@ -185,8 +181,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
|
||||
fake_context = {}
|
||||
self.assertRaises(driver.NoValidHost, sched.schedule_run_instance,
|
||||
fake_context, 1,
|
||||
dict(host_filter=None,
|
||||
request_spec={'instance_type': {}}))
|
||||
dict(host_filter=None, instance_type={}))
|
||||
|
||||
def test_schedule_do_not_schedule_with_hint(self):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user