def test_in_api(self):
        flavor = objects.Flavor(context=self.context, id=123)
        self.assertFalse(flavor._in_api)

        # First call, flavor not found, should be false
        with mock.patch.object(flavor, '_flavor_get_from_db') as mock_g:
            mock_g.side_effect = exception.FlavorNotFound(flavor_id='123')
            self.assertFalse(flavor.in_api)
            mock_g.assert_called_once_with(self.context, 123)

        # Second call, still not found, make sure we checked again
        with mock.patch.object(flavor, '_flavor_get_from_db') as mock_g:
            mock_g.side_effect = exception.FlavorNotFound(flavor_id='123')
            self.assertFalse(flavor.in_api)
            mock_g.assert_called_once_with(self.context, 123)

        # Third, flavor found, should be true
        with mock.patch.object(flavor, '_flavor_get_from_db') as mock_g:
            self.assertTrue(flavor.in_api)
            mock_g.assert_called_once_with(self.context, 123)

        # Fourth, flavor was already found, shouldn't check again, still true
        with mock.patch.object(flavor, '_flavor_get_from_db') as mock_g:
            self.assertTrue(flavor.in_api)
            self.assertFalse(mock_g.called)
    def test_not_found_because_flavor(self):
        req = self._get_request('1/os-extra_specs/key5',
                                use_admin_context=True)
        with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
            mock_get.side_effect = exception.FlavorNotFound(flavor_id='1')
            self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
                              req, 1, 'key5')
            self.assertRaises(webob.exc.HTTPNotFound,
                              self.controller.update,
                              req,
                              1,
                              'key5',
                              body={'key5': 'value5'})
            self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
                              req, 1, 'key5')

        req = self._get_request('1/os-extra_specs', use_admin_context=True)
        with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
            mock_get.side_effect = exception.FlavorNotFound(flavor_id='1')
            self.assertRaises(webob.exc.HTTPNotFound,
                              self.controller.create,
                              req,
                              1,
                              body={'extra_specs': {
                                  'key5': 'value5'
                              }})
示例#3
0
def _get_projects_from_db(context, flavorid):
    db_flavor = context.session.query(
        api_models.Flavors).filter_by(flavorid=flavorid).options(
            orm.joinedload(api_models.Flavors.projects)).first()
    if not db_flavor:
        raise exception.FlavorNotFound(flavor_id=flavorid)
    return [x['project_id'] for x in db_flavor['projects']]
 def _class_for_platform(self, platform):
     try:
         # try direct model first
         return dynamips_lib.__dict__[platform.upper()]
     except KeyError:
         raise exception.FlavorNotFound("Can not find router platform %s" %
                                        platform)
示例#5
0
 def test_create_flavor_not_found(self):
     body = {'extra_specs': {'hw:numa_nodes': '1'}}
     req = self._get_request('1/os-extra_specs', use_admin_context=True)
     with mock.patch('nova.objects.Flavor.save',
                     side_effect=exception.FlavorNotFound(flavor_id='')):
         self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                           req, 1, body=body)
 def _chassis_for_flavor(self, flavorname):
     res = re.match(r'c1\.(.*)', flavorname)
     if res:
         return res.group(1)
     else:
         raise exception.FlavorNotFound(
             "Dynamips accepts only c1.xxx flavors, got %s" % flavorname)
示例#7
0
def fake_get_flavor_by_flavor_id(flavorid, ctxt=None, read_deleted='yes'):
    if flavorid == 'failtest':
        raise exception.FlavorNotFound(flavor_id=flavorid)
    elif not str(flavorid) == '1234':
        raise Exception("This test expects flavorid 1234, not %s" % flavorid)
    if read_deleted != 'no':
        raise test.TestingException("Should not be reading deleted")

    return {
        'root_gb': 1,
        'ephemeral_gb': 1,
        'name': u'frob',
        'deleted': False,
        'created_at': datetime.datetime(2012, 1, 19, 18, 49, 30, 877329),
        'updated_at': None,
        'memory_mb': 256,
        'vcpus': 1,
        'flavorid': flavorid,
        'swap': 0,
        'rxtx_factor': 1.0,
        'extra_specs': {},
        'deleted_at': None,
        'vcpu_weight': None,
        'id': 7,
        'is_public': True,
        'disabled': False,
    }
示例#8
0
def get_instance_type_by_flavor_id(flavor_id):
    """Retrieve instance type by flavor_id."""
    ctxt = context.get_admin_context()
    try:
        return db.instance_type_get_by_flavor_id(ctxt, flavor_id)
    except ValueError:
        raise exception.FlavorNotFound(flavor_id=flavor_id)
示例#9
0
def fake_get_flavor_by_flavor_id(flavorid, ctxt=None, read_deleted='yes'):
    if flavorid == 'failtest':
        raise exception.FlavorNotFound(flavor_id=flavorid)
    elif not str(flavorid) == '1234':
        raise Exception("This test expects flavorid 1234, not %s" % flavorid)
    if read_deleted != 'no':
        raise test.TestingException("Should not be reading deleted")
    return fake_db_flavor(flavorid=flavorid)
示例#10
0
 def _flavor_get_from_db(context, id):
     """Returns a dict describing specific flavor."""
     result = Flavor._flavor_get_query_from_db(context).\
                     filter_by(id=id).\
                     first()
     if not result:
         raise exception.FlavorNotFound(flavor_id=id)
     return db_api._dict_with_extra_specs(result)
