Example #1
0
    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)
Example #2
0
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
Example #3
0
    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()
Example #4
0
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'], [])
Example #6
0
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