]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Removing locks from 3PAR FC and iSCSI drivers
authorAnthony Lee <anthony.mic.lee@hp.com>
Wed, 15 Oct 2014 21:16:32 +0000 (14:16 -0700)
committerAnthony Lee <anthony.mic.lee@hp.com>
Mon, 24 Nov 2014 21:33:14 +0000 (13:33 -0800)
Removed locks from the 3PAR FC and iSCSI drivers.  In high load
environments where many simultaneous volume creations/deletions
and attaches/detaches are happening errors occur periodically.

By changing the drivers to create a new connection to the 3PAR
backend whenever a volume request is made the errors are avoided
and performance is improved.

Closes-Bug: 1381190
Change-Id: Ie588a1d87cf5a22ddf2e890c440582e1fe67f2cb

cinder/tests/test_hp3par.py
cinder/volume/drivers/san/hp/hp_3par_common.py
cinder/volume/drivers/san/hp/hp_3par_fc.py
cinder/volume/drivers/san/hp/hp_3par_iscsi.py

index ed2f9048956ced19f6f840d2243d6aecee84f2d5..d9e090bbe01ec8ba89df7c7a6a5e6c5fc2c32560 100644 (file)
@@ -359,6 +359,19 @@ class HP3PARBaseDriver(object):
     # intentionally removed to make _retype more usable for other use cases.
     RETYPE_DIFF = None
 
+    standard_login = [
+        mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
+        mock.call.setSSHOptions(
+            HP3PAR_SAN_IP,
+            HP3PAR_USER_NAME,
+            HP3PAR_USER_PASS,
+            privatekey=HP3PAR_SAN_SSH_PRIVATE,
+            port=HP3PAR_SAN_SSH_PORT,
+            conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT)]
+
+    standard_logout = [
+        mock.call.logout()]
+
     def setup_configuration(self):
         configuration = mock.Mock()
         configuration.hp3par_debug = False
