Modify conductor to use RequestSpec object

Now, we can hydrate the RequestSpec object directly in the conductor and modify
the Scheduler client to primitive it before calling the RPC API.

Later changes will focus on modifying the scheduler.utils methods to play with
RequestSpec object (and possibly kick build_request_spec) but this can be done
on separate changes for cleaning that up.

NOTE: There is an ugly hack hidden in that change because of a bug
in oslo.messaging which doesn't accept datetime type for values. That will be
removed right in the next patch of the branch. Yeah, I know it's bad but it's
very temporary.

Change-Id: I916707d4dee66608e0bf7cd2d0784dafbfecda38
Partially-Implements: blueprint request-spec-object-mitaka
This commit is contained in:
Sylvain Bauza 2015-07-17 17:20:57 +02:00 committed by Nikola Dipanov
parent 79d6af9508
commit b67d62399b
9 changed files with 139 additions and 48 deletions

View File

@ -398,8 +398,11 @@ class ComputeTaskManager(base.Base):
def _schedule_instances(self, context, request_spec, filter_properties):
scheduler_utils.setup_instance_group(context, request_spec,
filter_properties)
hosts = self.scheduler_client.select_destinations(context,
request_spec, filter_properties)
# TODO(sbauza): Hydrate here the object until we modify the
# scheduler.utils methods to directly use the RequestSpec object
spec_obj = objects.RequestSpec.from_primitives(
context, request_spec, filter_properties)
hosts = self.scheduler_client.select_destinations(context, spec_obj)
return hosts
def unshelve_instance(self, context, instance):

View File

@ -173,8 +173,12 @@ class LiveMigrationTask(base.TaskBase):
filter_properties = {'ignore_hosts': attempted_hosts}
scheduler_utils.setup_instance_group(self.context, request_spec,
filter_properties)
# TODO(sbauza): Hydrate here the object until we modify the
# scheduler.utils methods to directly use the RequestSpec object
spec_obj = objects.RequestSpec.from_primitives(
self.context, request_spec, filter_properties)
host = self.scheduler_client.select_destinations(self.context,
request_spec, filter_properties)[0]['host']
spec_obj)[0]['host']
try:
self._check_compatible_with_source_hypervisor(host)
self._call_livem_checks_on_host(host)

View File

