Merge "Adding description for testcases - volume part4"

This commit is contained in:
Zuul 2020-09-04 18:23:36 +00:00 committed by Gerrit Code Review
commit 6c63c48146
10 changed files with 74 additions and 28 deletions

View File

@ -39,12 +39,14 @@ class VolumesServicesTestJSON(base.BaseVolumeAdminTest):
@decorators.idempotent_id('e0218299-0a59-4f43-8b2b-f1c035b3d26d')
def test_list_services(self):
"""Test listing volume services"""
services = (self.admin_volume_services_client.list_services()
['services'])
self.assertNotEmpty(services)
@decorators.idempotent_id('63a3e1ca-37ee-4983-826d-83276a370d25')
def test_get_service_by_service_binary_name(self):
"""Test getting volume service by binary name"""
services = (self.admin_volume_services_client.list_services(
binary=self.binary_name)['services'])
self.assertNotEmpty(services)
@ -53,6 +55,7 @@ class VolumesServicesTestJSON(base.BaseVolumeAdminTest):
@decorators.idempotent_id('178710e4-7596-4e08-9333-745cb8bc4f8d')
def test_get_service_by_host_name(self):
"""Test getting volume service by service host name"""
services_on_host = [service for service in self.services if
_get_host(service['host']) == self.host_name]
@ -69,6 +72,7 @@ class VolumesServicesTestJSON(base.BaseVolumeAdminTest):
@decorators.idempotent_id('67ec6902-f91d-4dec-91fa-338523208bbc')
def test_get_service_by_volume_host_name(self):
"""Test getting volume service by volume host name"""
volume_id = self.create_volume()['id']
volume = self.admin_volume_client.show_volume(volume_id)['volume']
hostname = _get_host(volume['os-vol-host-attr:host'])
@ -83,7 +87,7 @@ class VolumesServicesTestJSON(base.BaseVolumeAdminTest):
@decorators.idempotent_id('ffa6167c-4497-4944-a464-226bbdb53908')
def test_get_service_by_service_and_host_name(self):
"""Test getting volume service by binary name and host name"""
services = (self.admin_volume_services_client.list_services(
host=self.host_name, binary=self.binary_name))['services']

View File

@ -24,11 +24,13 @@ CONF = config.CONF
class VolumeTypesAccessTest(base.BaseVolumeAdminTest):
"""Test volume type access"""
credentials = ['primary', 'alt', 'admin']
@decorators.idempotent_id('d4dd0027-835f-4554-a6e5-50903fb79184')
def test_volume_type_access_add(self):
"""Test adding volume type access for non-admin project"""
# Creating a NON public volume type
params = {'os-volume-type-access:is_public': False}
volume_type = self.create_volume_type(**params)
@ -52,6 +54,7 @@ class VolumeTypesAccessTest(base.BaseVolumeAdminTest):
@decorators.idempotent_id('5220eb28-a435-43ce-baaf-ed46f0e95159')
def test_volume_type_access_list(self):
"""Test listing volume type access"""
# Creating a NON public volume type
params = {'os-volume-type-access:is_public': False}
volume_type = self.create_volume_type(**params)

View File

