diff --git a/mocks/XenAPI/__init__.py b/mocks/XenAPI/__init__.py index 21cb15ce9..8e45a1b46 100644 --- a/mocks/XenAPI/__init__.py +++ b/mocks/XenAPI/__init__.py @@ -1,3 +1,7 @@ class Failure(Exception): def __init__(self, details): pass + +def xapi_local(): + # Mock stub + pass diff --git a/tests/test_mpathcount.py b/tests/test_mpathcount.py index 72bcae78b..0415dbf74 100644 --- a/tests/test_mpathcount.py +++ b/tests/test_mpathcount.py @@ -5,6 +5,7 @@ import unittest.mock as mock import mpathcount +import XenAPI # pylint: disable=W0613; mocks don't need to be accessed # pylint: disable=R0201; methods must be instance for nose to work @@ -30,7 +31,7 @@ def test_get_path_count(self, mpath_cli): " |- 0:0:1:4 sdg 8:96 active ready running", " |- 7:0:0:4 sdab 65:176 failed faulty running", " `- 7:0:1:4 sdam 66:96 failed faulty running" - ] + ] count, total = mpathcount.get_path_count('3600a098038303973743f486833396d44') self.assertEqual(4, total, msg='total count incorrect') self.assertEqual(2, count, msg='count count incorrect') @@ -165,7 +166,7 @@ def fake_update_config(k, s, v, a, t, p): store = { 'mpath-3600a098038303973743f486833396d40': '[2, 4]', 'multipathed': True - } + } mpathcount.match_bySCSIid = False mpathcount.mpath_enabled = False mpathcount.check_devconfig( @@ -175,3 +176,36 @@ def fake_update_config(k, s, v, a, t, p): remove, None) self.assertNotIn('multipathed', store) self.assertNotIn('mpath-3600a098038303973743f486833396d40', store) + + @mock.patch('mpathcount.sys.exit', autospec=True) + def test_exit_logs_out(self, mock_exit): + # Arrange + session = mock.MagicMock() + + # Act + mpathcount.mpc_exit(session, 0) + + # Assert + mock_exit.assert_called_once_with(0) + session.xenapi.session.logout.assert_called_once() + + @mock.patch('mpathcount.sys.exit', autospec=True) + def test_exit_no_session(self, mock_exit): + # Act + mpathcount.mpc_exit(None, 0) + + # Assert + mock_exit.assert_called_once_with(0) + + @mock.patch('mpathcount.sys.exit', autospec=True) + def test_exit_log_out_error(self, mock_exit): + # Arrange + session = mock.MagicMock() + session.xenapi.session.logout.side_effect = XenAPI.Failure + + # Act + mpathcount.mpc_exit(session, 0) + + # Assert + mock_exit.assert_called_once_with(0) + session.xenapi.session.logout.assert_called_once() diff --git a/tests/test_util.py b/tests/test_util.py index 4bfb68832..0a0bf0452 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -713,3 +713,68 @@ def test_unictrunc(self): self.assertEqual(util.unictrunc(t, 2), 1) self.assertEqual(util.unictrunc(t, 1), 1) self.assertEqual(util.unictrunc(t, 0), 0) + + +class TestFistPoints(unittest.TestCase): + def setUp(self): + self.addCleanup(mock.patch.stopall) + sleep_patcher = mock.patch('util.time.sleep', autospec=True) + self.mock_sleep = sleep_patcher.start() + + log_patcher = mock.patch('util.SMlog', autospec=True) + self.mock_log = log_patcher.start() + + exists_patcher = mock.patch('util.os.path.exists', autospec=True) + self.mock_exists = exists_patcher.start() + self.mock_exists.side_effect = self.exists + self.existing_files = set() + + xenapi_patcher = mock.patch('util.XenAPI', autospec=True) + patched_xenapi = xenapi_patcher.start() + self.mock_xenapi = mock.MagicMock() + patched_xenapi.xapi_local.return_value = self.mock_xenapi + + def exists(self, path): + return path in self.existing_files + def test_activate_unknown(self): + test_uuid = str(uuid.uuid4()) + valid_fp_name = "TestValidFP" + invalid_fp_name = "TestInvalidFP" + + fistpoints = util.FistPoint([valid_fp_name]) + + fistpoints.activate(invalid_fp_name, test_uuid) + + # Assert + self.assertIn('Unknown fist point: TestInvalidFP', + self.mock_log.call_args[0][0]) + + def test_activate_not_active(self): + test_uuid = str(uuid.uuid4()) + valid_fp_name = "TestValidFP" + + fistpoints = util.FistPoint([valid_fp_name]) + + fistpoints.activate(valid_fp_name, test_uuid) + + # Assert (no side effect should have happened + self.mock_xenapi.xenapi.SR.add_to_other_config.assert_not_called() + self.mock_xenapi.xenapi.SR.remove_from_other_config.assert_not_called() + self.mock_sleep.assert_not_called() + + def test_activate_not_exit(self): + test_uuid = str(uuid.uuid4()) + valid_fp_name = "TestValidFP" + self.existing_files.add(os.path.join('/tmp', f'fist_{valid_fp_name}')) + + fistpoints = util.FistPoint([valid_fp_name]) + + fistpoints.activate(valid_fp_name, test_uuid) + + # Assert + self.mock_xenapi.xenapi.SR.add_to_other_config.assert_called_once_with( + mock.ANY, valid_fp_name, "active") + self.mock_xenapi.xenapi.SR.remove_from_other_config.assert_called_once_with( + mock.ANY, valid_fp_name) + self.mock_xenapi.xenapi.session.logout.assert_has_calls([mock.call(), mock.call()]) + self.mock_sleep.assert_called_once_with(util.FIST_PAUSE_PERIOD)