示例#11
0
    def test_update_flavor_not_found(self):
        body = {'hw:cpu_policy': 'shared'}

        req = self._get_request('1/os-extra_specs/hw:cpu_policy',
                                use_admin_context=True)
        with mock.patch('nova.objects.Flavor.save',
                        side_effect=exception.FlavorNotFound(flavor_id='')):
            self.assertRaises(webob.exc.HTTPNotFound, self.controller.update,
                              req, 1, 'hw:cpu_policy', body=body)
示例#12
0
    def test_get_inst_attrs_from_migration_flavor_not_found(
            self, mock_get_flavor):
        old_flavor, migration, instance = self._test_get_resources()
        expected_result = (instance.vcpus, instance.memory_mb)

        mock_get_flavor.side_effect = exception.FlavorNotFound(old_flavor.id)
        result = compute_utils.get_inst_attrs_from_migration(migration,
                                                             instance)
        self.assertEqual(expected_result, result)
示例#13
0
 def _flavor_get_by_flavor_id_from_db(context, flavor_id):
     """Returns a dict describing specific flavor_id."""
     result = Flavor._flavor_get_query_from_db(context).\
                     filter_by(flavorid=flavor_id).\
                     order_by(asc(api_models.Flavors.id)).\
                     first()
     if not result:
         raise exception.FlavorNotFound(flavor_id=flavor_id)
     return db_api._dict_with_extra_specs(result)
示例#14
0
 def _save(self, context, values):
     db_flavor = context.session.query(api_models.Flavors).\
         filter_by(id=self.id).first()
     if not db_flavor:
         raise exception.FlavorNotFound(flavor_id=self.id)
     db_flavor.update(values)
     db_flavor.save(context.session)
     # Refresh ourselves from the DB object so we get the new updated_at.
     self._from_db_object(context, self, db_flavor)
     self.obj_reset_changes()
示例#15
0
 def test_flavor_not_found(self, mock_get_instance, mock_update_usage):
     mock_update_usage.side_effect = exception.FlavorNotFound(flavor_id='')
     instance = self._fake_instance_obj()
     mock_get_instance.return_value = instance
     migration = objects.Migration(
         context=self.context,
         instance_uuid=instance.uuid,
     )
     self.tracker._update_usage_from_migrations(self.context, [migration])
     mock_get_instance.assert_called_once_with(self.context, instance.uuid)
     mock_update_usage.assert_called_once_with(self.context, instance, None,
                                               migration)
示例#16
0
    def test_delete(self, mock_destroy):
        res = self.controller._delete(self._get_http_request(), 1234)

        # NOTE: on v2.1, http status code is set as wsgi_code of API
        # method instead of status_int in a response object.
        if isinstance(self.controller,
                      flavormanage_v21.FlavorManageController):
            status_int = self.controller._delete.wsgi_code
        else:
            status_int = res.status_int
        self.assertEqual(202, status_int)

        # subsequent delete should fail
        mock_destroy.side_effect = exception.FlavorNotFound(flavor_id=1234)
        self.assertRaises(webob.exc.HTTPNotFound, self.controller._delete,
                          self._get_http_request(), 1234)
示例#17
0
def _flavor_destroy(context, flavor_id=None, flavorid=None):
    query = context.session.query(api_models.Flavors)

    if flavor_id is not None:
        query = query.filter(api_models.Flavors.id == flavor_id)
    else:
        query = query.filter(api_models.Flavors.flavorid == flavorid)
    result = query.first()

    if not result:
        raise exception.FlavorNotFound(flavor_id=(flavor_id or flavorid))

    context.session.query(api_models.FlavorProjects).\
        filter_by(flavor_id=result.id).delete()
    context.session.query(api_models.FlavorExtraSpecs).\
        filter_by(flavor_id=result.id).delete()
    context.session.delete(result)
示例#18
0
    def test_resize_invalid_flavor_fails(self):
        self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id')
        # Should never reach these.
        self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta')
        self.mox.StubOutWithMock(self.compute_api, 'update')
        self.mox.StubOutWithMock(quota.QUOTAS, 'commit')
        self.mox.StubOutWithMock(self.compute_api, '_record_action_start')
        self.mox.StubOutWithMock(self.compute_api.compute_task_api,
                                 'migrate_server')

        fake_inst = obj_base.obj_to_primitive(self._create_instance_obj())
        exc = exception.FlavorNotFound(flavor_id='flavor-id')

        flavors.get_flavor_by_flavor_id('flavor-id',
                                        read_deleted='no').AndRaise(exc)

        self.mox.ReplayAll()

        self.assertRaises(exception.FlavorNotFound,
                          self.compute_api.resize, self.context,
                          fake_inst, flavor_id='flavor-id')
def return_flavor_not_found(context, flavor_id, read_deleted=None):
    raise exception.FlavorNotFound(flavor_id=flavor_id)
示例#20
0
def fake_compute_api_resize_non_found_flavor(self, context, instance_id):
    raise exception.FlavorNotFound(flavor_id='')
示例#21
0
 def test_index_flavor_not_found(self, mock_get):
     req = self._get_request('1/os-extra_specs',
                             use_admin_context=True)
     mock_get.side_effect = exception.FlavorNotFound(flavor_id='1')
     self.assertRaises(webob.exc.HTTPNotFound, self.controller.index,
                       req, 1)
示例#22
0
 def fake_instance_type_extra_specs_update_or_create(*args, **kwargs):
     raise exception.FlavorNotFound(flavor_id='')
def return_flavor_not_found(flavor_id, ctxt=None):
    raise exception.FlavorNotFound(flavor_id=flavor_id)
