diff --git a/ChangeLog b/ChangeLog index 212d0eb5..98a61bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ PyU4V Change Log ================ +Version 9.2.0.1 - released 12/10/20 +=================================== +-Tighten base CI tests around RDF group creation and deletion. +-Update Unisphere minimum version to reflect 9.2 GA Unisphere version. + + Version 9.2.0.0 - released 29/09/20 =================================== diff --git a/PyU4V/__init__.py b/PyU4V/__init__.py index 11e31c5c..ba2f68a2 100644 --- a/PyU4V/__init__.py +++ b/PyU4V/__init__.py @@ -23,7 +23,7 @@ from .univmax_conn import U4VConn # noqa: F401 __title__ = 'pyu4v' -__version__ = '9.2.0.0' +__version__ = '9.2.0.1' __author__ = 'Dell EMC or its subsidiaries' __license__ = 'Apache 2.0' __copyright__ = 'Copyright 2020 Dell EMC Inc' diff --git a/PyU4V/tests/ci_tests/base.py b/PyU4V/tests/ci_tests/base.py index 43c51cee..767fe5f5 100644 --- a/PyU4V/tests/ci_tests/base.py +++ b/PyU4V/tests/ci_tests/base.py @@ -97,7 +97,7 @@ def delete_volume(self, sg_name, device_id): if device_id: self.provision.delete_volume(device_id) -# Replication Functions + # Replication Functions def create_sg_snapshot(self): """Create a test storage group snapshot. @@ -159,28 +159,78 @@ def create_rdf_sg(self): srdf_group_number -- int remote_volume -- int """ - sg_name = self.generate_name(object_type='sg') + # Check remote array exists self.check_for_remote_array() - self.provision.create_storage_group( - self.SRP, sg_name, self.SLO, None, False, 1, 1, 'GB', False, False, - 'CI_TEST_VOL') - job = self.replication.create_storage_group_srdf_pairings( - storage_group_id=sg_name, remote_sid=self.conn.remote_array, - srdf_mode='Synchronous', establish=True, force_new_rdf_group=True, - _async=True) - self.conn.common.wait_for_job_complete(job) - local_volume = self.provision.get_volumes_from_storage_group( - sg_name)[0] - srdf_group_number = ( - self.replication.get_storage_group_srdf_group_list( - sg_name))[0] - remote_volume = self.replication.get_rdf_group_volume( - rdf_number=srdf_group_number, device_id=local_volume).get( - 'remoteVolumeName') - self.addCleanup(self.cleanup_rdfg, sg_name, srdf_group_number) - - return sg_name, srdf_group_number, local_volume, remote_volume + # Generate SG name and create SG with one 1GB volume + sg_name = self.generate_name(object_type='sg') + vol_name = self.generate_name() + srdf_group_number = None + + try: + sg_create_success, sg_create_cnt = False, 0 + while not sg_create_success and sg_create_cnt <= 3: + try: + sg_create_cnt += 1 + storage_group = self.provision.create_storage_group( + self.SRP, sg_name, self.SLO, None, False, 1, 1, 'GB', + False, False, vol_name) + assert storage_group.get('storageGroupId') == sg_name + assert storage_group.get('num_of_vols') == 1 + sg_create_success = True + except (exception.VolumeBackendAPIException, + AssertionError) as error: + if sg_create_cnt == 3: + raise exception.VolumeBackendAPIException from error + else: + time.sleep(10) + + # Create SRDF pairing for SG and single volume + srdf_pair_create_success, srdf_pair_create_cnt = False, 0 + while not srdf_pair_create_success and srdf_pair_create_cnt <= 3: + try: + job = self.replication.create_storage_group_srdf_pairings( + storage_group_id=sg_name, + remote_sid=self.conn.remote_array, + srdf_mode='Synchronous', establish=True, + force_new_rdf_group=True, _async=True) + self.conn.common.wait_for_job_complete(job) + srdf_pair_info = ( + self.replication.get_storage_group_replication_details( + storage_group_id=sg_name)) + assert srdf_pair_info.get('rdf') is True + srdf_pair_create_success = True + except (exception.VolumeBackendAPIException, + AssertionError) as error: + if srdf_pair_create_cnt == 3: + raise exception.VolumeBackendAPIException from error + else: + time.sleep(10) + + # Get the device ID of the volume in the local SG + local_vol_list = self.provision.get_volumes_from_storage_group( + sg_name) + assert len(local_vol_list) == 1 + local_volume = local_vol_list[0] + + # Get the SRDF group number associated with our SG + srdf_group_list = ( + self.replication.get_storage_group_srdf_group_list(sg_name)) + assert len(srdf_group_list) == 1 + srdf_group_number = srdf_group_list[0] + + # Get details of the remote volume + remote_volume_details = self.replication.get_rdf_group_volume( + rdf_number=srdf_group_number, device_id=local_volume) + assert remote_volume_details + remote_vol_id = remote_volume_details.get('remoteVolumeName') + + except Exception as error: + raise Exception from error + finally: + self.addCleanup(self.cleanup_rdfg, sg_name, srdf_group_number) + + return sg_name, srdf_group_number, local_volume, remote_vol_id def check_for_remote_array(self): """Check for remote_array tag in configuration file.""" diff --git a/PyU4V/tests/ci_tests/test_pyu4v_ci_replication.py b/PyU4V/tests/ci_tests/test_pyu4v_ci_replication.py index 5c3c6567..a52bc94c 100644 --- a/PyU4V/tests/ci_tests/test_pyu4v_ci_replication.py +++ b/PyU4V/tests/ci_tests/test_pyu4v_ci_replication.py @@ -543,9 +543,10 @@ def test_create_storagegroup_srdf_pairings(self): """Test create_storagegroup_srdf_pairings.""" self.check_for_remote_array() sg_name = self.generate_name(object_type='sg') + vol_name = self.generate_name(object_type='v') self.conn.provisioning.create_storage_group( self.SRP, sg_name, self.SLO, None, False, 1, 1, 'GB', False, False, - 'CI_TEST_VOL') + vol_name) self.replication.create_storagegroup_srdf_pairings( storagegroup_id=sg_name, remote_sid=self.conn.remote_array, srdfmode='Synchronous', establish=True, forceNewRdfGroup=True) diff --git a/PyU4V/utils/constants.py b/PyU4V/utils/constants.py index 9e72cf09..536ac7fe 100644 --- a/PyU4V/utils/constants.py +++ b/PyU4V/utils/constants.py @@ -39,7 +39,7 @@ APP_MPART = 'multipart/form-data' # Unisphere REST URI constants -PYU4V_VERSION = '9.2.0.0' +PYU4V_VERSION = '9.2.0.1' UNISPHERE_VERSION = '92' VERSION = 'version' ITERATOR = 'Iterator' diff --git a/README.rst b/README.rst index 2d89c193..21cd010e 100644 --- a/README.rst +++ b/README.rst @@ -26,9 +26,9 @@ PyU4V Version 9.2 +-------------------------------+----------------------------+ | **Author** | Dell EMC | +-------------------------------+----------------------------+ -| **PyU4V Version** | 9.2.0.0 | +| **PyU4V Version** | 9.2.0.1 | +-------------------------------+----------------------------+ -| **Minimum Unisphere Version** | 9.2.0.0 | +| **Minimum Unisphere Version** | 9.2.0.1 | +-------------------------------+----------------------------+ | **Array Model** | VMAX-3, VMAX AFA, PowerMax | +-------------------------------+----------------------------+ @@ -80,7 +80,7 @@ specifying ``PyU4V`` as the install package for ``pip``:: $ pip install PyU4V # Install a specific version - $ pip install PyU4V==9.2.0.0 + $ pip install PyU4V==9.2.0.1 Copy the sample ``PyU4V.conf`` provided with PyU4V to either your working directory or within a directory named ``.PyU4V`` in your current users home @@ -169,7 +169,7 @@ outlined in the previous section). conn = PyU4V.U4VConn() conn.common.get_unisphere_version() - >> {'version': 'V9.2.0.0'} + >> {'version': 'V9.2.0.1'} If you wish to query another array without changing the configuration file, call the connection ``set_array_id()`` function: diff --git a/docs/source/conf.py b/docs/source/conf.py index c270bd3f..8404a762 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -26,7 +26,7 @@ # The short X.Y version. version = u'9.2' # The full version, including alpha/beta/rc tags -release = '9.2.0.0' +release = '9.2.0.1' # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: diff --git a/docs/source/index.rst b/docs/source/index.rst index ddc98098..5a2ee0c1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -35,9 +35,9 @@ Supported PyU4V Versions ------------------------ +-------------------------------+----------------------------------------+ -| **PyU4V Version** | 9.2.0.0 | +| **PyU4V Version** | 9.2.0.1 | +-------------------------------+----------------------------------------+ -| **Minimum Unisphere Version** | 9.2.0.0 | +| **Minimum Unisphere Version** | 9.2.0.1 | +-------------------------------+----------------------------------------+ | **Array Model** | VMAX-3, VMAX AFA, PowerMax | +-------------------------------+----------------------------------------+ diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 5d3eeba4..c71e1cba 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -5,9 +5,9 @@ Requirements ------------ +-------------------------------+----------------------------------------+ -| **PyU4V Version** | 9.2.0.0 | +| **PyU4V Version** | 9.2.0.1 | +-------------------------------+----------------------------------------+ -| **Minimum Unisphere Version** | 9.2.0.0 | +| **Minimum Unisphere Version** | 9.2.0.1 | +-------------------------------+----------------------------------------+ | **Array Model** | VMAX-3, VMAX AFA, PowerMax | +-------------------------------+----------------------------------------+ @@ -66,7 +66,7 @@ specifying ``PyU4V`` as the install package for ``pip``: $ pip install PyU4V # Install a specific version - $ pip install PyU4V==9.2.0.0 + $ pip install PyU4V==9.2.0.1 .. URL LINKS diff --git a/setup.py b/setup.py index 5a8a7629..0f6c9d75 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setuptools.setup( name='PyU4V', - version='9.2.0.0', + version='9.2.0.1', url='https://github.com/dell/PyU4V/', author='Dell Inc. or its subsidiaries', author_email='Michael.Mcaleer@dell.com',