Пример #1
0
    def from_api(cls, api_dict, image_uuid_specified):
        """Transform the API format of data to the internally used one.

        Only validate if the source_type field makes sense.
        """
        if not api_dict.get('no_device'):

            source_type = api_dict.get('source_type')
            device_uuid = api_dict.get('uuid')
            destination_type = api_dict.get('destination_type')

            if source_type not in ('volume', 'image', 'snapshot', 'blank'):
                raise exception.InvalidBDMFormat(
                    details=_("Invalid source_type field."))
            elif source_type == 'blank' and device_uuid:
                raise exception.InvalidBDMFormat(
                    details=_("Invalid device UUID."))
            elif source_type != 'blank':
                if not device_uuid:
                    raise exception.InvalidBDMFormat(
                        details=_("Missing device UUID."))
                api_dict[source_type + '_id'] = device_uuid
            if source_type == 'image' and destination_type == 'local':
                boot_index = api_dict.get('boot_index', -1)

                # if this bdm is generated from --image ,then
                # source_type = image and destination_type = local is allowed
                if not (image_uuid_specified and boot_index == 0):
                    raise exception.InvalidBDMFormat(
                        details=_("Mapping image to local is not supported."))

        api_dict.pop('uuid', None)
        return cls(api_dict)
Пример #2
0
    def _validate(self, bdm_dict):
        """Basic data format validations."""
        dict_fields = set(key for key, _ in six.iteritems(bdm_dict))

        # Check that there are no bogus fields
        if not (dict_fields <=
                (self._fields | self._db_only_fields)):
            raise exception.InvalidBDMFormat(
                details=_("Some fields are invalid."))

        if bdm_dict.get('no_device'):
            return

        # Check that all required fields are there
        if (self._required_fields and
                not ((dict_fields & self._required_fields) ==
                      self._required_fields)):
            raise exception.InvalidBDMFormat(
                details=_("Some required fields are missing"))

        if 'delete_on_termination' in bdm_dict:
            bdm_dict['delete_on_termination'] = strutils.bool_from_string(
                bdm_dict['delete_on_termination'])

        if bdm_dict.get('device_name') is not None:
            validate_device_name(bdm_dict['device_name'])

        validate_and_default_volume_size(bdm_dict)

        if bdm_dict.get('boot_index'):
            try:
                bdm_dict['boot_index'] = int(bdm_dict['boot_index'])
            except ValueError:
                raise exception.InvalidBDMFormat(
                    details=_("Boot index is invalid."))
Пример #3
0
def validate_device_name(value):
    try:
        # NOTE (ndipanov): Do not allow empty device names
        #                  until assigning default values
        #                  is supported by nova.compute
        utils.check_string_length(value, 'Device name',
                                  min_length=1, max_length=255)
    except exception.InvalidInput:
        raise exception.InvalidBDMFormat(
            details=_("Device name empty or too long."))

    if ' ' in value:
        raise exception.InvalidBDMFormat(
            details=_("Device name contains spaces."))
Пример #4
0
    def from_api(cls, api_dict, image_uuid_specified):
        """Transform the API format of data to the internally used one.

        Only validate if the source_type field makes sense.
        """
        if not api_dict.get('no_device'):

            source_type = api_dict.get('source_type')
            device_uuid = api_dict.get('uuid')
            destination_type = api_dict.get('destination_type')
            volume_type = api_dict.get('volume_type')

            if source_type == 'blank' and device_uuid:
                raise exception.InvalidBDMFormat(
                    details=_("Invalid device UUID."))
            elif source_type != 'blank':
                if not device_uuid:
                    raise exception.InvalidBDMFormat(
                        details=_("Missing device UUID."))
                api_dict[source_type + '_id'] = device_uuid
            if source_type == 'image' and destination_type == 'local':
                # NOTE(mriedem): boot_index can be None so we need to
                # account for that to avoid a TypeError.
                boot_index = api_dict.get('boot_index', -1)
                if boot_index is None:
                    # boot_index=None is equivalent to -1.
                    boot_index = -1
                boot_index = int(boot_index)

                # if this bdm is generated from --image, then
                # source_type = image and destination_type = local is allowed
                # if not (image_uuid_specified and boot_index == 0):
                if not image_uuid_specified:
                    raise exception.InvalidBDMFormat(
                        details=_("Mapping image to local is not supported."))

            if destination_type == 'local' and volume_type:
                raise exception.InvalidBDMFormat(
                    details=_("Specifying a volume_type with destination_type="
                              "local is not supported."))

            # Specifying a volume_type with a pre-existing source volume is
            # not supported.
            if source_type == 'volume' and volume_type:
                raise exception.InvalidBDMFormat(
                    details=_("Specifying volume type to existing volume is "
                              "not supported."))

        api_dict.pop('uuid', None)
        return cls(api_dict)
