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:
Walter A. Boring IV
2015-07-08 09:25:07 -07:00
parent d71f5da3a6
commit 98c4249cf4
3 changed files with 40 additions and 13 deletions

View File

@@ -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):

View File

@@ -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."""

View File

@@ -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'))