@ -39,8 +39,12 @@ class MigrationTask(base.TaskBase):
self.filter_properties)
scheduler_utils.populate_retry(self.filter_properties,
self.instance.uuid)
hosts = self.scheduler_client.select_destinations(
# TODO(sbauza): Hydrate here the object until we modify the
# scheduler.utils methods to directly use the RequestSpec object
spec_obj = objects.RequestSpec.from_primitives(
self.context, self.request_spec, self.filter_properties)
hosts = self.scheduler_client.select_destinations(
self.context, spec_obj)
host_state = hosts[0]
scheduler_utils.populate_filter_properties(self.filter_properties,

View File

@ -47,9 +47,8 @@ class SchedulerClient(object):
'nova.scheduler.client.report.SchedulerReportClient'))
@utils.retry_select_destinations
def select_destinations(self, context, request_spec, filter_properties):
return self.queryclient.select_destinations(
context, request_spec, filter_properties)
def select_destinations(self, context, spec_obj):
return self.queryclient.select_destinations(context, spec_obj)
def update_aggregates(self, context, aggregates):
self.queryclient.update_aggregates(context, aggregates)

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_serialization import jsonutils
from nova.scheduler import rpcapi as scheduler_rpcapi
@ -23,15 +24,27 @@ class SchedulerQueryClient(object):
def __init__(self):
self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
def select_destinations(self, context, request_spec, filter_properties):
def select_destinations(self, context, spec_obj):
"""Returns destinations(s) best suited for this request_spec and
filter_properties.
The result should be a list of dicts with 'host', 'nodename' and
'limits' as keys.
"""
return self.scheduler_rpcapi.select_destinations(
context, request_spec, filter_properties)
# TODO(sbauza): Provide directly the RequestSpec object as an arg
# once the RPC API is modified for that.
request_spec = spec_obj.to_legacy_request_spec_dict()
filter_properties = spec_obj.to_legacy_filter_properties_dict()
# FIXME(sbauza): Serialize/Unserialize the legacy dict because of
# oslo.messaging #1529084 to transform datetime values into strings.
# tl;dr: datetimes in dicts are not accepted as correct values by the
# rpc fake driver.
# will be removed in the next patch of that series.
# Yeah, that's an ugly hack I know, but that's only for not squashing
# both commits.
request_spec = jsonutils.loads(jsonutils.dumps(request_spec))
return self.scheduler_rpcapi.select_destinations(context, request_spec,
filter_properties)
def update_aggregates(self, context, aggregates):
"""Updates HostManager internal aggregates information.

View File

@ -252,6 +252,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -264,8 +265,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(
self.context, fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")
self.task._call_livem_checks_on_host("host1")
@ -278,6 +283,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -290,8 +296,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")
self.task._call_livem_checks_on_host("host1")
@ -303,6 +313,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -315,16 +326,21 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, {}, mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")\
.AndRaise(error)
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]})
objects.RequestSpec.from_primitives(
self.context, {}, mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host2'}])
self.task._check_compatible_with_source_hypervisor("host2")
self.task._call_livem_checks_on_host("host2")
@ -345,6 +361,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -357,8 +374,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")
self.task._call_livem_checks_on_host("host1")\
@ -366,8 +387,11 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]})
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host2'}])
self.task._check_compatible_with_source_hypervisor("host2")
self.task._call_livem_checks_on_host("host2")
@ -380,6 +404,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -392,8 +417,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")
self.task._call_livem_checks_on_host("host1")\
@ -401,8 +430,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host, "host1"]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host2'}])
self.task._check_compatible_with_source_hypervisor("host2")
self.task._call_livem_checks_on_host("host2")
@ -415,6 +448,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
self.mox.StubOutWithMock(self.task,
@ -426,8 +460,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context, mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
fake_spec).AndReturn(
[{'host': 'host1'}])
self.task._check_compatible_with_source_hypervisor("host1")\
.AndRaise(exception.DestinationHypervisorTooOld)
@ -443,6 +481,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(utils, 'get_image_from_system_metadata')
self.mox.StubOutWithMock(scheduler_utils, 'build_request_spec')
self.mox.StubOutWithMock(scheduler_utils, 'setup_instance_group')
self.mox.StubOutWithMock(objects.RequestSpec, 'from_primitives')
self.mox.StubOutWithMock(self.task.scheduler_client,
'select_destinations')
utils.get_image_from_system_metadata(
@ -451,8 +490,12 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
mox.IgnoreArg()).AndReturn({})
scheduler_utils.setup_instance_group(
self.context, {}, {'ignore_hosts': [self.instance_host]})
fake_spec = objects.RequestSpec()
objects.RequestSpec.from_primitives(
self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(fake_spec)
self.task.scheduler_client.select_destinations(self.context,
mox.IgnoreArg(), mox.IgnoreArg()).AndRaise(
fake_spec).AndRaise(
exception.NoValidHost(reason=""))
self.mox.ReplayAll()

View File

@ -55,12 +55,15 @@ class MigrationTaskTestCase(test.NoDBTestCase):
@mock.patch.object(scheduler_utils, 'build_request_spec')
@mock.patch.object(scheduler_utils, 'setup_instance_group')
@mock.patch.object(objects.RequestSpec, 'from_primitives')
@mock.patch.object(scheduler_client.SchedulerClient, 'select_destinations')
@mock.patch.object(compute_rpcapi.ComputeAPI, 'prep_resize')
@mock.patch.object(objects.Quotas, 'from_reservations')
def test_execute(self, quotas_mock, prep_resize_mock,
sel_dest_mock, sig_mock, brs_mock):
sel_dest_mock, spec_fp_mock, sig_mock, brs_mock):
brs_mock.return_value = self.request_spec
fake_spec = objects.RequestSpec()
spec_fp_mock.return_value = fake_spec
sel_dest_mock.return_value = self.hosts
task = self._generate_task()
@ -71,7 +74,7 @@ class MigrationTaskTestCase(test.NoDBTestCase):
sig_mock.assert_called_once_with(self.context, self.request_spec,
self.filter_properties)
task.scheduler_client.select_destinations.assert_called_once_with(
self.context, self.request_spec, self.filter_properties)
self.context, fake_spec)
prep_resize_mock.assert_called_once_with(
self.context, 'image', self.instance, self.flavor,
self.hosts[0]['host'], self.reservations,

View File

@ -818,12 +818,14 @@ class _BaseTaskTestCase(object):
{'host': None, 'node': expected_node, 'limits': expected_limits})
request_spec = {}
filter_properties = {'ignore_hosts': [(inst_obj.host)]}
fake_spec = objects.RequestSpec()
with test.nested(
mock.patch.object(self.conductor_manager.compute_rpcapi,
'rebuild_instance'),
mock.patch.object(scheduler_utils, 'setup_instance_group',
return_value=False),
mock.patch.object(objects.RequestSpec, 'from_primitives',
return_value=fake_spec),
mock.patch.object(self.conductor_manager.scheduler_client,
'select_destinations',
return_value=[{'host': expected_host,
@ -831,13 +833,13 @@ class _BaseTaskTestCase(object):
'limits': expected_limits}]),
mock.patch('nova.scheduler.utils.build_request_spec',
return_value=request_spec)
) as (rebuild_mock, sig_mock, select_dest_mock, bs_mock):
) as (rebuild_mock, sig_mock, fp_mock, select_dest_mock, bs_mock):
self.conductor_manager.rebuild_instance(context=self.context,
instance=inst_obj,
**rebuild_args)
select_dest_mock.assert_called_once_with(self.context,
request_spec,
filter_properties)
fp_mock.assert_called_once_with(self.context, request_spec,
filter_properties)
select_dest_mock.assert_called_once_with(self.context, fake_spec)
compute_args['host'] = expected_host
rebuild_mock.assert_called_once_with(self.context,
instance=inst_obj,
@ -851,25 +853,28 @@ class _BaseTaskTestCase(object):
rebuild_args, _ = self._prepare_rebuild_args({'host': None})
request_spec = {}
filter_properties = {'ignore_hosts': [(inst_obj.host)]}
fake_spec = objects.RequestSpec()
with test.nested(
mock.patch.object(self.conductor_manager.compute_rpcapi,
'rebuild_instance'),
mock.patch.object(scheduler_utils, 'setup_instance_group',
return_value=False),
mock.patch.object(objects.RequestSpec, 'from_primitives',
return_value=fake_spec),
mock.patch.object(self.conductor_manager.scheduler_client,
'select_destinations',
side_effect=exc.NoValidHost(reason='')),
mock.patch('nova.scheduler.utils.build_request_spec',
return_value=request_spec)
) as (rebuild_mock, sig_mock, select_dest_mock, bs_mock):
) as (rebuild_mock, sig_mock, fp_mock, select_dest_mock, bs_mock):
self.assertRaises(exc.NoValidHost,
self.conductor_manager.rebuild_instance,
context=self.context, instance=inst_obj,
**rebuild_args)
select_dest_mock.assert_called_once_with(self.context,
request_spec,
filter_properties)
fp_mock.assert_called_once_with(self.context, request_spec,
filter_properties)
select_dest_mock.assert_called_once_with(self.context, fake_spec)
self.assertFalse(rebuild_mock.called)
@mock.patch('nova.utils.spawn_n')
@ -1087,6 +1092,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(scheduler_utils, 'build_request_spec')
@mock.patch.object(scheduler_utils, 'setup_instance_group')
@mock.patch.object(objects.RequestSpec, 'from_primitives')
@mock.patch.object(utils, 'get_image_from_system_metadata')
@mock.patch.object(objects.Quotas, 'from_reservations')
@mock.patch.object(scheduler_client.SchedulerClient, 'select_destinations')
@ -1095,7 +1101,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(migrate.MigrationTask, 'rollback')
def test_cold_migrate_no_valid_host_back_in_active_state(
self, rollback_mock, notify_mock, select_dest_mock, quotas_mock,
metadata_mock, sig_mock, brs_mock):
metadata_mock, spec_fp_mock, sig_mock, brs_mock):
flavor = flavors.get_flavor_by_name('m1.tiny')
inst_obj = objects.Instance(
image_ref='fake-image_ref',
@ -1109,8 +1115,10 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
filter_props = dict(context=None)
resvs = 'fake-resvs'
image = 'fake-image'
fake_spec = objects.RequestSpec()
metadata_mock.return_value = image
brs_mock.return_value = request_spec
spec_fp_mock.return_value = fake_spec
exc_info = exc.NoValidHost(reason="")
select_dest_mock.side_effect = exc_info
updates = {'vm_state': vm_states.ACTIVE,
@ -1135,6 +1143,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(scheduler_utils, 'build_request_spec')
@mock.patch.object(scheduler_utils, 'setup_instance_group')
@mock.patch.object(objects.RequestSpec, 'from_primitives')
@mock.patch.object(utils, 'get_image_from_system_metadata')
@mock.patch.object(objects.Quotas, 'from_reservations')
@mock.patch.object(scheduler_client.SchedulerClient, 'select_destinations')
@ -1143,7 +1152,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(migrate.MigrationTask, 'rollback')
def test_cold_migrate_no_valid_host_back_in_stopped_state(
self, rollback_mock, notify_mock, select_dest_mock, quotas_mock,
metadata_mock, sig_mock, brs_mock):
metadata_mock, spec_fp_mock, sig_mock, brs_mock):
flavor = flavors.get_flavor_by_name('m1.tiny')
inst_obj = objects.Instance(
image_ref='fake-image_ref',
@ -1158,9 +1167,11 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
image=image)
filter_props = dict(context=None)
resvs = 'fake-resvs'
fake_spec = objects.RequestSpec()
metadata_mock.return_value = image
brs_mock.return_value = request_spec
spec_fp_mock.return_value = fake_spec
exc_info = exc.NoValidHost(reason="")
select_dest_mock.side_effect = exc_info
updates = {'vm_state': vm_states.STOPPED,
@ -1259,6 +1270,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(scheduler_utils, 'build_request_spec')
@mock.patch.object(scheduler_utils, 'setup_instance_group')
@mock.patch.object(objects.RequestSpec, 'from_primitives')
@mock.patch.object(utils, 'get_image_from_system_metadata')
@mock.patch.object(objects.Quotas, 'from_reservations')
@mock.patch.object(scheduler_client.SchedulerClient, 'select_destinations')
@ -1268,7 +1280,8 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
@mock.patch.object(compute_rpcapi.ComputeAPI, 'prep_resize')
def test_cold_migrate_exception_host_in_error_state_and_raise(
self, prep_resize_mock, rollback_mock, notify_mock,
select_dest_mock, quotas_mock, metadata_mock, sig_mock, brs_mock):
select_dest_mock, quotas_mock, metadata_mock, spec_fp_mock,
sig_mock, brs_mock):
flavor = flavors.get_flavor_by_name('m1.tiny')
inst_obj = objects.Instance(
image_ref='fake-image_ref',
@ -1283,10 +1296,12 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
image=image)
filter_props = dict(context=None)
resvs = 'fake-resvs'
fake_spec = objects.RequestSpec()
hosts = [dict(host='host1', nodename=None, limits={})]
metadata_mock.return_value = image
brs_mock.return_value = request_spec
spec_fp_mock.return_value = fake_spec
exc_info = test.TestingException('something happened')
select_dest_mock.return_value = hosts
@ -1308,7 +1323,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
sig_mock.assert_called_once_with(self.context, request_spec,
filter_props)
select_dest_mock.assert_called_once_with(
self.context, request_spec, filter_props)
self.context, fake_spec)
prep_resize_mock.assert_called_once_with(
self.context, image, inst_obj, flavor,
hosts[0]['host'], [resvs],
@ -1424,11 +1439,13 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
side_effect=exc.InstanceInfoCacheNotFound(
instance_uuid=instances[0].uuid)),
mock.patch.object(instances[1], 'refresh'),
mock.patch.object(objects.RequestSpec, 'from_primitives'),
mock.patch.object(self.conductor_manager.scheduler_client,
'select_destinations', return_value=destinations),
mock.patch.object(self.conductor_manager.compute_rpcapi,
'build_and_run_instance')
) as (inst1_refresh, inst2_refresh, select_destinations,
) as (inst1_refresh, inst2_refresh, from_primitives,
select_destinations,
build_and_run_instance):
# build_instances() is a cast, we need to wait for it to complete

View File

@ -62,17 +62,20 @@ class SchedulerQueryClientTestCase(test.NoDBTestCase):
def test_constructor(self):
self.assertIsNotNone(self.client.scheduler_rpcapi)
@mock.patch.object(objects.RequestSpec, 'to_legacy_filter_properties_dict')
@mock.patch.object(objects.RequestSpec, 'to_legacy_request_spec_dict')
@mock.patch.object(scheduler_rpcapi.SchedulerAPI, 'select_destinations')
def test_select_destinations(self, mock_select_destinations):
def test_select_destinations(self, mock_select_destinations, to_spec,
to_props):
fake_spec = objects.RequestSpec()
to_spec.return_value = 'fake_request_spec'
to_props.return_value = 'fake_props'
self.client.select_destinations(
context=self.context,
request_spec='fake_request_spec',
filter_properties='fake_prop'
spec_obj=fake_spec
)
mock_select_destinations.assert_called_once_with(
self.context,
'fake_request_spec',
'fake_prop')
self.context, 'fake_request_spec', 'fake_props')
@mock.patch.object(scheduler_rpcapi.SchedulerAPI, 'update_aggregates')
def test_update_aggregates(self, mock_update_aggs):
@ -106,20 +109,21 @@ class SchedulerClientTestCase(test.NoDBTestCase):
@mock.patch.object(scheduler_query_client.SchedulerQueryClient,
'select_destinations')
def test_select_destinations(self, mock_select_destinations):
fake_spec = objects.RequestSpec()
self.assertIsNone(self.client.queryclient.instance)
self.client.select_destinations('ctxt', 'fake_spec', 'fake_prop')
self.client.select_destinations('ctxt', fake_spec)
self.assertIsNotNone(self.client.queryclient.instance)
mock_select_destinations.assert_called_once_with(
'ctxt', 'fake_spec', 'fake_prop')
mock_select_destinations.assert_called_once_with('ctxt', fake_spec)
@mock.patch.object(scheduler_query_client.SchedulerQueryClient,
'select_destinations',
side_effect=messaging.MessagingTimeout())
def test_select_destinations_timeout(self, mock_select_destinations):
# check if the scheduler service times out properly
fake_args = ['ctxt', 'fake_spec', 'fake_prop']
fake_spec = objects.RequestSpec()
fake_args = ['ctxt', fake_spec]
self.assertRaises(messaging.MessagingTimeout,
self.client.select_destinations, *fake_args)
mock_select_destinations.assert_has_calls([mock.call(*fake_args)] * 2)
@ -129,7 +133,8 @@ class SchedulerClientTestCase(test.NoDBTestCase):
messaging.MessagingTimeout(), mock.DEFAULT])
def test_select_destinations_timeout_once(self, mock_select_destinations):
# scenario: the scheduler service times out & recovers after failure
fake_args = ['ctxt', 'fake_spec', 'fake_prop']
fake_spec = objects.RequestSpec()
fake_args = ['ctxt', fake_spec]
self.client.select_destinations(*fake_args)
mock_select_destinations.assert_has_calls([mock.call(*fake_args)] * 2)