def test_obj_make_compatible_pmu(self): """Tests that checks if we pop hw_pmu.""" obj = objects.ImageMetaProps(hw_pmu=True) primitive = obj.obj_to_primitive() old_primitive = obj.obj_to_primitive('1.22') self.assertIn('hw_pmu', primitive['nova_object.data']) self.assertNotIn('hw_pmu', old_primitive['nova_object.data'])
def test_isolate_agg_trait_on_flv_img_destination_not_set( self, mock_getnotmd): mock_getnotmd.return_value = [] flavor_traits = set(['HW_GPU_API_DXVA']) image_traits = set(['HW_NIC_DCB_ETS']) fake_flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0, extra_specs={ 'trait:' + trait: 'required' for trait in flavor_traits }) fake_image = objects.ImageMeta(properties=objects.ImageMetaProps( traits_required=[trait for trait in image_traits])) reqspec = objects.RequestSpec(flavor=fake_flavor, image=fake_image) result = request_filter.isolate_aggregates(self.context, reqspec) self.assertTrue(result) self.assertNotIn('requested_destination', reqspec) keys = [ 'trait:%s' % trait for trait in flavor_traits.union(image_traits) ] mock_getnotmd.assert_called_once_with(self.context, utils.ItemsMatcher(keys), 'trait:', value='required')
def test_isolate_aggregates(self, mock_getnotmd): agg4_traits = { 'trait:HW_GPU_API_DXVA': 'required', 'trait:HW_NIC_DCB_ETS': 'required' } mock_getnotmd.return_value = [ objects.Aggregate( uuid=uuids.agg1, metadata={'trait:CUSTOM_WINDOWS_LICENSED_TRAIT': 'required'}), objects.Aggregate(uuid=uuids.agg2, metadata={ 'trait:CUSTOM_WINDOWS_LICENSED_TRAIT': 'required', 'trait:CUSTOM_XYZ_TRAIT': 'required' }), objects.Aggregate(uuid=uuids.agg4, metadata=agg4_traits), ] fake_flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0, extra_specs=agg4_traits) fake_image = objects.ImageMeta(properties=objects.ImageMetaProps( traits_required=[])) reqspec = objects.RequestSpec(flavor=fake_flavor, image=fake_image) result = request_filter.isolate_aggregates(self.context, reqspec) self.assertTrue(result) self.assertItemsEqual( set([uuids.agg1, uuids.agg2, uuids.agg4]), reqspec.requested_destination.forbidden_aggregates) mock_getnotmd.assert_called_once_with(self.context, utils.ItemsMatcher(agg4_traits), 'trait:', value='required')
def test_obj_make_compatible(self): props = { 'hw_firmware_type': 'uefi', 'hw_cpu_realtime_mask': '^0-1', 'hw_cpu_thread_policy': 'prefer', 'img_config_drive': 'mandatory', 'os_admin_user': '******', 'hw_vif_multiqueue_enabled': True, 'img_hv_type': 'kvm', 'img_hv_requested_version': '>= 1.0', 'os_require_quiesce': True, 'os_secure_boot': 'required', 'hw_rescue_bus': 'ide', 'hw_rescue_device': 'disk', 'hw_watchdog_action': fields.WatchdogAction.DISABLED, } obj = objects.ImageMetaProps(**props) primitive = obj.obj_to_primitive('1.0') self.assertFalse( any([x in primitive['nova_object.data'] for x in props])) for bus in ('lxc', 'uml'): obj.hw_disk_bus = bus self.assertRaises(exception.ObjectActionError, obj.obj_to_primitive, '1.0')
def test_select_destination_with_old_client(self, from_primitives, mock_get_ac, mock_rfrs): fake_spec = objects.RequestSpec( flavor=objects.Flavor(vcpus=1, extra_specs={}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), numa_topology=None) fake_spec.instance_uuid = uuids.instance from_primitives.return_value = fake_spec place_res = (fakes.ALLOC_REQS, mock.sentinel.p_sums) mock_get_ac.return_value = place_res expected_alloc_reqs_by_rp_uuid = { cn.uuid: [fakes.ALLOC_REQS[x]] for x, cn in enumerate(fakes.COMPUTE_NODES) } with mock.patch.object(self.manager.driver, 'select_destinations') as select_destinations: self.manager.select_destinations( None, request_spec='fake_spec', filter_properties='fake_props', instance_uuids=[fake_spec.instance_uuid]) select_destinations.assert_called_once_with( None, fake_spec, [fake_spec.instance_uuid], expected_alloc_reqs_by_rp_uuid, mock.sentinel.p_sums) mock_get_ac.assert_called_once_with(mock_rfrs.return_value)
def test_select_destinations_fewer_num_instances(self, mock_schedule, mock_get_all): """Tests that the select_destinations() method properly handles resetting host state objects and raising NoValidHost when the _schedule() method returns no host matches. """ spec_obj = objects.RequestSpec( flavor=objects.Flavor(memory_mb=512, root_gb=512, ephemeral_gb=0, swap=0, vcpus=1, extra_specs={}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), numa_topology=objects.InstanceNUMATopology( cells=[objects.InstanceNUMACell(id=0, cpuset=set([1]), memory=512), ]), project_id=uuids.project_id, num_instances=2) host_state = mock.Mock(spec=host_manager.HostState) mock_schedule.return_value = [host_state] self.assertRaises(exception.NoValidHost, self.driver.select_destinations, self.context, spec_obj, [mock.sentinel.instance_uuid1, mock.sentinel.instance_uuid2], mock.sentinel.alloc_reqs_by_rp_uuid, mock.sentinel.p_sums) # Verify that the host state object has been marked as not updated so # it's picked up in the next pull from the DB for compute node objects self.assertIsNone(host_state.updated)
def _get_fake_request_spec(self): # NOTE(sbauza): Prevent to stub the Flavor.get_by_id call just by # directly providing a Flavor object flavor = objects.Flavor( flavorid="small", memory_mb=512, root_gb=1, ephemeral_gb=1, vcpus=1, swap=0, extra_specs={}, ) image_props = objects.ImageMeta(properties=objects.ImageMetaProps()) instance_properties = { "os_type": "linux", "project_id": "1234", } request_spec = objects.RequestSpec( flavor=flavor, num_instances=1, ignore_hosts=None, force_hosts=None, force_nodes=None, retry=None, availability_zone=None, image=image_props, instance_group=None, pci_requests=None, numa_topology=None, instance_uuid='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', # WRS extension display_name='fake-vm', name='instance-00000001', **instance_properties) return request_spec
def _get_spec_obj(self, numa_topology): image_meta = objects.ImageMeta(properties=objects.ImageMetaProps()) spec_obj = objects.RequestSpec(numa_topology=numa_topology, pci_requests=None, instance_uuid=uuids.fake, flavor=objects.Flavor(extra_specs={}), image=image_meta) return spec_obj
def test_vcpu_model_not_specified(self): spec_obj = objects.RequestSpec( flavor=objects.Flavor(memory_mb=1024, extra_specs={}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), scheduler_hints={'task_state': ['scheduling'], 'host': ['host1'], 'node': ['node1']}) host = fakes.FakeHostState('host1', 'node1', {}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_generic_get_deploy_patch_image_flavor_traits_none(self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps() expected = self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_obj_bochs_model_positive(self): """Test "bochs" support from Nova object version 1.30 onwards """ obj = objects.ImageMetaProps( hw_video_model=objects.fields.VideoModel.BOCHS, ) primitive = obj.obj_to_primitive('1.30') self.assertEqual(objects.fields.VideoModel.BOCHS, primitive['nova_object.data']['hw_video_model'])
def test_aggregate_image_properties_isolation_props_with_meta_passes( self, agg_mock): agg_mock.return_value = {'hw_vm_mode': 'hvm'} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps())) host = fakes.FakeHostState('host1', 'compute', {}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def _do_test_numa_topology_filter_cpu_policy( self, numa_topology, cpu_policy, cpu_thread_policy, passes): instance_topology = objects.InstanceNUMATopology(cells=[ objects.InstanceNUMACell( id=0, cpuset=set([1]), memory=512, cpu_policy=cpu_policy, cpu_thread_policy=cpu_thread_policy, ), objects.InstanceNUMACell( id=1, cpuset=set([3]), memory=512, cpu_policy=cpu_policy, cpu_thread_policy=cpu_thread_policy, ), ]) spec_obj = objects.RequestSpec(numa_topology=instance_topology, pci_requests=None, instance_uuid=uuids.fake) extra_specs = [ {}, { 'hw:cpu_policy': cpu_policy, 'hw:cpu_thread_policy': cpu_thread_policy, } ] image_props = [ {}, { 'hw_cpu_policy': cpu_policy, 'hw_cpu_thread_policy': cpu_thread_policy, } ] host = fakes.FakeHostState('host1', 'node1', { 'numa_topology': numa_topology, 'pci_stats': None, 'cpu_allocation_ratio': 1, 'ram_allocation_ratio': 1.5}) assertion = self.assertTrue if passes else self.assertFalse # test combinations of image properties and extra specs for specs, props in itertools.product(extra_specs, image_props): # ...except for the one where no policy is specified if specs == props == {}: continue fake_flavor = objects.Flavor(memory_mb=1024, extra_specs=specs) fake_image_props = objects.ImageMetaProps(**props) fake_image = objects.ImageMeta(properties=fake_image_props) spec_obj.image = fake_image spec_obj.flavor = fake_flavor assertion(self.filt_cls.host_passes(host, spec_obj)) self.assertIsNone(spec_obj.numa_topology.cells[0].cpu_pinning)
def test_aggregate_image_properties_isolation_props_not_match2_fails( self, agg_mock): agg_mock.return_value = {'hw_vm_mode': 'hvm', 'hw_cpu_cores': '1'} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps( hw_vm_mode='hvm', hw_cpu_cores=2))) host = fakes.FakeHostState('host1', 'compute', {}) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_vcpu_model_flavor_fails(self): spec_obj = objects.RequestSpec( flavor=objects.Flavor(extra_specs={'hw:cpu_model': 'Nehalem'}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), scheduler_hints={'task_state': ['scheduling'], 'host': ['host1'], 'node': ['node1']}) host = fakes.FakeHostState('host1', 'node1', {'cpu_info': '{"model": "Conroe"}'}) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_obj_bochs_model_negative(self): """Make sure an exception is raised for Nova object version < 1.30 """ obj = objects.ImageMetaProps( hw_video_model=objects.fields.VideoModel.BOCHS, ) ex = self.assertRaises(exception.ObjectActionError, obj.obj_to_primitive, '1.29') self.assertIn('hw_video_model=bochs not supported', str(ex))
def test_passthrough_vcpu_model_flavor_passes(self): spec_obj = objects.RequestSpec( flavor=objects.Flavor(extra_specs={'hw:cpu_model': 'Passthrough'}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), scheduler_hints={'task_state': ['scheduling'], 'host': ['host1'], 'node': ['node1']}) host = fakes.FakeHostState('host1', 'node1', {'cpu_info': '{"model": "Broadwell", "features": ["vmx"]}'}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_aggregate_image_properties_isolation_props_bad_comma( self, agg_mock): agg_mock.return_value = {'os_distro': set(['windows', 'linux'])} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps( os_distro='windows,'))) host = fakes.FakeHostState('host1', 'compute', {}) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_aggregate_image_properties_iso_props_with_custom_meta( self, agg_mock): agg_mock.return_value = {'os': set(['linux'])} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps( os_type='linux'))) host = fakes.FakeHostState('host1', 'compute', {}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_aggregate_image_properties_iso_props_with_matching_meta_fail( self, agg_mock): agg_mock.return_value = {'os_type': 'windows'} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps( os_type='linux'))) host = fakes.FakeHostState('host1', 'compute', {}) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_obj_make_compatible_watchdog_action_not_disabled(self): """Tests that we don't pop the hw_watchdog_action if the value is not 'disabled'. """ obj = objects.ImageMetaProps( hw_watchdog_action=fields.WatchdogAction.PAUSE) primitive = obj.obj_to_primitive('1.0') self.assertIn('hw_watchdog_action', primitive['nova_object.data']) self.assertEqual(fields.WatchdogAction.PAUSE, primitive['nova_object.data']['hw_watchdog_action'])
def test_vcpu_model_image_passes(self): props = objects.ImageMetaProps(hw_cpu_model='Nehalem') spec_obj = objects.RequestSpec( flavor=objects.Flavor(memory_mb=1024, extra_specs={}), image=objects.ImageMeta(properties=props), scheduler_hints={'task_state': ['scheduling'], 'host': ['host1'], 'node': ['node1']}) host = fakes.FakeHostState('host1', 'node1', {'cpu_info': '{"model": "Broadwell"}'}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_schedule_unsuccessful_claim(self, mock_get_hosts, mock_get_all_states, mock_claim, mock_cleanup, mock_get_by_uuid, mock_get_by_instance_uuid): """Tests that we return an empty list if we are unable to successfully claim resources for the instance """ spec_obj = objects.RequestSpec( num_instances=1, flavor=objects.Flavor(memory_mb=512, root_gb=512, ephemeral_gb=0, swap=0, vcpus=1, extra_specs={}), project_id=uuids.project_id, instance_group=None, instance_uuid='00000000-aaaa-bbbb-cccc-000000000000', image=objects.ImageMeta(properties=objects.ImageMetaProps()), numa_topology=None) host_state = mock.Mock(spec=host_manager.HostState, host=mock.sentinel.host, uuid=uuids.cn1, numa_topology=None) all_host_states = [host_state] mock_get_all_states.return_value = all_host_states mock_get_hosts.return_value = all_host_states mock_claim.return_value = False instance_uuids = [uuids.instance] allocs = \ [{'allocations': [ {'resources': {'VCPU': 1, 'MEMORY_MB': 512, 'DISK_GB': 512}, 'resource_provider': {'uuid': uuids.cn1}} ] }] alloc_reqs_by_rp_uuid = { uuids.cn1: allocs, } ctx = mock.Mock() selected_hosts = self.driver._schedule(ctx, spec_obj, instance_uuids, alloc_reqs_by_rp_uuid, mock.sentinel.provider_summaries) mock_get_all_states.assert_called_once_with( ctx.elevated.return_value, spec_obj, mock.sentinel.provider_summaries) mock_get_hosts.assert_called_once_with(spec_obj, all_host_states, 0) mock_claim.assert_called_once_with(ctx.elevated.return_value, spec_obj, uuids.instance, allocs) self.assertEqual([], selected_hosts) mock_cleanup.assert_called_once_with([]) # Ensure that we have consumed the resources on the chosen host states self.assertFalse(host_state.consume_from_request.called)
def test_image_properties_filter_fails_partial_inst_props(self): img_props = objects.ImageMeta(properties=objects.ImageMetaProps( hw_architecture=arch.X86_64, hw_vm_mode=vm_mode.HVM)) hypervisor_version = versionutils.convert_version_to_int('6.0.0') spec_obj = objects.RequestSpec(image=img_props) capabilities = { 'supported_instances': [(arch.X86_64, hv_type.XEN, vm_mode.XEN)], 'hypervisor_version': hypervisor_version } host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_aggregate_image_properties_isolation_props_namespace( self, agg_mock): self.flags(aggregate_image_properties_isolation_namespace="hw") self.flags(aggregate_image_properties_isolation_separator="_") agg_mock.return_value = {'hw_vm_mode': 'hvm', 'img_owner_id': 'foo'} spec_obj = objects.RequestSpec( context=mock.sentinel.ctx, image=objects.ImageMeta(properties=objects.ImageMetaProps( hw_vm_mode='hvm', img_owner_id='wrong'))) host = fakes.FakeHostState('host1', 'compute', {}) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_passthrough_migrate_vcpu_model_flavor_passes(self): spec_obj = objects.RequestSpec( flavor=objects.Flavor(extra_specs={'hw:cpu_model': 'Passthrough'}), image=objects.ImageMeta(properties=objects.ImageMetaProps()), scheduler_hints={'task_state': ['migrating'], 'host': ['host1'], 'node': ['node1']}) host = fakes.FakeHostState('host1', 'node1', {'cpu_info': '{"model": "Broadwell", ' '"features": ["pge", "avx", "vmx"]}'}) self.stub_out('nova.objects.ComputeNode.get_by_host_and_nodename', self._fake_compute_node_get_by_host_and_nodename) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_image_properties_filter_xen_hv_type_compat(self): # if an old image has 'xapi' for hv_type it should be treated as xen img_props = objects.ImageMeta(properties=objects.ImageMetaProps( img_hv_type='xapi')) hypervisor_version = versionutils.convert_version_to_int('6.0.0') spec_obj = objects.RequestSpec(image=img_props) capabilities = { 'supported_instances': [(arch.I686, hv_type.XEN, vm_mode.HVM)], 'hypervisor_version': hypervisor_version } host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_obj_make_compatible_vtpm(self): """Test that checks if we pop hw_tpm_model and hw_tpm_version.""" obj = objects.ImageMetaProps( hw_tpm_model='tpm-tis', hw_tpm_version='1.2', ) primitive = obj.obj_to_primitive() self.assertIn('hw_tpm_model', primitive['nova_object.data']) self.assertIn('hw_tpm_version', primitive['nova_object.data']) primitive = obj.obj_to_primitive('1.26') self.assertNotIn('hw_tpm_model', primitive['nova_object.data']) self.assertNotIn('hw_tpm_version', primitive['nova_object.data'])
def test_image_properties_filter_fails_without_host_props(self): img_props = objects.ImageMeta( properties=objects.ImageMetaProps( hw_architecture=obj_fields.Architecture.X86_64, img_hv_type=obj_fields.HVType.KVM, hw_vm_mode=obj_fields.VMMode.HVM)) hypervisor_version = versionutils.convert_version_to_int('6.0.0') spec_obj = objects.RequestSpec(image=img_props) capabilities = { 'enabled': True, 'hypervisor_version': hypervisor_version} host = fakes.FakeHostState('host1', 'node1', capabilities) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_obj_make_compatible_input_bus(self): """Check 'hw_input_bus' compatibility.""" # assert that 'hw_input_bus' is supported on a suitably new version obj = objects.ImageMetaProps( hw_input_bus=objects.fields.InputBus.VIRTIO, ) primitive = obj.obj_to_primitive('1.29') self.assertIn('hw_input_bus', primitive['nova_object.data']) self.assertEqual(objects.fields.InputBus.VIRTIO, primitive['nova_object.data']['hw_input_bus']) # and is absent on older versions primitive = obj.obj_to_primitive('1.28') self.assertNotIn('hw_input_bus', primitive['nova_object.data'])