示例#24
0
 def stub_flavor_access_add(context, flavorid, project_id):
     raise exception.FlavorNotFound(flavor_id=flavorid)
示例#25
0
 def stub_remove_flavor_access(context, flavorid, projectid):
     raise exception.FlavorNotFound(flavor_id=flavorid)
示例#26
0
class ServerActionsControllerTestV21(test.TestCase):
    image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
    image_base_url = 'http://*****:*****@mock.patch.object(compute_api.API, 'rebuild')
    def test_rebuild_instance_raise_auto_disk_config_exc(self, mock_rebuild):
        body = {
            "rebuild": {
                "imageRef": self._image_href,
            },
        }

        mock_rebuild.side_effect = exception.AutoDiskConfigDisabledByImage(
            image='dummy')

        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_rebuild,
                          self.req, FAKE_UUID, body=body)

    def test_resize_server(self):

        body = dict(resize=dict(flavorRef="http://localhost/3"))

        self.resize_called = False

        def resize_mock(*args):
            self.resize_called = True

        self.stub_out('nova.compute.api.API.resize', resize_mock)

        self.controller._action_resize(self.req, FAKE_UUID, body=body)

        self.assertTrue(self.resize_called)

    def test_resize_server_no_flavor(self):
        body = dict(resize=dict())

        self.assertRaises(self.validation_error,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_server_no_flavor_ref(self):
        body = dict(resize=dict(flavorRef=None))

        self.assertRaises(self.validation_error,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_server_with_extra_arg(self):
        body = dict(resize=dict(favorRef="http://localhost/3",
                                extra_arg="extra_arg"))
        self.assertRaises(self.validation_error,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_server_invalid_flavor_ref(self):
        body = dict(resize=dict(flavorRef=1.2))

        self.assertRaises(self.validation_error,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_with_server_not_found(self):
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        with mock.patch('nova.compute.api.API.get',
                        side_effect=exception.InstanceNotFound(
                            instance_id=FAKE_UUID)):
            self.assertRaises(webob.exc.HTTPNotFound,
                              self.controller._action_resize,
                              self.req, FAKE_UUID, body=body)

    def test_resize_with_image_exceptions(self):
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        self.resize_called = 0
        image_id = 'fake_image_id'

        exceptions = [
            (exception.ImageNotAuthorized(image_id=image_id),
             webob.exc.HTTPUnauthorized),
            (exception.ImageNotFound(image_id=image_id),
             webob.exc.HTTPBadRequest),
            (exception.Invalid, webob.exc.HTTPBadRequest),
            (exception.NoValidHost(reason='Bad host'),
             webob.exc.HTTPBadRequest),
            (exception.AutoDiskConfigDisabledByImage(image=image_id),
             webob.exc.HTTPBadRequest),
        ]

        raised, expected = map(iter, zip(*exceptions))

        def _fake_resize(obj, context, instance, flavor_id):
            self.resize_called += 1
            raise next(raised)

        self.stub_out('nova.compute.api.API.resize', _fake_resize)

        for call_no in range(len(exceptions)):
            next_exception = next(expected)
            actual = self.assertRaises(next_exception,
                                       self.controller._action_resize,
                                       self.req, FAKE_UUID, body=body)
            if (isinstance(exceptions[call_no][0],
                           exception.NoValidHost)):
                self.assertEqual(actual.explanation,
                                 'No valid host was found. Bad host')
            elif (isinstance(exceptions[call_no][0],
                           exception.AutoDiskConfigDisabledByImage)):
                self.assertEqual(actual.explanation,
                                 'Requested image fake_image_id has automatic'
                                 ' disk resize disabled.')
            self.assertEqual(self.resize_called, call_no + 1)

    @mock.patch('nova.compute.api.API.resize',
                side_effect=exception.CannotResizeDisk(reason=''))
    def test_resize_raises_cannot_resize_disk(self, mock_resize):
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    @mock.patch('nova.compute.api.API.resize',
                side_effect=exception.FlavorNotFound(reason='',
                                                     flavor_id='fake_id'))
    def test_resize_raises_flavor_not_found(self, mock_resize):
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_with_too_many_instances(self):
        body = dict(resize=dict(flavorRef="http://localhost/3"))

        def fake_resize(*args, **kwargs):
            raise exception.TooManyInstances(message="TooManyInstance")

        self.stub_out('nova.compute.api.API.resize', fake_resize)

        self.assertRaises(webob.exc.HTTPForbidden,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_resize_raises_conflict_on_invalid_state(self):
        body = dict(resize=dict(flavorRef="http://localhost/3"))

        def fake_resize(*args, **kwargs):
            raise exception.InstanceInvalidState(attr='fake_attr',
                state='fake_state', method='fake_method',
                instance_uuid='fake')

        self.stub_out('nova.compute.api.API.resize', fake_resize)

        self.assertRaises(webob.exc.HTTPConflict,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    @mock.patch('nova.compute.api.API.resize',
                side_effect=exception.NoValidHost(reason=''))
    def test_resize_raises_no_valid_host(self, mock_resize):
        body = dict(resize=dict(flavorRef="http://localhost/3"))

        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    @mock.patch.object(compute_api.API, 'resize')
    def test_resize_instance_raise_auto_disk_config_exc(self, mock_resize):
        mock_resize.side_effect = exception.AutoDiskConfigDisabledByImage(
            image='dummy')

        body = dict(resize=dict(flavorRef="http://localhost/3"))

        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    @mock.patch('nova.compute.api.API.resize',
                side_effect=exception.PciRequestAliasNotDefined(
                    alias='fake_name'))
    def test_resize_pci_alias_not_defined(self, mock_resize):
        # Tests that PciRequestAliasNotDefined is translated to a 400 error.
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_resize,
                          self.req, FAKE_UUID, body=body)

    def test_confirm_resize_server(self):
        body = dict(confirmResize=None)

        self.confirm_resize_called = False

        def cr_mock(*args):
            self.confirm_resize_called = True

        self.stub_out('nova.compute.api.API.confirm_resize', cr_mock)

        self.controller._action_confirm_resize(self.req, FAKE_UUID, body=body)

        self.assertTrue(self.confirm_resize_called)

    def test_confirm_resize_migration_not_found(self):
        body = dict(confirmResize=None)

        def confirm_resize_mock(*args):
            raise exception.MigrationNotFoundByStatus(instance_id=1,
                                                      status='finished')

        self.stub_out('nova.compute.api.API.confirm_resize',
                      confirm_resize_mock)

        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_confirm_resize,
                          self.req, FAKE_UUID, body=body)

    def test_confirm_resize_raises_conflict_on_invalid_state(self):
        body = dict(confirmResize=None)

        def fake_confirm_resize(*args, **kwargs):
            raise exception.InstanceInvalidState(attr='fake_attr',
                state='fake_state', method='fake_method',
                instance_uuid='fake')

        self.stub_out('nova.compute.api.API.confirm_resize',
                      fake_confirm_resize)

        self.assertRaises(webob.exc.HTTPConflict,
                          self.controller._action_confirm_resize,
                          self.req, FAKE_UUID, body=body)

    def test_revert_resize_migration_not_found(self):
        body = dict(revertResize=None)

        def revert_resize_mock(*args):
            raise exception.MigrationNotFoundByStatus(instance_id=1,
                                                      status='finished')

        self.stub_out('nova.compute.api.API.revert_resize',
                      revert_resize_mock)

        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.controller._action_revert_resize,
                          self.req, FAKE_UUID, body=body)

    def test_revert_resize_server_not_found(self):
        body = dict(revertResize=None)
        with mock.patch('nova.compute.api.API.get',
                        side_effect=exception.InstanceNotFound(
                            instance_id='bad_server_id')):
            self.assertRaises(webob. exc.HTTPNotFound,
                              self.controller._action_revert_resize,
                              self.req, "bad_server_id", body=body)

    def test_revert_resize_server(self):
        body = dict(revertResize=None)

        self.revert_resize_called = False

        def revert_mock(*args):
            self.revert_resize_called = True

        self.stub_out('nova.compute.api.API.revert_resize', revert_mock)

        body = self.controller._action_revert_resize(self.req, FAKE_UUID,
                                                     body=body)

        self.assertTrue(self.revert_resize_called)

    def test_revert_resize_raises_conflict_on_invalid_state(self):
        body = dict(revertResize=None)

        def fake_revert_resize(*args, **kwargs):
            raise exception.InstanceInvalidState(attr='fake_attr',
                state='fake_state', method='fake_method',
                instance_uuid='fake')

        self.stub_out('nova.compute.api.API.revert_resize',
                      fake_revert_resize)

        self.assertRaises(webob.exc.HTTPConflict,
                          self.controller._action_revert_resize,
                          self.req, FAKE_UUID, body=body)

    def test_create_image(self):
        body = {
            'createImage': {
                'name': 'Snapshot 1',
            },
        }

        response = self.controller._action_create_image(self.req, FAKE_UUID,
                                                        body=body)

        location = response.headers['Location']
        self.assertEqual(self.image_url + '123' if self.image_url else
            self.image_api.generate_image_url('123', self.context),
            location)

    def test_create_image_v2_45(self):
        """Tests the createImage server action API with the 2.45 microversion
        where there is a response body but no Location header.
        """
        body = {
            'createImage': {
                'name': 'Snapshot 1',
            },
        }
        req = fakes.HTTPRequest.blank('', version='2.45')
        response = self.controller._action_create_image(req, FAKE_UUID,
                                                        body=body)
        self.assertIsInstance(response, dict)
        self.assertEqual('123', response['image_id'])

    def test_create_image_name_too_long(self):
        long_name = 'a' * 260
        body = {
            'createImage': {
                'name': long_name,
            },
        }

        self.assertRaises(self.validation_error,
                          self.controller._action_create_image, self.req,
                          FAKE_UUID, body=body)

    def _do_test_create_volume_backed_image(
            self, extra_properties, mock_vol_create_side_effect=None):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['createImage']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id('a'),
                    volume_size=1,
                    device_name='vda',
                    delete_on_termination=False)]

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stub_out('nova.db.api.block_device_mapping_get_all_by_instance',
                      fake_block_device_mapping_get_all_by_instance)

        system_metadata = dict(image_kernel_id=_fake_id('b'),
                               image_ramdisk_id=_fake_id('c'),
                               image_root_device_name='/dev/vda',
                               image_block_device_mapping=str(bdm),
                               image_container_format='ami')
        instance = fakes.fake_compute_get(image_ref=uuids.fake,
                                          vm_state=vm_states.ACTIVE,
                                          root_device_name='/dev/vda',
                                          system_metadata=system_metadata)
        self.stub_out('nova.compute.api.API.get', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')

        snapshot = dict(id=_fake_id('d'))

        with test.nested(
            mock.patch.object(
                self.controller.compute_api.volume_api, 'get_absolute_limits',
                return_value={'totalSnapshotsUsed': 0,
                              'maxTotalSnapshots': 10}),
            mock.patch.object(self.controller.compute_api.compute_rpcapi,
                'quiesce_instance',
                side_effect=exception.InstanceQuiesceNotSupported(
                    instance_id='fake', reason='test')),
            mock.patch.object(self.controller.compute_api.volume_api, 'get',
                              return_value=volume),
            mock.patch.object(self.controller.compute_api.volume_api,
                              'create_snapshot_force',
                              return_value=snapshot),
        ) as (mock_get_limits, mock_quiesce, mock_vol_get, mock_vol_create):

            if mock_vol_create_side_effect:
                mock_vol_create.side_effect = mock_vol_create_side_effect

            response = self.controller._action_create_image(self.req,
                FAKE_UUID, body=body)

            location = response.headers['Location']
            image_id = location.replace(self.image_url or
                 self.image_api.generate_image_url('', self.context),
                                        '')
            image = image_service.show(None, image_id)

            self.assertEqual(image['name'], 'snapshot_of_volume_backed')
            properties = image['properties']
            self.assertEqual(properties['kernel_id'], _fake_id('b'))
            self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
            self.assertEqual(properties['root_device_name'], '/dev/vda')
            self.assertTrue(properties['bdm_v2'])
            bdms = properties['block_device_mapping']
            self.assertEqual(len(bdms), 1)
            self.assertEqual(bdms[0]['boot_index'], 0)
            self.assertEqual(bdms[0]['source_type'], 'snapshot')
            self.assertEqual(bdms[0]['destination_type'], 'volume')
            self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
            self.assertEqual('/dev/vda', bdms[0]['device_name'])
            for fld in ('connection_info', 'id', 'instance_uuid'):
                self.assertNotIn(fld, bdms[0])
            for k in extra_properties.keys():
                self.assertEqual(properties[k], extra_properties[k])

            mock_quiesce.assert_called_once_with(mock.ANY, mock.ANY)
            mock_vol_get.assert_called_once_with(mock.ANY, volume['id'])
            mock_vol_create.assert_called_once_with(mock.ANY, volume['id'],
                                                    mock.ANY, mock.ANY)

    def test_create_volume_backed_image_no_metadata(self):
        self._do_test_create_volume_backed_image({})

    def test_create_volume_backed_image_with_metadata(self):
        self._do_test_create_volume_backed_image(dict(ImageType='Gold',
                                                      ImageVersion='2.0'))

    def test_create_volume_backed_image_cinder_over_quota(self):
        self.assertRaises(
            webob.exc.HTTPForbidden,
            self._do_test_create_volume_backed_image, {},
            mock_vol_create_side_effect=exception.OverQuota(
                overs='snapshot'))

    def _test_create_volume_backed_image_with_metadata_from_volume(
            self, extra_metadata=None):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))
        if extra_metadata:
            body['createImage']['metadata'] = extra_metadata

        image_service = glance.get_default_image_service()

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stub_out('nova.db.api.block_device_mapping_get_all_by_instance',
                      fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_compute_get(
            image_ref='',
            vm_state=vm_states.ACTIVE,
            root_device_name='/dev/vda',
            system_metadata={'image_test_key1': 'test_value1',
                             'image_test_key2': 'test_value2'})
        self.stub_out('nova.compute.api.API.get', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')

        snapshot = dict(id=_fake_id('d'))

        with test.nested(
            mock.patch.object(
                self.controller.compute_api.volume_api, 'get_absolute_limits',
                return_value={'totalSnapshotsUsed': 0,
                              'maxTotalSnapshots': 10}),
            mock.patch.object(self.controller.compute_api.compute_rpcapi,
                'quiesce_instance',
                side_effect=exception.InstanceQuiesceNotSupported(
                    instance_id='fake', reason='test')),
            mock.patch.object(self.controller.compute_api.volume_api, 'get',
                              return_value=volume),
            mock.patch.object(self.controller.compute_api.volume_api,
                              'create_snapshot_force',
                              return_value=snapshot),
        ) as (mock_get_limits, mock_quiesce, mock_vol_get, mock_vol_create):

            response = self.controller._action_create_image(self.req,
                FAKE_UUID, body=body)
            location = response.headers['Location']
            image_id = location.replace(self.image_base_url, '')
            image = image_service.show(None, image_id)

            properties = image['properties']
            self.assertEqual(properties['test_key1'], 'test_value1')
            self.assertEqual(properties['test_key2'], 'test_value2')
            if extra_metadata:
                for key, val in extra_metadata.items():
                    self.assertEqual(properties[key], val)

            mock_quiesce.assert_called_once_with(mock.ANY, mock.ANY)
            mock_vol_get.assert_called_once_with(mock.ANY, volume['id'])
            mock_vol_create.assert_called_once_with(mock.ANY, volume['id'],
                                                    mock.ANY, mock.ANY)

    def test_create_vol_backed_img_with_meta_from_vol_without_extra_meta(self):
        self._test_create_volume_backed_image_with_metadata_from_volume()

    def test_create_vol_backed_img_with_meta_from_vol_with_extra_meta(self):
        self._test_create_volume_backed_image_with_metadata_from_volume(
            extra_metadata={'a': 'b'})

    def test_create_image_with_metadata(self):
        body = {
            'createImage': {
                'name': 'Snapshot 1',
                'metadata': {'key': 'asdf'},
            },
        }

        response = self.controller._action_create_image(self.req, FAKE_UUID,
                                                        body=body)

        location = response.headers['Location']
        self.assertEqual(self.image_url + '123' if self.image_url else
            self.image_api.generate_image_url('123', self.context), location)

    def test_create_image_with_too_much_metadata(self):
        body = {
            'createImage': {
                'name': 'Snapshot 1',
                'metadata': {},
            },
        }
        for num in range(CONF.quota.metadata_items + 1):
            body['createImage']['metadata']['foo%i' % num] = "bar"

        self.assertRaises(webob.exc.HTTPForbidden,
                          self.controller._action_create_image,
                          self.req, FAKE_UUID, body=body)

    def test_create_image_no_name(self):
        body = {
            'createImage': {},
        }

        self.assertRaises(self.validation_error,
                          self.controller._action_create_image,
                          self.req, FAKE_UUID, body=body)

    def test_create_image_blank_name(self):
        body = {
            'createImage': {
                'name': '',
            }
        }

        self.assertRaises(self.validation_error,
                          self.controller._action_create_image,
                          self.req, FAKE_UUID, body=body)

    def test_create_image_bad_metadata(self):
        body = {
            'createImage': {
                'name': 'geoff',
                'metadata': 'henry',
            },
        }

        self.assertRaises(self.validation_error,
                          self.controller._action_create_image,
                          self.req, FAKE_UUID, body=body)

    def test_create_image_raises_conflict_on_invalid_state(self):
        def snapshot(*args, **kwargs):
            raise exception.InstanceInvalidState(attr='fake_attr',
                state='fake_state', method='fake_method',
                instance_uuid='fake')
        self.stub_out('nova.compute.api.API.snapshot', snapshot)

        body = {
            "createImage": {
                "name": "test_snapshot",
            },
        }

        self.assertRaises(webob.exc.HTTPConflict,
                          self.controller._action_create_image,
                          self.req, FAKE_UUID, body=body)
示例#27
0
 def stub_remove_flavor_access(flavorid, projectid, ctxt=None):
     raise exception.FlavorNotFound(flavor_id=flavorid)
示例#28
0
class FlavorAccessTestV21(test.NoDBTestCase):
    api_version = "2.1"
    FlavorAccessController = flavor_access_v21.FlavorAccessController
    FlavorActionController = flavor_access_v21.FlavorActionController
    _prefix = "/v2/fake"
    validation_ex = exception.ValidationError

    def setUp(self):
        super(FlavorAccessTestV21, self).setUp()
        self.flavor_controller = flavors_api.FlavorsController()
        # We need to stub out verify_project_id so that it doesn't
        # generate an EndpointNotFound exception and result in a
        # server error.
        self.stub_out('nova.api.openstack.identity.verify_project_id',
                      lambda ctx, project_id: True)

        self.req = FakeRequest()
        self.req.environ = {
            "nova.context": context.RequestContext('fake_user', 'fake')
        }
        self.stub_out('nova.db.flavor_get_by_flavor_id',
                      fake_get_flavor_by_flavor_id)
        self.stub_out('nova.db.flavor_get_all',
                      fake_get_all_flavors_sorted_list)
        self.stub_out('nova.db.flavor_access_get_by_flavor_id',
                      fake_get_flavor_access_by_flavor_id)
        # Simulate no API flavors right now
        self.stub_out('nova.objects.flavor._flavor_get_all_from_db',
                      lambda *a, **k: [])
        self.stub_out('nova.objects.Flavor.in_api', False)
        self.stub_out('nova.objects.flavor._get_projects_from_db',
                      fake_get_flavor_projects_from_db)

        self.flavor_access_controller = self.FlavorAccessController()
        self.flavor_action_controller = self.FlavorActionController()

    def _verify_flavor_list(self, result, expected):
        # result already sorted by flavor_id
        self.assertEqual(len(result), len(expected))

        for d1, d2 in zip(result, expected):
            self.assertEqual(d1['id'], d2['id'])

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_list_flavor_access_public(self, mock_api_get):
        # query os-flavor-access on public flavor should return 404
        self.assertRaises(exc.HTTPNotFound,
                          self.flavor_access_controller.index, self.req, '1')

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_list_flavor_access_private(self, mock_api_get):
        expected = {
            'flavor_access': [{
                'flavor_id': '2',
                'tenant_id': 'proj2'
            }, {
                'flavor_id': '2',
                'tenant_id': 'proj3'
            }]
        }
        result = self.flavor_access_controller.index(self.req, '2')
        self.assertEqual(result, expected)

    def test_list_flavor_with_admin_default_proj1(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors',
                                      use_admin_context=True)
        req.environ['nova.context'].project_id = 'proj1'
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_admin_default_proj2(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}, {'id': '2'}]}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors',
                                      use_admin_context=True)
        req.environ['nova.context'].project_id = 'proj2'
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_admin_ispublic_true(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        url = self._prefix + '/flavors?is_public=true'
        req = fakes.HTTPRequest.blank(url, use_admin_context=True)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_admin_ispublic_false(self):
        expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
        url = self._prefix + '/flavors?is_public=false'
        req = fakes.HTTPRequest.blank(url, use_admin_context=True)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_admin_ispublic_false_proj2(self):
        expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
        url = self._prefix + '/flavors?is_public=false'
        req = fakes.HTTPRequest.blank(url, use_admin_context=True)
        req.environ['nova.context'].project_id = 'proj2'
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_admin_ispublic_none(self):
        expected = {
            'flavors': [{
                'id': '0'
            }, {
                'id': '1'
            }, {
                'id': '2'
            }, {
                'id': '3'
            }]
        }
        url = self._prefix + '/flavors?is_public=none'
        req = fakes.HTTPRequest.blank(url, use_admin_context=True)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_no_admin_default(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors',
                                      use_admin_context=False)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_no_admin_ispublic_true(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        url = self._prefix + '/flavors?is_public=true'
        req = fakes.HTTPRequest.blank(url, use_admin_context=False)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_no_admin_ispublic_false(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        url = self._prefix + '/flavors?is_public=false'
        req = fakes.HTTPRequest.blank(url, use_admin_context=False)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_list_flavor_with_no_admin_ispublic_none(self):
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
        url = self._prefix + '/flavors?is_public=none'
        req = fakes.HTTPRequest.blank(url, use_admin_context=False)
        result = self.flavor_controller.index(req)
        self._verify_flavor_list(result['flavors'], expected['flavors'])

    def test_show(self):
        resp = FakeResponse()
        self.flavor_action_controller.show(self.req, resp, '0')
        self.assertEqual({
            'id': '0',
            'os-flavor-access:is_public': True
        }, resp.obj['flavor'])
        self.flavor_action_controller.show(self.req, resp, '2')
        self.assertEqual({
            'id': '0',
            'os-flavor-access:is_public': False
        }, resp.obj['flavor'])

    def test_detail(self):
        resp = FakeResponse()
        self.flavor_action_controller.detail(self.req, resp)
        self.assertEqual([{
            'id': '0',
            'os-flavor-access:is_public': True
        }, {
            'id': '2',
            'os-flavor-access:is_public': False
        }], resp.obj['flavors'])

    def test_create(self):
        resp = FakeResponse()
        self.flavor_action_controller.create(self.req, {}, resp)
        self.assertEqual({
            'id': '0',
            'os-flavor-access:is_public': True
        }, resp.obj['flavor'])

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_add_tenant_access(self, mock_api_get):
        def stub_add_flavor_access(context, flavorid, projectid):
            self.assertEqual('3', flavorid, "flavorid")
            self.assertEqual("proj2", projectid, "projectid")

        self.stub_out('nova.db.flavor_access_add', stub_add_flavor_access)
        expected = {
            'flavor_access': [{
                'flavor_id': '3',
                'tenant_id': 'proj3'
            }]
        }
        body = {'addTenantAccess': {'tenant': 'proj2'}}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)

        result = self.flavor_action_controller._add_tenant_access(req,
                                                                  '3',
                                                                  body=body)
        self.assertEqual(result, expected)

    @mock.patch('nova.objects.Flavor.get_by_flavor_id',
                side_effect=exception.FlavorNotFound(flavor_id='1'))
    def test_add_tenant_access_with_flavor_not_found(self, mock_get):
        body = {'addTenantAccess': {'tenant': 'proj2'}}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        self.assertRaises(exc.HTTPNotFound,
                          self.flavor_action_controller._add_tenant_access,
                          req,
                          '2',
                          body=body)

    def test_add_tenant_access_with_no_tenant(self):
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        body = {'addTenantAccess': {'foo': 'proj2'}}
        self.assertRaises(self.validation_ex,
                          self.flavor_action_controller._add_tenant_access,
                          req,
                          '2',
                          body=body)
        body = {'addTenantAccess': {'tenant': ''}}
        self.assertRaises(self.validation_ex,
                          self.flavor_action_controller._add_tenant_access,
                          req,
                          '2',
                          body=body)

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_add_tenant_access_with_already_added_access(self, mock_api_get):
        def stub_add_flavor_access(context, flavorid, projectid):
            raise exception.FlavorAccessExists(flavor_id=flavorid,
                                               project_id=projectid)

        self.stub_out('nova.db.flavor_access_add', stub_add_flavor_access)
        body = {'addTenantAccess': {'tenant': 'proj2'}}
        self.assertRaises(exc.HTTPConflict,
                          self.flavor_action_controller._add_tenant_access,
                          self.req,
                          '3',
                          body=body)

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_remove_tenant_access_with_bad_access(self, mock_api_get):
        def stub_remove_flavor_access(context, flavorid, projectid):
            raise exception.FlavorAccessNotFound(flavor_id=flavorid,
                                                 project_id=projectid)

        self.stub_out('nova.db.flavor_access_remove',
                      stub_remove_flavor_access)
        body = {'removeTenantAccess': {'tenant': 'proj2'}}
        self.assertRaises(exc.HTTPNotFound,
                          self.flavor_action_controller._remove_tenant_access,
                          self.req,
                          '3',
                          body=body)

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_add_tenant_access_is_public(self, mock_api_get):
        body = {'addTenantAccess': {'tenant': 'proj2'}}
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        req.api_version_request = api_version.APIVersionRequest('2.7')
        self.assertRaises(exc.HTTPConflict,
                          self.flavor_action_controller._add_tenant_access,
                          req,
                          '1',
                          body=body)

    @mock.patch('nova.objects.Flavor._flavor_get_by_flavor_id_from_db',
                side_effect=exception.FlavorNotFound(flavor_id='foo'))
    def test_delete_tenant_access_with_no_tenant(self, mock_api_get):
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        body = {'removeTenantAccess': {'foo': 'proj2'}}
        self.assertRaises(self.validation_ex,
                          self.flavor_action_controller._remove_tenant_access,
                          req,
                          '2',
                          body=body)
        body = {'removeTenantAccess': {'tenant': ''}}
        self.assertRaises(self.validation_ex,
                          self.flavor_action_controller._remove_tenant_access,
                          req,
                          '2',
                          body=body)

    @mock.patch('nova.api.openstack.identity.verify_project_id',
                side_effect=exc.HTTPBadRequest(
                    explanation="Project ID proj2 is not a valid project."))
    def test_add_tenant_access_with_invalid_tenant(self, mock_verify):
        """Tests the case that the tenant does not exist in Keystone."""
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        body = {'addTenantAccess': {'tenant': 'proj2'}}
        self.assertRaises(exc.HTTPBadRequest,
                          self.flavor_action_controller._add_tenant_access,
                          req,
                          '2',
                          body=body)
        mock_verify.assert_called_once_with(req.environ['nova.context'],
                                            'proj2')

    @mock.patch('nova.api.openstack.identity.verify_project_id',
                side_effect=exc.HTTPBadRequest(
                    explanation="Project ID proj2 is not a valid project."))
    def test_remove_tenant_access_with_invalid_tenant(self, mock_verify):
        """Tests the case that the tenant does not exist in Keystone."""
        req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
                                      use_admin_context=True)
        body = {'removeTenantAccess': {'tenant': 'proj2'}}
        self.assertRaises(exc.HTTPBadRequest,
                          self.flavor_action_controller._remove_tenant_access,
                          req,
                          '2',
                          body=body)
        mock_verify.assert_called_once_with(req.environ['nova.context'],
                                            'proj2')
示例#29
0
def fake_get_flavor_projects_from_db(context, flavorid):
    raise exception.FlavorNotFound(flavor_id=flavorid)
示例#30
0
class FlavorManageTestV2_55(FlavorManageTestV21):
    microversion = '2.55'

    def setUp(self):
        super(FlavorManageTestV2_55, self).setUp()
        # Send a description in POST /flavors requests.
        self.request_body['flavor']['description'] = 'test description'

    def test_create_with_description(self):
        # test_create already tests this.
        pass

    @mock.patch('nova.objects.Flavor.get_by_flavor_id')
    @mock.patch('nova.objects.Flavor.save')
    def test_flavor_update_description(self, mock_flavor_save, mock_get):
        """Tests updating a flavor description."""
        # First create a flavor.
        flavor = self._create_flavor_success_case(self.request_body)['flavor']
        self.assertEqual('test description', flavor['description'])
        mock_get.return_value = objects.Flavor(
            flavorid=flavor['id'],
            name=flavor['name'],
            memory_mb=flavor['ram'],
            vcpus=flavor['vcpus'],
            root_gb=flavor['disk'],
            swap=flavor['swap'],
            ephemeral_gb=flavor['OS-FLV-EXT-DATA:ephemeral'],
            disabled=flavor['OS-FLV-DISABLED:disabled'],
            is_public=flavor['os-flavor-access:is_public'],
            rxtx_factor=flavor['rxtx_factor'],
            description=flavor['description'])
        # Now null out the flavor description.
        flavor = self.controller._update(
            self._get_http_request(),
            flavor['id'],
            body={'flavor': {
                'description': None
            }})['flavor']
        self.assertIsNone(flavor['description'])
        mock_get.assert_called_once_with(
            test.MatchType(fakes.FakeRequestContext), flavor['id'])
        mock_flavor_save.assert_called_once_with()

    @mock.patch('nova.objects.Flavor.get_by_flavor_id',
                side_effect=exception.FlavorNotFound(flavor_id='notfound'))
    def test_flavor_update_not_found(self, mock_get):
        """Tests that a 404 is returned if the flavor is not found."""
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller._update,
                          self._get_http_request(),
                          'notfound',
                          body={'flavor': {
                              'description': None
                          }})

    def test_flavor_update_missing_description(self):
        """Tests that a schema validation error is raised if no description
        is provided in the update request body.
        """
        self.assertRaises(self.validation_error,
                          self.controller._update,
                          self._get_http_request(),
                          'invalid',
                          body={'flavor': {}})

    def test_create_with_invalid_description(self):
        # NOTE(mriedem): Intentionally not using ddt for this since ddt will
        # create a test name that has 65536 'a's in the name which blows up
        # the console output.
        for description in (
                'bad !@#!$%\x00 description',  # printable chars
                'a' * 65536):  # maxLength
            self.request_body['flavor']['description'] = description
            self.assertRaises(self.validation_error,
                              self.controller._create,
                              self._get_http_request(),
                              body=self.request_body)

    @mock.patch('nova.objects.Flavor.get_by_flavor_id')
    @mock.patch('nova.objects.Flavor.save')
    def test_update_with_invalid_description(self, mock_flavor_save, mock_get):
        # First create a flavor.
        flavor = self._create_flavor_success_case(self.request_body)['flavor']
        self.assertEqual('test description', flavor['description'])
        mock_get.return_value = objects.Flavor(
            flavorid=flavor['id'],
            name=flavor['name'],
            memory_mb=flavor['ram'],
            vcpus=flavor['vcpus'],
            root_gb=flavor['disk'],
            swap=flavor['swap'],
            ephemeral_gb=flavor['OS-FLV-EXT-DATA:ephemeral'],
            disabled=flavor['OS-FLV-DISABLED:disabled'],
            is_public=flavor['os-flavor-access:is_public'],
            description=flavor['description'])
        # NOTE(mriedem): Intentionally not using ddt for this since ddt will
        # create a test name that has 65536 'a's in the name which blows up
        # the console output.
        for description in (
                'bad !@#!$%\x00 description',  # printable chars
                'a' * 65536):  # maxLength
            self.request_body['flavor']['description'] = description
            self.assertRaises(self.validation_error,
                              self.controller._update,
                              self._get_http_request(),
                              flavor['id'],
                              body={'flavor': {
                                  'description': description
                              }})