@@ -414,18 +427,12 @@ class HP3PARBaseDriver(object):
         self.ctxt = context.get_admin_context()
         mock_client = self.setup_mock_client(driver=hpfcdriver.HP3PARFCDriver)
         expected = [
-            mock.call.setSSHOptions(
-                HP3PAR_SAN_IP,
-                HP3PAR_USER_NAME,
-                HP3PAR_USER_PASS,
-                privatekey=HP3PAR_SAN_SSH_PRIVATE,
-                port=HP3PAR_SAN_SSH_PORT,
-                conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+            mock.call.getCPG(HP3PAR_CPG2)]
+        mock_client.assert_has_calls(
+            self.standard_login +
+            expected +
+            self.standard_logout)
 
     @mock.patch('hp3parclient.version', "3.1.1")
     def test_ssh_options(self):
@@ -443,6 +450,7 @@ class HP3PARBaseDriver(object):
         CONF.strict_ssh_host_key_policy = orig_strict_ssh_host_key_policy
 
         expected = [
+            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.setSSHOptions(
                 HP3PAR_SAN_IP,
                 HP3PAR_USER_NAME,
@@ -452,11 +460,11 @@ class HP3PARBaseDriver(object):
                 missing_key_policy="AutoAddPolicy",
                 port=HP3PAR_SAN_SSH_PORT,
                 conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+            mock.call.getCPG(HP3PAR_CPG2)]
+        mock_client.assert_has_calls(
+            expected +
+            self.standard_logout)
 
     @mock.patch('hp3parclient.version', "3.1.1")
     def test_ssh_options_strict(self):
@@ -474,6 +482,7 @@ class HP3PARBaseDriver(object):
         CONF.strict_ssh_host_key_policy = orig_strict_ssh_host_key_policy
 
         expected = [
+            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.setSSHOptions(
                 HP3PAR_SAN_IP,
                 HP3PAR_USER_NAME,
@@ -483,11 +492,9 @@ class HP3PARBaseDriver(object):
                 missing_key_policy="RejectPolicy",
                 port=HP3PAR_SAN_SSH_PORT,
                 conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+            mock.call.getCPG(HP3PAR_CPG2)]
+        mock_client.assert_has_calls(expected + self.standard_logout)
 
     def test_task_waiter(self):
 
@@ -501,68 +508,81 @@ class HP3PARBaseDriver(object):
 
         task_id = 1234
         interval = .001
-        waiter = self.driver.common.TaskWaiter(mock_client, task_id, interval)
-        status = waiter.wait_for_task()
 
-        expected = [
-            mock.call.getTask(task_id),
-            mock.call.getTask(task_id),
-            mock.call.getTask(task_id)
-        ]
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(status, self.STATUS_DONE)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            waiter = common.TaskWaiter(mock_client, task_id, interval)
+            status = waiter.wait_for_task()
+
+            expected = [
+                mock.call.getTask(task_id),
+                mock.call.getTask(task_id),
+                mock.call.getTask(task_id)
+            ]
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(status, self.STATUS_DONE)
 
     def test_create_volume(self):
-
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        self.driver.create_volume(self.volume)
-        comment = (
-            '{"display_name": "Foo Volume", "type": "OpenStack",'
-            ' "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createVolume(
-                self.VOLUME_3PAR_NAME,
-                HP3PAR_CPG,
-                1907, {
-                    'comment': comment,
-                    'tpvv': True,
-                    'snapCPG': HP3PAR_CPG_SNAP}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.create_volume(self.volume)
+            comment = (
+                '{"display_name": "Foo Volume", "type": "OpenStack",'
+                ' "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+            expected = [
+                mock.call.createVolume(
+                    self.VOLUME_3PAR_NAME,
+                    HP3PAR_CPG,
+                    1907, {
+                        'comment': comment,
+                        'tpvv': True,
+                        'snapCPG': HP3PAR_CPG_SNAP})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_create_volume_in_pool(self):
 
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        return_model = self.driver.create_volume(self.volume_pool)
-        comment = (
-            '{"display_name": "Foo Volume", "type": "OpenStack",'
-            ' "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createVolume(
-                self.VOLUME_3PAR_NAME,
-                HP3PAR_CPG2,
-                1907, {
-                    'comment': comment,
-                    'tpvv': True,
-                    'snapCPG': HP3PAR_CPG_SNAP}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(return_model, None)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            return_model = self.driver.create_volume(self.volume_pool)
+            comment = (
+                '{"display_name": "Foo Volume", "type": "OpenStack",'
+                ' "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+            expected = [
+                mock.call.createVolume(
+                    self.VOLUME_3PAR_NAME,
+                    HP3PAR_CPG2,
+                    1907, {
+                        'comment': comment,
+                        'tpvv': True,
+                        'snapCPG': HP3PAR_CPG_SNAP})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(return_model, None)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_get_snap_cpg_from_volume_type(self, _mock_volume_types):
 
-        self.setup_driver()
+        mock_client = self.setup_driver()
         expected_type_snap_cpg = "type_snap_cpg"
         _mock_volume_types.return_value = {
             'name': 'gold',
@@ -571,15 +591,20 @@ class HP3PARBaseDriver(object):
                 'snap_cpg': expected_type_snap_cpg,
                 'volume_type': self.volume_type}}
 
-        result = self.driver.common.get_volume_settings_from_type_id(
-            "mock", self.driver.configuration.hp3par_cpg)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            result = common.get_volume_settings_from_type_id(
+                "mock", self.driver.configuration.hp3par_cpg)
 
-        self.assertEqual(expected_type_snap_cpg, result['snap_cpg'])
+            self.assertEqual(expected_type_snap_cpg, result['snap_cpg'])
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_get_snap_cpg_from_volume_type_cpg(self, _mock_volume_types):
 
-        self.setup_driver()
+        mock_client = self.setup_driver()
         expected_cpg = 'use_extra_specs_cpg'
         _mock_volume_types.return_value = {
             'name': 'gold',
@@ -587,10 +612,15 @@ class HP3PARBaseDriver(object):
                 'cpg': expected_cpg,
                 'volume_type': self.volume_type}}
 
-        result = self.driver.common.get_volume_settings_from_type_id(
-            "mock", self.driver.configuration.hp3par_cpg)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            result = common.get_volume_settings_from_type_id(
+                "mock", self.driver.configuration.hp3par_cpg)
 
-        self.assertEqual(expected_cpg, result['snap_cpg'])
+            self.assertEqual(expected_cpg, result['snap_cpg'])
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_get_snap_cpg_from_volume_type_conf_snap_cpg(
@@ -602,9 +632,14 @@ class HP3PARBaseDriver(object):
 
         conf = self.setup_configuration()
         expected_snap_cpg = conf.hp3par_cpg_snap
-        self.setup_driver(config=conf)
-        result = self.driver.common.get_volume_settings_from_type_id(
-            "mock", self.driver.configuration.hp3par_cpg)
+        mock_client = self.setup_driver(config=conf)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            result = common.get_volume_settings_from_type_id(
+                "mock", self.driver.configuration.hp3par_cpg)
 
         self.assertEqual(expected_snap_cpg, result['snap_cpg'])
 
@@ -619,11 +654,16 @@ class HP3PARBaseDriver(object):
         conf = self.setup_configuration()
         conf.hp3par_cpg_snap = None
         expected_cpg = conf.hp3par_cpg
-        self.setup_driver(config=conf)
-        result = self.driver.common.get_volume_settings_from_type_id(
-            "mock", self.driver.configuration.hp3par_cpg)
+        mock_client = self.setup_driver(config=conf)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        self.assertEqual(expected_cpg, result['snap_cpg'])
+            result = common.get_volume_settings_from_type_id(
+                "mock", self.driver.configuration.hp3par_cpg)
+
+            self.assertEqual(expected_cpg, result['snap_cpg'])
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_create_volume_qos(self, _mock_volume_types):
@@ -641,48 +681,57 @@ class HP3PARBaseDriver(object):
                 'tpvv': True,
                 'volume_type': self.volume_type}}
 
-        return_model = self.driver.create_volume(self.volume_qos)
-        comment = (
-            '{"volume_type_name": "gold", "display_name": "Foo Volume"'
-            ', "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7'
-            '", "volume_type_id": "gold", "volume_id": "d03338a9-91'
-            '15-48a3-8dfc-35cdfcdc15a7", "qos": {}, "type": "OpenStack"}')
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getCPG(HP3PAR_CPG_QOS),
-            mock.call.createVolume(
-                self.VOLUME_3PAR_NAME,
-                HP3PAR_CPG_QOS,
-                1907, {
-                    'comment': comment,
-                    'tpvv': True,
-                    'snapCPG': HP3PAR_CPG_SNAP}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(return_model,
-                         {'host': volume_utils.append_host(self.FAKE_HOST,
-                                                           HP3PAR_CPG_QOS)})
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            return_model = self.driver.create_volume(self.volume_qos)
+            comment = (
+                '{"volume_type_name": "gold", "display_name": "Foo Volume"'
+                ', "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7'
+                '", "volume_type_id": "gold", "volume_id": "d03338a9-91'
+                '15-48a3-8dfc-35cdfcdc15a7", "qos": {}, "type": "OpenStack"}')
+
+            expected = [
+                mock.call.getCPG(HP3PAR_CPG_QOS),
+                mock.call.createVolume(
+                    self.VOLUME_3PAR_NAME,
+                    HP3PAR_CPG_QOS,
+                    1907, {
+                        'comment': comment,
+                        'tpvv': True,
+                        'snapCPG': HP3PAR_CPG_SNAP})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(return_model,
+                             {'host': volume_utils.append_host(
+                                 self.FAKE_HOST,
+                                 HP3PAR_CPG_QOS)})
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_not_3par(self, _mock_volume_types):
         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 
-        self.assertRaises(exception.InvalidHost,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_1,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST_NOT3PAR)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.InvalidHost,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_1,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST_NOT3PAR)
+
+            expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_volume_not_found(self, _mock_volume_types):
@@ -690,19 +739,22 @@ class HP3PARBaseDriver(object):
         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
         mock_client.getVolume.side_effect = hpexceptions.HTTPNotFound
 
-        self.assertRaises(hpexceptions.HTTPNotFound,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_1,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(hpexceptions.HTTPNotFound,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_1,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_specs_error_reverts_snap_cpg(self, _mock_volume_types):
@@ -715,29 +767,33 @@ class HP3PARBaseDriver(object):
         mock_client.addVolumeToVolumeSet.side_effect = \
             hpexceptions.HTTPForbidden
 
-        self.assertRaises(hpexceptions.HTTPForbidden,
-                          self.driver.retype,
-                          self.ctxt,
-                          {'id': self.VOLUME_ID},
-                          self.RETYPE_VOLUME_TYPE_0,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        old_settings = {
-            'snapCPG': self.RETYPE_VOLUME_INFO_0['snapCPG'],
-            'comment': self.RETYPE_VOLUME_INFO_0['comment']}
-        new_settings = {
-            'snapCPG': self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg'],
-            'comment': mock.ANY}
-
-        expected = [
-            mock.call.modifyVolume(self.VOLUME_3PAR_NAME, new_settings)
-        ]
-        mock_client.assert_has_calls(expected)
-        expected = [
-            mock.call.modifyVolume(self.VOLUME_3PAR_NAME, old_settings),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(hpexceptions.HTTPForbidden,
+                              self.driver.retype,
+                              self.ctxt,
+                              {'id': self.VOLUME_ID},
+                              self.RETYPE_VOLUME_TYPE_0,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            old_settings = {
+                'snapCPG': self.RETYPE_VOLUME_INFO_0['snapCPG'],
+                'comment': self.RETYPE_VOLUME_INFO_0['comment']}
+            new_settings = {
+                'snapCPG': (
+                    self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg']),
+                'comment': mock.ANY}
+
+            expected = [
+                mock.call.modifyVolume(self.VOLUME_3PAR_NAME, new_settings)
+            ]
+            mock_client.assert_has_calls(expected)
+            expected = [
+                mock.call.modifyVolume(self.VOLUME_3PAR_NAME, old_settings)
+            ]
+            mock_client.assert_has_calls(expected + self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_revert_comment(self, _mock_volume_types):
@@ -749,22 +805,24 @@ class HP3PARBaseDriver(object):
         # Fail the QOS setting to test the revert of the snap CPG rename.
         mock_client.deleteVolumeSet.side_effect = hpexceptions.HTTPForbidden
 
-        self.assertRaises(hpexceptions.HTTPForbidden,
-                          self.driver.retype,
-                          self.ctxt,
-                          {'id': self.VOLUME_ID},
-                          self.RETYPE_VOLUME_TYPE_2,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        original = {
-            'snapCPG': self.RETYPE_VOLUME_INFO_1['snapCPG'],
-            'comment': self.RETYPE_VOLUME_INFO_1['comment']}
-
-        expected = [
-            mock.call.modifyVolume('osv-0DM4qZEVSKON-DXN-NwVpw', original),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(hpexceptions.HTTPForbidden,
+                              self.driver.retype,
+                              self.ctxt,
+                              {'id': self.VOLUME_ID},
+                              self.RETYPE_VOLUME_TYPE_2,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            original = {
+                'snapCPG': self.RETYPE_VOLUME_INFO_1['snapCPG'],
+                'comment': self.RETYPE_VOLUME_INFO_1['comment']}
+
+            expected = [
+                mock.call.modifyVolume('osv-0DM4qZEVSKON-DXN-NwVpw', original)]
+            mock_client.assert_has_calls(expected + self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_different_array(self, _mock_volume_types):
@@ -774,21 +832,25 @@ class HP3PARBaseDriver(object):
         mock_client.getStorageSystemInfo.return_value = {
             'serialNumber': 'XXXXXXX'}
 
-        self.assertRaises(exception.InvalidHost,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_1,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getStorageSystemInfo(),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.InvalidHost,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_1,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getStorageSystemInfo()]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_across_cpg_domains(self, _mock_volume_types):
@@ -800,23 +862,28 @@ class HP3PARBaseDriver(object):
             {'domain': 'domain2'},
         ]
 
-        self.assertRaises(exception.Invalid3PARDomain,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_1,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getStorageSystemInfo(),
-            mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
-            mock.call.getCPG(self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg']),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.Invalid3PARDomain,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_1,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getStorageSystemInfo(),
+                mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
+                mock.call.getCPG(
+                    self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg'])
+            ]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_across_snap_cpg_domains(self, _mock_volume_types):
@@ -829,45 +896,52 @@ class HP3PARBaseDriver(object):
             {'domain': 'snap_cpg_domain_1'},
         ]
 
-        self.assertRaises(exception.Invalid3PARDomain,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_1,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getStorageSystemInfo(),
-            mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
-            mock.call.getCPG(self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg']),
-            mock.call.getCPG(
-                self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg']),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.Invalid3PARDomain,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_1,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getStorageSystemInfo(),
+                mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
+                mock.call.getCPG(
+                    self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg']),
+                mock.call.getCPG(
+                    self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg'])
+            ]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_to_bad_persona(self, _mock_volume_types):
         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_BAD_PERSONA
         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_BAD_PERSONA,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_BAD_PERSONA,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [mock.call.getVolume(self.VOLUME_3PAR_NAME)]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_to_bad_cpg(self, _mock_volume_types):
@@ -875,21 +949,25 @@ class HP3PARBaseDriver(object):
         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
         mock_client.getCPG.side_effect = hpexceptions.HTTPNotFound
 
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.retype,
-                          self.ctxt,
-                          self.RETYPE_VOLUME_INFO_0,
-                          self.RETYPE_VOLUME_TYPE_BAD_CPG,
-                          self.RETYPE_DIFF,
-                          self.RETYPE_HOST)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getCPG(
-                self.RETYPE_VOLUME_TYPE_BAD_CPG['extra_specs']['cpg']),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.retype,
+                              self.ctxt,
+                              self.RETYPE_VOLUME_INFO_0,
+                              self.RETYPE_VOLUME_TYPE_BAD_CPG,
+                              self.RETYPE_DIFF,
+                              self.RETYPE_HOST)
+
+            expected = [
+                mock.call.getCPG(
+                    self.RETYPE_VOLUME_TYPE_BAD_CPG['extra_specs']['cpg'])
+            ]
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_tune(self, _mock_volume_types):
@@ -912,26 +990,29 @@ class HP3PARBaseDriver(object):
 
         volume = {'id': HP3PARBaseDriver.CLONE_ID}
 
-        retyped = self.driver.retype(
-            self.ctxt, volume, type_ref, None, self.RETYPE_HOST)
-        self.assertTrue(retyped)
-
-        expected = [
-            mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
-                                   {'comment': mock.ANY,
-                                    'snapCPG': 'OpenStackCPGSnap'}),
-            mock.call.deleteVolumeSet('vvs-0DM4qZEVSKON-AAAAAAAAA'),
-            mock.call.addVolumeToVolumeSet('myvvs',
-                                           'osv-0DM4qZEVSKON-AAAAAAAAA'),
-            mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
-                                   {'action': 6,
-                                    'userCPG': 'OpenStackCPG',
-                                    'conversionOperation': 1,
-                                    'tuneOperation': 1}),
-            mock.call.getTask(1),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            retyped = self.driver.retype(
+                self.ctxt, volume, type_ref, None, self.RETYPE_HOST)
+            self.assertTrue(retyped)
+
+            expected = [
+                mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
+                                       {'comment': mock.ANY,
+                                        'snapCPG': 'OpenStackCPGSnap'}),
+                mock.call.deleteVolumeSet('vvs-0DM4qZEVSKON-AAAAAAAAA'),
+                mock.call.addVolumeToVolumeSet('myvvs',
+                                               'osv-0DM4qZEVSKON-AAAAAAAAA'),
+                mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
+                                       {'action': 6,
+                                        'userCPG': 'OpenStackCPG',
+                                        'conversionOperation': 1,
+                                        'tuneOperation': 1}),
+                mock.call.getTask(1)
+            ]
+            mock_client.assert_has_calls(expected + self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_retype_qos_spec(self, _mock_volume_types):
@@ -940,103 +1021,118 @@ class HP3PARBaseDriver(object):
 
         cpg = "any_cpg"
         snap_cpg = "any_cpg"
-        self.driver.common._retype(self.volume,
-                                   HP3PARBaseDriver.VOLUME_3PAR_NAME,
-                                   "old_type", "old_type_id",
-                                   HP3PARBaseDriver.RETYPE_HOST,
-                                   None, cpg, cpg, snap_cpg, snap_cpg,
-                                   True, True, None, None,
-                                   self.QOS_SPECS, self.RETYPE_QOS_SPECS,
-                                   "{}")
 
-        expected = [
-            mock.call.createVolumeSet('vvs-0DM4qZEVSKON-DXN-NwVpw', None),
-            mock.call.createQoSRules(
-                'vvs-0DM4qZEVSKON-DXN-NwVpw',
-                {'ioMinGoal': 100, 'ioMaxLimit': 1000,
-                 'bwMinGoalKB': 25600, 'bwMaxLimitKB': 51200,
-                 'priority': 3,
-                 'latencyGoal': 25}
-            ),
-            mock.call.addVolumeToVolumeSet(
-                'vvs-0DM4qZEVSKON-DXN-NwVpw', 'osv-0DM4qZEVSKON-DXN-NwVpw')]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            common._retype(self.volume,
+                           HP3PARBaseDriver.VOLUME_3PAR_NAME,
+                           "old_type", "old_type_id",
+                           HP3PARBaseDriver.RETYPE_HOST,
+                           None, cpg, cpg, snap_cpg, snap_cpg,
+                           True, True, None, None,
+                           self.QOS_SPECS, self.RETYPE_QOS_SPECS,
+                           "{}")
+
+            expected = [
+                mock.call.createVolumeSet('vvs-0DM4qZEVSKON-DXN-NwVpw', None),
+                mock.call.createQoSRules(
+                    'vvs-0DM4qZEVSKON-DXN-NwVpw',
+                    {'ioMinGoal': 100, 'ioMaxLimit': 1000,
+                     'bwMinGoalKB': 25600, 'bwMaxLimitKB': 51200,
+                     'priority': 3,
+                     'latencyGoal': 25}
+                ),
+                mock.call.addVolumeToVolumeSet(
+                    'vvs-0DM4qZEVSKON-DXN-NwVpw',
+                    'osv-0DM4qZEVSKON-DXN-NwVpw')]
+            mock_client.assert_has_calls(expected)
 
     def test_delete_volume(self):
-
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        self.driver.delete_volume(self.volume)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.delete_volume(self.volume)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
-            mock.call.logout()]
+            expected = [mock.call.deleteVolume(self.VOLUME_3PAR_NAME)]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_create_cloned_volume(self):
-
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
         mock_client.copyVolume.return_value = {'taskid': 1}
-
-        volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
-                  'id': HP3PARBaseDriver.CLONE_ID,
-                  'display_name': 'Foo Volume',
-                  'size': 2,
-                  'host': volume_utils.append_host(self.FAKE_HOST,
-                                                   HP3PAR_CPG2),
-                  'source_volid': HP3PARBaseDriver.VOLUME_ID}
-        src_vref = {}
-        model_update = self.driver.create_cloned_volume(volume, src_vref)
-        self.assertIsNone(model_update)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.copyVolume(
-                self.VOLUME_3PAR_NAME,
-                'osv-0DM4qZEVSKON-AAAAAAAAA',
-                HP3PAR_CPG2,
-                {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
-                 'online': True}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
+                      'id': HP3PARBaseDriver.CLONE_ID,
+                      'display_name': 'Foo Volume',
+                      'size': 2,
+                      'host': volume_utils.append_host(self.FAKE_HOST,
+                                                       HP3PAR_CPG2),
+                      'source_volid': HP3PARBaseDriver.VOLUME_ID}
+            src_vref = {}
+            model_update = self.driver.create_cloned_volume(volume, src_vref)
+            self.assertIsNone(model_update)
+
+            expected = [
+                mock.call.copyVolume(
+                    self.VOLUME_3PAR_NAME,
+                    'osv-0DM4qZEVSKON-AAAAAAAAA',
+                    HP3PAR_CPG2,
+                    {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
+                     'online': True})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_create_cloned_qos_volume(self, _mock_volume_types):
         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_2
         mock_client = self.setup_driver()
         mock_client.copyVolume.return_value = {'taskid': 1}
-
-        src_vref = {}
-        volume = self.volume_qos.copy()
-        host = "TEST_HOST"
-        pool = "TEST_POOL"
-        volume_host = volume_utils.append_host(host, pool)
-        expected_cpg = self.RETYPE_VOLUME_TYPE_2['extra_specs']['cpg']
-        expected_volume_host = volume_utils.append_host(host, expected_cpg)
-        volume['id'] = HP3PARBaseDriver.CLONE_ID
-        volume['host'] = volume_host
-        volume['source_volid'] = HP3PARBaseDriver.VOLUME_ID
-        model_update = self.driver.create_cloned_volume(volume, src_vref)
-        self.assertEqual(model_update, {'host': expected_volume_host})
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getCPG(expected_cpg),
-            mock.call.copyVolume(
-                self.VOLUME_3PAR_NAME,
-                'osv-0DM4qZEVSKON-AAAAAAAAA',
-                expected_cpg,
-                {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
-                 'online': True}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            src_vref = {}
+            volume = self.volume_qos.copy()
+            host = "TEST_HOST"
+            pool = "TEST_POOL"
+            volume_host = volume_utils.append_host(host, pool)
+            expected_cpg = self.RETYPE_VOLUME_TYPE_2['extra_specs']['cpg']
+            expected_volume_host = volume_utils.append_host(host, expected_cpg)
+            volume['id'] = HP3PARBaseDriver.CLONE_ID
+            volume['host'] = volume_host
+            volume['source_volid'] = HP3PARBaseDriver.VOLUME_ID
+            model_update = self.driver.create_cloned_volume(volume, src_vref)
+            self.assertEqual(model_update, {'host': expected_volume_host})
+
+            expected = [
+                mock.call.getCPG(expected_cpg),
+                mock.call.copyVolume(
+                    self.VOLUME_3PAR_NAME,
+                    'osv-0DM4qZEVSKON-AAAAAAAAA',
+                    expected_cpg,
+                    {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
+                     'online': True})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_migrate_volume(self):
 
@@ -1064,35 +1160,38 @@ class HP3PARBaseDriver(object):
                   'status': 'available',
                   'host': HP3PARBaseDriver.FAKE_HOST,
                   'source_volid': HP3PARBaseDriver.VOLUME_ID}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume_name_3par = common._encode_name(volume['id'])
+
+            loc_info = 'HP3PARDriver:1234:CPG-FC1'
+            host = {'host': 'stack@3parfc1#CPG-FC1',
+                    'capabilities': {'location_info': loc_info}}
+
+            result = self.driver.migrate_volume(context.get_admin_context(),
+                                                volume, host)
+            self.assertIsNotNone(result)
+            self.assertEqual((True, None), result)
+
+            osv_matcher = 'osv-' + volume_name_3par
+
+            expected = [
+                mock.call.modifyVolume(
+                    osv_matcher,
+                    {'comment': '{"qos": {}, "display_name": "Foo Volume"}',
+                     'snapCPG': HP3PAR_CPG_SNAP}),
+                mock.call.modifyVolume(osv_matcher,
+                                       {'action': 6,
+                                        'userCPG': 'CPG-FC1',
+                                        'conversionOperation': 1,
+                                        'tuneOperation': 1}),
+                mock.call.getTask(mock.ANY)
+            ]
 
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
-
-        loc_info = 'HP3PARDriver:1234:CPG-FC1'
-        host = {'host': 'stack@3parfc1#CPG-FC1',
-                'capabilities': {'location_info': loc_info}}
-
-        result = self.driver.migrate_volume(context.get_admin_context(),
-                                            volume, host)
-        self.assertIsNotNone(result)
-        self.assertEqual((True, None), result)
-
-        osv_matcher = 'osv-' + volume_name_3par
-
-        expected = [
-            mock.call.modifyVolume(
-                osv_matcher,
-                {'comment': '{"qos": {}, "display_name": "Foo Volume"}',
-                 'snapCPG': HP3PAR_CPG_SNAP}),
-            mock.call.modifyVolume(osv_matcher,
-                                   {'action': 6,
-                                    'userCPG': 'CPG-FC1',
-                                    'conversionOperation': 1,
-                                    'tuneOperation': 1}),
-            mock.call.getTask(mock.ANY),
-            mock.call.logout()
-        ]
-
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected + self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_migrate_volume_with_type(self, _mock_volume_types):
@@ -1124,46 +1223,53 @@ class HP3PARBaseDriver(object):
                   'host': HP3PARBaseDriver.FAKE_HOST,
                   'source_volid': HP3PARBaseDriver.VOLUME_ID}
 
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        loc_info = 'HP3PARDriver:1234:CPG-FC1'
-        host = {'host': 'stack@3parfc1#CPG-FC1',
-                'capabilities': {'location_info': loc_info}}
+            volume_name_3par = common._encode_name(volume['id'])
 
-        result = self.driver.migrate_volume(context.get_admin_context(),
-                                            volume, host)
-        self.assertIsNotNone(result)
-        expected_host = volume_utils.append_host(
-            "stack@3parfc1",
-            self.RETYPE_VOLUME_TYPE_2['extra_specs']['cpg'])
-        self.assertEqual((True, {'host': expected_host}), result)
-
-        osv_matcher = 'osv-' + volume_name_3par
-
-        expected_comment = {
-            "display_name": display_name,
-            "volume_type_id": self.RETYPE_VOLUME_TYPE_2['id'],
-            "volume_type_name": self.RETYPE_VOLUME_TYPE_2['name'],
-            "vvs": self.RETYPE_VOLUME_TYPE_2['extra_specs']['vvs']
-        }
-        expected = [
-            mock.call.modifyVolume(
-                osv_matcher,
-                {'comment': self.CommentMatcher(self.assertEqual,
-                                                expected_comment),
-                 'snapCPG': self.RETYPE_VOLUME_TYPE_2
-                 ['extra_specs']['snap_cpg']}),
-            mock.call.modifyVolume(
-                osv_matcher,
-                {'action': 6,
-                 'userCPG': self.RETYPE_VOLUME_TYPE_2['extra_specs']['cpg'],
-                 'conversionOperation': 1,
-                 'tuneOperation': 1}),
-            mock.call.getTask(mock.ANY),
-            mock.call.logout()
-        ]
+            loc_info = 'HP3PARDriver:1234:CPG-FC1'
+            host = {'host': 'stack@3parfc1#CPG-FC1',
+                    'capabilities': {'location_info': loc_info}}
 
-        mock_client.assert_has_calls(expected)
+            result = self.driver.migrate_volume(context.get_admin_context(),
+                                                volume, host)
+            self.assertIsNotNone(result)
+            expected_host = volume_utils.append_host(
+                "stack@3parfc1",
+                self.RETYPE_VOLUME_TYPE_2['extra_specs']['cpg'])
+            self.assertEqual((True, {'host': expected_host}), result)
+
+            osv_matcher = 'osv-' + volume_name_3par
+
+            expected_comment = {
+                "display_name": display_name,
+                "volume_type_id": self.RETYPE_VOLUME_TYPE_2['id'],
+                "volume_type_name": self.RETYPE_VOLUME_TYPE_2['name'],
+                "vvs": self.RETYPE_VOLUME_TYPE_2['extra_specs']['vvs']
+            }
+            expected = [
+                mock.call.modifyVolume(
+                    osv_matcher,
+                    {'comment': self.CommentMatcher(self.assertEqual,
+                                                    expected_comment),
+                     'snapCPG': self.RETYPE_VOLUME_TYPE_2
+                     ['extra_specs']['snap_cpg']}),
+                mock.call.modifyVolume(
+                    osv_matcher,
+                    {'action': 6,
+                     'userCPG': self.RETYPE_VOLUME_TYPE_2
+                     ['extra_specs']['cpg'],
+                     'conversionOperation': 1,
+                     'tuneOperation': 1}),
+                mock.call.getTask(mock.ANY)
+            ]
+
+            mock_client.assert_has_calls(
+                expected +
+                self.standard_logout)
 
     def test_migrate_volume_diff_host(self):
         conf = {
@@ -1171,7 +1277,7 @@ class HP3PARBaseDriver(object):
                 'serialNumber': 'different'},
         }
 
-        self.setup_driver(mock_conf=conf)
+        mock_client = self.setup_driver(mock_conf=conf)
 
         volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
                   'id': HP3PARBaseDriver.CLONE_ID,
@@ -1186,10 +1292,13 @@ class HP3PARBaseDriver(object):
         host = {'host': 'stack@3parfc1',
                 'capabilities': {'location_info': loc_info}}
 
-        result = self.driver.migrate_volume(context.get_admin_context(),
-                                            volume, host)
-        self.assertIsNotNone(result)
-        self.assertEqual((False, None), result)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            result = self.driver.migrate_volume(context.get_admin_context(),
+                                                volume, host)
+            self.assertIsNotNone(result)
+            self.assertEqual((False, None), result)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_migrate_volume_diff_domain(self, _mock_volume_types):
@@ -1220,34 +1329,38 @@ class HP3PARBaseDriver(object):
                   'host': HP3PARBaseDriver.FAKE_HOST,
                   'source_volid': HP3PARBaseDriver.VOLUME_ID}
 
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
-
-        loc_info = 'HP3PARDriver:1234:CPG-FC1'
-        host = {'host': 'stack@3parfc1#CPG-FC1',
-                'capabilities': {'location_info': loc_info}}
-
-        result = self.driver.migrate_volume(context.get_admin_context(),
-                                            volume, host)
-        self.assertIsNotNone(result)
-        self.assertEqual((True, None), result)
-
-        osv_matcher = 'osv-' + volume_name_3par
-
-        expected = [
-            mock.call.modifyVolume(
-                osv_matcher,
-                {'comment': '{"qos": {}, "display_name": "Foo Volume"}',
-                 'snapCPG': HP3PAR_CPG_SNAP}),
-            mock.call.modifyVolume(osv_matcher,
-                                   {'action': 6,
-                                    'userCPG': 'CPG-FC1',
-                                    'conversionOperation': 1,
-                                    'tuneOperation': 1}),
-            mock.call.getTask(mock.ANY),
-            mock.call.logout()
-        ]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume_name_3par = common._encode_name(volume['id'])
+
+            loc_info = 'HP3PARDriver:1234:CPG-FC1'
+            host = {'host': 'stack@3parfc1#CPG-FC1',
+                    'capabilities': {'location_info': loc_info}}
+
+            result = self.driver.migrate_volume(context.get_admin_context(),
+                                                volume, host)
+            self.assertIsNotNone(result)
+            self.assertEqual((True, None), result)
+
+            osv_matcher = 'osv-' + volume_name_3par
+
+            expected = [
+                mock.call.modifyVolume(
+                    osv_matcher,
+                    {'comment': '{"qos": {}, "display_name": "Foo Volume"}',
+                     'snapCPG': HP3PAR_CPG_SNAP}),
+                mock.call.modifyVolume(osv_matcher,
+                                       {'action': 6,
+                                        'userCPG': 'CPG-FC1',
+                                        'conversionOperation': 1,
+                                        'tuneOperation': 1}),
+                mock.call.getTask(mock.ANY),
+            ]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected + self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_migrate_volume_attached(self, _mock_volume_types):
@@ -1263,42 +1376,47 @@ class HP3PARBaseDriver(object):
                   'host': HP3PARBaseDriver.FAKE_HOST,
                   'source_volid': HP3PARBaseDriver.VOLUME_ID}
 
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
-        osv_matcher = 'osv-' + volume_name_3par
-
-        loc_info = 'HP3PARDriver:1234567:CPG-FC1'
-
-        protocol = "FC"
-        if self.properties['driver_volume_type'] == "iscsi":
-            protocol = "iSCSI"
-
-        host = {'host': 'stack@3parfc1',
-                'capabilities': {'location_info': loc_info,
-                                 'storage_protocol': protocol}}
-
-        result = self.driver.migrate_volume(context.get_admin_context(),
-                                            volume, host)
-
-        new_comment = {"qos": {},
-                       "retype_test": "test comment"}
-        expected = [
-            mock.call.modifyVolume(osv_matcher,
-                                   {'comment': self.CommentMatcher(
-                                       self.assertEqual, new_comment),
-                                    'snapCPG': 'OpenStackCPGSnap'}),
-            mock.call.modifyVolume(osv_matcher,
-                                   {'action': 6,
-                                    'userCPG': 'OpenStackCPG',
-                                    'conversionOperation': 1,
-                                    'tuneOperation': 1}),
-            mock.call.getTask(1),
-            mock.call.logout()
-        ]
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume_name_3par = common._encode_name(volume['id'])
+            osv_matcher = 'osv-' + volume_name_3par
+
+            loc_info = 'HP3PARDriver:1234567:CPG-FC1'
+
+            protocol = "FC"
+            if self.properties['driver_volume_type'] == "iscsi":
+                protocol = "iSCSI"
+
+            host = {'host': 'stack@3parfc1',
+                    'capabilities': {'location_info': loc_info,
+                                     'storage_protocol': protocol}}
+
+            result = self.driver.migrate_volume(context.get_admin_context(),
+                                                volume, host)
+
+            new_comment = {"qos": {},
+                           "retype_test": "test comment"}
+            expected = [
+                mock.call.modifyVolume(osv_matcher,
+                                       {'comment': self.CommentMatcher(
+                                           self.assertEqual, new_comment),
+                                        'snapCPG': 'OpenStackCPGSnap'}),
+                mock.call.modifyVolume(osv_matcher,
+                                       {'action': 6,
+                                        'userCPG': 'OpenStackCPG',
+                                        'conversionOperation': 1,
+                                        'tuneOperation': 1}),
+                mock.call.getTask(1),
+                mock.call.logout()
+            ]
+            mock_client.assert_has_calls(expected)
 
-        self.assertIsNotNone(result)
-        self.assertEqual((True, {'host': 'stack@3parfc1#OpenStackCPG'}),
-                         result)
+            self.assertIsNotNone(result)
+            self.assertEqual((True, {'host': 'stack@3parfc1#OpenStackCPG'}),
+                             result)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_migrate_volume_attached_diff_protocol(self, _mock_volume_types):
@@ -1330,106 +1448,122 @@ class HP3PARBaseDriver(object):
         mock_client.assert_has_calls(expected)
 
     def test_attach_volume(self):
-
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        self.driver.attach_volume(context.get_admin_context(),
-                                  self.volume,
-                                  'abcdef',
-                                  'newhost',
-                                  '/dev/vdb')
-
-        expected = [
-            mock.call.setVolumeMetaData(
-                self.VOLUME_3PAR_NAME,
-                'HPQ-CS-instance_uuid',
-                'abcdef')]
-
-        mock_client.assert_has_calls(expected)
-
-        # test the exception
-        mock_client.setVolumeMetaData.side_effect = Exception('Custom ex')
-        self.assertRaises(exception.CinderException,
-                          self.driver.attach_volume,
-                          context.get_admin_context(),
-                          self.volume,
-                          'abcdef',
-                          'newhost',
-                          '/dev/vdb')
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.attach_volume(context.get_admin_context(),
+                                      self.volume,
+                                      'abcdef',
+                                      'newhost',
+                                      '/dev/vdb')
+
+            expected = [
+                mock.call.setVolumeMetaData(
+                    self.VOLUME_3PAR_NAME,
+                    'HPQ-CS-instance_uuid',
+                    'abcdef')]
+
+            mock_client.assert_has_calls(expected)
+
+            # test the exception
+            mock_client.setVolumeMetaData.side_effect = Exception('Custom ex')
+            self.assertRaises(exception.CinderException,
+                              self.driver.attach_volume,
+                              context.get_admin_context(),
+                              self.volume,
+                              'abcdef',
+                              'newhost',
+                              '/dev/vdb')
 
     def test_detach_volume(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        self.driver.detach_volume(context.get_admin_context(), self.volume)
-        expected = [
-            mock.call.removeVolumeMetaData(
-                self.VOLUME_3PAR_NAME,
-                'HPQ-CS-instance_uuid')]
-
-        mock_client.assert_has_calls(expected)
-
-        # test the exception
-        mock_client.removeVolumeMetaData.side_effect = Exception('Custom ex')
-        self.assertRaises(exception.CinderException,
-                          self.driver.detach_volume,
-                          context.get_admin_context(),
-                          self.volume)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.detach_volume(context.get_admin_context(), self.volume)
+            expected = [
+                mock.call.removeVolumeMetaData(
+                    self.VOLUME_3PAR_NAME,
+                    'HPQ-CS-instance_uuid')]
+
+            mock_client.assert_has_calls(expected)
+
+            # test the exception
+            mock_client.removeVolumeMetaData.side_effect = Exception(
+                'Custom ex')
+            self.assertRaises(exception.CinderException,
+                              self.driver.detach_volume,
+                              context.get_admin_context(),
+                              self.volume)
 
     def test_create_snapshot(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        self.driver.create_snapshot(self.snapshot)
-
-        commet = (
-            '{"volume_id": "761fc5e5-5191-4ec7-aeba-33e36de44156",'
-            ' "display_name": "fakesnap",'
-            ' "description": "test description name",'
-            ' "volume_name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createSnapshot(
-                'oss-L4I73ONuTci9Fd4ceij-MQ',
-                'osv-dh-F5VGRTseuujPjbeRBVg',
-                {
-                    'comment': commet,
-                    'readOnly': True}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.create_snapshot(self.snapshot)
+
+            comment = (
+                '{"volume_id": "761fc5e5-5191-4ec7-aeba-33e36de44156",'
+                ' "display_name": "fakesnap",'
+                ' "description": "test description name",'
+                ' "volume_name":'
+                ' "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+
+            expected = [
+                mock.call.createSnapshot(
+                    'oss-L4I73ONuTci9Fd4ceij-MQ',
+                    'osv-dh-F5VGRTseuujPjbeRBVg',
+                    {
+                        'comment': comment,
+                        'readOnly': True})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_delete_snapshot(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.delete_snapshot(self.snapshot)
 
-        self.driver.delete_snapshot(self.snapshot)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.deleteVolume('oss-L4I73ONuTci9Fd4ceij-MQ'),
-            mock.call.logout()]
+            expected = [
+                mock.call.deleteVolume('oss-L4I73ONuTci9Fd4ceij-MQ')]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_delete_snapshot_in_use(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.create_snapshot(self.snapshot)
+            self.driver.create_volume_from_snapshot(self.volume, self.snapshot)
 
-        self.driver.create_snapshot(self.snapshot)
-        self.driver.create_volume_from_snapshot(self.volume, self.snapshot)
-
-        ex = hpexceptions.HTTPConflict("In use")
-        mock_client.deleteVolume = mock.Mock(side_effect=ex)
+            ex = hpexceptions.HTTPConflict("In use")
+            mock_client.deleteVolume = mock.Mock(side_effect=ex)
 
-        # Deleting the snapshot that a volume is dependent on should fail
-        self.assertRaises(exception.SnapshotIsBusy,
-                          self.driver.delete_snapshot,
-                          self.snapshot)
+            # Deleting the snapshot that a volume is dependent on should fail
+            self.assertRaises(exception.SnapshotIsBusy,
+                              self.driver.delete_snapshot,
+                              self.snapshot)
 
     def test_delete_snapshot_not_found(self):
         # setup_mock_client drive with default configuration
@@ -1450,32 +1584,38 @@ class HP3PARBaseDriver(object):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        model_update = self.driver.create_volume_from_snapshot(self.volume,
-                                                               self.snapshot)
-        self.assertIsNone(model_update)
-
-        comment = (
-            '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
-            ' "display_name": "Foo Volume",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createSnapshot(
-                self.VOLUME_3PAR_NAME,
-                'oss-L4I73ONuTci9Fd4ceij-MQ',
-                {
-                    'comment': comment,
-                    'readOnly': False}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-
-        volume = self.volume.copy()
-        volume['size'] = 1
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.create_volume_from_snapshot,
-                          volume, self.snapshot)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            model_update = self.driver.create_volume_from_snapshot(
+                self.volume,
+                self.snapshot)
+            self.assertIsNone(model_update)
+
+            comment = (
+                '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
+                ' "display_name": "Foo Volume",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+
+            expected = [
+                mock.call.createSnapshot(
+                    self.VOLUME_3PAR_NAME,
+                    'oss-L4I73ONuTci9Fd4ceij-MQ',
+                    {
+                        'comment': comment,
+                        'readOnly': False})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            volume = self.volume.copy()
+            volume['size'] = 1
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.create_volume_from_snapshot,
+                              volume, self.snapshot)
 
     def test_create_volume_from_snapshot_and_extend(self):
         # setup_mock_client drive with default configuration
@@ -1488,42 +1628,48 @@ class HP3PARBaseDriver(object):
         }
 
         mock_client = self.setup_driver(mock_conf=conf)
-
-        volume = self.volume.copy()
-        volume['size'] = self.volume['size'] + 10
-        model_update = self.driver.create_volume_from_snapshot(volume,
-                                                               self.snapshot)
-        self.assertEqual(model_update,
-                         {'host': volume_utils.append_host(self.FAKE_HOST,
-                                                           HP3PAR_CPG)})
-
-        comment = (
-            '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
-            ' "display_name": "Foo Volume",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
-        osv_matcher = 'osv-' + volume_name_3par
-        omv_matcher = 'omv-' + volume_name_3par
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createSnapshot(
-                self.VOLUME_3PAR_NAME,
-                'oss-L4I73ONuTci9Fd4ceij-MQ',
-                {
-                    'comment': comment,
-                    'readOnly': False}),
-            mock.call.copyVolume(
-                osv_matcher, omv_matcher, HP3PAR_CPG, mock.ANY),
-            mock.call.getTask(mock.ANY),
-            mock.call.getVolume(osv_matcher),
-            mock.call.deleteVolume(osv_matcher),
-            mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
-            mock.call.growVolume(osv_matcher, 10 * 1024),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume = self.volume.copy()
+            volume['size'] = self.volume['size'] + 10
+            model_update = self.driver.create_volume_from_snapshot(
+                volume,
+                self.snapshot)
+            self.assertEqual(model_update,
+                             {'host': volume_utils.append_host(self.FAKE_HOST,
+                                                               HP3PAR_CPG)})
+
+            comment = (
+                '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
+                ' "display_name": "Foo Volume",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+
+            volume_name_3par = common._encode_name(volume['id'])
+            osv_matcher = 'osv-' + volume_name_3par
+            omv_matcher = 'omv-' + volume_name_3par
+
+            expected = [
+                mock.call.createSnapshot(
+                    self.VOLUME_3PAR_NAME,
+                    'oss-L4I73ONuTci9Fd4ceij-MQ',
+                    {
+                        'comment': comment,
+                        'readOnly': False}),
+                mock.call.copyVolume(
+                    osv_matcher, omv_matcher, HP3PAR_CPG, mock.ANY),
+                mock.call.getTask(mock.ANY),
+                mock.call.getVolume(osv_matcher),
+                mock.call.deleteVolume(osv_matcher),
+                mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
+                mock.call.growVolume(osv_matcher, 10 * 1024)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_create_volume_from_snapshot_and_extend_with_qos(
@@ -1548,42 +1694,50 @@ class HP3PARBaseDriver(object):
                 'tpvv': True,
                 'volume_type': self.volume_type}}
 
-        volume = self.volume_qos.copy()
-        volume['size'] = self.volume['size'] + 10
-        model_update = self.driver.create_volume_from_snapshot(volume,
-                                                               self.snapshot)
-        self.assertEqual(model_update,
-                         {'host': volume_utils.append_host(self.FAKE_HOST,
-                                                           HP3PAR_CPG_QOS)})
-
-        comment = (
-            '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
-            ' "display_name": "Foo Volume",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-
-        volume_name_3par = self.driver.common._encode_name(volume['id'])
-        osv_matcher = 'osv-' + volume_name_3par
-        omv_matcher = 'omv-' + volume_name_3par
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createSnapshot(
-                self.VOLUME_3PAR_NAME,
-                'oss-L4I73ONuTci9Fd4ceij-MQ',
-                {
-                    'comment': comment,
-                    'readOnly': False}),
-            mock.call.getCPG(HP3PAR_CPG_QOS),
-            mock.call.copyVolume(
-                osv_matcher, omv_matcher, HP3PAR_CPG_QOS, mock.ANY),
-            mock.call.getTask(mock.ANY),
-            mock.call.getVolume(osv_matcher),
-            mock.call.deleteVolume(osv_matcher),
-            mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
-            mock.call.growVolume(osv_matcher, 10 * 1024),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume = self.volume_qos.copy()
+            volume['size'] = self.volume['size'] + 10
+            model_update = self.driver.create_volume_from_snapshot(
+                volume,
+                self.snapshot)
+            self.assertEqual(model_update,
+                             {'host': volume_utils.append_host(
+                                 self.FAKE_HOST,
+                                 HP3PAR_CPG_QOS)})
+
+            comment = (
+                '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
+                ' "display_name": "Foo Volume",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+
+            volume_name_3par = common._encode_name(volume['id'])
+            osv_matcher = 'osv-' + volume_name_3par
+            omv_matcher = 'omv-' + volume_name_3par
+
+            expected = [
+                mock.call.createSnapshot(
+                    self.VOLUME_3PAR_NAME,
+                    'oss-L4I73ONuTci9Fd4ceij-MQ',
+                    {
+                        'comment': comment,
+                        'readOnly': False}),
+                mock.call.getCPG(HP3PAR_CPG_QOS),
+                mock.call.copyVolume(
+                    osv_matcher, omv_matcher, HP3PAR_CPG_QOS, mock.ANY),
+                mock.call.getTask(mock.ANY),
+                mock.call.getVolume(osv_matcher),
+                mock.call.deleteVolume(osv_matcher),
+                mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
+                mock.call.growVolume(osv_matcher, 10 * 1024)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_create_volume_from_snapshot_and_extend_copy_fail(self):
         # setup_mock_client drive with default configuration
@@ -1610,38 +1764,44 @@ class HP3PARBaseDriver(object):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        _mock_volume_types.return_value = {
-            'name': 'gold',
-            'extra_specs': {
-                'cpg': HP3PAR_CPG,
-                'snap_cpg': HP3PAR_CPG_SNAP,
-                'vvs_name': self.VVS_NAME,
-                'qos': self.QOS,
-                'tpvv': True,
-                'volume_type': self.volume_type}}
-        self.driver.create_volume_from_snapshot(self.volume_qos, self.snapshot)
-
-        comment = (
-            '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
-            ' "display_name": "Foo Volume",'
-            ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.createSnapshot(
-                self.VOLUME_3PAR_NAME,
-                'oss-L4I73ONuTci9Fd4ceij-MQ', {
-                    'comment': comment,
-                    'readOnly': False}),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-
-        volume = self.volume.copy()
-        volume['size'] = 1
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.create_volume_from_snapshot,
-                          volume, self.snapshot)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            _mock_volume_types.return_value = {
+                'name': 'gold',
+                'extra_specs': {
+                    'cpg': HP3PAR_CPG,
+                    'snap_cpg': HP3PAR_CPG_SNAP,
+                    'vvs_name': self.VVS_NAME,
+                    'qos': self.QOS,
+                    'tpvv': True,
+                    'volume_type': self.volume_type}}
+            self.driver.create_volume_from_snapshot(
+                self.volume_qos,
+                self.snapshot)
+
+            comment = (
+                '{"snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",'
+                ' "display_name": "Foo Volume",'
+                ' "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"}')
+
+            expected = [
+                mock.call.createSnapshot(
+                    self.VOLUME_3PAR_NAME,
+                    'oss-L4I73ONuTci9Fd4ceij-MQ', {
+                        'comment': comment,
+                        'readOnly': False})]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            volume = self.volume.copy()
+            volume['size'] = 1
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.create_volume_from_snapshot,
+                              volume, self.snapshot)
 
     def test_terminate_connection(self):
         # setup_mock_client drive with default configuration
@@ -1652,26 +1812,30 @@ class HP3PARBaseDriver(object):
              'volumeName': self.VOLUME_3PAR_NAME,
              'lun': None, 'type': 0}]
 
-        self.driver.terminate_connection(
-            self.volume,
-            self.connector,
-            force=True)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.deleteVLUN(
-                self.VOLUME_3PAR_NAME,
-                None,
-                self.FAKE_HOST),
-            mock.call.deleteHost(self.FAKE_HOST),
-            mock.call.removeVolumeMetaData(
-                self.VOLUME_3PAR_NAME, CHAP_USER_KEY),
-            mock.call.removeVolumeMetaData(
-                self.VOLUME_3PAR_NAME, CHAP_PASS_KEY),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            self.driver.terminate_connection(
+                self.volume,
+                self.connector,
+                force=True)
+
+            expected = [
+                mock.call.getHostVLUNs(self.FAKE_HOST),
+                mock.call.deleteVLUN(
+                    self.VOLUME_3PAR_NAME,
+                    None,
+                    self.FAKE_HOST),
+                mock.call.deleteHost(self.FAKE_HOST),
+                mock.call.removeVolumeMetaData(
+                    self.VOLUME_3PAR_NAME, CHAP_USER_KEY),
+                mock.call.removeVolumeMetaData(
+                    self.VOLUME_3PAR_NAME, CHAP_PASS_KEY)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_update_volume_key_value_pair(self):
         # setup_mock_client drive with default configuration
@@ -1680,59 +1844,70 @@ class HP3PARBaseDriver(object):
 
         key = 'a'
         value = 'b'
-        self.driver.common.update_volume_key_value_pair(
-            self.volume,
-            key,
-            value)
 
-        expected = [
-            mock.call.setVolumeMetaData(self.VOLUME_3PAR_NAME, key, value)]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            common.update_volume_key_value_pair(
+                self.volume,
+                key,
+                value)
 
-        mock_client.assert_has_calls(expected)
+            expected = [
+                mock.call.setVolumeMetaData(self.VOLUME_3PAR_NAME, key, value)]
+
+            mock_client.assert_has_calls(expected)
 
-        # check exception
-        mock_client.setVolumeMetaData.side_effect = Exception('fake')
-        self.assertRaises(exception.VolumeBackendAPIException,
-                          self.driver.common.update_volume_key_value_pair,
-                          self.volume,
-                          None,
-                          'b')
+            # check exception
+            mock_client.setVolumeMetaData.side_effect = Exception('fake')
+            self.assertRaises(exception.VolumeBackendAPIException,
+                              common.update_volume_key_value_pair,
+                              self.volume,
+                              None,
+                              'b')
 
     def test_clear_volume_key_value_pair(self):
 
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            key = 'a'
+            common = self.driver._login()
+            common.clear_volume_key_value_pair(self.volume, key)
 
-        key = 'a'
-        self.driver.common.clear_volume_key_value_pair(self.volume, key)
-
-        expected = [
-            mock.call.removeVolumeMetaData(self.VOLUME_3PAR_NAME, key)]
+            expected = [
+                mock.call.removeVolumeMetaData(self.VOLUME_3PAR_NAME, key)]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        # check the exception
-        mock_client.removeVolumeMetaData.side_effect = Exception('fake')
-        self.assertRaises(exception.VolumeBackendAPIException,
-                          self.driver.common.clear_volume_key_value_pair,
-                          self.volume,
-                          None)
+            # check the exception
+            mock_client.removeVolumeMetaData.side_effect = Exception('fake')
+            self.assertRaises(exception.VolumeBackendAPIException,
+                              common.clear_volume_key_value_pair,
+                              self.volume,
+                              None)
 
     def test_extend_volume(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-        grow_size = 3
-        old_size = self.volume['size']
-        new_size = old_size + grow_size
-        self.driver.extend_volume(self.volume, str(new_size))
-        growth_size_mib = grow_size * units.Ki
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            grow_size = 3
+            old_size = self.volume['size']
+            new_size = old_size + grow_size
+            self.driver.extend_volume(self.volume, str(new_size))
+            growth_size_mib = grow_size * units.Ki
 
-        expected = [
-            mock.call.growVolume(self.VOLUME_3PAR_NAME, growth_size_mib)]
+            expected = [
+                mock.call.growVolume(self.VOLUME_3PAR_NAME, growth_size_mib)]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
     def test_extend_volume_non_base(self):
         extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
@@ -1748,12 +1923,15 @@ class HP3PARBaseDriver(object):
         }
 
         mock_client = self.setup_driver(mock_conf=conf)
-        grow_size = 3
-        old_size = self.volume['size']
-        new_size = old_size + grow_size
-        self.driver.extend_volume(self.volume, str(new_size))
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            grow_size = 3
+            old_size = self.volume['size']
+            new_size = old_size + grow_size
+            self.driver.extend_volume(self.volume, str(new_size))
 
-        self.assertEqual(2, mock_client.growVolume.call_count)
+            self.assertEqual(2, mock_client.growVolume.call_count)
 
     def test_extend_volume_non_base_failure(self):
         extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
@@ -1767,14 +1945,17 @@ class HP3PARBaseDriver(object):
             'growVolume.side_effect': extend_ex
         }
 
-        self.setup_driver(mock_conf=conf)
-        grow_size = 3
-        old_size = self.volume['size']
-        new_size = old_size + grow_size
-        self.assertRaises(hpexceptions.HTTPForbidden,
-                          self.driver.extend_volume,
-                          self.volume,
-                          str(new_size))
+        mock_client = self.setup_driver(mock_conf=conf)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            grow_size = 3
+            old_size = self.volume['size']
+            new_size = old_size + grow_size
+            self.assertRaises(hpexceptions.HTTPForbidden,
+                              self.driver.extend_volume,
+                              self.volume,
+                              str(new_size))
 
     def test_get_ports(self):
         # setup_mock_client drive with default configuration
@@ -1809,111 +1990,143 @@ class HP3PARBaseDriver(object):
                  'type': 2,
                  'portPos': {'node': 0, 'slot': 6, 'cardPort': 3}}]}
 
-        ports = self.driver.common.get_ports()['members']
-        self.assertEqual(len(ports), 3)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            ports = common.get_ports()['members']
+            self.assertEqual(len(ports), 3)
 
     def test_get_by_qos_spec_with_scoping(self):
-        self.setup_driver()
-        qos_ref = qos_specs.create(self.ctxt, 'qos-specs-1', self.QOS)
-        type_ref = volume_types.create(self.ctxt,
-                                       "type1", {"qos:maxIOPS": "100",
-                                                 "qos:maxBWS": "50",
-                                                 "qos:minIOPS": "10",
-                                                 "qos:minBWS": "20",
-                                                 "qos:latency": "5",
-                                                 "qos:priority": "high"})
-        qos_specs.associate_qos_with_type(self.ctxt,
-                                          qos_ref['id'],
-                                          type_ref['id'])
-        type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
-        qos = self.driver.common._get_qos_by_volume_type(type_ref)
-        self.assertEqual(qos, {'maxIOPS': '1000', 'maxBWS': '50',
-                               'minIOPS': '100', 'minBWS': '25',
-                               'latency': '25', 'priority': 'low'})
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            qos_ref = qos_specs.create(self.ctxt, 'qos-specs-1', self.QOS)
+            type_ref = volume_types.create(self.ctxt,
+                                           "type1", {"qos:maxIOPS": "100",
+                                                     "qos:maxBWS": "50",
+                                                     "qos:minIOPS": "10",
+                                                     "qos:minBWS": "20",
+                                                     "qos:latency": "5",
+                                                     "qos:priority": "high"})
+            qos_specs.associate_qos_with_type(self.ctxt,
+                                              qos_ref['id'],
+                                              type_ref['id'])
+            type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
+            qos = common._get_qos_by_volume_type(type_ref)
+            self.assertEqual(qos, {'maxIOPS': '1000', 'maxBWS': '50',
+                                   'minIOPS': '100', 'minBWS': '25',
+                                   'latency': '25', 'priority': 'low'})
 
     def test_get_by_qos_spec(self):
-        self.setup_driver()
-        qos_ref = qos_specs.create(self.ctxt, 'qos-specs-1', self.QOS_SPECS)
-        type_ref = volume_types.create(self.ctxt,
-                                       "type1", {"qos:maxIOPS": "100",
-                                                 "qos:maxBWS": "50",
-                                                 "qos:minIOPS": "10",
-                                                 "qos:minBWS": "20",
-                                                 "qos:latency": "5",
-                                                 "qos:priority": "high"})
-        qos_specs.associate_qos_with_type(self.ctxt,
-                                          qos_ref['id'],
-                                          type_ref['id'])
-        type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
-        qos = self.driver.common._get_qos_by_volume_type(type_ref)
-        self.assertEqual(qos, {'maxIOPS': '1000', 'maxBWS': '50',
-                               'minIOPS': '100', 'minBWS': '25',
-                               'latency': '25', 'priority': 'low'})
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            qos_ref = qos_specs.create(
+                self.ctxt,
+                'qos-specs-1',
+                self.QOS_SPECS)
+            type_ref = volume_types.create(self.ctxt,
+                                           "type1", {"qos:maxIOPS": "100",
+                                                     "qos:maxBWS": "50",
+                                                     "qos:minIOPS": "10",
+                                                     "qos:minBWS": "20",
+                                                     "qos:latency": "5",
+                                                     "qos:priority": "high"})
+            qos_specs.associate_qos_with_type(self.ctxt,
+                                              qos_ref['id'],
+                                              type_ref['id'])
+            type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
+            qos = common._get_qos_by_volume_type(type_ref)
+            self.assertEqual(qos, {'maxIOPS': '1000', 'maxBWS': '50',
+                                   'minIOPS': '100', 'minBWS': '25',
+                                   'latency': '25', 'priority': 'low'})
 
     def test_get_by_qos_by_type_only(self):
-        self.setup_driver()
-        type_ref = volume_types.create(self.ctxt,
-                                       "type1", {"qos:maxIOPS": "100",
-                                                 "qos:maxBWS": "50",
-                                                 "qos:minIOPS": "10",
-                                                 "qos:minBWS": "20",
-                                                 "qos:latency": "5",
-                                                 "qos:priority": "high"})
-        type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
-        qos = self.driver.common._get_qos_by_volume_type(type_ref)
-        self.assertEqual(qos, {'maxIOPS': '100', 'maxBWS': '50',
-                               'minIOPS': '10', 'minBWS': '20',
-                               'latency': '5', 'priority': 'high'})
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            type_ref = volume_types.create(self.ctxt,
+                                           "type1", {"qos:maxIOPS": "100",
+                                                     "qos:maxBWS": "50",
+                                                     "qos:minIOPS": "10",
+                                                     "qos:minBWS": "20",
+                                                     "qos:latency": "5",
+                                                     "qos:priority": "high"})
+            type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
+            qos = common._get_qos_by_volume_type(type_ref)
+            self.assertEqual(qos, {'maxIOPS': '100', 'maxBWS': '50',
+                                   'minIOPS': '10', 'minBWS': '20',
+                                   'latency': '5', 'priority': 'high'})
 
     def test_create_vlun(self):
         host = 'fake-host'
         lun_id = 11
         nsp = '1:2:3'
         mock_client = self.setup_driver()
-        location = ("%(name)s,%(lunid)s,%(host)s,%(nsp)s" %
-                    {'name': self.VOLUME_NAME,
-                     'lunid': lun_id,
-                     'host': host,
-                     'nsp': nsp})
-        mock_client.createVLUN.return_value = location
-
-        expected_info = {'volume_name': self.VOLUME_NAME,
-                         'lun_id': lun_id,
-                         'host_name': host,
-                         'nsp': nsp}
-        vlun_info = self.driver.common._create_3par_vlun(self.VOLUME_NAME,
-                                                         host, nsp)
-        self.assertEqual(expected_info, vlun_info)
-
-        location = ("%(name)s,%(lunid)s,%(host)s" %
-                    {'name': self.VOLUME_NAME,
-                     'lunid': lun_id,
-                     'host': host})
-        mock_client.createVLUN.return_value = location
-        expected_info = {'volume_name': self.VOLUME_NAME,
-                         'lun_id': lun_id,
-                         'host_name': host}
-        vlun_info = self.driver.common._create_3par_vlun(self.VOLUME_NAME,
-                                                         host, None)
-        self.assertEqual(expected_info, vlun_info)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            location = ("%(name)s,%(lunid)s,%(host)s,%(nsp)s" %
+                        {'name': self.VOLUME_NAME,
+                         'lunid': lun_id,
+                         'host': host,
+                         'nsp': nsp})
+            mock_client.createVLUN.return_value = location
+
+            expected_info = {'volume_name': self.VOLUME_NAME,
+                             'lun_id': lun_id,
+                             'host_name': host,
+                             'nsp': nsp}
+            common = self.driver._login()
+            vlun_info = common._create_3par_vlun(
+                self.VOLUME_NAME,
+                host,
+                nsp)
+            self.assertEqual(expected_info, vlun_info)
+
+            location = ("%(name)s,%(lunid)s,%(host)s" %
+                        {'name': self.VOLUME_NAME,
+                         'lunid': lun_id,
+                         'host': host})
+            mock_client.createVLUN.return_value = location
+            expected_info = {'volume_name': self.VOLUME_NAME,
+                             'lun_id': lun_id,
+                             'host_name': host}
+            vlun_info = common._create_3par_vlun(
+                self.VOLUME_NAME,
+                host,
+                None)
+            self.assertEqual(expected_info, vlun_info)
 
     def test__get_existing_volume_ref_name(self):
-        self.setup_driver()
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
 
-        existing_ref = {'source-name': unm_matcher}
-        result = self.driver.common._get_existing_volume_ref_name(existing_ref)
-        self.assertEqual(unm_matcher, result)
+            existing_ref = {'source-name': unm_matcher}
+            result = common._get_existing_volume_ref_name(existing_ref)
+            self.assertEqual(unm_matcher, result)
 
-        existing_ref = {'source-id': self.volume['id']}
-        result = self.driver.common._get_existing_volume_ref_name(existing_ref)
-        self.assertEqual(unm_matcher, result)
+            existing_ref = {'source-id': self.volume['id']}
+            result = common._get_existing_volume_ref_name(existing_ref)
+            self.assertEqual(unm_matcher, result)
 
-        existing_ref = {'bad-key': 'foo'}
-        self.assertRaises(
-            exception.ManageExistingInvalidReference,
-            self.driver.common._get_existing_volume_ref_name,
-            existing_ref)
+            existing_ref = {'bad-key': 'foo'}
+            self.assertRaises(
+                exception.ManageExistingInvalidReference,
+                common._get_existing_volume_ref_name,
+                existing_ref)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_manage_existing(self, _mock_volume_types):
@@ -1935,69 +2148,75 @@ class HP3PARBaseDriver(object):
         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
         mock_client.getTask.return_value = self.STATUS_DONE
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
-        vvs_matcher = self.driver.common._get_3par_vvs_name(volume['id'])
-        existing_ref = {'source-name': unm_matcher}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        obj = self.driver.manage_existing(volume, existing_ref)
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            osv_matcher = common._get_3par_vol_name(volume['id'])
+            vvs_matcher = common._get_3par_vvs_name(volume['id'])
+            existing_ref = {'source-name': unm_matcher}
 
-        expected_obj = {'display_name': 'Foo Volume',
-                        'host': 'my-stack1@3parxxx#fakepool'}
+            expected_obj = {'display_name': 'Foo Volume',
+                            'host': 'my-stack1@3parxxx#fakepool'}
 
-        expected_manage = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.modifyVolume(existing_ref['source-name'],
-                                   {'newName': osv_matcher,
-                                    'comment': self.CommentMatcher(
-                                        self.assertEqual, new_comment)}),
-        ]
+            obj = self.driver.manage_existing(volume, existing_ref)
 
-        retype_comment_qos = {
-            "display_name": "Foo Volume",
-            "volume_type_name": self.volume_type['name'],
-            "volume_type_id": self.volume_type['id'],
-            "qos": {
-                'maxIOPS': '1000',
-                'maxBWS': '50',
-                'minIOPS': '100',
-                'minBWS': '25',
-                'latency': '25',
-                'priority': 'low'
+            expected_manage = [
+                mock.call.getVolume(existing_ref['source-name']),
+                mock.call.modifyVolume(existing_ref['source-name'],
+                                       {'newName': osv_matcher,
+                                        'comment': self.CommentMatcher(
+                                            self.assertEqual, new_comment)}),
+            ]
+
+            retype_comment_qos = {
+                "display_name": "Foo Volume",
+                "volume_type_name": self.volume_type['name'],
+                "volume_type_id": self.volume_type['id'],
+                "qos": {
+                    'maxIOPS': '1000',
+                    'maxBWS': '50',
+                    'minIOPS': '100',
+                    'minBWS': '25',
+                    'latency': '25',
+                    'priority': 'low'
+                }
             }
-        }
 
-        expected_snap_cpg = self.volume_type['extra_specs']['cpg']
-        expected_retype_modify = [
-            mock.call.modifyVolume(osv_matcher,
-                                   {'comment': self.CommentMatcher(
-                                       self.assertEqual, retype_comment_qos),
-                                    'snapCPG': expected_snap_cpg}),
-            mock.call.deleteVolumeSet(vvs_matcher),
-        ]
+            expected_snap_cpg = self.volume_type['extra_specs']['cpg']
+            expected_retype_modify = [
+                mock.call.modifyVolume(osv_matcher,
+                                       {'comment': self.CommentMatcher(
+                                           self.assertEqual,
+                                           retype_comment_qos),
+                                        'snapCPG': expected_snap_cpg}),
+                mock.call.deleteVolumeSet(vvs_matcher),
+            ]
 
-        expected_retype_specs = [
-            mock.call.createVolumeSet(vvs_matcher, None),
-            mock.call.createQoSRules(
-                vvs_matcher,
-                {'ioMinGoal': 100, 'ioMaxLimit': 1000,
-                 'bwMinGoalKB': 25600, 'priority': 1, 'latencyGoal': 25,
-                 'bwMaxLimitKB': 51200}),
-            mock.call.addVolumeToVolumeSet(vvs_matcher, osv_matcher),
-            mock.call.modifyVolume(
-                osv_matcher,
-                {'action': 6,
-                 'userCPG': self.volume_type['extra_specs']['cpg'],
-                 'conversionOperation': 1, 'tuneOperation': 1}),
-            mock.call.getTask(1),
-            mock.call.logout()
-        ]
+            expected_retype_specs = [
+                mock.call.createVolumeSet(vvs_matcher, None),
+                mock.call.createQoSRules(
+                    vvs_matcher,
+                    {'ioMinGoal': 100, 'ioMaxLimit': 1000,
+                     'bwMinGoalKB': 25600, 'priority': 1, 'latencyGoal': 25,
+                     'bwMaxLimitKB': 51200}),
+                mock.call.addVolumeToVolumeSet(vvs_matcher, osv_matcher),
+                mock.call.modifyVolume(
+                    osv_matcher,
+                    {'action': 6,
+                     'userCPG': self.volume_type['extra_specs']['cpg'],
+                     'conversionOperation': 1, 'tuneOperation': 1}),
+                mock.call.getTask(1)
+            ]
 
-        mock_client.assert_has_calls(expected_manage)
-        mock_client.assert_has_calls(expected_retype_modify)
-        mock_client.assert_has_calls(expected_retype_specs)
-        self.assertEqual(expected_obj, obj)
+            mock_client.assert_has_calls(self.standard_login + expected_manage)
+            mock_client.assert_has_calls(expected_retype_modify)
+            mock_client.assert_has_calls(
+                expected_retype_specs +
+                self.standard_logout)
+            self.assertEqual(expected_obj, obj)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_manage_existing_vvs(self, _mock_volume_types):
@@ -2022,51 +2241,57 @@ class HP3PARBaseDriver(object):
                   'volume_type_id': 'acfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
                   'id': id}
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
-        vvs_matcher = self.driver.common._get_3par_vvs_name(volume['id'])
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        existing_ref = {'source-name': unm_matcher}
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            osv_matcher = common._get_3par_vol_name(volume['id'])
+            vvs_matcher = common._get_3par_vvs_name(volume['id'])
 
-        obj = self.driver.manage_existing(volume, existing_ref)
+            existing_ref = {'source-name': unm_matcher}
 
-        expected_obj = {'display_name': 'Test Volume',
-                        'host': 'my-stack1@3parxxx#qospool'}
-        expected_manage = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.modifyVolume(existing_ref['source-name'],
-                                   {'newName': osv_matcher,
-                                    'comment': self.CommentMatcher(
-                                        self.assertEqual, new_comment)})
-        ]
+            obj = self.driver.manage_existing(volume, existing_ref)
 
-        retype_comment_vvs = {
-            "display_name": "Foo Volume",
-            "volume_type_name": test_volume_type['name'],
-            "volume_type_id": test_volume_type['id'],
-            "vvs": vvs
-        }
+            expected_obj = {'display_name': 'Test Volume',
+                            'host': 'my-stack1@3parxxx#qospool'}
+            expected_manage = [
+                mock.call.getVolume(existing_ref['source-name']),
+                mock.call.modifyVolume(existing_ref['source-name'],
+                                       {'newName': osv_matcher,
+                                        'comment': self.CommentMatcher(
+                                            self.assertEqual, new_comment)})
+            ]
 
-        expected_retype = [
-            mock.call.modifyVolume(osv_matcher,
-                                   {'comment': self.CommentMatcher(
-                                       self.assertEqual, retype_comment_vvs),
-                                    'snapCPG': 'OpenStackCPGSnap'}),
-            mock.call.deleteVolumeSet(vvs_matcher),
-            mock.call.addVolumeToVolumeSet(vvs, osv_matcher),
-            mock.call.modifyVolume(osv_matcher,
-                                   {'action': 6, 'userCPG':
-                                    test_volume_type['extra_specs']['cpg'],
-                                    'conversionOperation': 1,
-                                    'tuneOperation': 1}),
-            mock.call.getTask(1),
-            mock.call.logout()
-        ]
+            retype_comment_vvs = {
+                "display_name": "Foo Volume",
+                "volume_type_name": test_volume_type['name'],
+                "volume_type_id": test_volume_type['id'],
+                "vvs": vvs
+            }
 
-        mock_client.assert_has_calls(expected_manage)
-        mock_client.assert_has_calls(expected_retype)
-        self.assertEqual(expected_obj, obj)
+            expected_retype = [
+                mock.call.modifyVolume(osv_matcher,
+                                       {'comment': self.CommentMatcher(
+                                           self.assertEqual,
+                                           retype_comment_vvs),
+                                        'snapCPG': 'OpenStackCPGSnap'}),
+                mock.call.deleteVolumeSet(vvs_matcher),
+                mock.call.addVolumeToVolumeSet(vvs, osv_matcher),
+                mock.call.modifyVolume(osv_matcher,
+                                       {'action': 6, 'userCPG':
+                                        test_volume_type['extra_specs']['cpg'],
+                                        'conversionOperation': 1,
+                                        'tuneOperation': 1}),
+                mock.call.getTask(1)
+            ]
+
+            mock_client.assert_has_calls(self.standard_login + expected_manage)
+            mock_client.assert_has_calls(
+                expected_retype +
+                self.standard_logout)
+            self.assertEqual(expected_obj, obj)
 
     def test_manage_existing_no_volume_type(self):
         mock_client = self.setup_driver()
@@ -2085,59 +2310,67 @@ class HP3PARBaseDriver(object):
 
         mock_client.getVolume.return_value = {'comment': comment}
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
-        existing_ref = {'source-name': unm_matcher}
-
-        obj = self.driver.manage_existing(volume, existing_ref)
-
-        expected_obj = {'display_name': 'Foo Volume'}
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.modifyVolume(existing_ref['source-name'],
-                                   {'newName': osv_matcher,
-                                    'comment': new_comment}),
-            mock.call.logout()
-        ]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            osv_matcher = common._get_3par_vol_name(volume['id'])
+            existing_ref = {'source-name': unm_matcher}
+
+            obj = self.driver.manage_existing(volume, existing_ref)
+
+            expected_obj = {'display_name': 'Foo Volume'}
+            expected = [
+                mock.call.getVolume(existing_ref['source-name']),
+                mock.call.modifyVolume(existing_ref['source-name'],
+                                       {'newName': osv_matcher,
+                                        'comment': new_comment})
+            ]
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_obj, obj)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(expected_obj, obj)
 
-        volume['display_name'] = 'Test Volume'
+            volume['display_name'] = 'Test Volume'
 
-        obj = self.driver.manage_existing(volume, existing_ref)
+            obj = self.driver.manage_existing(volume, existing_ref)
 
-        expected_obj = {'display_name': 'Test Volume'}
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.modifyVolume(existing_ref['source-name'],
-                                   {'newName': osv_matcher,
-                                    'comment': new_comment}),
-            mock.call.logout()
-        ]
+            expected_obj = {'display_name': 'Test Volume'}
+            expected = [
+                mock.call.getVolume(existing_ref['source-name']),
+                mock.call.modifyVolume(existing_ref['source-name'],
+                                       {'newName': osv_matcher,
+                                        'comment': new_comment})
+            ]
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_obj, obj)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(expected_obj, obj)
 
-        mock_client.getVolume.return_value = {}
-        volume['display_name'] = None
+            mock_client.getVolume.return_value = {}
+            volume['display_name'] = None
+            common = self.driver._login()
 
-        obj = self.driver.manage_existing(volume, existing_ref)
+            obj = self.driver.manage_existing(volume, existing_ref)
 
-        expected_obj = {'display_name': None}
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.modifyVolume(existing_ref['source-name'],
-                                   {'newName': osv_matcher,
-                                    'comment': new_comment}),
-            mock.call.logout()
-        ]
+            expected_obj = {'display_name': None}
+            expected = [
+                mock.call.getVolume(existing_ref['source-name']),
+                mock.call.modifyVolume(existing_ref['source-name'],
+                                       {'newName': osv_matcher,
+                                        'comment': new_comment})
+            ]
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_obj, obj)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(expected_obj, obj)
 
     def test_manage_existing_invalid_input(self):
         mock_client = self.setup_driver()
@@ -2148,21 +2381,24 @@ class HP3PARBaseDriver(object):
 
         mock_client.getVolume.side_effect = hpexceptions.HTTPNotFound('fake')
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        existing_ref = {'source-name': unm_matcher}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            existing_ref = {'source-name': unm_matcher}
 
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.manage_existing,
-                          volume=volume,
-                          existing_ref=existing_ref)
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.manage_existing,
+                              volume=volume,
+                              existing_ref=existing_ref)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.logout()
-        ]
+            expected = [mock.call.getVolume(existing_ref['source-name'])]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_manage_existing_volume_type_exception(self):
         mock_client = self.setup_driver()
@@ -2176,21 +2412,24 @@ class HP3PARBaseDriver(object):
 
         mock_client.getVolume.return_value = {'comment': comment}
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        existing_ref = {'source-name': unm_matcher}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            existing_ref = {'source-name': unm_matcher}
 
-        self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
-                          self.driver.manage_existing,
-                          volume=volume,
-                          existing_ref=existing_ref)
+            self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
+                              self.driver.manage_existing,
+                              volume=volume,
+                              existing_ref=existing_ref)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.logout()
-        ]
+            expected = [mock.call.getVolume(existing_ref['source-name'])]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_manage_existing_retype_exception(self, _mock_volume_types):
@@ -2221,119 +2460,137 @@ class HP3PARBaseDriver(object):
             {'domain': 'domain3'},
         ]
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
-
-        existing_ref = {'source-name': unm_matcher}
-
-        self.assertRaises(exception.Invalid3PARDomain,
-                          self.driver.manage_existing,
-                          volume=volume,
-                          existing_ref=existing_ref)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(unm_matcher),
-            mock.call.modifyVolume(
-                unm_matcher, {'newName': osv_matcher, 'comment': mock.ANY}),
-            mock.call.getCPG('OpenStackCPG'),
-            mock.call.getVolume(osv_matcher),
-            mock.call.getCPG('testUserCpg0'),
-            mock.call.getCPG('OpenStackCPG'),
-            mock.call.modifyVolume(
-                osv_matcher, {'newName': unm_matcher,
-                              'comment': self.MANAGE_VOLUME_INFO['comment']}),
-            mock.call.logout()
-        ]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            osv_matcher = common._get_3par_vol_name(volume['id'])
+
+            existing_ref = {'source-name': unm_matcher}
+
+            self.assertRaises(exception.Invalid3PARDomain,
+                              self.driver.manage_existing,
+                              volume=volume,
+                              existing_ref=existing_ref)
+
+            expected = [
+
+                mock.call.getVolume(unm_matcher),
+                mock.call.modifyVolume(
+                    unm_matcher, {
+                        'newName': osv_matcher,
+                        'comment': mock.ANY}),
+                mock.call.getCPG('OpenStackCPG'),
+                mock.call.getVolume(osv_matcher),
+                mock.call.getCPG('testUserCpg0'),
+                mock.call.getCPG('OpenStackCPG'),
+                mock.call.modifyVolume(
+                    osv_matcher, {'newName': unm_matcher,
+                                  'comment': self.MANAGE_VOLUME_INFO
+                                  ['comment']})
+            ]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_manage_existing_get_size(self):
         mock_client = self.setup_driver()
         mock_client.getVolume.return_value = {'sizeMiB': 2048}
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        volume = {}
-        existing_ref = {'source-name': unm_matcher}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            volume = {}
+            existing_ref = {'source-name': unm_matcher}
 
-        size = self.driver.manage_existing_get_size(volume, existing_ref)
+            size = self.driver.manage_existing_get_size(volume, existing_ref)
 
-        expected_size = 2
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.logout()
-        ]
+            expected_size = 2
+            expected = [mock.call.getVolume(existing_ref['source-name'])]
 
