Skip to content

Commit

Permalink
Add unittests for multisession LVHDoISCSI attach
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Syms <mark.syms@citrix.com>
  • Loading branch information
MarkSymsCtx committed Jan 11, 2024
1 parent 04958e7 commit be5b691
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 23 deletions.
22 changes: 13 additions & 9 deletions drivers/iscsilib.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ def match_targetIQN(tgtIQN, s):
return True
# Extract IQN from iscsiadm -m session
# Ex: tcp: [17] 10.220.98.9:3260,1 iqn.2009-01.xenrt.test:iscsi4181a93e
siqn = s.split(",")[1].split()[1]
siqn = s.split(",")[1].split()[1].strip()
return (siqn == tgtIQN)


Expand All @@ -489,6 +489,17 @@ def match_session(s):
return regex.search(s, 0)


def _compare_sessions_to_tgt(session_output, tgtIQN, tgt=''):
for line in session_output.split('\n'):
if match_targetIQN(tgtIQN, line) and match_session(line):
if len(tgt):
if match_target(tgt, line):
return True
else:
return True
return False


def _checkTGT(tgtIQN, tgt=''):
if not is_iscsi_daemon_running():
return False
Expand All @@ -501,14 +512,7 @@ def _checkTGT(tgtIQN, tgt=''):
except Exception as e:
util.SMlog("%s failed with %s" % (cmd, e.args))
stdout = ""
for line in stdout.split('\n'):
if match_targetIQN(tgtIQN, line) and match_session(line):
if len(tgt):
if match_target(tgt, line):
return True
else:
return True
return False
return _compare_sessions_to_tgt(stdout, tgtIQN, tgt)


def get_rootdisk_IQNs():
Expand Down
175 changes: 161 additions & 14 deletions tests/test_LVHDoISCSISR.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import os
import unittest
import unittest.mock as mock

import traceback

from uuid import uuid4

