From 3fa4783dd6c667df321c26e844db06a1f54a297e Mon Sep 17 00:00:00 2001 From: chenhb-zte Date: Sat, 4 Feb 2017 12:31:02 +0800 Subject: [PATCH] Switch cinder scenarios to cinder service 1. need to fix the bug of cinder servcie 2. switch cinder scenarios to cinder service 3. port new method of cinder to cinder service Change-Id: I49bef1d940acb09c64946ba31ca85bbd5230cc36 --- rally-jobs/cinder.yaml | 11 +- .../openstack/scenarios/cinder/utils.py | 18 + .../scenarios/cinder/volume_backups.py | 18 +- .../scenarios/cinder/volume_types.py | 48 +- .../openstack/scenarios/cinder/volumes.py | 294 +++---- .../plugins/openstack/scenarios/nova/utils.py | 9 +- .../openstack/services/storage/block.py | 20 +- .../services/storage/cinder_common.py | 65 +- .../openstack/services/storage/cinder_v1.py | 34 +- .../openstack/services/storage/cinder_v2.py | 33 +- .../cinder/create-and-update-volume.json | 3 +- .../cinder/create-and-update-volume.yaml | 3 +- .../create-snapshot-and-attach-volume.json | 6 +- .../create-snapshot-and-attach-volume.yaml | 6 +- .../openstack/scenarios/cinder/test_utils.py | 29 + .../scenarios/cinder/test_volume_backups.py | 39 +- .../scenarios/cinder/test_volume_types.py | 104 +-- .../scenarios/cinder/test_volumes.py | 816 ++++++++---------- .../scenarios/nova/test_server_groups.py | 0 .../openstack/scenarios/nova/test_servers.py | 0 .../openstack/scenarios/nova/test_utils.py | 13 +- .../openstack/services/storage/test_block.py | 7 + .../services/storage/test_cinder_common.py | 96 ++- .../services/storage/test_cinder_v1.py | 45 +- .../services/storage/test_cinder_v2.py | 51 +- 25 files changed, 957 insertions(+), 811 deletions(-) mode change 100755 => 100644 rally/plugins/openstack/scenarios/cinder/volumes.py mode change 100755 => 100644 rally/plugins/openstack/scenarios/nova/utils.py mode change 100755 => 100644 tests/unit/plugins/openstack/scenarios/cinder/test_volumes.py mode change 100755 => 100644 tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py mode change 100755 => 100644 tests/unit/plugins/openstack/scenarios/nova/test_servers.py mode change 100755 => 100644 tests/unit/plugins/openstack/scenarios/nova/test_utils.py diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index 3ef0cfe0fb..c4b8ab1768 100755 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -180,8 +180,7 @@ - args: update_volume_kwargs: - display_name: "name_updated" - display_description: "desc_updated" + description: "desc_updated" size: 1 runner: type: "constant" @@ -197,8 +196,7 @@ - args: update_volume_kwargs: - display_name: "name_updated" - display_description: "desc_updated" + description: "desc_updated" size: 1 image: name: {{image_name}} @@ -511,7 +509,6 @@ CinderVolumes.create_snapshot_and_attach_volume: - args: - volume_type: false size: min: 1 max: 1 @@ -535,7 +532,7 @@ - args: - volume_type: true + volume_type: "test" size: min: 1 max: 1 @@ -553,6 +550,8 @@ flavor: name: {{flavor_name}} servers_per_tenant: 1 + volume_types: + - "test" sla: failure_rate: max: 0 diff --git a/rally/plugins/openstack/scenarios/cinder/utils.py b/rally/plugins/openstack/scenarios/cinder/utils.py index 12bef74677..27b68bd3e7 100644 --- a/rally/plugins/openstack/scenarios/cinder/utils.py +++ b/rally/plugins/openstack/scenarios/cinder/utils.py @@ -19,6 +19,7 @@ from oslo_config import cfg from rally import exceptions from rally.plugins.openstack import scenario +from rally.plugins.openstack.services.storage import block from rally.plugins.openstack.wrappers import cinder as cinder_wrapper from rally.plugins.openstack.wrappers import glance as glance_wrapper from rally.task import atomic @@ -57,6 +58,23 @@ benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options") CONF.register_opts(CINDER_BENCHMARK_OPTS, group=benchmark_group) +class CinderBasic(scenario.OpenStackScenario): + def __init__(self, context=None, admin_clients=None, clients=None): + super(CinderBasic, self).__init__(context, admin_clients, clients) + if hasattr(self, "_admin_clients"): + self.admin_cinder = block.BlockStorage( + self._admin_clients, name_generator=self.generate_random_name, + atomic_inst=self.atomic_actions()) + if hasattr(self, "_clients"): + self.cinder = block.BlockStorage( + self._clients, name_generator=self.generate_random_name, + atomic_inst=self.atomic_actions()) + + def get_random_server(self): + server_id = random.choice(self.context["tenant"]["servers"]) + return self.clients("nova").servers.get(server_id) + + class CinderScenario(scenario.OpenStackScenario): """Base class for Cinder scenarios with basic atomic actions.""" diff --git a/rally/plugins/openstack/scenarios/cinder/volume_backups.py b/rally/plugins/openstack/scenarios/cinder/volume_backups.py index 96ecadaeb6..c6159a266e 100644 --- a/rally/plugins/openstack/scenarios/cinder/volume_backups.py +++ b/rally/plugins/openstack/scenarios/cinder/volume_backups.py @@ -22,13 +22,17 @@ from rally.task import validation @validation.number("size", minval=1, integer_only=True) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters("name", + subdict="create_backup_kwargs") @validation.required_cinder_services("cinder-backup") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumeBackups." "create_incremental_volume_backup") -class CreateIncrementalVolumeBackup(cinder_utils.CinderScenario): +class CreateIncrementalVolumeBackup(cinder_utils.CinderBasic): def run(self, size, do_delete=True, create_volume_kwargs=None, create_backup_kwargs=None): """Create a incremental volume backup. @@ -45,12 +49,12 @@ class CreateIncrementalVolumeBackup(cinder_utils.CinderScenario): create_volume_kwargs = create_volume_kwargs or {} create_backup_kwargs = create_backup_kwargs or {} - volume = self._create_volume(size, **create_volume_kwargs) - backup1 = self._create_backup(volume.id, **create_backup_kwargs) + volume = self.cinder.create_volume(size, **create_volume_kwargs) + backup1 = self.cinder.create_backup(volume.id, **create_backup_kwargs) - backup2 = self._create_backup(volume.id, incremental=True) + backup2 = self.cinder.create_backup(volume.id, incremental=True) if do_delete: - self._delete_backup(backup2) - self._delete_backup(backup1) - self._delete_volume(volume) + self.cinder.delete_backup(backup2) + self.cinder.delete_backup(backup1) + self.cinder.delete_volume(volume) diff --git a/rally/plugins/openstack/scenarios/cinder/volume_types.py b/rally/plugins/openstack/scenarios/cinder/volume_types.py index caeffcce8d..29efdd676f 100644 --- a/rally/plugins/openstack/scenarios/cinder/volume_types.py +++ b/rally/plugins/openstack/scenarios/cinder/volume_types.py @@ -23,11 +23,12 @@ from rally.task import validation """Scenarios for Cinder Volume Type.""" +@validation.restricted_parameters("name") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(admin=True) @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_and_delete_volume_type") -class CreateAndDeleteVolumeType(cinder_utils.CinderScenario): +class CreateAndDeleteVolumeType(cinder_utils.CinderBasic): def run(self, **kwargs): """Create and delete a volume Type. @@ -35,15 +36,16 @@ class CreateAndDeleteVolumeType(cinder_utils.CinderScenario): :param kwargs: Optional parameters used during volume type creation. """ - volume_type = self._create_volume_type(**kwargs) - self._delete_volume_type(volume_type) + volume_type = self.admin_cinder.create_volume_type(**kwargs) + self.admin_cinder.delete_volume_type(volume_type) +@validation.restricted_parameters("name") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(admin=True) @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_and_get_volume_type") -class CreateAndGetVolumeType(cinder_utils.CinderScenario): +class CreateAndGetVolumeType(cinder_utils.CinderBasic): def run(self, **kwargs): """Create a volume Type, then get the details of the type. @@ -51,16 +53,17 @@ class CreateAndGetVolumeType(cinder_utils.CinderScenario): :param kwargs: Optional parameters used during volume type creation. """ - volume_type = self._create_volume_type(**kwargs) - self._get_volume_type(volume_type) + volume_type = self.admin_cinder.create_volume_type(**kwargs) + self.admin_cinder.get_volume_type(volume_type) +@validation.restricted_parameters("name") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(admin=True) @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_volume_type" "_and_encryption_type") -class CreateVolumeTypeAndEncryptionType(cinder_utils.CinderScenario): +class CreateVolumeTypeAndEncryptionType(cinder_utils.CinderBasic): def run(self, specs, **kwargs): """Create encryption type @@ -72,16 +75,18 @@ class CreateVolumeTypeAndEncryptionType(cinder_utils.CinderScenario): :param kwargs: Optional parameters used during volume type creation. """ - volume_type = self._create_volume_type(**kwargs) - self._create_encryption_type(volume_type, specs) + volume_type = self.admin_cinder.create_volume_type(**kwargs) + self.admin_cinder.create_encryption_type(volume_type, + specs=specs) +@validation.restricted_parameters("name") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(admin=True) @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_and_list_" "encryption_type") -class CreateAndListEncryptionType(cinder_utils.CinderScenario): +class CreateAndListEncryptionType(cinder_utils.CinderBasic): def run(self, specs, search_opts=None, **kwargs): """Create and list encryption type @@ -95,16 +100,18 @@ class CreateAndListEncryptionType(cinder_utils.CinderScenario): :param kwargs: Optional parameters used during volume type creation. """ - volume_type = self._create_volume_type(**kwargs) - self._create_encryption_type(volume_type, specs) - self._list_encryption_type(search_opts) + volume_type = self.admin_cinder.create_volume_type(**kwargs) + self.admin_cinder.create_encryption_type(volume_type, + specs=specs) + self.admin_cinder.list_encryption_type(search_opts) +@validation.restricted_parameters("name") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(admin=True) @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_and_set_volume_type_keys") -class CreateAndSetVolumeTypeKeys(cinder_utils.CinderScenario): +class CreateAndSetVolumeTypeKeys(cinder_utils.CinderBasic): def run(self, volume_type_key, **kwargs): """Create and set a volume type's extra specs. @@ -113,9 +120,9 @@ class CreateAndSetVolumeTypeKeys(cinder_utils.CinderScenario): :param kwargs: Optional parameters used during volume type creation. """ - volume_type = self._create_volume_type(**kwargs) - - self._set_volume_type_keys(volume_type, volume_type_key) + volume_type = self.admin_cinder.create_volume_type(**kwargs) + self.admin_cinder.set_volume_type_keys(volume_type, + metadata=volume_type_key) @validation.required_services(consts.Service.CINDER) @@ -124,7 +131,7 @@ class CreateAndSetVolumeTypeKeys(cinder_utils.CinderScenario): @scenario.configure(context={"admin_cleanup": ["cinder"]}, name="CinderVolumeTypes.create_and_delete_" "encryption_type") -class CreateAndDeleteEncryptionType(cinder_utils.CinderScenario): +class CreateAndDeleteEncryptionType(cinder_utils.CinderBasic): def run(self, create_specs): """Create and delete encryption type @@ -135,5 +142,6 @@ class CreateAndDeleteEncryptionType(cinder_utils.CinderScenario): :param create_specs: the encryption type specifications to add """ volume_type = random.choice(self.context["volume_types"]) - self._create_encryption_type(volume_type["id"], create_specs) - self._delete_encryption_type(volume_type["id"]) + self.admin_cinder.create_encryption_type(volume_type["id"], + specs=create_specs) + self.admin_cinder.delete_encryption_type(volume_type["id"]) diff --git a/rally/plugins/openstack/scenarios/cinder/volumes.py b/rally/plugins/openstack/scenarios/cinder/volumes.py old mode 100755 new mode 100644 index 4c7a1082f8..71faf343b9 --- a/rally/plugins/openstack/scenarios/cinder/volumes.py +++ b/rally/plugins/openstack/scenarios/cinder/volumes.py @@ -32,14 +32,13 @@ LOG = logging.getLogger(__name__) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_list_volume") -class CreateAndListVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndListVolume(cinder_utils.CinderBasic): def run(self, size, detailed=True, image=None, **kwargs): """Create a volume and list all volumes. @@ -64,19 +63,18 @@ class CreateAndListVolume(cinder_utils.CinderScenario, if image: kwargs["imageRef"] = image - self._create_volume(size, **kwargs) - self._list_volumes(detailed) + self.cinder.create_volume(size, **kwargs) + self.cinder.list_volumes(detailed) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_get_volume") -class CreateAndGetVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndGetVolume(cinder_utils.CinderBasic): def run(self, size, image=None, **kwargs): """Create a volume and get the volume. @@ -93,17 +91,15 @@ class CreateAndGetVolume(cinder_utils.CinderScenario, if image: kwargs["imageRef"] = image - volume = self._create_volume(size, **kwargs) - self._get_volume(volume.id) + volume = self.cinder.create_volume(size, **kwargs) + self.cinder.get_volume(volume.id) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.list_volumes") -class ListVolumes(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class ListVolumes(cinder_utils.CinderBasic): def run(self, detailed=True): """List all volumes. @@ -115,13 +111,13 @@ class ListVolumes(cinder_utils.CinderScenario, should be listed """ - self._list_volumes(detailed) + self.cinder.list_volumes(detailed) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(name="CinderVolumes.list_types") -class ListTypes(cinder_utils.CinderScenario): +class ListTypes(cinder_utils.CinderBasic): def run(self, search_opts=None, is_public=None): """List all volume types. @@ -133,13 +129,13 @@ class ListTypes(cinder_utils.CinderScenario): :param is_public: If query public volume type """ - self._list_types(search_opts, is_public) + self.cinder.list_types(search_opts, is_public=is_public) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(name="CinderVolumes.list_transfers") -class ListTransfers(cinder_utils.CinderScenario): +class ListTransfers(cinder_utils.CinderBasic): def run(self, detailed=True, search_opts=None): """List all transfers. @@ -152,18 +148,20 @@ class ListTransfers(cinder_utils.CinderScenario): :param search_opts: Search options to filter out volume transfers. """ - self._list_transfers(detailed, search_opts) + self.cinder.list_transfers(detailed, search_opts=search_opts) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters(["name", "display_name"], + subdict="update_volume_kwargs") @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_update_volume") -class CreateAndUpdateVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndUpdateVolume(cinder_utils.CinderBasic): def run(self, size, image=None, create_volume_kwargs=None, update_volume_kwargs=None): @@ -173,24 +171,31 @@ class CreateAndUpdateVolume(cinder_utils.CinderScenario, :param image: image to be used to create volume :param create_volume_kwargs: dict, to be used to create volume :param update_volume_kwargs: dict, to be used to update volume + update_volume_kwargs["update_name"]=True, if updating the + name of volume. + update_volume_kwargs["description"]="desp", if updating the + description of volume. """ create_volume_kwargs = create_volume_kwargs or {} update_volume_kwargs = update_volume_kwargs or {} if image: create_volume_kwargs["imageRef"] = image - volume = self._create_volume(size, **create_volume_kwargs) - self._update_volume(volume, **update_volume_kwargs) + + if update_volume_kwargs.pop("update_name", False): + update_volume_kwargs["name"] = self.generate_random_name() + + volume = self.cinder.create_volume(size, **create_volume_kwargs) + self.cinder.update_volume(volume, **update_volume_kwargs) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_delete_volume") -class CreateAndDeleteVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndDeleteVolume(cinder_utils.CinderBasic): def run(self, size, image=None, min_sleep=0, max_sleep=0, **kwargs): """Create and then delete a volume. @@ -214,20 +219,19 @@ class CreateAndDeleteVolume(cinder_utils.CinderScenario, if image: kwargs["imageRef"] = image - volume = self._create_volume(size, **kwargs) + volume = self.cinder.create_volume(size, **kwargs) self.sleep_between(min_sleep, max_sleep) - self._delete_volume(volume) + self.cinder.delete_volume(volume) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_volume") -class CreateVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateVolume(cinder_utils.CinderBasic): def run(self, size, image=None, **kwargs): """Create a volume. @@ -245,7 +249,7 @@ class CreateVolume(cinder_utils.CinderScenario, if image: kwargs["imageRef"] = image - self._create_volume(size, **kwargs) + self.cinder.create_volume(size, **kwargs) @validation.required_services(consts.Service.CINDER) @@ -253,9 +257,7 @@ class CreateVolume(cinder_utils.CinderScenario, @validation.required_contexts("volumes") @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.modify_volume_metadata") -class ModifyVolumeMetadata(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class ModifyVolumeMetadata(cinder_utils.CinderBasic): def run(self, sets=10, set_size=3, deletes=5, delete_size=3): """Modify a volume's metadata. @@ -279,17 +281,19 @@ class ModifyVolumeMetadata(cinder_utils.CinderScenario, "num_deletes": deletes * delete_size}) volume = random.choice(self.context["tenant"]["volumes"]) - keys = self._set_metadata(volume["id"], sets, set_size) - self._delete_metadata(volume["id"], keys, deletes, delete_size) + keys = self.cinder.set_metadata(volume["id"], sets=sets, + set_size=set_size) + self.cinder.delete_metadata(volume["id"], keys=keys, + deletes=deletes, + delete_size=delete_size) +@validation.restricted_parameters(["name", "display_name"]) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_extend_volume") -class CreateAndExtendVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndExtendVolume(cinder_utils.CinderBasic): def run(self, size, new_size, min_sleep=0, max_sleep=0, **kwargs): """Create and extend a volume and then delete it. @@ -311,20 +315,19 @@ class CreateAndExtendVolume(cinder_utils.CinderScenario, deletion (in seconds) :param kwargs: optional args to extend the volume """ - volume = self._create_volume(size, **kwargs) - self._extend_volume(volume, new_size) + volume = self.cinder.create_volume(size, **kwargs) + self.cinder.extend_volume(volume, new_size=new_size) self.sleep_between(min_sleep, max_sleep) - self._delete_volume(volume) + self.cinder.delete_volume(volume) +@validation.restricted_parameters(["name", "display_name"]) @validation.required_services(consts.Service.CINDER) @validation.required_contexts("volumes") @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_from_volume_and_delete_volume") -class CreateFromVolumeAndDeleteVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateFromVolumeAndDeleteVolume(cinder_utils.CinderBasic): def run(self, size, min_sleep=0, max_sleep=0, **kwargs): """Create volume from volume and then delete it. @@ -346,20 +349,19 @@ class CreateFromVolumeAndDeleteVolume(cinder_utils.CinderScenario, :param kwargs: optional args to create a volume """ source_vol = random.choice(self.context["tenant"]["volumes"]) - volume = self._create_volume(size, source_volid=source_vol["id"], - **kwargs) + volume = self.cinder.create_volume(size, source_volid=source_vol["id"], + **kwargs) self.sleep_between(min_sleep, max_sleep) - self._delete_volume(volume) + self.cinder.delete_volume(volume) +@validation.restricted_parameters(["name", "display_name"]) @validation.required_services(consts.Service.CINDER) @validation.required_contexts("volumes") @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_delete_snapshot") -class CreateAndDeleteSnapshot(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndDeleteSnapshot(cinder_utils.CinderBasic): def run(self, force=False, min_sleep=0, max_sleep=0, **kwargs): """Create and then delete a volume-snapshot. @@ -377,21 +379,23 @@ class CreateAndDeleteSnapshot(cinder_utils.CinderScenario, :param kwargs: optional args to create a snapshot """ volume = random.choice(self.context["tenant"]["volumes"]) - snapshot = self._create_snapshot(volume["id"], force=force, **kwargs) + snapshot = self.cinder.create_snapshot(volume["id"], force=force, + **kwargs) self.sleep_between(min_sleep, max_sleep) - self._delete_snapshot(snapshot) + self.cinder.delete_snapshot(snapshot) @types.convert(image={"type": "glance_image"}, flavor={"type": "nova_flavor"}) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_params") @validation.image_valid_on_flavor("flavor", "image") @validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder", "nova"]}, name="CinderVolumes.create_and_attach_volume") -class CreateAndAttachVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndAttachVolume(cinder_utils.CinderBasic, + nova_utils.NovaScenario): @logging.log_deprecated_args( "Use 'create_vm_params' for additional instance parameters.", @@ -424,25 +428,25 @@ class CreateAndAttachVolume(cinder_utils.CinderScenario, create_vm_params = create_vm_params or kwargs or {} server = self._boot_server(image, flavor, **create_vm_params) - volume = self._create_volume(size, **create_volume_params) + volume = self.cinder.create_volume(size, **create_volume_params) attachment = self._attach_volume(server, volume) self._detach_volume(server, volume, attachment) - self._delete_volume(volume) + self.cinder.delete_volume(volume) self._delete_server(server) +@validation.restricted_parameters(["name", "display_name"]) @validation.volume_type_exists("volume_type") @validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder", "nova"]}, name="CinderVolumes.create_snapshot_and_attach_volume") -class CreateSnapshotAndAttachVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateSnapshotAndAttachVolume(cinder_utils.CinderBasic, + nova_utils.NovaScenario): - def run(self, volume_type=False, size=None, **kwargs): + def run(self, volume_type=None, size=None, **kwargs): """Create volume, snapshot and attach/detach volume. :param volume_type: Name of volume type to use @@ -456,35 +460,30 @@ class CreateSnapshotAndAttachVolume(cinder_utils.CinderScenario, if size is None: size = {"min": 1, "max": 5} - if isinstance(volume_type, bool): - LOG.warning("Selecting a random volume type is deprecated" - "as of Rally 0.7.0") - volume_types = [None] - volume_types_list = self.clients("cinder").volume_types.list() - for s in volume_types_list: - volume_types.append(s.name) - volume_type = random.choice(volume_types) - - volume = self._create_volume(size, volume_type=volume_type) - snapshot = self._create_snapshot(volume.id, False, **kwargs) + volume = self.cinder.create_volume(size, volume_type=volume_type) + snapshot = self.cinder.create_snapshot(volume.id, force=False, + **kwargs) server = self.get_random_server() attachment = self._attach_volume(server, volume) self._detach_volume(server, volume, attachment) - self._delete_snapshot(snapshot) - self._delete_volume(volume) + self.cinder.delete_snapshot(snapshot) + self.cinder.delete_volume(volume) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters(["name", "display_name"], + subdict="create_snapshot_kwargs") @validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder", "nova"]}, name="CinderVolumes.create_nested_snapshots" "_and_attach_volume") -class CreateNestedSnapshotsAndAttachVolume(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateNestedSnapshotsAndAttachVolume(cinder_utils.CinderBasic, + nova_utils.NovaScenario): @logging.log_deprecated_args( "Use 'create_snapshot_kwargs' for additional snapshot kwargs.", @@ -521,16 +520,16 @@ class CreateNestedSnapshotsAndAttachVolume(cinder_utils.CinderScenario, create_snapshot_kwargs = create_snapshot_kwargs or kwargs or {} server = self.get_random_server() - source_vol = self._create_volume(size, **create_volume_kwargs) - snapshot = self._create_snapshot(source_vol.id, False, - **create_snapshot_kwargs) + source_vol = self.cinder.create_volume(size, **create_volume_kwargs) + snapshot = self.cinder.create_snapshot(source_vol.id, force=False, + **create_snapshot_kwargs) attachment = self._attach_volume(server, source_vol) nes_objs = [(server, source_vol, snapshot, attachment)] for i in range(nested_level - 1): - volume = self._create_volume(size, snapshot_id=snapshot.id) - snapshot = self._create_snapshot(volume.id, False, - **create_snapshot_kwargs) + volume = self.cinder.create_volume(size, snapshot_id=snapshot.id) + snapshot = self.cinder.create_snapshot(volume.id, force=False, + **create_snapshot_kwargs) server = self.get_random_server() attachment = self._attach_volume(server, volume) @@ -539,16 +538,17 @@ class CreateNestedSnapshotsAndAttachVolume(cinder_utils.CinderScenario, nes_objs.reverse() for server, volume, snapshot, attachment in nes_objs: self._detach_volume(server, volume, attachment) - self._delete_snapshot(snapshot) - self._delete_volume(volume) + self.cinder.delete_snapshot(snapshot) + self.cinder.delete_volume(volume) +@validation.restricted_parameters(["name", "display_name"]) @validation.required_services(consts.Service.CINDER) @validation.required_contexts("volumes") @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_list_snapshots") -class CreateAndListSnapshots(cinder_utils.CinderScenario, +class CreateAndListSnapshots(cinder_utils.CinderBasic, nova_utils.NovaScenario, glance_utils.GlanceScenario): @@ -562,18 +562,18 @@ class CreateAndListSnapshots(cinder_utils.CinderScenario, :param kwargs: optional args to create a snapshot """ volume = random.choice(self.context["tenant"]["volumes"]) - self._create_snapshot(volume["id"], force=force, **kwargs) - self._list_snapshots(detailed) + self.cinder.create_snapshot(volume["id"], force=force, **kwargs) + self.cinder.list_snapshots(detailed) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.required_services(consts.Service.CINDER, consts.Service.GLANCE) @validation.required_openstack(users=True) @validation.required_parameters("size") @scenario.configure(context={"cleanup": ["cinder", "glance"]}, name="CinderVolumes.create_and_upload_volume_to_image") -class CreateAndUploadVolumeToImage(cinder_utils.CinderScenario, - nova_utils.NovaScenario, +class CreateAndUploadVolumeToImage(cinder_utils.CinderBasic, glance_utils.GlanceScenario): def run(self, size, image=None, force=False, container_format="bare", @@ -594,23 +594,25 @@ class CreateAndUploadVolumeToImage(cinder_utils.CinderScenario, """ if image: kwargs["imageRef"] = image - volume = self._create_volume(size, **kwargs) - image = self._upload_volume_to_image(volume, force, container_format, - disk_format) + volume = self.cinder.create_volume(size, **kwargs) + image = self.cinder.upload_volume_to_image( + volume, force=force, container_format=container_format, + disk_format=disk_format) if do_delete: - self._delete_volume(volume) + self.cinder.delete_volume(volume) self._delete_image(image) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters("name", subdict="create_backup_kwargs") @validation.required_cinder_services("cinder-backup") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_volume_backup") -class CreateVolumeBackup(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateVolumeBackup(cinder_utils.CinderBasic): def run(self, size, do_delete=True, create_volume_kwargs=None, create_backup_kwargs=None): @@ -625,22 +627,23 @@ class CreateVolumeBackup(cinder_utils.CinderScenario, create_volume_kwargs = create_volume_kwargs or {} create_backup_kwargs = create_backup_kwargs or {} - volume = self._create_volume(size, **create_volume_kwargs) - backup = self._create_backup(volume.id, **create_backup_kwargs) + volume = self.cinder.create_volume(size, **create_volume_kwargs) + backup = self.cinder.create_backup(volume.id, **create_backup_kwargs) if do_delete: - self._delete_volume(volume) - self._delete_backup(backup) + self.cinder.delete_volume(volume) + self.cinder.delete_backup(backup) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters("name", subdict="create_backup_kwargs") @validation.required_cinder_services("cinder-backup") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_restore_volume_backup") -class CreateAndRestoreVolumeBackup(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndRestoreVolumeBackup(cinder_utils.CinderBasic): def run(self, size, do_delete=True, create_volume_kwargs=None, create_backup_kwargs=None): @@ -655,23 +658,24 @@ class CreateAndRestoreVolumeBackup(cinder_utils.CinderScenario, create_volume_kwargs = create_volume_kwargs or {} create_backup_kwargs = create_backup_kwargs or {} - volume = self._create_volume(size, **create_volume_kwargs) - backup = self._create_backup(volume.id, **create_backup_kwargs) - self._restore_backup(backup.id) + volume = self.cinder.create_volume(size, **create_volume_kwargs) + backup = self.cinder.create_backup(volume.id, **create_backup_kwargs) + self.cinder.restore_backup(backup.id) if do_delete: - self._delete_volume(volume) - self._delete_backup(backup) + self.cinder.delete_volume(volume) + self.cinder.delete_backup(backup) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_volume_kwargs") +@validation.restricted_parameters("name", subdict="create_backup_kwargs") @validation.required_cinder_services("cinder-backup") @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_list_volume_backups") -class CreateAndListVolumeBackups(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateAndListVolumeBackups(cinder_utils.CinderBasic): def run(self, size, detailed=True, do_delete=True, create_volume_kwargs=None, create_backup_kwargs=None): @@ -687,24 +691,23 @@ class CreateAndListVolumeBackups(cinder_utils.CinderScenario, create_volume_kwargs = create_volume_kwargs or {} create_backup_kwargs = create_backup_kwargs or {} - volume = self._create_volume(size, **create_volume_kwargs) - backup = self._create_backup(volume.id, **create_backup_kwargs) - self._list_backups(detailed) + volume = self.cinder.create_volume(size, **create_volume_kwargs) + backup = self.cinder.create_backup(volume.id, **create_backup_kwargs) + self.cinder.list_backups(detailed) if do_delete: - self._delete_volume(volume) - self._delete_backup(backup) + self.cinder.delete_volume(volume) + self.cinder.delete_backup(backup) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_volume_and_clone") -class CreateVolumeAndClone(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateVolumeAndClone(cinder_utils.CinderBasic): def run(self, size, image=None, nested_level=1, **kwargs): """Create a volume, then clone it to another volume. @@ -728,24 +731,25 @@ class CreateVolumeAndClone(cinder_utils.CinderScenario, if image: kwargs["imageRef"] = image - source_vol = self._create_volume(size, **kwargs) + source_vol = self.cinder.create_volume(size, **kwargs) kwargs.pop("imageRef", None) for i in range(nested_level): with atomic.ActionTimer(self, "cinder.clone_volume"): - source_vol = self._create_volume(source_vol.size, - source_volid=source_vol.id, - atomic_action=False, **kwargs) + source_vol = self.cinder.create_volume( + source_vol.size, source_volid=source_vol.id, + **kwargs) +@validation.restricted_parameters(["name", "display_name"]) +@validation.restricted_parameters(["name", "display_name"], + subdict="create_snapshot_kwargs") @validation.required_services(consts.Service.CINDER) @validation.required_contexts("volumes") @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_volume_from_snapshot") -class CreateVolumeFromSnapshot(cinder_utils.CinderScenario, - nova_utils.NovaScenario, - glance_utils.GlanceScenario): +class CreateVolumeFromSnapshot(cinder_utils.CinderBasic): def run(self, do_delete=True, create_snapshot_kwargs=None, **kwargs): """Create a volume-snapshot, then create a volume from this snapshot. @@ -758,26 +762,26 @@ class CreateVolumeFromSnapshot(cinder_utils.CinderScenario, create_snapshot_kwargs = create_snapshot_kwargs or {} src_volume = random.choice(self.context["tenant"]["volumes"]) - snapshot = self._create_snapshot(src_volume["id"], - **create_snapshot_kwargs) - volume = self._create_volume(src_volume["size"], - snapshot_id=snapshot.id, - **kwargs) + snapshot = self.cinder.create_snapshot(src_volume["id"], + **create_snapshot_kwargs) + volume = self.cinder.create_volume(src_volume["size"], + snapshot_id=snapshot.id, + **kwargs) if do_delete: - self._delete_snapshot(snapshot) - self._delete_volume(volume) + self.cinder.delete_snapshot(snapshot) + self.cinder.delete_volume(volume) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_volume_" "and_update_readonly_flag") -class CreateVolumeAndUpdateReadonlyFlag(cinder_utils.CinderScenario, - glance_utils.GlanceScenario): +class CreateVolumeAndUpdateReadonlyFlag(cinder_utils.CinderBasic): def run(self, size, image=None, read_only=True, **kwargs): """Create a volume and then update its readonly flag. @@ -790,18 +794,18 @@ class CreateVolumeAndUpdateReadonlyFlag(cinder_utils.CinderScenario, """ if image: kwargs["imageRef"] = image - volume = self._create_volume(size, **kwargs) - self._update_readonly_flag(volume.id, read_only) + volume = self.cinder.create_volume(size, **kwargs) + self.cinder.update_readonly_flag(volume.id, read_only=read_only) @types.convert(image={"type": "glance_image"}) +@validation.restricted_parameters(["name", "display_name"]) @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @scenario.configure(context={"cleanup": ["cinder"]}, name="CinderVolumes.create_and_accept_transfer") -class CreateAndAcceptTransfer(cinder_utils.CinderScenario, - glance_utils.GlanceScenario): +class CreateAndAcceptTransfer(cinder_utils.CinderBasic): def run(self, size, image=None, **kwargs): """Create a volume transfer, then accept it @@ -814,6 +818,6 @@ class CreateAndAcceptTransfer(cinder_utils.CinderScenario, """ if image: kwargs["imageRef"] = image - volume = self._create_volume(size, **kwargs) - transfer = self._transfer_create(volume.id) - self._transfer_accept(transfer.id, transfer.auth_key) + volume = self.cinder.create_volume(size, **kwargs) + transfer = self.cinder.transfer_create(volume.id) + self.cinder.transfer_accept(transfer.id, auth_key=transfer.auth_key) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py old mode 100755 new mode 100644 index ceb4c19e79..ed7e0fef36 --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -19,6 +19,7 @@ from oslo_config import cfg from rally import exceptions from rally.plugins.openstack import scenario +from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils from rally.plugins.openstack.wrappers import glance as glance_wrapper from rally.plugins.openstack.wrappers import network as network_wrapper from rally.task import atomic @@ -713,6 +714,10 @@ class NovaScenario(scenario.OpenStackScenario): CONF.benchmark.nova_server_resize_revert_poll_interval) ) + def _update_volume_resource(self, resource): + cinder_service = cinder_utils.CinderBasic(self.context) + return cinder_service.cinder.get_volume(resource.id) + @atomic.action_timer("nova.attach_volume") def _attach_volume(self, server, volume, device=None): server_id = server.id @@ -722,7 +727,7 @@ class NovaScenario(scenario.OpenStackScenario): utils.wait_for_status( volume, ready_statuses=["in-use"], - update_resource=utils.get_from_manager(), + update_resource=self._update_volume_resource, timeout=CONF.benchmark.nova_server_resize_revert_timeout, check_interval=( CONF.benchmark.nova_server_resize_revert_poll_interval) @@ -741,7 +746,7 @@ class NovaScenario(scenario.OpenStackScenario): utils.wait_for_status( volume, ready_statuses=["available"], - update_resource=utils.get_from_manager(), + update_resource=self._update_volume_resource, timeout=CONF.benchmark.nova_detach_volume_timeout, check_interval=CONF.benchmark.nova_detach_volume_poll_interval ) diff --git a/rally/plugins/openstack/services/storage/block.py b/rally/plugins/openstack/services/storage/block.py index 40c31f6f8b..c421b5eece 100644 --- a/rally/plugins/openstack/services/storage/block.py +++ b/rally/plugins/openstack/services/storage/block.py @@ -43,13 +43,16 @@ CONF = cfg.CONF benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options") CONF.register_opts(CINDER_BENCHMARK_OPTS, group=benchmark_group) -Volume = collections.namedtuple("Volume", ["id", "name", "size"]) +Volume = collections.namedtuple("Volume", ["id", "name", "size", "status"]) VolumeSnapshot = collections.namedtuple("VolumeSnapshot", ["id", "name", - "volume_id"]) + "volume_id", + "status"]) VolumeBackup = collections.namedtuple("VolumeBackup", ["id", "name", - "volume_id"]) + "volume_id", + "status"]) VolumeTransfer = collections.namedtuple("VolumeTransfer", ["id", "name", - "volume_id"]) + "volume_id", + "auth_key"]) VolumeEncryptionType = collections.namedtuple("VolumeEncryptionType", ["id", "volume_type_id"]) @@ -305,6 +308,15 @@ class BlockStorage(service.UnifiedOpenStackService): description=description, is_public=is_public) + @service.should_be_overridden + def get_volume_type(self, volume_type): + """get details of volume_type. + + :param volume_type: The ID of the :class:`VolumeType` to get + :returns: :class:`VolumeType` + """ + return self._impl.get_volume_type(volume_type) + @service.should_be_overridden def delete_volume_type(self, volume_type): """delete a volume type. diff --git a/rally/plugins/openstack/services/storage/cinder_common.py b/rally/plugins/openstack/services/storage/cinder_common.py index f8ed8d72e4..ab8304b72e 100644 --- a/rally/plugins/openstack/services/storage/cinder_common.py +++ b/rally/plugins/openstack/services/storage/cinder_common.py @@ -28,11 +28,30 @@ class CinderMixin(object): def _get_client(self): return self._clients.cinder(self.version) + def _update_resource(self, resource): + try: + manager = getattr(resource, "manager", None) + if manager: + res = manager.get(resource.id) + else: + if isinstance(resource, block.Volume): + attr = "volumes" + elif isinstance(resource, block.VolumeSnapshot): + attr = "volume_snapshots" + elif isinstance(resource, block.VolumeBackup): + attr = "backups" + res = getattr(self._get_client(), attr).get(resource.id) + except Exception as e: + if getattr(e, "code", getattr(e, "http_status", 400)) == 404: + raise exceptions.GetResourceNotFound(resource=resource) + raise exceptions.GetResourceFailure(resource=resource, err=e) + return res + def _wait_available_volume(self, volume): return bench_utils.wait_for_status( volume, ready_statuses=["available"], - update_resource=bench_utils.get_from_manager(), + update_resource=self._update_resource, timeout=CONF.benchmark.cinder_volume_create_timeout, check_interval=CONF.benchmark.cinder_volume_create_poll_interval ) @@ -58,7 +77,7 @@ class CinderMixin(object): volume, ready_statuses=["deleted"], check_deletion=True, - update_resource=bench_utils.get_from_manager(), + update_resource=self._update_resource, timeout=CONF.benchmark.cinder_volume_delete_timeout, check_interval=(CONF.benchmark .cinder_volume_delete_poll_interval) @@ -72,7 +91,7 @@ class CinderMixin(object): aname = "cinder_v%s.extend_volume" % self.version with atomic.ActionTimer(self, aname): self._get_client().volumes.extend(volume, new_size) - self._wait_available_volume(volume) + return self._wait_available_volume(volume) def list_snapshots(self, detailed=True): """Get a list of all snapshots.""" @@ -199,7 +218,7 @@ class CinderMixin(object): snapshot, ready_statuses=["deleted"], check_deletion=True, - update_resource=bench_utils.get_from_manager(), + update_resource=self._update_resource, timeout=CONF.benchmark.cinder_volume_delete_timeout, check_interval=(CONF.benchmark .cinder_volume_delete_poll_interval) @@ -219,7 +238,7 @@ class CinderMixin(object): backup, ready_statuses=["deleted"], check_deletion=True, - update_resource=bench_utils.get_from_manager(), + update_resource=self._update_resource, timeout=CONF.benchmark.cinder_volume_delete_timeout, check_interval=(CONF.benchmark .cinder_volume_delete_poll_interval) @@ -259,6 +278,16 @@ class CinderMixin(object): with atomic.ActionTimer(self, aname): return self._get_client().transfers.list(detailed, search_opts) + def get_volume_type(self, volume_type): + """get details of volume_type. + + :param volume_type: The ID of the :class:`VolumeType` to get + :returns: :class:`VolumeType` + """ + aname = "cinder_v%s.get_volume_type" % self.version + with atomic.ActionTimer(self, aname): + return self._get_client().volume_types.get(volume_type) + def delete_volume_type(self, volume_type): """delete a volume type. @@ -348,12 +377,15 @@ class UnifiedCinderMixin(object): @staticmethod def _unify_backup(backup): return block.VolumeBackup(id=backup.id, name=backup.name, - volume_id=backup.volume_id) + volume_id=backup.volume_id, + status=backup.status) @staticmethod def _unify_transfer(transfer): + auth_key = transfer.auth_key if hasattr(transfer, "auth_key") else None return block.VolumeTransfer(id=transfer.id, name=transfer.name, - volume_id=transfer.volume_id) + volume_id=transfer.volume_id, + auth_key=auth_key) @staticmethod def _unify_encryption_type(encryption_type): @@ -431,17 +463,6 @@ class UnifiedCinderMixin(object): """Delete a volume backup.""" self._impl.delete_backup(backup) - def restore_backup(self, backup_id, volume_id=None): - """Restore the given backup. - - :param backup_id: The ID of the backup to restore. - :param volume_id: The ID of the volume to restore the backup to. - - :returns: Return the restored backup. - """ - return self._unify_backup(self._impl.restore_backup( - backup_id, volume_id=volume_id)) - def list_backups(self, detailed=True): """Return user volume backups list.""" return [self._unify_backup(backup) @@ -459,6 +480,14 @@ class UnifiedCinderMixin(object): for transfer in self._impl.list_transfers( detailed=detailed, search_opts=search_opts)] + def get_volume_type(self, volume_type): + """get details of volume_type. + + :param volume_type: The ID of the :class:`VolumeType` to get + :returns: :class:`VolumeType` + """ + return self._impl.get_volume_type(volume_type) + def delete_volume_type(self, volume_type): """delete a volume type. diff --git a/rally/plugins/openstack/services/storage/cinder_v1.py b/rally/plugins/openstack/services/storage/cinder_v1.py index 7f29fe427d..023b445af7 100644 --- a/rally/plugins/openstack/services/storage/cinder_v1.py +++ b/rally/plugins/openstack/services/storage/cinder_v1.py @@ -81,10 +81,14 @@ class CinderV1Service(service.Service, cinder_common.CinderMixin): :returns: The updated volume. """ - display_name = display_name or self.generate_random_name() - return self._get_client().volumes.update( - volume_id, display_name=display_name, - display_description=display_description) + kwargs = {} + if display_name is not None: + kwargs["display_name"] = display_name + if display_description is not None: + kwargs["display_description"] = display_description + updated_volume = self._get_client().volumes.update( + volume_id, **kwargs) + return updated_volume["volume"] @atomic.action_timer("cinder_v1.list_types") def list_types(self, search_opts=None): @@ -151,13 +155,18 @@ class UnifiedCinderV1Service(cinder_common.UnifiedCinderMixin, @staticmethod def _unify_volume(volume): - return block.Volume(id=volume.id, name=volume.display_name, - size=volume.size) + if isinstance(volume, dict): + return block.Volume(id=volume["id"], name=volume["display_name"], + size=volume["size"], status=volume["status"]) + else: + return block.Volume(id=volume.id, name=volume.display_name, + size=volume.size, status=volume.status) @staticmethod def _unify_snapshot(snapshot): return block.VolumeSnapshot(id=snapshot.id, name=snapshot.display_name, - volume_id=snapshot.volume_id) + volume_id=snapshot.volume_id, + status=snapshot.status) def create_volume(self, size, consistencygroup_id=None, group_id=None, snapshot_id=None, source_volid=None, @@ -291,3 +300,14 @@ class UnifiedCinderV1Service(cinder_common.UnifiedCinderMixin, :returns: Return the created volume type. """ return self._impl.create_volume_type(name=name) + + def restore_backup(self, backup_id, volume_id=None): + """Restore the given backup. + + :param backup_id: The ID of the backup to restore. + :param volume_id: The ID of the volume to restore the backup to. + + :returns: Return the restored backup. + """ + return self._unify_volume(self._impl.restore_backup( + backup_id, volume_id=volume_id)) diff --git a/rally/plugins/openstack/services/storage/cinder_v2.py b/rally/plugins/openstack/services/storage/cinder_v2.py index 7d7833e640..2c314de765 100644 --- a/rally/plugins/openstack/services/storage/cinder_v2.py +++ b/rally/plugins/openstack/services/storage/cinder_v2.py @@ -92,9 +92,14 @@ class CinderV2Service(service.Service, cinder_common.CinderMixin): :returns: The updated volume. """ - return self._get_client().volumes.update( - volume_id, name=name or self.generate_random_name(), - description=description) + kwargs = {} + if name is not None: + kwargs["name"] = name + if description is not None: + kwargs["description"] = description + updated_volume = self._get_client().volumes.update( + volume_id, **kwargs) + return updated_volume["volume"] @atomic.action_timer("cinder_v2.list_types") def list_types(self, search_opts=None, is_public=None): @@ -177,13 +182,18 @@ class UnifiedCinderV2Service(cinder_common.UnifiedCinderMixin, @staticmethod def _unify_volume(volume): - return block.Volume(id=volume.id, name=volume.name, - size=volume.size) + if isinstance(volume, dict): + return block.Volume(id=volume["id"], name=volume["name"], + size=volume["size"], status=volume["status"]) + else: + return block.Volume(id=volume.id, name=volume.name, + size=volume.size, status=volume.status) @staticmethod def _unify_snapshot(snapshot): return block.VolumeSnapshot(id=snapshot.id, name=snapshot.name, - volume_id=snapshot.volume_id) + volume_id=snapshot.volume_id, + status=snapshot.status) def create_volume(self, size, consistencygroup_id=None, group_id=None, snapshot_id=None, source_volid=None, @@ -321,3 +331,14 @@ class UnifiedCinderV2Service(cinder_common.UnifiedCinderMixin, return self._impl.create_volume_type(name=name, description=description, is_public=is_public) + + def restore_backup(self, backup_id, volume_id=None): + """Restore the given backup. + + :param backup_id: The ID of the backup to restore. + :param volume_id: The ID of the volume to restore the backup to. + + :returns: Return the restored backup. + """ + return self._unify_volume(self._impl.restore_backup( + backup_id, volume_id=volume_id)) diff --git a/samples/tasks/scenarios/cinder/create-and-update-volume.json b/samples/tasks/scenarios/cinder/create-and-update-volume.json index 50e49ac736..0810d4b378 100644 --- a/samples/tasks/scenarios/cinder/create-and-update-volume.json +++ b/samples/tasks/scenarios/cinder/create-and-update-volume.json @@ -4,8 +4,7 @@ "args": { "create_volume_kwargs": {}, "update_volume_kwargs": { - "display_name": "name_updated", - "display_description": "desc_updated" + "description": "desc_updated" }, "size": 1 }, diff --git a/samples/tasks/scenarios/cinder/create-and-update-volume.yaml b/samples/tasks/scenarios/cinder/create-and-update-volume.yaml index 05867c783f..409302fb06 100644 --- a/samples/tasks/scenarios/cinder/create-and-update-volume.yaml +++ b/samples/tasks/scenarios/cinder/create-and-update-volume.yaml @@ -3,8 +3,7 @@ - args: update_volume_kwargs: - display_name: "name_updated" - display_description: "desc_updated" + description: "desc_updated" create_volume_kwargs: {} size: 1 runner: diff --git a/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.json b/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.json index 4d8fc1cde7..7e24ba47f7 100644 --- a/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.json +++ b/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.json @@ -3,7 +3,6 @@ "CinderVolumes.create_snapshot_and_attach_volume": [ { "args": { - "volume_type": false, "size": { "min": 1, "max": 5 @@ -32,7 +31,7 @@ }, { "args": { - "volume_type": true, + "volume_type": "test", "size": { "min": 1, "max": 5 @@ -56,7 +55,8 @@ "name": "{{flavor_name}}" }, "servers_per_tenant": 2 - } + }, + "volume_types": ["test"] } } diff --git a/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.yaml b/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.yaml index b9431ed52d..f77a22fcd5 100644 --- a/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.yaml +++ b/samples/tasks/scenarios/cinder/create-snapshot-and-attach-volume.yaml @@ -3,7 +3,6 @@ CinderVolumes.create_snapshot_and_attach_volume: - args: - volume_type: false size: min: 1 max: 5 @@ -23,7 +22,7 @@ servers_per_tenant: 2 - args: - volume_type: true + volume_type: "test" size: min: 1 max: 5 @@ -41,4 +40,5 @@ flavor: name: "{{flavor_name}}" servers_per_tenant: 2 - + volume_types: + - "test" diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py b/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py index 7770a45cf9..167ce17c42 100644 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py @@ -26,6 +26,35 @@ CINDER_UTILS = "rally.plugins.openstack.scenarios.cinder.utils" CONF = cfg.CONF +class CinderBasicTestCase(test.ScenarioTestCase): + + def _get_context(self): + context = test.get_test_context() + context.update({ + "admin": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "user": {"id": "fake_user_id", + "credential": mock.MagicMock()}, + "tenant": {"id": "fake", "name": "fake", + "volumes": [{"id": "uuid", "size": 1}], + "servers": [1]}}) + return context + + def setUp(self): + super(CinderBasicTestCase, self).setUp() + + @mock.patch("random.choice") + def test_get_random_server(self, mock_choice): + basic = utils.CinderBasic(self._get_context()) + server_id = mock_choice(basic.context["tenant"]["servers"]) + return_server = basic.get_random_server() + basic.clients("nova").servers.get.assert_called_once_with(server_id) + self.assertEqual(basic.clients("nova").servers.get.return_value, + return_server) + + class CinderScenarioTestCase(test.ScenarioTestCase): def setUp(self): diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_volume_backups.py b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_backups.py index 0755e2a3cb..f49daa814f 100644 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_volume_backups.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_backups.py @@ -20,14 +20,29 @@ from tests.unit import test class CinderBackupTestCase(test.ScenarioTestCase): + def setUp(self): + super(CinderBackupTestCase, self).setUp() + patch = mock.patch( + "rally.plugins.openstack.services.storage.block.BlockStorage") + self.addCleanup(patch.stop) + self.mock_cinder = patch.start() + + def _get_context(self): + context = test.get_test_context() + context.update({ + "admin": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "user": {"id": "fake_user_id", + "credential": mock.MagicMock()}, + "tenant": {"id": "fake", "name": "fake"}}) + return context + def test_create_incremental_volume_backup(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - scenario = volume_backups.CreateIncrementalVolumeBackup(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._create_backup = mock.MagicMock(return_value=fake_backup) - scenario._delete_volume = mock.MagicMock() - scenario._delete_backup = mock.MagicMock() + mock_service = self.mock_cinder.return_value + scenario = volume_backups.CreateIncrementalVolumeBackup( + self._get_context()) volume_kwargs = {"some_var": "zaq"} backup_kwargs = {"incremental": True} @@ -35,7 +50,9 @@ class CinderBackupTestCase(test.ScenarioTestCase): scenario.run(1, do_delete=True, create_volume_kwargs=volume_kwargs, create_backup_kwargs=backup_kwargs) - self.assertEqual(2, scenario._create_backup.call_count) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._delete_backup.assert_has_calls(fake_backup) - scenario._delete_volume.assert_called_once_with(fake_volume) + self.assertEqual(2, mock_service.create_backup.call_count) + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.delete_backup.assert_has_calls( + mock_service.create_backup.return_value) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py index dd8bb128c2..94eee8d898 100644 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py @@ -18,85 +18,91 @@ from rally.plugins.openstack.scenarios.cinder import volume_types from tests.unit import test -class fake_type(object): - name = "fake" - - class CinderVolumeTypesTestCase(test.ScenarioTestCase): + def setUp(self): + super(CinderVolumeTypesTestCase, self).setUp() + patch = mock.patch( + "rally.plugins.openstack.services.storage.block.BlockStorage") + self.addCleanup(patch.stop) + self.mock_cinder = patch.start() + def _get_context(self): context = test.get_test_context() context.update({ - "volume_types": [{"id": "fake_id", - "name": "fake_name"}]}) + "admin": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "user": {"id": "fake_user_id", + "credential": mock.MagicMock()}, + "tenant": {"id": "fake", "name": "fake"}}) return context def test_create_and_get_volume_type(self): - scenario = volume_types.CreateAndGetVolumeType(self.context) - scenario._create_volume_type = mock.Mock() - scenario._get_volume_type = mock.Mock() + mock_service = self.mock_cinder.return_value + scenario = volume_types.CreateAndGetVolumeType(self._get_context()) scenario.run(fakeargs="f") - scenario._create_volume_type.assert_called_once_with(fakeargs="f") - scenario._get_volume_type.assert_called_once_with( - scenario._create_volume_type.return_value) + mock_service.create_volume_type.assert_called_once_with(fakeargs="f") + mock_service.get_volume_type.assert_called_once_with( + mock_service.create_volume_type.return_value) def test_create_and_delete_volume_type(self): - scenario = volume_types.CreateAndDeleteVolumeType(self.context) - scenario._create_volume_type = mock.Mock() - scenario._delete_volume_type = mock.Mock() + mock_service = self.mock_cinder.return_value + scenario = volume_types.CreateAndDeleteVolumeType(self._get_context()) scenario.run(fakeargs="fakeargs") - scenario._create_volume_type.assert_called_once_with( + mock_service.create_volume_type.assert_called_once_with( fakeargs="fakeargs") - scenario._delete_volume_type.assert_called_once_with( - scenario._create_volume_type.return_value) + mock_service.delete_volume_type.assert_called_once_with( + mock_service.create_volume_type.return_value) def test_create_and_delete_encryption_type(self): - scenario = volume_types.CreateAndDeleteEncryptionType( - self._get_context()) - scenario._create_encryption_type = mock.Mock() - scenario._delete_encryption_type = mock.Mock() + mock_service = self.mock_cinder.return_value + context = self._get_context() + context.update({ + "volume_types": [{"id": "fake_id", + "name": "fake_name"}]}) + scenario = volume_types.CreateAndDeleteEncryptionType(context) scenario.run(create_specs="fakecreatespecs") - scenario._create_encryption_type.assert_called_once_with( - "fake_id", "fakecreatespecs") - scenario._delete_encryption_type.assert_called_once_with( + mock_service.create_encryption_type.assert_called_once_with( + "fake_id", specs="fakecreatespecs") + mock_service.delete_encryption_type.assert_called_once_with( "fake_id") def test_create_volume_type_and_encryption_type(self): - scenario = volume_types.CreateVolumeTypeAndEncryptionType(self.context) - scenario._create_volume_type = mock.Mock() - scenario._create_encryption_type = mock.Mock() + mock_service = self.mock_cinder.return_value + scenario = volume_types.CreateVolumeTypeAndEncryptionType( + self._get_context()) scenario.run(specs="fakespecs", fakeargs="fakeargs") - scenario._create_volume_type.assert_called_once_with( + mock_service.create_volume_type.assert_called_once_with( fakeargs="fakeargs") - scenario._create_encryption_type.assert_called_once_with( - scenario._create_volume_type.return_value, "fakespecs") + mock_service.create_encryption_type.assert_called_once_with( + mock_service.create_volume_type.return_value, + specs="fakespecs") def test_create_and_list_encryption_type(self): - scenario = volume_types.CreateAndListEncryptionType(self.context) - scenario._create_volume_type = mock.Mock() - scenario._create_encryption_type = mock.Mock() - scenario._list_encryption_type = mock.Mock() + mock_service = self.mock_cinder.return_value + scenario = volume_types.CreateAndListEncryptionType( + self._get_context()) scenario.run(specs="fakespecs", search_opts="fakeopts", fakeargs="fakeargs") - scenario._create_volume_type.assert_called_once_with( + mock_service.create_volume_type.assert_called_once_with( fakeargs="fakeargs") - scenario._create_encryption_type.assert_called_once_with( - scenario._create_volume_type.return_value, "fakespecs") - scenario._list_encryption_type.assert_called_once_with( + mock_service.create_encryption_type.assert_called_once_with( + mock_service.create_volume_type.return_value, + specs="fakespecs") + mock_service.list_encryption_type.assert_called_once_with( "fakeopts") def test_create_and_set_volume_type_keys(self): - scenario = volume_types.CreateAndSetVolumeTypeKeys(self.context) - - volume_type = mock.MagicMock() + mock_service = self.mock_cinder.return_value volume_type_key = {"volume_backend_name": "LVM_iSCSI"} - scenario._create_volume_type = mock.MagicMock() - scenario._set_volume_type_keys = mock.MagicMock() - - scenario._create_volume_type.return_value = volume_type + scenario = volume_types.CreateAndSetVolumeTypeKeys( + self._get_context()) scenario.run(volume_type_key, fakeargs="fakeargs") - scenario._create_volume_type.assert_called_once_with( + mock_service.create_volume_type.assert_called_once_with( fakeargs="fakeargs") - scenario._set_volume_type_keys.assert_called_once_with(volume_type, - volume_type_key) + mock_service.set_volume_type_keys.assert_called_once_with( + mock_service.create_volume_type.return_value, + metadata=volume_type_key) diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_volumes.py b/tests/unit/plugins/openstack/scenarios/cinder/test_volumes.py old mode 100755 new mode 100644 index 6f95310034..073a5648b0 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_volumes.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_volumes.py @@ -19,12 +19,7 @@ import mock from rally.plugins.openstack.scenarios.cinder import volumes from tests.unit import test -CINDER_VOLUMES = ("rally.plugins.openstack.scenarios.cinder.volumes" - ".CinderVolumes") - - -class fake_type(object): - name = "fake" +CINDER_VOLUMES = ("rally.plugins.openstack.scenarios.cinder.volumes") @ddt.ddt @@ -33,199 +28,194 @@ class CinderServersTestCase(test.ScenarioTestCase): def _get_context(self): context = test.get_test_context() context.update({ - "user": {"tenant_id": "fake", + "admin": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "user": {"id": "fake_user_id", "credential": mock.MagicMock()}, "tenant": {"id": "fake", "name": "fake", "volumes": [{"id": "uuid", "size": 1}], "servers": [1]}}) return context + def setUp(self): + super(CinderServersTestCase, self).setUp() + patch = mock.patch( + "rally.plugins.openstack.services.storage.block.BlockStorage") + self.addCleanup(patch.stop) + self.mock_cinder = patch.start() + def test_create_and_list_volume(self): - scenario = volumes.CreateAndListVolume(self.context) - scenario._create_volume = mock.MagicMock() - scenario._list_volumes = mock.MagicMock() + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndListVolume(self._get_context()) scenario.run(1, True, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") - scenario._list_volumes.assert_called_once_with(True) + + mock_service.create_volume.assert_called_once_with(1, fakearg="f") + mock_service.list_volumes.assert_called_once_with(True) def test_create_and_get_volume(self): - scenario = volumes.CreateAndGetVolume(self.context) - scenario._create_volume = mock.MagicMock() - scenario._get_volume = mock.MagicMock() + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndGetVolume(self._get_context()) scenario.run(1, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") - scenario._get_volume.assert_called_once_with( - scenario._create_volume.return_value.id) + mock_service.create_volume.assert_called_once_with(1, fakearg="f") + mock_service.get_volume.assert_called_once_with( + mock_service.create_volume.return_value.id) def test_list_volumes(self): - scenario = volumes.ListVolumes(self.context) - scenario._list_volumes = mock.MagicMock() + mock_service = self.mock_cinder.return_value + scenario = volumes.ListVolumes(self._get_context()) scenario.run(True) - scenario._list_volumes.assert_called_once_with(True) + mock_service.list_volumes.assert_called_once_with(True) def test_list_types(self): - scenario = volumes.ListTypes(self.context) - scenario._list_types = mock.MagicMock() - scenario.run(None, None) - scenario._list_types.assert_called_once_with(None, None) + mock_service = self.mock_cinder.return_value + scenario = volumes.ListTypes(self._get_context()) + scenario.run(None, is_public=None) + mock_service.list_types.assert_called_once_with(None, + is_public=None) def test_list_transfers(self): - scenario = volumes.ListTransfers(self.context) + mock_service = self.mock_cinder.return_value + scenario = volumes.ListTransfers(self._get_context()) scenario._list_transfers = mock.MagicMock() - scenario.run(True, None) - scenario._list_transfers.assert_called_once_with(True, None) + scenario.run(True, search_opts=None) + mock_service.list_transfers.assert_called_once_with( + True, search_opts=None) - def test_create_and_update_volume(self): - volume_update_args = {"dispaly_name": "_updated"} - scenario = volumes.CreateAndUpdateVolume(self.context) - fake_volume = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._update_volume = mock.MagicMock() - scenario.run(1, update_volume_kwargs=volume_update_args) - scenario._create_volume.assert_called_once_with(1) - scenario._update_volume.assert_called_once_with(fake_volume, - **volume_update_args) + @ddt.data({"update_args": {"description": "desp"}, + "expected": {"description": "desp"}}, + {"update_args": {"update_name": True, "description": "desp"}, + "expected": {"name": "new_name", "description": "desp"}}) + @ddt.unpack + def test_create_and_update_volume(self, update_args, expected): + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndUpdateVolume(self._get_context()) + scenario.generate_random_name = mock.MagicMock() + scenario.generate_random_name.return_value = "new_name" + scenario.run(1, update_volume_kwargs=update_args) + mock_service.create_volume.assert_called_once_with(1) + mock_service.update_volume.assert_called_once_with( + mock_service.create_volume.return_value, **expected) + if update_args.get("update_name", False): + scenario.generate_random_name.assert_called_once_with() def test_create_volume_and_update_readonly_flag(self): - scenario = volumes.CreateVolumeAndUpdateReadonlyFlag(self.context) - fake_volume = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._update_readonly_flag = mock.MagicMock() - scenario.run(1, None, True, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") - scenario._update_readonly_flag.assert_called_once_with( - fake_volume.id, True) + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateVolumeAndUpdateReadonlyFlag( + self._get_context()) + scenario.run(1, image=None, read_only=True, fakearg="f") + mock_service.create_volume.assert_called_once_with(1, fakearg="f") + mock_service.update_readonly_flag.assert_called_once_with( + mock_service.create_volume.return_value.id, read_only=True) def test_create_and_delete_volume(self): - fake_volume = mock.MagicMock() - - scenario = volumes.CreateAndDeleteVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndDeleteVolume(self._get_context()) scenario.sleep_between = mock.MagicMock() - scenario._delete_volume = mock.MagicMock() - scenario.run(size=1, min_sleep=10, max_sleep=20, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") + mock_service.create_volume.assert_called_once_with(1, fakearg="f") scenario.sleep_between.assert_called_once_with(10, 20) - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) def test_create_volume(self): - fake_volume = mock.MagicMock() - scenario = volumes.CreateVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateVolume(self._get_context()) scenario.run(1, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") + mock_service.create_volume.assert_called_once_with(1, fakearg="f") def test_create_volume_and_modify_metadata(self): + mock_service = self.mock_cinder.return_value scenario = volumes.ModifyVolumeMetadata(self._get_context()) - scenario._set_metadata = mock.Mock() - scenario._delete_metadata = mock.Mock() - scenario.run(sets=5, set_size=4, deletes=3, delete_size=2) - scenario._set_metadata.assert_called_once_with("uuid", 5, 4) - scenario._delete_metadata.assert_called_once_with( + mock_service.set_metadata.assert_called_once_with( + "uuid", set_size=4, sets=5) + mock_service.delete_metadata.assert_called_once_with( "uuid", - scenario._set_metadata.return_value, 3, 2) + keys=mock_service.set_metadata.return_value, + deletes=3, delete_size=2) def test_create_and_extend_volume(self): - fake_volume = mock.MagicMock() + mock_service = self.mock_cinder.return_value - scenario = volumes.CreateAndExtendVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._extend_volume = mock.MagicMock(return_value=fake_volume) + scenario = volumes.CreateAndExtendVolume(self._get_context()) scenario.sleep_between = mock.MagicMock() - scenario._delete_volume = mock.MagicMock() scenario.run(1, 2, 10, 20, fakearg="f") - scenario._create_volume.assert_called_once_with(1, fakearg="f") - self.assertTrue(scenario._extend_volume.called) + mock_service.create_volume.assert_called_once_with(1, fakearg="f") + mock_service.extend_volume.assert_called_once_with( + mock_service.create_volume.return_value, new_size=2) scenario.sleep_between.assert_called_once_with(10, 20) - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) def test_create_from_image_and_delete_volume(self): - fake_volume = mock.MagicMock() - scenario = volumes.CreateAndDeleteVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndDeleteVolume(self._get_context()) scenario.run(1, image="fake_image") - scenario._create_volume.assert_called_once_with(1, - imageRef="fake_image") - - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.create_volume.assert_called_once_with( + 1, imageRef="fake_image") + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) def test_create_volume_from_image(self): - fake_volume = mock.MagicMock() - scenario = volumes.CreateVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateVolume(self._get_context()) scenario.run(1, image="fake_image") - scenario._create_volume.assert_called_once_with(1, - imageRef="fake_image") + mock_service.create_volume.assert_called_once_with( + 1, imageRef="fake_image") def test_create_volume_from_image_and_list(self): - fake_volume = mock.MagicMock() - scenario = volumes.CreateAndListVolume(self.context) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._list_volumes = mock.MagicMock() - + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndListVolume(self._get_context()) scenario.run(1, True, "fake_image") - scenario._create_volume.assert_called_once_with(1, - imageRef="fake_image") - scenario._list_volumes.assert_called_once_with(True) + mock_service.create_volume.assert_called_once_with( + 1, imageRef="fake_image") + mock_service.list_volumes.assert_called_once_with(True) def test_create_from_volume_and_delete_volume(self): - fake_volume = mock.MagicMock() + mock_service = self.mock_cinder.return_value vol_size = 1 scenario = volumes.CreateFromVolumeAndDeleteVolume(self._get_context()) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario.run(vol_size) - scenario._create_volume.assert_called_once_with(1, source_volid="uuid") - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.create_volume.assert_called_once_with( + 1, source_volid="uuid") + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) - def test_create_and_delete_snapshot(self): - fake_snapshot = mock.MagicMock() + @mock.patch("%s.CreateAndDeleteSnapshot.sleep_between" % CINDER_VOLUMES) + def test_create_and_delete_snapshot(self, mock_sleep_between): + mock_service = self.mock_cinder.return_value scenario = volumes.CreateAndDeleteSnapshot(self._get_context()) - - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario.sleep_between = mock.MagicMock() - scenario._delete_snapshot = mock.MagicMock() - scenario.run(False, 10, 20, fakearg="f") - scenario._create_snapshot.assert_called_once_with("uuid", force=False, - fakearg="f") - scenario.sleep_between.assert_called_once_with(10, 20) - scenario._delete_snapshot.assert_called_once_with(fake_snapshot) + mock_service.create_snapshot.assert_called_once_with("uuid", + force=False, + fakearg="f") + mock_sleep_between.assert_called_once_with(10, 20) + mock_service.delete_snapshot.assert_called_once_with( + mock_service.create_snapshot.return_value) def test_create_and_list_snapshots(self): - fake_snapshot = mock.MagicMock() + mock_service = self.mock_cinder.return_value scenario = volumes.CreateAndListSnapshots(self._get_context()) - - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._list_snapshots = mock.MagicMock() scenario.run(False, True, fakearg="f") - scenario._create_snapshot.assert_called_once_with("uuid", force=False, - fakearg="f") - scenario._list_snapshots.assert_called_once_with(True) + mock_service.create_snapshot.assert_called_once_with("uuid", + force=False, + fakearg="f") + mock_service.list_snapshots.assert_called_once_with(True) def test_create_and_attach_volume(self): - fake_volume = mock.MagicMock() fake_server = mock.MagicMock() - fake_attach = mock.MagicMock() - scenario = volumes.CreateAndAttachVolume(self.context) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) - scenario._detach_volume = mock.MagicMock() + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndAttachVolume(self._get_context()) scenario._boot_server = mock.MagicMock(return_value=fake_server) scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() + scenario._attach_volume = mock.MagicMock() + scenario._detach_volume = mock.MagicMock() volume_args = {"some_key": "some_val"} vm_args = {"some_key": "some_val"} @@ -233,378 +223,262 @@ class CinderServersTestCase(test.ScenarioTestCase): scenario.run(10, "img", "0", create_volume_params=volume_args, create_vm_params=vm_args) - scenario._attach_volume.assert_called_once_with(fake_server, - fake_volume) - scenario._detach_volume.assert_called_once_with(fake_server, - fake_volume, - fake_attach) - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.create_volume.assert_called_once_with( + 10, **volume_args) + scenario._attach_volume.assert_called_once_with( + fake_server, mock_service.create_volume.return_value) + scenario._detach_volume.assert_called_once_with( + fake_server, mock_service.create_volume.return_value, + scenario._attach_volume.return_value) + + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) scenario._delete_server.assert_called_once_with(fake_server) def test_create_and_upload_volume_to_image(self): - fake_volume = mock.Mock() - fake_image = mock.Mock() - scenario = volumes.CreateAndUploadVolumeToImage(self.context) + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateAndUploadVolumeToImage(self._get_context()) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._upload_volume_to_image = mock.MagicMock( - return_value=fake_image) - scenario._delete_volume = mock.MagicMock() scenario._delete_image = mock.MagicMock() scenario.run(2, image="img", container_format="fake", disk_format="disk", do_delete=False, fakeargs="fakeargs") - scenario._create_volume.assert_called_once_with(2, imageRef="img", - fakeargs="fakeargs") - scenario._upload_volume_to_image.assert_called_once_with(fake_volume, - False, - "fake", - "disk") - scenario._create_volume.reset_mock() - scenario._upload_volume_to_image.reset_mock() + mock_service.create_volume.assert_called_once_with( + 2, imageRef="img", fakeargs="fakeargs") + mock_service.upload_volume_to_image.assert_called_once_with( + mock_service.create_volume.return_value, + container_format="fake", disk_format="disk", force=False) + + mock_service.create_volume.reset_mock() + mock_service.upload_volume_to_image.reset_mock() scenario.run(1, image=None, do_delete=True, fakeargs="fakeargs") - scenario._create_volume.assert_called_once_with(1, fakeargs="fakeargs") - scenario._upload_volume_to_image.assert_called_once_with(fake_volume, - False, - "bare", - "raw") - scenario._delete_volume.assert_called_once_with(fake_volume) - scenario._delete_image.assert_called_once_with(fake_image) + mock_service.create_volume.assert_called_once_with( + 1, fakeargs="fakeargs") + mock_service.upload_volume_to_image.assert_called_once_with( + mock_service.create_volume.return_value, + container_format="bare", disk_format="raw", force=False) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) + scenario._delete_image.assert_called_once_with( + mock_service.upload_volume_to_image.return_value) def test_create_snapshot_and_attach_volume(self): - fake_volume = mock.MagicMock() - fake_snapshot = mock.MagicMock() - fake_server = mock.MagicMock() - fake_attach = mock.MagicMock() + mock_service = self.mock_cinder.return_value scenario = volumes.CreateSnapshotAndAttachVolume(self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) + scenario.get_random_server = mock.MagicMock() + scenario._attach_volume = mock.MagicMock() scenario._detach_volume = mock.MagicMock() - scenario._boot_server = mock.MagicMock(return_value=fake_server) - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() - - self.clients("nova").servers.get = mock.MagicMock( - return_value=fake_server) - scenario.run() - self.assertTrue(scenario._create_volume.called) - scenario._create_snapshot.assert_called_once_with(fake_volume.id, - False) - scenario._delete_snapshot.assert_called_once_with(fake_snapshot) + self.assertTrue(mock_service.create_volume.called) + volume = mock_service.create_volume.return_value + snapshot = mock_service.create_snapshot.return_value + mock_service.create_snapshot.assert_called_once_with(volume.id, + force=False) + mock_service.delete_snapshot.assert_called_once_with(snapshot) + scenario._attach_volume.assert_called_once_with( + scenario.get_random_server.return_value, volume) + scenario._detach_volume.assert_called_once_with( + scenario.get_random_server.return_value, volume, + scenario._attach_volume.return_value) + mock_service.delete_volume.assert_called_once_with(volume) + + @mock.patch("random.choice") + def test_create_snapshot_and_attach_volume_use_volume_type_with_name( + self, mock_choice): + mock_service = self.mock_cinder.return_value + + scenario = volumes.CreateSnapshotAndAttachVolume(self._get_context()) + scenario.get_random_server = mock.MagicMock() + scenario._attach_volume = mock.MagicMock() + scenario._detach_volume = mock.MagicMock() + scenario.run(volume_type="type") + + fake_volume = mock_service.create_volume.return_value + fake_attach = scenario._attach_volume.return_value + fake_server = scenario.get_random_server.return_value + fake_snapshot = mock_service.create_snapshot.return_value + + mock_service.create_volume.assert_called_once_with( + {"min": 1, "max": 5}, volume_type="type") + mock_service.create_snapshot.assert_called_once_with(fake_volume.id, + force=False) + mock_service.delete_snapshot.assert_called_once_with(fake_snapshot) scenario._attach_volume.assert_called_once_with(fake_server, fake_volume) scenario._detach_volume.assert_called_once_with(fake_server, fake_volume, fake_attach) - scenario._delete_volume.assert_called_once_with(fake_volume) - - def test_create_snapshot_and_attach_volume_use_volume_type_with_name(self): - fake_volume = mock.MagicMock() - fake_snapshot = mock.MagicMock() - fake_server = mock.MagicMock() - fake_attach = mock.MagicMock() - - scenario = volumes.CreateSnapshotAndAttachVolume(self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) - scenario._detach_volume = mock.MagicMock() - scenario._boot_server = mock.MagicMock(return_value=fake_server) - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() - fake = fake_type() - - self.clients("cinder").volume_types.list = mock.MagicMock( - return_value=[fake]) - self.clients("nova").servers.get = mock.MagicMock( - return_value=fake_server) - - scenario.run(volume_type="fake_volume_type") - - # Make sure create volume's second arg was the correct volume type. - # fake or none (randomly selected) - self.assertTrue(scenario._create_volume.called) - vol_type = scenario._create_volume.call_args_list[0][1]["volume_type"] - self.assertEqual(vol_type, "fake_volume_type") - scenario._create_snapshot.assert_called_once_with(fake_volume.id, - False) - scenario._delete_snapshot.assert_called_once_with(fake_snapshot) - scenario._attach_volume.assert_called_once_with(fake_server, - fake_volume) - scenario._detach_volume.assert_called_once_with(fake_server, - fake_volume, - fake_attach) - scenario._delete_volume.assert_called_once_with(fake_volume) - - def test_create_nested_snapshots_and_attach_volume(self): - fake_volume = mock.MagicMock() - fake_snapshot = mock.MagicMock() - fake_attach = mock.MagicMock() - - scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - context=self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) - scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() - - scenario.run() - - volume_count = scenario._create_volume.call_count - snapshots_count = scenario._create_snapshot.call_count - attached_count = scenario._attach_volume.call_count - - self.assertEqual(scenario._delete_volume.call_count, volume_count) - self.assertEqual(scenario._delete_snapshot.call_count, snapshots_count) - self.assertEqual(scenario._detach_volume.call_count, attached_count) - - def test_create_nested_snapshots_and_attach_volume_kwargs(self): - fake_volume = mock.MagicMock() - fake_snapshot = mock.MagicMock() - fake_attach = mock.MagicMock() - - scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - context=self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) - scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() - - volume_kwargs = {"volume_type": "type1"} - scenario.run(size={"min": 1, "max": 1}, - create_volume_kwargs=volume_kwargs) - - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - self.assertEqual(fake_volume, scenario._create_volume.return_value) - - def test_create_nested_snapshots_and_attach_volume_snapshot_kwargs(self): - fake_volume = mock.MagicMock() - fake_volume.id = "FAKE_ID" - fake_snapshot = mock.MagicMock() - fake_attach = mock.MagicMock() - - scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - context=self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) - scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() + mock_service.delete_volume.assert_called_once_with(fake_volume) + @mock.patch("random.randint") + def test_create_nested_snapshots_and_attach_volume(self, mock_randint): + mock_service = self.mock_cinder.return_value + mock_randint.return_value = 2 volume_kwargs = {"volume_type": "type1"} snapshot_kwargs = {"name": "snapshot1", "description": "snaphot one"} - scenario.run(size={"min": 1, "max": 1}, - create_volume_kwargs=volume_kwargs, + + scenario = volumes.CreateNestedSnapshotsAndAttachVolume( + context=self._get_context()) + scenario.get_random_server = mock.MagicMock() + scenario._attach_volume = mock.MagicMock() + scenario._detach_volume = mock.MagicMock() + scenario.run(create_volume_kwargs=volume_kwargs, create_snapshot_kwargs=snapshot_kwargs) - scenario._create_snapshot.assert_called_once_with(fake_volume.id, - False, - **snapshot_kwargs) - self.assertEqual(fake_snapshot, scenario._create_snapshot.return_value) + mock_service.create_volume.assert_called_once_with( + mock_randint.return_value, **volume_kwargs) + mock_service.create_snapshot.assert_called_once_with( + mock_service.create_volume.return_value.id, force=False, + **snapshot_kwargs) + scenario._attach_volume(scenario.get_random_server.return_value, + mock_service.create_volume.return_value) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) + mock_service.delete_snapshot.assert_called_once_with( + mock_service.create_snapshot.return_value) + scenario._detach_volume.assert_called_once_with( + scenario.get_random_server.return_value, + mock_service.create_volume.return_value, + scenario._attach_volume.return_value) - def test_create_nested_snapshots_and_attach_volume_deprecate_kwargs(self): - fake_volume = mock.MagicMock() - fake_volume.id = "FAKE_ID" - fake_snapshot = mock.MagicMock() - fake_attach = mock.MagicMock() + @mock.patch("random.randint") + def test_create_nested_snapshots_and_attach_volume_2(self, mock_randint): + mock_service = self.mock_cinder.return_value + mock_randint.return_value = 2 + nested_level = 3 + volume_size = mock_randint.return_value + fake_volumes = [mock.Mock(size=volume_size) + for i in range(nested_level)] + fake_snapshots = [mock.Mock() + for i in range(nested_level)] + fake_attachs = [mock.Mock(size=volume_size) + for i in range(nested_level)] + mock_service.create_volume.side_effect = fake_volumes + mock_service.create_snapshot.side_effect = fake_snapshots scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=fake_attach) + context=self._get_context()) + scenario.get_random_server = mock.MagicMock() + scenario._attach_volume = mock.MagicMock(side_effect=fake_attachs) scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() + scenario.run(nested_level=nested_level) - volume_kwargs = {"volume_type": "type1"} - snapshot_kwargs = {"name": "snapshot1", "description": "snaphot one"} - scenario.run(size={"min": 1, "max": 1}, - create_volume_kwargs=volume_kwargs, - **snapshot_kwargs) + expected_volumes = [mock.call(volume_size)] + expected_snapshots = [mock.call(fake_volumes[0].id, force=False)] + expected_attachs = [mock.call(scenario.get_random_server.return_value, + fake_volumes[0])] + for i in range(nested_level - 1): + expected_volumes.append( + mock.call(volume_size, snapshot_id=fake_snapshots[i].id)) + expected_snapshots.append( + mock.call(fake_volumes[i + 1].id, force=False)) + expected_attachs.append( + mock.call(scenario.get_random_server.return_value, + fake_volumes[i + 1])) - scenario._create_snapshot.assert_called_once_with(fake_volume.id, - False, - **snapshot_kwargs) - self.assertEqual(fake_snapshot, scenario._create_snapshot.return_value) - - def test_create_nested_snapshots_calls_order(self): - fake_volume1 = mock.MagicMock() - fake_volume2 = mock.MagicMock() - fake_snapshot1 = mock.MagicMock() - fake_snapshot2 = mock.MagicMock() - - scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - self._get_context()) - - scenario._attach_volume = mock.MagicMock(return_value=mock.MagicMock()) - scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock( - side_effect=[fake_volume1, fake_volume2]) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock( - side_effect=[fake_snapshot1, fake_snapshot2]) - scenario._delete_snapshot = mock.MagicMock() - - scenario.run(nested_level=2) - - vol_delete_calls = [mock.call(fake_volume2), mock.call(fake_volume1)] - snap_delete_calls = [mock.call(fake_snapshot2), - mock.call(fake_snapshot1)] - - scenario._delete_volume.assert_has_calls(vol_delete_calls) - scenario._delete_snapshot.assert_has_calls(snap_delete_calls) - - @mock.patch("rally.plugins.openstack.scenarios.cinder.volumes.random") - def test_create_nested_snapshots_check_resources_size(self, mock_random): - mock_random.randint.return_value = 3 - fake_volume = mock.MagicMock() - fake_snapshot = mock.MagicMock() - fake_server = mock.MagicMock() - - scenario = volumes.CreateNestedSnapshotsAndAttachVolume( - self._get_context()) - - scenario.get_random_server = mock.MagicMock(return_value=fake_server) - scenario._attach_volume = mock.MagicMock(return_value=mock.MagicMock()) - scenario._detach_volume = mock.MagicMock() - scenario._delete_server = mock.MagicMock() - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_volume = mock.MagicMock() - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._delete_snapshot = mock.MagicMock() - - scenario.run(nested_level=2) - - # NOTE: One call for random size - random_call_count = mock_random.randint.call_count - self.assertEqual(1, random_call_count) - - calls = scenario._create_volume.mock_calls - expected_calls = [mock.call(3)] - expected_calls.extend( - [mock.call(3, snapshot_id=fake_snapshot.id)]) - self.assertEqual(expected_calls, calls) + mock_service.create_volume.assert_has_calls(expected_volumes) + mock_service.create_snapshot.assert_has_calls(expected_snapshots) + scenario._attach_volume.assert_has_calls(expected_attachs) + fake_volumes.reverse() + fake_snapshots.reverse() + fake_attachs.reverse() + mock_service.delete_volume.assert_has_calls( + [mock.call(volume) for volume in fake_volumes]) + mock_service.delete_snapshot.assert_has_calls( + [mock.call(snapshot) for snapshot in fake_snapshots]) + scenario._detach_volume.assert_has_calls( + [mock.call(scenario.get_random_server.return_value, + fake_volumes[i], fake_attachs[i]) + for i in range(len(fake_volumes))]) def test_create_volume_backup(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - scenario = volumes.CreateVolumeBackup(self.context) - self._get_scenario(scenario, fake_volume, fake_backup) + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateVolumeBackup(self._get_context()) volume_kwargs = {"some_var": "zaq"} scenario.run(1, do_delete=True, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - scenario._delete_volume.assert_called_once_with(fake_volume) - scenario._delete_backup.assert_called_once_with(fake_backup) + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with( + mock_service.create_volume.return_value.id) + mock_service.delete_volume.assert_called_once_with( + mock_service.create_volume.return_value) + mock_service.delete_backup.assert_called_once_with( + mock_service.create_backup.return_value) def test_create_volume_backup_no_delete(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - scenario = volumes.CreateVolumeBackup(self.context) - self._get_scenario(scenario, fake_volume, fake_backup) + mock_service = self.mock_cinder.return_value + scenario = volumes.CreateVolumeBackup(self._get_context()) volume_kwargs = {"some_var": "zaq"} scenario.run(1, do_delete=False, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - self.assertFalse(scenario._delete_volume.called) - self.assertFalse(scenario._delete_backup.called) - - def _get_scenario(self, scenario, fake_volume, - fake_backup, fake_restore=None): - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._create_backup = mock.MagicMock(return_value=fake_backup) - scenario._restore_backup = mock.MagicMock(return_value=fake_restore) - scenario._list_backups = mock.MagicMock() - scenario._delete_volume = mock.MagicMock() - scenario._delete_backup = mock.MagicMock() + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with( + mock_service.create_volume.return_value.id) + self.assertFalse(mock_service.delete_volume.called) + self.assertFalse(mock_service.delete_backup.called) def test_create_and_restore_volume_backup(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - fake_restore = mock.MagicMock() - scenario = volumes.CreateAndRestoreVolumeBackup(self.context) - self._get_scenario(scenario, fake_volume, fake_backup, fake_restore) - + mock_service = self.mock_cinder.return_value volume_kwargs = {"some_var": "zaq"} + + scenario = volumes.CreateAndRestoreVolumeBackup(self._get_context()) scenario.run(1, do_delete=True, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - scenario._restore_backup.assert_called_once_with(fake_backup.id) - scenario._delete_volume.assert_called_once_with(fake_volume) - scenario._delete_backup.assert_called_once_with(fake_backup) + + fake_volume = mock_service.create_volume.return_value + fake_backup = mock_service.create_backup.return_value + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with(fake_volume.id) + mock_service.restore_backup.assert_called_once_with(fake_backup.id) + mock_service.delete_volume.assert_called_once_with(fake_volume) + mock_service.delete_backup.assert_called_once_with(fake_backup) def test_create_and_restore_volume_backup_no_delete(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - fake_restore = mock.MagicMock() - scenario = volumes.CreateAndRestoreVolumeBackup(self.context) - self._get_scenario(scenario, fake_volume, fake_backup, fake_restore) - + mock_service = self.mock_cinder.return_value volume_kwargs = {"some_var": "zaq"} + scenario = volumes.CreateAndRestoreVolumeBackup(self._get_context()) scenario.run(1, do_delete=False, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - scenario._restore_backup.assert_called_once_with(fake_backup.id) - self.assertFalse(scenario._delete_volume.called) - self.assertFalse(scenario._delete_backup.called) + + fake_volume = mock_service.create_volume.return_value + fake_backup = mock_service.create_backup.return_value + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with(fake_volume.id) + mock_service.restore_backup.assert_called_once_with(fake_backup.id) + self.assertFalse(mock_service.delete_volume.called) + self.assertFalse(mock_service.delete_backup.called) def test_create_and_list_volume_backups(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - scenario = volumes.CreateAndListVolumeBackups(self.context) - self._get_scenario(scenario, fake_volume, fake_backup) - + mock_service = self.mock_cinder.return_value volume_kwargs = {"some_var": "zaq"} + scenario = volumes.CreateAndListVolumeBackups(self._get_context()) scenario.run(1, detailed=True, do_delete=True, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - scenario._list_backups.assert_called_once_with(True) - scenario._delete_volume.assert_called_once_with(fake_volume) - scenario._delete_backup.assert_called_once_with(fake_backup) + + fake_volume = mock_service.create_volume.return_value + fake_backup = mock_service.create_backup.return_value + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with(fake_volume.id) + mock_service.list_backups.assert_called_once_with(True) + mock_service.delete_volume.assert_called_once_with(fake_volume) + mock_service.delete_backup.assert_called_once_with(fake_backup) def test_create_and_list_volume_backups_no_delete(self): - fake_volume = mock.MagicMock() - fake_backup = mock.MagicMock() - scenario = volumes.CreateAndListVolumeBackups(self.context) - self._get_scenario(scenario, fake_volume, fake_backup) - + mock_service = self.mock_cinder.return_value volume_kwargs = {"some_var": "zaq"} + scenario = volumes.CreateAndListVolumeBackups(self._get_context()) scenario.run(1, detailed=True, do_delete=False, create_volume_kwargs=volume_kwargs) - scenario._create_volume.assert_called_once_with(1, **volume_kwargs) - scenario._create_backup.assert_called_once_with(fake_volume.id) - scenario._list_backups.assert_called_once_with(True) - self.assertFalse(scenario._delete_volume.called) - self.assertFalse(scenario._delete_backup.called) + + fake_volume = mock_service.create_volume.return_value + mock_service.create_volume.assert_called_once_with(1, **volume_kwargs) + mock_service.create_backup.assert_called_once_with(fake_volume.id) + mock_service.list_backups.assert_called_once_with(True) + self.assertFalse(mock_service.delete_volume.called) + self.assertFalse(mock_service.delete_backup.called) @ddt.data({}, {"nested_level": 2}, @@ -613,72 +487,70 @@ class CinderServersTestCase(test.ScenarioTestCase): def test_create_volume_and_clone(self, nested_level=1, image=None): create_volumes_count = nested_level + 1 - fake_volumes = [mock.Mock(size=1) for i in range(create_volumes_count)] - scenario = volumes.CreateVolumeAndClone(self.context) - scenario._create_volume = mock.MagicMock(side_effect=fake_volumes) + fake_volumes = [mock.Mock(size=1) + for i in range(create_volumes_count)] + mock_service = self.mock_cinder.return_value + mock_service.create_volume.side_effect = fake_volumes - scenario.run(1, image=image, nested_level=nested_level, fakearg="fake") + scenario = volumes.CreateVolumeAndClone(self._get_context()) + scenario.run(1, image=image, nested_level=nested_level, + fakearg="fake") expected = [mock.call(1, imageRef=image, fakearg="fake") if image else mock.call(1, fakearg="fake")] for i in range(nested_level): expected.append(mock.call(fake_volumes[i].size, source_volid=fake_volumes[i].id, - atomic_action=False, fakearg="fake") + fakearg="fake") ) self._test_atomic_action_timer(scenario.atomic_actions(), "cinder.clone_volume") - scenario._create_volume.assert_has_calls(expected) + mock_service.create_volume.assert_has_calls(expected) def test_create_volume_from_snapshot(self): - fake_snapshot = mock.MagicMock(id=1) - fake_volume = mock.MagicMock() + mock_service = self.mock_cinder.return_value create_snapshot_args = {"force": False} + scenario = volumes.CreateVolumeFromSnapshot(self._get_context()) - - scenario._create_snapshot = mock.MagicMock(return_value=fake_snapshot) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._delete_snapshot = mock.MagicMock() - scenario._delete_volume = mock.MagicMock() - scenario.run(fakearg="f") - scenario._create_snapshot.assert_called_once_with("uuid") - scenario._create_volume.assert_called_once_with( + fake_snapshot = mock_service.create_snapshot.return_value + fake_volume = mock_service.create_volume.return_value + mock_service.create_snapshot.assert_called_once_with("uuid") + mock_service.create_volume.assert_called_once_with( 1, snapshot_id=fake_snapshot.id, fakearg="f") - scenario._delete_snapshot.assert_called_once_with(fake_snapshot) - scenario._delete_volume.assert_called_once_with(fake_volume) + mock_service.delete_snapshot.assert_called_once_with(fake_snapshot) + mock_service.delete_volume.assert_called_once_with(fake_volume) - scenario._create_snapshot.reset_mock() - scenario._create_volume.reset_mock() - scenario._delete_snapshot.reset_mock() - scenario._delete_volume.reset_mock() + mock_service.create_snapshot.reset_mock() + mock_service.create_volume.reset_mock() + mock_service.delete_snapshot.reset_mock() + mock_service.delete_volume.reset_mock() scenario.run(do_delete=False, create_snapshot_kwargs=create_snapshot_args, fakearg="f") - scenario._create_snapshot.assert_called_once_with( + mock_service.create_snapshot.assert_called_once_with( "uuid", **create_snapshot_args) - scenario._create_volume.assert_called_once_with( + mock_service.create_volume.assert_called_once_with( 1, snapshot_id=fake_snapshot.id, fakearg="f") - self.assertFalse(scenario._delete_snapshot.called) - self.assertFalse(scenario._delete_volume.called) + self.assertFalse(mock_service.delete_snapshot.called) + self.assertFalse(mock_service.delete_volume.called) @ddt.data({}, {"image": "img"}) @ddt.unpack def test_create_and_accept_transfer(self, image=None): - fake_volume = mock.MagicMock() - fake_transfer = mock.MagicMock() + mock_service = self.mock_cinder.return_value scenario = volumes.CreateAndAcceptTransfer(self._get_context()) - scenario._create_volume = mock.MagicMock(return_value=fake_volume) - scenario._transfer_create = mock.MagicMock(return_value=fake_transfer) - scenario._transfer_accept = mock.MagicMock() scenario.run(1, image=image, fakearg="fake") + expected = [mock.call(1, imageRef=image, fakearg="fake") if image else mock.call(1, fakearg="fake")] - scenario._create_volume.assert_has_calls(expected) - scenario._transfer_create.assert_called_once_with(fake_volume.id) - scenario._transfer_accept.assert_called_once_with( - fake_transfer.id, fake_transfer.auth_key) + mock_service.create_volume.assert_has_calls(expected) + mock_service.transfer_create.assert_called_once_with( + mock_service.create_volume.return_value.id) + mock_service.transfer_accept.assert_called_once_with( + mock_service.transfer_create.return_value.id, + auth_key=mock_service.transfer_create.return_value.auth_key) diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py b/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py old mode 100755 new mode 100644 diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py old mode 100755 new mode 100644 diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py old mode 100755 new mode 100644 index c60897f4d6..7d3bf29e34 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -37,8 +37,8 @@ class NovaScenarioTestCase(test.ScenarioTestCase): self.volume = mock.Mock() self.floating_ip = mock.Mock() self.image = mock.Mock() - self.context["iteration"] = 3 - self.context["config"] = {"users": {"tenants": 2}} + self.context.update( + {"user": {"id": "fake_user_id", "credential": mock.MagicMock()}}) def _context_with_networks(self, networks): retval = {"tenant": {"networks": networks}} @@ -596,6 +596,15 @@ class NovaScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.resize_revert") + @mock.patch("rally.plugins.openstack.services.storage.block.BlockStorage") + def test__update_volume_resource(self, mock_block_storage): + volume = fakes.FakeVolume(id=1) + cinder = mock_block_storage.return_value + cinder.get_volume = mock.MagicMock() + nova_scenario = utils.NovaScenario(context=self.context) + self.assertEqual(cinder.get_volume.return_value, + nova_scenario._update_volume_resource(volume)) + def test__attach_volume(self): expect_attach = mock.MagicMock() device = None diff --git a/tests/unit/plugins/openstack/services/storage/test_block.py b/tests/unit/plugins/openstack/services/storage/test_block.py index b0e0e93d1d..9c1e6933b8 100644 --- a/tests/unit/plugins/openstack/services/storage/test_block.py +++ b/tests/unit/plugins/openstack/services/storage/test_block.py @@ -167,6 +167,13 @@ class BlockTestCase(test.TestCase): self.service._impl.create_volume_type.assert_called_once_with( name="type", description=None, is_public=True) + def test_get_volume_type(self): + self.assertEqual( + self.service._impl.get_volume_type.return_value, + self.service.get_volume_type("volume_type")) + self.service._impl.get_volume_type.assert_called_once_with( + "volume_type") + def test_delete_volume_type(self): self.service.delete_volume_type("volume_type") self.service._impl.delete_volume_type.assert_called_once_with( diff --git a/tests/unit/plugins/openstack/services/storage/test_cinder_common.py b/tests/unit/plugins/openstack/services/storage/test_cinder_common.py index 1982ba4c30..c286d0c60a 100644 --- a/tests/unit/plugins/openstack/services/storage/test_cinder_common.py +++ b/tests/unit/plugins/openstack/services/storage/test_cinder_common.py @@ -14,11 +14,13 @@ import uuid +import ddt import mock from oslo_config import cfg from rally import exceptions from rally.plugins.openstack import service +from rally.plugins.openstack.services.storage import block from rally.plugins.openstack.services.storage import cinder_common from tests.unit import fakes from tests.unit import test @@ -32,6 +34,7 @@ class FullCinder(service.Service, cinder_common.CinderMixin): pass +@ddt.ddt class CinderMixinTestCase(test.ScenarioTestCase): def setUp(self): super(CinderMixinTestCase, self).setUp() @@ -50,20 +53,63 @@ class CinderMixinTestCase(test.ScenarioTestCase): self.assertEqual(self.cinder, self.service._get_client()) + def test__update_resource_with_manage(self): + resource = mock.MagicMock(id=1, manager=mock.MagicMock()) + self.assertEqual(resource.manager.get.return_value, + self.service._update_resource(resource)) + resource.manager.get.assert_called_once_with( + resource.id) + + @ddt.data({"resource": block.Volume(id=1, name="vol", + size=1, status="st"), + "attr": "volumes"}, + {"resource": block.VolumeSnapshot(id=2, name="snapshot", + volume_id=1, status="st"), + "attr": "volume_snapshots"}, + {"resource": block.VolumeBackup(id=3, name="backup", + volume_id=1, status="st"), + "attr": "backups"}) + @ddt.unpack + def test__update_resource_with_no_manage(self, resource, attr): + self.assertEqual(getattr(self.cinder, attr).get.return_value, + self.service._update_resource(resource)) + getattr(self.cinder, attr).get.assert_called_once_with( + resource.id) + + def test__update_resource_with_not_found(self): + manager = mock.MagicMock() + resource = fakes.FakeResource(manager=manager, status="ERROR") + + class NotFoundException(Exception): + http_status = 404 + + manager.get = mock.MagicMock(side_effect=NotFoundException) + self.assertRaises(exceptions.GetResourceNotFound, + self.service._update_resource, resource) + + def test__update_resource_with_http_exception(self): + manager = mock.MagicMock() + resource = fakes.FakeResource(manager=manager, status="ERROR") + + class HTTPException(Exception): + pass + + manager.get = mock.MagicMock(side_effect=HTTPException) + self.assertRaises(exceptions.GetResourceFailure, + self.service._update_resource, resource) + def test__wait_available_volume(self): volume = fakes.FakeVolume() - return_volume = self.service._wait_available_volume(volume) + self.assertEqual(self.mock_wait_for_status.mock.return_value, + self.service._wait_available_volume(volume)) - self.mock_get_from_manager.mock.assert_called_once_with() self.mock_wait_for_status.mock.assert_called_once_with( volume, ready_statuses=["available"], - update_resource=self.mock_get_from_manager.mock.return_value, + update_resource=self.service._update_resource, timeout=CONF.benchmark.cinder_volume_create_timeout, check_interval=CONF.benchmark.cinder_volume_create_poll_interval ) - self.assertEqual(self.mock_wait_for_status.mock.return_value, - return_volume) def test_list_volumes(self): self.assertEqual(self.cinder.volumes.list.return_value, @@ -81,12 +127,11 @@ class CinderMixinTestCase(test.ScenarioTestCase): self.service.delete_volume(volume) self.cinder.volumes.delete.assert_called_once_with(volume) - self.mock_get_from_manager.mock.assert_called_once_with() self.mock_wait_for_status.mock.assert_called_once_with( volume, ready_statuses=["deleted"], check_deletion=True, - update_resource=self.mock_get_from_manager.mock.return_value, + update_resource=self.service._update_resource, timeout=CONF.benchmark.cinder_volume_delete_timeout, check_interval=CONF.benchmark.cinder_volume_delete_poll_interval ) @@ -97,7 +142,8 @@ class CinderMixinTestCase(test.ScenarioTestCase): self.service._wait_available_volume = mock.MagicMock() self.service._wait_available_volume.return_value = fakes.FakeVolume() - self.service.extend_volume(volume, 1) + self.assertEqual(self.service._wait_available_volume.return_value, + self.service.extend_volume(volume, 1)) self.cinder.volumes.extend.assert_called_once_with(volume, 1) self.service._wait_available_volume.assert_called_once_with(volume) @@ -168,7 +214,7 @@ class CinderMixinTestCase(test.ScenarioTestCase): mock.call( volume, ready_statuses=["available"], - update_resource=self.mock_get_from_manager.mock.return_value, + update_resource=self.service._update_resource, timeout=CONF.benchmark.cinder_volume_create_timeout, check_interval=CONF.benchmark. cinder_volume_create_poll_interval), @@ -180,7 +226,6 @@ class CinderMixinTestCase(test.ScenarioTestCase): check_interval=CONF.benchmark. glance_image_create_poll_interval) ]) - self.mock_get_from_manager.mock.assert_called_once_with() glance_client.images.get.assert_called_once_with(1) def test_delete_snapshot(self): @@ -191,11 +236,10 @@ class CinderMixinTestCase(test.ScenarioTestCase): snapshot, ready_statuses=["deleted"], check_deletion=True, - update_resource=self.mock_get_from_manager.mock.return_value, + update_resource=self.service._update_resource, timeout=cfg.CONF.benchmark.cinder_volume_create_timeout, check_interval=cfg.CONF.benchmark .cinder_volume_create_poll_interval) - self.mock_get_from_manager.mock.assert_called_once_with() def test_delete_backup(self): backup = mock.Mock() @@ -205,11 +249,10 @@ class CinderMixinTestCase(test.ScenarioTestCase): backup, ready_statuses=["deleted"], check_deletion=True, - update_resource=self.mock_get_from_manager.mock.return_value, + update_resource=self.service._update_resource, timeout=cfg.CONF.benchmark.cinder_volume_create_timeout, check_interval=cfg.CONF.benchmark .cinder_volume_create_poll_interval) - self.mock_get_from_manager.mock.assert_called_once_with() def test_restore_backup(self): backup = mock.Mock() @@ -238,6 +281,12 @@ class CinderMixinTestCase(test.ScenarioTestCase): self.cinder.transfers.list.return_value, return_transfers_list) + def test_get_volume_type(self): + self.assertEqual(self.cinder.volume_types.get.return_value, + self.service.get_volume_type("volume_type")) + self.cinder.volume_types.get.assert_called_once_with( + "volume_type") + def test_delete_volume_type(self): volume_type = mock.Mock() self.service.delete_volume_type(volume_type) @@ -341,20 +390,24 @@ class UnifiedCinderMixinTestCase(test.TestCase): id = 1 name = "backup" volume_id = "volume" + status = "st" backup = self.service._unify_backup(SomeBackup()) self.assertEqual(1, backup.id) self.assertEqual("backup", backup.name) self.assertEqual("volume", backup.volume_id) + self.assertEqual("st", backup.status) def test__unify_transfer(self): class SomeTransfer(object): id = 1 name = "transfer" volume_id = "volume" + status = "st" transfer = self.service._unify_backup(SomeTransfer()) self.assertEqual(1, transfer.id) self.assertEqual("transfer", transfer.name) self.assertEqual("volume", transfer.volume_id) + self.assertEqual("st", transfer.status) def test__unify_encryption_type(self): class SomeEncryptionType(object): @@ -408,15 +461,6 @@ class UnifiedCinderMixinTestCase(test.TestCase): self.service.delete_backup("backup") self.service._impl.delete_backup.assert_called_once_with("backup") - def test_restore_backup(self): - self.service._unify_backup = mock.MagicMock() - self.assertEqual(self.service._unify_backup.return_value, - self.service.restore_backup(1, volume_id=1)) - self.service._impl.restore_backup.assert_called_once_with(1, - volume_id=1) - self.service._unify_backup.assert_called_once_with( - self.service._impl.restore_backup.return_value) - def test_list_backups(self): self.service._unify_backup = mock.MagicMock() self.service._impl.list_backups.return_value = ["backup"] @@ -437,6 +481,12 @@ class UnifiedCinderMixinTestCase(test.TestCase): self.service._unify_transfer.assert_called_once_with( "transfer") + def test_get_volume_type(self): + self.assertEqual(self.service._impl.get_volume_type.return_value, + self.service.get_volume_type("volume_type")) + self.service._impl.get_volume_type.assert_called_once_with( + "volume_type") + def test_delete_volume_type(self): self.assertEqual(self.service._impl.delete_volume_type.return_value, self.service.delete_volume_type("volume_type")) diff --git a/tests/unit/plugins/openstack/services/storage/test_cinder_v1.py b/tests/unit/plugins/openstack/services/storage/test_cinder_v1.py index ee7507244f..7c0ace2736 100644 --- a/tests/unit/plugins/openstack/services/storage/test_cinder_v1.py +++ b/tests/unit/plugins/openstack/services/storage/test_cinder_v1.py @@ -88,28 +88,25 @@ class CinderV1ServiceTestCase(test.ScenarioTestCase): return_volume) def test_update_volume(self): - self.service.generate_random_name = mock.MagicMock( - return_value="volume") + return_value = {"volume": fakes.FakeVolume()} + self.cinder.volumes.update.return_value = return_value - return_volume = self.service.update_volume( - 1, display_description="fake") - - self.service.generate_random_name.assert_called_once_with() - self.cinder.volumes.update.assert_called_once_with( - 1, display_name="volume", display_description="fake") - self.assertEqual(self.cinder.volumes.update.return_value, - return_volume) + self.assertEqual(return_value["volume"], + self.service.update_volume(1)) + self.cinder.volumes.update.assert_called_once_with(1) self._test_atomic_action_timer(self.atomic_actions(), "cinder_v1.update_volume") - def test_update_volume_with_name(self): + def test_update_volume_with_name_description(self): + return_value = {"volume": fakes.FakeVolume()} + self.cinder.volumes.update.return_value = return_value + return_volume = self.service.update_volume( 1, display_name="volume", display_description="fake") self.cinder.volumes.update.assert_called_once_with( 1, display_name="volume", display_description="fake") - self.assertEqual(self.cinder.volumes.update.return_value, - return_volume) + self.assertEqual(return_value["volume"], return_volume) self._test_atomic_action_timer(self.atomic_actions(), "cinder_v1.update_volume") @@ -224,20 +221,33 @@ class UnifiedCinderV1ServiceTestCase(test.TestCase): id = 1 display_name = "volume" size = 1 + status = "st" volume = self.service._unify_volume(SomeVolume()) self.assertEqual(1, volume.id) self.assertEqual("volume", volume.name) self.assertEqual(1, volume.size) + self.assertEqual("st", volume.status) + + def test__unify_volume_with_dict(self): + some_volume = {"display_name": "volume", "id": 1, + "size": 1, "status": "st"} + volume = self.service._unify_volume(some_volume) + self.assertEqual(1, volume.id) + self.assertEqual("volume", volume.name) + self.assertEqual(1, volume.size) + self.assertEqual("st", volume.status) def test__unify_snapshot(self): class SomeSnapshot(object): id = 1 display_name = "snapshot" volume_id = "volume" + status = "st" snapshot = self.service._unify_snapshot(SomeSnapshot()) self.assertEqual(1, snapshot.id) self.assertEqual("snapshot", snapshot.name) self.assertEqual("volume", snapshot.volume_id) + self.assertEqual("st", snapshot.status) def test_create_volume(self): self.service._unify_volume = mock.MagicMock() @@ -334,3 +344,12 @@ class UnifiedCinderV1ServiceTestCase(test.TestCase): self.service.create_volume_type(name="type")) self.service._impl.create_volume_type.assert_called_once_with( name="type") + + def test_restore_backup(self): + self.service._unify_volume = mock.MagicMock() + self.assertEqual(self.service._unify_volume.return_value, + self.service.restore_backup(1, volume_id=1)) + self.service._impl.restore_backup.assert_called_once_with(1, + volume_id=1) + self.service._unify_volume.assert_called_once_with( + self.service._impl.restore_backup.return_value) diff --git a/tests/unit/plugins/openstack/services/storage/test_cinder_v2.py b/tests/unit/plugins/openstack/services/storage/test_cinder_v2.py index de83d0c805..6695bb9c2d 100644 --- a/tests/unit/plugins/openstack/services/storage/test_cinder_v2.py +++ b/tests/unit/plugins/openstack/services/storage/test_cinder_v2.py @@ -96,27 +96,25 @@ class CinderV2ServiceTestCase(test.ScenarioTestCase): return_volume) def test_update_volume(self): - self.service.generate_random_name = mock.MagicMock( - return_value="volume") + return_value = {"volume": fakes.FakeVolume()} + self.cinder.volumes.update.return_value = return_value - return_volume = self.service.update_volume(1, description="fake") - - self.service.generate_random_name.assert_called_once_with() - self.cinder.volumes.update.assert_called_once_with(1, name="volume", - description="fake") - self.assertEqual(self.cinder.volumes.update.return_value, - return_volume) + self.assertEqual(return_value["volume"], + self.service.update_volume(1)) + self.cinder.volumes.update.assert_called_once_with(1) self._test_atomic_action_timer(self.atomic_actions(), "cinder_v2.update_volume") - def test_update_volume_with_name(self): - return_volume = self.service.update_volume(1, name="volume", - description="fake") + def test_update_volume_with_name_description(self): + return_value = {"volume": fakes.FakeVolume()} + self.cinder.volumes.update.return_value = return_value - self.cinder.volumes.update.assert_called_once_with(1, name="volume", - description="fake") - self.assertEqual(self.cinder.volumes.update.return_value, - return_volume) + return_volume = self.service.update_volume( + 1, name="volume", description="fake") + + self.cinder.volumes.update.assert_called_once_with( + 1, name="volume", description="fake") + self.assertEqual(return_value["volume"], return_volume) self._test_atomic_action_timer(self.atomic_actions(), "cinder_v2.update_volume") @@ -237,20 +235,32 @@ class UnifiedCinderV2ServiceTestCase(test.TestCase): id = 1 name = "volume" size = 1 + status = "st" volume = self.service._unify_volume(SomeVolume()) self.assertEqual(1, volume.id) self.assertEqual("volume", volume.name) self.assertEqual(1, volume.size) + self.assertEqual("st", volume.status) + + def test__unify_volume_with_dict(self): + some_volume = {"name": "volume", "id": 1, "size": 1, "status": "st"} + volume = self.service._unify_volume(some_volume) + self.assertEqual(1, volume.id) + self.assertEqual("volume", volume.name) + self.assertEqual(1, volume.size) + self.assertEqual("st", volume.status) def test__unify_snapshot(self): class SomeSnapshot(object): id = 1 name = "snapshot" volume_id = "volume" + status = "st" snapshot = self.service._unify_snapshot(SomeSnapshot()) self.assertEqual(1, snapshot.id) self.assertEqual("snapshot", snapshot.name) self.assertEqual("volume", snapshot.volume_id) + self.assertEqual("st", snapshot.status) def test_create_volume(self): self.service._unify_volume = mock.MagicMock() @@ -355,3 +365,12 @@ class UnifiedCinderV2ServiceTestCase(test.TestCase): is_public=True)) self.service._impl.create_volume_type.assert_called_once_with( name="type", description="desp", is_public=True) + + def test_restore_backup(self): + self.service._unify_volume = mock.MagicMock() + self.assertEqual(self.service._unify_volume.return_value, + self.service.restore_backup(1, volume_id=1)) + self.service._impl.restore_backup.assert_called_once_with(1, + volume_id=1) + self.service._unify_volume.assert_called_once_with( + self.service._impl.restore_backup.return_value)