-        mock_client.assert_has_calls(expected, True)
-        self.assertEqual(expected_size, size)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(expected_size, size)
 
     def test_manage_existing_get_size_invalid_reference(self):
         mock_client = self.setup_driver()
-        volume = {}
-        existing_ref = {'source-name': self.VOLUME_3PAR_NAME}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            volume = {}
+            existing_ref = {'source-name': self.VOLUME_3PAR_NAME}
 
-        self.assertRaises(exception.ManageExistingInvalidReference,
-                          self.driver.manage_existing_get_size,
-                          volume=volume,
-                          existing_ref=existing_ref)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.logout()
-        ]
-
-        mock_client.assert_has_calls(expected)
+            self.assertRaises(exception.ManageExistingInvalidReference,
+                              self.driver.manage_existing_get_size,
+                              volume=volume,
+                              existing_ref=existing_ref)
 
-        existing_ref = {}
+            mock_client.assert_has_calls(
+                self.standard_login +
+                self.standard_logout)
 
-        self.assertRaises(exception.ManageExistingInvalidReference,
-                          self.driver.manage_existing_get_size,
-                          volume=volume,
-                          existing_ref=existing_ref)
+            existing_ref = {}
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.logout()
-        ]
+            self.assertRaises(exception.ManageExistingInvalidReference,
+                              self.driver.manage_existing_get_size,
+                              volume=volume,
+                              existing_ref=existing_ref)
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                self.standard_logout)
 
     def test_manage_existing_get_size_invalid_input(self):
         mock_client = self.setup_driver()
         mock_client.getVolume.side_effect = hpexceptions.HTTPNotFound('fake')
 
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-        volume = {}
-        existing_ref = {'source-name': unm_matcher}
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
+            volume = {}
+            existing_ref = {'source-name': unm_matcher}
 
