Skip to content

Commit be5b691

Browse files
committed
Add unittests for multisession LVHDoISCSI attach
Signed-off-by: Mark Syms <[email protected]>
1 parent 04958e7 commit be5b691

File tree

2 files changed

+174
-23
lines changed

2 files changed

+174
-23
lines changed

drivers/iscsilib.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ def match_targetIQN(tgtIQN, s):
480480
return True
481481
# Extract IQN from iscsiadm -m session
482482
# Ex: tcp: [17] 10.220.98.9:3260,1 iqn.2009-01.xenrt.test:iscsi4181a93e
483-
siqn = s.split(",")[1].split()[1]
483+
siqn = s.split(",")[1].split()[1].strip()
484484
return (siqn == tgtIQN)
485485

486486

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

491491

492+
def _compare_sessions_to_tgt(session_output, tgtIQN, tgt=''):
493+
for line in session_output.split('\n'):
494+
if match_targetIQN(tgtIQN, line) and match_session(line):
495+
if len(tgt):
496+
if match_target(tgt, line):
497+
return True
498+
else:
499+
return True
500+
return False
501+
502+
492503
def _checkTGT(tgtIQN, tgt=''):
493504
if not is_iscsi_daemon_running():
494505
return False
@@ -501,14 +512,7 @@ def _checkTGT(tgtIQN, tgt=''):
501512
except Exception as e:
502513
util.SMlog("%s failed with %s" % (cmd, e.args))
503514
stdout = ""
504-
for line in stdout.split('\n'):
505-
if match_targetIQN(tgtIQN, line) and match_session(line):
506-
if len(tgt):
507-
if match_target(tgt, line):
508-
return True
509-
else:
510-
return True
511-
return False
515+
return _compare_sessions_to_tgt(stdout, tgtIQN, tgt)
512516

513517

514518
def get_rootdisk_IQNs():

tests/test_LVHDoISCSISR.py

+161-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import os
12
import unittest
23
import unittest.mock as mock
34

5+
import traceback
6+
47
from uuid import uuid4
58

