From 17fb19cef3773ec86603bbd0e92800de3b457256 Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Fri, 28 Sep 2018 02:27:52 -0400 Subject: [PATCH 1/7] Added admit/dismiss link --- hpe3parclient/client.py | 241 +++++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 29 deletions(-) diff --git a/hpe3parclient/client.py b/hpe3parclient/client.py index 3a1ed8dd..d3d62ae9 100644 --- a/hpe3parclient/client.py +++ b/hpe3parclient/client.py @@ -3049,6 +3049,34 @@ def getRemoteCopyGroup(self, name): response, body = self.http.get('/remotecopygroups/%s' % name) return body + def getRemoteCopyGroupVolumes(self, remoteCopyGroupName): + """ + Returns information on all volumes in a Remote Copy Groups + + :param remoteCopyGroupName: the remote copy group name + :type name: str + + :returns: list of volumes in a Remote Copy Groups + + """ + response, body = self.http.get('/remotecopygroups/%s/volumes' % remoteCopyGroupName) + return body + + def getRemoteCopyGroupVolume(self, remoteCopyGroupName, volumeName): + """ + Returns information on one volume of a Remote Copy Group + + :param remoteCopyGroupName: the remote copy group name + :type name: str + :param volumeName: the remote copy group name + :type name: str + + :returns: RemoteVolume + + """ + response, body = self.http.get('/remotecopygroups/%s/volumes/%s' % (remoteCopyGroupName, volumeName)) + return body + def createRemoteCopyGroup(self, name, targets, optional=None): """ Creates a remote copy group @@ -3394,7 +3422,7 @@ def modifyRemoteCopyGroup(self, name, optional=None): return body def addVolumeToRemoteCopyGroup(self, name, volumeName, targets, - optional=None): + optional=None, useHttpPost=False): """ Adds a volume to a remote copy group @@ -3601,19 +3629,29 @@ def addVolumeToRemoteCopyGroup(self, name, volumeName, targets, group is in the failover state. Both systems are in the primary state. """ - parameters = {'action': 1, - 'volumeName': volumeName, - 'targets': targets} - if optional: - parameters = self._mergeDict(parameters, optional) + if not useHttpPost: + parameters = {'action': 1, + 'volumeName': volumeName, + 'targets': targets} + if optional: + parameters = self._mergeDict(parameters, optional) - response, body = self.http.put('/remotecopygroups/%s' % name, - body=parameters) + response, body = self.http.put('/remotecopygroups/%s' % name, + body=parameters) + else: + parameters = {'volumeName': volumeName, + 'targets': targets} + if optional: + parameters = self._mergeDict(parameters, optional) + + response, body = self.http.post('/remotecopygroups/%s/volumes' % name, + body=parameters) return body def removeVolumeFromRemoteCopyGroup(self, name, volumeName, optional=None, - removeFromTarget=False): + removeFromTarget=False, + useHttpDelete=False): """ Removes a volume from a remote copy group @@ -3667,29 +3705,43 @@ def removeVolumeFromRemoteCopyGroup(self, name, volumeName, - RCOPY_TARGET_IS_NOT_READY - The remote-copy group target is not ready. """ - # If removeFromTarget is set to True, we need to issue the command via - # ssh due to this feature not being supported in the WSAPI. - if removeFromTarget: - if optional: - keep_snap = optional.get('keepSnap', False) - else: - keep_snap = False + if not useHttpDelete: + # If removeFromTarget is set to True, we need to issue the command via + # ssh due to this feature not being supported in the WSAPI. + if removeFromTarget: + if optional: + keep_snap = optional.get('keepSnap', False) + else: + keep_snap = False - if keep_snap: - cmd = ['dismissrcopyvv', '-f', '-keepsnap', '-removevv', - volumeName, name] + if keep_snap: + cmd = ['dismissrcopyvv', '-f', '-keepsnap', '-removevv', + volumeName, name] + else: + cmd = ['dismissrcopyvv', '-f', '-removevv', volumeName, name] + self._run(cmd) else: - cmd = ['dismissrcopyvv', '-f', '-removevv', volumeName, name] - self._run(cmd) - else: - parameters = {'action': 2, - 'volumeName': volumeName} - if optional: - parameters = self._mergeDict(parameters, optional) + parameters = {'action': 2, + 'volumeName': volumeName} + if optional: + parameters = self._mergeDict(parameters, optional) - response, body = self.http.put('/remotecopygroups/%s' % name, - body=parameters) - return body + response, body = self.http.put('/remotecopygroups/%s' % name, + body=parameters) + + else: + option = None + if optional and optional.get('keepSnap') and removeFromTarget: + raise Exception("keepSnap and removeFromTarget cannot be bpoth true while removing the volume from remote copy group") + elif optional and optional.get('keepSnap'): + option = 'keepSnap' + elif removeFromTarget: + option = 'removeSecondaryVolume' + delete_url = '/remotecopygroups/%s/volumes/%s' % (name, volumeName) + if option: + delete_url += '?%s=true' % option + response, body = self.http.delete(delete_url) + return body def startRemoteCopy(self, name, optional=None): """ @@ -4208,3 +4260,134 @@ def resyncPhysicalCopy(self, volume_name): info = {'action': self.RESYNC_PHYSICAL_COPY} response = self.http.put("/volumes/%s" % (volume_name), body=info) return response[1] + + def admitRemoteCopyLinks(self, targetName, source_port, target_port_wwn_or_ip): + """Adding remote copy link from soure to target. + :param targetName - The name of target system + :type - string + :source_port - Source ethernet/Fibre channel port + :type- string + :target_port_wwn_or_ip- Target system's peer port WWN/IP + :type- string + """ + source_target_port_pair=source_port + ':' + target_port_wwn_or_ip + try: + cmd = ['admitrcopylink', targetName, source_target_port_pair] + response=self._run(cmd) + if response != []: + response = response[0] + raise exceptions.SSHException(response) + except exceptions.SSHException as ex: + raise exceptions.SSHException(ex) + return response + + def dismissRemoteCopyLinks(self, targetName, source_port, target_port_wwn_or_ip): + """Dismiss remote copy link from soure to target. + :param targetName - The name of target system + :type - string + :source_port - Source ethernet/Fibre channel port + :type- string + :target_port_wwn_or_ip- Target system's peer port WWN/IP + :type- string + """ + source_target_port_pair=source_port + ':' + target_port_wwn_or_ip + try: + cmd = ['dismissrcopylink', targetName, source_target_port_pair] + response=self._run(cmd) + if response != []: + response = response[0] + raise exceptions.SSHException(response) + except exceptions.SSHException as ex: + raise exceptions.SSHException(ex) + return response + + def startrCopy(self): + """Starting remote copy service + :param No + """ + try: + cmd = ['startrcopy'] + response=self._run(cmd) + if response != []: + response = response[0] + raise exceptions.SSHException(response) + except exceptions.SSHException as ex: + raise exceptions.SSHException(ex) + return response + + def rcopyServiceExists(self): + """Checking remote copy service status. + :returns: True if remote copy service status is 'Started' + : False if remote copy service status is 'Stopped' + """ + cmd = ['showrcopy'] + response=self._run(cmd) + rcopyservice_status=False + if 'Started' in response[2]: + rcopyservice_status=True + return rcopyservice_status + + def rcopyLinkExists(self,targetName,local_port,target_system_peer_port): + """Checking remote copy link from soure to target. + :param targetName - The name of target system + :type - string + :source_port - Source ethernet/Fibre channel port + :type- string + :target_port_wwn_or_ip- Target system's peer port WWN/IP + :type- string + :returns: True if remote copy link exists + : False if remote copy link doesn't exist + """ + cmd = ['showrcopy'] + response=self._run(cmd) + rcopy_link=targetName + ',' + local_port + ',' + target_system_peer_port + remote_link_exist=False + for item in response: + if rcopy_link in item: + remote_link_exist=True + return remote_link_exist + + def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, source_target_volume_pairs_list=[]): + """Adding target to remote copy group + :param targetName - The name of target system + :type - string + :mode - synchronization mode + :type - string + :remote_copy_group_name + :type - string + :source_target_volume_pairs_list: list of pairs of primary and remote copy volumes + :type - list + """ + if source_target_volume_pairs_list == []: + cmd = ['admitrcopytarget', targetName, mode, remote_copy_group_name] + else: + cmd = ['admitrcopytarget', targetName, mode, remote_copy_group_name] + for volume_pair_tuple in source_target_volume_pairs_list: + source_target_pair = volume_pair_tuple[0] + ':' + volume_pair_tuple[1] + cmd.append(source_target_pair) + try: + response=self._run(cmd) + if response != []: + response = response[0] + raise exceptions.SSHException(response) + except exceptions.SSHException as ex: + raise exceptions.SSHException(ex) + return response + + def dismissRemoteCopyTarget(self, targetName, remote_copy_group_name): + """Removing target from remote copy group + :param targetName - The name of target system + :type - string + :remote_copy_group_name + :type - string + """ + option='-f' + cmd = ['dismissrcopytarget', option, targetName, remote_copy_group_name] + try: + response=self._run(cmd) + if response != []: + response = response[0] + raise exceptions.SSHException(response) + except exceptions.SSHException as ex: + raise exceptions.SSHException(ex) + return response From 65e7a3e1c77eabfae65b21b3c65a96642ca8ff00 Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Fri, 28 Sep 2018 06:42:13 -0400 Subject: [PATCH 2/7] Added targetInRemoteCopyGroupExists function --- hpe3parclient/client.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/hpe3parclient/client.py b/hpe3parclient/client.py index d3d62ae9..52ec07aa 100644 --- a/hpe3parclient/client.py +++ b/hpe3parclient/client.py @@ -4391,3 +4391,24 @@ def dismissRemoteCopyTarget(self, targetName, remote_copy_group_name): except exceptions.SSHException as ex: raise exceptions.SSHException(ex) return response + + def targetInRemoteCopyGroupExists(self, target_name, remote_copy_group_name): + """Determines whether target is present in remote copy group. + + :param name: target_name + :type name: str + :remote_copy_group_name + :type key: str + + :returns: bool + + """ + try: + contents = self.getRemoteCopyGroup(remote_copy_group_name) + for item in contents['targets']: + if item['target'] == target_name: + return True + except Exception: + pass + return False + From 6511b0df2dd415352451e6fe85c78024e27bff31 Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Fri, 5 Oct 2018 02:39:21 -0400 Subject: [PATCH 3/7] Added getRemoteCopyLink function --- hpe3parclient/client.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/hpe3parclient/client.py b/hpe3parclient/client.py index 52ec07aa..b491bd2a 100644 --- a/hpe3parclient/client.py +++ b/hpe3parclient/client.py @@ -4315,6 +4315,7 @@ def startrCopy(self): raise exceptions.SSHException(ex) return response + def rcopyServiceExists(self): """Checking remote copy service status. :returns: True if remote copy service status is 'Started' @@ -4327,6 +4328,14 @@ def rcopyServiceExists(self): rcopyservice_status=True return rcopyservice_status + def getRemoteCopyLink(self, link_name): + """ + Querying specific remote copy link + :returns: Specific remote copy link info + """ + response, body = self.http.get('/remotecopylinks/%s' % link_name) + return body + def rcopyLinkExists(self,targetName,local_port,target_system_peer_port): """Checking remote copy link from soure to target. :param targetName - The name of target system @@ -4338,14 +4347,15 @@ def rcopyLinkExists(self,targetName,local_port,target_system_peer_port): :returns: True if remote copy link exists : False if remote copy link doesn't exist """ - cmd = ['showrcopy'] - response=self._run(cmd) - rcopy_link=targetName + ',' + local_port + ',' + target_system_peer_port - remote_link_exist=False - for item in response: - if rcopy_link in item: - remote_link_exist=True - return remote_link_exist + rcopylink_exits=False + link_name = targetName + '_' + local_port.replace(':','_') + try: + response = self.getRemoteCopyLink(link_name) + if response and response['address'] == target_system_peer_port : + rcopylink_exits=True + except exceptions.HTTPNotFound: + pass + return rcopylink_exits def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, source_target_volume_pairs_list=[]): """Adding target to remote copy group From dcaff629c56f0ccc0733496f111c5e9101a0713b Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Fri, 5 Oct 2018 07:59:06 -0400 Subject: [PATCH 4/7] Fixed pep8 errors --- hpe3parclient/client.py | 97 ++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/hpe3parclient/client.py b/hpe3parclient/client.py index b491bd2a..6b49315b 100644 --- a/hpe3parclient/client.py +++ b/hpe3parclient/client.py @@ -3059,7 +3059,9 @@ def getRemoteCopyGroupVolumes(self, remoteCopyGroupName): :returns: list of volumes in a Remote Copy Groups """ - response, body = self.http.get('/remotecopygroups/%s/volumes' % remoteCopyGroupName) + response, body = self.http.get( + '/remotecopygroups/%s/volumes' % (remoteCopyGroupName) + ) return body def getRemoteCopyGroupVolume(self, remoteCopyGroupName, volumeName): @@ -3074,7 +3076,10 @@ def getRemoteCopyGroupVolume(self, remoteCopyGroupName, volumeName): :returns: RemoteVolume """ - response, body = self.http.get('/remotecopygroups/%s/volumes/%s' % (remoteCopyGroupName, volumeName)) + response, body = self.http.get( + '/remotecopygroups/%s/volumes/%s' % + (remoteCopyGroupName, volumeName) + ) return body def createRemoteCopyGroup(self, name, targets, optional=None): @@ -3644,8 +3649,10 @@ def addVolumeToRemoteCopyGroup(self, name, volumeName, targets, if optional: parameters = self._mergeDict(parameters, optional) - response, body = self.http.post('/remotecopygroups/%s/volumes' % name, - body=parameters) + response, body = self.http.post( + '/remotecopygroups/%s/volumes' % + name, body=parameters + ) return body def removeVolumeFromRemoteCopyGroup(self, name, volumeName, @@ -3706,8 +3713,9 @@ def removeVolumeFromRemoteCopyGroup(self, name, volumeName, not ready. """ if not useHttpDelete: - # If removeFromTarget is set to True, we need to issue the command via - # ssh due to this feature not being supported in the WSAPI. + # If removeFromTarget is set to True, we need to issue the + # command via ssh due to this feature not being supported + # in the WSAPI. if removeFromTarget: if optional: keep_snap = optional.get('keepSnap', False) @@ -3718,7 +3726,8 @@ def removeVolumeFromRemoteCopyGroup(self, name, volumeName, cmd = ['dismissrcopyvv', '-f', '-keepsnap', '-removevv', volumeName, name] else: - cmd = ['dismissrcopyvv', '-f', '-removevv', volumeName, name] + cmd = ['dismissrcopyvv', '-f', '-removevv', volumeName, + name] self._run(cmd) else: parameters = {'action': 2, @@ -3732,7 +3741,8 @@ def removeVolumeFromRemoteCopyGroup(self, name, volumeName, else: option = None if optional and optional.get('keepSnap') and removeFromTarget: - raise Exception("keepSnap and removeFromTarget cannot be bpoth true while removing the volume from remote copy group") + raise Exception("keepSnap and removeFromTarget cannot be bpoth\ + true while removing the volume from remote copy group") elif optional and optional.get('keepSnap'): option = 'keepSnap' elif removeFromTarget: @@ -4261,19 +4271,20 @@ def resyncPhysicalCopy(self, volume_name): response = self.http.put("/volumes/%s" % (volume_name), body=info) return response[1] - def admitRemoteCopyLinks(self, targetName, source_port, target_port_wwn_or_ip): + def admitRemoteCopyLinks( + self, targetName, source_port, target_port_wwn_or_ip): """Adding remote copy link from soure to target. :param targetName - The name of target system :type - string :source_port - Source ethernet/Fibre channel port :type- string :target_port_wwn_or_ip- Target system's peer port WWN/IP - :type- string + :type- string """ - source_target_port_pair=source_port + ':' + target_port_wwn_or_ip + source_target_port_pair = source_port + ':' + target_port_wwn_or_ip try: cmd = ['admitrcopylink', targetName, source_target_port_pair] - response=self._run(cmd) + response = self._run(cmd) if response != []: response = response[0] raise exceptions.SSHException(response) @@ -4281,19 +4292,20 @@ def admitRemoteCopyLinks(self, targetName, source_port, target_port_wwn_or_ip): raise exceptions.SSHException(ex) return response - def dismissRemoteCopyLinks(self, targetName, source_port, target_port_wwn_or_ip): + def dismissRemoteCopyLinks( + self, targetName, source_port, target_port_wwn_or_ip): """Dismiss remote copy link from soure to target. :param targetName - The name of target system :type - string :source_port - Source ethernet/Fibre channel port :type- string :target_port_wwn_or_ip- Target system's peer port WWN/IP - :type- string + :type- string """ - source_target_port_pair=source_port + ':' + target_port_wwn_or_ip + source_target_port_pair = source_port + ':' + target_port_wwn_or_ip try: cmd = ['dismissrcopylink', targetName, source_target_port_pair] - response=self._run(cmd) + response = self._run(cmd) if response != []: response = response[0] raise exceptions.SSHException(response) @@ -4307,7 +4319,7 @@ def startrCopy(self): """ try: cmd = ['startrcopy'] - response=self._run(cmd) + response = self._run(cmd) if response != []: response = response[0] raise exceptions.SSHException(response) @@ -4315,17 +4327,16 @@ def startrCopy(self): raise exceptions.SSHException(ex) return response - def rcopyServiceExists(self): """Checking remote copy service status. - :returns: True if remote copy service status is 'Started' + :returns: True if remote copy service status is 'Started' : False if remote copy service status is 'Stopped' """ cmd = ['showrcopy'] - response=self._run(cmd) - rcopyservice_status=False + response = self._run(cmd) + rcopyservice_status = False if 'Started' in response[2]: - rcopyservice_status=True + rcopyservice_status = True return rcopyservice_status def getRemoteCopyLink(self, link_name): @@ -4336,28 +4347,29 @@ def getRemoteCopyLink(self, link_name): response, body = self.http.get('/remotecopylinks/%s' % link_name) return body - def rcopyLinkExists(self,targetName,local_port,target_system_peer_port): + def rcopyLinkExists(self, targetName, local_port, target_system_peer_port): """Checking remote copy link from soure to target. :param targetName - The name of target system :type - string :source_port - Source ethernet/Fibre channel port :type- string :target_port_wwn_or_ip- Target system's peer port WWN/IP - :type- string - :returns: True if remote copy link exists + :type- string + :returns: True if remote copy link exists : False if remote copy link doesn't exist """ - rcopylink_exits=False - link_name = targetName + '_' + local_port.replace(':','_') + rcopylink_exits = False + link_name = targetName + '_' + local_port.replace(':', '_') try: response = self.getRemoteCopyLink(link_name) - if response and response['address'] == target_system_peer_port : - rcopylink_exits=True + if response and response['address'] == target_system_peer_port: + rcopylink_exits = True except exceptions.HTTPNotFound: pass return rcopylink_exits - def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, source_target_volume_pairs_list=[]): + def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, + source_target_volume_pairs_list=[]): """Adding target to remote copy group :param targetName - The name of target system :type - string @@ -4365,18 +4377,22 @@ def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, source :type - string :remote_copy_group_name :type - string - :source_target_volume_pairs_list: list of pairs of primary and remote copy volumes + :source_target_volume_pairs_list: list of pairs of primary + : and remote copy volumes :type - list """ if source_target_volume_pairs_list == []: - cmd = ['admitrcopytarget', targetName, mode, remote_copy_group_name] + cmd = ['admitrcopytarget', targetName, + mode, remote_copy_group_name] else: - cmd = ['admitrcopytarget', targetName, mode, remote_copy_group_name] + cmd = ['admitrcopytarget', targetName, + mode, remote_copy_group_name] for volume_pair_tuple in source_target_volume_pairs_list: - source_target_pair = volume_pair_tuple[0] + ':' + volume_pair_tuple[1] + source_target_pair = volume_pair_tuple[0] +\ + ':' + volume_pair_tuple[1] cmd.append(source_target_pair) try: - response=self._run(cmd) + response = self._run(cmd) if response != []: response = response[0] raise exceptions.SSHException(response) @@ -4391,10 +4407,11 @@ def dismissRemoteCopyTarget(self, targetName, remote_copy_group_name): :remote_copy_group_name :type - string """ - option='-f' - cmd = ['dismissrcopytarget', option, targetName, remote_copy_group_name] + option = '-f' + cmd = ['dismissrcopytarget', option, targetName, + remote_copy_group_name] try: - response=self._run(cmd) + response = self._run(cmd) if response != []: response = response[0] raise exceptions.SSHException(response) @@ -4402,7 +4419,8 @@ def dismissRemoteCopyTarget(self, targetName, remote_copy_group_name): raise exceptions.SSHException(ex) return response - def targetInRemoteCopyGroupExists(self, target_name, remote_copy_group_name): + def targetInRemoteCopyGroupExists( + self, target_name, remote_copy_group_name): """Determines whether target is present in remote copy group. :param name: target_name @@ -4421,4 +4439,3 @@ def targetInRemoteCopyGroupExists(self, target_name, remote_copy_group_name): except Exception: pass return False - From 9904cbc5fcc3a574e5822aafaf39e115b05ac745 Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Wed, 10 Oct 2018 01:45:15 -0400 Subject: [PATCH 5/7] Fixed port validation issue --- hpe3parclient/client.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hpe3parclient/client.py b/hpe3parclient/client.py index 6b49315b..a05a29d6 100644 --- a/hpe3parclient/client.py +++ b/hpe3parclient/client.py @@ -4286,7 +4286,6 @@ def admitRemoteCopyLinks( cmd = ['admitrcopylink', targetName, source_target_port_pair] response = self._run(cmd) if response != []: - response = response[0] raise exceptions.SSHException(response) except exceptions.SSHException as ex: raise exceptions.SSHException(ex) @@ -4307,7 +4306,6 @@ def dismissRemoteCopyLinks( cmd = ['dismissrcopylink', targetName, source_target_port_pair] response = self._run(cmd) if response != []: - response = response[0] raise exceptions.SSHException(response) except exceptions.SSHException as ex: raise exceptions.SSHException(ex) @@ -4321,7 +4319,6 @@ def startrCopy(self): cmd = ['startrcopy'] response = self._run(cmd) if response != []: - response = response[0] raise exceptions.SSHException(response) except exceptions.SSHException as ex: raise exceptions.SSHException(ex) @@ -4394,7 +4391,6 @@ def admitRemoteCopyTarget(self, targetName, mode, remote_copy_group_name, try: response = self._run(cmd) if response != []: - response = response[0] raise exceptions.SSHException(response) except exceptions.SSHException as ex: raise exceptions.SSHException(ex) @@ -4413,7 +4409,6 @@ def dismissRemoteCopyTarget(self, targetName, remote_copy_group_name): try: response = self._run(cmd) if response != []: - response = response[0] raise exceptions.SSHException(response) except exceptions.SSHException as ex: raise exceptions.SSHException(ex) From 68b50cf139b1d52eec540034e55f5ed2620137c9 Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Mon, 29 Oct 2018 07:36:35 -0400 Subject: [PATCH 6/7] Added unit test cases for admit/dismiss rcopy link and startrcopy --- test/test_HPE3ParClient_volume.py | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/test/test_HPE3ParClient_volume.py b/test/test_HPE3ParClient_volume.py index 6b6dbea1..85d74b7e 100644 --- a/test/test_HPE3ParClient_volume.py +++ b/test/test_HPE3ParClient_volume.py @@ -17,7 +17,7 @@ import time import unittest from testconfig import config - +import mock from test import HPE3ParClient_base as hpe3parbase from hpe3parclient import exceptions @@ -45,6 +45,9 @@ SKIP_RCOPY_MESSAGE = ("Only works with flask server.") SKIP_FLASK_RCOPY_MESSAGE = ("Remote copy is not configured to be tested " "on live arrays.") +TARGET_NAME = 'testtarget' +SOURCE_PORT = '1:1:1' +TARGET_PORT = '10.10.10.1' RCOPY_STARTED = 3 RCOPY_STOPPED = 5 FAILOVER_GROUP = 7 @@ -2189,6 +2192,42 @@ def test_25_promote_vcopy_on_rep_vol_with_bad_param(self): self.printFooter('promote_vcopy_on_rep_vol_with_bad_param') + @mock.patch('hpe3parclient.client.HPE3ParClient._run') + @mock.patch('hpe3parclient.client.HPE3ParClient.getRemoteCopyLink') + def test_admit_rcopy_link(self,mock_get_rcopy_link, mock_run): + self.printHeader('admit_rcopy_link_test') + mock_run.return_value = [] + mock_get_rcopy_link.return_value = {'address':'10.10.10.1'} + res = self.cl.admitRemoteCopyLinks(TARGET_NAME, SOURCE_PORT, TARGET_PORT) + self.assertEqual(res, []) + res = self.cl.rcopyLinkExists(TARGET_NAME, SOURCE_PORT, TARGET_PORT) + self.assertEqual(res, True) + self.printFooter('admit_rcopy_link_test') + + + @mock.patch('hpe3parclient.client.HPE3ParClient._run') + @mock.patch('hpe3parclient.client.HPE3ParClient.getRemoteCopyLink') + def test_dismiss_rcopy_link(self,mock_get_rcopy_link, mock_run): + self.printHeader('dismiss_rcopy_link_test') + mock_run.return_value = [] + mock_get_rcopy_link.return_value = {} + res = self.cl.dismissRemoteCopyLinks(TARGET_NAME, SOURCE_PORT, TARGET_PORT) + self.assertEqual(res, []) + res = self.cl.rcopyLinkExists(TARGET_NAME, SOURCE_PORT, TARGET_PORT) + self.assertEqual(res, False) + self.printFooter('dismiss_rcopy_link_test') + + + @mock.patch('hpe3parclient.client.HPE3ParClient._run') + def test_start_rcopy(self, mock_run): + self.printHeader('start_rcopy_test') + mock_run.return_value = [] + res = self.cl.startrCopy() + self.assertEqual(res, []) + mock_run.return_value = ['x','y','Started'] + res = self.cl.rcopyServiceExists() + self.assertEqual(res, True) + self.printFooter('start_rcopy_test') # testing # suite = unittest.TestLoader(). # loadTestsFromTestCase(HPE3ParClientVolumeTestCase) From b7cdc1ad345816796c4816a8540058652e26b55f Mon Sep 17 00:00:00 2001 From: Arshad Ansari Date: Tue, 30 Oct 2018 00:48:16 -0400 Subject: [PATCH 7/7] Added admit/dismiss rcopy target test cases --- test/test_HPE3ParClient_volume.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/test_HPE3ParClient_volume.py b/test/test_HPE3ParClient_volume.py index 85d74b7e..426da2d9 100644 --- a/test/test_HPE3ParClient_volume.py +++ b/test/test_HPE3ParClient_volume.py @@ -52,6 +52,8 @@ RCOPY_STOPPED = 5 FAILOVER_GROUP = 7 RESTORE_GROUP = 10 +MODE = 'sync' +VOLUME_PAIR_LIST = [('primary_vol1','secondary_vol1'),('primary_vol2','secondary_vol2')] def is_live_test(): @@ -2228,6 +2230,32 @@ def test_start_rcopy(self, mock_run): res = self.cl.rcopyServiceExists() self.assertEqual(res, True) self.printFooter('start_rcopy_test') + + + @mock.patch('hpe3parclient.client.HPE3ParClient._run') + @mock.patch('hpe3parclient.client.HPE3ParClient.getRemoteCopyGroup') + def test_admit_rcopy_target(self,mock_target_in_rcg, mock_run): + self.printHeader('admit_rcopy_target_test') + mock_run.return_value = [] + res = self.cl.admitRemoteCopyTarget(TARGET_NAME, MODE, REMOTE_COPY_GROUP_NAME1, VOLUME_PAIR_LIST) + self.assertEqual(res, []) + mock_run.return_value = [] + res = self.cl.admitRemoteCopyTarget(TARGET_NAME, MODE, REMOTE_COPY_GROUP_NAME1) + self.assertEqual(res, []) + mock_target_in_rcg.return_value = {'targets':[{'target':TARGET_NAME}]} + res = self.cl.targetInRemoteCopyGroupExists(TARGET_NAME, REMOTE_COPY_GROUP_NAME1) + self.assertEqual(res, True) + self.printFooter('admit_rcopy_target_test') + + + @mock.patch('hpe3parclient.client.HPE3ParClient._run') + @mock.patch('hpe3parclient.client.HPE3ParClient.getRemoteCopyGroup') + def test_dismiss_rcopy_target(self,mock_target_in_rcg, mock_run): + self.printHeader('dismiss_rcopy_target_test') + mock_run.return_value = [] + res = self.cl.dismissRemoteCopyTarget(TARGET_NAME, REMOTE_COPY_GROUP_NAME1) + self.assertEqual(res, []) + self.printFooter('dismiss_rcopy_target_test') # testing # suite = unittest.TestLoader(). # loadTestsFromTestCase(HPE3ParClientVolumeTestCase)