def test_register_image_by_bdm(self, get_os_image): self.glance.images.create.return_value = (fakes.OSImage( fakes.OS_IMAGE_2)) self.db_api.add_item.side_effect = (tools.get_db_api_add_item( fakes.ID_EC2_IMAGE_2)) self.set_mock_db_items(fakes.DB_SNAPSHOT_1, fakes.DB_IMAGE_AKI_1, fakes.DB_IMAGE_ARI_1) get_os_image.side_effect = [ fakes.OSImage(fakes.OS_IMAGE_AKI_1), fakes.OSImage(fakes.OS_IMAGE_ARI_1) ] resp = self.execute( 'RegisterImage', { 'RootDeviceName': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'Name': 'fake_name', 'KernelId': fakes.ID_EC2_IMAGE_AKI_1, 'RamdiskId': fakes.ID_EC2_IMAGE_ARI_1, 'BlockDeviceMapping.1.DeviceName': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'BlockDeviceMapping.1.Ebs.SnapshotId': fakes.ID_EC2_SNAPSHOT_1 }) self.assertThat( resp, matchers.DictMatches({'imageId': fakes.ID_EC2_IMAGE_2})) self.db_api.add_item.assert_called_once_with( mock.ANY, 'ami', { 'os_id': fakes.ID_OS_IMAGE_2, 'is_public': False, 'description': None }, project_id=None) self.assertEqual(1, self.glance.images.create.call_count) self.assertEqual((), self.glance.images.create.call_args[0]) self.assertIn('properties', self.glance.images.create.call_args[1]) self.assertIsInstance( self.glance.images.create.call_args[1]['properties'], dict) bdm = self.glance.images.create.call_args[1]['properties'].pop( 'block_device_mapping', None) self.assertEqual( { 'is_public': False, 'size': 0, 'name': 'fake_name', 'properties': { 'root_device_name': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'kernel_id': fakes.ID_OS_IMAGE_AKI_1, 'ramdisk_id': fakes.ID_OS_IMAGE_ARI_1 } }, self.glance.images.create.call_args[1]) self.assertEqual([{ 'device_name': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'delete_on_termination': True, 'snapshot_id': fakes.ID_OS_SNAPSHOT_1 }], json.loads(bdm)) get_os_image.assert_has_calls([ mock.call(mock.ANY, fakes.ID_EC2_IMAGE_AKI_1), mock.call(mock.ANY, fakes.ID_EC2_IMAGE_ARI_1) ])
def test_s3_parse_manifest(self): db_api = self.mock_db() glance = self.mock_glance() db_api.set_mock_items(fakes.DB_IMAGE_AKI_1, fakes.DB_IMAGE_ARI_1) glance.images.get.side_effect = (tools.get_by_1st_arg_getter({ fakes.ID_OS_IMAGE_AKI_1: fakes.OSImage(fakes.OS_IMAGE_AKI_1), fakes.ID_OS_IMAGE_ARI_1: fakes.OSImage(fakes.OS_IMAGE_ARI_1) })) metadata, image_parts, key, iv = image_api._s3_parse_manifest( base.create_context(), AMI_MANIFEST_XML) expected_metadata = { 'disk_format': 'ami', 'container_format': 'ami', 'properties': { 'architecture': 'x86_64', 'kernel_id': fakes.ID_OS_IMAGE_AKI_1, 'ramdisk_id': fakes.ID_OS_IMAGE_ARI_1, 'mappings': [{ "device": "sda1", "virtual": "ami" }, { "device": "/dev/sda1", "virtual": "root" }, { "device": "sda2", "virtual": "ephemeral0" }, { "device": "sda3", "virtual": "swap" }] } } self.assertThat( metadata, matchers.DictMatches(expected_metadata, orderless_lists=True)) self.assertThat(image_parts, matchers.ListMatches(['foo'])) self.assertEqual('foo', key) self.assertEqual('foo', iv) db_api.get_items_ids.assert_any_call( mock.ANY, 'aki', item_ids=(fakes.ID_EC2_IMAGE_AKI_1, ), item_os_ids=None) db_api.get_items_ids.assert_any_call( mock.ANY, 'ari', item_ids=(fakes.ID_EC2_IMAGE_ARI_1, ), item_os_ids=None)
def _get_new_ebs_image(self, image_project_id=None, bdm_image_project_id=None): os_image_id = fakes.random_os_id() os_snapshot_id = fakes.random_os_id() os_bdm_image_id = fakes.random_os_id() os_image = { 'id': os_image_id, 'owner': image_project_id, 'is_public': True, 'container_format': 'ami', 'bdm_v2': True, 'block_device_mapping': [{ 'device_name': '/dev/vds', 'source_type': 'snapshot', 'destination_type': 'volume', 'snapshot_id': os_snapshot_id }], } if os_bdm_image_id: os_image['block_device_mapping'].append({ 'device_name': '/dev/vdi', 'source_type': 'image', 'destination_type': 'volume', 'image_id': os_bdm_image_id, 'size': 100 }) os_snapshot = { 'id': os_snapshot_id, } os_bdm_image = { 'id': os_bdm_image_id, 'owner': bdm_image_project_id, 'is_public': True, } os_images = [fakes.OSImage(os_image)] if bdm_image_project_id: os_images.append(fakes.OSImage(os_bdm_image)) self.glance.images.list.return_value = os_images self.cinder.volume_snapshots.list.return_value = ([ fakes.OSSnapshot(os_snapshot) ] if image_project_id == fakes.ID_OS_PROJECT else []) images = image_api.describe_images(self.context) return next(i for i in images['imagesSet'] if i['blockDeviceMapping'])
def _setup_model(self): self.set_mock_db_items(fakes.DB_IMAGE_1, fakes.DB_IMAGE_2, fakes.DB_SNAPSHOT_1, fakes.DB_SNAPSHOT_2, fakes.DB_IMAGE_AKI_1, fakes.DB_IMAGE_ARI_1, fakes.DB_VOLUME_1, fakes.DB_VOLUME_2) self.db_api.get_public_items.return_value = [] self.glance.images.list.side_effect = ( lambda: [fakes.OSImage(fakes.OS_IMAGE_1), fakes.OSImage(fakes.OS_IMAGE_2)]) self.glance.images.get.side_effect = ( lambda os_id: (fakes.OSImage(fakes.OS_IMAGE_1) if os_id == fakes. ID_OS_IMAGE_1 else fakes.OSImage(fakes.OS_IMAGE_2) if os_id == fakes.ID_OS_IMAGE_2 else None))
def test_format_image(self): image_ids = { fakes.ID_OS_IMAGE_1: fakes.ID_EC2_IMAGE_1, fakes.ID_OS_IMAGE_AKI_1: fakes.ID_EC2_IMAGE_AKI_1, fakes.ID_OS_IMAGE_ARI_1: fakes.ID_EC2_IMAGE_ARI_1 } os_image = copy.deepcopy(fakes.OS_IMAGE_1) os_image['properties'] = {'image_location': 'location'} os_image['name'] = None image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('location', image['imageLocation']) self.assertEqual('location', image['name']) os_image['properties'] = {} os_image['name'] = 'fake_name' image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('None (fake_name)', image['imageLocation']) self.assertEqual('fake_name', image['name']) os_image['properties'] = { 'bdm_v2': True, 'root_device_name': '/dev/vda', 'block_device_mapping': [{ 'boot_index': 0, 'snapshot_id': fakes.ID_OS_SNAPSHOT_2 }] } image = image_api._format_image( 'fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids, snapshot_ids={fakes.ID_OS_SNAPSHOT_2: fakes.ID_EC2_SNAPSHOT_2}) self.assertEqual('ebs', image['rootDeviceType'])
def do_test(s3_conn, s3_download_file, s3_decrypt_image, s3_untarzip_image): (s3_conn.return_value. get_object.return_value) = {'Body': FILE_MANIFEST_XML} s3_download_file.return_value = tempf s3_untarzip_image.return_value = tempf os_image_id = fakes.random_os_id() (glance.images.create.return_value) = ( fakes.OSImage({'id': os_image_id, 'status': 'queued'})) data = [ ({'image_location': 'testbucket_1/test.img.manifest.xml'}, 'testbucket_1', 'test.img.manifest.xml'), ({'image_location': '/testbucket_2/test.img.manifest.xml'}, 'testbucket_2', 'test.img.manifest.xml')] for mdata, bucket, manifest in data: image = image_api._s3_create(fake_context, mdata) eventlet.sleep() self.glance.images.update.assert_called_with( os_image_id, image_state='available') self.glance.images.upload.assert_any_call( os_image_id, mock.ANY) s3_conn.return_value.get_object.assert_called_with( Bucket=bucket, Key=manifest) s3_download_file.assert_called_with( mock.ANY, bucket, 'foo', mock.ANY) s3_decrypt_image.assert_called_with( fake_context, mock.ANY, 'foo', 'foo', mock.ANY) s3_untarzip_image.assert_called_with(mock.ANY, mock.ANY) do_test()
def test_describe_new_instance_then_its_alien_image_attribute(self): os_instance_id = fakes.random_os_id() os_image_id = fakes.random_os_id() alien_project_id = fakes.random_os_id() os_instance = { 'id': os_instance_id, 'flavor': {'id': 'fake'}, 'image': {'id': os_image_id}, } os_image = { 'id': os_image_id, 'owner': alien_project_id, 'is_public': True, } self.nova_admin.servers.list.return_value = [ fakes.OSInstance_full(os_instance)] self.glance.images.get.return_value = fakes.OSImage(os_image) reservations = instance_api.describe_instances(self.context) instance = reservations['reservationSet'][0]['instancesSet'][0] image_id = instance['imageId'] # NOTE(ft): ensure that InvalidAMIID.NotFound is not raised self.assertRaises(exception.AuthFailure, image_api.describe_image_attribute, self.context, image_id, 'description')
def test_get_os_image(self, db_api, glance): glance = glance.return_value fake_context = base.create_context() os_image = fakes.OSImage(fakes.OS_IMAGE_1) glance.images.get.return_value = os_image # check normal flow db_api.get_items_ids.return_value = [(fakes.ID_EC2_IMAGE_1, fakes.ID_OS_IMAGE_1)] self.assertEqual( os_image, ec2utils.get_os_image(fake_context, fakes.ID_EC2_IMAGE_1)) db_api.get_items_ids.assert_called_with( mock.ANY, 'ami', item_ids=(fakes.ID_EC2_IMAGE_1, ), item_os_ids=None) glance.images.get.assert_called_with(fakes.ID_OS_IMAGE_1) # check case of absence of an image in OS glance.images.get.side_effect = glance_exception.HTTPNotFound() self.assertRaises(exception.InvalidAMIIDNotFound, ec2utils.get_os_image, fake_context, fakes.ID_EC2_IMAGE_1) # check case of an unknown image id db_api.get_items_ids.return_value = [] self.assertRaises(exception.InvalidAMIIDNotFound, ec2utils.get_os_image, fake_context, fakes.random_ec2_id('ami')) # check case of creating image db_api.get_items_ids.return_value = [(fakes.ID_EC2_IMAGE_1, None)] self.assertIsNone( ec2utils.get_os_image(fake_context, fakes.ID_EC2_IMAGE_1))
def _setup_model(self): self.set_mock_db_items(fakes.DB_IMAGE_1, fakes.DB_IMAGE_2, fakes.DB_SNAPSHOT_1, fakes.DB_SNAPSHOT_2, fakes.DB_IMAGE_AKI_1, fakes.DB_IMAGE_ARI_1, fakes.DB_VOLUME_1, fakes.DB_VOLUME_2) self.db_api.get_public_items.return_value = [] # NOTE(ft): glance.image.list returns an iterator, not just a list self.glance.images.list.side_effect = ( lambda: (fakes.OSImage(i) for i in (fakes.OS_IMAGE_1, fakes.OS_IMAGE_2))) self.glance.images.get.side_effect = ( lambda os_id: (fakes.OSImage(fakes.OS_IMAGE_1, from_get=True) if os_id == fakes.ID_OS_IMAGE_1 else fakes.OSImage( fakes.OS_IMAGE_2, from_get=True) if os_id == fakes.ID_OS_IMAGE_2 else None))
def test_register_image_by_s3(self, s3_create): s3_create.return_value = fakes.OSImage(fakes.OS_IMAGE_1) self.db_api.add_item.side_effect = (tools.get_db_api_add_item( fakes.ID_EC2_IMAGE_1)) resp = self.execute('RegisterImage', {'ImageLocation': fakes.LOCATION_IMAGE_1}) self.assertThat( resp, matchers.DictMatches({'imageId': fakes.ID_EC2_IMAGE_1})) s3_create.assert_called_once_with( mock.ANY, { 'name': fakes.LOCATION_IMAGE_1, 'properties': { 'image_location': fakes.LOCATION_IMAGE_1 } }) s3_create.reset_mock() resp = self.execute('RegisterImage', { 'ImageLocation': fakes.LOCATION_IMAGE_1, 'Name': 'an image name' }) self.assertThat( resp, matchers.DictMatches({'imageId': fakes.ID_EC2_IMAGE_1})) s3_create.assert_called_once_with( mock.ANY, { 'name': 'an image name', 'properties': { 'image_location': fakes.LOCATION_IMAGE_1 } })
def _test_describe_new_instance_then_its_image(self, image_project_id): os_instance_id = fakes.random_os_id() os_image_id = fakes.random_os_id() os_instance = { 'id': os_instance_id, 'flavor': {'id': 'fake'}, 'image': {'id': os_image_id}, } os_image = { 'id': os_image_id, 'owner': image_project_id, 'is_public': True, } self.nova_admin.servers.list.return_value = [ fakes.OSInstance_full(os_instance)] self.glance.images.list.return_value = [fakes.OSImage(os_image)] reservations = instance_api.describe_instances(self.context) instance = reservations['reservationSet'][0]['instancesSet'][0] image_id = instance['imageId'] image = (image_api.describe_images(self.context, image_id=[image_id]) ['imagesSet'][0]) self.assertEqual(image_id, image['imageId']) self.assertEqual(image_project_id, image['imageOwnerId']) expected_project_id = (fakes.ID_OS_PROJECT if image_project_id == fakes.ID_OS_PROJECT else None) self.assert_image_project(expected_project_id, image['imageId'])
def _test_create_image(self, instance_status, no_reboot, is_ebs_instance): self.set_mock_db_items(fakes.DB_INSTANCE_2) os_instance = mock.MagicMock() os_instance.configure_mock(id=fakes.ID_OS_INSTANCE_2, status=instance_status) stop_called = iter([False, True]) os_instance.stop.side_effect = lambda: next(stop_called) os_instance.get.side_effect = lambda: (setattr( os_instance, 'status', 'SHUTOFF') if next(stop_called) else None) image_id = fakes.random_ec2_id('ami') os_image_id = fakes.random_os_id() os_instance.create_image.return_value = os_image_id self.glance.images.get.return_value = fakes.OSImage( {'id': os_image_id}, from_get=True) self.nova.servers.get.return_value = os_instance is_ebs_instance.return_value = True self.db_api.add_item.side_effect = tools.get_db_api_add_item(image_id) resp = self.execute( 'CreateImage', { 'InstanceId': fakes.ID_EC2_INSTANCE_2, 'Name': 'fake_name', 'Description': 'fake desc', 'NoReboot': str(no_reboot) }) self.assertEqual({'imageId': image_id}, resp) self.db_api.get_item_by_id.assert_called_once_with( mock.ANY, fakes.ID_EC2_INSTANCE_2) self.nova.servers.get.assert_called_once_with(fakes.ID_OS_INSTANCE_2) is_ebs_instance.assert_called_once_with(mock.ANY, os_instance.id) expected_image = {'is_public': False, 'description': 'fake desc'} if no_reboot: expected_image['os_id'] = os_image_id self.db_api.add_item.assert_called_once_with(mock.ANY, 'ami', expected_image) if not no_reboot: eventlet.sleep() if not no_reboot: os_instance.stop.assert_called_once_with() os_instance.get.assert_called_once_with() os_instance.start.assert_called_once_with() if no_reboot: os_instance.create_image.assert_called_once_with('fake_name') else: os_instance.create_image.assert_called_once_with( 'fake_name', metadata={'ec2_id': image_id}) self.db_api.update_item.assert_called_once_with( mock.ANY, { 'id': image_id, 'is_public': False, 'description': 'fake desc', 'os_id': os_image_id, 'vpc_id': None }) self.db_api.reset_mock() self.nova.servers.reset_mock()
def _test_describe_new_images(self, image_project_id=None, aki_image_project_id=None, with_id_mapping=False): os_image_id = fakes.random_os_id() os_aki_image_id = fakes.random_os_id() os_image = { 'id': os_image_id, 'owner': image_project_id, 'is_public': True, 'container_format': 'ami', 'properties': { 'kernel_id': os_aki_image_id, }, } os_aki_image = { 'id': os_aki_image_id, 'owner': aki_image_project_id, 'is_public': True, 'container_format': 'aki', } self.glance.images.list.return_value = ( [fakes.OSImage(os_image), fakes.OSImage(os_aki_image)] if with_id_mapping else [fakes.OSImage(os_aki_image), fakes.OSImage(os_image)]) images = image_api.describe_images(self.context) image = next(i for i in images['imagesSet'] if i['imageType'] == 'machine') aki_image = next(i for i in images['imagesSet'] if i['imageType'] == 'kernel') self.assertEqual(image_project_id, image['imageOwnerId']) self.assert_image_project( (image_project_id if image_project_id == fakes.ID_OS_PROJECT else None), image['imageId']) self.assertEqual(aki_image_project_id, aki_image['imageOwnerId']) self.assert_image_project( (aki_image_project_id if aki_image_project_id == fakes.ID_OS_PROJECT else None), aki_image['imageId'])
def test_register_image_by_url(self, is_ebs_instance): self.set_mock_db_items(fakes.DB_INSTANCE_2) is_ebs_instance.return_value = True # Setup the mock parameters image_id = fakes.random_ec2_id('ami') os_image_id = fakes.random_os_id() self.glance.images.create.return_value = fakes.OSImage( {'id': os_image_id}, from_get=True) self.db_api.add_item.side_effect = tools.get_db_api_add_item(image_id) # Setup Import Command import_command = 'RegisterImage' # Setup the import arguments args = { 'Name': 'TestImage123', 'ImageLocation': fakes.LOCATION_IMAGE_2, 'Architecture': 'x86_64' } # Execute the import image process resp = self.execute(import_command, args) # Assert that the image returned is equal to what was expected self.assertEqual({'imageId': image_id}, resp) # Assert that Glance Image Create was called self.glance.images.create.assert_called_once_with( name='TestImage123', disk_format='raw', container_format='bare', visibility='private', architecture='x86_64', image_location=fakes.LOCATION_IMAGE_2) # Assert that Glance Image Import was called self.glance.images.image_import.assert_called_once_with( os_image_id, method='web-download', uri=fakes.LOCATION_IMAGE_2) # Assert that the image was created expected_image = {'is_public': False, 'os_id': mock.ANY, 'description': None} self.db_api.add_item.assert_called_once_with( mock.ANY, 'ami', expected_image) # Reset all test settings/state self.db_api.reset_mock() self.glance.reset_mock()
def test_s3_create_image_locations(self, osimage_update): self.configure(image_decryption_dir=None) _handle, tempf = tempfile.mkstemp() fake_context = base.create_context() with contextlib.nested( mock.patch('ec2api.api.image._s3_conn'), mock.patch('ec2api.api.image._s3_download_file'), mock.patch('ec2api.api.image._s3_decrypt_image'), mock.patch('ec2api.api.image._s3_untarzip_image')) as ( s3_conn, s3_download_file, s3_decrypt_image, s3_untarzip_image): (s3_conn.return_value.get_bucket.return_value.get_key.return_value. get_contents_as_string.return_value) = FILE_MANIFEST_XML s3_download_file.return_value = tempf s3_untarzip_image.return_value = tempf (self.glance.images.create.return_value) = (fakes.OSImage({ 'id': fakes.random_os_id(), 'status': 'queued' })) data = [({ 'properties': { 'image_location': 'testbucket_1/test.img.manifest.xml' } }, 'testbucket_1', 'test.img.manifest.xml'), ({ 'properties': { 'image_location': '/testbucket_2/test.img.manifest.xml' } }, 'testbucket_2', 'test.img.manifest.xml')] for mdata, bucket, manifest in data: image = image_api._s3_create(fake_context, mdata) eventlet.sleep() osimage_update.assert_called_with( image, properties={'image_state': 'available'}) osimage_update.assert_any_call(image, data=mock.ANY) s3_conn.return_value.get_bucket.assert_called_with(bucket) (s3_conn.return_value.get_bucket.return_value.get_key. assert_called_with(manifest)) (s3_conn.return_value.get_bucket.return_value.get_key. return_value.get_contents_as_string.assert_called_with()) s3_download_file.assert_called_with( s3_conn.return_value.get_bucket.return_value, 'foo', mock.ANY) s3_decrypt_image.assert_called_with(fake_context, mock.ANY, 'foo', 'foo', mock.ANY) s3_untarzip_image.assert_called_with(mock.ANY, mock.ANY)
def do_test(s3_conn, s3_download_file, s3_decrypt_image, s3_untarzip_image): (s3_conn.return_value.get_bucket.return_value.get_key.return_value. get_contents_as_string.return_value) = FILE_MANIFEST_XML s3_download_file.return_value = tempf s3_untarzip_image.return_value = tempf (glance.images.create.return_value) = (fakes.OSImage({ 'id': fakes.random_os_id(), 'status': 'queued' })) data = [({ 'properties': { 'image_location': 'testbucket_1/test.img.manifest.xml' } }, 'testbucket_1', 'test.img.manifest.xml'), ({ 'properties': { 'image_location': '/testbucket_2/test.img.manifest.xml' } }, 'testbucket_2', 'test.img.manifest.xml')] for mdata, bucket, manifest in data: image = image_api._s3_create(fake_context, mdata) eventlet.sleep() osimage_update.assert_called_with( image, properties={'image_state': 'available'}) osimage_update.assert_any_call(image, data=mock.ANY) s3_conn.return_value.get_bucket.assert_called_with(bucket) (s3_conn.return_value.get_bucket.return_value.get_key. assert_called_with(manifest)) (s3_conn.return_value.get_bucket.return_value.get_key. return_value.get_contents_as_string.assert_called_with()) s3_download_file.assert_called_with( s3_conn.return_value.get_bucket.return_value, 'foo', mock.ANY) s3_decrypt_image.assert_called_with(fake_context, mock.ANY, 'foo', 'foo', mock.ANY) s3_untarzip_image.assert_called_with(mock.ANY, mock.ANY) do_test()
def test_get_os_image(self, db_api, glance): glance = glance.return_value fake_context = mock.Mock(service_catalog=[{'type': 'fake'}]) os_image = fakes.OSImage(fakes.OS_IMAGE_1) glance.images.get.return_value = os_image # NOTE(ft): check normal flow for an user owned image db_api.get_public_items.return_value = [] db_api.get_item_by_id.return_value = fakes.DB_IMAGE_1 self.assertEqual( os_image, ec2utils.get_os_image(fake_context, fakes.ID_EC2_IMAGE_1)) db_api.get_item_by_id.assert_called_with( mock.ANY, fakes.ID_EC2_IMAGE_1) glance.images.get.assert_called_with(fakes.ID_OS_IMAGE_1) # NOTE(ft): check normal flow for a public image db_api.get_public_items.return_value = [fakes.DB_IMAGE_1] db_api.get_item_by_id.return_value = None self.assertEqual( os_image, ec2utils.get_os_image(fake_context, fakes.ID_EC2_IMAGE_1)) db_api.get_public_items.assert_called_with( mock.ANY, 'ami', (fakes.ID_EC2_IMAGE_1,)) glance.images.get.assert_called_with(fakes.ID_OS_IMAGE_1) # NOTE(ft): check case of absence of an image in OS glance.images.get.side_effect = glance_exception.HTTPNotFound() self.assertRaises( exception.InvalidAMIIDNotFound, ec2utils.get_os_image, fake_context, fakes.ID_EC2_IMAGE_1) # NOTE(ft): check case of an unknown image id db_api.get_public_items.return_value = [] db_api.get_item_by_id.return_value = None self.assertRaises( exception.InvalidAMIIDNotFound, ec2utils.get_os_image, fake_context, fakes.random_ec2_id('ami'))
def test_describe_images_being_created(self): db_api = self.mock_db() glance = self.mock_glance() context = base.create_context() image_id = fakes.random_ec2_id('ami') image = { 'id': image_id, 'os_id': None, 'is_public': False, 'description': 'fake desc' } db_api.set_mock_items(image) db_api.get_public_items.return_value = [] # describe cases when no glance image exists glance.images.list.return_value = [] expected = { 'imagesSet': [{ 'imageId': image_id, 'description': 'fake desc', 'imageOwnerId': fakes.ID_OS_PROJECT, 'imageState': 'pending', 'imageType': 'machine', 'isPublic': False }] } # describe all images result = image_api.describe_images(context) self.assertEqual(expected, result) # describe the image result = image_api.describe_images(context, image_id=[image_id]) self.assertEqual(expected, result) # describe failed image image['state'] = 'failed' expected['imagesSet'][0]['imageState'] = 'failed' result = image_api.describe_images(base.create_context()) self.assertEqual(expected, result) # describe cases when glance image exists, db item is yet not updated del image['state'] os_image_id = fakes.random_os_id() os_image = { 'id': os_image_id, 'owner': fakes.ID_OS_PROJECT, 'status': 'active', 'is_public': False, 'properties': { 'ec2_id': image_id } } glance.images.list.return_value = [fakes.OSImage(os_image)] expected['imagesSet'] = [{ 'architecture': None, 'creationDate': None, 'description': 'fake desc', 'imageId': image_id, 'imageLocation': 'None (None)', 'imageOwnerId': fakes.ID_OS_PROJECT, 'imageState': 'available', 'imageType': 'machine', 'isPublic': False, 'name': None, 'rootDeviceType': 'instance-store' }] # describe all images result = image_api.describe_images(context) self.assertEqual(expected, result) db_api.update_item.assert_called_once_with( context, tools.update_dict(image, {'os_id': os_image_id})) # describe the image db_api.reset_mock() result = image_api.describe_images(context, image_id=[image_id]) self.assertEqual(expected, result) db_api.update_item.assert_called_once_with( context, tools.update_dict(image, {'os_id': os_image_id}))
def test_format_image(self): image_ids = { fakes.ID_OS_IMAGE_1: fakes.ID_EC2_IMAGE_1, fakes.ID_OS_IMAGE_AKI_1: fakes.ID_EC2_IMAGE_AKI_1, fakes.ID_OS_IMAGE_ARI_1: fakes.ID_EC2_IMAGE_ARI_1 } os_image = copy.deepcopy(fakes.OS_IMAGE_1) # check name and location attributes for an unnamed image os_image['properties'] = {'image_location': 'location'} os_image['name'] = None image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('location', image['imageLocation']) self.assertEqual('location', image['name']) # check name and location attributes for complete image os_image['properties'] = {} os_image['name'] = 'fake_name' image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('None (fake_name)', image['imageLocation']) self.assertEqual('fake_name', image['name']) # check ebs image type for bdm_v2 mapping type os_image['properties'] = { 'bdm_v2': True, 'root_device_name': '/dev/vda', 'block_device_mapping': [{ 'boot_index': 0, 'snapshot_id': fakes.ID_OS_SNAPSHOT_2, 'source_type': 'snapshot', 'destination_type': 'volume' }] } image = image_api._format_image( 'fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids, snapshot_ids={fakes.ID_OS_SNAPSHOT_2: fakes.ID_EC2_SNAPSHOT_2}) self.assertEqual('ebs', image['rootDeviceType']) # check instance-store image attributes with no any device mappings os_image['properties'] = {'root_device_name': '/dev/vda'} image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, None) self.assertEqual('instance-store', image['rootDeviceType']) self.assertNotIn('blockDeviceMapping', image) # check Glance status translation os_image = fakes.OSImage({'id': fakes.ID_OS_IMAGE_1}) def check_status_translation(status, expected): os_image.status = status image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, os_image, None, None) self.assertEqual(expected, image['imageState'], "Wrong '%s' Glance status translation" % status) check_status_translation('queued', 'pending') check_status_translation('saving', 'pending') check_status_translation('active', 'available') check_status_translation('killed', 'deregistered') check_status_translation('pending_delete', 'deregistered') check_status_translation('deleted', 'deregistered') check_status_translation('deactivated', 'invalid') check_status_translation('unknown-status', 'error') # check internal state translation os_image.status = 'queued' def check_state_translation(state, expected): os_image.properties['image_state'] = state image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, os_image, None, None) self.assertEqual(expected, image['imageState'], "Wrong '%s' internal state translation" % state) for state in ('downloading', 'decrypting', 'untarring', 'uploading'): check_state_translation(state, 'pending') for state in ('failed_download', 'failed_decrypt', 'failed_untar', 'failed_upload'): check_state_translation(state, 'failed') os_image.status = 'active' check_state_translation('available', 'available') check_state_translation('unknown-state', 'available')
def test_register_image_by_bdm(self, get_os_image): self.glance.images.create.return_value = (fakes.OSImage( fakes.OS_IMAGE_2)) self.cinder.volume_snapshots.get.side_effect = ( tools.get_by_1st_arg_getter( { fakes.ID_OS_SNAPSHOT_1: (fakes.OSSnapshot(fakes.OS_SNAPSHOT_1)) }, notfound_exception=cinder_exception.NotFound(404))) self.db_api.add_item.side_effect = (tools.get_db_api_add_item( fakes.ID_EC2_IMAGE_2)) self.set_mock_db_items(fakes.DB_SNAPSHOT_1, fakes.DB_SNAPSHOT_2, fakes.DB_IMAGE_AKI_1, fakes.DB_IMAGE_ARI_1) get_os_image.side_effect = [ fakes.OSImage(fakes.OS_IMAGE_AKI_1), fakes.OSImage(fakes.OS_IMAGE_ARI_1) ] resp = self.execute( 'RegisterImage', { 'RootDeviceName': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'Name': 'fake_name', 'KernelId': fakes.ID_EC2_IMAGE_AKI_1, 'RamdiskId': fakes.ID_EC2_IMAGE_ARI_1, 'BlockDeviceMapping.1.DeviceName': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'BlockDeviceMapping.1.Ebs.SnapshotId': fakes.ID_EC2_SNAPSHOT_1, 'BlockDeviceMapping.2.DeviceName': '/dev/vdf', 'BlockDeviceMapping.2.Ebs.VolumeSize': '100', 'BlockDeviceMapping.2.Ebs.DeleteOnTermination': 'False', 'BlockDeviceMapping.3.DeviceName': '/dev/vdg', 'BlockDeviceMapping.3.Ebs.SnapshotId': fakes.ID_EC2_SNAPSHOT_1, 'BlockDeviceMapping.3.Ebs.VolumeSize': '55', 'BlockDeviceMapping.3.Ebs.DeleteOnTermination': 'True', 'BlockDeviceMapping.4.DeviceName': '/dev/vdh', 'BlockDeviceMapping.4.Ebs.SnapshotId': fakes.ID_EC2_SNAPSHOT_2 }) self.assertThat( resp, matchers.DictMatches({'imageId': fakes.ID_EC2_IMAGE_2})) self.db_api.add_item.assert_called_once_with(mock.ANY, 'ami', { 'os_id': fakes.ID_OS_IMAGE_2, 'is_public': False, 'description': None }) self.assertEqual(1, self.glance.images.create.call_count) self.assertEqual((), self.glance.images.create.call_args[0]) self.assertIn('properties', self.glance.images.create.call_args[1]) self.assertIsInstance( self.glance.images.create.call_args[1]['properties'], dict) bdm = self.glance.images.create.call_args[1]['properties'].pop( 'block_device_mapping', 'null') self.assertEqual( { 'is_public': False, 'size': 0, 'name': 'fake_name', 'properties': { 'root_device_name': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'kernel_id': fakes.ID_OS_IMAGE_AKI_1, 'ramdisk_id': fakes.ID_OS_IMAGE_ARI_1, 'bdm_v2': True } }, self.glance.images.create.call_args[1]) self.assertEqual([{ 'boot_index': 0, 'delete_on_termination': True, 'destination_type': 'volume', 'device_name': fakes.ROOT_DEVICE_NAME_IMAGE_2, 'source_type': 'snapshot', 'snapshot_id': fakes.ID_OS_SNAPSHOT_1, 'volume_size': 1 }, { 'boot_index': -1, 'delete_on_termination': False, 'destination_type': 'volume', 'device_name': '/dev/vdf', 'source_type': 'blank', 'volume_size': 100 }, { 'boot_index': -1, 'delete_on_termination': True, 'destination_type': 'volume', 'device_name': '/dev/vdg', 'source_type': 'snapshot', 'snapshot_id': fakes.ID_OS_SNAPSHOT_1, 'volume_size': 55 }, { 'boot_index': -1, 'delete_on_termination': True, 'destination_type': 'volume', 'device_name': '/dev/vdh', 'source_type': 'snapshot', 'snapshot_id': fakes.ID_OS_SNAPSHOT_2 }], json.loads(bdm)) get_os_image.assert_has_calls([ mock.call(mock.ANY, fakes.ID_EC2_IMAGE_AKI_1), mock.call(mock.ANY, fakes.ID_EC2_IMAGE_ARI_1) ]) self.cinder.volume_snapshots.get.assert_any_call( fakes.ID_OS_SNAPSHOT_1)
def test_format_image(self): image_ids = { fakes.ID_OS_IMAGE_1: fakes.ID_EC2_IMAGE_1, fakes.ID_OS_IMAGE_AKI_1: fakes.ID_EC2_IMAGE_AKI_1, fakes.ID_OS_IMAGE_ARI_1: fakes.ID_EC2_IMAGE_ARI_1 } os_image = copy.deepcopy(fakes.OS_IMAGE_1) # check name and location attributes for an unnamed image os_image['properties'] = {'image_location': 'location'} os_image['name'] = None image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('location', image['imageLocation']) self.assertEqual('location', image['name']) # check name and location attributes for complete image os_image['properties'] = {} os_image['name'] = 'fake_name' image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids) self.assertEqual('None (fake_name)', image['imageLocation']) self.assertEqual('fake_name', image['name']) # check ebs image type for bdm_v2 mapping type os_image['properties'] = { 'bdm_v2': True, 'root_device_name': '/dev/vda', 'block_device_mapping': [{ 'boot_index': 0, 'snapshot_id': fakes.ID_OS_SNAPSHOT_2, 'source_type': 'snapshot', 'destination_type': 'volume' }] } image = image_api._format_image( 'fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, image_ids, snapshot_ids={fakes.ID_OS_SNAPSHOT_2: fakes.ID_EC2_SNAPSHOT_2}) self.assertEqual('ebs', image['rootDeviceType']) # check instance-store image attributes with no any device mappings os_image['properties'] = {'root_device_name': '/dev/vda'} image = image_api._format_image('fake_context', fakes.DB_IMAGE_1, fakes.OSImage(os_image), None, None) self.assertEqual('instance-store', image['rootDeviceType']) self.assertNotIn('blockDeviceMapping', image)