Added ABCMeta class to the InitiatorConnector
This patch adds python ABCMeta class to the InitiatorConnector for the purposes of defining a required contract that all Connector objects must adhere to. Currently, the existing required methods of connect_volume, disconnect_volume are the 2 required methods that must be implemented by the child Connector objects. This will be helpful for future features and forcing Connectors to adhere to the API interface Contract. Change-Id: Ie862ad7f358a70d57eddb2bce269230df3c3cdc7 Implements: blueprint os-brick-abc-connectors
This commit is contained in:
@@ -20,6 +20,7 @@ The connectors here are responsible for discovering and removing volumes for
|
||||
each of the supported transport protocols.
|
||||
"""
|
||||
|
||||
import abc
|
||||
import copy
|
||||
import os
|
||||
import platform
|
||||
@@ -106,6 +107,7 @@ def get_connector_properties(root_helper, my_ip, multipath, enforce_multipath,
|
||||
return props
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class InitiatorConnector(executor.Executor):
|
||||
def __init__(self, root_helper, driver=None,
|
||||
execute=putils.execute,
|
||||
@@ -232,21 +234,36 @@ class InitiatorConnector(executor.Executor):
|
||||
return False
|
||||
return True
|
||||
|
||||
@abc.abstractmethod
|
||||
def connect_volume(self, connection_properties):
|
||||
"""Connect to a volume.
|
||||
|
||||
The connection_properties describes the information needed by
|
||||
the specific protocol to use to make the connection.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def disconnect_volume(self, connection_properties, device_info):
|
||||
"""Disconnect a volume from the local host.
|
||||
|
||||
The connection_properties are the same as from connect_volume.
|
||||
The device_info is returned from connect_volume.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
pass
|
||||
|
||||
|
||||
class FakeConnector(InitiatorConnector):
|
||||
|
||||
fake_path = '/dev/vdFAKE'
|
||||
|
||||
def connect_volume(self, connection_properties):
|
||||
fake_device_info = {'type': 'fake',
|
||||
'path': self.fake_path}
|
||||
return fake_device_info
|
||||
|
||||
def disconnect_volume(self, connection_properties, device_info):
|
||||
pass
|
||||
|
||||
|
||||
class ISCSIConnector(InitiatorConnector):
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import testtools
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
from oslo_log import log as oslo_logging
|
||||
from oslo_utils import strutils
|
||||
from oslotest import base
|
||||
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestCase(base.BaseTestCase):
|
||||
class TestCase(testtools.TestCase):
|
||||
|
||||
"""Test case base class for all unit tests."""
|
||||
|
||||
|
||||
@@ -112,15 +112,25 @@ class ConnectorTestCase(base.TestCase):
|
||||
self.cmds.append(" ".join(cmd))
|
||||
return "", None
|
||||
|
||||
def fake_connection(self):
|
||||
return {
|
||||
'driver_volume_type': 'fake',
|
||||
'data': {
|
||||
'volume_id': 'fake_volume_id',
|
||||
'target_portal': 'fake_location',
|
||||
'target_iqn': 'fake_iqn',
|
||||
'target_lun': 1,
|
||||
}
|
||||
}
|
||||
|
||||
def test_connect_volume(self):
|
||||
self.connector = connector.InitiatorConnector(None)
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.connector.connect_volume, None)
|
||||
self.connector = connector.FakeConnector(None)
|
||||
device_info = self.connector.connect_volume(self.fake_connection())
|
||||
self.assertIn('type', device_info)
|
||||
self.assertIn('path', device_info)
|
||||
|
||||
def test_disconnect_volume(self):
|
||||
self.connector = connector.InitiatorConnector(None)
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.connector.disconnect_volume, None, None)
|
||||
self.connector = connector.FakeConnector(None)
|
||||
|
||||
def test_factory(self):
|
||||
obj = connector.InitiatorConnector.factory('iscsi', None)
|
||||
@@ -158,13 +168,13 @@ class ConnectorTestCase(base.TestCase):
|
||||
"bogus", None)
|
||||
|
||||
def test_check_valid_device_with_wrong_path(self):
|
||||
self.connector = connector.InitiatorConnector(None)
|
||||
self.connector = connector.FakeConnector(None)
|
||||
self.connector._execute = \
|
||||
lambda *args, **kwargs: ("", None)
|
||||
self.assertFalse(self.connector.check_valid_device('/d0v'))
|
||||
|
||||
def test_check_valid_device(self):
|
||||
self.connector = connector.InitiatorConnector(None)
|
||||
self.connector = connector.FakeConnector(None)
|
||||
self.connector._execute = \
|
||||
lambda *args, **kwargs: ("", "")
|
||||
self.assertTrue(self.connector.check_valid_device('/dev'))
|
||||
@@ -172,7 +182,7 @@ class ConnectorTestCase(base.TestCase):
|
||||
def test_check_valid_device_with_cmd_error(self):
|
||||
def raise_except(*args, **kwargs):
|
||||
raise putils.ProcessExecutionError
|
||||
self.connector = connector.InitiatorConnector(None)
|
||||
self.connector = connector.FakeConnector(None)
|
||||
with mock.patch.object(self.connector, '_execute',
|
||||
side_effect=putils.ProcessExecutionError):
|
||||
self.assertFalse(self.connector.check_valid_device('/dev'))
|
||||
|
||||
Reference in New Issue
Block a user