def validate_and_default_volume_size(bdm):
    if bdm.get('volume_size'):
        try:
            bdm['volume_size'] = utils.validate_integer(
                bdm['volume_size'], 'volume_size', min_value=0)
        except exception.InvalidInput as e:
            raise exception.InvalidBDMFormat(
                details="Invalid volume_size.")
Пример #6
0
def validate_and_default_volume_size(bdm):
    if bdm.get('volume_size'):
        try:
            bdm['volume_size'] = utils.validate_integer(
                bdm['volume_size'], 'volume_size', min_value=0)
        except exception.InvalidInput:
            # NOTE: We can remove this validation code after removing
            # Nova v2.0 API code because v2.1 API validates this case
            # already at its REST API layer.
            raise exception.InvalidBDMFormat(
                details=_("Invalid volume_size."))
    def from_api(cls, api_dict):
        """Transform the API format of data to the internally used one.

        Only validate if the source_type field makes sense.
        """
        if not api_dict.get('no_device'):

            source_type = api_dict.get('source_type')
            device_uuid = api_dict.get('uuid')

            if source_type not in ('volume', 'image', 'snapshot', 'blank'):
                raise exception.InvalidBDMFormat(
                    details="Invalid source_type field.")
            elif source_type != 'blank':
                if not device_uuid:
                    raise exception.InvalidBDMFormat(
                        details="Missing device UUID.")
                api_dict[source_type + '_id'] = device_uuid

        api_dict.pop('uuid', None)
        return cls(api_dict)
Пример #8
0
    def _get_available_controller_slot(self, controller_type, slot_map):
        max_slots = (os_win_const.IDE_CONTROLLER_SLOTS_NUMBER
                     if controller_type == constants.CTRL_TYPE_IDE else
                     os_win_const.SCSI_CONTROLLER_SLOTS_NUMBER)
        for idx, ctrl in enumerate(slot_map[controller_type]):
            if slot_map[controller_type][idx] >= 1:
                drive_addr = idx
                ctrl_disk_addr = max_slots - slot_map[controller_type][idx]
                slot_map[controller_type][idx] -= 1
                return (drive_addr, ctrl_disk_addr)

        msg = _(
            "There are no more free slots on controller %s") % controller_type
        raise exception.InvalidBDMFormat(details=msg)
Пример #9
0
    def validate_and_update_bdi(self, instance, image_meta, vm_gen,
                                block_device_info):
        slot_map = self._initialize_controller_slot_counter(instance, vm_gen)
        self._check_and_update_root_device(vm_gen, image_meta,
                                           block_device_info, slot_map)
        self._check_and_update_ephemerals(vm_gen, block_device_info, slot_map)
        self._check_and_update_volumes(vm_gen, block_device_info, slot_map)

        if vm_gen == constants.VM_GEN_2 and configdrive.required_by(instance):
            # for Generation 2 VMs, the configdrive is attached to the SCSI
            # controller. Check that there is still a slot available for it.
            if slot_map[constants.CTRL_TYPE_SCSI][0] == 0:
                msg = _("There are no more free slots on controller %s for "
                        "configdrive.") % constants.CTRL_TYPE_SCSI
                raise exception.InvalidBDMFormat(details=msg)
Пример #10
0
    def from_legacy(cls, legacy_bdm):

        copy_over_fields = bdm_legacy_fields & bdm_new_fields
        copy_over_fields |= (bdm_db_only_fields | bdm_db_inherited_fields)
        # NOTE (ndipanov): These fields cannot be computed
        # from legacy bdm, so do not default them
        # to avoid overwriting meaningful values in the db
        non_computable_fields = set(
            ['boot_index', 'disk_bus', 'guest_format', 'device_type'])

        new_bdm = {
            fld: val
            for fld, val in six.iteritems(legacy_bdm)
            if fld in copy_over_fields
        }

        virt_name = legacy_bdm.get('virtual_name')

        if is_swap_or_ephemeral(virt_name):
            new_bdm['source_type'] = 'blank'
            new_bdm['delete_on_termination'] = True
            new_bdm['destination_type'] = 'local'

            if virt_name == 'swap':
                new_bdm['guest_format'] = 'swap'
            else:
                new_bdm['guest_format'] = CONF.default_ephemeral_format

        elif legacy_bdm.get('snapshot_id'):
            new_bdm['source_type'] = 'snapshot'
            new_bdm['destination_type'] = 'volume'

        elif legacy_bdm.get('volume_id'):
            new_bdm['source_type'] = 'volume'
            new_bdm['destination_type'] = 'volume'

        elif legacy_bdm.get('no_device'):
            # NOTE (ndipanov): Just keep the BDM for now,
            pass

        else:
            raise exception.InvalidBDMFormat(
                details=_("Unrecognized legacy format."))

        return cls(new_bdm, non_computable_fields)
