summaryrefslogtreecommitdiffstats
path: root/test/test-controller.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-controller.py')
-rwxr-xr-xtest/test-controller.py302
1 files changed, 302 insertions, 0 deletions
diff --git a/test/test-controller.py b/test/test-controller.py
new file mode 100755
index 0000000..d33a6a2
--- /dev/null
+++ b/test/test-controller.py
@@ -0,0 +1,302 @@
+#!/usr/bin/python3
+import logging
+import unittest
+from staslib import conf, ctrl, timeparse, trid
+from pyfakefs.fake_filesystem_unittest import TestCase
+
+
+class TestController(ctrl.Controller):
+ def _find_existing_connection(self):
+ pass
+
+ def _on_aen(self, aen: int):
+ pass
+
+ def _on_nvme_event(self, nvme_event):
+ pass
+
+ def reload_hdlr(self):
+ pass
+
+
+class TestDc(ctrl.Dc):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self._connected = True
+
+ class Ctrl:
+ def __init__(this):
+ this.name = 'nvme666'
+
+ def connected(this):
+ return self._connected
+
+ def disconnect(this):
+ pass
+
+ self._ctrl = Ctrl()
+
+ def _find_existing_connection(self):
+ pass
+
+ def _on_aen(self, aen: int):
+ pass
+
+ def _on_nvme_event(self, nvme_event):
+ pass
+
+ def reload_hdlr(self):
+ pass
+
+ def set_connected(self, value):
+ self._connected = value
+
+ def connected(self):
+ return self._connected
+
+
+class TestStaf:
+ def is_avahi_reported(self, tid):
+ return False
+
+ def controller_unresponsive(self, tid):
+ pass
+
+ @property
+ def tron(self):
+ return True
+
+
+stafd_conf_1 = '''
+[Global]
+tron=false
+hdr-digest=false
+data-digest=false
+kato=30
+queue-size=128
+reconnect-delay=10
+ctrl-loss-tmo=600
+disable-sqflow=false
+ignore-iface=false
+ip-family=ipv4+ipv6
+pleo=enabled
+
+[Service Discovery]
+zeroconf=enabled
+
+[Discovery controller connection management]
+persistent-connections=true
+zeroconf-connections-persistence=10 seconds
+'''
+
+stafd_conf_2 = '''
+[Discovery controller connection management]
+zeroconf-connections-persistence=-1
+'''
+
+
+class Test(TestCase):
+ '''Unit tests for class Controller'''
+
+ def setUp(self):
+ self.setUpPyfakefs()
+
+ self.fs.create_file(
+ '/etc/nvme/hostnqn', contents='nqn.2014-08.org.nvmexpress:uuid:01234567-0123-0123-0123-0123456789ab\n'
+ )
+ self.fs.create_file('/etc/nvme/hostid', contents='01234567-89ab-cdef-0123-456789abcdef\n')
+ self.fs.create_file(
+ '/dev/nvme-fabrics',
+ contents='instance=-1,cntlid=-1,transport=%s,traddr=%s,trsvcid=%s,nqn=%s,queue_size=%d,nr_io_queues=%d,reconnect_delay=%d,ctrl_loss_tmo=%d,keep_alive_tmo=%d,hostnqn=%s,host_traddr=%s,host_iface=%s,hostid=%s,disable_sqflow,hdr_digest,data_digest,nr_write_queues=%d,nr_poll_queues=%d,tos=%d,fast_io_fail_tmo=%d,discovery,dhchap_secret=%s,dhchap_ctrl_secret=%s\n',
+ )
+
+ self.NVME_TID = trid.TID(
+ {
+ 'transport': 'tcp',
+ 'traddr': '10.10.10.10',
+ 'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
+ 'trsvcid': '8009',
+ 'host-traddr': '1.2.3.4',
+ 'host-iface': 'wlp0s20f3',
+ }
+ )
+
+ default_conf = {
+ ('Global', 'tron'): False,
+ ('Global', 'hdr-digest'): False,
+ ('Global', 'data-digest'): False,
+ ('Global', 'kato'): None, # None to let the driver decide the default
+ ('Global', 'queue-size'): None, # None to let the driver decide the default
+ ('Global', 'reconnect-delay'): None, # None to let the driver decide the default
+ ('Global', 'ctrl-loss-tmo'): None, # None to let the driver decide the default
+ ('Global', 'disable-sqflow'): None, # None to let the driver decide the default
+ ('Global', 'persistent-connections'): True,
+ ('Discovery controller connection management', 'persistent-connections'): True,
+ ('Discovery controller connection management', 'zeroconf-connections-persistence'): timeparse.timeparse(
+ '72hours'
+ ),
+ ('Global', 'ignore-iface'): False,
+ ('Global', 'ip-family'): (4, 6),
+ ('Global', 'pleo'): True,
+ ('Service Discovery', 'zeroconf'): True,
+ ('Controllers', 'controller'): list(),
+ ('Controllers', 'exclude'): list(),
+ }
+
+ self.stafd_conf_file1 = '/etc/stas/stafd1.conf'
+ self.fs.create_file(self.stafd_conf_file1, contents=stafd_conf_1)
+
+ self.stafd_conf_file2 = '/etc/stas/stafd2.conf'
+ self.fs.create_file(self.stafd_conf_file2, contents=stafd_conf_2)
+
+ self.svcconf = conf.SvcConf(default_conf=default_conf)
+ self.svcconf.set_conf_file(self.stafd_conf_file1)
+
+ def tearDown(self):
+ pass
+
+ def test_cannot_instantiate_concrete_classes_if_abstract_method_are_not_implemented(self):
+ # Make sure we can't instantiate the ABC directly (Abstract Base Class).
+ class Controller(ctrl.Controller):
+ pass
+
+ self.assertRaises(TypeError, lambda: ctrl.Controller(tid=self.NVME_TID))
+
+ def test_get_device(self):
+ controller = TestController(tid=self.NVME_TID, service=TestStaf())
+ self.assertEqual(controller._connect_attempts, 0)
+ controller._try_to_connect()
+ self.assertEqual(controller._connect_attempts, 1)
+ self.assertEqual(
+ controller.id, "(tcp, 10.10.10.10, 8009, nqn.1988-11.com.dell:SFSS:2:20220208134025e8, wlp0s20f3, 1.2.3.4)"
+ )
+ # raise Exception(controller._connect_op)
+ self.assertEqual(
+ str(controller.tid),
+ "(tcp, 10.10.10.10, 8009, nqn.1988-11.com.dell:SFSS:2:20220208134025e8, wlp0s20f3, 1.2.3.4)",
+ )
+ self.assertEqual(controller.device, 'nvme?')
+ self.assertEqual(
+ controller.controller_id_dict(),
+ {
+ 'transport': 'tcp',
+ 'traddr': '10.10.10.10',
+ 'trsvcid': '8009',
+ 'host-traddr': '1.2.3.4',
+ 'host-iface': 'wlp0s20f3',
+ 'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
+ 'device': 'nvme?',
+ },
+ )
+
+ self.assertEqual(
+ controller.info(),
+ {
+ 'transport': 'tcp',
+ 'traddr': '10.10.10.10',
+ 'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
+ 'trsvcid': '8009',
+ 'host-traddr': '1.2.3.4',
+ 'host-iface': 'wlp0s20f3',
+ 'device': 'nvme?',
+ 'connect attempts': '1',
+ 'retry connect timer': '60.0s [off]',
+ 'connect operation': "{'fail count': 0, 'completed': False, 'alive': True}",
+ },
+ )
+ self.assertEqual(
+ controller.details(),
+ {
+ 'dctype': '',
+ 'cntrltype': '',
+ 'connected': 'False',
+ 'transport': 'tcp',
+ 'traddr': '10.10.10.10',
+ 'trsvcid': '8009',
+ 'host-traddr': '1.2.3.4',
+ 'host-iface': 'wlp0s20f3',
+ 'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
+ 'device': 'nvme?',
+ 'connect attempts': '1',
+ 'retry connect timer': '60.0s [off]',
+ 'hostid': '',
+ 'hostnqn': '',
+ 'model': '',
+ 'serial': '',
+ 'connect operation': "{'fail count': 0, 'completed': False, 'alive': True}",
+ },
+ )
+
+ # print(controller._connect_op)
+ self.assertEqual(controller.cancel(), None)
+ self.assertEqual(controller.kill(), None)
+ self.assertIsNone(controller.disconnect(lambda *args: None, True))
+
+ def test_connect(self):
+ controller = TestController(tid=self.NVME_TID, service=TestStaf())
+ self.assertEqual(controller._connect_attempts, 0)
+ controller._find_existing_connection = lambda: None
+ with self.assertLogs(logger=logging.getLogger(), level='DEBUG') as captured:
+ controller._try_to_connect()
+ self.assertTrue(len(captured.records) > 0)
+ self.assertTrue(
+ captured.records[0]
+ .getMessage()
+ .startswith(
+ "Controller._do_connect() - (tcp, 10.10.10.10, 8009, nqn.1988-11.com.dell:SFSS:2:20220208134025e8, wlp0s20f3, 1.2.3.4) Connecting to nvme control with cfg={"
+ )
+ )
+ self.assertEqual(controller._connect_attempts, 1)
+
+ def test_dlp_supp_opts_as_string(self):
+ dlp_supp_opts = 0x7
+ opts = ctrl.dlp_supp_opts_as_string(dlp_supp_opts)
+ self.assertEqual(['EXTDLPES', 'PLEOS', 'ALLSUBES'], opts)
+
+ def test_ncc(self):
+ dlpe = {'eflags': '4'}
+ ncc = ctrl.get_ncc(ctrl.get_eflags(dlpe))
+ self.assertTrue(ncc)
+
+ dlpe = {}
+ ncc = ctrl.get_ncc(ctrl.get_eflags(dlpe))
+ self.assertFalse(ncc)
+
+ def test_dc(self):
+ self.svcconf.set_conf_file(self.stafd_conf_file1)
+
+ controller = TestDc(TestStaf(), tid=self.NVME_TID)
+ controller.set_connected(True)
+ controller.origin = 'discovered'
+
+ with self.assertLogs(logger=logging.getLogger(), level='DEBUG') as captured:
+ controller.origin = 'blah'
+ self.assertEqual(len(captured.records), 1)
+ self.assertNotEqual(-1, captured.records[0].getMessage().find("Trying to set invalid origin to blah"))
+
+ controller.set_connected(False)
+ with self.assertLogs(logger=logging.getLogger(), level='DEBUG') as captured:
+ controller.origin = 'discovered'
+ self.assertEqual(len(captured.records), 1)
+ self.assertNotEqual(
+ -1, captured.records[0].getMessage().find("Controller is not responding. Will be removed by")
+ )
+
+ self.svcconf.set_conf_file(self.stafd_conf_file2)
+ with self.assertLogs(logger=logging.getLogger(), level='DEBUG') as captured:
+ controller.origin = 'discovered'
+ self.assertEqual(len(captured.records), 1)
+ self.assertNotEqual(-1, captured.records[0].getMessage().find("Controller not responding. Retrying..."))
+
+ controller.set_connected(True)
+ with self.assertLogs(logger=logging.getLogger(), level='DEBUG') as captured:
+ controller.disconnect(lambda *args: None, keep_connection=False)
+ self.assertEqual(len(captured.records), 2)
+ self.assertNotEqual(-1, captured.records[0].getMessage().find("nvme666: keep_connection=False"))
+ self.assertNotEqual(-1, captured.records[1].getMessage().find("nvme666 - Disconnect initiated"))
+
+ # def test_disconnect(self):
+
+
+if __name__ == '__main__':
+ unittest.main()