-        self.assertRaises(exception.InvalidInput,
-                          self.driver.manage_existing_get_size,
-                          volume=volume,
-                          existing_ref=existing_ref)
+            self.assertRaises(exception.InvalidInput,
+                              self.driver.manage_existing_get_size,
+                              volume=volume,
+                              existing_ref=existing_ref)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(existing_ref['source-name']),
-            mock.call.logout()
-        ]
+            expected = [mock.call.getVolume(existing_ref['source-name'])]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_unmanage(self):
         mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            self.driver.unmanage(self.volume)
 
-        self.driver.unmanage(self.volume)
-
-        osv_matcher = self.driver.common._get_3par_vol_name(self.volume['id'])
-        unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.modifyVolume(osv_matcher, {'newName': unm_matcher}),
-            mock.call.logout()]
+            osv_matcher = common._get_3par_vol_name(self.volume['id'])
+            unm_matcher = common._get_3par_unm_name(self.volume['id'])
 
-        mock_client.assert_has_calls(expected)
+            expected = [
+                mock.call.modifyVolume(osv_matcher, {'newName': unm_matcher})
+            ]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test__safe_hostname(self):
         long_hostname = "abc123abc123abc123abc123abc123abc123"
@@ -2366,18 +2623,12 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
             driver=hpfcdriver.HP3PARFCDriver)
 
         expected = [
-            mock.call.setSSHOptions(
-                HP3PAR_SAN_IP,
-                HP3PAR_USER_NAME,
-                HP3PAR_USER_PASS,
-                privatekey=HP3PAR_SAN_SSH_PRIVATE,
-                port=HP3PAR_SAN_SSH_PORT,
-                conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+            mock.call.getCPG(HP3PAR_CPG2)]
+        mock_client.assert_has_calls(
+            self.standard_login +
+            expected +
+            self.standard_logout)
         mock_client.reset_mock()
         return mock_client
 
@@ -2406,7 +2657,11 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                                          'slot': 2},
                              'vendor': None,
                              'wwn': self.wwn[1]}]}]
