Merge "GlanceImages.create_and_update_image"
This commit is contained in:
commit
3e66c8f2b0
@ -581,6 +581,24 @@
|
|||||||
failure_rate:
|
failure_rate:
|
||||||
max: 0
|
max: 0
|
||||||
|
|
||||||
|
GlanceImages.create_and_update_image:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
image_location: "{{ cirros_image_url }}"
|
||||||
|
container_format: "bare"
|
||||||
|
disk_format: "qcow2"
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 4
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
||||||
|
|
||||||
SwiftObjects.create_container_and_object_then_list_objects:
|
SwiftObjects.create_container_and_object_then_list_objects:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
|
@ -602,6 +602,24 @@
|
|||||||
failure_rate:
|
failure_rate:
|
||||||
max: 0
|
max: 0
|
||||||
|
|
||||||
|
GlanceImages.create_and_update_image:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
image_location: "{{ cirros_image_url }}"
|
||||||
|
container_format: "bare"
|
||||||
|
disk_format: "qcow2"
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 4
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
||||||
|
|
||||||
SwiftObjects.create_container_and_object_then_list_objects:
|
SwiftObjects.create_container_and_object_then_list_objects:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
|
@ -198,3 +198,46 @@ class CreateImageAndBootInstances(GlanceBasic, nova_utils.NovaScenario):
|
|||||||
|
|
||||||
self._boot_servers(image.id, flavor, number_instances,
|
self._boot_servers(image.id, flavor, number_instances,
|
||||||
**boot_server_kwargs)
|
**boot_server_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@types.convert(image_location={"type": "path_or_url"},
|
||||||
|
kwargs={"type": "glance_image_args"})
|
||||||
|
@validation.required_services(consts.Service.GLANCE)
|
||||||
|
@validation.add("required_platform", platform="openstack", users=True)
|
||||||
|
@scenario.configure(context={"cleanup": ["glance"]},
|
||||||
|
name="GlanceImages.create_and_update_image")
|
||||||
|
class CreateAndUpdateImage(GlanceBasic):
|
||||||
|
|
||||||
|
def run(self, container_format, image_location, disk_format,
|
||||||
|
remove_props=None, visibility="private", create_min_disk=0,
|
||||||
|
create_min_ram=0, update_min_disk=0, update_min_ram=0):
|
||||||
|
"""Create an image then update it.
|
||||||
|
|
||||||
|
Measure the "glance image-create" and "glance image-update" commands
|
||||||
|
performance.
|
||||||
|
|
||||||
|
:param container_format: container format of image. Acceptable
|
||||||
|
formats: ami, ari, aki, bare, and ovf
|
||||||
|
:param image_location: image file location
|
||||||
|
:param disk_format: disk format of image. Acceptable formats:
|
||||||
|
ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, and iso
|
||||||
|
:param remove_props: List of property names to remove.
|
||||||
|
(It is only supported by Glance v2.)
|
||||||
|
:param visibility: The access permission for the created image
|
||||||
|
:param create_min_disk: The min disk of created images
|
||||||
|
:param create_min_ram: The min ram of created images
|
||||||
|
:param update_min_disk: The min disk of updated images
|
||||||
|
:param update_min_ram: The min ram of updated images
|
||||||
|
"""
|
||||||
|
image = self.glance.create_image(
|
||||||
|
container_format=container_format,
|
||||||
|
image_location=image_location,
|
||||||
|
disk_format=disk_format,
|
||||||
|
visibility=visibility,
|
||||||
|
min_disk=create_min_disk,
|
||||||
|
min_ram=create_min_ram)
|
||||||
|
|
||||||
|
self.glance.update_image(image.id,
|
||||||
|
min_disk=update_min_disk,
|
||||||
|
min_ram=update_min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
@ -79,6 +79,23 @@ class GlanceV1Service(service.Service):
|
|||||||
|
|
||||||
return image_obj
|
return image_obj
|
||||||
|
|
||||||
|
@atomic.action_timer("glance_v1.update_image")
|
||||||
|
def update_image(self, image_id, image_name=None, min_disk=0,
|
||||||
|
min_ram=0):
|
||||||
|
"""Update image.
|
||||||
|
|
||||||
|
:param image_id: ID of image to update
|
||||||
|
:param image_name: Image name to be updated to
|
||||||
|
:param min_disk: The min disk of updated image
|
||||||
|
:param min_ram: The min ram of updated image
|
||||||
|
"""
|
||||||
|
image_name = image_name or self.generate_random_name()
|
||||||
|
|
||||||
|
return self._clients.glance("1").images.update(image_id=image_id,
|
||||||
|
name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram)
|
||||||
|
|
||||||
@atomic.action_timer("glance_v1.get_image")
|
@atomic.action_timer("glance_v1.get_image")
|
||||||
def get_image(self, image):
|
def get_image(self, image):
|
||||||
"""Get specified image.
|
"""Get specified image.
|
||||||
@ -158,6 +175,27 @@ class UnifiedGlanceV1Service(image.Image):
|
|||||||
min_ram=min_ram)
|
min_ram=min_ram)
|
||||||
return self._unify_image(image_obj)
|
return self._unify_image(image_obj)
|
||||||
|
|
||||||
|
def update_image(self, image_id, image_name=None, min_disk=0,
|
||||||
|
min_ram=0, remove_props=None):
|
||||||
|
"""Update image.
|
||||||
|
|
||||||
|
:param image_id: ID of image to update
|
||||||
|
:param image_name: Image name to be updated to
|
||||||
|
:param min_disk: The min disk of updated image
|
||||||
|
:param min_ram: The min ram of updated image
|
||||||
|
:param remove_props: List of property names to remove
|
||||||
|
"""
|
||||||
|
if remove_props is not None:
|
||||||
|
raise image.RemovePropsException("Remove prop: %s is not"
|
||||||
|
"supported in"
|
||||||
|
"glance_v1" % remove_props)
|
||||||
|
image_obj = self._impl.update_image(
|
||||||
|
image_id=image_id,
|
||||||
|
image_name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram)
|
||||||
|
return self._unify_image(image_obj)
|
||||||
|
|
||||||
def list_images(self, status="active", visibility=None, owner=None):
|
def list_images(self, status="active", visibility=None, owner=None):
|
||||||
"""List images.
|
"""List images.
|
||||||
|
|
||||||
|
@ -91,6 +91,26 @@ class GlanceV2Service(service.Service):
|
|||||||
check_interval=CONF.benchmark.glance_image_create_poll_interval)
|
check_interval=CONF.benchmark.glance_image_create_poll_interval)
|
||||||
return image_obj
|
return image_obj
|
||||||
|
|
||||||
|
@atomic.action_timer("glance_v2.update_image")
|
||||||
|
def update_image(self, image_id, image_name=None, min_disk=0,
|
||||||
|
min_ram=0, remove_props=None):
|
||||||
|
"""Update image.
|
||||||
|
|
||||||
|
:param image_id: ID of image to update
|
||||||
|
:param image_name: Image name to be updated to
|
||||||
|
:param min_disk: The min disk of updated image
|
||||||
|
:param min_ram: The min ram of updated image
|
||||||
|
:param remove_props: List of property names to remove
|
||||||
|
"""
|
||||||
|
image_name = image_name or self.generate_random_name()
|
||||||
|
|
||||||
|
return self._clients.glance("2").images.update(
|
||||||
|
image_id=image_id,
|
||||||
|
name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
|
||||||
@atomic.action_timer("glance_v2.get_image")
|
@atomic.action_timer("glance_v2.get_image")
|
||||||
def get_image(self, image):
|
def get_image(self, image):
|
||||||
"""Get specified image.
|
"""Get specified image.
|
||||||
@ -171,6 +191,24 @@ class UnifiedGlanceV2Service(image.Image):
|
|||||||
min_ram=min_ram)
|
min_ram=min_ram)
|
||||||
return self._unify_image(image_obj)
|
return self._unify_image(image_obj)
|
||||||
|
|
||||||
|
def update_image(self, image_id, image_name=None, min_disk=0,
|
||||||
|
min_ram=0, remove_props=None):
|
||||||
|
"""Update image.
|
||||||
|
|
||||||
|
:param image_id: ID of image to update
|
||||||
|
:param image_name: Image name to be updated to
|
||||||
|
:param min_disk: The min disk of updated image
|
||||||
|
:param min_ram: The min ram of updated image
|
||||||
|
:param remove_props: List of property names to remove
|
||||||
|
"""
|
||||||
|
image_obj = self._impl.update_image(
|
||||||
|
image_id=image_id,
|
||||||
|
image_name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
return self._unify_image(image_obj)
|
||||||
|
|
||||||
def list_images(self, status="active", visibility=None, owner=None):
|
def list_images(self, status="active", visibility=None, owner=None):
|
||||||
"""List images.
|
"""List images.
|
||||||
|
|
||||||
|
@ -29,6 +29,12 @@ class VisibilityException(Exception):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class RemovePropsException(Exception):
|
||||||
|
"""Remove Props it not supported exception.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Image(service.UnifiedOpenStackService):
|
class Image(service.UnifiedOpenStackService):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_applicable(cls, clients):
|
def is_applicable(cls, clients):
|
||||||
@ -72,6 +78,24 @@ class Image(service.UnifiedOpenStackService):
|
|||||||
min_ram=min_ram)
|
min_ram=min_ram)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
@service.should_be_overridden
|
||||||
|
def update_image(self, image_id, image_name=None,
|
||||||
|
min_disk=0, min_ram=0, remove_props=None):
|
||||||
|
"""Update image.
|
||||||
|
|
||||||
|
:param image_id: ID of image to update
|
||||||
|
:param image_name: Image name to be updated to
|
||||||
|
:param min_disk: The min disk of updated image
|
||||||
|
:param min_ram: The min ram of updated image
|
||||||
|
:param remove_props: List of property names to remove
|
||||||
|
"""
|
||||||
|
return self._impl.update_image(
|
||||||
|
image_id,
|
||||||
|
image_name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
|
||||||
@service.should_be_overridden
|
@service.should_be_overridden
|
||||||
def list_images(self, status="active", visibility=None, owner=None):
|
def list_images(self, status="active", visibility=None, owner=None):
|
||||||
"""List images.
|
"""List images.
|
||||||
|
32
samples/tasks/scenarios/glance/create-and-update-image.json
Normal file
32
samples/tasks/scenarios/glance/create-and-update-image.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"GlanceImages.create_and_update_image": [
|
||||||
|
{
|
||||||
|
"args": {
|
||||||
|
"image_location": "http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img",
|
||||||
|
"container_format": "bare",
|
||||||
|
"disk_format": "qcow2"
|
||||||
|
},
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 4,
|
||||||
|
"concurrency": 2
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 2,
|
||||||
|
"users_per_tenant": 2
|
||||||
|
},
|
||||||
|
"api_versions": {
|
||||||
|
"glance": {
|
||||||
|
"version": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sla": {
|
||||||
|
"failure_rate": {
|
||||||
|
"max": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
21
samples/tasks/scenarios/glance/create-and-update-image.yaml
Normal file
21
samples/tasks/scenarios/glance/create-and-update-image.yaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
GlanceImages.create_and_update_image:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
image_location: "http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img"
|
||||||
|
container_format: "bare"
|
||||||
|
disk_format: "qcow2"
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 4
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
||||||
|
api_versions:
|
||||||
|
glance:
|
||||||
|
version: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
@ -167,3 +167,22 @@ class GlanceBasicTestCase(test.ScenarioTestCase):
|
|||||||
image_service.create_image.assert_called_once_with(**call_args)
|
image_service.create_image.assert_called_once_with(**call_args)
|
||||||
mock_boot_servers.assert_called_once_with("image-id-0", "fid",
|
mock_boot_servers.assert_called_once_with("image-id-0", "fid",
|
||||||
5, **boot_server_kwargs)
|
5, **boot_server_kwargs)
|
||||||
|
|
||||||
|
def test_create_and_update_image(self):
|
||||||
|
image_service = self.mock_image.return_value
|
||||||
|
|
||||||
|
fake_image = fakes.FakeImage(id=1, name="imagexxx")
|
||||||
|
image_service.create_image.return_value = fake_image
|
||||||
|
create_args = {"container_format": "cf",
|
||||||
|
"image_location": "url",
|
||||||
|
"disk_format": "df",
|
||||||
|
"visibility": "vs",
|
||||||
|
"min_disk": 0,
|
||||||
|
"min_ram": 0}
|
||||||
|
|
||||||
|
images.CreateAndUpdateImage(self.context).run(
|
||||||
|
"cf", "url", "df", None, "vs", 0, 0, 0, 0)
|
||||||
|
|
||||||
|
image_service.create_image.assert_called_once_with(**create_args)
|
||||||
|
image_service.update_image.assert_called_once_with(
|
||||||
|
fake_image.id, min_disk=0, min_ram=0, remove_props=None)
|
||||||
|
@ -76,6 +76,37 @@ class GlanceV1ServiceTestCase(test.TestCase):
|
|||||||
self.gc.images.create.assert_called_once_with(**call_args)
|
self.gc.images.create.assert_called_once_with(**call_args)
|
||||||
self.assertEqual(image, self.mock_wait_for_status.mock.return_value)
|
self.assertEqual(image, self.mock_wait_for_status.mock.return_value)
|
||||||
|
|
||||||
|
def test_update_image(self):
|
||||||
|
image_id = "image_id"
|
||||||
|
image_name1 = self.name_generator.return_value
|
||||||
|
image_name2 = "image_name"
|
||||||
|
min_disk = 0
|
||||||
|
min_ram = 0
|
||||||
|
|
||||||
|
# case: image_name is None:
|
||||||
|
call_args1 = {"image_id": image_id,
|
||||||
|
"name": image_name1,
|
||||||
|
"min_disk": min_disk,
|
||||||
|
"min_ram": min_ram}
|
||||||
|
image1 = self.service.update_image(image_id=image_id,
|
||||||
|
image_name=None,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram)
|
||||||
|
self.assertEqual(self.gc.images.update.return_value, image1)
|
||||||
|
self.gc.images.update.assert_called_once_with(**call_args1)
|
||||||
|
|
||||||
|
# case: image_name is not None:
|
||||||
|
call_args2 = {"image_id": image_id,
|
||||||
|
"name": image_name2,
|
||||||
|
"min_disk": min_disk,
|
||||||
|
"min_ram": min_ram}
|
||||||
|
image2 = self.service.update_image(image_id=image_id,
|
||||||
|
image_name=image_name2,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram)
|
||||||
|
self.assertEqual(self.gc.images.update.return_value, image2)
|
||||||
|
self.gc.images.update.assert_called_with(**call_args2)
|
||||||
|
|
||||||
def test_get_image(self):
|
def test_get_image(self):
|
||||||
image_id = "image_id"
|
image_id = "image_id"
|
||||||
self.service.get_image(image_id)
|
self.service.get_image(image_id)
|
||||||
@ -146,6 +177,21 @@ class UnifiedGlanceV1ServiceTestCase(test.TestCase):
|
|||||||
self.service._impl.create_image.assert_called_once_with(**callargs)
|
self.service._impl.create_image.assert_called_once_with(**callargs)
|
||||||
self.assertEqual(mock_image__unify_image.return_value, image)
|
self.assertEqual(mock_image__unify_image.return_value, image)
|
||||||
|
|
||||||
|
@mock.patch(PATH)
|
||||||
|
def test_update_image(self, mock_image__unify_image):
|
||||||
|
image_id = "image_id"
|
||||||
|
image_name = "image_name"
|
||||||
|
callargs = {"image_id": image_id,
|
||||||
|
"image_name": image_name,
|
||||||
|
"min_disk": 0,
|
||||||
|
"min_ram": 0}
|
||||||
|
|
||||||
|
image = self.service.update_image(image_id,
|
||||||
|
image_name=image_name)
|
||||||
|
|
||||||
|
self.assertEqual(mock_image__unify_image.return_value, image)
|
||||||
|
self.service._impl.update_image.assert_called_once_with(**callargs)
|
||||||
|
|
||||||
@mock.patch(PATH)
|
@mock.patch(PATH)
|
||||||
def test_get_image(self, mock_image__unify_image):
|
def test_get_image(self, mock_image__unify_image):
|
||||||
image_id = "image_id"
|
image_id = "image_id"
|
||||||
|
@ -75,6 +75,42 @@ class GlanceV2ServiceTestCase(test.TestCase):
|
|||||||
self.gc.images.create.assert_called_once_with(**call_args)
|
self.gc.images.create.assert_called_once_with(**call_args)
|
||||||
self.assertEqual(image, self.mock_wait_for_status.mock.return_value)
|
self.assertEqual(image, self.mock_wait_for_status.mock.return_value)
|
||||||
|
|
||||||
|
def test_update_image(self):
|
||||||
|
image_id = "image_id"
|
||||||
|
image_name1 = self.name_generator.return_value
|
||||||
|
image_name2 = "image_name"
|
||||||
|
min_disk = 0
|
||||||
|
min_ram = 0
|
||||||
|
remove_props = None
|
||||||
|
|
||||||
|
# case: image_name is None:
|
||||||
|
call_args1 = {"image_id": image_id,
|
||||||
|
"name": image_name1,
|
||||||
|
"min_disk": min_disk,
|
||||||
|
"min_ram": min_ram,
|
||||||
|
"remove_props": remove_props}
|
||||||
|
image1 = self.service.update_image(image_id=image_id,
|
||||||
|
image_name=None,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
self.assertEqual(self.gc.images.update.return_value, image1)
|
||||||
|
self.gc.images.update.assert_called_once_with(**call_args1)
|
||||||
|
|
||||||
|
# case: image_name is not None:
|
||||||
|
call_args2 = {"image_id": image_id,
|
||||||
|
"name": image_name2,
|
||||||
|
"min_disk": min_disk,
|
||||||
|
"min_ram": min_ram,
|
||||||
|
"remove_props": remove_props}
|
||||||
|
image2 = self.service.update_image(image_id=image_id,
|
||||||
|
image_name=image_name2,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
self.assertEqual(self.gc.images.update.return_value, image2)
|
||||||
|
self.gc.images.update.assert_called_with(**call_args2)
|
||||||
|
|
||||||
def test_get_image(self):
|
def test_get_image(self):
|
||||||
image_id = "image_id"
|
image_id = "image_id"
|
||||||
self.service.get_image(image_id)
|
self.service.get_image(image_id)
|
||||||
@ -143,6 +179,22 @@ class UnifiedGlanceV2ServiceTestCase(test.TestCase):
|
|||||||
self.assertEqual(mock_image__unify_image.return_value, image)
|
self.assertEqual(mock_image__unify_image.return_value, image)
|
||||||
self.service._impl.create_image.assert_called_once_with(**callargs)
|
self.service._impl.create_image.assert_called_once_with(**callargs)
|
||||||
|
|
||||||
|
@mock.patch(PATH)
|
||||||
|
def test_update_image(self, mock_image__unify_image):
|
||||||
|
image_id = "image_id"
|
||||||
|
image_name = "image_name"
|
||||||
|
callargs = {"image_id": image_id,
|
||||||
|
"image_name": image_name,
|
||||||
|
"min_disk": 0,
|
||||||
|
"min_ram": 0,
|
||||||
|
"remove_props": None}
|
||||||
|
|
||||||
|
image = self.service.update_image(image_id,
|
||||||
|
image_name=image_name)
|
||||||
|
|
||||||
|
self.assertEqual(mock_image__unify_image.return_value, image)
|
||||||
|
self.service._impl.update_image.assert_called_once_with(**callargs)
|
||||||
|
|
||||||
@mock.patch(PATH)
|
@mock.patch(PATH)
|
||||||
def test_get_image(self, mock_image__unify_image):
|
def test_get_image(self, mock_image__unify_image):
|
||||||
image_id = "image_id"
|
image_id = "image_id"
|
||||||
|
@ -55,6 +55,20 @@ class ImageTestCase(test.TestCase):
|
|||||||
image_location=image_location, disk_format=disk_format,
|
image_location=image_location, disk_format=disk_format,
|
||||||
visibility=visibility, min_disk=min_disk, min_ram=min_ram)
|
visibility=visibility, min_disk=min_disk, min_ram=min_ram)
|
||||||
|
|
||||||
|
@ddt.data(("image_id", "image_name", "min_disk", "min_ram",
|
||||||
|
"remove_props"))
|
||||||
|
def test_update_image(self, params):
|
||||||
|
(image_id, image_name, min_disk, min_ram, remove_props) = params
|
||||||
|
service = self.get_service_with_fake_impl()
|
||||||
|
service.update_image(image_id,
|
||||||
|
image_name=image_name,
|
||||||
|
min_disk=min_disk,
|
||||||
|
min_ram=min_ram,
|
||||||
|
remove_props=remove_props)
|
||||||
|
service._impl.update_image.assert_called_once_with(
|
||||||
|
image_id, image_name=image_name, min_disk=min_disk,
|
||||||
|
min_ram=min_ram, remove_props=remove_props)
|
||||||
|
|
||||||
@ddt.data("image_id")
|
@ddt.data("image_id")
|
||||||
def test_get_image(self, param):
|
def test_get_image(self, param):
|
||||||
image_id = param
|
image_id = param
|
||||||
|
Loading…
Reference in New Issue
Block a user