Пример #11
0
 def _validate(*args, **kwargs):
     raise exception.InvalidBDMFormat(details='Wrong BDM')
class BlockDeviceMappingTestV21(test.TestCase):
    validation_error = exception.ValidationError

    def _setup_controller(self):
        ext_info = extension_info.LoadedExtensionInfo()
        self.controller = servers_v21.ServersController(
            extension_info=ext_info)
        CONF.set_override('extensions_blacklist', 'os-block-device-mapping',
                          'osapi_v21')
        self.no_bdm_v2_controller = servers_v21.ServersController(
            extension_info=ext_info)
        CONF.set_override('extensions_blacklist', '', 'osapi_v21')

    def setUp(self):
        super(BlockDeviceMappingTestV21, self).setUp()
        fakes.stub_out_nw_api(self)
        self._setup_controller()
        fake.stub_out_image_service(self)

        self.bdm = [{
            'no_device': None,
            'source_type': 'volume',
            'destination_type': 'volume',
            'uuid': 'fake',
            'device_name': 'vdb',
            'delete_on_termination': False,
        }]

    def _get_servers_body(self, no_image=False):
        body = {
            'server': {
                'name': 'server_test',
                'imageRef': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
                'flavorRef': 'http://localhost/123/flavors/3',
                'metadata': {
                    'hello': 'world',
                    'open': 'stack',
                },
            },
        }
        if no_image:
            del body['server']['imageRef']
        return body

    def _test_create(self, params, no_image=False, override_controller=None):
        body = self._get_servers_body(no_image)
        body['server'].update(params)

        req = fakes.HTTPRequest.blank('/v2/fake/servers')
        req.method = 'POST'
        req.headers['content-type'] = 'application/json'

        req.body = jsonutils.dump_as_bytes(body)

        if override_controller:
            override_controller.create(req, body=body).obj['server']
        else:
            self.controller.create(req, body=body).obj['server']

    def test_create_instance_with_block_device_mapping_disabled(self):
        bdm = [{'device_name': 'foo'}]

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertNotIn('block_device_mapping', kwargs)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: bdm}
        self._test_create(params,
                          override_controller=self.no_bdm_v2_controller)

    def test_create_instance_with_volumes_enabled_no_image(self):
        """Test that the create will fail if there is no image
        and no bdms supplied in the request
        """
        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertNotIn('imageRef', kwargs)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        self.assertRaises(exc.HTTPBadRequest,
                          self._test_create, {},
                          no_image=True)

    @mock.patch.object(compute_api.API, '_validate_bdm')
    @mock.patch.object(compute_api.API, '_get_bdm_image_metadata')
    def test_create_instance_with_bdms_and_no_image(self,
                                                    mock_bdm_image_metadata,
                                                    mock_validate_bdm):
        mock_bdm_image_metadata.return_value = {}
        mock_validate_bdm.return_value = True
        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertThat(
                block_device.BlockDeviceDict(self.bdm[0]),
                matchers.DictMatches(kwargs['block_device_mapping'][0]))
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self._test_create(params, no_image=True)

        mock_validate_bdm.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY,
                                                  mock.ANY)
        mock_bdm_image_metadata.assert_called_once_with(
            mock.ANY, mock.ANY, False)

    @mock.patch.object(compute_api.API, '_validate_bdm')
    @mock.patch.object(compute_api.API, '_get_bdm_image_metadata')
    def test_create_instance_with_bdms_and_empty_imageRef(
            self, mock_bdm_image_metadata, mock_validate_bdm):
        mock_bdm_image_metadata.return_value = {}
        mock_validate_bdm.return_value = True
        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertThat(
                block_device.BlockDeviceDict(self.bdm[0]),
                matchers.DictMatches(kwargs['block_device_mapping'][0]))
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {
            block_device_mapping.ATTRIBUTE_NAME: self.bdm,
            'imageRef': ''
        }
        self._test_create(params)

    def test_create_instance_with_imageRef_as_full_url(self):
        bdm = [{'device_name': 'foo'}]
        image_href = ('http://localhost/v2/fake/images/'
                      '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6')
        params = {
            block_device_mapping.ATTRIBUTE_NAME: bdm,
            'imageRef': image_href
        }
        self.assertRaises(exception.ValidationError, self._test_create, params)

    def test_create_instance_with_non_uuid_imageRef(self):
        bdm = [{'device_name': 'foo'}]

        params = {
            block_device_mapping.ATTRIBUTE_NAME: bdm,
            'imageRef': '123123abcd'
        }
        self.assertRaises(exception.ValidationError, self._test_create, params)

    def test_create_instance_with_invalid_bdm_in_2nd_dict(self):
        bdm_1st = {
            "source_type": "image",
            "delete_on_termination": True,
            "boot_index": 0,
            "uuid": "2ff3a1d3-ed70-4c3f-94ac-941461153bc0",
            "destination_type": "local"
        }
        bdm_2nd = {
            "source_type": "volume",
            "uuid": "99d92140-3d0c-4ea5-a49c-f94c38c607f0",
            "destination_type": "invalid"
        }
        bdm = [bdm_1st, bdm_2nd]

        params = {
            block_device_mapping.ATTRIBUTE_NAME: bdm,
            'imageRef': '2ff3a1d3-ed70-4c3f-94ac-941461153bc0'
        }
        self.assertRaises(exception.ValidationError, self._test_create, params)

    def test_create_instance_with_boot_index_none_ok(self):
        """Tests creating a server with two block devices. One is the boot
        device and the other is a non-bootable device.
        """
        # From the docs:
        # To disable a device from booting, set the boot index to a negative
        # value or use the default boot index value, which is None. The
        # simplest usage is, set the boot index of the boot device to 0 and use
        # the default boot index value, None, for any other devices.
        bdms = [
            # This is the bootable device that would create a 20GB cinder
            # volume from the given image.
            {
                'source_type': 'image',
                'destination_type': 'volume',
                'boot_index': 0,
                'uuid': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
                'volume_size': 20
            },
            # This is the non-bootable 10GB ext4 ephemeral block device.
            {
                'source_type': 'blank',
                'destination_type': 'local',
                'boot_index': None,
                # If 'guest_format' is 'swap' then a swap device is created.
                'guest_format': 'ext4'
            }
        ]
        params = {block_device_mapping.ATTRIBUTE_NAME: bdms}
        self._test_create(params, no_image=True)

    def test_create_instance_with_boot_index_none_image_local_fails(self):
        """Tests creating a server with a local image-based block device which
        has a boot_index of None which is invalid.
        """
        bdms = [{
            'source_type': 'image',
            'destination_type': 'local',
            'boot_index': None,
            'uuid': '155d900f-4e14-4e4c-a73d-069cbf4541e6'
        }]
        params = {block_device_mapping.ATTRIBUTE_NAME: bdms}
        self.assertRaises(exc.HTTPBadRequest,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_with_invalid_boot_index(self):
        bdm = [{
            "source_type": "image",
            "delete_on_termination": True,
            "boot_index": 'invalid',
            "uuid": "2ff3a1d3-ed70-4c3f-94ac-941461153bc0",
            "destination_type": "local"
        }]

        params = {
            block_device_mapping.ATTRIBUTE_NAME: bdm,
            'imageRef': '2ff3a1d3-ed70-4c3f-94ac-941461153bc0'
        }
        self.assertRaises(exception.ValidationError, self._test_create, params)

    def test_create_instance_with_device_name_not_string(self):
        self.bdm[0]['device_name'] = 123
        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertEqual(kwargs['block_device_mapping'], self.bdm)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    @mock.patch.object(compute_api.API, 'create')
    def test_create_instance_with_bdm_param_not_list(self, mock_create):
        self.params = {'block_device_mapping': '/dev/vdb'}
        self.assertRaises(self.validation_error, self._test_create,
                          self.params)

    def test_create_instance_with_device_name_empty(self):
        self.bdm[0]['device_name'] = ''

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertEqual(kwargs['block_device_mapping'], self.bdm)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_with_device_name_too_long(self):
        self.bdm[0]['device_name'] = 'a' * 256

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertEqual(kwargs['block_device_mapping'], self.bdm)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_with_space_in_device_name(self):
        self.bdm[0]['device_name'] = 'v da'

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertTrue(kwargs['legacy_bdm'])
            self.assertEqual(kwargs['block_device_mapping'], self.bdm)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_with_invalid_size(self):
        self.bdm[0]['volume_size'] = 'hello world'

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertEqual(kwargs['block_device_mapping'], self.bdm)
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    def _test_create_instance_with_destination_type_error(
            self, destination_type):
        self.bdm[0]['destination_type'] = destination_type

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(self.validation_error,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_with_destination_type_empty_string(self):
        self._test_create_instance_with_destination_type_error('')

    def test_create_instance_with_invalid_destination_type(self):
        self._test_create_instance_with_destination_type_error('fake')

    @mock.patch.object(compute_api.API, '_validate_bdm')
    def test_create_instance_bdm(self, mock_validate_bdm):
        bdm = [{
            'source_type': 'volume',
            'device_name': 'fake_dev',
            'uuid': 'fake_vol'
        }]
        bdm_expected = [{
            'source_type': 'volume',
            'device_name': 'fake_dev',
            'volume_id': 'fake_vol'
        }]

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertFalse(kwargs['legacy_bdm'])
            for expected, received in zip(bdm_expected,
                                          kwargs['block_device_mapping']):
                self.assertThat(block_device.BlockDeviceDict(expected),
                                matchers.DictMatches(received))
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: bdm}
        self._test_create(params, no_image=True)
        mock_validate_bdm.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY,
                                                  mock.ANY)

    @mock.patch.object(compute_api.API, '_validate_bdm')
    def test_create_instance_bdm_missing_device_name(self, mock_validate_bdm):
        del self.bdm[0]['device_name']

        old_create = compute_api.API.create

        def create(*args, **kwargs):
            self.assertFalse(kwargs['legacy_bdm'])
            self.assertNotIn(None,
                             kwargs['block_device_mapping'][0]['device_name'])
            return old_create(*args, **kwargs)

        self.stub_out('nova.compute.api.API.create', create)

        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self._test_create(params, no_image=True)
        mock_validate_bdm.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY,
                                                  mock.ANY)

    @mock.patch.object(
        block_device.BlockDeviceDict,
        '_validate',
        side_effect=exception.InvalidBDMFormat(details='Wrong BDM'))
    def test_create_instance_bdm_validation_error(self, mock_validate):
        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        self.assertRaises(exc.HTTPBadRequest,
                          self._test_create,
                          params,
                          no_image=True)

    @mock.patch('nova.compute.api.API._get_bdm_image_metadata')
    def test_create_instance_non_bootable_volume_fails(self, fake_bdm_meta):
        params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
        fake_bdm_meta.side_effect = exception.InvalidBDMVolumeNotBootable(id=1)
        self.assertRaises(exc.HTTPBadRequest,
                          self._test_create,
                          params,
                          no_image=True)

    def test_create_instance_bdm_api_validation_fails(self):
        self.validation_fail_test_validate_called = False
        self.validation_fail_instance_destroy_called = False

        bdm_exceptions = ((exception.InvalidBDMSnapshot, {
            'id': 'fake'
        }), (exception.InvalidBDMVolume, {
            'id': 'fake'
        }), (exception.InvalidBDMImage, {
            'id': 'fake'
        }), (exception.InvalidBDMBootSequence, {}),
                          (exception.InvalidBDMLocalsLimit, {}))

        ex_iter = iter(bdm_exceptions)

        def _validate_bdm(*args, **kwargs):
            self.validation_fail_test_validate_called = True
            ex, kargs = next(ex_iter)
            raise ex(**kargs)

        def _instance_destroy(*args, **kwargs):
            self.validation_fail_instance_destroy_called = True

        self.stub_out('nova.compute.api.API._validate_bdm', _validate_bdm)
        self.stub_out('nova.objects.Instance.destroy', _instance_destroy)

        for _unused in range(len(bdm_exceptions)):
            params = {
                block_device_mapping.ATTRIBUTE_NAME: [self.bdm[0].copy()]
            }
            self.assertRaises(exc.HTTPBadRequest, self._test_create, params)
            self.assertTrue(self.validation_fail_test_validate_called)
            self.assertFalse(self.validation_fail_instance_destroy_called)
            self.validation_fail_test_validate_called = False
            self.validation_fail_instance_destroy_called = False
Пример #13
0
 def _validate(self, bdm_dict):
     """Basic data format validations."""
     if (not set(key for key, _ in bdm_dict.iteritems()) <=
         (self._fields | self._db_only_fields)):
         raise exception.InvalidBDMFormat()