-        mock_client.findHost.return_value = self.FAKE_HOST
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
         mock_client.getHostVLUNs.return_value = [
             {'active': True,
              'volumeName': self.VOLUME_3PAR_NAME,
@@ -2418,26 +2673,32 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                      'nsp': 'something'})
         mock_client.createVLUN.return_value = location
 
-        result = self.driver.initialize_connection(self.volume, self.connector)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.ANY,
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.getPorts(),
-            mock.call.createVLUN(
-                self.VOLUME_3PAR_NAME,
-                auto=True,
-                hostname=self.FAKE_HOST),
-            mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertDictMatch(result, self.properties)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            result = self.driver.initialize_connection(
+                self.volume,
+                self.connector)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.ANY,
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.getPorts(),
+                mock.call.createVLUN(
+                    self.VOLUME_3PAR_NAME,
+                    auto=True,
+                    hostname=self.FAKE_HOST),
+                mock.call.getHostVLUNs(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            self.assertDictMatch(result, self.properties)
 
     @mock.patch('cinder.zonemanager.utils.create_lookup_service')
     def test_initialize_connection_with_lookup_single_nsp(self, mock_lookup):
@@ -2467,7 +2728,11 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                                          'slot': 2},
                              'vendor': None,
                              'wwn': self.wwn[0]}]}]
-        mock_client.findHost.return_value = self.FAKE_HOST
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
         mock_client.getHostVLUNs.return_value = [
             {'active': True,
              'volumeName': self.VOLUME_3PAR_NAME,
@@ -2495,28 +2760,32 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                                          ['0987654321234']
                                          }}}
 
-        result = self.driver.initialize_connection(self.volume, connector)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.ANY,
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.getPorts(),
-            mock.call.getPorts(),
-            mock.call.createVLUN(
-                self.VOLUME_3PAR_NAME,
-                auto=True,
-                hostname=self.FAKE_HOST,
-                portPos={'node': 7, 'slot': 1, 'cardPort': 1}),
-            mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertDictMatch(result, expected_properties)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            result = self.driver.initialize_connection(self.volume, connector)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.ANY,
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.getPorts(),
+                mock.call.getPorts(),
+                mock.call.createVLUN(
+                    self.VOLUME_3PAR_NAME,
+                    auto=True,
+                    hostname=self.FAKE_HOST,
+                    portPos={'node': 7, 'slot': 1, 'cardPort': 1}),
+                mock.call.getHostVLUNs(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            self.assertDictMatch(result, expected_properties)
 
     def test_terminate_connection(self):
         # setup_mock_client drive with default configuration
@@ -2531,7 +2800,6 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getHostVLUNs.side_effect = effects
 
         expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
@@ -2539,35 +2807,46 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                 self.FAKE_HOST),
             mock.call.deleteHost(self.FAKE_HOST),
             mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.getPorts(),
-            mock.call.logout()]
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
-        self.assertIn('data', conn_info)
-        self.assertIn('initiator_target_map', conn_info['data'])
-        mock_client.reset_mock()
-
-        mock_client.getHostVLUNs.side_effect = effects
-
-        # mock some deleteHost exceptions that are handled
-        delete_with_vlun = hpexceptions.HTTPConflict(
-            error={'message': "has exported VLUN"})
-        delete_with_hostset = hpexceptions.HTTPConflict(
-            error={'message': "host is a member of a set"})
-        mock_client.deleteHost = mock.Mock(
-            side_effect=[delete_with_vlun, delete_with_hostset])
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
-        mock_client.reset_mock()
-        mock_client.getHostVLUNs.side_effect = effects
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
+            mock.call.getPorts()]
+
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertIn('data', conn_info)
+            self.assertIn('initiator_target_map', conn_info['data'])
+            mock_client.reset_mock()
+
+            mock_client.getHostVLUNs.side_effect = effects
+
+            # mock some deleteHost exceptions that are handled
+            delete_with_vlun = hpexceptions.HTTPConflict(
+                error={'message': "has exported VLUN"})
+            delete_with_hostset = hpexceptions.HTTPConflict(
+                error={'message': "host is a member of a set"})
+            mock_client.deleteHost = mock.Mock(
+                side_effect=[delete_with_vlun, delete_with_hostset])
+
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            mock_client.reset_mock()
+            mock_client.getHostVLUNs.side_effect = effects
+
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     @mock.patch('cinder.zonemanager.utils.create_lookup_service')
     def test_terminate_connection_with_lookup(self, mock_lookup):
@@ -2593,7 +2872,6 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getHostVLUNs.side_effect = effects
 
         expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
@@ -2601,35 +2879,46 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                 self.FAKE_HOST),
             mock.call.deleteHost(self.FAKE_HOST),
             mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.getPorts(),
-            mock.call.logout()]
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
-        self.assertIn('data', conn_info)
-        self.assertIn('initiator_target_map', conn_info['data'])
-        mock_client.reset_mock()
-
-        mock_client.getHostVLUNs.side_effect = effects
-
-        # mock some deleteHost exceptions that are handled
-        delete_with_vlun = hpexceptions.HTTPConflict(
-            error={'message': "has exported VLUN"})
-        delete_with_hostset = hpexceptions.HTTPConflict(
-            error={'message': "host is a member of a set"})
-        mock_client.deleteHost = mock.Mock(
-            side_effect=[delete_with_vlun, delete_with_hostset])
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
-        mock_client.reset_mock()
-        mock_client.getHostVLUNs.side_effect = effects
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expected)
+            mock.call.getPorts()]
+
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertIn('data', conn_info)
+            self.assertIn('initiator_target_map', conn_info['data'])
+            mock_client.reset_mock()
+
+            mock_client.getHostVLUNs.side_effect = effects
+
+            # mock some deleteHost exceptions that are handled
+            delete_with_vlun = hpexceptions.HTTPConflict(
+                error={'message': "has exported VLUN"})
+            delete_with_hostset = hpexceptions.HTTPConflict(
+                error={'message': "host is a member of a set"})
+            mock_client.deleteHost = mock.Mock(
+                side_effect=[delete_with_vlun, delete_with_hostset])
+
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            mock_client.reset_mock()
+            mock_client.getHostVLUNs.side_effect = effects
+
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
 
     def test_terminate_connection_more_vols(self):
         mock_client = self.setup_driver()
@@ -2645,19 +2934,23 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
             ]
 
         expect_less = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
                 None,
                 self.FAKE_HOST),
-            mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.logout()]
-
-        conn_info = self.driver.terminate_connection(self.volume,
-                                                     self.connector)
-        mock_client.assert_has_calls(expect_less)
-        self.assertNotIn('initiator_target_map', conn_info['data'])
+            mock.call.getHostVLUNs(self.FAKE_HOST)]
+
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            conn_info = self.driver.terminate_connection(self.volume,
+                                                         self.connector)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expect_less +
+                self.standard_logout)
+            self.assertNotIn('initiator_target_map', conn_info['data'])
 
     def test_get_volume_stats(self):
         # setup_mock_client drive with default configuration
@@ -2669,52 +2962,58 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
             'freeCapacityMiB': 1024.0 * 2,
             'totalCapacityMiB': 1024.0 * 123
         }
-        stats = self.driver.get_volume_stats(True)
-        const = 0.0009765625
-        self.assertEqual(stats['storage_protocol'], 'FC')
-        self.assertEqual(stats['total_capacity_gb'], 0)
-        self.assertEqual(stats['free_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
-        self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getStorageSystemInfo(),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
 
-        mock_client.assert_has_calls(expected)
-        stats = self.driver.get_volume_stats(True)
-        self.assertEqual(stats['storage_protocol'], 'FC')
-        self.assertEqual(stats['total_capacity_gb'], 0)
-        self.assertEqual(stats['free_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
-        self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
-
-        cpg2 = self.cpgs[0].copy()
-        cpg2.update({'SDGrowth': {'limitMiB': 8192}})
-        mock_client.getCPG.return_value = cpg2
-
-        stats = self.driver.get_volume_stats(True)
-        self.assertEqual(stats['storage_protocol'], 'FC')
-        total_capacity_gb = 8192 * const
-        self.assertEqual(stats['total_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['total_capacity_gb'],
-                         total_capacity_gb)
-        free_capacity_gb = int(
-            (8192 - self.cpgs[0]['UsrUsage']['usedMiB']) * const)
-        self.assertEqual(stats['free_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['free_capacity_gb'],
-                         free_capacity_gb)
-        self.driver.common.client.deleteCPG(HP3PAR_CPG)
-        self.driver.common.client.createCPG(HP3PAR_CPG, {})
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            stats = self.driver.get_volume_stats(True)
+            const = 0.0009765625
+            self.assertEqual(stats['storage_protocol'], 'FC')
+            self.assertEqual(stats['total_capacity_gb'], 0)
+            self.assertEqual(stats['free_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
+            self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
+
+            expected = [
+                mock.call.getStorageSystemInfo(),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getCPG(HP3PAR_CPG2)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            stats = self.driver.get_volume_stats(True)
+            self.assertEqual(stats['storage_protocol'], 'FC')
+            self.assertEqual(stats['total_capacity_gb'], 0)
+            self.assertEqual(stats['free_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
+            self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
+
+            cpg2 = self.cpgs[0].copy()
+            cpg2.update({'SDGrowth': {'limitMiB': 8192}})
+            mock_client.getCPG.return_value = cpg2
+
+            stats = self.driver.get_volume_stats(True)
+            self.assertEqual(stats['storage_protocol'], 'FC')
+            total_capacity_gb = 8192 * const
+            self.assertEqual(stats['total_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['total_capacity_gb'],
+                             total_capacity_gb)
+            free_capacity_gb = int(
+                (8192 - self.cpgs[0]['UsrUsage']['usedMiB']) * const)
+            self.assertEqual(stats['free_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['free_capacity_gb'],
+                             free_capacity_gb)
+            common.client.deleteCPG(HP3PAR_CPG)
+            common.client.createCPG(HP3PAR_CPG, {})
 
     def test_create_host(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
-
         mock_client.getVolume.return_value = {'userCPG': HP3PAR_CPG}
         mock_client.getCPG.return_value = {}
         mock_client.getHost.side_effect = [
@@ -2736,25 +3035,30 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                                          'slot': 2},
                              'vendor': None,
                              'wwn': self.wwn[1]}]}]
-        mock_client.findHost.return_value = None
+        mock_client.queryHost.return_value = None
         mock_client.getVLUN.return_value = {'lun': 186}
-
-        host = self.driver._create_host(self.volume, self.connector)
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(wwn='123456789012345'),
-            mock.call.findHost(wwn='123456789054321'),
-            mock.call.createHost(
-                self.FAKE_HOST,
-                FCWwns=['123456789012345', '123456789054321'],
-                optional={'domain': None, 'persona': 2}),
-            mock.call.getHost(self.FAKE_HOST)]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host = self.driver._create_host(
+                common,
+                self.volume,
+                self.connector)
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.queryHost(['123456789012345', '123456789054321']),
+                mock.call.createHost(
+                    self.FAKE_HOST,
+                    FCWwns=['123456789012345', '123456789054321'],
+                    optional={'domain': None, 'persona': 2}),
+                mock.call.getHost(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
 
     def test_create_invalid_host(self):
         # setup_mock_client drive with default configuration
@@ -2768,20 +3072,31 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                 'name': 'fakehost.foo',
                 'FCPaths': [{'wwn': '123456789012345'}, {
                     'wwn': '123456789054321'}]}]
-        mock_client.findHost.return_value = 'fakehost.foo'
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': 'fakehost.foo'
+            }]
+        }
 
-        host = self.driver._create_host(self.volume, self.connector)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host = self.driver._create_host(
+                common,
+                self.volume,
+                self.connector)
 
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost('fakehost'),
-            mock.call.findHost(wwn='123456789012345'),
-            mock.call.getHost('fakehost.foo')]
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost('fakehost'),
+                mock.call.queryHost(['123456789012345', '123456789054321']),
+                mock.call.getHost('fakehost.foo')]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        self.assertEqual(host['name'], 'fakehost.foo')
+            self.assertEqual(host['name'], 'fakehost.foo')
 
     def test_create_modify_host(self):
         # setup_mock_client drive with default configuration
@@ -2795,21 +3110,28 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                 'FCPaths': [{'wwn': '123456789012345'}, {
                     'wwn': '123456789054321'}]}]
 
-        host = self.driver._create_host(self.volume, self.connector)
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost('fakehost'),
-            mock.call.modifyHost(
-                'fakehost', {
-                    'FCWWNs': ['123456789012345', '123456789054321'],
-                    'pathOperation': 1}),
-            mock.call.getHost('fakehost')]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(len(host['FCPaths']), 2)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host = self.driver._create_host(
+                common,
+                self.volume,
+                self.connector)
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost('fakehost'),
+                mock.call.modifyHost(
+                    'fakehost', {
+                        'FCWWNs': ['123456789012345', '123456789054321'],
+                        'pathOperation': 1}),
+                mock.call.getHost('fakehost')]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(len(host['FCPaths']), 2)
 
     def test_modify_host_with_new_wwn(self):
         # setup_mock_client drive with default configuration
@@ -2826,21 +3148,28 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                         {'wwn': '123456789054321'}]}
         mock_client.getHost.side_effect = [getHost_ret1, getHost_ret2]
 
-        host = self.driver._create_host(self.volume, self.connector)
-
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost('fakehost'),
-            mock.call.modifyHost(
-                'fakehost', {
-                    'FCWWNs': ['123456789012345'], 'pathOperation': 1}),
-            mock.call.getHost('fakehost')]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(len(host['FCPaths']), 2)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host = self.driver._create_host(
+                common,
+                self.volume,
+                self.connector)
+
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost('fakehost'),
+                mock.call.modifyHost(
+                    'fakehost', {
+                        'FCWWNs': ['123456789012345'], 'pathOperation': 1}),
+                mock.call.getHost('fakehost')]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(len(host['FCPaths']), 2)
 
     def test_modify_host_with_unknown_wwn_and_new_wwn(self):
         # setup_mock_client drive with default configuration
@@ -2859,21 +3188,28 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                         {'wwn': 'xxxxxxxxxxxxxxx'}]}
         mock_client.getHost.side_effect = [getHost_ret1, getHost_ret2]
 
-        host = self.driver._create_host(self.volume, self.connector)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host = self.driver._create_host(
+                common,
+                self.volume,
+                self.connector)
 
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost('fakehost'),
-            mock.call.modifyHost(
-                'fakehost', {
-                    'FCWWNs': ['123456789012345'], 'pathOperation': 1}),
-            mock.call.getHost('fakehost')]
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost('fakehost'),
+                mock.call.modifyHost(
+                    'fakehost', {
+                        'FCWWNs': ['123456789012345'], 'pathOperation': 1}),
+                mock.call.getHost('fakehost')]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(len(host['FCPaths']), 3)
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(len(host['FCPaths']), 3)
 
 
 class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
@@ -2898,22 +3234,17 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             m_conf=mock_conf,
             driver=hpdriver.HP3PARISCSIDriver)
 
