def test_reboot_hard_with_hard_in_progress(self): body = dict(reboot=dict(type="HARD")) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( vm_state=vm_states.ACTIVE, task_state=task_states.REBOOTING_HARD)) self.controller._action_reboot(self.req, FAKE_UUID, body=body)
def test_reboot_hard_with_hard_in_progress(self): body = dict(reboot=dict(type="HARD")) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( vm_state=vm_states.ACTIVE, task_state=task_states.REBOOTING_HARD)) self.controller._action_reboot(self.req, FAKE_UUID, body=body)
def test_rebuild_accepted_minimum_pass_disabled(self): # run with enable_instance_password disabled to verify adminPass # is missing from response. See lp bug 921814 self.flags(enable_instance_password=False, group='api') return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) self_href = 'http://localhost/v2/servers/%s' % FAKE_UUID body = { "rebuild": { "imageRef": self._image_href, }, } robj = self.controller._action_rebuild(self.req, FAKE_UUID, body=body) body = robj.obj self.assertEqual(body['server']['image']['id'], '2') self.assertNotIn("adminPass", body['server']) self.assertEqual(robj['location'], self_href) # pep3333 requires applications produces headers which are str self.assertEqual(str, type(robj['location']))
def test_show_normal_server(self, mock_get_instance): meta = {"preemptible": False} instance = fake_instance.fake_instance_obj( self.req.environ["nova.context"], expected_attrs={"system_metadata": meta}) mock_get_instance.return_value = instance self.stub_out('nova.db.instance_get', os_api_fakes.fake_instance_get(system_metadata=meta)) self.stub_out('nova.db.instance_get_by_uuid', os_api_fakes.fake_instance_get(system_metadata=meta)) # NOTE(sdague): because of the way extensions work, we have to # also stub out the Request compute cache with a real compute # object. Delete this once we remove all the gorp of # extensions modifying the server objects. self.stub_out('nova.api.openstack.wsgi.Request.get_db_instance', os_api_fakes.fake_compute_get(system_metadata=meta)) req = os_api_fakes.HTTPRequest.blank( self.base_url + '/servers/' + instance.uuid) req.headers['Content-Type'] = 'application/json' response = req.get_response(self.app) self.assertEqual(200, response.status_int) res_dict = jsonutils.loads(response.body) self.assertTrue(res_dict['server']['preemptible'])
def test_reboot_soft_with_soft_in_progress_raises_conflict(self): body = dict(reboot=dict(type="SOFT")) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get(vm_state=vm_states.ACTIVE, task_state=task_states.REBOOTING)) self.assertRaises(webob.exc.HTTPConflict, self.controller._action_reboot, self.req, FAKE_UUID, body=body)
def test_reboot_soft_with_soft_in_progress_raises_conflict(self): body = dict(reboot=dict(type="SOFT")) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get(vm_state=vm_states.ACTIVE, task_state=task_states.REBOOTING)) self.assertRaises(webob.exc.HTTPConflict, self.controller._action_reboot, self.req, FAKE_UUID, body=body)
def setUp(self): super(BadStateServerMetaDataTestV21, self).setUp() self.stub_out('nova.db.api.instance_metadata_get', return_server_metadata) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( **{'uuid': '0cc3346e-9fef-4445-abe6-5d2b2690ec64', 'name': 'fake', 'vm_state': vm_states.BUILDING})) self.stub_out('nova.db.api.instance_metadata_delete', delete_server_metadata) self._set_up_resources()
def setUp(self): super(ServerMetaDataTestV21, self).setUp() metadata = stub_server_metadata() self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( **{'uuid': '0cc3346e-9fef-4445-abe6-5d2b2690ec64', 'name': 'fake', 'launched_at': timeutils.utcnow(), 'vm_state': vm_states.ACTIVE, 'metadata': metadata})) self.stub_out('nova.db.api.instance_metadata_get', return_server_metadata) self._set_up_resources()
def setUp(self): super(BadStateServerMetaDataTestV21, self).setUp() self.stub_out('nova.db.api.instance_metadata_get', return_server_metadata) self.stub_out( 'nova.compute.rpcapi.ComputeAPI.change_instance_metadata', fake_change_instance_metadata) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( **{'uuid': '0cc3346e-9fef-4445-abe6-5d2b2690ec64', 'name': 'fake', 'vm_state': vm_states.BUILDING})) self.stub_out('nova.db.api.instance_metadata_delete', delete_server_metadata) self._set_up_resources()
def test_show(self): self.stub_out('nova.db.instance_get', fakes.fake_instance_get()) self.stub_out('nova.db.instance_get_by_uuid', fakes.fake_instance_get()) # NOTE(sdague): because of the way extensions work, we have to # also stub out the Request compute cache with a real compute # object. Delete this once we remove all the gorp of # extensions modifying the server objects. self.stub_out('nova.api.openstack.wsgi.Request.get_db_instance', fakes.fake_compute_get()) req = fakes.HTTPRequest.blank(self.base_url + uuids.sentinel) req.headers['Content-Type'] = 'application/json' response = req.get_response(self.app) self.assertEqual(response.status_int, 200) res_dict = jsonutils.loads(response.body) self.assertIn('config_drive', res_dict['server'])
def test_rebuild_admin_pass(self): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "adminPass": "******", }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['image']['id'], '2') self.assertEqual(body['server']['adminPass'], 'asdf')
def test_show(self): self.stub_out('nova.db.instance_get', fakes.fake_instance_get()) self.stub_out('nova.db.instance_get_by_uuid', fakes.fake_instance_get()) # NOTE(sdague): because of the way extensions work, we have to # also stub out the Request compute cache with a real compute # object. Delete this once we remove all the gorp of # extensions modifying the server objects. self.stub_out('nova.api.openstack.wsgi.Request.get_db_instance', fakes.fake_compute_get()) req = fakes.HTTPRequest.blank(self.base_url + uuids.sentinel) req.headers['Content-Type'] = 'application/json' response = req.get_response(self.app) self.assertEqual(response.status_int, 200) res_dict = jsonutils.loads(response.body) self.assertIn('config_drive', res_dict['server'])
def test_rebuild_admin_pass(self): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "adminPass": "******", }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['image']['id'], '2') self.assertEqual(body['server']['adminPass'], 'asdf')
def setUp(self): super(ServerMetaDataTestV21, self).setUp() metadata = stub_server_metadata() self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get( **{'uuid': '0cc3346e-9fef-4445-abe6-5d2b2690ec64', 'name': 'fake', 'launched_at': timeutils.utcnow(), 'vm_state': vm_states.ACTIVE, 'metadata': metadata})) self.stub_out('nova.db.api.instance_metadata_get', return_server_metadata) self.stub_out( 'nova.compute.rpcapi.ComputeAPI.change_instance_metadata', fake_change_instance_metadata) self._set_up_resources()
def setUp(self): super(AccessIPsAPIValidationTestV21, self).setUp() def fake_save(context, **kwargs): pass def fake_rebuild(*args, **kwargs): pass fakes.stub_out_nw_api(self) self._set_up_controller() self.useFixture(fixtures.GlanceFixture(self)) self.stub_out( 'nova.compute.api.API.get', # This project_id matches fakes.HTTPRequest.blank. fakes.fake_compute_get(project_id=fakes.FAKE_PROJECT_ID)) self.stub_out('nova.objects.instance.Instance.save', fake_save) self.stub_out('nova.compute.api.API.rebuild', fake_rebuild)
def test_rebuild_accepted_with_metadata(self): metadata = {'new': 'metadata'} return_server = fakes.fake_compute_get(metadata=metadata, vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "metadata": metadata, }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['metadata'], metadata)
def test_rebuild_accepted_with_metadata(self): metadata = {'new': 'metadata'} return_server = fakes.fake_compute_get(metadata=metadata, vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "metadata": metadata, }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['metadata'], metadata)
def setUp(self): super(ServerActionsControllerTestV21, self).setUp() self.flags(group='glance', api_servers=['http://localhost:9292']) self.stub_out('nova.compute.api.API.get', fakes.fake_compute_get(vm_state=vm_states.ACTIVE, host='fake_host')) self.stub_out('nova.objects.Instance.save', lambda *a, **kw: None) fakes.stub_out_compute_api_snapshot(self) fake.stub_out_image_service(self) self.flags(enable_instance_password=True, group='api') self._image_href = '155d900f-4e14-4e4c-a73d-069cbf4541e6' self.controller = self._get_controller() self.compute_api = self.controller.compute_api # We don't care about anything getting as far as hitting the compute # RPC API so we just mock it out here. mock_rpcapi = mock.patch.object(self.compute_api, 'compute_rpcapi') mock_rpcapi.start() self.addCleanup(mock_rpcapi.stop) # The project_id here matches what is used by default in # fake_compute_get which need to match for policy checks. self.req = fakes.HTTPRequest.blank('', project_id='fake_project') self.context = self.req.environ['nova.context'] self.image_api = image.API() # Assume that anything that hits the compute API and looks for a # RequestSpec doesn't care about it, since testing logic that deep # should be done in nova.tests.unit.compute.test_compute_api. mock_reqspec = mock.patch('nova.objects.RequestSpec') mock_reqspec.start() self.addCleanup(mock_reqspec.stop) # Similarly we shouldn't care about anything hitting conductor from # these tests. mock_conductor = mock.patch.object( self.controller.compute_api, 'compute_task_api') mock_conductor.start() self.addCleanup(mock_conductor.stop) # Assume that none of the tests are using ports with resource requests. self.mock_list_port = self.useFixture( fixtures.MockPatch( 'nova.network.neutronv2.api.API.list_ports')).mock self.mock_list_port.return_value = {'ports': []}
def test_rebuild_accepted_minimum(self): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) self_href = 'http://localhost/v2/servers/%s' % FAKE_UUID body = { "rebuild": { "imageRef": self._image_href, }, } robj = self.controller._action_rebuild(self.req, FAKE_UUID, body=body) body = robj.obj self.assertEqual(body['server']['image']['id'], '2') self.assertEqual(len(body['server']['adminPass']), CONF.password_length) self.assertEqual(robj['location'], self_href.encode('utf-8'))
def setUp(self): super(AccessIPsAPIValidationTestV21, self).setUp() def fake_save(context, **kwargs): pass def fake_rebuild(*args, **kwargs): pass # Neutron security groups are tested in test_neutron_security_groups.py self.flags(use_neutron=False) fakes.stub_out_nw_api(self) self._set_up_controller() fake.stub_out_image_service(self) self.stub_out('nova.compute.api.API.get', # This project_id matches fakes.HTTPRequest.blank. fakes.fake_compute_get(project_id=fakes.FAKE_PROJECT_ID)) self.stub_out('nova.objects.instance.Instance.save', fake_save) self.stub_out('nova.compute.api.API.rebuild', fake_rebuild) self.req = fakes.HTTPRequest.blank('')
def test_rebuild_admin_pass_pass_disabled(self): # run with enable_instance_password disabled to verify adminPass # is missing from response. See lp bug 921814 self.flags(enable_instance_password=False, group='api') return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "adminPass": "******", }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['image']['id'], '2') self.assertNotIn('adminPass', body['server'])
def test_rebuild_admin_pass_pass_disabled(self): # run with enable_instance_password disabled to verify adminPass # is missing from response. See lp bug 921814 self.flags(enable_instance_password=False, group='api') return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, "adminPass": "******", }, } body = self.controller._action_rebuild(self.req, FAKE_UUID, body=body).obj self.assertEqual(body['server']['image']['id'], '2') self.assertNotIn('adminPass', body['server'])
def test_rebuild_accepted_minimum(self): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) self_href = 'http://localhost/v2/servers/%s' % FAKE_UUID body = { "rebuild": { "imageRef": self._image_href, }, } robj = self.controller._action_rebuild(self.req, FAKE_UUID, body=body) body = robj.obj self.assertEqual(body['server']['image']['id'], '2') self.assertEqual(len(body['server']['adminPass']), CONF.password_length) self.assertEqual(robj['location'], self_href) # pep3333 requires applications produces headers which are str self.assertEqual(str, type(robj['location']))
def _test_rebuild_preserve_ephemeral(self, value=None): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, }, } if value is not None: body['rebuild']['preserve_ephemeral'] = value with mock.patch.object(compute_api.API, 'rebuild') as mock_rebuild: self.controller._action_rebuild(self.req, FAKE_UUID, body=body) if value is not None: mock_rebuild.assert_called_once_with(self.context, mock.ANY, self._image_href, mock.ANY, preserve_ephemeral=value) else: mock_rebuild.assert_called_once_with(self.context, mock.ANY, self._image_href, mock.ANY)
def _test_rebuild_preserve_ephemeral(self, value=None): return_server = fakes.fake_compute_get(image_ref='2', vm_state=vm_states.ACTIVE, host='fake_host') self.stub_out('nova.compute.api.API.get', return_server) body = { "rebuild": { "imageRef": self._image_href, }, } if value is not None: body['rebuild']['preserve_ephemeral'] = value with mock.patch.object(compute_api.API, 'rebuild') as mock_rebuild: self.controller._action_rebuild(self.req, FAKE_UUID, body=body) if value is not None: mock_rebuild.assert_called_once_with(self.context, mock.ANY, self._image_href, mock.ANY, preserve_ephemeral=value) else: mock_rebuild.assert_called_once_with(self.context, mock.ANY, self._image_href, mock.ANY)
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_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 _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_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)