1
+ import os
1
2
import unittest
2
3
import unittest .mock as mock
3
4
5
+ import traceback
6
+
4
7
from uuid import uuid4
5
8
6
9
import SR
7
10
import LVHDoISCSISR
11
+ import iscsilib
8
12
from BaseISCSI import BaseISCSISR
9
13
import SRCommand
10
14
import util
@@ -126,13 +130,29 @@ def test_1st_try_block_raise_RandomError(
126
130
class TestLVHDoISCSISR (unittest .TestCase ):
127
131
128
132
def setUp (self ):
129
- util_patcher = mock .patch ('LVHDoISCSISR.util' )
133
+ util_patcher = mock .patch ('LVHDoISCSISR.util' , autospec = True )
130
134
self .mock_util = util_patcher .start ()
135
+ # self.mock_util.SMlog.side_effect = print
136
+ self .mock_util .isVDICommand = util .isVDICommand
131
137
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 )
133
142
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 ()
136
156
self .mock_session = mock .MagicMock ()
137
157
xenapi_patcher = mock .patch ('SR.XenAPI' )
138
158
mock_xenapi = xenapi_patcher .start ()
@@ -153,28 +173,81 @@ def deepcopy(to_copy):
153
173
154
174
self .addCleanup (mock .patch .stopall )
155
175
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 = {
158
229
'SCSIid' : '3600a098038313577792450384a4a6275' ,
159
230
'multihomelist' : 'tgt1:3260,tgt2:3260' ,
160
231
'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'
162
234
}
163
- dummy_cmd .params = {
235
+ if additional_dconf :
236
+ sr_cmd .dconf .update (additional_dconf )
237
+
238
+ sr_cmd .params = {
164
239
'command' : 'nop' ,
165
240
'session_ref' : 'test_session' ,
166
241
'host_ref' : 'test_host' ,
167
242
'sr_ref' : 'sr_ref'
168
243
}
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
174
246
175
247
def test_check_sr_pbd_not_found (self ):
176
248
# Arrange
177
249
self .mock_util .find_my_pbd .return_value = None
250
+ self .create_test_sr (self .create_sr_command ())
178
251
179
252
# Act
180
253
self .subject .check_sr (TEST_SR_UUID )
@@ -189,6 +262,7 @@ def test_check_sr_correct_sessions_count(self):
189
262
self .mock_session .xenapi .PBD .get_other_config .return_value = {
190
263
'iscsi_sessions' : 2
191
264
}
265
+ self .create_test_sr (self .create_sr_command ())
192
266
193
267
# Act
194
268
self .subject .check_sr (TEST_SR_UUID )
@@ -202,7 +276,7 @@ def test_check_sr_not_enough_sessions(self):
202
276
self .mock_session .xenapi .PBD .get_other_config .return_value = {
203
277
'iscsi_sessions' : 1
204
278
}
205
-
279
+ self . create_test_sr ( self . create_sr_command ())
206
280
207
281
# Act
208
282
self .subject .check_sr (TEST_SR_UUID )
@@ -211,3 +285,76 @@ def test_check_sr_not_enough_sessions(self):
211
285
self .mock_baseiscsi .attach .assert_called_with (
212
286
TEST_SR_UUID
213
287
)
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