-        expected = [
-            mock.call.setSSHOptions(
-                HP3PAR_SAN_IP,
-                HP3PAR_USER_NAME,
-                HP3PAR_USER_PASS,
-                privatekey=HP3PAR_SAN_SSH_PRIVATE,
-                port=HP3PAR_SAN_SSH_PORT,
-                conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
+        expected_get_cpgs = [
             mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout(),
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getPorts(),
-            mock.call.logout()]
-        mock_client.assert_has_calls(expected)
+            mock.call.getCPG(HP3PAR_CPG2)]
+        expected_get_ports = [mock.call.getPorts()]
+        mock_client.assert_has_calls(
+            self.standard_login +
+            expected_get_cpgs +
+            self.standard_logout +
+            self.standard_login +
+            expected_get_ports +
+            self.standard_logout)
         mock_client.reset_mock()
 
         return mock_client
@@ -2939,26 +3270,32 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
                      'nsp': 'something'})
         mock_client.createVLUN.return_value = location
 
-        result = self.driver.initialize_connection(self.volume, self.connector)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume(self.VOLUME_3PAR_NAME),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.createVLUN(
-                self.VOLUME_3PAR_NAME,
-                auto=True,
-                hostname='fakehost',
-                portPos={'node': 8, 'slot': 1, 'cardPort': 1}),
-            mock.call.getHostVLUNs(self.FAKE_HOST),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertDictMatch(result, self.properties)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            result = self.driver.initialize_connection(
+                self.volume,
+                self.connector)
+
+            expected = [
+                mock.call.getVolume(self.VOLUME_3PAR_NAME),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.createVLUN(
+                    self.VOLUME_3PAR_NAME,
+                    auto=True,
+                    hostname='fakehost',
+                    portPos={'node': 8, 'slot': 1, 'cardPort': 1}),
+                mock.call.getHostVLUNs(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            self.assertDictMatch(result, self.properties)
 
     def test_get_volume_stats(self):
         # setup_mock_client drive with default configuration
@@ -2970,38 +3307,44 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'freeCapacityMiB': 1024.0 * 2,
             'totalCapacityMiB': 1024.0 * 123
         }
-        stats = self.driver.get_volume_stats(True)
-        const = 0.0009765625
-        self.assertEqual(stats['storage_protocol'], 'iSCSI')
-        self.assertEqual(stats['total_capacity_gb'], 0)
-        self.assertEqual(stats['free_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
-        self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
-
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getStorageSystemInfo(),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getCPG(HP3PAR_CPG2),
-            mock.call.logout()]
-
-        mock_client.assert_has_calls(expected)
 
-        cpg2 = self.cpgs[0].copy()
-        cpg2.update({'SDGrowth': {'limitMiB': 8192}})
-        mock_client.getCPG.return_value = cpg2
-
-        stats = self.driver.get_volume_stats(True)
-        self.assertEqual(stats['storage_protocol'], 'iSCSI')
-        total_capacity_gb = 8192 * const
-        self.assertEqual(stats['total_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['total_capacity_gb'],
-                         total_capacity_gb)
-        free_capacity_gb = int(
-            (8192 - self.cpgs[0]['UsrUsage']['usedMiB']) * const)
-        self.assertEqual(stats['free_capacity_gb'], 0)
-        self.assertEqual(stats['pools'][0]['free_capacity_gb'],
-                         free_capacity_gb)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+
+            stats = self.driver.get_volume_stats(True)
+            const = 0.0009765625
+            self.assertEqual(stats['storage_protocol'], 'iSCSI')
+            self.assertEqual(stats['total_capacity_gb'], 0)
+            self.assertEqual(stats['free_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['total_capacity_gb'], 123.0)
+            self.assertEqual(stats['pools'][0]['free_capacity_gb'], 2.0)
+
+            expected = [
+                mock.call.getStorageSystemInfo(),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getCPG(HP3PAR_CPG2)]
+
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+
+            cpg2 = self.cpgs[0].copy()
+            cpg2.update({'SDGrowth': {'limitMiB': 8192}})
+            mock_client.getCPG.return_value = cpg2
+
+            stats = self.driver.get_volume_stats(True)
+            self.assertEqual(stats['storage_protocol'], 'iSCSI')
+            total_capacity_gb = 8192 * const
+            self.assertEqual(stats['total_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['total_capacity_gb'],
+                             total_capacity_gb)
+            free_capacity_gb = int(
+                (8192 - self.cpgs[0]['UsrUsage']['usedMiB']) * const)
+            self.assertEqual(stats['free_capacity_gb'], 0)
+            self.assertEqual(stats['pools'][0]['free_capacity_gb'],
+                             free_capacity_gb)
 
     def test_create_host(self):
         # setup_mock_client drive with default configuration
@@ -3016,24 +3359,28 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.findHost.return_value = None
         mock_client.getVLUN.return_value = {'lun': self.TARGET_LUN}
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
-            mock.call.createHost(
-                self.FAKE_HOST,
-                optional={'domain': None, 'persona': 2},
-                iscsiNames=['iqn.1993-08.org.debian:01:222']),
-            mock.call.getHost(self.FAKE_HOST)]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(auth_username, None)
-        self.assertEqual(auth_password, None)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
+                mock.call.createHost(
+                    self.FAKE_HOST,
+                    optional={'domain': None, 'persona': 2},
+                    iscsiNames=['iqn.1993-08.org.debian:01:222']),
+                mock.call.getHost(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(auth_username, None)
+            self.assertEqual(auth_password, None)
 
     def test_create_host_chap_enabled(self):
         # setup_mock_client drive with CHAP enabled configuration
@@ -3067,32 +3414,36 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
 
         mock_client.getVolumeMetaData.side_effect = get_side_effect
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
-            mock.call.createHost(
-                self.FAKE_HOST,
-                optional={'domain': None, 'persona': 2},
-                iscsiNames=['iqn.1993-08.org.debian:01:222']),
-            mock.call.modifyHost(
-                'fakehost',
-                expected_mod_request),
-            mock.call.getHost(self.FAKE_HOST)
-        ]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
+                mock.call.createHost(
+                    self.FAKE_HOST,
+                    optional={'domain': None, 'persona': 2},
+                    iscsiNames=['iqn.1993-08.org.debian:01:222']),
+                mock.call.modifyHost(
+                    'fakehost',
+                    expected_mod_request),
+                mock.call.getHost(self.FAKE_HOST)
+            ]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(auth_username, 'test-user')
-        self.assertEqual(auth_password, 'test-pass')
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(auth_username, 'test-user')
+            self.assertEqual(auth_password, 'test-pass')
 
     def test_create_invalid_host(self):
         # setup_mock_client drive with default configuration
@@ -3105,21 +3456,25 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             {'name': 'fakehost.foo'}]
         mock_client.findHost.return_value = 'fakehost.foo'
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
 
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
-            mock.call.getHost('fakehost.foo')]
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
+                mock.call.getHost('fakehost.foo')]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        self.assertEqual(host['name'], 'fakehost.foo')
-        self.assertEqual(auth_username, None)
-        self.assertEqual(auth_password, None)
+            self.assertEqual(host['name'], 'fakehost.foo')
+            self.assertEqual(auth_username, None)
+            self.assertEqual(auth_password, None)
 
     def test_create_invalid_host_chap_enabled(self):
         # setup_mock_client drive with CHAP enabled configuration
@@ -3152,29 +3507,33 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'chapSecret': 'test-pass'
         }
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
-
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
-            mock.call.modifyHost(
-                'fakehost.foo',
-                expected_mod_request),
-            mock.call.getHost('fakehost.foo')
-        ]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
+
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
+                mock.call.modifyHost(
+                    'fakehost.foo',
+                    expected_mod_request),
+                mock.call.getHost('fakehost.foo')
+            ]
 
-        mock_client.assert_has_calls(expected)
+            mock_client.assert_has_calls(expected)
 
-        self.assertEqual(host['name'], 'fakehost.foo')
-        self.assertEqual(auth_username, 'test-user')
-        self.assertEqual(auth_password, 'test-pass')
+            self.assertEqual(host['name'], 'fakehost.foo')
+            self.assertEqual(auth_username, 'test-user')
+            self.assertEqual(auth_password, 'test-pass')
 
     def test_create_modify_host(self):
         # setup_mock_client drive with default configuration
@@ -3188,25 +3547,29 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
              'FCPaths': [{'wwn': '123456789012345'},
                          {'wwn': '123456789054321'}]}]
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
-
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.modifyHost(
-                self.FAKE_HOST,
-                {'pathOperation': 1,
-                    'iSCSINames': ['iqn.1993-08.org.debian:01:222']}),
-            mock.call.getHost(self.FAKE_HOST)]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(auth_username, None)
-        self.assertEqual(auth_password, None)
-        self.assertEqual(len(host['FCPaths']), 2)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
+
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.modifyHost(
+                    self.FAKE_HOST,
+                    {'pathOperation': 1,
+                        'iSCSINames': ['iqn.1993-08.org.debian:01:222']}),
+                mock.call.getHost(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(auth_username, None)
+            self.assertEqual(auth_password, None)
+            self.assertEqual(len(host['FCPaths']), 2)
 
     def test_create_modify_host_chap_enabled(self):
         # setup_mock_client drive with CHAP enabled configuration
@@ -3240,33 +3603,37 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'chapSecret': 'test-pass'
         }
 
-        host, auth_username, auth_password = self.driver._create_host(
-            self.volume, self.connector)
-
-        expected = [
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getCPG(HP3PAR_CPG),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
-            mock.call.getVolumeMetaData(
-                'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
-            mock.call.getHost(self.FAKE_HOST),
-            mock.call.modifyHost(
-                self.FAKE_HOST,
-                {'pathOperation': 1,
-                    'iSCSINames': ['iqn.1993-08.org.debian:01:222']}),
-            mock.call.modifyHost(
-                self.FAKE_HOST,
-                expected_mod_request
-            ),
-            mock.call.getHost(self.FAKE_HOST)]
-
-        mock_client.assert_has_calls(expected)
-
-        self.assertEqual(host['name'], self.FAKE_HOST)
-        self.assertEqual(auth_username, 'test-user')
-        self.assertEqual(auth_password, 'test-pass')
-        self.assertEqual(len(host['FCPaths']), 2)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            host, auth_username, auth_password = self.driver._create_host(
+                common, self.volume, self.connector)
+
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getCPG(HP3PAR_CPG),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_USER_KEY),
+                mock.call.getVolumeMetaData(
+                    'osv-0DM4qZEVSKON-DXN-NwVpw', CHAP_PASS_KEY),
+                mock.call.getHost(self.FAKE_HOST),
+                mock.call.modifyHost(
+                    self.FAKE_HOST,
+                    {'pathOperation': 1,
+                        'iSCSINames': ['iqn.1993-08.org.debian:01:222']}),
+                mock.call.modifyHost(
+                    self.FAKE_HOST,
+                    expected_mod_request
+                ),
+                mock.call.getHost(self.FAKE_HOST)]
+
+            mock_client.assert_has_calls(expected)
+
+            self.assertEqual(host['name'], self.FAKE_HOST)
+            self.assertEqual(auth_username, 'test-user')
+            self.assertEqual(auth_password, 'test-pass')
+            self.assertEqual(len(host['FCPaths']), 2)
 
     def test_get_least_used_nsp_for_host_single(self):
         # setup_mock_client drive with default configuration
@@ -3276,14 +3643,19 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getPorts.return_value = PORTS_RET
         mock_client.getVLUNs.return_value = VLUNS1_RET
 
-        #Setup a single ISCSI IP
-        iscsi_ips = ["10.10.220.253"]
-        self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        self.driver.initialize_iscsi_ports()
+            #Setup a single ISCSI IP
+            iscsi_ips = ["10.10.220.253"]
+            self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
 
-        nsp = self.driver._get_least_used_nsp_for_host('newhost')
-        self.assertEqual(nsp, "1:8:1")
+            self.driver.initialize_iscsi_ports(common)
+
+            nsp = self.driver._get_least_used_nsp_for_host(common, 'newhost')
+            self.assertEqual(nsp, "1:8:1")
 
     def test_get_least_used_nsp_for_host_new(self):
         # setup_mock_client drive with default configuration
@@ -3293,16 +3665,21 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getPorts.return_value = PORTS_RET
         mock_client.getVLUNs.return_value = VLUNS1_RET
 
-        #Setup two ISCSI IPs
-        iscsi_ips = ["10.10.220.252", "10.10.220.253"]
-        self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        self.driver.initialize_iscsi_ports()
+            #Setup two ISCSI IPs
+            iscsi_ips = ["10.10.220.252", "10.10.220.253"]
+            self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
 
-        # Host 'newhost' does not yet have any iscsi paths,
-        # so the 'least used' is returned
-        nsp = self.driver._get_least_used_nsp_for_host('newhost')
-        self.assertEqual(nsp, "1:8:2")
+            self.driver.initialize_iscsi_ports(common)
+
+            # Host 'newhost' does not yet have any iscsi paths,
+            # so the 'least used' is returned
+            nsp = self.driver._get_least_used_nsp_for_host(common, 'newhost')
+            self.assertEqual(nsp, "1:8:2")
 
     def test_get_least_used_nsp_for_host_reuse(self):
         # setup_mock_client drive with default configuration
@@ -3312,19 +3689,24 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getPorts.return_value = PORTS_RET
         mock_client.getVLUNs.return_value = VLUNS1_RET
 
-        #Setup two ISCSI IPs
-        iscsi_ips = ["10.10.220.252", "10.10.220.253"]
-        self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
 
-        self.driver.initialize_iscsi_ports()
+            #Setup two ISCSI IPs
+            iscsi_ips = ["10.10.220.252", "10.10.220.253"]
+            self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
 
-        # hosts 'foo' and 'bar' already have active iscsi paths
-        # the same one should be used
-        nsp = self.driver._get_least_used_nsp_for_host('foo')
-        self.assertEqual(nsp, "1:8:2")
+            self.driver.initialize_iscsi_ports(common)
 
-        nsp = self.driver._get_least_used_nsp_for_host('bar')
-        self.assertEqual(nsp, "1:8:1")
+            # hosts 'foo' and 'bar' already have active iscsi paths
+            # the same one should be used
+            nsp = self.driver._get_least_used_nsp_for_host(common, 'foo')
+            self.assertEqual(nsp, "1:8:2")
+
+            nsp = self.driver._get_least_used_nsp_for_host(common, 'bar')
+            self.assertEqual(nsp, "1:8:1")
 
     def test_get_least_used_nps_for_host_fc(self):
         # setup_mock_client drive with default configuration
@@ -3338,11 +3720,15 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         iscsi_ips = ["10.10.220.252", "10.10.220.253"]
         self.driver.configuration.hp3par_iscsi_ips = iscsi_ips
 
-        self.driver.initialize_iscsi_ports()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            self.driver.initialize_iscsi_ports(common)
 
-        nsp = self.driver._get_least_used_nsp_for_host('newhost')
-        self.assertNotEqual(nsp, "0:6:3")
-        self.assertEqual(nsp, "1:8:1")
+            nsp = self.driver._get_least_used_nsp_for_host(common, 'newhost')
+            self.assertNotEqual(nsp, "0:6:3")
+            self.assertEqual(nsp, "1:8:1")
 
     def test_invalid_iscsi_ip(self):
         config = self.setup_configuration()
@@ -3391,59 +3777,87 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True}]
         mock_client.getVLUNs.return_value = {'members': ports}
 
-        # in use count
-        vluns = self.driver.common.client.getVLUNs()
-        nsp = self.driver._get_least_used_nsp(vluns['members'],
-                                              ['0:2:1', '1:8:1'])
-        self.assertEqual(nsp, '1:8:1')
-
-        ports = [
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True}]
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            # in use count
+            vluns = common.client.getVLUNs()
+            nsp = self.driver._get_least_used_nsp(common, vluns['members'],
+                                                  ['0:2:1', '1:8:1'])
+            self.assertEqual(nsp, '1:8:1')
+
+            ports = [
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True}]
 
-        mock_client.getVLUNs.return_value = {'members': ports}
+            mock_client.getVLUNs.return_value = {'members': ports}
 
-        # in use count
-        vluns = self.driver.common.client.getVLUNs()
-        nsp = self.driver._get_least_used_nsp(vluns['members'],
-                                              ['0:2:1', '1:2:1'])
-        self.assertEqual(nsp, '1:2:1')
+            # in use count
+            common = self.driver._login()
+            vluns = common.client.getVLUNs()
+            nsp = self.driver._get_least_used_nsp(common, vluns['members'],
+                                                  ['0:2:1', '1:2:1'])
+            self.assertEqual(nsp, '1:2:1')
 
-        ports = [
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True},
-            {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1}, 'active': True}]
+            ports = [
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 1, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True},
+                {'portPos': {'node': 0, 'slot': 2, 'cardPort': 1},
+                 'active': True}]
 
-        mock_client.getVLUNs.return_value = {'members': ports}
+            mock_client.getVLUNs.return_value = {'members': ports}
 
-        # in use count
-        vluns = self.driver.common.client.getVLUNs()
-        nsp = self.driver._get_least_used_nsp(vluns['members'],
-                                              ['1:1:1', '1:2:1'])
-        self.assertEqual(nsp, '1:1:1')
+            # in use count
+            common = self.driver._login()
+            vluns = common.client.getVLUNs()
+            nsp = self.driver._get_least_used_nsp(common, vluns['members'],
+                                                  ['1:1:1', '1:2:1'])
+            self.assertEqual(nsp, '1:1:1')
 
     def test_set_3par_chaps(self):
         # setup_mock_client drive with default configuration
         # and return the mock HTTP 3PAR client
         mock_client = self.setup_driver()
 
-        expected = []
-        self.driver._set_3par_chaps(
-            'test-host', 'test-vol', 'test-host', 'pass')
-        mock_client.assert_has_calls(expected)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            expected = []
+            self.driver._set_3par_chaps(
+                common, 'test-host', 'test-vol', 'test-host', 'pass')
+            mock_client.assert_has_calls(expected)
 
         # setup_mock_client drive with CHAP enabled configuration
         # and return the mock HTTP 3PAR client
@@ -3451,19 +3865,23 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         config.hp3par_iscsi_chap_enabled = True
         mock_client = self.setup_driver(config=config)
 
-        expected_mod_request = {
-            'chapOperation': mock_client.HOST_EDIT_ADD,
-            'chapOperationMode': mock_client.CHAP_INITIATOR,
-            'chapName': 'test-host',
-            'chapSecret': 'fake'
-        }
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            expected_mod_request = {
+                'chapOperation': mock_client.HOST_EDIT_ADD,
+                'chapOperationMode': mock_client.CHAP_INITIATOR,
+                'chapName': 'test-host',
+                'chapSecret': 'fake'
+            }
 
-        expected = [
-            mock.call.modifyHost('test-host', expected_mod_request)
-        ]
-        self.driver._set_3par_chaps(
-            'test-host', 'test-vol', 'test-host', 'fake')
-        mock_client.assert_has_calls(expected)
+            expected = [
+                mock.call.modifyHost('test-host', expected_mod_request)
+            ]
+            self.driver._set_3par_chaps(
+                common, 'test-host', 'test-vol', 'test-host', 'fake')
+            mock_client.assert_has_calls(expected)
 
     @mock.patch('cinder.volume.utils.generate_password')
     def test_do_export(self, mock_utils):
@@ -3490,12 +3908,17 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
 
         expected = []
         expected_model = {'provider_auth': None}
-        model = self.driver._do_export(volume)
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_model, model)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            model = self.driver._do_export(common, volume)
 
-        mock_client.reset_mock()
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(expected_model, model)
+
+            mock_client.reset_mock()
 
         # setup_mock_client drive with CHAP enabled configuration
         # and return the mock HTTP 3PAR client
@@ -3532,9 +3955,13 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         ]
         expected_model = {'provider_auth': 'CHAP test-host random-pass'}
 
-        model = self.driver._do_export(volume)
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_model, model)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            model = self.driver._do_export(common, volume)
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(expected_model, model)
 
     @mock.patch('cinder.volume.utils.generate_password')
     def test_do_export_host_not_found(self, mock_utils):
@@ -3554,9 +3981,6 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'value': 'random-pass'
         }
 
-        config = self.setup_configuration()
-        config.hp3par_iscsi_chap_enabled = True
-
         expected = [
             mock.call.getHostVLUNs('test-host'),
             mock.call.setVolumeMetaData(
@@ -3566,9 +3990,13 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         ]
         expected_model = {'provider_auth': 'CHAP test-host random-pass'}
 
-        model = self.driver._do_export(volume)
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_model, model)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            model = self.driver._do_export(common, volume)
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(expected_model, model)
 
     @mock.patch('cinder.volume.utils.generate_password')
     def test_do_export_host_chap_disabled(self, mock_utils):
