def test_destroy_with_traits(self): """Test deleting a resource provider that has a trait successfully. """ rp = resource_provider.ResourceProvider(self.context, uuid=uuids.rp, name='fake_rp1') rp.create() custom_trait = resource_provider.Trait(self.context, uuid=uuids.trait, name='CUSTOM_TRAIT_1') custom_trait.create() rp.set_traits([custom_trait]) trl = resource_provider.TraitList.get_all_by_resource_provider( self.context, rp) self.assertEqual(1, len(trl)) # Delete a resource provider that has a trait assosiation. rp.destroy() # Assert the record has been deleted # in 'resource_provider_traits' table # after Resource Provider object has been destroyed. trl = resource_provider.TraitList.get_all_by_resource_provider( self.context, rp) self.assertEqual(0, len(trl)) # Assert that NotFound exception is raised. self.assertRaises(exception.NotFound, resource_provider.ResourceProvider.get_by_uuid, self.context, uuids.rp)
def put_trait(req): context = req.environ['placement.context'] want_version = req.environ[microversion.MICROVERSION_ENVIRON] name = util.wsgi_path_item(req.environ, 'name') try: jsonschema.validate(name, schema.CUSTOM_TRAIT) except jsonschema.ValidationError: raise webob.exc.HTTPBadRequest( _('The trait is invalid. A valid trait must be no longer than ' '255 characters, start with the prefix "CUSTOM_" and use ' 'following characters: "A"-"Z", "0"-"9" and "_"')) trait = rp_obj.Trait(context) trait.name = name try: trait.create() req.response.status = 201 except exception.TraitExists: # Get the trait that already exists to get last-modified time. if want_version.matches((1, 15)): trait = rp_obj.Trait.get_by_name(context, name) req.response.status = 204 req.response.content_type = None req.response.location = util.trait_url(req.environ, trait) if want_version.matches((1, 15)): req.response.last_modified = trait.created_at req.response.cache_control = 'no-cache' return req.response
def test_set_traits_resets_changes(self, mock_set_traits, mock_reset): trait = resource_provider.Trait(name="HW_CPU_X86_AVX2") traits = resource_provider.TraitList(objects=[trait]) rp = resource_provider.ResourceProvider(self.context, name='cn1', uuid=uuids.cn1) rp.set_traits(traits) mock_set_traits.assert_called_once_with(self.context, rp, traits) mock_reset.assert_called_once_with()
def _set_traits(rp, *traits): tlist = [] for tname in traits: try: trait = rp_obj.Trait.get_by_name(rp._context, tname) except exception.TraitNotFound: trait = rp_obj.Trait(rp._context, name=tname) trait.create() tlist.append(trait) rp.set_traits(rp_obj.TraitList(objects=tlist))
def test_get_provider_ids_having_all_traits(self): def run(traitnames, expected_ids): tmap = {} if traitnames: tmap = rp_obj._trait_ids_from_names(self.ctx, traitnames) obs = rp_obj._get_provider_ids_having_all_traits(self.ctx, tmap) self.assertEqual(sorted(expected_ids), sorted(obs)) # No traits. This will never be returned, because it's illegal to # invoke the method with no traits. self._create_provider('one') # One trait rp2 = self._create_provider('two') _set_traits(rp2, 'HW_CPU_X86_TBM') # One the same as rp2 rp3 = self._create_provider('three') _set_traits(rp3, 'HW_CPU_X86_TBM', 'HW_CPU_X86_TSX', 'HW_CPU_X86_SGX') # Disjoint rp4 = self._create_provider('four') _set_traits(rp4, 'HW_CPU_X86_SSE2', 'HW_CPU_X86_SSE3', 'CUSTOM_FOO') # Request with no traits not allowed self.assertRaises( ValueError, rp_obj._get_provider_ids_having_all_traits, self.ctx, None) self.assertRaises( ValueError, rp_obj._get_provider_ids_having_all_traits, self.ctx, {}) # Common trait returns both RPs having it run(['HW_CPU_X86_TBM'], [rp2.id, rp3.id]) # Just the one run(['HW_CPU_X86_TSX'], [rp3.id]) run(['HW_CPU_X86_TSX', 'HW_CPU_X86_SGX'], [rp3.id]) run(['CUSTOM_FOO'], [rp4.id]) # Including the common one still just gets me rp3 run(['HW_CPU_X86_TBM', 'HW_CPU_X86_SGX'], [rp3.id]) run(['HW_CPU_X86_TBM', 'HW_CPU_X86_TSX', 'HW_CPU_X86_SGX'], [rp3.id]) # Can't be satisfied run(['HW_CPU_X86_TBM', 'HW_CPU_X86_TSX', 'CUSTOM_FOO'], []) run(['HW_CPU_X86_TBM', 'HW_CPU_X86_TSX', 'HW_CPU_X86_SGX', 'CUSTOM_FOO'], []) run(['HW_CPU_X86_SGX', 'HW_CPU_X86_SSE3'], []) run(['HW_CPU_X86_TBM', 'CUSTOM_FOO'], []) run(['HW_CPU_X86_BMI'], []) rp_obj.Trait(self.ctx, name='CUSTOM_BAR').create() run(['CUSTOM_BAR'], [])
def put_trait(req): context = req.environ['placement.context'] name = util.wsgi_path_item(req.environ, 'name') try: jsonschema.validate(name, CUSTOM_TRAIT) except jsonschema.ValidationError: raise webob.exc.HTTPBadRequest( _('The trait is invalid. A valid trait must include prefix ' '"CUSTOM_" and use following characters: "A"-"Z", "0"-"9" and ' '"_"')) trait = rp_obj.Trait(context) trait.name = name try: trait.create() req.response.status = 201 except exception.TraitExists: req.response.status = 204 req.response.content_type = None req.response.location = util.trait_url(req.environ, trait) return req.response