diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index bd7acc98..4ee71196 100755 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -179,8 +179,7 @@ - args: update_volume_kwargs: - display_name: "name_updated" - display_description: "desc_updated" + description: "desc_updated" size: 1 runner: type: "constant" @@ -196,8 +195,7 @@ - args: update_volume_kwargs: - display_name: "name_updated" - display_description: "desc_updated" + description: "desc_updated" size: 1 image: name: {{image_name}} @@ -510,7 +508,6 @@ CinderVolumes.create_snapshot_and_attach_volume: - args: - volume_type: false size: min: 1 max: 1 @@ -534,7 +531,7 @@ - args: - volume_type: true + volume_type: "test" size: min: 1 max: 1 @@ -552,6 +549,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 12bef746..27b68bd3 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 96ecadae..c6159a26 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 caeffcce..29efdd67 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 4c7a1082..71faf343 --- 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 ceb4c19e..ed7e0fef --- 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 40c31f6f..c421b5ee 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 f8ed8d72..ab8304b7 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 7f29fe42..023b445a 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 7d7833e6..2c314de7 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 50e49ac7..0810d4b3 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 05867c78..409302fb 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 4d8fc1cd..7e24ba47 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 b9431ed5..f77a22fc 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 7770a45c..167ce17c 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 0755e2a3..f49daa81 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 dd8bb128..94eee8d8 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 6f953100..073a5648 --- 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 c60897f4..7d3bf29e --- 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 b0e0e93d..9c1e6933 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 1982ba4c..c286d0c6 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 ee750724..7c0ace27 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 de83d0c8..6695bb9c 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)