eliminate the need for hp3parclient in tests
In order to eliminate the need to have the hp3parclient in the global-requirements project, we need to remove the hp3parclient from being imported in all 3par driver unit tests in cinder. Closes-Bug: #1315195 Change-Id: Ife5c70871e742be5970be8f0284e12554f93cab4
This commit is contained in:
parent
4726b6543c
commit
541cc9d53a
27
cinder/tests/fake_hp_3par_client.py
Normal file
27
cinder/tests/fake_hp_3par_client.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
"""Fake HP client for testing 3PAR without installing the client."""
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from cinder.tests import fake_hp_client_exceptions as hpexceptions
|
||||||
|
|
||||||
|
hp3par = mock.Mock()
|
||||||
|
hp3par.version = "3.0.0"
|
||||||
|
hp3par.exceptions = hpexceptions
|
||||||
|
|
||||||
|
sys.modules['hp3parclient'] = hp3par
|
57
cinder/tests/fake_hp_client_exceptions.py
Normal file
57
cinder/tests/fake_hp_client_exceptions.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
"""Fake HP client exceptions to use when mocking HP clients."""
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPConflict(Exception):
|
||||||
|
http_status = 409
|
||||||
|
message = "Conflict"
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPNotFound(Exception):
|
||||||
|
http_status = 404
|
||||||
|
message = "Not found"
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPForbidden(Exception):
|
||||||
|
http_status = 403
|
||||||
|
message = "Forbidden"
|
||||||
|
|
||||||
|
def __init__(self, error=None):
|
||||||
|
if error:
|
||||||
|
if 'code' in error:
|
||||||
|
self._error_code = error['code']
|
||||||
|
|
||||||
|
def get_code(self):
|
||||||
|
return self._error_code
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPBadRequest(Exception):
|
||||||
|
http_status = 400
|
||||||
|
message = "Bad request"
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPServerError(Exception):
|
||||||
|
http_status = 500
|
||||||
|
message = "Error"
|
||||||
|
|
||||||
|
def __init__(self, error=None):
|
||||||
|
if error:
|
||||||
|
if 'message' in error:
|
||||||
|
self._error_desc = error['message']
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
return self._error_desc
|
@ -17,19 +17,20 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from hp3parclient import client
|
|
||||||
from hp3parclient import exceptions as hpexceptions
|
|
||||||
|
|
||||||
from cinder import context
|
from cinder import context
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder.openstack.common import log as logging
|
from cinder.openstack.common import log as logging
|
||||||
from cinder import test
|
from cinder import test
|
||||||
from cinder import units
|
from cinder import units
|
||||||
|
|
||||||
|
from cinder.tests import fake_hp_3par_client as hp3parclient
|
||||||
from cinder.volume.drivers.san.hp import hp_3par_fc as hpfcdriver
|
from cinder.volume.drivers.san.hp import hp_3par_fc as hpfcdriver
|
||||||
from cinder.volume.drivers.san.hp import hp_3par_iscsi as hpdriver
|
from cinder.volume.drivers.san.hp import hp_3par_iscsi as hpdriver
|
||||||
from cinder.volume import qos_specs
|
from cinder.volume import qos_specs
|
||||||
from cinder.volume import volume_types
|
from cinder.volume import volume_types
|
||||||
|
|
||||||
|
hpexceptions = hp3parclient.hpexceptions
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
HP3PAR_CPG = 'OpenStackCPG'
|
HP3PAR_CPG = 'OpenStackCPG'
|
||||||
@ -157,6 +158,18 @@ class HP3PARBaseDriver(object):
|
|||||||
'state': 1,
|
'state': 1,
|
||||||
'uuid': '29c214aa-62b9-41c8-b198-543f6cf24edf'}]
|
'uuid': '29c214aa-62b9-41c8-b198-543f6cf24edf'}]
|
||||||
|
|
||||||
|
mock_client_conf = {
|
||||||
|
'PORT_MODE_TARGET': 2,
|
||||||
|
'PORT_STATE_READY': 4,
|
||||||
|
'PORT_PROTO_ISCSI': 2,
|
||||||
|
'PORT_PROTO_FC': 1,
|
||||||
|
'TASK_DONE': 1,
|
||||||
|
'HOST_EDIT_ADD': 1,
|
||||||
|
'getPorts.return_value': {
|
||||||
|
'members': FAKE_FC_PORTS + [FAKE_ISCSI_PORT]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def setup_configuration(self):
|
def setup_configuration(self):
|
||||||
configuration = mock.Mock()
|
configuration = mock.Mock()
|
||||||
configuration.hp3par_debug = False
|
configuration.hp3par_debug = False
|
||||||
@ -181,15 +194,15 @@ class HP3PARBaseDriver(object):
|
|||||||
@mock.patch(
|
@mock.patch(
|
||||||
'hp3parclient.client.HP3ParClient',
|
'hp3parclient.client.HP3ParClient',
|
||||||
spec=True,
|
spec=True,
|
||||||
PORT_MODE_TARGET=client.HP3ParClient.PORT_MODE_TARGET,
|
)
|
||||||
PORT_STATE_READY=client.HP3ParClient.PORT_STATE_READY,
|
|
||||||
PORT_PROTO_ISCSI=client.HP3ParClient.PORT_PROTO_ISCSI,
|
|
||||||
PORT_PROTO_FC=client.HP3ParClient.PORT_PROTO_FC,
|
|
||||||
TASK_DONE=client.HP3ParClient.TASK_DONE,
|
|
||||||
HOST_EDIT_ADD=client.HP3ParClient.HOST_EDIT_ADD)
|
|
||||||
def setup_mock_client(self, _m_client, driver, conf=None, m_conf=None):
|
def setup_mock_client(self, _m_client, driver, conf=None, m_conf=None):
|
||||||
|
|
||||||
_m_client = _m_client.return_value
|
_m_client = _m_client.return_value
|
||||||
|
|
||||||
|
# Configure the base constants, defaults etc...
|
||||||
|
_m_client.configure_mock(**self.mock_client_conf)
|
||||||
|
|
||||||
|
# If m_conf, drop those over the top of the base_conf.
|
||||||
if m_conf is not None:
|
if m_conf is not None:
|
||||||
_m_client.configure_mock(**m_conf)
|
_m_client.configure_mock(**m_conf)
|
||||||
|
|
||||||
@ -304,8 +317,6 @@ class HP3PARBaseDriver(object):
|
|||||||
def test_migrate_volume(self):
|
def test_migrate_volume(self):
|
||||||
|
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getStorageSystemInfo.return_value': {
|
'getStorageSystemInfo.return_value': {
|
||||||
'serialNumber': '1234'},
|
'serialNumber': '1234'},
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
@ -356,8 +367,6 @@ class HP3PARBaseDriver(object):
|
|||||||
|
|
||||||
def test_migrate_volume_diff_host(self):
|
def test_migrate_volume_diff_host(self):
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getStorageSystemInfo.return_value': {
|
'getStorageSystemInfo.return_value': {
|
||||||
'serialNumber': 'different'},
|
'serialNumber': 'different'},
|
||||||
}
|
}
|
||||||
@ -383,8 +392,6 @@ class HP3PARBaseDriver(object):
|
|||||||
|
|
||||||
def test_migrate_volume_diff_domain(self):
|
def test_migrate_volume_diff_domain(self):
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getStorageSystemInfo.return_value': {
|
'getStorageSystemInfo.return_value': {
|
||||||
'serialNumber': '1234'},
|
'serialNumber': '1234'},
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
@ -413,16 +420,8 @@ class HP3PARBaseDriver(object):
|
|||||||
self.assertEqual((False, None), result)
|
self.assertEqual((False, None), result)
|
||||||
|
|
||||||
def test_migrate_volume_attached(self):
|
def test_migrate_volume_attached(self):
|
||||||
conf = {
|
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getStorageSystemInfo.return_value': {
|
|
||||||
'serialNumber': '1234'},
|
|
||||||
'getTask.return_value': {
|
|
||||||
'status': 1}
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_client = self.setup_driver(mock_conf=conf)
|
mock_client = self.setup_driver()
|
||||||
|
|
||||||
volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
|
volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
|
||||||
'id': HP3PARBaseDriver.CLONE_ID,
|
'id': HP3PARBaseDriver.CLONE_ID,
|
||||||
@ -596,8 +595,6 @@ class HP3PARBaseDriver(object):
|
|||||||
# setup_mock_client drive with default configuration
|
# setup_mock_client drive with default configuration
|
||||||
# and return the mock HTTP 3PAR client
|
# and return the mock HTTP 3PAR client
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
'status': 1},
|
'status': 1},
|
||||||
'copyVolume.return_value': {'taskid': 1},
|
'copyVolume.return_value': {'taskid': 1},
|
||||||
@ -641,8 +638,6 @@ class HP3PARBaseDriver(object):
|
|||||||
# setup_mock_client drive with default configuration
|
# setup_mock_client drive with default configuration
|
||||||
# and return the mock HTTP 3PAR client
|
# and return the mock HTTP 3PAR client
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
'status': 4,
|
'status': 4,
|
||||||
'failure message': 'out of disk space'},
|
'failure message': 'out of disk space'},
|
||||||
@ -787,8 +782,6 @@ class HP3PARBaseDriver(object):
|
|||||||
def test_extend_volume_non_base(self):
|
def test_extend_volume_non_base(self):
|
||||||
extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
|
extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
'status': 1},
|
'status': 1},
|
||||||
'getCPG.return_value': {},
|
'getCPG.return_value': {},
|
||||||
@ -810,8 +803,6 @@ class HP3PARBaseDriver(object):
|
|||||||
def test_extend_volume_non_base_failure(self):
|
def test_extend_volume_non_base_failure(self):
|
||||||
extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
|
extend_ex = hpexceptions.HTTPForbidden(error={'code': 150})
|
||||||
conf = {
|
conf = {
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]},
|
|
||||||
'getTask.return_value': {
|
'getTask.return_value': {
|
||||||
'status': 1},
|
'status': 1},
|
||||||
'getCPG.return_value': {},
|
'getCPG.return_value': {},
|
||||||
@ -1019,8 +1010,6 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||||||
{'active': True,
|
{'active': True,
|
||||||
'volumeName': self.VOLUME_3PAR_NAME,
|
'volumeName': self.VOLUME_3PAR_NAME,
|
||||||
'lun': 90, 'type': 0}]
|
'lun': 90, 'type': 0}]
|
||||||
mock_client.getPorts.return_value = {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}
|
|
||||||
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
|
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
|
||||||
{'volume_name': self.VOLUME_3PAR_NAME,
|
{'volume_name': self.VOLUME_3PAR_NAME,
|
||||||
'lun_id': 90,
|
'lun_id': 90,
|
||||||
@ -1057,8 +1046,6 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||||||
{'active': True,
|
{'active': True,
|
||||||
'volumeName': self.VOLUME_3PAR_NAME,
|
'volumeName': self.VOLUME_3PAR_NAME,
|
||||||
'lun': None, 'type': 0}]
|
'lun': None, 'type': 0}]
|
||||||
mock_client.getPorts.return_value = {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}
|
|
||||||
|
|
||||||
self.driver.terminate_connection(
|
self.driver.terminate_connection(
|
||||||
self.volume,
|
self.volume,
|
||||||
@ -1299,11 +1286,6 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
|
|||||||
def setup_driver(self, config=None, mock_conf=None):
|
def setup_driver(self, config=None, mock_conf=None):
|
||||||
|
|
||||||
self.ctxt = context.get_admin_context()
|
self.ctxt = context.get_admin_context()
|
||||||
# setup_mock_client default config, if necessary
|
|
||||||
if mock_conf is None:
|
|
||||||
mock_conf = {
|
|
||||||
'getPorts.return_value': {
|
|
||||||
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}}
|
|
||||||
|
|
||||||
mock_client = self.setup_mock_client(
|
mock_client = self.setup_mock_client(
|
||||||
conf=config,
|
conf=config,
|
||||||
|
@ -41,9 +41,12 @@ import pprint
|
|||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import hp3parclient
|
from cinder.openstack.common import importutils
|
||||||
from hp3parclient import client
|
hp3parclient = importutils.try_import("hp3parclient")
|
||||||
from hp3parclient import exceptions as hpexceptions
|
if hp3parclient:
|
||||||
|
from hp3parclient import client
|
||||||
|
from hp3parclient import exceptions as hpexceptions
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from cinder import context
|
from cinder import context
|
||||||
@ -124,10 +127,11 @@ class HP3PARCommon(object):
|
|||||||
2.0.8 - Fix detach issue for multiple hosts bug #1288927
|
2.0.8 - Fix detach issue for multiple hosts bug #1288927
|
||||||
2.0.9 - Remove unused 3PAR driver method bug #1310807
|
2.0.9 - Remove unused 3PAR driver method bug #1310807
|
||||||
2.0.10 - Fixed an issue with 3PAR vlun location bug #1315542
|
2.0.10 - Fixed an issue with 3PAR vlun location bug #1315542
|
||||||
|
2.0.11 - Remove hp3parclient requirement from unit tests #1315195
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "2.0.10"
|
VERSION = "2.0.11"
|
||||||
|
|
||||||
stats = {}
|
stats = {}
|
||||||
|
|
||||||
@ -209,6 +213,9 @@ class HP3PARCommon(object):
|
|||||||
LOG.debug("Disconnect from 3PAR")
|
LOG.debug("Disconnect from 3PAR")
|
||||||
|
|
||||||
def do_setup(self, context):
|
def do_setup(self, context):
|
||||||
|
if hp3parclient is None:
|
||||||
|
msg = _('You must install hp3parclient before using 3PAR drivers.')
|
||||||
|
raise exception.VolumeBackendAPIException(data=msg)
|
||||||
try:
|
try:
|
||||||
self.client = self._create_client()
|
self.client = self._create_client()
|
||||||
except hpexceptions.UnsupportedVersion as ex:
|
except hpexceptions.UnsupportedVersion as ex:
|
||||||
|
@ -29,7 +29,10 @@ Set the following in the cinder.conf file to enable the
|
|||||||
volume_driver=cinder.volume.drivers.san.hp.hp_3par_fc.HP3PARFCDriver
|
volume_driver=cinder.volume.drivers.san.hp.hp_3par_fc.HP3PARFCDriver
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from hp3parclient import exceptions as hpexceptions
|
try:
|
||||||
|
from hp3parclient import exceptions as hpexceptions
|
||||||
|
except ImportError:
|
||||||
|
hpexceptions = None
|
||||||
|
|
||||||
from cinder.openstack.common import log as logging
|
from cinder.openstack.common import log as logging
|
||||||
from cinder import utils
|
from cinder import utils
|
||||||
|
@ -29,7 +29,10 @@ volume_driver=cinder.volume.drivers.san.hp.hp_3par_iscsi.HP3PARISCSIDriver
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from hp3parclient import exceptions as hpexceptions
|
try:
|
||||||
|
from hp3parclient import exceptions as hpexceptions
|
||||||
|
except ImportError:
|
||||||
|
hpexceptions = None
|
||||||
|
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder.openstack.common import log as logging
|
from cinder.openstack.common import log as logging
|
||||||
|
@ -3,7 +3,6 @@ hacking>=0.8.0,<0.9
|
|||||||
coverage>=3.6
|
coverage>=3.6
|
||||||
discover
|
discover
|
||||||
fixtures>=0.3.14
|
fixtures>=0.3.14
|
||||||
hp3parclient>=3.0,<4.0
|
|
||||||
hplefthandclient>=1.0.0,<2.0.0
|
hplefthandclient>=1.0.0,<2.0.0
|
||||||
mock>=1.0
|
mock>=1.0
|
||||||
mox>=0.5.3
|
mox>=0.5.3
|
||||||
|
Loading…
Reference in New Issue
Block a user