69
import SR
710
import LVHDoISCSISR
11+
import iscsilib
812
from BaseISCSI import BaseISCSISR
913
import SRCommand
1014
import util
@@ -126,13 +130,29 @@ def test_1st_try_block_raise_RandomError(
126130
class TestLVHDoISCSISR(unittest.TestCase):
127131

128132
def setUp(self):
129-
util_patcher = mock.patch('LVHDoISCSISR.util')
133+
util_patcher = mock.patch('LVHDoISCSISR.util', autospec=True)
130134
self.mock_util = util_patcher.start()
135+
# self.mock_util.SMlog.side_effect = print
136+
self.mock_util.isVDICommand = util.isVDICommand
131137
self.mock_util.sessions_less_than_targets = util.sessions_less_than_targets
132-
baseiscsi_patcher = mock.patch('LVHDoISCSISR.BaseISCSI.BaseISCSISR')
138+
139+
self.base_srs = set()
140+
baseiscsi_patcher = mock.patch('LVHDoISCSISR.BaseISCSI.BaseISCSISR',
141+
autospec=True)
133142
patched_baseiscsi = baseiscsi_patcher.start()
134-
self.mock_baseiscsi = mock.create_autospec(BaseISCSISR)
135-
patched_baseiscsi.return_value = self.mock_baseiscsi
143+
patched_baseiscsi.side_effect = self.baseiscsi
144+
lvhdsr_patcher = mock.patch ('LVHDoISCSISR.LVHDSR')
145+
146+
iscsilib_patcher = mock.patch('LVHDoISCSISR.iscsilib',
147+
autospec=True)
148+
self.mock_iscsilib = iscsilib_patcher.start()
149+
self.mock_iscsilib.discovery.side_effect = self.discovery
150+
self.mock_iscsilib._checkTGT.side_effect = self._checkTGT
151+
self.mock_iscsilib.login.side_effect = self.iscsi_login
152+
self.discovery_data = {}
153+
self.sessions = []
154+
155+
self.mock_lvhdsr = lvhdsr_patcher.start()
136156
self.mock_session = mock.MagicMock()
137157
xenapi_patcher = mock.patch('SR.XenAPI')
138158
mock_xenapi = xenapi_patcher.start()
@@ -153,28 +173,81 @@ def deepcopy(to_copy):
153173

154174
self.addCleanup(mock.patch.stopall)
155175

156-
dummy_cmd = mock.create_autospec(SRCommand)
157-
dummy_cmd.dconf = {
176+
def _checkTGT(self, tgtIQN, tgt=''):
177+
all_sessions = '\n'.join(self.sessions)
178+
matched = iscsilib._compare_sessions_to_tgt(all_sessions, tgtIQN, tgt)
179+
return matched
180+
181+
def discovery(self, target, port, chapuser, chappassword,
182+
targetIQN="any", interfaceArray=["default"]):
183+
return self.discovery_data.get(target, [])
184+
185+
def iscsi_login(self, target, target_iqn, chauser, chappassword,
186+
incoming_user, incoming_password, mpath):
187+
print(f"Logging in {target} - {target_iqn}")
188+
session_count = len(self.sessions)
189+
self.sessions.append(f'tcp: [{session_count}] {target}:3260,1 {target_iqn}')
190+
191+
@property
192+
def mock_baseiscsi(self):
193+
assert len(self.base_srs) == 1
194+
single_sr = None
195+
for sr in self.base_srs:
196+
single_sr = sr
197+
198+
return single_sr
199+
200+
def baseiscsi(self, srcmd, sr_uuid):
201+
new_baseiscsi = mock.create_autospec(BaseISCSISR)
202+
local_iqn = srcmd.dconf['localIQN']
203+
target_iqn = srcmd.dconf['targetIQN']
204+
target = srcmd.dconf['target']
205+
new_baseiscsi.localIQN = local_iqn
206+
new_baseiscsi.targetIQN = target_iqn
207+
new_baseiscsi.target = target
208+
new_baseiscsi.path = os.path.join('/dev/iscsi', target_iqn, target)
209+
new_baseiscsi.port = 3260
210+
new_baseiscsi.chapuser = srcmd.dconf.get('chapuser')
211+
new_baseiscsi.chappassword = srcmd.dconf.get('chappassword')
212+
new_baseiscsi.incoming_chapuser = srcmd.dconf.get('incoming_chapuser')
213+
new_baseiscsi.incoming_chappassword = srcmd.dconf.get('incoming_chappassword')
214+
self.base_srs.add(new_baseiscsi)
215+
216+
return new_baseiscsi
217+
218+
def create_test_sr(self, sr_cmd):
219+
self.sr_uuid = str(uuid4())
220+
self.subject = LVHDoISCSISR.LVHDoISCSISR(
221+
sr_cmd, self.sr_uuid)
222+
223+
def create_sr_command(
224+
self, additional_dconf=None, cmd=None,
225+
target_iqn='iqn.2009-01.example.test:iscsi085e938a'):
226+
227+
sr_cmd = mock.create_autospec(SRCommand)
228+
sr_cmd.dconf = {
158229
'SCSIid': '3600a098038313577792450384a4a6275',
159230
'multihomelist': 'tgt1:3260,tgt2:3260',
160231
'target': "10.70.89.34",
161-
'targetIQN': 'iqn.2009-01.example.test:iscsi085e938a'
232+
'targetIQN': target_iqn,
233+
'localIQN': 'iqn.2018-05.com.example:0d312804'
162234
}
163-
dummy_cmd.params = {
235+
if additional_dconf:
236+
sr_cmd.dconf.update(additional_dconf)
237+
238+
sr_cmd.params = {
164239
'command': 'nop',
165240
'session_ref': 'test_session',
166241
'host_ref': 'test_host',
167242
'sr_ref': 'sr_ref'
168243
}
169-
dummy_cmd.cmd = None
170-
171-
self.sr_uuid = str(uuid4())
172-
self.subject = LVHDoISCSISR.LVHDoISCSISR(
173-
dummy_cmd, self.sr_uuid)
244+
sr_cmd.cmd = cmd
245+
return sr_cmd
174246

175247
def test_check_sr_pbd_not_found(self):
176248
# Arrange
177249
self.mock_util.find_my_pbd.return_value = None
250+
self.create_test_sr(self.create_sr_command())
178251

179252
# Act
180253
self.subject.check_sr(TEST_SR_UUID)
@@ -189,6 +262,7 @@ def test_check_sr_correct_sessions_count(self):
189262
self.mock_session.xenapi.PBD.get_other_config.return_value = {
190263
'iscsi_sessions': 2
191264
}
265+
self.create_test_sr(self.create_sr_command())
192266

193267
# Act
194268
self.subject.check_sr(TEST_SR_UUID)
@@ -202,7 +276,7 @@ def test_check_sr_not_enough_sessions(self):
202276
self.mock_session.xenapi.PBD.get_other_config.return_value = {
203277
'iscsi_sessions': 1
204278
}
205-
279+
self.create_test_sr(self.create_sr_command())
206280

207281
# Act
208282
self.subject.check_sr(TEST_SR_UUID)
@@ -211,3 +285,76 @@ def test_check_sr_not_enough_sessions(self):
211285
self.mock_baseiscsi.attach.assert_called_with(
212286
TEST_SR_UUID
213287
)
288+
289+
def test_sr_attach_multi_session(self):
290+
# Arrange
291+
self.mock_util.find_my_pbd.return_value = 'my_pbd'
292+
additional_dconf = {
293+
'multiSession': '10.207.6.60,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
294+
'10.207.3.65,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
295+
'10.207.3.61,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
296+
'10.207.6.61,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
297+
'10.207.3.63,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
298+
'10.207.6.62,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
299+
'10.207.3.62,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
300+
'10.207.3.60,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3393|'
301+
'10.207.6.64,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
302+
'10.207.6.65,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
303+
'10.207.3.64,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
304+
'10.207.6.63,3260,iqn.2009-11.com.infinidat:storage:infinibox-sn-3394|'
305+
}
306+
307+
tpg_data = [
308+
[
309+
('10.207.3.60:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
310+
('10.207.3.61:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
311+
('10.207.3.62:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393')],
312+
[
313+
('10.207.3.63:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
314+
('10.207.3.64:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
315+
('10.207.3.65:3260', 1, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394')],
316+
[
317+
('10.207.6.60:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
318+
('10.207.6.61:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393'),
319+
('10.207.6.62:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3393')
320+
],
321+
[
322+
('10.207.6.63:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
323+
('10.207.6.64:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394'),
324+
('10.207.6.65:3260', 2, 'iqn.2009-11.com.infinidat:storage:infinibox-sn-3394')
325+
]
326+
]
327+
328+
self.discovery_data = {
329+
'10.207.3.60': tpg_data[0],
330+
'10.207.3.61': tpg_data[0],
331+
'10.207.3.62': tpg_data[0],
332+
'10.207.3.63': tpg_data[1],
333+
'10.207.3.64': tpg_data[1],
334+
'10.207.3.65': tpg_data[1],
335+
'10.207.6.60': tpg_data[2],
336+
'10.207.6.61': tpg_data[2],
337+
'10.207.6.62': tpg_data[2],
338+
'10.207.6.63': tpg_data[3],
339+
'10.207.6.64': tpg_data[3],
340+
'10.207.6.65': tpg_data[3]
341+
}
342+
343+
# Create SR
344+
self.create_test_sr(self.create_sr_command(
345+
additional_dconf=additional_dconf,
346+
cmd='sr_attach',
347+
target_iqn='*'))
348+
349+
# Act
350+
self.subject.attach(TEST_SR_UUID)
351+
352+
# Assert
353+
# print(f"iscsilib calls {self.mock_iscsilib.mock_calls}")
354+
attach_count = 0
355+
for sr in self.base_srs:
356+
attach_count += sr.attach.call_count
357+
358+
self.assertEqual(12, attach_count)
359+
self.assertEqual(12, self.mock_iscsilib.discovery.call_count)
360+
self.assertEqual(12, self.mock_iscsilib.login.call_count)

0 commit comments

Comments
 (0)