@@ -3595,11 +4023,6 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'value': 'random-pass'
         }
 
-        mock_client.reset_mock()
-
-        config = self.setup_configuration()
-        config.hp3par_iscsi_chap_enabled = True
-
         expected = [
             mock.call.getHostVLUNs('test-host'),
             mock.call.getHost('test-host'),
@@ -3612,9 +4035,13 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         ]
         expected_model = {'provider_auth': 'CHAP test-host random-pass'}
 
-        model = self.driver._do_export(volume)
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(expected_model, model)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            model = self.driver._do_export(common, volume)
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(expected_model, model)
 
     @mock.patch('cinder.volume.utils.generate_password')
     def test_do_export_no_active_vluns(self, mock_utils):
@@ -3651,9 +4078,13 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         ]
         expected_model = {'provider_auth': 'CHAP test-host random-pass'}
 
-        model = self.driver._do_export(volume)
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(model, expected_model)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+            model = self.driver._do_export(common, volume)
+            mock_client.assert_has_calls(expected)
+            self.assertEqual(model, expected_model)
 
     def test_ensure_export(self):
         # setup_mock_client drive with default configuration
@@ -3668,51 +4099,56 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'members': []
         }
 
-        model = self.driver.ensure_export(None, volume)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            model = self.driver.ensure_export(None, volume)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getAllVolumeMetaData('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.logout()
-        ]
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getAllVolumeMetaData('osv-0DM4qZEVSKON-DXN-NwVpw')
+            ]
 
-        expected_model = {'provider_auth': None}
+            expected_model = {'provider_auth': None}
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(model, expected_model)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(model, expected_model)
 
-        mock_client.getAllVolumeMetaData.return_value = {
-            'total': 2,
-            'members': [
-                {
-                    'creationTimeSec': 1406074222,
-                    'value': 'fake-host',
-                    'key': CHAP_USER_KEY,
-                    'creationTime8601': '2014-07-22T17:10:22-07:00'
-                },
-                {
-                    'creationTimeSec': 1406074222,
-                    'value': 'random-pass',
-                    'key': CHAP_PASS_KEY,
-                    'creationTime8601': '2014-07-22T17:10:22-07:00'
-                }
-            ]
-        }
+            mock_client.getAllVolumeMetaData.return_value = {
+                'total': 2,
+                'members': [
+                    {
+                        'creationTimeSec': 1406074222,
+                        'value': 'fake-host',
+                        'key': CHAP_USER_KEY,
+                        'creationTime8601': '2014-07-22T17:10:22-07:00'
+                    },
+                    {
+                        'creationTimeSec': 1406074222,
+                        'value': 'random-pass',
+                        'key': CHAP_PASS_KEY,
+                        'creationTime8601': '2014-07-22T17:10:22-07:00'
+                    }
+                ]
+            }
 
-        model = self.driver.ensure_export(None, volume)
+            model = self.driver.ensure_export(None, volume)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.getAllVolumeMetaData('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.logout()
-        ]
+            expected = [
+                mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
+                mock.call.getAllVolumeMetaData('osv-0DM4qZEVSKON-DXN-NwVpw')
+            ]
 
-        expected_model = {'provider_auth': "CHAP fake-host random-pass"}
+            expected_model = {'provider_auth': "CHAP fake-host random-pass"}
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(model, expected_model)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(model, expected_model)
 
     def test_ensure_export_missing_volume(self):
         # setup_mock_client drive with default configuration
@@ -3725,18 +4161,20 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         mock_client.getVolume.side_effect = hpexceptions.HTTPNotFound(
             'fake')
 
-        model = self.driver.ensure_export(None, volume)
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            model = self.driver.ensure_export(None, volume)
 
-        expected = [
-            mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
-            mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
-            mock.call.logout()
-        ]
+            expected = [mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw')]
 
-        expected_model = None
+            expected_model = None
 
-        mock_client.assert_has_calls(expected)
-        self.assertEqual(model, expected_model)
+            mock_client.assert_has_calls(
+                self.standard_login +
+                expected +
+                self.standard_logout)
+            self.assertEqual(model, expected_model)
 
     @mock.patch.object(volume_types, 'get_volume_type')
     def test_get_volume_settings_default_pool(self, _mock_volume_types):
@@ -3744,19 +4182,27 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
             'name': 'gold',
             'id': 'gold-id',
             'extra_specs': {}}
