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' }})
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)
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)
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, }
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)
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)
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)
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)
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)
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)
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()
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)
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)
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)
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)
def fake_compute_api_resize_non_found_flavor(self, context, instance_id): raise exception.FlavorNotFound(flavor_id='')
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)
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)
def stub_flavor_access_add(context, flavorid, project_id): raise exception.FlavorNotFound(flavor_id=flavorid)
def stub_remove_flavor_access(context, flavorid, projectid): raise exception.FlavorNotFound(flavor_id=flavorid)
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)
def stub_remove_flavor_access(flavorid, projectid, ctxt=None): raise exception.FlavorNotFound(flavor_id=flavorid)
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')
def fake_get_flavor_projects_from_db(context, flavorid): raise exception.FlavorNotFound(flavor_id=flavorid)
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 }})