@ -19,6 +19,7 @@ from tempest.lib import exceptions as lib_exc
class VolumeTypesExtraSpecsTest(base.BaseVolumeAdminTest):
"""Test volume type extra specs"""
@classmethod
def resource_setup(cls):
@ -27,7 +28,7 @@ class VolumeTypesExtraSpecsTest(base.BaseVolumeAdminTest):
@decorators.idempotent_id('b42923e9-0452-4945-be5b-d362ae533e60')
def test_volume_type_extra_specs_list(self):
# List Volume types extra specs.
"""Test listing volume type extra specs"""
extra_specs = {"spec1": "val1"}
body = self.admin_volume_types_client.create_volume_type_extra_specs(
self.volume_type['id'], extra_specs)['extra_specs']
@ -40,7 +41,7 @@ class VolumeTypesExtraSpecsTest(base.BaseVolumeAdminTest):
@decorators.idempotent_id('0806db36-b4a0-47a1-b6f3-c2e7f194d017')
def test_volume_type_extra_specs_update(self):
# Update volume type extra specs
"""Test updating volume type extra specs"""
extra_specs = {"spec2": "val1"}
body = self.admin_volume_types_client.create_volume_type_extra_specs(
self.volume_type['id'], extra_specs)['extra_specs']
@ -74,7 +75,7 @@ class VolumeTypesExtraSpecsTest(base.BaseVolumeAdminTest):
@decorators.idempotent_id('d4772798-601f-408a-b2a5-29e8a59d1220')
def test_volume_type_extra_spec_create_get_delete(self):
# Create/Get/Delete volume type extra spec.
"""Test Create/Get/Delete volume type extra specs"""
spec_key = "spec3"
extra_specs = {spec_key: "val1"}
body = self.admin_volume_types_client.create_volume_type_extra_specs(

View File

@ -24,6 +24,7 @@ CONF = config.CONF
class VolumesListAdminTestJSON(base.BaseVolumeAdminTest):
"""Test listing volumes with admin privilege"""
@classmethod
def resource_setup(cls):
@ -41,7 +42,7 @@ class VolumesListAdminTestJSON(base.BaseVolumeAdminTest):
@decorators.idempotent_id('5866286f-3290-4cfd-a414-088aa6cdc469')
def test_volume_list_param_tenant(self):
# Test to list volumes from single tenant
"""Test admin can list volumes belonging to specified project"""
# Create a volume in admin tenant
adm_vol = self.admin_volume_client.create_volume(
size=CONF.volume.volume_size)['volume']

View File

@ -22,7 +22,7 @@ class AvailabilityZoneTestJSON(base.BaseVolumeTest):
@decorators.idempotent_id('01f1ae88-eba9-4c6b-a011-6f7ace06b725')
def test_get_availability_zone_list(self):
# List of availability zone
"""Test listing volume available zones"""
availability_zone = (
self.availability_zone_client.list_availability_zones()
['availabilityZoneInfo'])

View File

@ -26,10 +26,11 @@ LOG = logging.getLogger(__name__)
class ExtensionsTestJSON(base.BaseVolumeTest):
"""Test volume extensions"""
@decorators.idempotent_id('94607eb0-43a5-47ca-82aa-736b41bd2e2c')
def test_list_extensions(self):
# List of all extensions
"""Test listing volume extensions"""
extensions = (self.volumes_extension_client.list_extensions()
['extensions'])
if not CONF.volume_feature_enabled.api_extensions:

View File

@ -24,6 +24,7 @@ CONF = config.CONF
class VolumesImageMetadata(base.BaseVolumeTest):
"""Test volume image metadata"""
@classmethod
def skip_checks(cls):
@ -41,6 +42,7 @@ class VolumesImageMetadata(base.BaseVolumeTest):
@decorators.idempotent_id('03efff0b-5c75-4822-8f10-8789ac15b13e')
@utils.services('image')
def test_update_show_delete_image_metadata(self):
"""Test update/show/delete volume's image metadata"""
# Update image metadata
image_metadata = {'image_id': '5137a025-3c5f-43c1-bc64-5f41270040a5',
'image_name': 'image',

View File

@ -23,6 +23,8 @@ CONF = config.CONF
class SnapshotMetadataTestJSON(base.BaseVolumeTest):
"""Test snapshot metadata"""
@classmethod
def skip_checks(cls):
super(SnapshotMetadataTestJSON, cls).skip_checks()
@ -45,6 +47,7 @@ class SnapshotMetadataTestJSON(base.BaseVolumeTest):
@decorators.idempotent_id('a2f20f99-e363-4584-be97-bc33afb1a56c')
def test_crud_snapshot_metadata(self):
"""Test create/get/update/delete snapshot metadata"""
# Create metadata for the snapshot
metadata = {"key1": "value1",
"key2": "value2",
@ -82,7 +85,7 @@ class SnapshotMetadataTestJSON(base.BaseVolumeTest):
@decorators.idempotent_id('e8ff85c5-8f97-477f-806a-3ac364a949ed')
def test_update_show_snapshot_metadata_item(self):
# Update metadata item for the snapshot
"""Test update/show snapshot metadata item"""
metadata = {"key1": "value1",
"key2": "value2",
"key3": "value3"}

View File

@ -25,6 +25,8 @@ CONF = config.CONF
class VolumesActionsTest(base.BaseVolumeTest):
"""Test volume actions"""
create_default_network = True
@classmethod
@ -38,6 +40,7 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.attr(type='smoke')
@utils.services('compute')
def test_attach_detach_volume_to_instance(self):
"""Test attaching and detaching volume to instance"""
# Create a server
server = self.create_server()
# Volume is attached and detached successfully from an instance
@ -53,7 +56,7 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.idempotent_id('63e21b4c-0a0c-41f6-bfc3-7c2816815599')
def test_volume_bootable(self):
# Verify that a volume bootable flag is retrieved
"""Test setting and retrieving bootable flag of a volume"""
for bool_bootable in [True, False]:
self.volumes_client.set_bootable_volume(self.volume['id'],
bootable=bool_bootable)
@ -69,6 +72,11 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.idempotent_id('9516a2c8-9135-488c-8dd6-5677a7e5f371')
@utils.services('compute')
def test_get_volume_attachment(self):
"""Test getting volume attachments
Attach a volume to a server, and then retrieve volume's attachments
info.
"""
# Create a server
server = self.create_server()
# Verify that a volume's attachment information is retrieved
@ -96,6 +104,7 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.idempotent_id('d8f1ca95-3d5b-44a3-b8ca-909691c9532d')
@utils.services('image')
def test_volume_upload(self):
"""Test uploading volume to create an image"""
# NOTE(gfidente): the volume uploaded in Glance comes from setUpClass,
# it is shared with the other tests. After it is uploaded in Glance,
# there is no way to delete it from Cinder, so we delete it from Glance
@ -118,6 +127,7 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.idempotent_id('92c4ef64-51b2-40c0-9f7e-4749fbaaba33')
def test_reserve_unreserve_volume(self):
"""Test reserving and unreserving volume"""
# Mark volume as reserved.
self.volumes_client.reserve_volume(self.volume['id'])
# To get the volume info
@ -131,6 +141,7 @@ class VolumesActionsTest(base.BaseVolumeTest):
@decorators.idempotent_id('fff74e1e-5bd3-4b33-9ea9-24c103bc3f59')
def test_volume_readonly_update(self):
"""Test updating and retrieve volume's readonly flag"""
for readonly in [True, False]:
# Update volume readonly
self.volumes_client.update_volume_readonly(self.volume['id'],

View File

@ -28,6 +28,7 @@ CONF = config.CONF
class VolumesNegativeTest(base.BaseVolumeTest):
"""Negative tests of volumes"""
@classmethod
def resource_setup(cls):
@ -58,50 +59,49 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('f131c586-9448-44a4-a8b0-54ca838aa43e')
def test_volume_get_nonexistent_volume_id(self):
# Should not be able to get a non-existent volume
"""Test getting non existent volume should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.show_volume,
data_utils.rand_uuid())
@decorators.attr(type=['negative'])
@decorators.idempotent_id('555efa6e-efcd-44ef-8a3b-4a7ca4837a29')
def test_volume_delete_nonexistent_volume_id(self):
# Should not be able to delete a non-existent Volume
"""Test deleting non existent volume should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.delete_volume,
data_utils.rand_uuid())
@decorators.attr(type=['negative'])
@decorators.idempotent_id('1ed83a8a-682d-4dfb-a30e-ee63ffd6c049')
def test_create_volume_with_invalid_size(self):
# Should not be able to create volume with invalid size in request
"""Test creating volume with invalid size should fail"""
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume, size='#$%')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9387686f-334f-4d31-a439-33494b9e2683')
def test_create_volume_without_passing_size(self):
# Should not be able to create volume without passing size
# in request
"""Test creating volume with empty size should fail"""
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume, size='')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('41331caa-eaf4-4001-869d-bc18c1869360')
def test_create_volume_with_size_zero(self):
# Should not be able to create volume with size zero
"""Test creating volume with zero size should fail"""
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume, size='0')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('8b472729-9eba-446e-a83b-916bdb34bef7')
def test_create_volume_with_size_negative(self):
# Should not be able to create volume with size negative
"""Test creating volume with negative size should fail"""
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume, size='-1')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('10254ed8-3849-454e-862e-3ab8e6aa01d2')
def test_create_volume_with_nonexistent_volume_type(self):
# Should not be able to create volume with non-existent volume type
"""Test creating volume with non existent volume type should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size=CONF.volume.volume_size,
volume_type=data_utils.rand_uuid())
@ -109,7 +109,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('0c36f6ae-4604-4017-b0a9-34fdc63096f9')
def test_create_volume_with_nonexistent_snapshot_id(self):
# Should not be able to create volume with non-existent snapshot
"""Test creating volume with non existent snapshot should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size=CONF.volume.volume_size,
snapshot_id=data_utils.rand_uuid())
@ -117,7 +117,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('47c73e08-4be8-45bb-bfdf-0c4e79b88344')
def test_create_volume_with_nonexistent_source_volid(self):
# Should not be able to create volume with non-existent source volume
"""Test creating volume with non existent source volume should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size=CONF.volume.volume_size,
source_volid=data_utils.rand_uuid())
@ -125,46 +125,49 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('0186422c-999a-480e-a026-6a665744c30c')
def test_update_volume_with_nonexistent_volume_id(self):
"""Test updating non existent volume should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id=data_utils.rand_uuid())
@decorators.attr(type=['negative'])
@decorators.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
def test_update_volume_with_invalid_volume_id(self):
"""Test updating volume with invalid volume id should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id=data_utils.rand_name('invalid'))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
def test_update_volume_with_empty_volume_id(self):
"""Test updating volume with empty volume id should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id='')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('30799cfd-7ee4-446c-b66c-45b383ed211b')
def test_get_invalid_volume_id(self):
# Should not be able to get volume with invalid id
"""Test getting volume with invalid volume id should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.show_volume,
data_utils.rand_name('invalid'))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('c6c3db06-29ad-4e91-beb0-2ab195fe49e3')
def test_get_volume_without_passing_volume_id(self):
# Should not be able to get volume when empty ID is passed
"""Test getting volume with empty volume id should fail"""
self.assertRaises(lib_exc.NotFound,
self.volumes_client.show_volume, '')
@decorators.attr(type=['negative'])
@decorators.idempotent_id('1f035827-7c32-4019-9240-b4ec2dbd9dfd')
def test_delete_invalid_volume_id(self):
# Should not be able to delete volume when invalid ID is passed
"""Test deleting volume with invalid volume id should fail"""
self.assertRaises(lib_exc.NotFound, self.volumes_client.delete_volume,
data_utils.rand_name('invalid'))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('441a1550-5d44-4b30-af0f-a6d402f52026')
def test_delete_volume_without_passing_volume_id(self):
# Should not be able to delete volume when empty ID is passed
"""Test deleting volume with empty volume id should fail"""
self.assertRaises(lib_exc.NotFound,
self.volumes_client.delete_volume, '')
@ -172,6 +175,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.idempotent_id('f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6')
@utils.services('compute')
def test_attach_volumes_with_nonexistent_volume_id(self):
"""Test attaching non existent volume to server should fail"""
server = self.create_server()
self.assertRaises(lib_exc.NotFound,
@ -183,6 +187,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9f9c24e4-011d-46b5-b992-952140ce237a')
def test_detach_volumes_with_invalid_volume_id(self):
"""Test detaching volume with invalid volume id should fail"""
self.assertRaises(lib_exc.NotFound,
self.volumes_client.detach_volume,
'xxx')
@ -190,7 +195,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('e0c75c74-ee34-41a9-9288-2a2051452854')
def test_volume_extend_with_size_smaller_than_original_size(self):
# Extend volume with smaller size than original size.
"""Test extending volume with decreasing size should fail"""
extend_size = 0
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.extend_volume,
@ -199,7 +204,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('5d0b480d-e833-439f-8a5a-96ad2ed6f22f')
def test_volume_extend_with_non_number_size(self):
# Extend volume when size is non number.
"""Test extending volume with non-integer size should fail"""
extend_size = 'abc'
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.extend_volume,
@ -208,7 +213,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('355218f1-8991-400a-a6bb-971239287d92')
def test_volume_extend_with_None_size(self):
# Extend volume with None size.
"""Test extending volume with none size should fail"""
extend_size = None
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.extend_volume,
@ -217,7 +222,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
def test_volume_extend_with_nonexistent_volume_id(self):
# Extend volume size when volume is nonexistent.
"""Test extending non existent volume should fail"""
extend_size = self.volume['size'] + 1
self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
data_utils.rand_uuid(), new_size=extend_size)
@ -225,7 +230,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
def test_volume_extend_without_passing_volume_id(self):
# Extend volume size when passing volume id is None.
"""Test extending volume without passing volume id should fail"""
extend_size = self.volume['size'] + 1
self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
None, new_size=extend_size)
@ -233,6 +238,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('ac6084c0-0546-45f9-b284-38a367e0e0e2')
def test_reserve_volume_with_nonexistent_volume_id(self):
"""Test reserving non existent volume should fail"""
self.assertRaises(lib_exc.NotFound,
self.volumes_client.reserve_volume,
data_utils.rand_uuid())
@ -240,6 +246,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('eb467654-3dc1-4a72-9b46-47c29d22654c')
def test_unreserve_volume_with_nonexistent_volume_id(self):
"""Test unreserving non existent volume should fail"""
self.assertRaises(lib_exc.NotFound,
self.volumes_client.unreserve_volume,
data_utils.rand_uuid())
@ -247,6 +254,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('449c4ed2-ecdd-47bb-98dc-072aeccf158c')
def test_reserve_volume_with_negative_volume_status(self):
"""Test reserving already reserved volume should fail"""
# Mark volume as reserved.
self.volumes_client.reserve_volume(self.volume['id'])
# Mark volume which is marked as reserved before
@ -259,6 +267,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f')
def test_list_volumes_with_nonexistent_name(self):
"""Test listing volumes with non existent name should get nothing"""
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
params = {'name': v_name}
fetched_volume = self.volumes_client.list_volumes(
@ -268,6 +277,10 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9ca17820-a0e7-4cbd-a7fa-f4468735e359')
def test_list_volumes_detail_with_nonexistent_name(self):
"""Test listing volume details with non existent name
Listing volume details with non existent name should get nothing.
"""
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
params = {'name': v_name}
fetched_volume = \
@ -278,6 +291,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
def test_list_volumes_with_invalid_status(self):
"""Test listing volumes with invalid status should get nothing"""
params = {'status': 'null'}
fetched_volume = self.volumes_client.list_volumes(
params=params)['volumes']
@ -286,6 +300,10 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('ba94b27b-be3f-496c-a00e-0283b373fa75')
def test_list_volumes_detail_with_invalid_status(self):
"""Test listing volume details with invalid status
Listing volume details with invalid status should get nothing
"""
params = {'status': 'null'}
fetched_volume = \
self.volumes_client.list_volumes(detail=True,
@ -296,6 +314,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.idempotent_id('5b810c91-0ad1-47ce-aee8-615f789be78f')
@utils.services('image')
def test_create_volume_from_image_with_decreasing_size(self):
"""Test creating volume from image with decreasing size should fail"""
# Create image
image = self.create_image()
@ -311,6 +330,7 @@ class VolumesNegativeTest(base.BaseVolumeTest):
@decorators.idempotent_id('d15e7f35-2cfc-48c8-9418-c8223a89bcbb')
@utils.services('image')
def test_create_volume_from_deactivated_image(self):
"""Test creating volume from deactivated image should fail"""
# Create image
image = self.create_image()