-        self.setup_driver()
-        volume = {'host': 'test-host@3pariscsi#pool_foo',
-                  'id': 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'}
-        pool = volume_utils.extract_host(volume['host'], 'pool')
-        model = self.driver.common.get_volume_settings_from_type_id('gold-id',
-                                                                    pool)
-        self.assertEqual(model['cpg'], 'pool_foo')
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            volume = {'host': 'test-host@3pariscsi#pool_foo',
+                      'id': 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'}
+            pool = volume_utils.extract_host(volume['host'], 'pool')
+            model = common.get_volume_settings_from_type_id('gold-id', pool)
+            self.assertEqual(model['cpg'], 'pool_foo')
 
     def test_get_model_update(self):
-        self.setup_driver()
-        model_update = self.driver.common._get_model_update('xxx@yyy#zzz',
-                                                            'CPG')
-        self.assertEqual(model_update, {'host': 'xxx@yyy#CPG'})
+        mock_client = self.setup_driver()
+        with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
+                as mock_create_client:
+            mock_create_client.return_value = mock_client
+            common = self.driver._login()
+
+            model_update = common._get_model_update('xxx@yyy#zzz', 'CPG')
+            self.assertEqual(model_update, {'host': 'xxx@yyy#CPG'})
 
 VLUNS5_RET = ({'members':
                [{'portPos': {'node': 0, 'slot': 8, 'cardPort': 2},
index e1e7bc01a040947ab00c16699b176f8c5bc61bb0..0ea4876e577ecd4a89f476483176f5bd19ed650a 100644 (file)
@@ -158,10 +158,11 @@ class HP3PARCommon(object):
         2.0.25 - Migrate without losing type settings bug #1356608
         2.0.26 - Don't ignore extra-specs snap_cpg when missing cpg #1368972
         2.0.27 - Fixing manage source-id error bug #1357075
+        2.0.28 - Removing locks bug #1381190
 
     """
 
-    VERSION = "2.0.27"
+    VERSION = "2.0.28"
 
     stats = {}
 
@@ -199,6 +200,7 @@ class HP3PARCommon(object):
         self.config = config
         self.hosts_naming_dict = dict()
         self.client = None
+        self.uuid = uuid.uuid4()
 
     def get_version(self):
         return self.VERSION
@@ -222,27 +224,6 @@ class HP3PARCommon(object):
             LOG.error(ex_msg)
             raise exception.InvalidInput(reason=ex_msg)
 
-        if client_version < MIN_CLIENT_SSH_ARGS_VERSION:
-            cl.setSSHOptions(self.config.san_ip,
-                             self.config.san_login,
-                             self.config.san_password,
-                             port=self.config.san_ssh_port,
-                             conn_timeout=self.config.ssh_conn_timeout,
-                             privatekey=self.config.san_private_key)
-        else:
-            known_hosts_file = CONF.ssh_hosts_key_file
-            policy = "AutoAddPolicy"
-            if CONF.strict_ssh_host_key_policy:
-                policy = "RejectPolicy"
-            cl.setSSHOptions(self.config.san_ip,
-                             self.config.san_login,
-                             self.config.san_password,
-                             port=self.config.san_ssh_port,
-                             conn_timeout=self.config.ssh_conn_timeout,
-                             privatekey=self.config.san_private_key,
-                             missing_key_policy=policy,
-                             known_hosts_file=known_hosts_file)
-
         return cl
 
     def client_login(self):
@@ -256,9 +237,35 @@ class HP3PARCommon(object):
             LOG.error(msg)
             raise exception.InvalidInput(reason=msg)
 
+        client_version = hp3parclient.version
+
+        if client_version < MIN_CLIENT_SSH_ARGS_VERSION:
+            self.client.setSSHOptions(
+                self.config.san_ip,
+                self.config.san_login,
+                self.config.san_password,
+                port=self.config.san_ssh_port,
+                conn_timeout=self.config.ssh_conn_timeout,
+                privatekey=self.config.san_private_key)
+        else:
+            known_hosts_file = CONF.ssh_hosts_key_file
+            policy = "AutoAddPolicy"
+            if CONF.strict_ssh_host_key_policy:
+                policy = "RejectPolicy"
+            self.client.setSSHOptions(
+                self.config.san_ip,
+                self.config.san_login,
+                self.config.san_password,
+                port=self.config.san_ssh_port,
+                conn_timeout=self.config.ssh_conn_timeout,
+                privatekey=self.config.san_private_key,
+                missing_key_policy=policy,
+                known_hosts_file=known_hosts_file)
+
     def client_logout(self):
+        LOG.info(_LI("Disconnect from 3PAR REST and SSH %s") % self.uuid)
         self.client.logout()
-        LOG.debug("Disconnect from 3PAR")
+        LOG.info(_LI("logout Done %s") % self.uuid)
 
     def do_setup(self, context):
         if hp3parclient is None:
@@ -274,8 +281,8 @@ class HP3PARCommon(object):
         if self.config.hp3par_debug:
             self.client.debug_rest(True)
 
+    def check_for_setup_error(self):
         self.client_login()
-
         try:
             cpg_names = self.config.hp3par_cpg
             for cpg_name in cpg_names:
index 981dc42485ae2b5468b02d66bd346f815ed849cc..66b80858828c1359e29f2c70370a21b48e2cbfa5 100644 (file)
@@ -34,10 +34,11 @@ try:
 except ImportError:
     hpexceptions = None
 
+import pprint
+
 from cinder import exception
-from cinder.i18n import _, _LI
+from cinder.i18n import _, _LI, _LW
 from cinder.openstack.common import log as logging
-from cinder import utils
 import cinder.volume.driver
 from cinder.volume.drivers.san.hp import hp_3par_common as hpcommon
 from cinder.volume.drivers.san import san
@@ -72,14 +73,14 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         2.0.8 - Fixing missing login/logout around attach/detach bug #1367429
         2.0.9 - Add support for pools with model update
         2.0.10 - Migrate without losing type settings bug #1356608
+        2.0.11 - Removing locks bug #1381190
 
     """
 
-    VERSION = "2.0.10"
+    VERSION = "2.0.11"
 
     def __init__(self, *args, **kwargs):
         super(HP3PARFCDriver, self).__init__(*args, **kwargs)
-        self.common = None
         self.configuration.append_config_values(hpcommon.hp3par_opts)
         self.configuration.append_config_values(san.san_opts)
         self.lookup_service = fczm_utils.create_lookup_service()
@@ -87,18 +88,26 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
     def _init_common(self):
         return hpcommon.HP3PARCommon(self.configuration)
 
-    def _check_flags(self):
+    def _login(self):
+        common = self._init_common()
+        common.do_setup(None)
+        common.client_login()
+        return common
+
+    def _logout(self, common):
+        common.client_logout()
+
+    def _check_flags(self, common):
         """Sanity check to ensure we have required options set."""
         required_flags = ['hp3par_api_url', 'hp3par_username',
                           'hp3par_password',
                           'san_ip', 'san_login', 'san_password']
-        self.common.check_flags(self.configuration, required_flags)
+        common.check_flags(self.configuration, required_flags)
 
-    @utils.synchronized('3par', external=True)
     def get_volume_stats(self, refresh):
-        self.common.client_login()
+        common = self._login()
         try:
-            stats = self.common.get_volume_stats(refresh)
+            stats = common.get_volume_stats(refresh)
             stats['storage_protocol'] = 'FC'
             stats['driver_version'] = self.VERSION
             backend_name = self.configuration.safe_get('volume_backend_name')
@@ -106,72 +115,65 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
                                             self.__class__.__name__)
             return stats
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     def do_setup(self, context):
-        self.common = self._init_common()
-        self._check_flags()
-        self.common.do_setup(context)
+        common = self._init_common()
+        common.do_setup(context)
+        self._check_flags(common)
+        common.check_for_setup_error()
 
     def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
+        """Setup errors are already checked for in do_setup so return pass."""
+        pass
 
-    @utils.synchronized('3par', external=True)
     def create_volume(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_volume(volume)
+            return common.create_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_cloned_volume(self, volume, src_vref):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_cloned_volume(volume, src_vref)
+            return common.create_cloned_volume(volume, src_vref)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def delete_volume(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.delete_volume(volume)
+            common.delete_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_volume_from_snapshot(self, volume, snapshot):
         """Create a volume from a snapshot.
 
         TODO: support using the size from the user.
         """
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_volume_from_snapshot(volume,
-                                                           snapshot)
+            return common.create_volume_from_snapshot(volume, snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_snapshot(self, snapshot):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.create_snapshot(snapshot)
+            common.create_snapshot(snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def delete_snapshot(self, snapshot):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.delete_snapshot(snapshot)
+            common.delete_snapshot(snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     @fczm_utils.AddFCZone
-    @utils.synchronized('3par', external=True)
     def initialize_connection(self, volume, connector):
         """Assigns the volume to a server.
 
@@ -209,25 +211,25 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
           * Create a VLUN for that HOST with the volume we want to export.
 
         """
-        self.common.client_login()
+        common = self._login()
         try:
             # we have to make sure we have a host
-            host = self._create_host(volume, connector)
+            host = self._create_host(common, volume, connector)
 
             target_wwns, init_targ_map, numPaths = \
-                self._build_initiator_target_map(connector)
+                self._build_initiator_target_map(common, connector)
 
             # now that we have a host, create the VLUN
             if self.lookup_service is not None and numPaths == 1:
                 nsp = None
-                active_fc_port_list = self.common.get_active_fc_target_ports()
+                active_fc_port_list = common.get_active_fc_target_ports()
                 for port in active_fc_port_list:
                     if port['portWWN'].lower() == target_wwns[0].lower():
                         nsp = port['nsp']
                         break
-                vlun = self.common.create_vlun(volume, host, nsp)
+                vlun = common.create_vlun(volume, host, nsp)
             else:
-                vlun = self.common.create_vlun(volume, host)
+                vlun = common.create_vlun(volume, host)
 
             info = {'driver_volume_type': 'fibre_channel',
                     'data': {'target_lun': vlun['lun'],
@@ -236,42 +238,41 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
                              'initiator_target_map': init_targ_map}}
             return info
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     @fczm_utils.RemoveFCZone
-    @utils.synchronized('3par', external=True)
     def terminate_connection(self, volume, connector, **kwargs):
         """Driver entry point to unattach a volume from an instance."""
-        self.common.client_login()
+        common = self._login()
         try:
-            hostname = self.common._safe_hostname(connector['host'])
-            self.common.terminate_connection(volume, hostname,
-                                             wwn=connector['wwpns'])
+            hostname = common._safe_hostname(connector['host'])
+            common.terminate_connection(volume, hostname,
+                                        wwn=connector['wwpns'])
 
             info = {'driver_volume_type': 'fibre_channel',
                     'data': {}}
 
             try:
-                self.common.client.getHostVLUNs(hostname)
+                common.client.getHostVLUNs(hostname)
             except hpexceptions.HTTPNotFound:
                 # No more exports for this host.
                 LOG.info(_LI("Need to remove FC Zone, building initiator "
                              "target map"))
 
                 target_wwns, init_targ_map, _numPaths = \
-                    self._build_initiator_target_map(connector)
+                    self._build_initiator_target_map(common, connector)
 
                 info['data'] = {'target_wwn': target_wwns,
                                 'initiator_target_map': init_targ_map}
             return info
 
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    def _build_initiator_target_map(self, connector):
+    def _build_initiator_target_map(self, common, connector):
         """Build the target_wwns and the initiator target map."""
 
-        fc_ports = self.common.get_active_fc_target_ports()
+        fc_ports = common.get_active_fc_target_ports()
         all_target_wwns = []
         target_wwns = []
         init_targ_map = {}
@@ -308,7 +309,8 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
 
         return target_wwns, init_targ_map, numPaths
 
-    def _create_3par_fibrechan_host(self, hostname, wwns, domain, persona_id):
+    def _create_3par_fibrechan_host(self, common, hostname, wwns,
+                                    domain, persona_id):
         """Create a 3PAR host.
 
         Create a 3PAR host, if there is already a host on the 3par using
@@ -317,48 +319,50 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         """
         # first search for an existing host
         host_found = None
-        for wwn in wwns:
-            host_found = self.common.client.findHost(wwn=wwn)
-            if host_found is not None:
-                break
+        hosts = common.client.queryHost(wwns)
+
+        LOG.warn(_LW("Found HOSTS %s") % pprint.pformat(hosts))
+        if hosts and hosts['members']:
+            host_found = hosts['members'][0]['name']
 
         if host_found is not None:
-            self.common.hosts_naming_dict[hostname] = host_found
+            common.hosts_naming_dict[hostname] = host_found
             return host_found
         else:
             persona_id = int(persona_id)
-            self.common.client.createHost(hostname, FCWwns=wwns,
-                                          optional={'domain': domain,
-                                                    'persona': persona_id})
+            common.client.createHost(hostname, FCWwns=wwns,
+                                     optional={'domain': domain,
+                                               'persona': persona_id})
             return hostname
 
-    def _modify_3par_fibrechan_host(self, hostname, wwn):
-        mod_request = {'pathOperation': self.common.client.HOST_EDIT_ADD,
+    def _modify_3par_fibrechan_host(self, common, hostname, wwn):
+        mod_request = {'pathOperation': common.client.HOST_EDIT_ADD,
                        'FCWWNs': wwn}
 
-        self.common.client.modifyHost(hostname, mod_request)
+        common.client.modifyHost(hostname, mod_request)
 
-    def _create_host(self, volume, connector):
+    def _create_host(self, common, volume, connector):
         """Creates or modifies existing 3PAR host."""
         host = None
-        hostname = self.common._safe_hostname(connector['host'])
-        cpg = self.common.get_cpg(volume, allowSnap=True)
-        domain = self.common.get_domain(cpg)
+        hostname = common._safe_hostname(connector['host'])
+        cpg = common.get_cpg(volume, allowSnap=True)
+        domain = common.get_domain(cpg)
         try:
-            host = self.common._get_3par_host(hostname)
+            host = common._get_3par_host(hostname)
         except hpexceptions.HTTPNotFound:
             # get persona from the volume type extra specs
-            persona_id = self.common.get_persona_type(volume)
+            persona_id = common.get_persona_type(volume)
             # host doesn't exist, we have to create it
-            hostname = self._create_3par_fibrechan_host(hostname,
+            hostname = self._create_3par_fibrechan_host(common,
+                                                        hostname,
                                                         connector['wwpns'],
                                                         domain,
                                                         persona_id)
-            host = self.common._get_3par_host(hostname)
+            host = common._get_3par_host(hostname)
 
-        return self._add_new_wwn_to_host(host, connector['wwpns'])
+        return self._add_new_wwn_to_host(common, host, connector['wwpns'])
 
-    def _add_new_wwn_to_host(self, host, wwns):
+    def _add_new_wwn_to_host(self, common, host, wwns):
         """Add wwns to a host if one or more don't exist.
 
         Identify if argument wwns contains any world wide names
@@ -383,85 +387,71 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         # if any wwns found that were not in host list,
         # add them to the host
         if (len(new_wwns) > 0):
-            self._modify_3par_fibrechan_host(host['name'], new_wwns)
-            host = self.common._get_3par_host(host['name'])
+            self._modify_3par_fibrechan_host(common, host['name'], new_wwns)
+            host = common._get_3par_host(host['name'])
         return host
 
-    @utils.synchronized('3par', external=True)
     def create_export(self, context, volume):
         pass
 
-    @utils.synchronized('3par', external=True)
     def ensure_export(self, context, volume):
         pass
 
-    @utils.synchronized('3par', external=True)
     def remove_export(self, context, volume):
         pass
 
-    @utils.synchronized('3par', external=True)
     def extend_volume(self, volume, new_size):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.extend_volume(volume, new_size)
+            common.extend_volume(volume, new_size)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def manage_existing(self, volume, existing_ref):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.manage_existing(volume, existing_ref)
+            return common.manage_existing(volume, existing_ref)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def manage_existing_get_size(self, volume, existing_ref):
-        self.common.client_login()
+        common = self._login()
         try:
-            size = self.common.manage_existing_get_size(volume, existing_ref)
+            return common.manage_existing_get_size(volume, existing_ref)
         finally:
-            self.common.client_logout()
-
-        return size
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def unmanage(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.unmanage(volume)
+            common.unmanage(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def attach_volume(self, context, volume, instance_uuid, host_name,
                       mountpoint):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.attach_volume(volume, instance_uuid)
+            common.attach_volume(volume, instance_uuid)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def detach_volume(self, context, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.detach_volume(volume)
+            common.detach_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def retype(self, context, volume, new_type, diff, host):
         """Convert the volume to be of the new type."""
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.retype(volume, new_type, diff, host)
+            return common.retype(volume, new_type, diff, host)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def migrate_volume(self, context, volume, host):
-
         if volume['status'] == 'in-use':
             protocol = host['capabilities']['storage_protocol']
             if protocol != 'FC':
@@ -469,19 +459,19 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
                           "to a host with storage_protocol=%s." % protocol)
                 return False, None
 
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.migrate_volume(volume, host)
+            return common.migrate_volume(volume, host)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     def get_pool(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.get_cpg(volume)
+            return common.get_cpg(volume)
         except hpexceptions.HTTPNotFound:
             reason = (_("Volume %s doesn't exist on array.") % volume)
             LOG.error(reason)
             raise exception.InvalidVolume(reason)
         finally:
-            self.common.client_logout()
+            self._logout(common)
index 6f1d673bf5f25ae42af4a9e93484ef98669bbb29..376749d1b5a8659ac69b797abb063e05d8331332 100644 (file)
@@ -38,7 +38,6 @@ except ImportError:
 from cinder import exception
 from cinder.i18n import _, _LE
 from cinder.openstack.common import log as logging
-from cinder import utils
 import cinder.volume.driver
 from cinder.volume.drivers.san.hp import hp_3par_common as hpcommon
 from cinder.volume.drivers.san import san
@@ -76,32 +75,40 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         2.0.6 - Fixing missing login/logout around attach/detach bug #1367429
         2.0.7 - Add support for pools with model update
         2.0.8 - Migrate without losing type settings bug #1356608
+        2.0.9 - Removing locks bug #1381190
 
     """
 
-    VERSION = "2.0.8"
+    VERSION = "2.0.9"
 
     def __init__(self, *args, **kwargs):
         super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
-        self.common = None
         self.configuration.append_config_values(hpcommon.hp3par_opts)
         self.configuration.append_config_values(san.san_opts)
 
     def _init_common(self):
         return hpcommon.HP3PARCommon(self.configuration)
 
-    def _check_flags(self):
+    def _login(self):
+        common = self._init_common()
+        common.do_setup(None)
+        common.client_login()
+        return common
+
+    def _logout(self, common):
+        common.client_logout()
+
+    def _check_flags(self, common):
         """Sanity check to ensure we have required options set."""
         required_flags = ['hp3par_api_url', 'hp3par_username',
                           'hp3par_password', 'san_ip', 'san_login',
                           'san_password']
-        self.common.check_flags(self.configuration, required_flags)
+        common.check_flags(self.configuration, required_flags)
 
-    @utils.synchronized('3par', external=True)
     def get_volume_stats(self, refresh):
-        self.common.client_login()
+        common = self._login()
         try:
-            stats = self.common.get_volume_stats(refresh)
+            stats = common.get_volume_stats(refresh)
             stats['storage_protocol'] = 'iSCSI'
             stats['driver_version'] = self.VERSION
             backend_name = self.configuration.safe_get('volume_backend_name')
@@ -109,20 +116,21 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
                                             self.__class__.__name__)
             return stats
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     def do_setup(self, context):
-        self.common = self._init_common()
-        self._check_flags()
-        self.common.do_setup(context)
+        common = self._init_common()
+        common.do_setup(context)
+        self._check_flags(common)
+        common.check_for_setup_error()
 
-        self.common.client_login()
+        common.client_login()
         try:
-            self.initialize_iscsi_ports()
+            self.initialize_iscsi_ports(common)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    def initialize_iscsi_ports(self):
+    def initialize_iscsi_ports(self, common):
         # map iscsi_ip-> ip_port
         #             -> iqn
         #             -> nsp
@@ -153,7 +161,7 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         # get all the valid iSCSI ports from 3PAR
         # when found, add the valid iSCSI ip, ip port, iqn and nsp
         # to the iSCSI IP dictionary
-        iscsi_ports = self.common.get_active_iscsi_target_ports()
+        iscsi_ports = common.get_active_iscsi_target_ports()
 
         for port in iscsi_ports:
             ip = port['IPAddr']
@@ -184,64 +192,56 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
             raise exception.InvalidInput(reason=(msg))
 
     def check_for_setup_error(self):
-        """Returns an error if prerequisites aren't met."""
-        self._check_flags()
+        """Setup errors are already checked for in do_setup so return pass."""
+        pass
 
-    @utils.synchronized('3par', external=True)
     def create_volume(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_volume(volume)
+            return common.create_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_cloned_volume(self, volume, src_vref):
         """Clone an existing volume."""
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_cloned_volume(volume, src_vref)
+            return common.create_cloned_volume(volume, src_vref)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def delete_volume(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.delete_volume(volume)
+            common.delete_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_volume_from_snapshot(self, volume, snapshot):
         """Creates a volume from a snapshot.
 
         TODO: support using the size from the user.
         """
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.create_volume_from_snapshot(volume,
-                                                           snapshot)
+            return common.create_volume_from_snapshot(volume, snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def create_snapshot(self, snapshot):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.create_snapshot(snapshot)
+            common.create_snapshot(snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def delete_snapshot(self, snapshot):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.delete_snapshot(snapshot)
+            common.delete_snapshot(snapshot)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def initialize_connection(self, volume, connector):
         """Assigns the volume to a server.
 
@@ -267,14 +267,19 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
           * Create a host on the 3par
           * create vlun on the 3par
         """
-        self.common.client_login()
+        common = self._login()
         try:
             # we have to make sure we have a host
-            host, username, password = self._create_host(volume, connector)
-            least_used_nsp = self._get_least_used_nsp_for_host(host['name'])
+            host, username, password = self._create_host(
+                common,
+                volume,
+                connector)
+            least_used_nsp = self._get_least_used_nsp_for_host(
+                common,
+                host['name'])
 
             # now that we have a host, create the VLUN
-            vlun = self.common.create_vlun(volume, host, least_used_nsp)
+            vlun = common.create_vlun(volume, host, least_used_nsp)
 
             if least_used_nsp is None:
                 msg = _("Least busy iSCSI port not found, "
@@ -302,42 +307,44 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
 
             return info
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def terminate_connection(self, volume, connector, **kwargs):
         """Driver entry point to unattach a volume from an instance."""
-        self.common.client_login()
+        common = self._login()
         try:
-            hostname = self.common._safe_hostname(connector['host'])
-            self.common.terminate_connection(volume, hostname,
-                                             iqn=connector['initiator'])
-            self._clear_chap_3par(volume)
+            hostname = common._safe_hostname(connector['host'])
+            common.terminate_connection(
+                volume,
+                hostname,
+                iqn=connector['initiator'])
+            self._clear_chap_3par(common, volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    def _clear_chap_3par(self, volume):
+    def _clear_chap_3par(self, common, volume):
         """Clears CHAP credentials on a 3par volume.
 
         Ignore exceptions caused by the keys not being present on a volume.
         """
-        vol_name = self.common._get_3par_vol_name(volume['id'])
+        vol_name = common._get_3par_vol_name(volume['id'])
 
         try:
-            self.common.client.removeVolumeMetaData(vol_name, CHAP_USER_KEY)
+            common.client.removeVolumeMetaData(vol_name, CHAP_USER_KEY)
         except hpexceptions.HTTPNotFound:
             pass
         except Exception:
             raise
 
         try:
-            self.common.client.removeVolumeMetaData(vol_name, CHAP_PASS_KEY)
+            common.client.removeVolumeMetaData(vol_name, CHAP_PASS_KEY)
         except hpexceptions.HTTPNotFound:
             pass
         except Exception:
             raise
 
-    def _create_3par_iscsi_host(self, hostname, iscsi_iqn, domain, persona_id):
+    def _create_3par_iscsi_host(self, common, hostname, iscsi_iqn, domain,
+                                persona_id):
         """Create a 3PAR host.
 
         Create a 3PAR host, if there is already a host on the 3par using
@@ -345,9 +352,9 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         used by 3PAR.
         """
         # first search for an existing host
-        host_found = self.common.client.findHost(iqn=iscsi_iqn)
+        host_found = common.client.findHost(iqn=iscsi_iqn)
         if host_found is not None:
-            self.common.hosts_naming_dict[hostname] = host_found
+            common.hosts_naming_dict[hostname] = host_found
             return host_found
         else:
             if isinstance(iscsi_iqn, str) or isinstance(iscsi_iqn, unicode):
@@ -355,73 +362,86 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
             else:
                 iqn = iscsi_iqn
             persona_id = int(persona_id)
-            self.common.client.createHost(hostname, iscsiNames=iqn,
-                                          optional={'domain': domain,
-                                                    'persona': persona_id})
+            common.client.createHost(hostname, iscsiNames=iqn,
+                                     optional={'domain': domain,
+                                               'persona': persona_id})
             return hostname
 
-    def _modify_3par_iscsi_host(self, hostname, iscsi_iqn):
-        mod_request = {'pathOperation': self.common.client.HOST_EDIT_ADD,
+    def _modify_3par_iscsi_host(self, common, hostname, iscsi_iqn):
+        mod_request = {'pathOperation': common.client.HOST_EDIT_ADD,
                        'iSCSINames': [iscsi_iqn]}
 
-        self.common.client.modifyHost(hostname, mod_request)
+        common.client.modifyHost(hostname, mod_request)
 
-    def _set_3par_chaps(self, hostname, volume, username, password):
+    def _set_3par_chaps(self, common, hostname, volume, username, password):
         """Sets a 3PAR host's CHAP credentials."""
         if not self.configuration.hp3par_iscsi_chap_enabled:
             return
 
-        mod_request = {'chapOperation': self.common.client.HOST_EDIT_ADD,
-                       'chapOperationMode': self.common.client.CHAP_INITIATOR,
+        mod_request = {'chapOperation': common.client.HOST_EDIT_ADD,
+                       'chapOperationMode': common.client.CHAP_INITIATOR,
                        'chapName': username,
                        'chapSecret': password}
-        self.common.client.modifyHost(hostname, mod_request)
+        common.client.modifyHost(hostname, mod_request)
 
-    def _create_host(self, volume, connector):
+    def _create_host(self, common, volume, connector):
         """Creates or modifies existing 3PAR host."""
         # make sure we don't have the host already
         host = None
         username = None
         password = None
-        hostname = self.common._safe_hostname(connector['host'])
-        cpg = self.common.get_cpg(volume, allowSnap=True)
-        domain = self.common.get_domain(cpg)
+        hostname = common._safe_hostname(connector['host'])
+        cpg = common.get_cpg(volume, allowSnap=True)
+        domain = common.get_domain(cpg)
 
         # Get the CHAP secret if CHAP is enabled
         if self.configuration.hp3par_iscsi_chap_enabled:
-            vol_name = self.common._get_3par_vol_name(volume['id'])
-            username = self.common.client.getVolumeMetaData(
+            vol_name = common._get_3par_vol_name(volume['id'])
+            username = common.client.getVolumeMetaData(
                 vol_name, CHAP_USER_KEY)['value']
-            password = self.common.client.getVolumeMetaData(
+            password = common.client.getVolumeMetaData(
                 vol_name, CHAP_PASS_KEY)['value']
 
         try:
-            host = self.common._get_3par_host(hostname)
+            host = common._get_3par_host(hostname)
         except hpexceptions.HTTPNotFound:
             # get persona from the volume type extra specs
-            persona_id = self.common.get_persona_type(volume)
+            persona_id = common.get_persona_type(volume)
             # host doesn't exist, we have to create it
-            hostname = self._create_3par_iscsi_host(hostname,
+            hostname = self._create_3par_iscsi_host(common,
+                                                    hostname,
                                                     connector['initiator'],
                                                     domain,
                                                     persona_id)
-            self._set_3par_chaps(hostname, volume, username, password)
-            host = self.common._get_3par_host(hostname)
+            self._set_3par_chaps(common, hostname, volume, username, password)
+            host = common._get_3par_host(hostname)
         else:
             if 'iSCSIPaths' not in host or len(host['iSCSIPaths']) < 1:
-                self._modify_3par_iscsi_host(hostname, connector['initiator'])
-                self._set_3par_chaps(hostname, volume, username, password)
-                host = self.common._get_3par_host(hostname)
+                self._modify_3par_iscsi_host(
+                    common, hostname,
+                    connector['initiator'])
+                self._set_3par_chaps(
+                    common,
+                    hostname,
+                    volume,
+                    username,
+                    password)
+                host = common._get_3par_host(hostname)
             elif (not host['initiatorChapEnabled'] and
                     self.configuration.hp3par_iscsi_chap_enabled):
                 LOG.warn(_("Host exists without CHAP credentials set and has "
                            "iSCSI attachments but CHAP is enabled.  Updating "
                            "host with new CHAP credentials."))
-                self._set_3par_chaps(hostname, volume, username, password)
+                self._set_3par_chaps(
+                    common,
+                    hostname,
+                    volume,
+                    username,
+                    password)
 
         return host, username, password
 
-    def _do_export(self, volume):
+    def _do_export(self, common, volume):
         """Gets the associated account, generates CHAP info and updates."""
         model_update = {}
 
@@ -435,10 +455,10 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         chap_password = None
         try:
             # Get all active VLUNs for the host
-            vluns = self.common.client.getHostVLUNs(chap_username)
+            vluns = common.client.getHostVLUNs(chap_username)
 
             # Host has active VLUNs... is CHAP enabled on host?
-            host_info = self.common.client.getHost(chap_username)
+            host_info = common.client.getHost(chap_username)
 
             if not host_info['initiatorChapEnabled']:
                 LOG.warn(_("Host has no CHAP key, but CHAP is enabled."))
@@ -464,7 +484,7 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
                 if ('remoteName' in vlun and
                         re.match('iqn.*', vlun['remoteName'])):
                     try:
-                        chap_password = self.common.client.getVolumeMetaData(
+                        chap_password = common.client.getVolumeMetaData(
                             vlun['volumeName'], CHAP_PASS_KEY)['value']
                         chap_exists = True
                         break
@@ -481,10 +501,10 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
                            "Generating new CHAP key."))
 
         # Add CHAP credentials to the volume metadata
-        vol_name = self.common._get_3par_vol_name(volume['id'])
-        self.common.client.setVolumeMetaData(
+        vol_name = common._get_3par_vol_name(volume['id'])
+        common.client.setVolumeMetaData(
             vol_name, CHAP_USER_KEY, chap_username)
-        self.common.client.setVolumeMetaData(
+        common.client.setVolumeMetaData(
             vol_name, CHAP_PASS_KEY, chap_password)
 
         model_update['provider_auth'] = ('CHAP %s %s' %
@@ -492,28 +512,26 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
 
         return model_update
 
-    @utils.synchronized('3par', external=True)
     def create_export(self, context, volume):
+        common = self._login()
         try:
-            self.common.client_login()
-            return self._do_export(volume)
+            return self._do_export(common, volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def ensure_export(self, context, volume):
         """Ensure the volume still exists on the 3PAR.
 
         Also retrieves CHAP credentials, if present on the volume
         """
+        common = self._login()
         try:
-            self.common.client_login()
-            vol_name = self.common._get_3par_vol_name(volume['id'])
-            self.common.client.getVolume(vol_name)
+            vol_name = common._get_3par_vol_name(volume['id'])
+            common.client.getVolume(vol_name)
         except hpexceptions.HTTPNotFound:
             LOG.error(_LE("Volume %s doesn't exist on array.") % vol_name)
         else:
-            metadata = self.common.client.getAllVolumeMetaData(vol_name)
+            metadata = common.client.getAllVolumeMetaData(vol_name)
 
             username = None
             password = None
@@ -532,13 +550,12 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
 
             return model_update
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def remove_export(self, context, volume):
         pass
 
-    def _get_least_used_nsp_for_host(self, hostname):
+    def _get_least_used_nsp_for_host(self, common, hostname):
         """Get the least used NSP for the current host.
 
         Steps to determine which NSP to use.
@@ -553,17 +570,18 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
             return iscsi_nsps[0]
 
         # Try to reuse an existing iscsi path to the host
-        vluns = self.common.client.getVLUNs()
+        vluns = common.client.getVLUNs()
         for vlun in vluns['members']:
             if vlun['active']:
                 if vlun['hostname'] == hostname:
-                    temp_nsp = self.common.build_nsp(vlun['portPos'])
+                    temp_nsp = common.build_nsp(vlun['portPos'])
                     if temp_nsp in iscsi_nsps:
                         # this host already has an iscsi path, so use it
                         return temp_nsp
 
         # Calculate the least used iscsi nsp
-        least_used_nsp = self._get_least_used_nsp(vluns['members'],
+        least_used_nsp = self._get_least_used_nsp(common,
+                                                  vluns['members'],
                                                   self._get_iscsi_nsps())
         return least_used_nsp
 
@@ -580,7 +598,7 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
             if value['nsp'] == nsp:
                 return key
 
-    def _get_least_used_nsp(self, vluns, nspss):
+    def _get_least_used_nsp(self, common, vluns, nspss):
         """"Return the nsp that has the fewest active vluns."""
         # return only the nsp (node:server:port)
         # count the number of nsps
@@ -593,7 +611,7 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
 
         for vlun in vluns:
             if vlun['active']:
-                nsp = self.common.build_nsp(vlun['portPos'])
+                nsp = common.build_nsp(vlun['portPos'])
                 if nsp in nsp_counts:
                     nsp_counts[nsp] = nsp_counts[nsp] + 1
 
@@ -606,69 +624,58 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
 
         return current_least_used_nsp
 
-    @utils.synchronized('3par', external=True)
     def extend_volume(self, volume, new_size):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.extend_volume(volume, new_size)
+            common.extend_volume(volume, new_size)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def manage_existing(self, volume, existing_ref):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.manage_existing(volume, existing_ref)
+            return common.manage_existing(volume, existing_ref)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def manage_existing_get_size(self, volume, existing_ref):
-        self.common.client_login()
+        common = self._login()
         try:
-            size = self.common.manage_existing_get_size(volume, existing_ref)
+            return common.manage_existing_get_size(volume, existing_ref)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-        return size
-
-    @utils.synchronized('3par', external=True)
     def unmanage(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.unmanage(volume)
+            common.unmanage(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def attach_volume(self, context, volume, instance_uuid, host_name,
                       mountpoint):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.attach_volume(volume, instance_uuid)
+            common.attach_volume(volume, instance_uuid)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def detach_volume(self, context, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            self.common.detach_volume(volume)
+            common.detach_volume(volume)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def retype(self, context, volume, new_type, diff, host):
         """Convert the volume to be of the new type."""
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.retype(volume, new_type, diff, host)
+            return common.retype(volume, new_type, diff, host)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
-    @utils.synchronized('3par', external=True)
     def migrate_volume(self, context, volume, host):
-
         if volume['status'] == 'in-use':
             protocol = host['capabilities']['storage_protocol']
             if protocol != 'iSCSI':
@@ -676,19 +683,19 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
                           "to a host with storage_protocol=%s." % protocol)
                 return False, None
 
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.migrate_volume(volume, host)
+            return common.migrate_volume(volume, host)
         finally:
-            self.common.client_logout()
+            self._logout(common)
 
     def get_pool(self, volume):
-        self.common.client_login()
+        common = self._login()
         try:
-            return self.common.get_cpg(volume)
+            return common.get_cpg(volume)
         except hpexceptions.HTTPNotFound:
             reason = (_("Volume %s doesn't exist on array.") % volume)
             LOG.error(reason)
             raise exception.InvalidVolume(reason)
         finally:
-            self.common.client_logout()
+            self._logout(common)