import SR
import LVHDoISCSISR
import iscsilib
from BaseISCSI import BaseISCSISR
import SRCommand
import util
Expand Down Expand Up @@ -126,13 +130,29 @@ def test_1st_try_block_raise_RandomError(
class TestLVHDoISCSISR(unittest.TestCase):

def setUp(self):
util_patcher = mock.patch('LVHDoISCSISR.util')
util_patcher = mock.patch('LVHDoISCSISR.util', autospec=True)
self.mock_util = util_patcher.start()
# self.mock_util.SMlog.side_effect = print
self.mock_util.isVDICommand = util.isVDICommand
self.mock_util.sessions_less_than_targets = util.sessions_less_than_targets
baseiscsi_patcher = mock.patch('LVHDoISCSISR.BaseISCSI.BaseISCSISR')

self.base_srs = set()
baseiscsi_patcher = mock.patch('LVHDoISCSISR.BaseISCSI.BaseISCSISR',
autospec=True)
patched_baseiscsi = baseiscsi_patcher.start()
self.mock_baseiscsi = mock.create_autospec(BaseISCSISR)
patched_baseiscsi.return_value = self.mock_baseiscsi
patched_baseiscsi.side_effect = self.baseiscsi
lvhdsr_patcher = mock.patch ('LVHDoISCSISR.LVHDSR')

iscsilib_patcher = mock.patch('LVHDoISCSISR.iscsilib',
autospec=True)
self.mock_iscsilib = iscsilib_patcher.start()
self.mock_iscsilib.discovery.side_effect = self.discovery
self.mock_iscsilib._checkTGT.side_effect = self._checkTGT
self.mock_iscsilib.login.side_effect = self.iscsi_login
self.discovery_data = {}
self.sessions = []

self.mock_lvhdsr = lvhdsr_patcher.start()
self.mock_session = mock.MagicMock()
xenapi_patcher = mock.patch('SR.XenAPI')
mock_xenapi = xenapi_patcher.start()
Expand All @@ -153,28 +173,81 @@ def deepcopy(to_copy):

self.addCleanup(mock.patch.stopall)

dummy_cmd = mock.create_autospec(SRCommand)
dummy_cmd.dconf = {
def _checkTGT(self, tgtIQN, tgt=''):
all_sessions = '\n'.join(self.sessions)
matched = iscsilib._compare_sessions_to_tgt(all_sessions, tgtIQN, tgt)
return matched

def discovery(self, target, port, chapuser, chappassword,
targetIQN="any", interfaceArray=["default"]):
return self.discovery_data.get(target, [])

def iscsi_login(self, target, target_iqn, chauser, chappassword,
incoming_user, incoming_password, mpath):
print(f"Logging in {target} - {target_iqn}")
session_count = len(self.sessions)
self.sessions.append(f'tcp: [{session_count}] {target}:3260,1 {target_iqn}')

@property
def mock_baseiscsi(self):
assert len(self.base_srs) == 1
single_sr = None
for sr in self.base_srs:
single_sr = sr

return single_sr

def baseiscsi(self, srcmd, sr_uuid):
new_baseiscsi = mock.create_autospec(BaseISCSISR)
local_iqn = srcmd.dconf['localIQN']
target_iqn = srcmd.dconf['targetIQN']
target = srcmd.dconf['target']
new_baseiscsi.localIQN = local_iqn
new_baseiscsi.targetIQN = target_iqn
new_baseiscsi.target = target
new_baseiscsi.path = os.path.join('/dev/iscsi', target_iqn, target)
new_baseiscsi.port = 3260
new_baseiscsi.chapuser = srcmd.dconf.get('chapuser')
new_baseiscsi.chappassword = srcmd.dconf.get('chappassword')
new_baseiscsi.incoming_chapuser = srcmd.dconf.get('incoming_chapuser')
new_baseiscsi.incoming_chappassword = srcmd.dconf.get('incoming_chappassword')
self.base_srs.add(new_baseiscsi)

return new_baseiscsi

def create_test_sr(self, sr_cmd):
self.sr_uuid = str(uuid4())
self.subject = LVHDoISCSISR.LVHDoISCSISR(
sr_cmd, self.sr_uuid)

def create_sr_command(
self, additional_dconf=None, cmd=None,
target_iqn='iqn.2009-01.example.test:iscsi085e938a'):

sr_cmd = mock.create_autospec(SRCommand)
sr_cmd.dconf = {
'SCSIid': '3600a098038313577792450384a4a6275',
'multihomelist': 'tgt1:3260,tgt2:3260',
'target': "10.70.89.34",
'targetIQN': 'iqn.2009-01.example.test:iscsi085e938a'
'targetIQN': target_iqn,
'localIQN': 'iqn.2018-05.com.example:0d312804'
}
dummy_cmd.params = {
if additional_dconf:
sr_cmd.dconf.update(additional_dconf)

sr_cmd.params = {
'command': 'nop',
'session_ref': 'test_session',
'host_ref': 'test_host',
'sr_ref': 'sr_ref'
}
dummy_cmd.cmd = None

self.sr_uuid = str(uuid4())
self.subject = LVHDoISCSISR.LVHDoISCSISR(
dummy_cmd, self.sr_uuid)
sr_cmd.cmd = cmd
return sr_cmd

def test_check_sr_pbd_not_found(self):
# Arrange
self.mock_util.find_my_pbd.return_value = None
self.create_test_sr(self.create_sr_command())

# Act
self.subject.check_sr(TEST_SR_UUID)
Expand All @@ -189,6 +262,7 @@ def test_check_sr_correct_sessions_count(self):
self.mock_session.xenapi.PBD.get_other_config.return_value = {
'iscsi_sessions': 2
}
self.create_test_sr(self.create_sr_command())

# Act
self.subject.check_sr(TEST_SR_UUID)
Expand All @@ -202,7 +276,7 @@ def test_check_sr_not_enough_sessions(self):
self.mock_session.xenapi.PBD.get_other_config.return_value = {
'iscsi_sessions': 1
}

self.create_test_sr(self.create_sr_command())

# Act
self.subject.check_sr(TEST_SR_UUID)
Expand All @@ -211,3 +285,76 @@ def test_check_sr_not_enough_sessions(self):
self.mock_baseiscsi.attach.assert_called_with(
TEST_SR_UUID
)

def test_sr_attach_multi_session(self):
# Arrange
self.mock_util.find_my_pbd.return_value = 'my_pbd'
additional_dconf = {
'multiSession': '10.207.6.60,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.3.65,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
'10.207.3.61,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.6.61,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.3.63,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
'10.207.6.62,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.3.62,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.3.60,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
'10.207.6.64,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
'10.207.6.65,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
'10.207.3.64,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
'10.207.6.63,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
}

tpg_data = [
[
('10.207.3.60:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
('10.207.3.61:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
('10.207.3.62:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393')],
[
('10.207.3.63:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
('10.207.3.64:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
('10.207.3.65:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394')],
[
('10.207.6.60:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
('10.207.6.61:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
('10.207.6.62:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393')
],
[
('10.207.6.63:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
('10.207.6.64:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
('10.207.6.65:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394')
]
]

self.discovery_data = {
'10.207.3.60': tpg_data[0],
'10.207.3.61': tpg_data[0],
'10.207.3.62': tpg_data[0],
'10.207.3.63': tpg_data[1],
'10.207.3.64': tpg_data[1],
'10.207.3.65': tpg_data[1],
'10.207.6.60': tpg_data[2],
'10.207.6.61': tpg_data[2],
'10.207.6.62': tpg_data[2],
'10.207.6.63': tpg_data[3],
'10.207.6.64': tpg_data[3],
'10.207.6.65': tpg_data[3]
}

# Create SR
self.create_test_sr(self.create_sr_command(
additional_dconf=additional_dconf,
cmd='sr_attach',
target_iqn='*'))

# Act
self.subject.attach(TEST_SR_UUID)

# Assert
# print(f"iscsilib calls {self.mock_iscsilib.mock_calls}")
attach_count = 0
for sr in self.base_srs:
attach_count += sr.attach.call_count

self.assertEqual(12, attach_count)
self.assertEqual(12, self.mock_iscsilib.discovery.call_count)
self.assertEqual(12, self.mock_iscsilib.login.call_count)

0 comments on commit be5b691

Please sign in to comment.