1#
2# Copyright (c) 2016 NEC Corporation.
3# All Rights Reserved.
4#
5#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6#    not use this file except in compliance with the License. You may obtain
7#    a copy of the License at
8#
9#         http://www.apache.org/licenses/LICENSE-2.0
10#
11#    Unless required by applicable law or agreed to in writing, software
12#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14#    License for the specific language governing permissions and limitations
15#    under the License.
16
17import ddt
18import mock
19
20from cinder import exception
21from cinder import test
22from cinder.tests.unit import fake_constants as constants
23from cinder.volume import configuration as conf
24from cinder.volume.drivers.nec import cli
25from cinder.volume.drivers.nec import volume_common
26from cinder.volume.drivers.nec import volume_helper
27
28
29xml_out = '''
30<REQUEST>
31 <CMD_REQUEST cmd_name="/opt/iSMCliGateway/impl/query/iSMquery"
32              arg="-cinder -xml -all "
33              version="Version 9.4.001">
34  <CHAPTER name="Disk Array">
35   <OBJECT name="Disk Array">
36    <SECTION name="Disk Array Detail Information">
37     <UNIT name="Product ID">M310</UNIT>
38    </SECTION>
39   </OBJECT>
40  </CHAPTER>
41  <CHAPTER name="Logical Disk">
42   <OBJECT name="Logical Disk">
43    <SECTION name="LD Detail Information">
44     <UNIT name="LDN(h)">0000</UNIT>
45     <UNIT name="OS Type">LX</UNIT>
46     <UNIT name="LD Name">287RbQoP7VdwR1WsPC2fZT</UNIT>
47     <UNIT name="LD Capacity">1073741824</UNIT>
48     <UNIT name="Pool No.(h)">0000</UNIT>
49     <UNIT name="Purpose">---</UNIT>
50     <UNIT name="RPL Attribute">MV</UNIT>
51    </SECTION>
52   </OBJECT>
53   <OBJECT name="Logical Disk">
54    <SECTION name="LD Detail Information">
55     <UNIT name="LDN(h)">0001</UNIT>
56     <UNIT name="OS Type">  </UNIT>
57     <UNIT name="LD Name">backup_SDV0001</UNIT>
58     <UNIT name="LD Capacity">5368709120</UNIT>
59     <UNIT name="Pool No.(h)">0001</UNIT>
60     <UNIT name="Purpose">(invalid attribute)</UNIT>
61     <UNIT name="RPL Attribute">IV</UNIT>
62    </SECTION>
63   </OBJECT>
64   <OBJECT name="Logical Disk">
65    <SECTION name="LD Detail Information">
66     <UNIT name="LDN(h)">0003</UNIT>
67     <UNIT name="OS Type">LX</UNIT>
68     <UNIT name="LD Name">31HxzqBiAFTUxxOlcVn3EA</UNIT>
69     <UNIT name="LD Capacity">1073741824</UNIT>
70     <UNIT name="Pool No.(h)">0001</UNIT>
71     <UNIT name="Purpose">---</UNIT>
72     <UNIT name="RPL Attribute">RV</UNIT>
73    </SECTION>
74   </OBJECT>
75   <OBJECT name="Logical Disk">
76    <SECTION name="LD Detail Information">
77     <UNIT name="LDN(h)">0004</UNIT>
78     <UNIT name="OS Type">LX</UNIT>
79     <UNIT name="LD Name">287RbQoP7VdwR1WsPC2fZT_back</UNIT>
80     <UNIT name="LD Capacity">1073741824</UNIT>
81     <UNIT name="Pool No.(h)">0000</UNIT>
82     <UNIT name="Purpose">---</UNIT>
83     <UNIT name="RPL Attribute">RV</UNIT>
84    </SECTION>
85   </OBJECT>
86   <OBJECT name="Logical Disk">
87    <SECTION name="LD Detail Information">
88     <UNIT name="LDN(h)">0005</UNIT>
89     <UNIT name="OS Type">LX</UNIT>
90     <UNIT name="LD Name">20000009910200140005</UNIT>
91     <UNIT name="LD Capacity">10737418240</UNIT>
92     <UNIT name="Pool No.(h)">0000</UNIT>
93     <UNIT name="Purpose">---</UNIT>
94     <UNIT name="RPL Attribute">RV</UNIT>
95    </SECTION>
96   </OBJECT>
97   <OBJECT name="Logical Disk">
98    <SECTION name="LD Detail Information">
99     <UNIT name="LDN(h)">0006</UNIT>
100     <UNIT name="OS Type">LX</UNIT>
101     <UNIT name="LD Name">287RbQoP7VdwR1WsPC2fZT_l</UNIT>
102     <UNIT name="LD Capacity">10737418240</UNIT>
103     <UNIT name="Pool No.(h)">0000</UNIT>
104     <UNIT name="Purpose">---</UNIT>
105     <UNIT name="RPL Attribute">IV</UNIT>
106    </SECTION>
107   </OBJECT>
108   <OBJECT name="Logical Disk">
109    <SECTION name="LD Detail Information">
110     <UNIT name="LDN(h)">0007</UNIT>
111     <UNIT name="OS Type">  </UNIT>
112     <UNIT name="LD Name">20000009910200140007</UNIT>
113     <UNIT name="LD Capacity">10737418240</UNIT>
114     <UNIT name="Pool No.(h)">0000</UNIT>
115     <UNIT name="Purpose">---</UNIT>
116     <UNIT name="RPL Attribute">IV</UNIT>
117    </SECTION>
118   </OBJECT>
119   <OBJECT name="Logical Disk">
120    <SECTION name="LD Detail Information">
121     <UNIT name="LDN(h)">0008</UNIT>
122     <UNIT name="OS Type">  </UNIT>
123     <UNIT name="LD Name">20000009910200140008</UNIT>
124     <UNIT name="LD Capacity">10737418240</UNIT>
125     <UNIT name="Pool No.(h)">0000</UNIT>
126     <UNIT name="Purpose">---</UNIT>
127     <UNIT name="RPL Attribute">IV</UNIT>
128    </SECTION>
129   </OBJECT>
130   <OBJECT name="Logical Disk">
131    <SECTION name="LD Detail Information">
132     <UNIT name="LDN(h)">0009</UNIT>
133     <UNIT name="OS Type">  </UNIT>
134     <UNIT name="LD Name">20000009910200140009</UNIT>
135     <UNIT name="LD Capacity">10737418240</UNIT>
136     <UNIT name="Pool No.(h)">0000</UNIT>
137     <UNIT name="Purpose">---</UNIT>
138     <UNIT name="RPL Attribute">IV</UNIT>
139    </SECTION>
140   </OBJECT>
141   <OBJECT name="Logical Disk">
142    <SECTION name="LD Detail Information">
143     <UNIT name="LDN(h)">000a</UNIT>
144     <UNIT name="OS Type">  </UNIT>
145     <UNIT name="LD Name">2000000991020012000A</UNIT>
146     <UNIT name="LD Capacity">6442450944</UNIT>
147     <UNIT name="Pool No.(h)">0000</UNIT>
148     <UNIT name="Purpose">---</UNIT>
149     <UNIT name="RPL Attribute">IV</UNIT>
150    </SECTION>
151   </OBJECT>
152   <OBJECT name="Logical Disk">
153    <SECTION name="LD Detail Information">
154     <UNIT name="LDN(h)">000b</UNIT>
155     <UNIT name="OS Type">  </UNIT>
156     <UNIT name="LD Name">2000000991020012000B</UNIT>
157     <UNIT name="LD Capacity">6442450944</UNIT>
158     <UNIT name="Pool No.(h)">0000</UNIT>
159     <UNIT name="Purpose">---</UNIT>
160     <UNIT name="RPL Attribute">IV</UNIT>
161    </SECTION>
162   </OBJECT>
163   <OBJECT name="Logical Disk">
164    <SECTION name="LD Detail Information">
165     <UNIT name="LDN(h)">000c</UNIT>
166     <UNIT name="OS Type">  </UNIT>
167     <UNIT name="LD Name">2000000991020012000C</UNIT>
168     <UNIT name="LD Capacity">6442450944</UNIT>
169     <UNIT name="Pool No.(h)">0000</UNIT>
170     <UNIT name="Purpose">---</UNIT>
171     <UNIT name="RPL Attribute">IV</UNIT>
172    </SECTION>
173   </OBJECT>
174   <OBJECT name="Logical Disk">
175    <SECTION name="LD Detail Information">
176     <UNIT name="LDN(h)">000d</UNIT>
177     <UNIT name="OS Type">LX</UNIT>
178     <UNIT name="LD Name">yEUHrXa5AHMjOZZLb93eP</UNIT>
179     <UNIT name="LD Capacity">6442450944</UNIT>
180     <UNIT name="Pool No.(h)">0001</UNIT>
181     <UNIT name="Purpose">---</UNIT>
182     <UNIT name="RPL Attribute">IV</UNIT>
183    </SECTION>
184   </OBJECT>
185   <OBJECT name="Logical Disk">
186    <SECTION name="LD Detail Information">
187     <UNIT name="LDN(h)">000e</UNIT>
188     <UNIT name="OS Type">LX</UNIT>
189     <UNIT name="LD Name">4T7JpyqI3UuPlKeT9D3VQF</UNIT>
190     <UNIT name="LD Capacity">6442450944</UNIT>
191     <UNIT name="Pool No.(h)">0001</UNIT>
192     <UNIT name="Purpose">(invalid attribute)</UNIT>
193     <UNIT name="RPL Attribute">SV</UNIT>
194    </SECTION>
195   </OBJECT>
196   <OBJECT name="Logical Disk">
197    <SECTION name="LD Detail Information">
198     <UNIT name="LDN(h)">0fff</UNIT>
199     <UNIT name="OS Type">  </UNIT>
200     <UNIT name="LD Name">Pool0000_SYV0FFF</UNIT>
201     <UNIT name="LD Capacity">8589934592</UNIT>
202     <UNIT name="Pool No.(h)">0000</UNIT>
203     <UNIT name="Purpose">(invalid attribute)</UNIT>
204     <UNIT name="RPL Attribute">---</UNIT>
205    </SECTION>
206   </OBJECT>
207  </CHAPTER>
208  <CHAPTER name="Pool">
209   <OBJECT name="Pool">
210    <SECTION name="Pool Detail Information">
211     <UNIT name="Pool No.(h)">0000</UNIT>
212     <UNIT name="Pool Capacity">281320357888</UNIT>
213     <UNIT name="Used Pool Capacity">84020297728</UNIT>
214     <UNIT name="Free Pool Capacity">197300060160</UNIT>
215    </SECTION>
216   </OBJECT>
217   <OBJECT name="Pool">
218    <SECTION name="Pool Detail Information">
219     <UNIT name="Pool No.(h)">0001</UNIT>
220     <UNIT name="Pool Capacity">89657442304</UNIT>
221     <UNIT name="Used Pool Capacity">6710886400</UNIT>
222     <UNIT name="Free Pool Capacity">82946555904</UNIT>
223    </SECTION>
224   </OBJECT>
225   <OBJECT name="Pool">
226    <SECTION name="Pool Detail Information">
227     <UNIT name="Pool No.(h)">0002</UNIT>
228     <UNIT name="Pool Capacity">1950988894208</UNIT>
229     <UNIT name="Used Pool Capacity">18446744073441116160</UNIT>
230     <UNIT name="Free Pool Capacity">1951257329664</UNIT>
231    </SECTION>
232   </OBJECT>
233   <OBJECT name="Pool">
234    <SECTION name="Pool Detail Information">
235     <UNIT name="Pool No.(h)">0003</UNIT>
236     <UNIT name="Pool Capacity">1950988894208</UNIT>
237     <UNIT name="Used Pool Capacity">18446744073441116160</UNIT>
238     <UNIT name="Free Pool Capacity">1951257329664</UNIT>
239    </SECTION>
240   </OBJECT>
241  </CHAPTER>
242  <CHAPTER name="Controller">
243   <OBJECT name="Host Port">
244    <SECTION name="Host Director/Host Port Information">
245     <UNIT name="Port No.(h)">00-00</UNIT>
246     <UNIT name="WWPN">2100000991020012</UNIT>
247    </SECTION>
248   </OBJECT>
249   <OBJECT name="Host Port">
250    <SECTION name="Host Director/Host Port Information">
251     <UNIT name="Port No.(h)">00-01</UNIT>
252     <UNIT name="WWPN">2200000991020012</UNIT>
253    </SECTION>
254   </OBJECT>
255   <OBJECT name="Host Port">
256    <SECTION name="Host Director/Host Port Information">
257     <UNIT name="Port No.(h)">00-02</UNIT>
258     <UNIT name="IP Address">192.168.1.90</UNIT>
259     <UNIT name="Link Status">Link Down</UNIT>
260    </SECTION>
261   </OBJECT>
262   <OBJECT name="Host Port">
263    <SECTION name="Host Director/Host Port Information">
264     <UNIT name="Port No.(h)">00-03</UNIT>
265     <UNIT name="IP Address">192.168.1.91</UNIT>
266     <UNIT name="Link Status">Link Down</UNIT>
267    </SECTION>
268   </OBJECT>
269   <OBJECT name="Host Port">
270    <SECTION name="Host Director/Host Port Information">
271     <UNIT name="Port No.(h)">01-00</UNIT>
272     <UNIT name="WWPN">2900000991020012</UNIT>
273    </SECTION>
274   </OBJECT>
275   <OBJECT name="Host Port">
276    <SECTION name="Host Director/Host Port Information">
277     <UNIT name="Port No.(h)">01-01</UNIT>
278     <UNIT name="WWPN">2A00000991020012</UNIT>
279    </SECTION>
280   </OBJECT>
281   <OBJECT name="Host Port">
282    <SECTION name="Host Director/Host Port Information">
283     <UNIT name="Port No.(h)">01-02</UNIT>
284     <UNIT name="IP Address">192.168.2.92</UNIT>
285     <UNIT name="Link Status">Link Down</UNIT>
286    </SECTION>
287   </OBJECT>
288   <OBJECT name="Host Port">
289    <SECTION name="Host Director/Host Port Information">
290     <UNIT name="Port No.(h)">01-03</UNIT>
291     <UNIT name="IP Address">192.168.2.93</UNIT>
292     <UNIT name="Link Status">Link Up</UNIT>
293    </SECTION>
294   </OBJECT>
295  </CHAPTER>
296  <CHAPTER name="Access Control">
297   <OBJECT name="LD Set(FC)">
298    <SECTION name="LD Set(FC) Information">
299     <UNIT name="Platform">LX</UNIT>
300     <UNIT name="LD Set Name">OpenStack1</UNIT>
301    </SECTION>
302    <SECTION name="Path List">
303     <UNIT name="Path">1000-0090-FAA0-786B</UNIT>
304    </SECTION>
305    <SECTION name="Path List">
306     <UNIT name="Path">1000-0090-FAA0-786A</UNIT>
307    </SECTION>
308    <SECTION name="LUN/LD List">
309     <UNIT name="LUN(h)">0000</UNIT>
310     <UNIT name="LDN(h)">0005</UNIT>
311    </SECTION>
312    <SECTION name="LUN/LD List">
313     <UNIT name="LUN(h)">0001</UNIT>
314     <UNIT name="LDN(h)">0006</UNIT>
315    </SECTION>
316   </OBJECT>
317   <OBJECT name="LD Set(iSCSI)">
318    <SECTION name="LD Set(iSCSI) Information">
319     <UNIT name="Platform">LX</UNIT>
320     <UNIT name="LD Set Name">OpenStack0</UNIT>
321     <UNIT name="Target Mode">Multi-Target</UNIT>
322    </SECTION>
323    <SECTION name="Portal">
324     <UNIT name="Portal">192.168.1.90:3260</UNIT>
325    </SECTION>
326    <SECTION name="Portal">
327     <UNIT name="Portal">192.168.1.91:3260</UNIT>
328    </SECTION>
329    <SECTION name="Portal">
330     <UNIT name="Portal">192.168.2.92:3260</UNIT>
331    </SECTION>
332    <SECTION name="Portal">
333     <UNIT name="Portal">192.168.2.93:3260</UNIT>
334    </SECTION>
335    <SECTION name="Initiator List">
336     <UNIT name="Initiator List">iqn.1994-05.com.redhat:d1d8e8f23255</UNIT>
337    </SECTION>
338    <SECTION name="Target Information For Multi-Target Mode">
339     <UNIT name="Target Name">iqn.2001-03.target0000</UNIT>
340     <UNIT name="LUN(h)">0000</UNIT>
341     <UNIT name="LDN(h)">0000</UNIT>
342    </SECTION>
343   </OBJECT>
344  </CHAPTER>
345 <RETURN_MSG>Command Completed Successfully!!</RETURN_MSG>
346 <RETURN_CODE>0</RETURN_CODE>
347 </CMD_REQUEST>
348</REQUEST>
349'''
350
351
352class DummyVolume(object):
353
354    def __init__(self, volid, volsize=1):
355        super(DummyVolume, self).__init__()
356        self.id = volid
357        self.size = volsize
358        self.status = None
359        self.migration_status = None
360        self.volume_id = None
361        self.volume_type_id = None
362        self.attach_status = None
363        self.provider_location = None
364
365
366@ddt.ddt
367class VolumeIDConvertTest(volume_helper.MStorageDSVDriver, test.TestCase):
368
369    def setUp(self):
370        super(VolumeIDConvertTest, self).setUp()
371        self.mock_object(self, '_create_ismview_dir')
372        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
373        self.do_setup(None)
374        self.vol = DummyVolume(constants.VOLUME_ID)
375
376    @ddt.data(("AAAAAAAA", "LX:37mA82"), ("BBBBBBBB", "LX:3R9ZwR"))
377    @ddt.unpack
378    def test_volumeid_should_change_62scale(self, volid, ldname):
379        self.vol.id = volid
380        actual = self._convert_id2name(self.vol)
381        self.assertEqual(ldname, actual,
382                         "ID:%(volid)s should be change to %(ldname)s" %
383                         {'volid': volid, 'ldname': ldname})
384
385    @ddt.data(("AAAAAAAA", "LX:37mA82"), ("BBBBBBBB", "LX:3R9ZwR"))
386    @ddt.unpack
387    def test_snap_volumeid_should_change_62scale_andpostfix(self,
388                                                            volid,
389                                                            ldname):
390        self.vol.id = volid
391        actual = self._convert_id2snapname(self.vol)
392        self.assertEqual(ldname, actual,
393                         "ID:%(volid)s should be change to %(ldname)s" %
394                         {'volid': volid, 'ldname': ldname})
395
396    @ddt.data(("AAAAAAAA", "LX:37mA82_m"), ("BBBBBBBB", "LX:3R9ZwR_m"))
397    @ddt.unpack
398    def test_ddrsnap_volumeid_should_change_62scale_and_m(self,
399                                                          volid,
400                                                          ldname):
401        self.vol.id = volid
402        actual = self._convert_id2migratename(self.vol)
403        self.assertEqual(ldname, actual,
404                         "ID:%(volid)s should be change to %(ldname)s" %
405                         {'volid': volid, 'ldname': ldname})
406
407
408class NominatePoolLDTest(volume_helper.MStorageDSVDriver, test.TestCase):
409
410    def setUp(self):
411        super(NominatePoolLDTest, self).setUp()
412        self.mock_object(self, '_create_ismview_dir')
413        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
414        self.mock_object(self._cli, '_execute',
415                         return_value=('success', 0, 0))
416        self.mock_object(self._cli, 'view_all', return_value=xml_out)
417        self.do_setup(None)
418        self.xml = xml_out
419        self._properties['cli_fip'] = '10.0.0.1'
420        self._properties['pool_pools'] = {0, 1}
421        self._properties['pool_backup_pools'] = {2, 3}
422        (self.pools,
423         self.lds,
424         self.ldsets,
425         self.used_ldns,
426         self.hostports,
427         self.max_ld_count) = self.configs(self.xml)
428
429        pool_data = {'pool_num': 1,
430                     'total': 1,
431                     'free': 1,
432                     'ld_list': []}
433        volume = {'id': 'X'}
434        self.test_pools = []
435        for var in range(0, 1025):
436            pool_data['ld_list'].append(volume)
437        self.test_pools = [pool_data]
438        self.vol = DummyVolume(constants.VOLUME_ID, 10)
439
440    def test_getxml(self):
441        self.assertIsNotNone(self.xml, "iSMview xml should not be None")
442
443    def test_selectldn_for_normalvolume(self):
444        ldn = self._select_ldnumber(self.used_ldns, self.max_ld_count)
445        self.assertEqual(2, ldn, "selected ldn should be XXX")
446
447    def test_selectpool_for_normalvolume(self):
448        pool = self._select_leastused_poolnumber(self.vol,
449                                                 self.pools,
450                                                 self.xml)
451        self.assertEqual(1, pool, "selected pool should be 1")
452        # config:pool_pools=[1]
453        self.vol.size = 999999999999
454        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
455                                     'No available pools found.'):
456            pool = self._select_leastused_poolnumber(self.vol,
457                                                     self.pools,
458                                                     self.xml)
459
460    def test_return_poolnumber(self):
461        self.assertEqual(1, self._return_poolnumber(self.test_pools))
462
463    def test_selectpool_for_migratevolume(self):
464        self.vol.id = "46045673-41e7-44a7-9333-02f07feab04b"
465        dummyhost = {}
466        dummyhost['capabilities'] = self._update_volume_status()
467        pool = self._select_migrate_poolnumber(self.vol,
468                                               self.pools,
469                                               self.xml,
470                                               dummyhost)
471        self.assertEqual(1, pool, "selected pool should be 1")
472        self.vol.id = "1febb976-86d0-42ed-9bc0-4aa3e158f27d"
473        pool = self._select_migrate_poolnumber(self.vol,
474                                               self.pools,
475                                               self.xml,
476                                               dummyhost)
477        self.assertEqual(-1, pool, "selected pool is the same pool(return -1)")
478        self.vol.size = 999999999999
479        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
480                                     'No available pools found.'):
481            pool = self._select_migrate_poolnumber(self.vol,
482                                                   self.pools,
483                                                   self.xml,
484                                                   dummyhost)
485
486    def test_selectpool_for_snapvolume(self):
487        savePool1 = self.pools[1]['free']
488        self.pools[1]['free'] = 0
489        pool = self._select_dsv_poolnumber(self.vol, self.pools)
490        self.assertEqual(2, pool, "selected pool should be 2")
491        # config:pool_backup_pools=[2]
492        self.pools[1]['free'] = savePool1
493
494        if len(self.pools[0]['ld_list']) is 1024:
495            savePool2 = self.pools[2]['free']
496            savePool3 = self.pools[3]['free']
497            self.pools[2]['free'] = 0
498            self.pools[3]['free'] = 0
499            with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
500                                         'No available pools found.'):
501                pool = self._select_dsv_poolnumber(self.vol, self.pools)
502            self.pools[2]['free'] = savePool2
503            self.pools[3]['free'] = savePool3
504
505        self.vol.size = 999999999999
506        pool = self._select_dsv_poolnumber(self.vol, self.pools)
507        self.assertEqual(2, pool, "selected pool should be 2")
508        # config:pool_backup_pools=[2]
509
510    def test_selectpool_for_ddrvolume(self):
511        pool = self._select_ddr_poolnumber(self.vol,
512                                           self.pools,
513                                           self.xml,
514                                           10)
515        self.assertEqual(2, pool, "selected pool should be 2")
516        # config:pool_backup_pools=[2]
517
518        savePool2 = self.pools[2]['free']
519        savePool3 = self.pools[3]['free']
520        self.pools[2]['free'] = 0
521        self.pools[3]['free'] = 0
522        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
523                                     'No available pools found.'):
524            pool = self._select_ddr_poolnumber(self.vol,
525                                               self.pools,
526                                               self.xml,
527                                               10)
528        self.pools[2]['free'] = savePool2
529        self.pools[3]['free'] = savePool3
530
531        self.vol.size = 999999999999
532        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
533                                     'No available pools found.'):
534            pool = self._select_ddr_poolnumber(self.vol,
535                                               self.pools,
536                                               self.xml,
537                                               999999999999)
538
539    def test_selectpool_for_volddrvolume(self):
540        pool = self._select_volddr_poolnumber(self.vol,
541                                              self.pools,
542                                              self.xml,
543                                              10)
544        self.assertEqual(1, pool, "selected pool should be 1")
545        # config:pool_backup_pools=[2]
546
547        savePool0 = self.pools[0]['free']
548        savePool1 = self.pools[1]['free']
549        self.pools[0]['free'] = 0
550        self.pools[1]['free'] = 0
551        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
552                                     'No available pools found.'):
553            pool = self._select_volddr_poolnumber(self.vol,
554                                                  self.pools,
555                                                  self.xml,
556                                                  10)
557        self.pools[0]['free'] = savePool0
558        self.pools[1]['free'] = savePool1
559
560        self.vol.size = 999999999999
561        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
562                                     'No available pools found.'):
563            pool = self._select_volddr_poolnumber(self.vol,
564                                                  self.pools,
565                                                  self.xml,
566                                                  999999999999)
567
568
569class GetInformationTest(volume_helper.MStorageDSVDriver, test.TestCase):
570
571    def setUp(self):
572        super(GetInformationTest, self).setUp()
573        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
574        self.do_setup(None)
575
576    def test_get_ldset(self):
577        self.xml = xml_out
578        (self.pools,
579         self.lds,
580         self.ldsets,
581         self.used_ldns,
582         self.hostports,
583         self.max_ld_count) = self.configs(self.xml)
584        self._properties['ldset_name'] = ''
585        ldset = self.get_ldset(self.ldsets)
586        self.assertIsNone(ldset)
587        self._properties['ldset_name'] = 'LX:OpenStack1'
588        ldset = self.get_ldset(self.ldsets)
589        self.assertEqual('LX:OpenStack1', ldset['ldsetname'])
590        self._properties['ldset_name'] = 'LX:OpenStackX'
591        with self.assertRaisesRegexp(exception.NotFound,
592                                     'Logical Disk Set'
593                                     ' `LX:OpenStackX`'
594                                     ' could not be found.'):
595            self.get_ldset(self.ldsets)
596
597
598class VolumeCreateTest(volume_helper.MStorageDSVDriver, test.TestCase):
599
600    def setUp(self):
601        super(VolumeCreateTest, self).setUp()
602        self.mock_object(self, '_create_ismview_dir')
603        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
604        self.mock_object(self._cli, '_execute',
605                         return_value=('success', 0, 0))
606        self.mock_object(self._cli, 'view_all', return_value=xml_out)
607        self.do_setup(None)
608        self.xml = xml_out
609        self.vol = DummyVolume("46045673-41e7-44a7-9333-02f07feab04b", 1)
610
611    def test_validate_migrate_volume(self):
612        self.vol.status = 'available'
613        self._validate_migrate_volume(self.vol, self.xml)
614
615        self.vol.status = 'creating'
616        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
617                                     'Specified Logical Disk'
618                                     ' LX:287RbQoP7VdwR1WsPC2fZT'
619                                     ' is not available.'):
620            self._validate_migrate_volume(self.vol, self.xml)
621
622        self.vol.id = "AAAAAAAA"
623        self.vol.status = 'available'
624        with self.assertRaisesRegexp(exception.NotFound,
625                                     'Logical Disk `LX:37mA82`'
626                                     ' could not be found.'):
627            self._validate_migrate_volume(self.vol, self.xml)
628
629    def test_extend_volume(self):
630        self.vol.status = 'available'
631        self.extend_volume(self.vol, 10)
632
633        self.vol.id = "00046058-d38e-7f60-67b7-59ed65e54225"  # RV
634        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
635                                     'RPL Attribute Error. '
636                                     'RPL Attribute = RV.'):
637            self.extend_volume(self.vol, 10)
638
639
640class BindLDTest(volume_helper.MStorageDSVDriver, test.TestCase):
641
642    def setUp(self):
643        super(BindLDTest, self).setUp()
644        self.mock_object(self, '_create_ismview_dir')
645        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
646        self.mock_object(self._cli, '_execute',
647                         return_value=('success', 0, 0))
648        self.mock_object(self._cli, 'view_all', return_value=xml_out)
649        self.do_setup(None)
650        self.mock_object(self, '_bind_ld', return_value=(0, 0, 0))
651        self.vol = DummyVolume(constants.VOLUME_ID, 1)
652
653    def test_bindld_CreateVolume(self):
654        self.vol.migration_status = "success"
655        self.create_volume(self.vol)
656        self._bind_ld.assert_called_once_with(
657            self.vol, self.vol.size, None,
658            self._convert_id2name,
659            self._select_leastused_poolnumber)
660
661    def test_bindld_CreateCloneVolume(self):
662        self.vol.migration_status = "success"
663        self.src = DummyVolume("46045673-41e7-44a7-9333-02f07feab04b", 1)
664        self.mock_object(self._cli, 'query_BV_SV_status',
665                         return_value='snap/active')
666        self.mock_object(self._cli, 'query_MV_RV_name',
667                         return_value='separated')
668        self.mock_object(self._cli, 'backup_restore')
669        self.create_cloned_volume(self.vol, self.src)
670        self._bind_ld.assert_called_once_with(
671            self.vol, self.vol.size, None,
672            self._convert_id2name,
673            self._select_leastused_poolnumber)
674
675    def test_bindld_CreateCloneWaitingInterval(self):
676        self.assertEqual(10, cli.get_sleep_time_for_clone(0))
677        self.assertEqual(12, cli.get_sleep_time_for_clone(2))
678        self.assertEqual(60, cli.get_sleep_time_for_clone(19))
679
680    def test_delete_volume(self):
681        self.vol.id = "46045673-41e7-44a7-9333-02f07feab04b"
682        detached = self._detach_from_all(self.vol)
683        self.assertTrue(detached)
684        self.vol.id = constants.VOLUME_ID
685        detached = self._detach_from_all(self.vol)
686        self.assertFalse(detached)
687        self.vol.id = constants.VOLUME2_ID
688        with mock.patch.object(self, '_detach_from_all') as detach_mock:
689            self.delete_volume(self.vol)
690            detach_mock.assert_called_once_with(self.vol)
691
692
693class BindLDTest_Snap(volume_helper.MStorageDSVDriver, test.TestCase):
694
695    def setUp(self):
696        super(BindLDTest_Snap, self).setUp()
697        self.mock_object(self, '_create_ismview_dir')
698        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
699        self.mock_object(self._cli, '_execute',
700                         return_value=('success', 0, 0))
701        self.mock_object(self._cli, 'view_all', return_value=xml_out)
702        self.do_setup(None)
703        self.mock_object(self, '_bind_ld', return_value=(0, 0, 0))
704        self.mock_object(self, '_create_snapshot')
705        self.vol = DummyVolume(constants.VOLUME_ID)
706        self.snap = DummyVolume(constants.SNAPSHOT_ID)
707
708    def test_bindld_CreateSnapshot(self):
709        self.snap.volume_id = constants.VOLUME_ID
710        self.create_snapshot(self.snap)
711        self._create_snapshot.assert_called_once_with(
712            self.snap, self._properties['diskarray_name'])
713
714    def test_bindld_CreateFromSnapshot(self):
715        self.vol.migration_status = "success"
716        self.snap.id = "63410c76-2f12-4473-873d-74a63dfcd3e2"
717        self.snap.volume_id = "1febb976-86d0-42ed-9bc0-4aa3e158f27d"
718        self.mock_object(self._cli, 'query_BV_SV_status',
719                         return_value='snap/active')
720        self.mock_object(self._cli, 'backup_restore')
721        self.create_volume_from_snapshot(self.vol, self.snap)
722        self._bind_ld.assert_called_once_with(
723            self.vol, 1, None,
724            self._convert_id2name,
725            self._select_volddr_poolnumber, 1)
726
727
728class ExportTest(volume_helper.MStorageDSVDriver, test.TestCase):
729
730    def setUp(self):
731        super(ExportTest, self).setUp()
732        self.mock_object(self, '_create_ismview_dir')
733        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
734        self.mock_object(self._cli, '_execute',
735                         return_value=('success', 0, 0))
736        self.mock_object(self._cli, 'view_all', return_value=xml_out)
737        self.do_setup(None)
738        self.vol = DummyVolume("46045673-41e7-44a7-9333-02f07feab04b", 10)
739
740    def test_iscsi_portal(self):
741        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
742        self.iscsi_do_export(None, self.vol, connector,
743                             self._properties['diskarray_name'])
744
745    def test_fc_do_export(self):
746        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
747        self.fc_do_export(None, self.vol, connector)
748
749    def test_iscsi_initialize_connection(self):
750        loc = "127.0.0.1:3260:1 iqn.2010-10.org.openstack:volume-00000001 88"
751        self.vol.provider_location = loc
752        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255",
753                     'multipath': True}
754        info = self._iscsi_initialize_connection(self.vol, connector)
755        self.assertEqual('iscsi', info['driver_volume_type'])
756        self.assertEqual('iqn.2010-10.org.openstack:volume-00000001',
757                         info['data']['target_iqn'])
758        self.assertEqual('127.0.0.1:3260', info['data']['target_portal'])
759        self.assertEqual(88, info['data']['target_lun'])
760        self.assertEqual('iqn.2010-10.org.openstack:volume-00000001',
761                         info['data']['target_iqns'][0])
762        self.assertEqual('127.0.0.1:3260', info['data']['target_portals'][0])
763        self.assertEqual(88, info['data']['target_luns'][0])
764
765    def test_iscsi_terminate_connection(self):
766        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255",
767                     'multipath': True}
768        ret = self._iscsi_terminate_connection(self.vol, connector)
769        self.assertIsNone(ret)
770
771    def test_iscsi_terminate_connection_negative(self):
772        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255",
773                     'multipath': True}
774        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
775                                     r'Failed to unregister Logical Disk from'
776                                     r' Logical Disk Set \(iSM31064\)'):
777            self.mock_object(self._cli, 'delldsetld',
778                             return_value=(False, 'iSM31064'))
779            self._iscsi_terminate_connection(self.vol, connector)
780
781    def test_fc_initialize_connection(self):
782        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
783        info = self._fc_initialize_connection(self.vol, connector)
784        self.assertEqual('fibre_channel', info['driver_volume_type'])
785        self.assertEqual('2100000991020012', info['data']['target_wwn'][0])
786        self.assertEqual('2200000991020012', info['data']['target_wwn'][1])
787        self.assertEqual('2900000991020012', info['data']['target_wwn'][2])
788        self.assertEqual('2A00000991020012', info['data']['target_wwn'][3])
789        self.assertEqual(
790            '2100000991020012',
791            info['data']['initiator_target_map']['10000090FAA0786A'][0])
792        self.assertEqual(
793            '2100000991020012',
794            info['data']['initiator_target_map']['10000090FAA0786B'][0])
795        self.assertEqual(
796            '2200000991020012',
797            info['data']['initiator_target_map']['10000090FAA0786A'][1])
798        self.assertEqual(
799            '2200000991020012',
800            info['data']['initiator_target_map']['10000090FAA0786B'][1])
801        self.assertEqual(
802            '2900000991020012',
803            info['data']['initiator_target_map']['10000090FAA0786A'][2])
804        self.assertEqual(
805            '2900000991020012',
806            info['data']['initiator_target_map']['10000090FAA0786B'][2])
807        self.assertEqual(
808            '2A00000991020012',
809            info['data']['initiator_target_map']['10000090FAA0786A'][3])
810        self.assertEqual(
811            '2A00000991020012',
812            info['data']['initiator_target_map']['10000090FAA0786B'][3])
813        with self.assertRaisesRegexp(exception.VolumeBackendAPIException,
814                                     r'Failed to unregister Logical Disk from'
815                                     r' Logical Disk Set \(iSM31064\)'):
816            self.mock_object(self._cli, 'delldsetld',
817                             return_value=(False, 'iSM31064'))
818            self._fc_terminate_connection(self.vol, connector)
819
820    def test_fc_terminate_connection(self):
821        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
822        info = self._fc_terminate_connection(self.vol, connector)
823        self.assertEqual('fibre_channel', info['driver_volume_type'])
824        self.assertEqual('2100000991020012', info['data']['target_wwn'][0])
825        self.assertEqual('2200000991020012', info['data']['target_wwn'][1])
826        self.assertEqual('2900000991020012', info['data']['target_wwn'][2])
827        self.assertEqual('2A00000991020012', info['data']['target_wwn'][3])
828        self.assertEqual(
829            '2100000991020012',
830            info['data']['initiator_target_map']['10000090FAA0786A'][0])
831        self.assertEqual(
832            '2100000991020012',
833            info['data']['initiator_target_map']['10000090FAA0786B'][0])
834        self.assertEqual(
835            '2200000991020012',
836            info['data']['initiator_target_map']['10000090FAA0786A'][1])
837        self.assertEqual(
838            '2200000991020012',
839            info['data']['initiator_target_map']['10000090FAA0786B'][1])
840        self.assertEqual(
841            '2900000991020012',
842            info['data']['initiator_target_map']['10000090FAA0786A'][2])
843        self.assertEqual(
844            '2900000991020012',
845            info['data']['initiator_target_map']['10000090FAA0786B'][2])
846        self.assertEqual(
847            '2A00000991020012',
848            info['data']['initiator_target_map']['10000090FAA0786A'][3])
849        self.assertEqual(
850            '2A00000991020012',
851            info['data']['initiator_target_map']['10000090FAA0786B'][3])
852        info = self._fc_terminate_connection(self.vol, None)
853        self.assertEqual('fibre_channel', info['driver_volume_type'])
854        self.assertEqual({}, info['data'])
855
856    def test_iscsi_portal_with_controller_node_name(self):
857        self.vol.status = 'downloading'
858        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
859        self._properties['ldset_controller_node_name'] = 'LX:OpenStack1'
860        self._properties['portal_number'] = 2
861        location = self.iscsi_do_export(None, self.vol, connector,
862                                        self._properties['diskarray_name'])
863        self.assertEqual('192.168.1.90:3260;192.168.1.91:3260;'
864                         '192.168.2.92:3260;192.168.2.93:3260'
865                         ',1 iqn.2001-03.target0000 0',
866                         location['provider_location'])
867
868    def test_fc_do_export_with_controller_node_name(self):
869        self.vol.status = 'downloading'
870        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
871        self._properties['ldset_controller_node_name'] = 'LX:OpenStack0'
872        location = self.fc_do_export(None, self.vol, connector)
873        self.assertIsNone(location)
874
875
876class DeleteDSVVolume_test(volume_helper.MStorageDSVDriver,
877                           test.TestCase):
878
879    def setUp(self):
880        super(DeleteDSVVolume_test, self).setUp()
881        self.mock_object(self, '_create_ismview_dir')
882        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
883        self.mock_object(self._cli, '_execute',
884                         return_value=('success', 0, 0))
885        self.mock_object(self._cli, 'view_all', return_value=xml_out)
886        self.do_setup(None)
887        self.vol = DummyVolume(constants.SNAPSHOT_ID)
888        self.vol.volume_id = constants.VOLUME_ID
889
890    def test_delete_snapshot(self):
891        self.mock_object(self._cli, 'query_BV_SV_status',
892                         return_value='snap/active')
893        ret = self.delete_snapshot(self.vol)
894        self.assertIsNone(ret)
895
896
897class NonDisruptiveBackup_test(volume_helper.MStorageDSVDriver,
898                               test.TestCase):
899
900    def setUp(self):
901        super(NonDisruptiveBackup_test, self).setUp()
902        self.mock_object(self, '_create_ismview_dir')
903        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
904        self.mock_object(self._cli, '_execute',
905                         return_value=('success', 0, 0))
906        self.mock_object(self._cli, 'view_all', return_value=xml_out)
907        self.do_setup(None)
908        self.vol = DummyVolume('46045673-41e7-44a7-9333-02f07feab04b')
909        self.xml = xml_out
910        (self.pools,
911         self.lds,
912         self.ldsets,
913         self.used_ldns,
914         self.hostports,
915         self.max_ld_count) = self.configs(self.xml)
916
917    def test_validate_ld_exist(self):
918        ldname = self._validate_ld_exist(
919            self.lds, self.vol.id, self._properties['ld_name_format'])
920        self.assertEqual('LX:287RbQoP7VdwR1WsPC2fZT', ldname)
921        self.vol.id = "00000000-0000-0000-0000-6b6d96553b4b"
922        with self.assertRaisesRegexp(exception.NotFound,
923                                     'Logical Disk `LX:XXXXXXXX`'
924                                     ' could not be found.'):
925            self._validate_ld_exist(
926                self.lds, self.vol.id, self._properties['ld_name_format'])
927
928    def test_validate_iscsildset_exist(self):
929        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
930        ldset = self._validate_iscsildset_exist(self.ldsets, connector)
931        self.assertEqual('LX:OpenStack0', ldset['ldsetname'])
932        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f232XX"}
933        mock_data = {'ldsetname': 'LX:redhatd1d8e8f23',
934                     'protocol': 'iSCSI',
935                     'mode': 'Multi-Target',
936                     'portal_list': ['1.1.1.1:3260', '2.2.2.2:3260'],
937                     'lds': {},
938                     'initiator_list':
939                         ['iqn.1994-05.com.redhat:d1d8e8f232XX']}
940        mock_ldset = {}
941        mock_ldset['LX:redhatd1d8e8f23'] = mock_data
942        self.mock_object(
943            self, 'configs',
944            return_value=(None, None, mock_ldset, None, None, None))
945        ldset = self._validate_iscsildset_exist(self.ldsets, connector)
946        self.assertEqual('LX:redhatd1d8e8f23', ldset['ldsetname'])
947        self.assertEqual('iqn.1994-05.com.redhat:d1d8e8f232XX',
948                         ldset['initiator_list'][0])
949
950    def test_validate_fcldset_exist(self):
951        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
952        ldset = self._validate_fcldset_exist(self.ldsets, connector)
953        self.assertEqual('LX:OpenStack1', ldset['ldsetname'])
954        connector = {'wwpns': ["10000090FAA0786X", "10000090FAA0786Y"]}
955        mock_data = {'ldsetname': 'LX:10000090FAA0786X',
956                     'lds': {},
957                     'protocol': 'FC',
958                     'wwpn': ["1000-0090-FAA0-786X", "1000-0090-FAA0-786Y"],
959                     'port': []}
960        mock_ldset = {}
961        mock_ldset['LX:10000090FAA0786X'] = mock_data
962        self.mock_object(
963            self, 'configs',
964            return_value=(None, None, mock_ldset, None, None, None))
965        ldset = self._validate_fcldset_exist(self.ldsets, connector)
966        self.assertEqual('LX:10000090FAA0786X', ldset['ldsetname'])
967        self.assertEqual('1000-0090-FAA0-786X', ldset['wwpn'][0])
968        self.assertEqual('1000-0090-FAA0-786Y', ldset['wwpn'][1])
969
970    def test_enumerate_iscsi_portals(self):
971        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
972        ldset = self._validate_iscsildset_exist(self.ldsets, connector)
973        self.assertEqual('LX:OpenStack0', ldset['ldsetname'])
974        self._properties['portal_number'] = 2
975        portal = self._enumerate_iscsi_portals(self.hostports, ldset)
976        self.assertEqual('192.168.1.90:3260', portal[0])
977        self.assertEqual('192.168.1.91:3260', portal[1])
978        self.assertEqual('192.168.2.92:3260', portal[2])
979        self.assertEqual('192.168.2.93:3260', portal[3])
980
981    def test_initialize_connection_snapshot(self):
982        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
983        loc = "127.0.0.1:3260:1 iqn.2010-10.org.openstack:volume-00000001 88"
984        self.vol.provider_location = loc
985        ret = self.iscsi_initialize_connection_snapshot(self.vol, connector)
986        self.assertIsNotNone(ret)
987        self.assertEqual('iscsi', ret['driver_volume_type'])
988
989        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
990        ret = self.fc_initialize_connection_snapshot(self.vol, connector)
991        self.assertIsNotNone(ret)
992        self.assertEqual('fibre_channel', ret['driver_volume_type'])
993
994    def test_terminate_connection_snapshot(self):
995        connector = {'initiator': "iqn.1994-05.com.redhat:d1d8e8f23255"}
996        self.iscsi_terminate_connection_snapshot(self.vol, connector)
997
998        connector = {'wwpns': ["10000090FAA0786A", "10000090FAA0786B"]}
999        ret = self.fc_terminate_connection_snapshot(self.vol, connector)
1000        self.assertEqual('fibre_channel', ret['driver_volume_type'])
1001
1002    def test_remove_export_snapshot(self):
1003        self.remove_export_snapshot(None, self.vol)
1004
1005    def test_backup_use_temp_snapshot(self):
1006        ret = self.backup_use_temp_snapshot()
1007        self.assertTrue(ret)
1008
1009
1010class VolumeStats_test(volume_helper.MStorageDSVDriver, test.TestCase):
1011
1012    def setUp(self):
1013        super(VolumeStats_test, self).setUp()
1014        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
1015        self.do_setup(None)
1016        self._properties['cli_fip'] = '10.0.0.1'
1017        self._properties['pool_pools'] = {0, 1}
1018        self._properties['pool_backup_pools'] = {2, 3}
1019
1020    def test_update_volume_status(self):
1021        self.mock_object(volume_common.MStorageVolumeCommon, 'parse_xml',
1022                         side_effect=Exception)
1023        stats = self._update_volume_status()
1024        self.assertEqual('dummy', stats.get('volume_backend_name'))
1025        self.assertEqual('NEC', stats.get('vendor_name'))
1026        self.assertEqual(self.VERSION, stats.get('driver_version'))
1027        self.assertEqual('10.0.0.1', stats.get('location_info').split(':')[0])
1028        self.assertEqual('0,1', stats.get('location_info').split(':')[1])
1029
1030
1031class GetFreeLun_test(volume_helper.MStorageDSVDriver, test.TestCase):
1032
1033    def setUp(self):
1034        super(GetFreeLun_test, self).setUp()
1035        self.do_setup(None)
1036
1037    def test_get_free_lun_iscsi_multi(self):
1038        ldset = {'protocol': 'iSCSI',
1039                 'mode': 'Multi-Target',
1040                 'lds': {}}
1041        target_lun = self._get_free_lun(ldset)
1042        self.assertIsNone(target_lun)
1043
1044    def test_get_free_lun_iscsi_lun0(self):
1045        ldset = {'protocol': 'iSCSI',
1046                 'mode': 'Normal',
1047                 'lds': {}}
1048        target_lun = self._get_free_lun(ldset)
1049        self.assertEqual(0, target_lun)
1050
1051    def test_get_free_lun_iscsi_lun2(self):
1052        ld0 = {'lun': 0}
1053        ld1 = {'lun': 1}
1054        ld3 = {'lun': 3}
1055        ldsetlds = {}
1056        ldsetlds[0] = ld0
1057        ldsetlds[1] = ld1
1058        ldsetlds[3] = ld3
1059        ldset = {'protocol': 'iSCSI',
1060                 'mode': 'Normal',
1061                 'lds': ldsetlds}
1062        target_lun = self._get_free_lun(ldset)
1063        self.assertEqual(2, target_lun)
1064
1065    def test_get_free_lun_fc_lun1(self):
1066        ld0 = {'lun': 0}
1067        ldsetlds = {}
1068        ldsetlds[0] = ld0
1069        ldset = {'lds': ldsetlds,
1070                 'protocol': 'FC'}
1071        target_lun = self._get_free_lun(ldset)
1072        self.assertEqual(1, target_lun)
1073
1074
1075class Migrate_test(volume_helper.MStorageDSVDriver, test.TestCase):
1076
1077    def setUp(self):
1078        super(Migrate_test, self).setUp()
1079        self.mock_object(self, '_create_ismview_dir')
1080        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
1081        self.mock_object(self._cli, '_execute',
1082                         return_value=('success', 0, 0))
1083        self.mock_object(self._cli, 'view_all', return_value=xml_out)
1084        self.do_setup(None)
1085        self.newvol = DummyVolume(constants.VOLUME_ID)
1086        self.sourcevol = DummyVolume(constants.VOLUME2_ID)
1087
1088    def test_update_migrate_volume(self):
1089        update_data = self.update_migrated_volume(None, self.sourcevol,
1090                                                  self.newvol, 'available')
1091        self.assertIsNone(update_data['_name_id'])
1092        self.assertIsNone(update_data['provider_location'])
1093
1094
1095class ManageUnmanage_test(volume_helper.MStorageDSVDriver, test.TestCase):
1096
1097    def setUp(self):
1098        super(ManageUnmanage_test, self).setUp()
1099        self.mock_object(self, '_create_ismview_dir')
1100        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
1101        self.mock_object(self._cli, 'view_all', return_value=xml_out)
1102        self.do_setup(None)
1103        self._properties['pool_pools'] = {0}
1104        self._properties['pool_backup_pools'] = {1}
1105        self.newvol = DummyVolume(constants.VOLUME_ID)
1106
1107    def test_is_manageable_volume(self):
1108        ld_ok_iv = {'pool_num': 0, 'RPL Attribute': 'IV', 'Purpose': '---'}
1109        ld_ok_bv = {'pool_num': 0, 'RPL Attribute': 'BV', 'Purpose': 'INV'}
1110        ld_ng_pool = {'pool_num': 1, 'RPL Attribute': 'IV', 'Purpose': '---'}
1111        ld_ng_rpl1 = {'pool_num': 0, 'RPL Attribute': 'MV', 'Purpose': 'INV'}
1112        ld_ng_rpl2 = {'pool_num': 0, 'RPL Attribute': 'RV', 'Purpose': 'INV'}
1113        ld_ng_rpl3 = {'pool_num': 0, 'RPL Attribute': 'SV', 'Purpose': 'INV'}
1114        ld_ng_purp = {'pool_num': 0, 'RPL Attribute': 'IV', 'Purpose': 'INV'}
1115        self.assertTrue(self._is_manageable_volume(ld_ok_iv))
1116        self.assertTrue(self._is_manageable_volume(ld_ok_bv))
1117        self.assertFalse(self._is_manageable_volume(ld_ng_pool))
1118        self.assertFalse(self._is_manageable_volume(ld_ng_rpl1))
1119        self.assertFalse(self._is_manageable_volume(ld_ng_rpl2))
1120        self.assertFalse(self._is_manageable_volume(ld_ng_rpl3))
1121        self.assertFalse(self._is_manageable_volume(ld_ng_purp))
1122
1123    def test_get_manageable_volumes(self):
1124        current_volumes = []
1125        volumes = self.get_manageable_volumes(current_volumes, None,
1126                                              100, 0, ['reference'], ['dec'])
1127        self.assertEqual('LX:287RbQoP7VdwR1WsPC2fZT',
1128                         volumes[2]['reference']['source-name'])
1129        current_volumes = []
1130        volumes = self.get_manageable_volumes(current_volumes, None,
1131                                              100, 0, ['reference'], ['asc'])
1132        self.assertEqual('  :2000000991020012000A',
1133                         volumes[0]['reference']['source-name'])
1134        self.assertEqual(10, len(volumes))
1135
1136        volume = {'id': '46045673-41e7-44a7-9333-02f07feab04b'}
1137        current_volumes = []
1138        current_volumes.append(volume)
1139        volumes = self.get_manageable_volumes(current_volumes, None,
1140                                              100, 0, ['reference'], ['dec'])
1141        self.assertFalse(volumes[2]['safe_to_manage'])
1142        self.assertFalse(volumes[3]['safe_to_manage'])
1143        self.assertTrue(volumes[4]['safe_to_manage'])
1144
1145    def test_manage_existing(self):
1146        self.mock_object(self._cli, 'changeldname')
1147        current_volumes = []
1148        volumes = self.get_manageable_volumes(current_volumes, None,
1149                                              100, 0, ['reference'], ['dec'])
1150        self.manage_existing(self.newvol, volumes[4]['reference'])
1151        self._cli.changeldname.assert_called_once_with(
1152            None, 'LX:vD03hJCiHvGpvP4iSevKk', '  :20000009910200140009')
1153        with self.assertRaisesRegex(exception.ManageExistingInvalidReference,
1154                                    'Specified resource is already in-use.'):
1155            self.manage_existing(self.newvol, volumes[3]['reference'])
1156        volume = {'source-name': 'LX:yEUHrXa5AHMjOZZLb93eP'}
1157        with self.assertRaisesRegex(exception.ManageExistingVolumeTypeMismatch,
1158                                    'Volume type is unmatched.'):
1159            self.manage_existing(self.newvol, volume)
1160
1161    def test_manage_existing_get_size(self):
1162        current_volumes = []
1163        volumes = self.get_manageable_volumes(current_volumes, None,
1164                                              100, 0, ['reference'], ['dec'])
1165        size_in_gb = self.manage_existing_get_size(self.newvol,
1166                                                   volumes[3]['reference'])
1167        self.assertEqual(10, size_in_gb)
1168
1169
1170class ManageUnmanage_Snap_test(volume_helper.MStorageDSVDriver, test.TestCase):
1171
1172    def setUp(self):
1173        super(ManageUnmanage_Snap_test, self).setUp()
1174        self.mock_object(self, '_create_ismview_dir')
1175        self._set_config(conf.Configuration(None), 'dummy', 'dummy')
1176        self.mock_object(self._cli, 'view_all', return_value=xml_out)
1177        self.do_setup(None)
1178        self._properties['pool_pools'] = {0}
1179        self._properties['pool_backup_pools'] = {1}
1180        self.newsnap = DummyVolume('46045673-41e7-44a7-9333-02f07feab04b')
1181        self.newsnap.volume_id = "1febb976-86d0-42ed-9bc0-4aa3e158f27d"
1182
1183    def test_is_manageable_snapshot(self):
1184        ld_ok_sv1 = {'pool_num': 1, 'RPL Attribute': 'SV', 'Purpose': 'INV'}
1185        ld_ok_sv2 = {'pool_num': 1, 'RPL Attribute': 'SV', 'Purpose': '---'}
1186        ld_ng_pool = {'pool_num': 0, 'RPL Attribute': 'SV', 'Purpose': 'INV'}
1187        ld_ng_rpl1 = {'pool_num': 1, 'RPL Attribute': 'MV', 'Purpose': 'INV'}
1188        ld_ng_rpl2 = {'pool_num': 1, 'RPL Attribute': 'RV', 'Purpose': 'INV'}
1189        ld_ng_rpl3 = {'pool_num': 1, 'RPL Attribute': 'IV', 'Purpose': '---'}
1190        ld_ng_rpl4 = {'pool_num': 1, 'RPL Attribute': 'BV', 'Purpose': 'INV'}
1191        self.assertTrue(self._is_manageable_snapshot(ld_ok_sv1))
1192        self.assertTrue(self._is_manageable_snapshot(ld_ok_sv2))
1193        self.assertFalse(self._is_manageable_snapshot(ld_ng_pool))
1194        self.assertFalse(self._is_manageable_snapshot(ld_ng_rpl1))
1195        self.assertFalse(self._is_manageable_snapshot(ld_ng_rpl2))
1196        self.assertFalse(self._is_manageable_snapshot(ld_ng_rpl3))
1197        self.assertFalse(self._is_manageable_snapshot(ld_ng_rpl4))
1198
1199    def test_get_manageable_snapshots(self):
1200        self.mock_object(self._cli, 'get_bvname',
1201                         return_value='yEUHrXa5AHMjOZZLb93eP')
1202        current_snapshots = []
1203        volumes = self.get_manageable_snapshots(current_snapshots, None,
1204                                                100, 0, ['reference'], ['asc'])
1205        self.assertEqual('LX:4T7JpyqI3UuPlKeT9D3VQF',
1206                         volumes[0]['reference']['source-name'])
1207
1208    def test_manage_existing_snapshot(self):
1209        self.mock_object(self._cli, 'changeldname')
1210        self.mock_object(self._cli, 'get_bvname',
1211                         return_value='yEUHrXa5AHMjOZZLb93eP')
1212        current_snapshots = []
1213        snaps = self.get_manageable_snapshots(current_snapshots, None,
1214                                              100, 0, ['reference'], ['asc'])
1215        self.manage_existing_snapshot(self.newsnap, snaps[0]['reference'])
1216        self._cli.changeldname.assert_called_once_with(
1217            None,
1218            'LX:287RbQoP7VdwR1WsPC2fZT',
1219            'LX:4T7JpyqI3UuPlKeT9D3VQF')
1220
1221        self.newsnap.volume_id = "AAAAAAAA"
1222        with self.assertRaisesRegex(exception.ManageExistingInvalidReference,
1223                                    'Snapshot source is unmatch.'):
1224            self.manage_existing_snapshot(self.newsnap, snaps[0]['reference'])
1225
1226        self._cli.get_bvname.return_value = "2000000991020012000C"
1227        self.newsnap.volume_id = "00046058-d38e-7f60-67b7-59ed6422520c"
1228        snap = {'source-name': '  :2000000991020012000B'}
1229        with self.assertRaisesRegex(exception.ManageExistingVolumeTypeMismatch,
1230                                    'Volume type is unmatched.'):
1231            self.manage_existing_snapshot(self.newsnap, snap)
1232
1233    def test_manage_existing_snapshot_get_size(self):
1234        self.mock_object(self._cli, 'get_bvname',
1235                         return_value='yEUHrXa5AHMjOZZLb93eP')
1236        current_snapshots = []
1237        snaps = self.get_manageable_snapshots(current_snapshots, None,
1238                                              100, 0, ['reference'], ['asc'])
1239        size_in_gb = self.manage_existing_snapshot_get_size(
1240            self.newsnap,
1241            snaps[0]['reference'])
1242        self.assertEqual(6, size_in_gb)
1243