Coverage for manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py: 99%

1778 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright (c) 2015 Clinton Knight. All rights reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); you may 

4# not use this file except in compliance with the License. You may obtain 

5# a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

12# License for the specific language governing permissions and limitations 

13# under the License. 

14""" 

15Unit tests for the NetApp Data ONTAP cDOT multi-SVM storage driver library. 

16""" 

17 

18import copy 

19import time 

20from unittest import mock 

21 

22import ddt 

23from oslo_log import log 

24from oslo_serialization import jsonutils 

25from oslo_utils import units 

26 

27from manila.common import constants 

28from manila import context 

29from manila import exception 

30from manila.share.drivers.netapp.dataontap.client import api as netapp_api 

31from manila.share.drivers.netapp.dataontap.cluster_mode import data_motion 

32from manila.share.drivers.netapp.dataontap.cluster_mode import lib_base 

33from manila.share.drivers.netapp.dataontap.cluster_mode import lib_multi_svm 

34from manila.share.drivers.netapp import utils as na_utils 

35from manila.share import share_types 

36from manila.share import utils as share_utils 

37from manila import test 

38from manila.tests.share.drivers.netapp.dataontap.client import fakes as c_fake 

39from manila.tests.share.drivers.netapp.dataontap.cluster_mode.test_lib_base\ 

40 import _get_config 

41from manila.tests.share.drivers.netapp.dataontap import fakes as fake 

42 

43 

44@ddt.ddt 

45class NetAppFileStorageLibraryTestCase(test.TestCase): 

46 

47 def setUp(self): 

48 super(NetAppFileStorageLibraryTestCase, self).setUp() 

49 

50 self.mock_object(na_utils, 'validate_driver_instantiation') 

51 

52 self.sleep_patcher = mock.patch.object(time, 'sleep', lambda s: None) 

53 self.sleep_patcher.start() 

54 self.addCleanup(self.sleep_patcher.stop) 

55 

56 # Mock loggers as themselves to allow logger arg validation 

57 mock_logger = log.getLogger('mock_logger') 

58 self.mock_object(lib_multi_svm.LOG, 

59 'warning', 

60 mock.Mock(side_effect=mock_logger.warning)) 

61 self.mock_object(lib_multi_svm.LOG, 

62 'error', 

63 mock.Mock(side_effect=mock_logger.error)) 

64 

65 kwargs = { 

66 'configuration': fake.get_config_cmode(), 

67 'private_storage': mock.Mock(), 

68 'app_version': fake.APP_VERSION 

69 } 

70 

71 self.library = lib_multi_svm.NetAppCmodeMultiSVMFileStorageLibrary( 

72 fake.DRIVER_NAME, **kwargs) 

73 self.library._client = mock.Mock() 

74 self.library._client.get_ontapi_version.return_value = (1, 21) 

75 self.client = self.library._client 

76 self.fake_new_replica = copy.deepcopy(fake.SHARE) 

77 self.fake_new_ss = copy.deepcopy(fake.SHARE_SERVER) 

78 self.fake_new_vserver_name = 'fake_new_vserver' 

79 self.fake_new_ss['backend_details']['vserver_name'] = ( 

80 self.fake_new_vserver_name 

81 ) 

82 self.fake_new_replica['share_server'] = self.fake_new_ss 

83 self.fake_new_replica_host = 'fake_new_host' 

84 self.fake_replica = copy.deepcopy(fake.SHARE) 

85 self.fake_replica['id'] = fake.SHARE_ID2 

86 fake_ss = copy.deepcopy(fake.SHARE_SERVER) 

87 self.fake_vserver = 'fake_vserver' 

88 fake_ss['backend_details']['vserver_name'] = ( 

89 self.fake_vserver) 

90 self.fake_replica['share_server'] = fake_ss 

91 self.fake_replica_host = 'fake_host' 

92 

93 self.fake_new_client = mock.Mock() 

94 self.fake_client = mock.Mock() 

95 self.library._default_nfs_config = fake.NFS_CONFIG_DEFAULT 

96 

97 # Server migration 

98 self.dm_session = data_motion.DataMotionSession() 

99 self.fake_src_share = copy.deepcopy(fake.SHARE) 

100 self.fake_src_share_server = copy.deepcopy(fake.SHARE_SERVER) 

101 self.fake_src_vserver = 'source_vserver' 

102 self.fake_src_backend_name = ( 

103 self.fake_src_share_server['host'].split('@')[1]) 

104 self.fake_src_share_server['backend_details']['vserver_name'] = ( 

105 self.fake_src_vserver 

106 ) 

107 self.fake_src_share['share_server'] = self.fake_src_share_server 

108 self.fake_src_share['id'] = 'fb9be037-8a75-4c2a-bb7d-f63dffe13015' 

109 self.fake_src_vol_name = 'share_fb9be037_8a75_4c2a_bb7d_f63dffe13015' 

110 self.fake_dest_share = copy.deepcopy(fake.SHARE) 

111 self.fake_dest_share_server = copy.deepcopy(fake.SHARE_SERVER_2) 

112 self.fake_dest_vserver = 'dest_vserver' 

113 self.fake_dest_backend_name = ( 

114 self.fake_dest_share_server['host'].split('@')[1]) 

115 self.fake_dest_share_server['backend_details']['vserver_name'] = ( 

116 self.fake_dest_vserver 

117 ) 

118 self.fake_dest_share['share_server'] = self.fake_dest_share_server 

119 self.fake_dest_share['id'] = 'aa6a3941-f87f-4874-92ca-425d3df85457' 

120 self.fake_dest_vol_name = 'share_aa6a3941_f87f_4874_92ca_425d3df85457' 

121 

122 self.mock_src_client = mock.Mock() 

123 self.mock_dest_client = mock.Mock() 

124 

125 def test_check_for_setup_error_cluster_creds_no_vserver(self): 

126 self.library._have_cluster_creds = True 

127 mock_list_non_root_aggregates = self.mock_object( 

128 self.client, 'list_non_root_aggregates', 

129 mock.Mock(return_value=fake.AGGREGATES)) 

130 mock_init_flexgroup = self.mock_object(self.library, 

131 '_initialize_flexgroup_pools') 

132 self.mock_object(self.library, 

133 'is_flexvol_pool_configured', 

134 mock.Mock(return_value=True)) 

135 self.mock_object(self.library, 

136 '_find_matching_aggregates', 

137 mock.Mock(return_value=fake.AGGREGATES)) 

138 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

139 'check_for_setup_error') 

140 

141 self.library.check_for_setup_error() 

142 

143 mock_list_non_root_aggregates.assert_called_once_with() 

144 mock_init_flexgroup.assert_called_once_with(set(fake.AGGREGATES)) 

145 self.assertTrue(self.library.is_flexvol_pool_configured.called) 

146 self.assertTrue(self.library._find_matching_aggregates.called) 

147 mock_super.assert_called_once_with() 

148 

149 def test_check_for_setup_error_cluster_creds_with_vserver(self): 

150 self.library._have_cluster_creds = True 

151 self.library.configuration.netapp_vserver = fake.VSERVER1 

152 mock_list_non_root_aggregates = self.mock_object( 

153 self.client, 'list_non_root_aggregates', 

154 mock.Mock(return_value=fake.AGGREGATES)) 

155 mock_init_flexgroup = self.mock_object(self.library, 

156 '_initialize_flexgroup_pools') 

157 self.mock_object(self.library, 

158 'is_flexvol_pool_configured', 

159 mock.Mock(return_value=True)) 

160 self.mock_object(self.library, 

161 '_find_matching_aggregates', 

162 mock.Mock(return_value=fake.AGGREGATES)) 

163 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

164 'check_for_setup_error') 

165 

166 self.library.check_for_setup_error() 

167 

168 mock_super.assert_called_once_with() 

169 mock_list_non_root_aggregates.assert_called_once_with() 

170 mock_init_flexgroup.assert_called_once_with(set(fake.AGGREGATES)) 

171 self.assertTrue(self.library.is_flexvol_pool_configured.called) 

172 self.assertTrue(self.library._find_matching_aggregates.called) 

173 self.assertTrue(lib_multi_svm.LOG.warning.called) 

174 

175 def test_check_for_setup_error_no_aggregates_no_flexvol_pool(self): 

176 self.library._have_cluster_creds = True 

177 mock_list_non_root_aggregates = self.mock_object( 

178 self.client, 'list_non_root_aggregates', 

179 mock.Mock(return_value=fake.AGGREGATES)) 

180 mock_init_flexgroup = self.mock_object(self.library, 

181 '_initialize_flexgroup_pools') 

182 self.mock_object(self.library, 

183 'is_flexvol_pool_configured', 

184 mock.Mock(return_value=False)) 

185 self.mock_object(self.library, 

186 '_find_matching_aggregates', 

187 mock.Mock(return_value=[])) 

188 

189 self.library.check_for_setup_error() 

190 

191 mock_list_non_root_aggregates.assert_called_once_with() 

192 mock_init_flexgroup.assert_called_once_with(set(fake.AGGREGATES)) 

193 self.assertTrue(self.library.is_flexvol_pool_configured.called) 

194 self.assertTrue(self.library._find_matching_aggregates.called) 

195 

196 def test_check_for_setup_error_vserver_creds(self): 

197 self.library._have_cluster_creds = False 

198 

199 self.assertRaises(exception.InvalidInput, 

200 self.library.check_for_setup_error) 

201 

202 def test_check_for_setup_error_no_aggregates(self): 

203 self.library._have_cluster_creds = True 

204 mock_list_non_root_aggregates = self.mock_object( 

205 self.client, 'list_non_root_aggregates', 

206 mock.Mock(return_value=fake.AGGREGATES)) 

207 mock_init_flexgroup = self.mock_object(self.library, 

208 '_initialize_flexgroup_pools') 

209 self.mock_object(self.library, 

210 'is_flexvol_pool_configured', 

211 mock.Mock(return_value=True)) 

212 self.mock_object(self.library, 

213 '_find_matching_aggregates', 

214 mock.Mock(return_value=[])) 

215 

216 self.assertRaises(exception.NetAppException, 

217 self.library.check_for_setup_error) 

218 

219 mock_list_non_root_aggregates.assert_called_once_with() 

220 mock_init_flexgroup.assert_called_once_with(set(fake.AGGREGATES)) 

221 self.assertTrue(self.library.is_flexvol_pool_configured.called) 

222 self.assertTrue(self.library._find_matching_aggregates.called) 

223 

224 def test_get_vserver_no_share_server(self): 

225 

226 self.assertRaises(exception.InvalidInput, 

227 self.library._get_vserver) 

228 

229 def test_get_vserver_no_share_server_with_vserver_name(self): 

230 fake_vserver_client = mock.Mock() 

231 

232 mock_vserver_exists = self.mock_object( 

233 fake_vserver_client, 'vserver_exists', 

234 mock.Mock(return_value=True)) 

235 self.mock_object(self.library, 

236 '_get_api_client', 

237 mock.Mock(return_value=fake_vserver_client)) 

238 

239 result_vserver, result_vserver_client = self.library._get_vserver( 

240 share_server=None, vserver_name=fake.VSERVER1) 

241 

242 mock_vserver_exists.assert_called_once_with( 

243 fake.VSERVER1 

244 ) 

245 self.assertEqual(fake.VSERVER1, result_vserver) 

246 self.assertEqual(fake_vserver_client, result_vserver_client) 

247 

248 def test_get_vserver_no_backend_details(self): 

249 

250 fake_share_server = copy.deepcopy(fake.SHARE_SERVER) 

251 fake_share_server.pop('backend_details') 

252 kwargs = {'share_server': fake_share_server} 

253 

254 self.assertRaises(exception.VserverNotSpecified, 

255 self.library._get_vserver, 

256 **kwargs) 

257 

258 def test_get_vserver_none_backend_details(self): 

259 

260 fake_share_server = copy.deepcopy(fake.SHARE_SERVER) 

261 fake_share_server['backend_details'] = None 

262 kwargs = {'share_server': fake_share_server} 

263 

264 self.assertRaises(exception.VserverNotSpecified, 

265 self.library._get_vserver, 

266 **kwargs) 

267 

268 def test_get_vserver_no_vserver(self): 

269 

270 fake_share_server = copy.deepcopy(fake.SHARE_SERVER) 

271 fake_share_server['backend_details'].pop('vserver_name') 

272 kwargs = {'share_server': fake_share_server} 

273 

274 self.assertRaises(exception.VserverNotSpecified, 

275 self.library._get_vserver, 

276 **kwargs) 

277 

278 def test_get_vserver_none_vserver(self): 

279 

280 fake_share_server = copy.deepcopy(fake.SHARE_SERVER) 

281 fake_share_server['backend_details']['vserver_name'] = None 

282 kwargs = {'share_server': fake_share_server} 

283 

284 self.assertRaises(exception.VserverNotSpecified, 

285 self.library._get_vserver, 

286 **kwargs) 

287 

288 def test_get_vserver_not_found(self): 

289 

290 mock_client = mock.Mock() 

291 mock_client.vserver_exists.return_value = False 

292 self.mock_object(self.library, 

293 '_get_api_client', 

294 mock.Mock(return_value=mock_client)) 

295 kwargs = {'share_server': fake.SHARE_SERVER} 

296 

297 self.assertRaises(exception.VserverNotFound, 

298 self.library._get_vserver, 

299 **kwargs) 

300 

301 def test_get_vserver(self): 

302 

303 mock_client = mock.Mock() 

304 mock_client.vserver_exists.return_value = True 

305 self.mock_object(self.library, 

306 '_get_api_client', 

307 mock.Mock(return_value=mock_client)) 

308 

309 result = self.library._get_vserver(share_server=fake.SHARE_SERVER) 

310 

311 self.assertTupleEqual((fake.VSERVER1, mock_client), result) 

312 

313 def test_get_ems_pool_info(self): 

314 

315 self.mock_object(self.library, 

316 '_find_matching_aggregates', 

317 mock.Mock(return_value=['aggr1', 'aggr2'])) 

318 self.library._flexgroup_pools = {'fg': ['aggr1', 'aggr2']} 

319 

320 result = self.library._get_ems_pool_info() 

321 

322 expected = { 

323 'pools': { 

324 'vserver': None, 

325 'aggregates': ['aggr1', 'aggr2'], 

326 'flexgroup_aggregates': {'fg': ['aggr1', 'aggr2']}, 

327 }, 

328 } 

329 self.assertEqual(expected, result) 

330 

331 @ddt.data({'fake_vserver_name': fake, 'nfs_config_support': False}, 

332 {'fake_vserver_name': fake.IDENTIFIER, 

333 'nfs_config_support': True}) 

334 @ddt.unpack 

335 def test_manage_server(self, fake_vserver_name, nfs_config_support): 

336 

337 self.mock_object(context, 

338 'get_admin_context', 

339 mock.Mock(return_value='fake_admin_context')) 

340 mock_get_vserver_name = self.mock_object( 

341 self.library, '_get_vserver_name', 

342 mock.Mock(return_value=fake_vserver_name)) 

343 self.library.is_nfs_config_supported = nfs_config_support 

344 mock_get_nfs_config = self.mock_object( 

345 self.library._client, 'get_nfs_config', 

346 mock.Mock(return_value=fake.NFS_CONFIG_DEFAULT)) 

347 

348 new_identifier, new_details = self.library.manage_server( 

349 context, fake.SHARE_SERVER, fake.IDENTIFIER, {}) 

350 

351 mock_get_vserver_name.assert_called_once_with(fake.SHARE_SERVER['id']) 

352 self.assertEqual(fake_vserver_name, new_details['vserver_name']) 

353 self.assertEqual(fake_vserver_name, new_identifier) 

354 if nfs_config_support: 

355 mock_get_nfs_config.assert_called_once_with( 

356 list(self.library.NFS_CONFIG_EXTRA_SPECS_MAP.values()), 

357 fake_vserver_name) 

358 self.assertEqual(jsonutils.dumps(fake.NFS_CONFIG_DEFAULT), 

359 new_details['nfs_config']) 

360 else: 

361 mock_get_nfs_config.assert_not_called() 

362 

363 def test_get_share_server_network_info(self): 

364 

365 fake_vserver_client = mock.Mock() 

366 

367 self.mock_object(context, 

368 'get_admin_context', 

369 mock.Mock(return_value='fake_admin_context')) 

370 mock_get_vserver = self.mock_object( 

371 self.library, '_get_vserver', 

372 mock.Mock(return_value=['fake', fake_vserver_client])) 

373 

374 net_interfaces = copy.deepcopy(c_fake.NETWORK_INTERFACES_MULTIPLE) 

375 

376 self.mock_object(fake_vserver_client, 

377 'get_network_interfaces', 

378 mock.Mock(return_value=net_interfaces)) 

379 

380 result = self.library.get_share_server_network_info(context, 

381 fake.SHARE_SERVER, 

382 fake.IDENTIFIER, 

383 {}) 

384 mock_get_vserver.assert_called_once_with( 

385 vserver_name=fake.IDENTIFIER 

386 ) 

387 reference_allocations = [] 

388 for lif in net_interfaces: 

389 reference_allocations.append(lif['address']) 

390 

391 self.assertEqual(reference_allocations, result) 

392 

393 @ddt.data((True, fake.IDENTIFIER), 

394 (False, fake.IDENTIFIER)) 

395 @ddt.unpack 

396 def test__verify_share_server_name(self, vserver_exists, identifier): 

397 

398 mock_exists = self.mock_object(self.client, 'vserver_exists', 

399 mock.Mock(return_value=vserver_exists)) 

400 expected_result = identifier 

401 if not vserver_exists: 

402 expected_result = self.library._get_vserver_name(identifier) 

403 

404 result = self.library._get_correct_vserver_old_name(identifier) 

405 

406 self.assertEqual(result, expected_result) 

407 mock_exists.assert_called_once_with(identifier) 

408 

409 def test_handle_housekeeping_tasks(self): 

410 

411 self.mock_object(self.client, 'prune_deleted_nfs_export_policies') 

412 self.mock_object(self.client, 'prune_deleted_snapshots') 

413 self.mock_object(self.client, 'prune_deleted_volumes') 

414 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

415 '_handle_housekeeping_tasks') 

416 

417 self.library._handle_housekeeping_tasks() 

418 

419 self.assertTrue(self.client.prune_deleted_nfs_export_policies.called) 

420 self.assertTrue(self.client.prune_deleted_snapshots.called) 

421 self.assertTrue(self.client.prune_deleted_volumes.called) 

422 self.assertTrue(mock_super.called) 

423 

424 def test_find_matching_aggregates(self): 

425 

426 mock_is_flexvol_pool_configured = self.mock_object( 

427 self.library, 'is_flexvol_pool_configured', 

428 mock.Mock(return_value=True)) 

429 mock_list_non_root_aggregates = self.mock_object( 

430 self.client, 'list_non_root_aggregates', 

431 mock.Mock(return_value=fake.AGGREGATES)) 

432 self.library.configuration.netapp_aggregate_name_search_pattern = ( 

433 '.*_aggr_1') 

434 

435 result = self.library._find_matching_aggregates() 

436 

437 self.assertListEqual([fake.AGGREGATES[0]], result) 

438 mock_is_flexvol_pool_configured.assert_called_once_with() 

439 mock_list_non_root_aggregates.assert_called_once_with() 

440 mock_list_non_root_aggregates.assert_called_once_with() 

441 

442 def test_find_matching_aggregates_no_flexvol_pool(self): 

443 

444 self.mock_object(self.library, 

445 'is_flexvol_pool_configured', 

446 mock.Mock(return_value=False)) 

447 

448 result = self.library._find_matching_aggregates() 

449 

450 self.assertListEqual([], result) 

451 

452 def test__set_network_with_metadata(self): 

453 net_info_1 = copy.deepcopy(fake.NETWORK_INFO) 

454 net_info_2 = copy.deepcopy(fake.NETWORK_INFO) 

455 net_info_2['subnet_metadata'] = {'fake_key': 'fake_value'} 

456 net_info_3 = copy.deepcopy(fake.NETWORK_INFO) 

457 metadata_vlan = 1 

458 net_info_3['subnet_metadata'] = { 

459 'set_vlan': metadata_vlan, 

460 'set_mtu': '1' 

461 } 

462 net_info_4 = copy.deepcopy(fake.NETWORK_INFO) 

463 metadata_vlan = 1 

464 net_info_4['subnet_metadata'] = { 

465 'set_vlan': metadata_vlan 

466 } 

467 

468 net_list = [net_info_1, net_info_2, net_info_3, net_info_4] 

469 self.library._set_network_with_metadata(net_list) 

470 

471 net_info = copy.deepcopy(fake.NETWORK_INFO) 

472 self.assertEqual(net_info, net_list[0]) 

473 net_info['subnet_metadata'] = {'fake_key': 'fake_value'} 

474 self.assertEqual(net_info, net_list[1]) 

475 self.assertEqual(metadata_vlan, net_list[2]['segmentation_id']) 

476 for allocation in net_list[2]['network_allocations']: 

477 self.assertEqual(metadata_vlan, allocation['segmentation_id']) 

478 self.assertEqual(1, allocation['mtu']) 

479 self.assertEqual(metadata_vlan, net_list[3]['segmentation_id']) 

480 for allocation in net_list[3]['network_allocations']: 

481 self.assertEqual(metadata_vlan, allocation['segmentation_id']) 

482 self.assertEqual(fake.MTU, allocation['mtu']) 

483 

484 @ddt.data({'set_vlan': '0', 'set_mtu': '1500'}, 

485 {'set_vlan': '1000', 'set_mtu': '1bla'}) 

486 def test__set_network_with_metadata_exception(self, metadata): 

487 net_info = copy.deepcopy(fake.NETWORK_INFO) 

488 net_info['subnet_metadata'] = metadata 

489 

490 self.assertRaises( 

491 exception.NetworkBadConfigurationException, 

492 self.library._set_network_with_metadata, 

493 [net_info]) 

494 

495 @ddt.data({'nfs_config_support': False, 'with_encryption': True}, 

496 {'nfs_config_support': True, 

497 'nfs_config': fake.NFS_CONFIG_UDP_MAX, 

498 'with_encryption': False}, 

499 {'nfs_config_support': True, 

500 'nfs_config': fake.NFS_CONFIG_DEFAULT, 'with_encryption': True}) 

501 @ddt.unpack 

502 def test_setup_server(self, nfs_config_support, nfs_config=None, 

503 with_encryption=False): 

504 mock_get_vserver_name = self.mock_object( 

505 self.library, 

506 '_get_vserver_name', 

507 mock.Mock(return_value=fake.VSERVER1)) 

508 

509 mock_create_vserver = self.mock_object(self.library, '_create_vserver') 

510 mock_validate_network_type = self.mock_object( 

511 self.library, 

512 '_validate_network_type') 

513 mock_validate_share_network_subnets = self.mock_object( 

514 self.library, 

515 '_validate_share_network_subnets') 

516 self.library.is_nfs_config_supported = nfs_config_support 

517 mock_get_extra_spec = self.mock_object( 

518 share_types, "get_share_type_extra_specs", 

519 mock.Mock(return_value=fake.EXTRA_SPEC)) 

520 mock_check_extra_spec = self.mock_object( 

521 self.library, 

522 '_check_nfs_config_extra_specs_validity', 

523 mock.Mock()) 

524 self.library.configuration.netapp_restrict_lif_creation_per_ha_pair = ( 

525 True 

526 ) 

527 check_lif_limit = self.mock_object( 

528 self.library, 

529 '_check_data_lif_count_limit_reached_for_ha_pair', 

530 ) 

531 mock_get_nfs_config = self.mock_object( 

532 self.library, 

533 "_get_nfs_config_provisioning_options", 

534 mock.Mock(return_value=nfs_config)) 

535 mock_set_with_meta = self.mock_object( 

536 self.library, '_set_network_with_metadata') 

537 mock_barbican_kms_config = self.mock_object( 

538 self.library, '_create_barbican_kms_config_for_specified_vserver') 

539 

540 fake_server_metadata = ( 

541 fake.SERVER_METADATA_WITH_ENCRYPTION 

542 if with_encryption else fake.SERVER_METADATA) 

543 result = self.library.setup_server(fake.NETWORK_INFO_LIST, 

544 fake_server_metadata) 

545 

546 ports = {} 

547 for network_allocation in fake.NETWORK_INFO['network_allocations']: 

548 ports[network_allocation['id']] = network_allocation['ip_address'] 

549 

550 mock_set_with_meta.assert_called_once_with(fake.NETWORK_INFO_LIST) 

551 self.assertTrue(mock_validate_network_type.called) 

552 self.assertTrue(mock_validate_share_network_subnets.called) 

553 self.assertTrue(mock_get_vserver_name.called) 

554 self.assertTrue(mock_create_vserver.called) 

555 self.assertTrue(check_lif_limit.called) 

556 if nfs_config_support: 

557 mock_get_extra_spec.assert_called_once_with( 

558 fake_server_metadata['share_type_id']) 

559 mock_check_extra_spec.assert_called_once_with( 

560 fake.EXTRA_SPEC) 

561 mock_get_nfs_config.assert_called_once_with( 

562 fake.EXTRA_SPEC) 

563 else: 

564 mock_get_extra_spec.assert_not_called() 

565 mock_check_extra_spec.assert_not_called() 

566 mock_get_nfs_config.assert_not_called() 

567 

568 expected = { 

569 'vserver_name': fake.VSERVER1, 

570 'ports': jsonutils.dumps(ports), 

571 } 

572 if nfs_config_support: 

573 expected.update({'nfs_config': jsonutils.dumps(nfs_config)}) 

574 self.assertDictEqual(expected, result) 

575 if with_encryption: 

576 mock_barbican_kms_config.assert_called_once_with( 

577 fake.VSERVER1, fake_server_metadata) 

578 else: 

579 mock_barbican_kms_config.assert_not_called() 

580 

581 def test_setup_server_with_error(self): 

582 self.library.is_nfs_config_supported = False 

583 mock_get_vserver_name = self.mock_object( 

584 self.library, 

585 '_get_vserver_name', 

586 mock.Mock(return_value=fake.VSERVER1)) 

587 

588 fake_exception = exception.ManilaException("fake") 

589 mock_create_vserver = self.mock_object( 

590 self.library, 

591 '_create_vserver', 

592 mock.Mock(side_effect=fake_exception)) 

593 

594 mock_validate_network_type = self.mock_object( 

595 self.library, 

596 '_validate_network_type') 

597 

598 mock_validate_share_network_subnets = self.mock_object( 

599 self.library, 

600 '_validate_share_network_subnets') 

601 self.mock_object(self.library, '_set_network_with_metadata') 

602 

603 self.assertRaises( 

604 exception.ManilaException, 

605 self.library.setup_server, 

606 fake.NETWORK_INFO_LIST, 

607 fake.SERVER_METADATA) 

608 

609 ports = {} 

610 for network_allocation in fake.NETWORK_INFO['network_allocations']: 

611 ports[network_allocation['id']] = network_allocation['ip_address'] 

612 

613 self.assertTrue(mock_validate_network_type.called) 

614 self.assertTrue(mock_validate_share_network_subnets.called) 

615 self.assertTrue(mock_get_vserver_name.called) 

616 self.assertTrue(mock_create_vserver.called) 

617 

618 self.assertDictEqual( 

619 {'server_details': { 

620 'vserver_name': fake.VSERVER1, 

621 'ports': jsonutils.dumps(ports), 

622 }}, 

623 fake_exception.detail_data) 

624 

625 def test_setup_server_invalid_subnet(self): 

626 invalid_subnet_exception = exception.NetworkBadConfigurationException( 

627 reason='This is a fake message') 

628 self.mock_object(self.library, '_get_vserver_name', 

629 mock.Mock(return_value=fake.VSERVER1)) 

630 self.mock_object(self.library, '_validate_network_type') 

631 self.mock_object(self.library, '_validate_share_network_subnets', 

632 mock.Mock(side_effect=invalid_subnet_exception)) 

633 self.mock_object(self.library, '_set_network_with_metadata') 

634 

635 self.assertRaises( 

636 exception.NetworkBadConfigurationException, 

637 self.library.setup_server, 

638 fake.NETWORK_INFO_LIST) 

639 

640 self.library._validate_share_network_subnets.assert_called_once_with( 

641 fake.NETWORK_INFO_LIST) 

642 

643 def test_validate_share_network_subnets(self): 

644 fake_vlan = fake.NETWORK_INFO['segmentation_id'] 

645 network_info_different_seg_id = copy.deepcopy(fake.NETWORK_INFO) 

646 network_info_different_seg_id['segmentation_id'] = fake_vlan 

647 allocations = network_info_different_seg_id['network_allocations'] 

648 allocations[0]['segmentation_id'] = fake_vlan 

649 fake.NETWORK_INFO_LIST.append(network_info_different_seg_id) 

650 

651 result = self.library._validate_share_network_subnets( 

652 fake.NETWORK_INFO_LIST) 

653 

654 self.assertIsNone(result) 

655 

656 def test_validate_share_network_subnets_invalid_vlan_config(self): 

657 network_info_different_seg_id = copy.deepcopy(fake.NETWORK_INFO) 

658 network_info_different_seg_id['segmentation_id'] = 4004 

659 allocations = network_info_different_seg_id['network_allocations'] 

660 allocations[0]['segmentation_id'] = 4004 

661 fake.NETWORK_INFO_LIST.append(network_info_different_seg_id) 

662 

663 self.assertRaises( 

664 exception.NetworkBadConfigurationException, 

665 self.library._validate_share_network_subnets, 

666 fake.NETWORK_INFO_LIST) 

667 

668 @ddt.data( 

669 {'network_info': [{'network_type': 'vlan', 'segmentation_id': 1000}]}, 

670 {'network_info': [{'network_type': None, 'segmentation_id': None}]}, 

671 {'network_info': [{'network_type': 'flat', 'segmentation_id': None}]}) 

672 @ddt.unpack 

673 def test_validate_network_type_with_valid_network_types(self, 

674 network_info): 

675 result = self.library._validate_network_type(network_info) 

676 self.assertIsNone(result) 

677 

678 @ddt.data( 

679 {'network_info': [{'network_type': 'vxlan', 'segmentation_id': 1000}]}, 

680 {'network_info': [{'network_type': 'gre', 'segmentation_id': 100}]}) 

681 @ddt.unpack 

682 def test_validate_network_type_with_invalid_network_types(self, 

683 network_info): 

684 self.assertRaises(exception.NetworkBadConfigurationException, 

685 self.library._validate_network_type, 

686 network_info) 

687 

688 def test_get_vserver_name(self): 

689 vserver_id = fake.NETWORK_INFO['server_id'] 

690 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

691 

692 actual_result = self.library._get_vserver_name(vserver_id) 

693 

694 self.assertEqual(vserver_name, actual_result) 

695 

696 @ddt.data({'existing_ipspace': None, 

697 'nfs_config': fake.NFS_CONFIG_TCP_UDP_MAX}, 

698 {'existing_ipspace': fake.IPSPACE, 'nfs_config': None}) 

699 @ddt.unpack 

700 def test_create_vserver(self, existing_ipspace, nfs_config): 

701 

702 versions = ['fake_v1', 'fake_v2'] 

703 self.library.configuration.netapp_enabled_share_protocols = versions 

704 self.library.configuration.netapp_cifs_aes_encryption = False 

705 vserver_id = fake.NETWORK_INFO['server_id'] 

706 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

707 fake_lif_home_ports = {fake.CLUSTER_NODES[0]: 'fake_port', 

708 fake.CLUSTER_NODES[1]: 'another_fake_port'} 

709 

710 vserver_client = mock.Mock() 

711 self.mock_object(self.library._client, 

712 'list_cluster_nodes', 

713 mock.Mock(return_value=fake.CLUSTER_NODES)) 

714 self.mock_object(self.library, 

715 '_get_node_data_port', 

716 mock.Mock(return_value='fake_port')) 

717 self.mock_object(context, 

718 'get_admin_context', 

719 mock.Mock(return_value='fake_admin_context')) 

720 self.mock_object(self.library, 

721 '_get_api_client', 

722 mock.Mock(return_value=vserver_client)) 

723 self.mock_object(self.library._client, 

724 'vserver_exists', 

725 mock.Mock(return_value=False)) 

726 self.mock_object(self.library, 

727 '_find_matching_aggregates', 

728 mock.Mock(return_value=fake.AGGREGATES)) 

729 self.mock_object(self.library, 

730 '_get_flexgroup_aggr_set', 

731 mock.Mock(return_value=fake.AGGREGATES)) 

732 self.mock_object(self.library, 

733 '_create_ipspace', 

734 mock.Mock(return_value=fake.IPSPACE)) 

735 self.mock_object(self.library, 

736 '_create_vserver_lifs') 

737 self.mock_object(self.library, 

738 '_create_vserver_routes') 

739 self.mock_object(self.library, 

740 '_create_vserver_admin_lif') 

741 self.mock_object(self.library._client, 

742 'create_port_and_broadcast_domain', 

743 mock.Mock(side_effect=['fake_port', 

744 'another_fake_port'])) 

745 get_ipspace_name_for_vlan_port = self.mock_object( 

746 self.library._client, 

747 'get_ipspace_name_for_vlan_port', 

748 mock.Mock(return_value=existing_ipspace)) 

749 

750 self.library._create_vserver(vserver_name, fake.NETWORK_INFO_LIST, 

751 fake.NFS_CONFIG_TCP_UDP_MAX, 

752 nfs_config=nfs_config) 

753 

754 get_ipspace_name_for_vlan_port.assert_called_once_with( 

755 fake.CLUSTER_NODES[0], 

756 'fake_port', 

757 fake.NETWORK_INFO['segmentation_id']) 

758 if not existing_ipspace: 

759 self.library._create_ipspace.assert_called_once_with( 

760 fake.NETWORK_INFO) 

761 self.library._client.create_vserver.assert_called_once_with( 

762 vserver_name, fake.ROOT_VOLUME_AGGREGATE, fake.ROOT_VOLUME, 

763 set(fake.AGGREGATES), fake.IPSPACE, 

764 fake.SECURITY_CERT_DEFAULT_EXPIRE_DAYS, 

765 fake.DELETE_RETENTION_HOURS, 

766 False) 

767 self.library._get_api_client.assert_called_once_with( 

768 vserver=vserver_name) 

769 self.library._create_vserver_lifs.assert_called_once_with( 

770 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE, 

771 lif_home_ports=fake_lif_home_ports) 

772 self.library._create_vserver_routes.assert_called_once_with( 

773 vserver_client, fake.NETWORK_INFO) 

774 self.library._create_vserver_admin_lif.assert_called_once_with( 

775 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE, 

776 lif_home_ports=fake_lif_home_ports) 

777 vserver_client.enable_nfs.assert_called_once_with( 

778 versions, nfs_config=nfs_config) 

779 self.library._client.setup_security_services.assert_called_once_with( 

780 fake.NETWORK_INFO['security_services'], vserver_client, 

781 vserver_name, False) 

782 self.library._get_flexgroup_aggr_set.assert_called_once_with() 

783 

784 @ddt.data(None, fake.IPSPACE) 

785 def test_create_vserver_dp_destination(self, existing_ipspace): 

786 versions = ['fake_v1', 'fake_v2'] 

787 self.library.configuration.netapp_enabled_share_protocols = versions 

788 vserver_id = fake.NETWORK_INFO['server_id'] 

789 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

790 

791 self.mock_object(self.library._client, 

792 'vserver_exists', 

793 mock.Mock(return_value=False)) 

794 self.mock_object(self.library._client, 

795 'list_cluster_nodes', 

796 mock.Mock(return_value=fake.CLUSTER_NODES)) 

797 self.mock_object(self.library, 

798 '_get_node_data_port', 

799 mock.Mock(return_value='fake_port')) 

800 self.mock_object(context, 

801 'get_admin_context', 

802 mock.Mock(return_value='fake_admin_context')) 

803 self.mock_object(self.library, 

804 '_find_matching_aggregates', 

805 mock.Mock(return_value=fake.AGGREGATES)) 

806 self.mock_object(self.library, 

807 '_get_flexgroup_aggr_set', 

808 mock.Mock(return_value=fake.AGGREGATES)) 

809 self.mock_object(self.library, 

810 '_create_ipspace', 

811 mock.Mock(return_value=fake.IPSPACE)) 

812 

813 get_ipspace_name_for_vlan_port = self.mock_object( 

814 self.library._client, 

815 'get_ipspace_name_for_vlan_port', 

816 mock.Mock(return_value=existing_ipspace)) 

817 self.mock_object(self.library, '_create_port_and_broadcast_domain') 

818 

819 self.library._create_vserver(vserver_name, fake.NETWORK_INFO_LIST, 

820 metadata={'migration_destination': True}) 

821 

822 get_ipspace_name_for_vlan_port.assert_called_once_with( 

823 fake.CLUSTER_NODES[0], 

824 'fake_port', 

825 fake.NETWORK_INFO['segmentation_id']) 

826 if not existing_ipspace: 

827 self.library._create_ipspace.assert_called_once_with( 

828 fake.NETWORK_INFO) 

829 create_server_mock = self.library._client.create_vserver_dp_destination 

830 create_server_mock.assert_called_once_with( 

831 vserver_name, fake.AGGREGATES, fake.IPSPACE, 

832 fake.DELETE_RETENTION_HOURS, False) 

833 self.library._create_port_and_broadcast_domain.assert_called_once_with( 

834 fake.IPSPACE, fake.NETWORK_INFO) 

835 self.library._get_flexgroup_aggr_set.assert_not_called() 

836 

837 def test_create_vserver_already_present(self): 

838 

839 vserver_id = fake.NETWORK_INFO['server_id'] 

840 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

841 

842 self.mock_object(context, 

843 'get_admin_context', 

844 mock.Mock(return_value='fake_admin_context')) 

845 self.mock_object(self.library._client, 

846 'vserver_exists', 

847 mock.Mock(return_value=True)) 

848 

849 self.assertRaises(exception.NetAppException, 

850 self.library._create_vserver, 

851 vserver_name, 

852 fake.NETWORK_INFO, 

853 fake.NFS_CONFIG_TCP_UDP_MAX) 

854 

855 @ddt.data( 

856 {'network_exception': netapp_api.NaApiError, 

857 'existing_ipspace': fake.IPSPACE}, 

858 {'network_exception': netapp_api.NaApiError, 

859 'existing_ipspace': None}, 

860 {'network_exception': exception.NetAppException, 

861 'existing_ipspace': None}, 

862 {'network_exception': exception.NetAppException, 

863 'existing_ipspace': fake.IPSPACE}) 

864 @ddt.unpack 

865 def test_create_vserver_lif_creation_failure(self, 

866 network_exception, 

867 existing_ipspace): 

868 

869 vserver_id = fake.NETWORK_INFO['server_id'] 

870 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

871 vserver_client = mock.Mock() 

872 security_service = fake.NETWORK_INFO['security_services'] 

873 

874 self.mock_object(self.library._client, 

875 'list_cluster_nodes', 

876 mock.Mock(return_value=fake.CLUSTER_NODES)) 

877 self.mock_object(self.library, 

878 '_get_node_data_port', 

879 mock.Mock(return_value='fake_port')) 

880 self.mock_object(context, 

881 'get_admin_context', 

882 mock.Mock(return_value='fake_admin_context')) 

883 self.mock_object(self.library, 

884 '_get_api_client', 

885 mock.Mock(return_value=vserver_client)) 

886 self.mock_object(self.library._client, 

887 'vserver_exists', 

888 mock.Mock(return_value=False)) 

889 self.mock_object(self.library, 

890 '_find_matching_aggregates', 

891 mock.Mock(return_value=fake.AGGREGATES)) 

892 self.mock_object(self.library, 

893 '_get_flexgroup_aggr_set', 

894 mock.Mock(return_value=fake.AGGREGATES)) 

895 self.mock_object(self.library._client, 

896 'get_ipspace_name_for_vlan_port', 

897 mock.Mock(return_value=existing_ipspace)) 

898 self.mock_object(self.library, 

899 '_create_ipspace', 

900 mock.Mock(return_value=fake.IPSPACE)) 

901 self.mock_object(self.library, 

902 '_setup_network_for_vserver', 

903 mock.Mock(side_effect=network_exception)) 

904 self.mock_object(self.library, '_delete_vserver') 

905 

906 self.assertRaises(network_exception, 

907 self.library._create_vserver, 

908 vserver_name, 

909 fake.NETWORK_INFO_LIST, 

910 fake.NFS_CONFIG_TCP_UDP_MAX) 

911 

912 self.library._get_api_client.assert_called_with(vserver=vserver_name) 

913 self.assertTrue(self.library._client.create_vserver.called) 

914 self.library._setup_network_for_vserver.assert_called_with( 

915 vserver_name, 

916 vserver_client, 

917 fake.NETWORK_INFO_LIST, 

918 fake.IPSPACE, 

919 security_services=security_service, 

920 nfs_config=None) 

921 self.library._delete_vserver.assert_called_once_with( 

922 vserver_name, 

923 needs_lock=False, 

924 security_services=security_service) 

925 self.assertFalse(vserver_client.enable_nfs.called) 

926 self.assertEqual(1, lib_multi_svm.LOG.error.call_count) 

927 

928 def test__create_barbican_kms_config_for_specified_vserver(self): 

929 

930 vserver_id = fake.NETWORK_INFO['server_id'] 

931 vserver_name = fake.VSERVER_NAME_TEMPLATE % vserver_id 

932 fake_config_uuid = "fake_uuid" 

933 

934 self.mock_object( 

935 share_utils, 'extract_host', 

936 mock.Mock( 

937 return_value=fake.SERVER_METADATA_WITH_ENCRYPTION[ 

938 'request_host'])) 

939 self.mock_object(data_motion, 'get_client_for_backend', 

940 mock.Mock(return_value=self.fake_client)) 

941 self.mock_object(self.fake_client, 

942 'create_barbican_kms_config_for_specified_vserver') 

943 self.mock_object(self.fake_client, 

944 'get_key_store_config_uuid', 

945 mock.Mock(return_value=fake_config_uuid)) 

946 self.mock_object(self.fake_client, 

947 'enable_key_store_config') 

948 

949 self.library._create_barbican_kms_config_for_specified_vserver( 

950 vserver_name, fake.SERVER_METADATA_WITH_ENCRYPTION) 

951 

952 share_utils.extract_host.assert_called_once_with( 

953 fake.SERVER_METADATA_WITH_ENCRYPTION['request_host'], 

954 level='backend_name') 

955 data_motion.get_client_for_backend.assert_called_once_with( 

956 fake.SERVER_METADATA_WITH_ENCRYPTION['request_host'], 

957 vserver_name=None, 

958 force_rest_client=True) 

959 self.fake_client.create_barbican_kms_config_for_specified_vserver.\ 

960 assert_called_once_with( 

961 vserver_name, mock.ANY, 

962 fake.SERVER_METADATA_WITH_ENCRYPTION['encryption_key_ref'], 

963 fake.SERVER_METADATA_WITH_ENCRYPTION['keystone_url'], 

964 fake.SERVER_METADATA_WITH_ENCRYPTION 

965 ['application_credential_id'], 

966 fake.SERVER_METADATA_WITH_ENCRYPTION 

967 ['application_credential_secret']) 

968 self.fake_client.enable_key_store_config(fake_config_uuid) 

969 

970 def test_get_valid_ipspace_name(self): 

971 

972 result = self.library._get_valid_ipspace_name(fake.IPSPACE_ID) 

973 

974 expected = 'ipspace_' + fake.IPSPACE_ID.replace('-', '_') 

975 self.assertEqual(expected, result) 

976 

977 def test_create_ipspace_not_supported(self): 

978 

979 self.library._client.features.IPSPACES = False 

980 

981 result = self.library._create_ipspace(fake.NETWORK_INFO) 

982 

983 self.assertIsNone(result) 

984 

985 @ddt.data(None, 'flat') 

986 def test_create_ipspace_not_vlan(self, network_type): 

987 

988 self.library._client.features.IPSPACES = True 

989 network_info = copy.deepcopy(fake.NETWORK_INFO) 

990 network_info['network_allocations'][0]['segmentation_id'] = None 

991 network_info['network_allocations'][0]['network_type'] = network_type 

992 

993 result = self.library._create_ipspace(network_info) 

994 

995 self.assertEqual('Default', result) 

996 

997 def test_create_ipspace(self): 

998 

999 self.library._client.features.IPSPACES = True 

1000 self.mock_object(self.library._client, 

1001 'create_ipspace', 

1002 mock.Mock(return_value=False)) 

1003 

1004 result = self.library._create_ipspace(fake.NETWORK_INFO) 

1005 

1006 expected = self.library._get_valid_ipspace_name( 

1007 fake.NETWORK_INFO['neutron_net_id']) 

1008 self.assertEqual(expected, result) 

1009 self.library._client.create_ipspace.assert_called_once_with(expected) 

1010 

1011 def test_create_vserver_lifs(self): 

1012 

1013 self.mock_object(self.library._client, 

1014 'list_cluster_nodes', 

1015 mock.Mock(return_value=fake.CLUSTER_NODES)) 

1016 self.mock_object(self.library, 

1017 '_get_lif_name', 

1018 mock.Mock(side_effect=['fake_lif1', 'fake_lif2'])) 

1019 self.mock_object(self.library, '_create_lif') 

1020 

1021 self.library._create_vserver_lifs(fake.VSERVER1, 

1022 'fake_vserver_client', 

1023 fake.NETWORK_INFO, 

1024 fake.IPSPACE) 

1025 

1026 self.library._create_lif.assert_has_calls([ 

1027 mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE, 

1028 fake.CLUSTER_NODES[0], 'fake_lif1', 

1029 fake.NETWORK_INFO['network_allocations'][0], 

1030 lif_home_port=None), 

1031 mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE, 

1032 fake.CLUSTER_NODES[1], 'fake_lif2', 

1033 fake.NETWORK_INFO['network_allocations'][1], 

1034 lif_home_port=None)]) 

1035 

1036 def test_create_vserver_lifs_pre_configured_home_ports(self): 

1037 

1038 self.mock_object(self.library._client, 

1039 'list_cluster_nodes', 

1040 mock.Mock(return_value=fake.CLUSTER_NODES)) 

1041 self.mock_object(self.library, 

1042 '_get_lif_name', 

1043 mock.Mock(side_effect=['fake_lif1', 'fake_lif2'])) 

1044 self.mock_object(self.library, '_create_lif') 

1045 

1046 lif_home_ports = { 

1047 fake.CLUSTER_NODES[0]: 'fake_port1', 

1048 fake.CLUSTER_NODES[1]: 'fake_port2' 

1049 } 

1050 

1051 self.library._create_vserver_lifs(fake.VSERVER1, 

1052 'fake_vserver_client', 

1053 fake.NETWORK_INFO, 

1054 fake.IPSPACE, 

1055 lif_home_ports=lif_home_ports) 

1056 

1057 self.library._create_lif.assert_has_calls([ 

1058 mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE, 

1059 fake.CLUSTER_NODES[0], 'fake_lif1', 

1060 fake.NETWORK_INFO['network_allocations'][0], 

1061 lif_home_port=lif_home_ports[fake.CLUSTER_NODES[0]]), 

1062 mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE, 

1063 fake.CLUSTER_NODES[1], 'fake_lif2', 

1064 fake.NETWORK_INFO['network_allocations'][1], 

1065 lif_home_port=lif_home_ports[fake.CLUSTER_NODES[1]])]) 

1066 

1067 def test_create_vserver_admin_lif(self): 

1068 

1069 self.mock_object(self.library._client, 

1070 'list_cluster_nodes', 

1071 mock.Mock(return_value=fake.CLUSTER_NODES)) 

1072 self.mock_object(self.library, 

1073 '_get_lif_name', 

1074 mock.Mock(return_value='fake_admin_lif')) 

1075 self.mock_object(self.library, '_create_lif') 

1076 

1077 self.library._create_vserver_admin_lif(fake.VSERVER1, 

1078 'fake_vserver_client', 

1079 fake.NETWORK_INFO, 

1080 fake.IPSPACE) 

1081 

1082 self.library._create_lif.assert_has_calls([ 

1083 mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE, 

1084 fake.CLUSTER_NODES[0], 'fake_admin_lif', 

1085 fake.NETWORK_INFO['admin_network_allocations'][0], 

1086 lif_home_port=None)]) 

1087 

1088 def test_create_vserver_admin_lif_no_admin_network(self): 

1089 

1090 fake_network_info = copy.deepcopy(fake.NETWORK_INFO) 

1091 fake_network_info['admin_network_allocations'] = [] 

1092 

1093 self.mock_object(self.library._client, 

1094 'list_cluster_nodes', 

1095 mock.Mock(return_value=fake.CLUSTER_NODES)) 

1096 self.mock_object(self.library, 

1097 '_get_lif_name', 

1098 mock.Mock(return_value='fake_admin_lif')) 

1099 self.mock_object(self.library, '_create_lif') 

1100 

1101 self.library._create_vserver_admin_lif(fake.VSERVER1, 

1102 'fake_vserver_client', 

1103 fake_network_info, 

1104 fake.IPSPACE) 

1105 

1106 self.assertFalse(self.library._create_lif.called) 

1107 

1108 @ddt.data( 

1109 fake.get_network_info(fake.USER_NETWORK_ALLOCATIONS, 

1110 fake.ADMIN_NETWORK_ALLOCATIONS), 

1111 fake.get_network_info(fake.USER_NETWORK_ALLOCATIONS_IPV6, 

1112 fake.ADMIN_NETWORK_ALLOCATIONS)) 

1113 def test_create_vserver_routes(self, network_info): 

1114 expected_gateway = network_info['network_allocations'][0]['gateway'] 

1115 vserver_client = mock.Mock() 

1116 self.mock_object(vserver_client, 'create_route') 

1117 

1118 retval = self.library._create_vserver_routes( 

1119 vserver_client, network_info) 

1120 

1121 self.assertIsNone(retval) 

1122 vserver_client.create_route.assert_called_once_with(expected_gateway) 

1123 

1124 def test_get_node_data_port(self): 

1125 

1126 self.mock_object(self.client, 

1127 'list_node_data_ports', 

1128 mock.Mock(return_value=fake.NODE_DATA_PORTS)) 

1129 self.library.configuration.netapp_port_name_search_pattern = 'e0c' 

1130 

1131 result = self.library._get_node_data_port(fake.CLUSTER_NODE) 

1132 

1133 self.assertEqual('e0c', result) 

1134 self.library._client.list_node_data_ports.assert_has_calls([ 

1135 mock.call(fake.CLUSTER_NODE)]) 

1136 

1137 def test_get_node_data_port_no_match(self): 

1138 

1139 self.mock_object(self.client, 

1140 'list_node_data_ports', 

1141 mock.Mock(return_value=fake.NODE_DATA_PORTS)) 

1142 self.library.configuration.netapp_port_name_search_pattern = 'ifgroup1' 

1143 

1144 self.assertRaises(exception.NetAppException, 

1145 self.library._get_node_data_port, 

1146 fake.CLUSTER_NODE) 

1147 

1148 def test_get_lif_name(self): 

1149 

1150 result = self.library._get_lif_name( 

1151 'fake_node', fake.NETWORK_INFO['network_allocations'][0]) 

1152 

1153 self.assertEqual('os_132dbb10-9a36-46f2-8d89-3d909830c356', result) 

1154 

1155 @ddt.data(fake.MTU, None, 'not-present') 

1156 def test_create_lif(self, mtu): 

1157 """Tests cases where MTU is a valid value, None or not present.""" 

1158 

1159 expected_mtu = (mtu if mtu not in (None, 'not-present') else 

1160 fake.DEFAULT_MTU) 

1161 

1162 network_allocations = copy.deepcopy( 

1163 fake.NETWORK_INFO['network_allocations'][0]) 

1164 network_allocations['mtu'] = mtu 

1165 

1166 if mtu == 'not-present': 

1167 network_allocations.pop('mtu') 

1168 

1169 vserver_client = mock.Mock() 

1170 

1171 self.mock_object(self.library, '_get_node_data_port', 

1172 mock.Mock(return_value='fake_port')) 

1173 

1174 vserver_client.network_interface_exists = mock.Mock( 

1175 return_value=False) 

1176 

1177 self.library._client.create_port_and_broadcast_domain = ( 

1178 mock.Mock(return_value='fake_port')) 

1179 

1180 self.library._create_lif(vserver_client, 

1181 'fake_vserver', 

1182 'fake_ipspace', 

1183 'fake_node', 

1184 'fake_lif', 

1185 network_allocations, 

1186 lif_home_port=None) 

1187 

1188 self.library._get_node_data_port.assert_called_once_with( 

1189 'fake_node') 

1190 

1191 (vserver_client.network_interface_exists 

1192 .assert_called_once_with('fake_vserver', 'fake_node', 'fake_port', 

1193 '10.10.10.10', '255.255.255.0', '1000', 

1194 home_port=None)) 

1195 

1196 (self.library._client.create_port_and_broadcast_domain 

1197 .assert_called_once_with('fake_node', 'fake_port', '1000', 

1198 expected_mtu, 'fake_ipspace')) 

1199 

1200 (self.library._client.create_network_interface 

1201 .assert_called_once_with('10.10.10.10', '255.255.255.0', 

1202 'fake_node', 'fake_port', 

1203 'fake_vserver', 'fake_lif')) 

1204 

1205 def test_create_lif_existent_home_port(self): 

1206 """Tests case where a existent port is passed to the function""" 

1207 

1208 network_allocations = copy.deepcopy( 

1209 fake.NETWORK_INFO['network_allocations'][0]) 

1210 

1211 vserver_client = mock.Mock() 

1212 mock_get_node_data_port = self.mock_object( 

1213 self.library, '_get_node_data_port') 

1214 

1215 vserver_client.network_interface_exists = mock.Mock( 

1216 return_value=False) 

1217 

1218 mock_create_port_and_broadcast_domain = ( 

1219 self.library._client.create_port_and_broadcast_domain) 

1220 

1221 self.library._create_lif(vserver_client, 

1222 'fake_vserver', 

1223 'fake_ipspace', 

1224 'fake_node', 

1225 'fake_lif', 

1226 network_allocations, 

1227 lif_home_port='fake_port_from_param') 

1228 

1229 (vserver_client.network_interface_exists 

1230 .assert_called_once_with('fake_vserver', 'fake_node', 

1231 'fake_port_from_param', 

1232 '10.10.10.10', '255.255.255.0', '1000', 

1233 home_port='fake_port_from_param')) 

1234 

1235 mock_get_node_data_port.assert_not_called() 

1236 mock_create_port_and_broadcast_domain.assert_not_called() 

1237 

1238 (self.library._client.create_network_interface 

1239 .assert_called_once_with('10.10.10.10', '255.255.255.0', 

1240 'fake_node', 'fake_port_from_param', 

1241 'fake_vserver', 'fake_lif')) 

1242 

1243 def test_create_lif_if_nonexistent_already_present(self): 

1244 

1245 vserver_client = mock.Mock() 

1246 vserver_client.network_interface_exists = mock.Mock( 

1247 return_value=True) 

1248 self.mock_object(self.library, 

1249 '_get_node_data_port', 

1250 mock.Mock(return_value='fake_port')) 

1251 

1252 self.library._create_lif(vserver_client, 

1253 'fake_vserver', 

1254 fake.IPSPACE, 

1255 'fake_node', 

1256 'fake_lif', 

1257 fake.NETWORK_INFO['network_allocations'][0], 

1258 lif_home_port=None) 

1259 

1260 self.assertFalse(self.library._client.create_network_interface.called) 

1261 

1262 def test_get_network_allocations_number(self): 

1263 

1264 self.library._client.list_cluster_nodes.return_value = ( 

1265 fake.CLUSTER_NODES) 

1266 

1267 result = self.library.get_network_allocations_number() 

1268 

1269 self.assertEqual(len(fake.CLUSTER_NODES), result) 

1270 

1271 def test_get_admin_network_allocations_number(self): 

1272 

1273 result = self.library.get_admin_network_allocations_number( 

1274 'fake_admin_network_api') 

1275 

1276 self.assertEqual(1, result) 

1277 

1278 def test_get_admin_network_allocations_number_no_admin_network(self): 

1279 

1280 result = self.library.get_admin_network_allocations_number(None) 

1281 

1282 self.assertEqual(0, result) 

1283 

1284 def test_teardown_server(self): 

1285 

1286 self.library._client.vserver_exists.return_value = True 

1287 mock_delete_vserver = self.mock_object(self.library, 

1288 '_delete_vserver') 

1289 

1290 self.library.teardown_server( 

1291 fake.SHARE_SERVER['backend_details'], 

1292 security_services=fake.NETWORK_INFO['security_services']) 

1293 

1294 self.library._client.vserver_exists.assert_called_once_with( 

1295 fake.VSERVER1) 

1296 mock_delete_vserver.assert_called_once_with( 

1297 fake.VSERVER1, 

1298 security_services=fake.NETWORK_INFO['security_services']) 

1299 

1300 @ddt.data(None, {}, {'vserver_name': None}) 

1301 def test_teardown_server_no_share_server(self, server_details): 

1302 

1303 mock_delete_vserver = self.mock_object(self.library, 

1304 '_delete_vserver') 

1305 

1306 self.library.teardown_server(server_details) 

1307 

1308 self.assertFalse(mock_delete_vserver.called) 

1309 self.assertTrue(lib_multi_svm.LOG.warning.called) 

1310 

1311 def test_teardown_server_no_vserver(self): 

1312 

1313 self.library._client.vserver_exists.return_value = False 

1314 mock_delete_vserver = self.mock_object(self.library, 

1315 '_delete_vserver') 

1316 

1317 self.library.teardown_server( 

1318 fake.SHARE_SERVER['backend_details'], 

1319 security_services=fake.NETWORK_INFO['security_services']) 

1320 

1321 self.library._client.vserver_exists.assert_called_once_with( 

1322 fake.VSERVER1) 

1323 self.assertFalse(mock_delete_vserver.called) 

1324 self.assertTrue(lib_multi_svm.LOG.warning.called) 

1325 

1326 @ddt.data(True, False) 

1327 def test_delete_vserver_no_ipspace(self, lock): 

1328 

1329 self.mock_object(self.library._client, 

1330 'get_ipspaces', 

1331 mock.Mock(return_value=[])) 

1332 vserver_client = mock.Mock() 

1333 self.mock_object(self.library, 

1334 '_get_api_client', 

1335 mock.Mock(return_value=vserver_client)) 

1336 self.mock_object(self.library._client, 

1337 'get_snapmirror_policies', 

1338 mock.Mock(return_value=[])) 

1339 

1340 net_interfaces = copy.deepcopy(c_fake.NETWORK_INTERFACES_MULTIPLE) 

1341 

1342 self.mock_object(vserver_client, 

1343 'get_network_interfaces', 

1344 mock.Mock(return_value=net_interfaces)) 

1345 security_services = fake.NETWORK_INFO['security_services'] 

1346 self.mock_object(self.library, '_delete_vserver_peers') 

1347 self.mock_object(self.library, '_delete_port_vlans') 

1348 

1349 self.library._delete_vserver(fake.VSERVER1, 

1350 security_services=security_services, 

1351 needs_lock=lock) 

1352 

1353 self.library._client.get_ipspaces.assert_called_once_with( 

1354 vserver_name=fake.VSERVER1) 

1355 self.library._delete_vserver_peers.assert_called_once_with( 

1356 fake.VSERVER1) 

1357 self.library._client.delete_vserver.assert_called_once_with( 

1358 fake.VSERVER1, vserver_client, security_services=security_services) 

1359 self.library._client.delete_ipspace.assert_not_called() 

1360 self.library._delete_port_vlans.assert_not_called() 

1361 self.library._client.delete_vlan.assert_not_called() 

1362 

1363 @ddt.data(True, False) 

1364 def test_delete_vserver_ipspace_has_data_vservers(self, lock): 

1365 

1366 self.library._client.features.IPSPACES = True 

1367 self.mock_object(self.library._client, 

1368 'get_ipspaces', 

1369 mock.Mock(return_value=c_fake.IPSPACES)) 

1370 vserver_client = mock.Mock() 

1371 self.mock_object(self.library, 

1372 '_get_api_client', 

1373 mock.Mock(return_value=vserver_client)) 

1374 self.mock_object(self.library._client, 

1375 'ipspace_has_data_vservers', 

1376 mock.Mock(return_value=True)) 

1377 self.mock_object(self.library._client, 

1378 'get_snapmirror_policies', 

1379 mock.Mock(return_value=[])) 

1380 self.mock_object(self.library, '_delete_vserver_peers') 

1381 self.mock_object( 

1382 vserver_client, 'get_network_interfaces', 

1383 mock.Mock(return_value=c_fake.NETWORK_INTERFACES)) 

1384 self.mock_object(self.library._client, 

1385 'delete_ipspace', 

1386 mock.Mock(return_value=False)) 

1387 self.mock_object(self.library._client, 

1388 'get_degraded_ports', 

1389 mock.Mock(return_value=[])) 

1390 self.mock_object(self.library, '_delete_port_vlans') 

1391 security_services = fake.NETWORK_INFO['security_services'] 

1392 

1393 self.library._delete_vserver(fake.VSERVER1, 

1394 security_services=security_services, 

1395 needs_lock=lock) 

1396 

1397 self.library._client.get_ipspaces.assert_called_once_with( 

1398 vserver_name=fake.VSERVER1) 

1399 self.library._client.delete_vserver.assert_called_once_with( 

1400 fake.VSERVER1, vserver_client, security_services=security_services) 

1401 self.library._delete_vserver_peers.assert_called_once_with( 

1402 fake.VSERVER1) 

1403 self.library._client.delete_ipspace.assert_called_once_with( 

1404 c_fake.IPSPACE_NAME 

1405 ) 

1406 self.library._client.get_degraded_ports.assert_called_once_with( 

1407 [c_fake.BROADCAST_DOMAIN], c_fake.IPSPACE_NAME 

1408 ) 

1409 # not NETWORK_QUALIFIED_PORTS2, which would be given by get_ipspaces() 

1410 self.library._delete_port_vlans.assert_called_once_with( 

1411 self.library._client, set(c_fake.NETWORK_QUALIFIED_PORTS)) 

1412 

1413 @ddt.data([], c_fake.NETWORK_INTERFACES) 

1414 def test_delete_vserver_with_ipspace(self, interfaces): 

1415 

1416 self.mock_object(self.library._client, 

1417 'get_ipspaces', 

1418 mock.Mock(return_value=c_fake.IPSPACES)) 

1419 vserver_client = mock.Mock() 

1420 self.mock_object(self.library, 

1421 '_get_api_client', 

1422 mock.Mock(return_value=vserver_client)) 

1423 self.mock_object(self.library._client, 

1424 'ipspace_has_data_vservers', 

1425 mock.Mock(return_value=False)) 

1426 self.mock_object(self.library, '_delete_vserver_peers') 

1427 self.mock_object(vserver_client, 

1428 'get_network_interfaces', 

1429 mock.Mock(return_value=interfaces)) 

1430 self.mock_object(self.library._client, 

1431 'get_snapmirror_policies', 

1432 mock.Mock(return_value=['fake_policy'])) 

1433 

1434 security_services = fake.NETWORK_INFO['security_services'] 

1435 

1436 self.library._delete_vserver(fake.VSERVER1, 

1437 security_services=security_services) 

1438 vserver_client.delete_snapmirror_policy.assert_called_once_with( 

1439 'fake_policy') 

1440 self.library._delete_vserver_peers.assert_called_once_with( 

1441 fake.VSERVER1 

1442 ) 

1443 self.library._client.get_ipspaces.assert_called_once_with( 

1444 vserver_name=fake.VSERVER1) 

1445 self.library._client.delete_vserver.assert_called_once_with( 

1446 fake.VSERVER1, vserver_client, security_services=security_services) 

1447 self.library._client.delete_ipspace.assert_called_once_with( 

1448 c_fake.IPSPACE_NAME) 

1449 self.library._client.get_degraded_ports.assert_not_called() 

1450 self.library._client.delete_vlan.assert_called_once_with( 

1451 c_fake.NODE_NAME2, c_fake.PORT, c_fake.VLAN) 

1452 

1453 def test__delete_vserver_peers(self): 

1454 

1455 self.mock_object(self.library, 

1456 '_get_vserver_peers', 

1457 mock.Mock(return_value=fake.VSERVER_PEER)) 

1458 self.mock_object(self.library, '_delete_vserver_peer') 

1459 

1460 self.library._delete_vserver_peers(fake.VSERVER1) 

1461 

1462 self.library._get_vserver_peers.assert_called_once_with( 

1463 vserver=fake.VSERVER1 

1464 ) 

1465 self.library._delete_vserver_peer.assert_called_once_with( 

1466 fake.VSERVER_PEER[0]['vserver'], 

1467 fake.VSERVER_PEER[0]['peer-vserver'] 

1468 ) 

1469 

1470 def test_delete_port_vlans(self): 

1471 

1472 self.library._delete_port_vlans(self.library._client, 

1473 c_fake.NETWORK_QUALIFIED_PORTS) 

1474 for port_name in c_fake.NETWORK_QUALIFIED_PORTS: 

1475 node, port = port_name.split(':') 

1476 port, vlan = port.split('-') 

1477 self.library._client.delete_vlan.assert_called_once_with( 

1478 node, port, vlan) 

1479 

1480 def test_delete_port_vlans_client_error(self): 

1481 

1482 mock_exception_log = self.mock_object(lib_multi_svm.LOG, 'exception') 

1483 self.mock_object( 

1484 self.library._client, 

1485 'delete_vlan', 

1486 mock.Mock(side_effect=exception.NetAppException("fake error"))) 

1487 

1488 self.library._delete_port_vlans(self.library._client, 

1489 c_fake.NETWORK_QUALIFIED_PORTS) 

1490 for port_name in c_fake.NETWORK_QUALIFIED_PORTS: 

1491 node, port = port_name.split(':') 

1492 port, vlan = port.split('-') 

1493 self.library._client.delete_vlan.assert_called_once_with( 

1494 node, port, vlan) 

1495 self.assertEqual(1, mock_exception_log.call_count) 

1496 

1497 @ddt.data([], [{'vserver': c_fake.VSERVER_NAME, 

1498 'peer-vserver': c_fake.VSERVER_PEER_NAME, 

1499 'applications': [ 

1500 {'vserver-peer-application': 'snapmirror'}] 

1501 }]) 

1502 def test_create_replica(self, vserver_peers): 

1503 fake_cluster_name = 'fake_cluster' 

1504 self.mock_object(self.library, '_get_vservers_from_replicas', 

1505 mock.Mock(return_value=(self.fake_vserver, 

1506 self.fake_new_vserver_name))) 

1507 self.mock_object(self.library, 'find_active_replica', 

1508 mock.Mock(return_value=self.fake_replica)) 

1509 self.mock_object(share_utils, 'extract_host', 

1510 mock.Mock(side_effect=[self.fake_new_replica_host, 

1511 self.fake_replica_host])) 

1512 self.mock_object(data_motion, 'get_client_for_backend', 

1513 mock.Mock(side_effect=[self.fake_new_client, 

1514 self.fake_client])) 

1515 self.mock_object(self.library, '_get_vserver_peers', 

1516 mock.Mock(return_value=vserver_peers)) 

1517 self.mock_object(self.fake_new_client, 'get_cluster_name', 

1518 mock.Mock(return_value=fake_cluster_name)) 

1519 self.mock_object(self.fake_client, 'create_vserver_peer') 

1520 self.mock_object(self.fake_new_client, 'accept_vserver_peer') 

1521 lib_base_model_update = { 

1522 'export_locations': [], 

1523 'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC, 

1524 'access_rules_status': constants.STATUS_ACTIVE, 

1525 } 

1526 self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

1527 'create_replica', 

1528 mock.Mock(return_value=lib_base_model_update)) 

1529 

1530 model_update = self.library.create_replica( 

1531 None, [self.fake_replica], self.fake_new_replica, [], [], 

1532 share_server=None) 

1533 

1534 self.assertDictEqual(lib_base_model_update, model_update) 

1535 self.library._get_vservers_from_replicas.assert_called_once_with( 

1536 None, [self.fake_replica], self.fake_new_replica 

1537 ) 

1538 self.library.find_active_replica.assert_called_once_with( 

1539 [self.fake_replica] 

1540 ) 

1541 self.assertEqual(2, share_utils.extract_host.call_count) 

1542 self.assertEqual(2, data_motion.get_client_for_backend.call_count) 

1543 self.library._get_vserver_peers.assert_called_once_with( 

1544 self.fake_new_vserver_name, self.fake_vserver 

1545 ) 

1546 self.fake_new_client.get_cluster_name.assert_called_once_with() 

1547 if not vserver_peers: 

1548 self.fake_client.create_vserver_peer.assert_called_once_with( 

1549 self.fake_new_vserver_name, self.fake_vserver, 

1550 peer_cluster_name=fake_cluster_name 

1551 ) 

1552 self.fake_new_client.accept_vserver_peer.assert_called_once_with( 

1553 self.fake_vserver, self.fake_new_vserver_name 

1554 ) 

1555 base_class = lib_base.NetAppCmodeFileStorageLibrary 

1556 base_class.create_replica.assert_called_once_with( 

1557 None, [self.fake_replica], self.fake_new_replica, [], [] 

1558 ) 

1559 

1560 def test_delete_replica(self): 

1561 base_class = lib_base.NetAppCmodeFileStorageLibrary 

1562 vserver_peers = copy.deepcopy(fake.VSERVER_PEER) 

1563 vserver_peers[0]['vserver'] = self.fake_vserver 

1564 vserver_peers[0]['peer-vserver'] = self.fake_new_vserver_name 

1565 self.mock_object(self.library, '_get_vservers_from_replicas', 

1566 mock.Mock(return_value=(self.fake_vserver, 

1567 self.fake_new_vserver_name))) 

1568 self.mock_object(base_class, 'delete_replica') 

1569 self.mock_object(self.library, '_get_snapmirrors_destinations', 

1570 mock.Mock(return_value=[])) 

1571 self.mock_object(self.library, '_get_snapmirrors', 

1572 mock.Mock(return_value=[])) 

1573 self.mock_object(self.library, '_get_vserver_peers', 

1574 mock.Mock(return_value=vserver_peers)) 

1575 self.mock_object(self.library, '_delete_vserver_peer') 

1576 

1577 self.library.delete_replica(None, [self.fake_replica], 

1578 self.fake_new_replica, [], 

1579 share_server=None) 

1580 

1581 self.library._get_vservers_from_replicas.assert_called_once_with( 

1582 None, [self.fake_replica], self.fake_new_replica 

1583 ) 

1584 self.library._get_snapmirrors_destinations.assert_has_calls( 

1585 [mock.call(self.fake_vserver, self.fake_new_vserver_name), 

1586 mock.call(self.fake_new_vserver_name, self.fake_vserver)] 

1587 ) 

1588 base_class.delete_replica.assert_called_once_with( 

1589 None, [self.fake_replica], self.fake_new_replica, [] 

1590 ) 

1591 self.library._get_snapmirrors.assert_has_calls( 

1592 [mock.call(self.fake_vserver, self.fake_new_vserver_name), 

1593 mock.call(self.fake_new_vserver_name, self.fake_vserver)] 

1594 ) 

1595 self.library._get_vserver_peers.assert_called_once_with( 

1596 self.fake_new_vserver_name, self.fake_vserver 

1597 ) 

1598 self.library._delete_vserver_peer.assert_called_once_with( 

1599 self.fake_new_vserver_name, self.fake_vserver 

1600 ) 

1601 

1602 def test_get_vservers_from_replicas(self): 

1603 self.mock_object(self.library, 'find_active_replica', 

1604 mock.Mock(return_value=self.fake_replica)) 

1605 

1606 vserver, peer_vserver = self.library._get_vservers_from_replicas( 

1607 None, [self.fake_replica], self.fake_new_replica) 

1608 

1609 self.library.find_active_replica.assert_called_once_with( 

1610 [self.fake_replica] 

1611 ) 

1612 self.assertEqual(self.fake_vserver, vserver) 

1613 self.assertEqual(self.fake_new_vserver_name, peer_vserver) 

1614 

1615 def test_get_vserver_peers(self): 

1616 self.mock_object(self.library._client, 'get_vserver_peers') 

1617 

1618 self.library._get_vserver_peers( 

1619 vserver=self.fake_vserver, peer_vserver=self.fake_new_vserver_name) 

1620 

1621 self.library._client.get_vserver_peers.assert_called_once_with( 

1622 self.fake_vserver, self.fake_new_vserver_name 

1623 ) 

1624 

1625 def test_create_vserver_peer(self): 

1626 self.mock_object(self.library._client, 'create_vserver_peer') 

1627 

1628 self.library._create_vserver_peer( 

1629 None, vserver=self.fake_vserver, 

1630 peer_vserver=self.fake_new_vserver_name) 

1631 

1632 self.library._client.create_vserver_peer.assert_called_once_with( 

1633 self.fake_vserver, self.fake_new_vserver_name 

1634 ) 

1635 

1636 def test_delete_vserver_peer(self): 

1637 self.mock_object(self.library._client, 'delete_vserver_peer') 

1638 

1639 self.library._delete_vserver_peer( 

1640 vserver=self.fake_vserver, peer_vserver=self.fake_new_vserver_name) 

1641 

1642 self.library._client.delete_vserver_peer.assert_called_once_with( 

1643 self.fake_vserver, self.fake_new_vserver_name 

1644 ) 

1645 

1646 def test_create_share_from_snapshot(self): 

1647 fake_parent_share = copy.deepcopy(fake.SHARE) 

1648 fake_parent_share['id'] = fake.SHARE_ID2 

1649 mock_create_from_snap = self.mock_object( 

1650 lib_base.NetAppCmodeFileStorageLibrary, 

1651 'create_share_from_snapshot') 

1652 

1653 self.library.create_share_from_snapshot( 

1654 None, fake.SHARE, fake.SNAPSHOT, share_server=fake.SHARE_SERVER, 

1655 parent_share=fake_parent_share) 

1656 

1657 mock_create_from_snap.assert_called_once_with( 

1658 None, fake.SHARE, fake.SNAPSHOT, share_server=fake.SHARE_SERVER, 

1659 parent_share=fake_parent_share 

1660 ) 

1661 

1662 def test_create_share_from_snapshot_group(self): 

1663 share = copy.deepcopy(fake.SHARE) 

1664 share['source_share_group_snapshot_member_id'] = ( 

1665 fake.CG_SNAPSHOT_MEMBER_ID1) 

1666 fake_parent_share = copy.deepcopy(fake.SHARE) 

1667 fake_parent_share['id'] = fake.SHARE_ID2 

1668 fake_parent_share['host'] = fake.MANILA_HOST_NAME_2 

1669 mock_create_from_snap = self.mock_object( 

1670 lib_base.NetAppCmodeFileStorageLibrary, 

1671 'create_share_from_snapshot') 

1672 mock_data_session = self.mock_object(data_motion, 'DataMotionSession') 

1673 

1674 self.library.create_share_from_snapshot( 

1675 None, share, fake.SNAPSHOT, share_server=fake.SHARE_SERVER, 

1676 parent_share=fake_parent_share) 

1677 

1678 mock_create_from_snap.assert_called_once_with( 

1679 None, share, fake.SNAPSHOT, share_server=fake.SHARE_SERVER, 

1680 parent_share=fake_parent_share 

1681 ) 

1682 mock_data_session.assert_not_called() 

1683 

1684 @ddt.data( 

1685 {'src_cluster_name': fake.CLUSTER_NAME, 

1686 'dest_cluster_name': fake.CLUSTER_NAME, 'has_vserver_peers': None}, 

1687 {'src_cluster_name': fake.CLUSTER_NAME, 

1688 'dest_cluster_name': fake.CLUSTER_NAME_2, 'has_vserver_peers': False}, 

1689 {'src_cluster_name': fake.CLUSTER_NAME, 

1690 'dest_cluster_name': fake.CLUSTER_NAME_2, 'has_vserver_peers': True} 

1691 ) 

1692 @ddt.unpack 

1693 def test_create_share_from_snaphot_different_hosts(self, src_cluster_name, 

1694 dest_cluster_name, 

1695 has_vserver_peers): 

1696 class FakeDBObj(dict): 

1697 def to_dict(self): 

1698 return self 

1699 

1700 fake_parent_share = copy.deepcopy(fake.SHARE) 

1701 fake_parent_share['id'] = fake.SHARE_ID2 

1702 fake_parent_share['host'] = fake.MANILA_HOST_NAME_2 

1703 fake_share = FakeDBObj(fake.SHARE) 

1704 fake_share_server = FakeDBObj(fake.SHARE_SERVER) 

1705 src_vserver = fake.VSERVER2 

1706 dest_vserver = fake.VSERVER1 

1707 src_backend = fake.BACKEND_NAME 

1708 dest_backend = fake.BACKEND_NAME_2 

1709 mock_dm_session = mock.Mock() 

1710 

1711 mock_dm_constr = self.mock_object( 

1712 data_motion, "DataMotionSession", 

1713 mock.Mock(return_value=mock_dm_session)) 

1714 mock_get_vserver = self.mock_object( 

1715 mock_dm_session, 'get_vserver_from_share', 

1716 mock.Mock(return_value=src_vserver)) 

1717 mock_get_vserver_from_share_server = self.mock_object( 

1718 mock_dm_session, 'get_vserver_from_share_server', 

1719 mock.Mock(return_value=dest_vserver)) 

1720 src_vserver_client = mock.Mock() 

1721 dest_vserver_client = mock.Mock() 

1722 mock_extract_host = self.mock_object( 

1723 share_utils, 'extract_host', 

1724 mock.Mock(side_effect=[src_backend, dest_backend])) 

1725 mock_dm_get_client = self.mock_object( 

1726 data_motion, 'get_client_for_backend', 

1727 mock.Mock(side_effect=[src_vserver_client, dest_vserver_client])) 

1728 mock_get_src_cluster_name = self.mock_object( 

1729 src_vserver_client, 'get_cluster_name', 

1730 mock.Mock(return_value=src_cluster_name)) 

1731 mock_get_dest_cluster_name = self.mock_object( 

1732 dest_vserver_client, 'get_cluster_name', 

1733 mock.Mock(return_value=dest_cluster_name)) 

1734 mock_get_vserver_peers = self.mock_object( 

1735 self.library, '_get_vserver_peers', 

1736 mock.Mock(return_value=has_vserver_peers)) 

1737 mock_create_vserver_peer = self.mock_object(dest_vserver_client, 

1738 'create_vserver_peer') 

1739 mock_accept_peer = self.mock_object(src_vserver_client, 

1740 'accept_vserver_peer') 

1741 mock_create_from_snap = self.mock_object( 

1742 lib_base.NetAppCmodeFileStorageLibrary, 

1743 'create_share_from_snapshot') 

1744 

1745 self.library.create_share_from_snapshot( 

1746 None, fake_share, fake.SNAPSHOT, share_server=fake_share_server, 

1747 parent_share=fake_parent_share) 

1748 

1749 internal_share = copy.deepcopy(fake.SHARE) 

1750 internal_share['share_server'] = copy.deepcopy(fake.SHARE_SERVER) 

1751 

1752 mock_dm_constr.assert_called_once() 

1753 mock_get_vserver.assert_called_once_with(fake_parent_share) 

1754 mock_get_vserver_from_share_server.assert_called_once_with( 

1755 fake_share_server) 

1756 mock_extract_host.assert_has_calls([ 

1757 mock.call(fake_parent_share['host'], level='backend_name'), 

1758 mock.call(internal_share['host'], level='backend_name')]) 

1759 mock_dm_get_client.assert_has_calls([ 

1760 mock.call(src_backend, vserver_name=src_vserver), 

1761 mock.call(dest_backend, vserver_name=dest_vserver) 

1762 ]) 

1763 mock_get_src_cluster_name.assert_called_once() 

1764 mock_get_dest_cluster_name.assert_called_once() 

1765 if src_cluster_name != dest_cluster_name: 

1766 mock_get_vserver_peers.assert_called_once_with(dest_vserver, 

1767 src_vserver) 

1768 if not has_vserver_peers: 

1769 mock_create_vserver_peer.assert_called_once_with( 

1770 dest_vserver, src_vserver, 

1771 peer_cluster_name=src_cluster_name) 

1772 mock_accept_peer.assert_called_once_with(src_vserver, 

1773 dest_vserver) 

1774 mock_create_from_snap.assert_called_once_with( 

1775 None, fake.SHARE, fake.SNAPSHOT, share_server=fake.SHARE_SERVER, 

1776 parent_share=fake_parent_share) 

1777 

1778 def test_check_if_extra_spec_is_positive_with_negative_integer(self): 

1779 self.assertRaises(exception.NetAppException, 

1780 self.library._check_if_max_files_is_valid, 

1781 fake.SHARE, -1) 

1782 

1783 def test_check_if_extra_spec_is_positive_with_string(self): 

1784 self.assertRaises(ValueError, 

1785 self.library._check_if_max_files_is_valid, 

1786 fake.SHARE, 'abc') 

1787 

1788 def test_check_nfs_config_extra_specs_validity(self): 

1789 result = self.library._check_nfs_config_extra_specs_validity( 

1790 fake.EXTRA_SPEC) 

1791 

1792 self.assertIsNone(result) 

1793 

1794 def test_check_nfs_config_extra_specs_validity_empty_spec(self): 

1795 result = self.library._check_nfs_config_extra_specs_validity({}) 

1796 

1797 self.assertIsNone(result) 

1798 

1799 @ddt.data(fake.INVALID_TCP_MAX_XFER_SIZE_EXTRA_SPEC, 

1800 fake.INVALID_UDP_MAX_XFER_SIZE_EXTRA_SPEC) 

1801 def test_check_nfs_config_extra_specs_validity_invalid_value(self, 

1802 extra_specs): 

1803 self.assertRaises( 

1804 exception.NetAppException, 

1805 self.library._check_nfs_config_extra_specs_validity, 

1806 extra_specs) 

1807 

1808 @ddt.data({}, fake.STRING_EXTRA_SPEC) 

1809 def test_get_nfs_config_provisioning_options_empty(self, extra_specs): 

1810 result = self.library._get_nfs_config_provisioning_options( 

1811 extra_specs) 

1812 

1813 self.assertDictEqual(result, fake.NFS_CONFIG_DEFAULT) 

1814 

1815 @ddt.data( 

1816 {'extra_specs': fake.NFS_CONFIG_TCP_MAX_DDT['extra_specs'], 

1817 'expected': fake.NFS_CONFIG_TCP_MAX_DDT['expected']}, 

1818 {'extra_specs': fake.NFS_CONFIG_UDP_MAX_DDT['extra_specs'], 

1819 'expected': fake.NFS_CONFIG_UDP_MAX_DDT['expected']}, 

1820 {'extra_specs': fake.NFS_CONFIG_TCP_UDP_MAX_DDT['extra_specs'], 

1821 'expected': fake.NFS_CONFIG_TCP_UDP_MAX_DDT['expected']}, 

1822 ) 

1823 @ddt.unpack 

1824 def test_get_nfs_config_provisioning_options_valid(self, extra_specs, 

1825 expected): 

1826 result = self.library._get_nfs_config_provisioning_options( 

1827 extra_specs) 

1828 

1829 self.assertDictEqual(expected, result) 

1830 

1831 @ddt.data({'fake_share_server': fake.SHARE_SERVER_NFS_TCP, 

1832 'expected_nfs_config': fake.NFS_CONFIG_TCP_MAX}, 

1833 {'fake_share_server': fake.SHARE_SERVER_NFS_UDP, 

1834 'expected_nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1835 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1836 'expected_nfs_config': fake.NFS_CONFIG_TCP_UDP_MAX}, 

1837 {'fake_share_server': fake.SHARE_SERVER_NO_DETAILS, 

1838 'expected_nfs_config': fake.NFS_CONFIG_DEFAULT}, 

1839 {'fake_share_server': fake.SHARE_SERVER_NFS_DEFAULT, 

1840 'expected_nfs_config': None}, 

1841 {'fake_share_server': fake.SHARE_SERVER_NO_NFS_NONE, 

1842 'expected_nfs_config': fake.NFS_CONFIG_DEFAULT}) 

1843 @ddt.unpack 

1844 def test_is_share_server_compatible_true(self, fake_share_server, 

1845 expected_nfs_config): 

1846 is_same = self.library._is_share_server_compatible( 

1847 fake_share_server, expected_nfs_config) 

1848 self.assertTrue(is_same) 

1849 

1850 @ddt.data({'fake_share_server': fake.SHARE_SERVER_NFS_TCP, 

1851 'expected_nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1852 {'fake_share_server': fake.SHARE_SERVER_NFS_UDP, 

1853 'expected_nfs_config': fake.NFS_CONFIG_TCP_MAX}, 

1854 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1855 'expected_nfs_config': fake.NFS_CONFIG_TCP_MAX}, 

1856 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1857 'expected_nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1858 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1859 'expected_nfs_config': None}, 

1860 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1861 'expected_nfs_config': {}}, 

1862 {'fake_share_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1863 'expected_nfs_config': fake.NFS_CONFIG_DEFAULT}, 

1864 {'fake_share_server': fake.SHARE_SERVER_NO_DETAILS, 

1865 'expected_nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1866 {'fake_share_server': fake.SHARE_SERVER_NFS_DEFAULT, 

1867 'expected_nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1868 {'fake_share_server': fake.SHARE_SERVER_NO_NFS_NONE, 

1869 'expected_nfs_config': fake.NFS_CONFIG_TCP_MAX}) 

1870 @ddt.unpack 

1871 def test_is_share_server_compatible_false(self, fake_share_server, 

1872 expected_nfs_config): 

1873 is_same = self.library._is_share_server_compatible( 

1874 fake_share_server, expected_nfs_config) 

1875 self.assertFalse(is_same) 

1876 

1877 @ddt.data( 

1878 {'expected_server': fake.SHARE_SERVER_NFS_TCP, 

1879 'share_group': {'share_server_id': fake.SHARE_SERVER_NFS_TCP['id']}, 

1880 'nfs_config': fake.NFS_CONFIG_TCP_MAX}, 

1881 {'expected_server': fake.SHARE_SERVER_NFS_UDP, 

1882 'share_group': {'share_server_id': fake.SHARE_SERVER_NFS_UDP['id']}, 

1883 'nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1884 {'expected_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1885 'share_group': { 

1886 'share_server_id': fake.SHARE_SERVER_NFS_TCP_UDP['id']}, 

1887 'nfs_config': fake.NFS_CONFIG_TCP_UDP_MAX}, 

1888 {'expected_server': fake.SHARE_SERVER_NFS_DEFAULT, 

1889 'share_group': { 

1890 'share_server_id': fake.SHARE_SERVER_NFS_DEFAULT['id']}, 

1891 'nfs_config': fake.NFS_CONFIG_DEFAULT}, 

1892 {'expected_server': None, 

1893 'share_group': {'share_server_id': 'invalid_id'}, 

1894 'nfs_config': fake.NFS_CONFIG_TCP_MAX}) 

1895 @ddt.unpack 

1896 def test_choose_share_server_compatible_with_share_group_and_nfs_config( 

1897 self, expected_server, share_group, nfs_config): 

1898 self.library.is_nfs_config_supported = True 

1899 mock_get_extra_spec = self.mock_object( 

1900 share_types, "get_extra_specs_from_share", 

1901 mock.Mock(return_value=fake.EXTRA_SPEC)) 

1902 mock_get_nfs_config = self.mock_object( 

1903 self.library, 

1904 "_get_nfs_config_provisioning_options", 

1905 mock.Mock(return_value=nfs_config)) 

1906 mock_client = mock.Mock() 

1907 self.mock_object(self.library, '_get_vserver', 

1908 mock.Mock(return_value=('fake_name', 

1909 mock_client))) 

1910 self.mock_object(mock_client, 'get_vserver_info', 

1911 mock.Mock(return_value=fake.VSERVER_INFO)) 

1912 self.mock_object(mock_client, 'list_vserver_aggregates', 

1913 mock.Mock(return_value=fake.AGGREGATES)) 

1914 

1915 server = self.library.choose_share_server_compatible_with_share( 

1916 None, fake.SHARE_SERVERS, fake.SHARE_2, None, share_group) 

1917 

1918 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

1919 mock_get_nfs_config.assert_called_once_with(fake.EXTRA_SPEC) 

1920 self.assertEqual(expected_server, server) 

1921 

1922 @ddt.data( 

1923 {'expected_server': fake.SHARE_SERVER_NO_NFS_NONE, 

1924 'share_group': { 

1925 'share_server_id': fake.SHARE_SERVER_NO_NFS_NONE['id']}}, 

1926 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

1927 'share_group': { 

1928 'share_server_id': fake.SHARE_SERVER_NO_DETAILS['id']}}, 

1929 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

1930 'share_group': { 

1931 'share_server_id': fake.SHARE_SERVER_NO_DETAILS['id']}, 

1932 'nfs_config_support': False}, 

1933 {'expected_server': None, 

1934 'share_group': {'share_server_id': 'invalid_id'}}) 

1935 @ddt.unpack 

1936 def test_choose_share_server_compatible_with_share_group_only( 

1937 self, expected_server, share_group, nfs_config_support=True): 

1938 self.library.is_nfs_config_supported = nfs_config_support 

1939 mock_get_extra_spec = self.mock_object( 

1940 share_types, "get_extra_specs_from_share", 

1941 mock.Mock(return_value=fake.EMPTY_EXTRA_SPEC)) 

1942 mock_get_nfs_config = self.mock_object( 

1943 self.library, 

1944 "_get_nfs_config_provisioning_options", 

1945 mock.Mock(return_value=fake.NFS_CONFIG_DEFAULT)) 

1946 mock_client = mock.Mock() 

1947 self.mock_object(self.library, '_get_vserver', 

1948 mock.Mock(return_value=('fake_name', 

1949 mock_client))) 

1950 self.mock_object(mock_client, 'get_vserver_info', 

1951 mock.Mock(return_value=fake.VSERVER_INFO)) 

1952 self.mock_object(mock_client, 'list_vserver_aggregates', 

1953 mock.Mock(return_value=fake.AGGREGATES)) 

1954 

1955 server = self.library.choose_share_server_compatible_with_share( 

1956 None, fake.SHARE_SERVERS, fake.SHARE_2, None, share_group) 

1957 

1958 self.assertEqual(expected_server, server) 

1959 if nfs_config_support: 

1960 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

1961 mock_get_nfs_config.assert_called_once_with(fake.EMPTY_EXTRA_SPEC) 

1962 

1963 @ddt.data( 

1964 {'expected_server': fake.SHARE_SERVER_NFS_TCP, 

1965 'nfs_config': fake.NFS_CONFIG_TCP_MAX}, 

1966 {'expected_server': fake.SHARE_SERVER_NFS_UDP, 

1967 'nfs_config': fake.NFS_CONFIG_UDP_MAX}, 

1968 {'expected_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

1969 'nfs_config': fake.NFS_CONFIG_TCP_UDP_MAX}, 

1970 {'expected_server': fake.SHARE_SERVER_NFS_DEFAULT, 

1971 'nfs_config': fake.NFS_CONFIG_DEFAULT}, 

1972 {'expected_server': None, 

1973 'nfs_config': {'invalid': 'invalid'}}, 

1974 {'expected_server': fake.SHARE_SERVER_NFS_TCP, 

1975 'nfs_config': None, 'nfs_config_support': False}, 

1976 ) 

1977 @ddt.unpack 

1978 def test_choose_share_server_compatible_with_share_nfs_config_only( 

1979 self, expected_server, nfs_config, nfs_config_support=True): 

1980 self.library.is_nfs_config_supported = nfs_config_support 

1981 mock_get_extra_spec = self.mock_object( 

1982 share_types, "get_extra_specs_from_share", 

1983 mock.Mock(return_value=fake.EXTRA_SPEC)) 

1984 mock_get_nfs_config = self.mock_object( 

1985 self.library, 

1986 "_get_nfs_config_provisioning_options", 

1987 mock.Mock(return_value=nfs_config)) 

1988 mock_client = mock.Mock() 

1989 self.mock_object(self.library, '_get_vserver', 

1990 mock.Mock(return_value=('fake_name', 

1991 mock_client))) 

1992 self.mock_object(mock_client, 'get_vserver_info', 

1993 mock.Mock(return_value=fake.VSERVER_INFO)) 

1994 self.mock_object(mock_client, 'list_vserver_aggregates', 

1995 mock.Mock(return_value=fake.AGGREGATES)) 

1996 

1997 server = self.library.choose_share_server_compatible_with_share( 

1998 None, fake.SHARE_SERVERS, fake.SHARE_2) 

1999 

2000 self.assertEqual(expected_server, server) 

2001 if nfs_config_support: 

2002 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

2003 mock_get_nfs_config.assert_called_once_with(fake.EXTRA_SPEC) 

2004 

2005 @ddt.data( 

2006 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

2007 'share_servers': [ 

2008 fake.SHARE_SERVER_NFS_TCP, fake.SHARE_SERVER_NO_DETAILS]}, 

2009 {'expected_server': fake.SHARE_SERVER_NO_NFS_NONE, 

2010 'share_servers': [ 

2011 fake.SHARE_SERVER_NFS_UDP, fake.SHARE_SERVER_NO_NFS_NONE]}, 

2012 {'expected_server': fake.SHARE_SERVER_NFS_DEFAULT, 

2013 'share_servers': [ 

2014 fake.SHARE_SERVER_NFS_UDP, fake.SHARE_SERVER_NFS_DEFAULT]}, 

2015 {'expected_server': None, 

2016 'share_servers': [ 

2017 fake.SHARE_SERVER_NFS_TCP, fake.SHARE_SERVER_NFS_UDP]}, 

2018 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

2019 'share_servers': [fake.SHARE_SERVER_NO_DETAILS], 

2020 'nfs_config_support': False} 

2021 ) 

2022 @ddt.unpack 

2023 def test_choose_share_server_compatible_with_share_no_specification( 

2024 self, expected_server, share_servers, nfs_config_support=True): 

2025 self.library.is_nfs_config_supported = nfs_config_support 

2026 mock_get_extra_spec = self.mock_object( 

2027 share_types, "get_extra_specs_from_share", 

2028 mock.Mock(return_value=fake.EMPTY_EXTRA_SPEC)) 

2029 mock_get_nfs_config = self.mock_object( 

2030 self.library, 

2031 "_get_nfs_config_provisioning_options", 

2032 mock.Mock(return_value=fake.NFS_CONFIG_DEFAULT)) 

2033 mock_client = mock.Mock() 

2034 self.mock_object(self.library, '_get_vserver', 

2035 mock.Mock(return_value=('fake_name', 

2036 mock_client))) 

2037 self.mock_object(mock_client, 'get_vserver_info', 

2038 mock.Mock(return_value=fake.VSERVER_INFO)) 

2039 self.mock_object(mock_client, 'list_vserver_aggregates', 

2040 mock.Mock(return_value=fake.AGGREGATES)) 

2041 

2042 server = self.library.choose_share_server_compatible_with_share( 

2043 None, share_servers, fake.SHARE_2) 

2044 

2045 self.assertEqual(expected_server, server) 

2046 if nfs_config_support: 

2047 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

2048 mock_get_nfs_config.assert_called_once_with(fake.EMPTY_EXTRA_SPEC) 

2049 

2050 def test_manage_existing_error(self): 

2051 fake_server = {'id': 'id'} 

2052 fake_nfs_config = 'fake_nfs_config' 

2053 self.library.is_nfs_config_supported = True 

2054 

2055 mock_get_extra_spec = self.mock_object( 

2056 share_types, "get_extra_specs_from_share", 

2057 mock.Mock(return_value=fake.EXTRA_SPEC)) 

2058 mock_get_nfs_config = self.mock_object( 

2059 self.library, 

2060 "_get_nfs_config_provisioning_options", 

2061 mock.Mock(return_value=fake_nfs_config)) 

2062 mock_is_compatible = self.mock_object( 

2063 self.library, 

2064 "_is_share_server_compatible", 

2065 mock.Mock(return_value=False)) 

2066 

2067 self.assertRaises(exception.NetAppException, 

2068 self.library.manage_existing, 

2069 fake.SHARE, 'opts', fake_server) 

2070 

2071 mock_get_extra_spec.assert_called_once_with(fake.SHARE) 

2072 mock_get_nfs_config.assert_called_once_with(fake.EXTRA_SPEC) 

2073 mock_is_compatible.assert_called_once_with(fake_server, 

2074 fake_nfs_config) 

2075 

2076 def test_choose_share_server_compatible_with_share_group_no_share_server( 

2077 self): 

2078 server = self.library.choose_share_server_compatible_with_share_group( 

2079 None, [], fake.SHARE_GROUP_REF) 

2080 

2081 self.assertIsNone(server) 

2082 

2083 @ddt.data( 

2084 [fake.NFS_CONFIG_DEFAULT, fake.NFS_CONFIG_TCP_MAX], 

2085 [fake.NFS_CONFIG_TCP_MAX, fake.NFS_CONFIG_UDP_MAX], 

2086 [fake.NFS_CONFIG_TCP_UDP_MAX, fake.NFS_CONFIG_TCP_MAX], 

2087 [fake.NFS_CONFIG_DEFAULT, fake.NFS_CONFIG_TCP_UDP_MAX]) 

2088 def test_choose_share_server_compatible_with_share_group_nfs_conflict( 

2089 self, nfs_config_list): 

2090 self.library.is_nfs_config_supported = True 

2091 self.mock_object( 

2092 share_types, "get_share_type_extra_specs", 

2093 mock.Mock(return_value=fake.EXTRA_SPEC)) 

2094 mock_get_nfs_config = self.mock_object( 

2095 self.library, 

2096 "_get_nfs_config_provisioning_options", 

2097 mock.Mock(side_effect=nfs_config_list)) 

2098 mock_check_extra_spec = self.mock_object( 

2099 self.library, 

2100 '_check_nfs_config_extra_specs_validity', 

2101 mock.Mock()) 

2102 

2103 self.assertRaises(exception.InvalidInput, 

2104 self.library. 

2105 choose_share_server_compatible_with_share_group, 

2106 None, fake.SHARE_SERVERS, fake.SHARE_GROUP_REF) 

2107 

2108 mock_get_nfs_config.assert_called_with(fake.EXTRA_SPEC) 

2109 mock_check_extra_spec.assert_called_once_with(fake.EXTRA_SPEC) 

2110 

2111 @ddt.data( 

2112 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

2113 'nfs_config': fake.NFS_CONFIG_DEFAULT, 

2114 'share_servers': [ 

2115 fake.SHARE_SERVER_NFS_TCP, fake.SHARE_SERVER_NO_DETAILS]}, 

2116 {'expected_server': fake.SHARE_SERVER_NO_NFS_NONE, 

2117 'nfs_config': fake.NFS_CONFIG_DEFAULT, 

2118 'share_servers': [ 

2119 fake.SHARE_SERVER_NFS_UDP, fake.SHARE_SERVER_NO_NFS_NONE]}, 

2120 {'expected_server': fake.SHARE_SERVER_NFS_DEFAULT, 

2121 'nfs_config': fake.NFS_CONFIG_DEFAULT, 

2122 'share_servers': [ 

2123 fake.SHARE_SERVER_NFS_UDP, fake.SHARE_SERVER_NFS_DEFAULT]}, 

2124 {'expected_server': None, 

2125 'nfs_config': fake.NFS_CONFIG_DEFAULT, 

2126 'share_servers': [ 

2127 fake.SHARE_SERVER_NFS_TCP, fake.SHARE_SERVER_NFS_UDP, 

2128 fake.SHARE_SERVER_NFS_TCP_UDP]}, 

2129 {'expected_server': fake.SHARE_SERVER_NFS_TCP_UDP, 

2130 'nfs_config': fake.NFS_CONFIG_TCP_UDP_MAX, 

2131 'share_servers': [ 

2132 fake.SHARE_SERVER_NFS_TCP, fake.SHARE_SERVER_NFS_UDP, 

2133 fake.SHARE_SERVER_NFS_DEFAULT, fake.SHARE_SERVER_NFS_TCP_UDP]}, 

2134 {'expected_server': fake.SHARE_SERVER_NO_DETAILS, 

2135 'nfs_config': None, 

2136 'share_servers': [fake.SHARE_SERVER_NO_DETAILS], 

2137 'nfs_config_supported': False} 

2138 ) 

2139 @ddt.unpack 

2140 def test_choose_share_server_compatible_with_share_group_nfs( 

2141 self, expected_server, nfs_config, share_servers, 

2142 nfs_config_supported=True): 

2143 self.library.is_nfs_config_supported = nfs_config_supported 

2144 mock_client = mock.Mock() 

2145 self.mock_object( 

2146 share_types, "get_share_type_extra_specs", 

2147 mock.Mock(return_value=fake.EXTRA_SPEC)) 

2148 mock_get_nfs_config = self.mock_object( 

2149 self.library, 

2150 "_get_nfs_config_provisioning_options", 

2151 mock.Mock(return_value=nfs_config)) 

2152 mock_check_extra_spec = self.mock_object( 

2153 self.library, 

2154 '_check_nfs_config_extra_specs_validity', 

2155 mock.Mock()) 

2156 self.mock_object(self.library, '_get_vserver', 

2157 mock.Mock(return_value=('fake_name', 

2158 mock_client))) 

2159 self.mock_object(mock_client, 'get_vserver_info', 

2160 mock.Mock(return_value=fake.VSERVER_INFO)) 

2161 

2162 server = self.library.choose_share_server_compatible_with_share_group( 

2163 None, share_servers, fake.SHARE_GROUP_REF) 

2164 

2165 if nfs_config_supported: 

2166 mock_get_nfs_config.assert_called_with(fake.EXTRA_SPEC) 

2167 mock_check_extra_spec.assert_called_once_with(fake.EXTRA_SPEC) 

2168 else: 

2169 mock_get_nfs_config.assert_not_called() 

2170 mock_check_extra_spec.assert_not_called() 

2171 self.assertEqual(expected_server, server) 

2172 

2173 def test_share_server_migration_check_compatibility_same_backend( 

2174 self): 

2175 not_compatible = fake.SERVER_MIGRATION_CHECK_NOT_COMPATIBLE 

2176 self.library._have_cluster_creds = True 

2177 self.mock_object(self.library, '_get_vserver', 

2178 mock.Mock(return_value=(None, None))) 

2179 

2180 result = self.library.share_server_migration_check_compatibility( 

2181 None, self.fake_src_share_server, 

2182 self.fake_src_share_server['host'], 

2183 None, None, None) 

2184 

2185 self.assertEqual(not_compatible, result) 

2186 

2187 def _init_mocks_for_svm_dr_check_compatibility( 

2188 self, src_svm_dr_supported=True, dest_svm_dr_supported=True, 

2189 check_capacity_result=True, flexgroup_support=False, 

2190 is_flexgroup_destination_host=False): 

2191 self.mock_object(self.mock_src_client, 'is_svm_dr_supported', 

2192 mock.Mock(return_value=src_svm_dr_supported)) 

2193 self.mock_object(self.mock_dest_client, 'is_svm_dr_supported', 

2194 mock.Mock(return_value=dest_svm_dr_supported)) 

2195 self.mock_object(self.library, '_check_capacity_compatibility', 

2196 mock.Mock(return_value=check_capacity_result)) 

2197 self.mock_object(self.mock_src_client, 'is_flexgroup_supported', 

2198 mock.Mock(return_value=flexgroup_support)) 

2199 self.mock_object(data_motion, 'DataMotionSession') 

2200 self.mock_object(self.library, 'is_flexgroup_destination_host', 

2201 mock.Mock(return_value=is_flexgroup_destination_host)) 

2202 

2203 def _configure_mocks_share_server_migration_check_compatibility( 

2204 self, have_cluster_creds=True, 

2205 src_cluster_name=fake.CLUSTER_NAME, 

2206 dest_cluster_name=fake.CLUSTER_NAME_2, 

2207 pools=fake.POOLS, is_svm_dr=True, failure_scenario=False): 

2208 migration_method = 'svm_dr' if is_svm_dr else 'svm_migrate' 

2209 

2210 self.library._have_cluster_creds = have_cluster_creds 

2211 self.mock_object(self.library, '_get_vserver', 

2212 mock.Mock(return_value=(self.fake_src_vserver, 

2213 self.mock_src_client))) 

2214 self.mock_object(self.mock_src_client, 'get_cluster_name', 

2215 mock.Mock(return_value=src_cluster_name)) 

2216 self.mock_object(self.client, 'get_cluster_name', 

2217 mock.Mock(return_value=dest_cluster_name)) 

2218 self.mock_object(data_motion, 'get_client_for_backend', 

2219 mock.Mock(return_value=self.mock_dest_client)) 

2220 self.mock_object(self.library, '_check_for_migration_support', 

2221 mock.Mock(return_value=( 

2222 migration_method, not failure_scenario))) 

2223 self.mock_object(self.library, '_get_pools', 

2224 mock.Mock(return_value=pools)) 

2225 

2226 def test_share_server_migration_check_compatibility_dest_with_pool( 

2227 self): 

2228 not_compatible = fake.SERVER_MIGRATION_CHECK_NOT_COMPATIBLE 

2229 self.library._have_cluster_creds = True 

2230 

2231 result = self.library.share_server_migration_check_compatibility( 

2232 None, self.fake_src_share_server, fake.MANILA_HOST_NAME, 

2233 None, None, None) 

2234 

2235 self.assertEqual(not_compatible, result) 

2236 

2237 def test_share_server_migration_check_compatibility_same_cluster( 

2238 self): 

2239 not_compatible = fake.SERVER_MIGRATION_CHECK_NOT_COMPATIBLE 

2240 self._configure_mocks_share_server_migration_check_compatibility( 

2241 src_cluster_name=fake.CLUSTER_NAME, 

2242 dest_cluster_name=fake.CLUSTER_NAME, 

2243 ) 

2244 

2245 result = self.library.share_server_migration_check_compatibility( 

2246 None, self.fake_src_share_server, 

2247 self.fake_dest_share_server['host'], 

2248 None, None, None) 

2249 

2250 self.assertEqual(not_compatible, result) 

2251 self.library._get_vserver.assert_called_once_with( 

2252 self.fake_src_share_server, 

2253 backend_name=self.fake_src_backend_name 

2254 ) 

2255 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2256 self.assertTrue(self.client.get_cluster_name.called) 

2257 

2258 @ddt.data( 

2259 {'src_svm_dr_supported': False, 

2260 'dest_svm_dr_supported': False, 

2261 'check_capacity_result': False, 

2262 'is_flexgroup_destination_host': False, 

2263 }, 

2264 {'src_svm_dr_supported': True, 

2265 'dest_svm_dr_supported': True, 

2266 'check_capacity_result': False, 

2267 'is_flexgroup_destination_host': False, 

2268 }, 

2269 {'src_svm_dr_supported': True, 

2270 'dest_svm_dr_supported': True, 

2271 'check_capacity_result': True, 

2272 'is_flexgroup_destination_host': True, 

2273 }, 

2274 ) 

2275 @ddt.unpack 

2276 def test__check_compatibility_svm_dr_not_compatible( 

2277 self, src_svm_dr_supported, dest_svm_dr_supported, 

2278 check_capacity_result, is_flexgroup_destination_host): 

2279 server_total_size = (fake.SHARE_REQ_SPEC.get('shares_size', 0) + 

2280 fake.SHARE_REQ_SPEC.get('snapshots_size', 0)) 

2281 

2282 self._init_mocks_for_svm_dr_check_compatibility( 

2283 src_svm_dr_supported=src_svm_dr_supported, 

2284 dest_svm_dr_supported=dest_svm_dr_supported, 

2285 check_capacity_result=check_capacity_result, 

2286 flexgroup_support=is_flexgroup_destination_host, 

2287 is_flexgroup_destination_host=is_flexgroup_destination_host) 

2288 

2289 method, result = self.library._check_compatibility_using_svm_dr( 

2290 self.mock_src_client, self.mock_dest_client, 

2291 fake.SERVER_MIGRATION_REQUEST_SPEC, fake.POOLS) 

2292 

2293 self.assertEqual(method, 'svm_dr') 

2294 self.assertEqual(result, False) 

2295 self.assertTrue(self.mock_src_client.is_svm_dr_supported.called) 

2296 

2297 if (src_svm_dr_supported and dest_svm_dr_supported and 

2298 is_flexgroup_destination_host): 

2299 self.assertTrue(self.mock_src_client.is_flexgroup_supported.called) 

2300 self.assertTrue(self.library.is_flexgroup_destination_host.called) 

2301 

2302 if (check_capacity_result and not is_flexgroup_destination_host and 2302 ↛ 2304line 2302 didn't jump to line 2304 because the condition on line 2302 was never true

2303 not src_svm_dr_supported): 

2304 self.assertFalse(self.mock_dest_client.is_svm_dr_supported.called) 

2305 self.library._check_capacity_compatibility.assert_called_once_with( 

2306 fake.POOLS, True, server_total_size) 

2307 

2308 def test_share_server_migration_check_compatibility_different_sec_service( 

2309 self): 

2310 not_compatible = fake.SERVER_MIGRATION_CHECK_NOT_COMPATIBLE 

2311 self._configure_mocks_share_server_migration_check_compatibility() 

2312 new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) 

2313 new_sec_service['id'] = 'new_sec_serv_id' 

2314 new_share_network = copy.deepcopy(fake.SHARE_NETWORK) 

2315 new_share_network['id'] = 'fake_share_network_id_2' 

2316 new_share_network['security_services'] = [new_sec_service] 

2317 

2318 result = self.library.share_server_migration_check_compatibility( 

2319 None, self.fake_src_share_server, 

2320 self.fake_dest_share_server['host'], 

2321 fake.SHARE_NETWORK, new_share_network, None) 

2322 

2323 self.assertEqual(not_compatible, result) 

2324 self.library._get_vserver.assert_called_once_with( 

2325 self.fake_src_share_server, 

2326 backend_name=self.fake_src_backend_name 

2327 ) 

2328 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2329 self.assertTrue(self.client.get_cluster_name.called) 

2330 data_motion.get_client_for_backend.assert_called_once_with( 

2331 self.fake_dest_backend_name, vserver_name=None 

2332 ) 

2333 

2334 @ddt.data('netapp_flexvol_encryption', 'revert_to_snapshot_support') 

2335 def test_share_server_migration_check_compatibility_invalid_capabilities( 

2336 self, capability): 

2337 not_compatible = fake.SERVER_MIGRATION_CHECK_NOT_COMPATIBLE 

2338 pools_without_capability = copy.deepcopy(fake.POOLS) 

2339 for pool in pools_without_capability: 

2340 pool[capability] = False 

2341 self._configure_mocks_share_server_migration_check_compatibility( 

2342 pools=pools_without_capability 

2343 ) 

2344 

2345 result = self.library.share_server_migration_check_compatibility( 

2346 None, self.fake_src_share_server, 

2347 self.fake_dest_share_server['host'], 

2348 fake.SHARE_NETWORK, fake.SHARE_NETWORK, 

2349 fake.SERVER_MIGRATION_REQUEST_SPEC) 

2350 

2351 self.assertEqual(not_compatible, result) 

2352 self.library._get_vserver.assert_called_once_with( 

2353 self.fake_src_share_server, 

2354 backend_name=self.fake_src_backend_name 

2355 ) 

2356 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2357 self.assertTrue(self.client.get_cluster_name.called) 

2358 data_motion.get_client_for_backend.assert_called_once_with( 

2359 self.fake_dest_backend_name, vserver_name=None 

2360 ) 

2361 

2362 @ddt.data((True, "svm_migrate"), (False, "svm_dr")) 

2363 @ddt.unpack 

2364 def test__check_for_migration_support( 

2365 self, svm_migrate_supported, expected_migration_method): 

2366 mock_dest_is_svm_migrate_supported = self.mock_object( 

2367 self.mock_dest_client, 'is_svm_migrate_supported', 

2368 mock.Mock(return_value=svm_migrate_supported)) 

2369 mock_src_is_svm_migrate_supported = self.mock_object( 

2370 self.mock_src_client, 'is_svm_migrate_supported', 

2371 mock.Mock(return_value=svm_migrate_supported)) 

2372 mock_find_matching_aggregates = self.mock_object( 

2373 self.library, '_find_matching_aggregates', 

2374 mock.Mock(return_value=fake.AGGREGATES)) 

2375 mock_get_vserver_name = self.mock_object( 

2376 self.library, '_get_vserver_name', 

2377 mock.Mock(return_value=fake.VSERVER1)) 

2378 mock_svm_migration_check_svm_mig = self.mock_object( 

2379 self.library, '_check_compatibility_for_svm_migrate', 

2380 mock.Mock(return_value=True)) 

2381 mock_svm_migration_check_svm_dr = self.mock_object( 

2382 self.library, '_check_compatibility_using_svm_dr', 

2383 mock.Mock(side_effect=[('svm_dr', True)])) 

2384 

2385 migration_method, result = self.library._check_for_migration_support( 

2386 self.mock_src_client, self.mock_dest_client, fake.SHARE_SERVER, 

2387 fake.SHARE_REQ_SPEC, fake.CLUSTER_NAME, fake.POOLS) 

2388 

2389 self.assertIs(True, result) 

2390 self.assertEqual(migration_method, expected_migration_method) 

2391 

2392 mock_dest_is_svm_migrate_supported.assert_called_once() 

2393 if svm_migrate_supported: 

2394 mock_src_is_svm_migrate_supported.assert_called_once() 

2395 mock_find_matching_aggregates.assert_called_once() 

2396 mock_get_vserver_name.assert_not_called() 

2397 mock_svm_migration_check_svm_mig.assert_called_once_with( 

2398 fake.CLUSTER_NAME, fake.VSERVER1, fake.SHARE_SERVER, 

2399 fake.AGGREGATES, self.mock_dest_client) 

2400 else: 

2401 mock_svm_migration_check_svm_dr.assert_called_once_with( 

2402 self.mock_src_client, self.mock_dest_client, 

2403 fake.SHARE_REQ_SPEC, fake.POOLS) 

2404 

2405 def test__check_for_migration_support_svm_migrate_exception(self): 

2406 svm_migrate_supported = True 

2407 expected_migration_method = 'svm_migrate' 

2408 mock_dest_is_svm_migrate_supported = self.mock_object( 

2409 self.mock_dest_client, 'is_svm_migrate_supported', 

2410 mock.Mock(return_value=svm_migrate_supported)) 

2411 mock_src_is_svm_migrate_supported = self.mock_object( 

2412 self.mock_src_client, 'is_svm_migrate_supported', 

2413 mock.Mock(return_value=svm_migrate_supported)) 

2414 mock_find_matching_aggregates = self.mock_object( 

2415 self.library, '_find_matching_aggregates', 

2416 mock.Mock(return_value=fake.AGGREGATES)) 

2417 mock_get_vserver_name = self.mock_object( 

2418 self.library, '_get_vserver_name', 

2419 mock.Mock(return_value=fake.VSERVER1)) 

2420 mock_svm_migration_check_svm_mig = self.mock_object( 

2421 self.library, '_check_compatibility_for_svm_migrate', 

2422 mock.Mock(side_effect=exception.NetAppException())) 

2423 

2424 migration_method, result = self.library._check_for_migration_support( 

2425 self.mock_src_client, self.mock_dest_client, fake.SHARE_SERVER, 

2426 fake.SHARE_REQ_SPEC, fake.CLUSTER_NAME, fake.POOLS) 

2427 

2428 self.assertIs(False, result) 

2429 self.assertEqual(migration_method, expected_migration_method) 

2430 

2431 mock_dest_is_svm_migrate_supported.assert_called_once() 

2432 mock_src_is_svm_migrate_supported.assert_called_once() 

2433 mock_find_matching_aggregates.assert_called_once() 

2434 mock_get_vserver_name.assert_not_called() 

2435 mock_svm_migration_check_svm_mig.assert_called_once_with( 

2436 fake.CLUSTER_NAME, fake.VSERVER1, fake.SHARE_SERVER, 

2437 fake.AGGREGATES, self.mock_dest_client) 

2438 

2439 @ddt.data( 

2440 (mock.Mock, True), 

2441 (exception.NetAppException, False) 

2442 ) 

2443 @ddt.unpack 

2444 def test__check_compatibility_for_svm_migrate(self, expected_exception, 

2445 expected_compatibility): 

2446 network_info = { 

2447 'network_allocations': 

2448 self.fake_src_share_server['network_allocations'], 

2449 'neutron_subnet_id': 

2450 self.fake_src_share_server['share_network_subnets'][0].get( 

2451 'neutron_subnet_id') 

2452 } 

2453 self.library.configuration.netapp_restrict_lif_creation_per_ha_pair = ( 

2454 True 

2455 ) 

2456 check_lif_limit = self.mock_object( 

2457 self.library, 

2458 '_check_data_lif_count_limit_reached_for_ha_pair', 

2459 ) 

2460 self.mock_object(self.library._client, 'list_cluster_nodes', 

2461 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2462 self.mock_object(self.library, '_get_node_data_port', 

2463 mock.Mock(return_value=fake.NODE_DATA_PORT)) 

2464 self.mock_object( 

2465 self.library._client, 'get_ipspace_name_for_vlan_port', 

2466 mock.Mock(return_value=fake.IPSPACE)) 

2467 self.mock_object(self.library, '_create_port_and_broadcast_domain') 

2468 self.mock_object(self.mock_dest_client, 'get_ipspaces', 

2469 mock.Mock(return_value=[{'uuid': fake.IPSPACE_ID}])) 

2470 self.mock_object( 

2471 self.mock_dest_client, 'svm_migration_start', 

2472 mock.Mock(return_value=c_fake.FAKE_MIGRATION_RESPONSE_WITH_JOB)) 

2473 self.mock_object(self.library, '_get_job_uuid', 

2474 mock.Mock(return_value=c_fake.FAKE_JOB_ID)) 

2475 self.mock_object(self.library, '_wait_for_operation_status', 

2476 mock.Mock(side_effect=expected_exception)) 

2477 self.mock_object(self.mock_dest_client, 'list_cluster_nodes', 

2478 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2479 

2480 compatibility = self.library._check_compatibility_for_svm_migrate( 

2481 fake.CLUSTER_NAME, fake.VSERVER1, self.fake_src_share_server, 

2482 fake.AGGREGATES, self.mock_dest_client) 

2483 

2484 self.assertIs(expected_compatibility, compatibility) 

2485 self.mock_dest_client.svm_migration_start.assert_called_once_with( 

2486 fake.CLUSTER_NAME, fake.VSERVER1, fake.AGGREGATES, check_only=True, 

2487 dest_ipspace=fake.IPSPACE) 

2488 self.library._get_job_uuid.assert_called_once_with( 

2489 c_fake.FAKE_MIGRATION_RESPONSE_WITH_JOB) 

2490 self.library._client.list_cluster_nodes.assert_called_once() 

2491 self.library._get_node_data_port.assert_called_with( 

2492 fake.CLUSTER_NODES[0]) 

2493 (self.library._client.get_ipspace_name_for_vlan_port 

2494 .assert_called_once_with( 

2495 fake.CLUSTER_NODES[0], fake.NODE_DATA_PORT, 

2496 self.fake_src_share_server['network_allocations'][0][ 

2497 'segmentation_id'])) 

2498 self.library._create_port_and_broadcast_domain.assert_called_once_with( 

2499 fake.IPSPACE, network_info) 

2500 self.assertTrue(check_lif_limit.called) 

2501 

2502 def test__check_compatibility_for_svm_migrate_check_failure(self): 

2503 network_info = { 

2504 'network_allocations': 

2505 self.fake_src_share_server['network_allocations'], 

2506 'neutron_subnet_id': 

2507 self.fake_src_share_server['share_network_subnets'][0].get( 

2508 'neutron_subnet_id') 

2509 } 

2510 

2511 self.mock_object(self.library._client, 'list_cluster_nodes', 

2512 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2513 self.mock_object(self.library, '_get_node_data_port', 

2514 mock.Mock(return_value=fake.NODE_DATA_PORT)) 

2515 self.mock_object( 

2516 self.library._client, 'get_ipspace_name_for_vlan_port', 

2517 mock.Mock(return_value=fake.IPSPACE)) 

2518 self.mock_object(self.library, '_create_port_and_broadcast_domain') 

2519 self.mock_object(self.mock_dest_client, 'get_ipspaces', 

2520 mock.Mock(return_value=[{'uuid': fake.IPSPACE_ID}])) 

2521 self.mock_object( 

2522 self.mock_dest_client, 'svm_migration_start', 

2523 mock.Mock(side_effect=exception.NetAppException())) 

2524 self.mock_object(self.mock_dest_client, 'delete_ipspace') 

2525 self.mock_object(self.mock_dest_client, 'list_cluster_nodes', 

2526 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2527 

2528 self.assertRaises( 

2529 exception.NetAppException, 

2530 self.library._check_compatibility_for_svm_migrate, 

2531 fake.CLUSTER_NAME, 

2532 fake.VSERVER1, 

2533 self.fake_src_share_server, 

2534 fake.AGGREGATES, 

2535 self.mock_dest_client) 

2536 

2537 self.library._client.list_cluster_nodes.assert_called_once() 

2538 self.library._get_node_data_port.assert_called_with( 

2539 fake.CLUSTER_NODES[0]) 

2540 (self.library._client.get_ipspace_name_for_vlan_port 

2541 .assert_called_once_with( 

2542 fake.CLUSTER_NODES[0], fake.NODE_DATA_PORT, 

2543 self.fake_src_share_server['network_allocations'][0][ 

2544 'segmentation_id'])) 

2545 self.library._create_port_and_broadcast_domain.assert_called_once_with( 

2546 fake.IPSPACE, network_info) 

2547 self.mock_dest_client.delete_ipspace.assert_called_once_with( 

2548 fake.IPSPACE) 

2549 

2550 def test_share_server_migration_check_compatibility_compatible(self): 

2551 compatible = { 

2552 'compatible': True, 

2553 'writable': True, 

2554 'nondisruptive': False, 

2555 'preserve_snapshots': True, 

2556 'migration_cancel': True, 

2557 'migration_get_progress': False, 

2558 'share_network_id': fake.SHARE_NETWORK['id'], 

2559 } 

2560 self._configure_mocks_share_server_migration_check_compatibility( 

2561 is_svm_dr=True) 

2562 

2563 result = self.library.share_server_migration_check_compatibility( 

2564 None, self.fake_src_share_server, 

2565 self.fake_dest_share_server['host'], 

2566 fake.SHARE_NETWORK, fake.SHARE_NETWORK, 

2567 fake.SERVER_MIGRATION_REQUEST_SPEC) 

2568 

2569 self.assertEqual(compatible, result) 

2570 self.library._get_vserver.assert_called_once_with( 

2571 self.fake_src_share_server, 

2572 backend_name=self.fake_src_backend_name 

2573 ) 

2574 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2575 self.assertTrue(self.client.get_cluster_name.called) 

2576 data_motion.get_client_for_backend.assert_called_once_with( 

2577 self.fake_dest_backend_name, vserver_name=None 

2578 ) 

2579 

2580 def test__get_job_uuid(self): 

2581 self.assertEqual( 

2582 self.library._get_job_uuid( 

2583 c_fake.FAKE_MIGRATION_RESPONSE_WITH_JOB), 

2584 c_fake.FAKE_JOB_ID 

2585 ) 

2586 

2587 def test__wait_for_operation_status(self): 

2588 job_starting_state = copy.copy(c_fake.FAKE_JOB_SUCCESS_STATE) 

2589 job_starting_state['state'] = 'starting' 

2590 returned_jobs = [ 

2591 job_starting_state, 

2592 c_fake.FAKE_JOB_SUCCESS_STATE, 

2593 ] 

2594 

2595 self.mock_object(self.mock_dest_client, 'get_job', 

2596 mock.Mock(side_effect=returned_jobs)) 

2597 

2598 self.library._wait_for_operation_status( 

2599 c_fake.FAKE_JOB_ID, self.mock_dest_client.get_job 

2600 ) 

2601 

2602 self.assertEqual( 

2603 self.mock_dest_client.get_job.call_count, len(returned_jobs)) 

2604 

2605 def test__wait_for_operation_status_error(self): 

2606 starting_job = copy.copy(c_fake.FAKE_JOB_SUCCESS_STATE) 

2607 starting_job['state'] = 'starting' 

2608 errored_job = copy.copy(c_fake.FAKE_JOB_SUCCESS_STATE) 

2609 errored_job['state'] = constants.STATUS_ERROR 

2610 returned_jobs = [starting_job, errored_job] 

2611 

2612 self.mock_object(self.mock_dest_client, 'get_job', 

2613 mock.Mock(side_effect=returned_jobs)) 

2614 

2615 self.assertRaises( 

2616 exception.NetAppException, 

2617 self.library._wait_for_operation_status, 

2618 c_fake.FAKE_JOB_ID, 

2619 self.mock_dest_client.get_job 

2620 ) 

2621 

2622 @ddt.data( 

2623 {'src_supports_svm_migrate': True, 'dest_supports_svm_migrate': True}, 

2624 {'src_supports_svm_migrate': True, 'dest_supports_svm_migrate': False}, 

2625 {'src_supports_svm_migrate': False, 'dest_supports_svm_migrate': True}, 

2626 {'src_supports_svm_migrate': False, 'dest_supports_svm_migrate': False} 

2627 ) 

2628 @ddt.unpack 

2629 def test_share_server_migration_start(self, src_supports_svm_migrate, 

2630 dest_supports_svm_migrate): 

2631 fake_migration_data = {'fake_migration_key': 'fake_migration_value'} 

2632 self.mock_object( 

2633 self.library, '_get_vserver', 

2634 mock.Mock( 

2635 side_effect=[(self.fake_src_vserver, self.mock_src_client)])) 

2636 self.mock_object(data_motion, 'get_client_for_backend', 

2637 mock.Mock(return_value=self.mock_dest_client)) 

2638 mock_start_using_svm_migrate = self.mock_object( 

2639 self.library, '_migration_start_using_svm_migrate', 

2640 mock.Mock(return_value=fake_migration_data)) 

2641 mock_start_using_svm_dr = self.mock_object( 

2642 self.library, '_migration_start_using_svm_dr', 

2643 mock.Mock(return_value=fake_migration_data)) 

2644 

2645 self.mock_src_client.is_svm_migrate_supported.return_value = ( 

2646 src_supports_svm_migrate) 

2647 self.mock_dest_client.is_svm_migrate_supported.return_value = ( 

2648 dest_supports_svm_migrate) 

2649 src_and_dest_support_svm_migrate = all( 

2650 [src_supports_svm_migrate, dest_supports_svm_migrate]) 

2651 

2652 result = self.library.share_server_migration_start( 

2653 None, self.fake_src_share_server, self.fake_dest_share_server, 

2654 [fake.SHARE_INSTANCE], []) 

2655 

2656 self.library._get_vserver.assert_called_once_with( 

2657 share_server=self.fake_src_share_server, 

2658 backend_name=self.fake_src_backend_name) 

2659 if src_and_dest_support_svm_migrate: 

2660 mock_start_using_svm_migrate.assert_called_once_with( 

2661 None, self.fake_src_share_server, self.fake_dest_share_server, 

2662 self.mock_src_client, self.mock_dest_client) 

2663 else: 

2664 mock_start_using_svm_dr.assert_called_once_with( 

2665 self.fake_src_share_server, self.fake_dest_share_server 

2666 ) 

2667 self.assertEqual(result, fake_migration_data) 

2668 

2669 @ddt.data({'vserver_peered': True, 'src_cluster': fake.CLUSTER_NAME}, 

2670 {'vserver_peered': False, 'src_cluster': fake.CLUSTER_NAME}, 

2671 {'vserver_peered': False, 'src_cluster': fake.CLUSTER_NAME_2}) 

2672 @ddt.unpack 

2673 def test__migration_start_using_svm_dr(self, vserver_peered, src_cluster): 

2674 dest_cluster = fake.CLUSTER_NAME 

2675 dm_session_mock = mock.Mock() 

2676 self.mock_object(self.library, '_get_vserver', 

2677 mock.Mock(side_effect=[ 

2678 (self.fake_src_vserver, self.mock_src_client), 

2679 (self.fake_dest_vserver, 

2680 self.mock_dest_client)])) 

2681 self.mock_object(self.mock_src_client, 'get_cluster_name', 

2682 mock.Mock(return_value=src_cluster)) 

2683 self.mock_object(self.mock_dest_client, 'get_cluster_name', 

2684 mock.Mock(return_value=dest_cluster)) 

2685 self.mock_object(self.library, '_get_vserver_peers', 

2686 mock.Mock(return_value=vserver_peered)) 

2687 self.mock_object(data_motion, "DataMotionSession", 

2688 mock.Mock(return_value=dm_session_mock)) 

2689 

2690 self.library._migration_start_using_svm_dr( 

2691 self.fake_src_share_server, self.fake_dest_share_server) 

2692 

2693 self.library._get_vserver.assert_has_calls([ 

2694 mock.call(share_server=self.fake_src_share_server, 

2695 backend_name=self.fake_src_backend_name), 

2696 mock.call(share_server=self.fake_dest_share_server, 

2697 backend_name=self.fake_dest_backend_name)]) 

2698 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2699 self.assertTrue(self.mock_dest_client.get_cluster_name.called) 

2700 self.library._get_vserver_peers.assert_called_once_with( 

2701 self.fake_dest_vserver, self.fake_src_vserver 

2702 ) 

2703 mock_vserver_peer = self.mock_dest_client.create_vserver_peer 

2704 if vserver_peered: 

2705 self.assertFalse(mock_vserver_peer.called) 

2706 else: 

2707 mock_vserver_peer.assert_called_once_with( 

2708 self.fake_dest_vserver, self.fake_src_vserver, 

2709 peer_cluster_name=src_cluster 

2710 ) 

2711 accept_peer_mock = self.mock_src_client.accept_vserver_peer 

2712 if src_cluster != dest_cluster: 

2713 accept_peer_mock.assert_called_once_with( 

2714 self.fake_src_vserver, self.fake_dest_vserver 

2715 ) 

2716 else: 

2717 self.assertFalse(accept_peer_mock.called) 

2718 dm_session_mock.create_snapmirror_svm.assert_called_once_with( 

2719 self.fake_src_share_server, self.fake_dest_share_server 

2720 ) 

2721 

2722 def test_share_server_migration_start_snapmirror_start_failure(self): 

2723 self.mock_object(self.library, '_get_vserver', 

2724 mock.Mock(side_effect=[ 

2725 (self.fake_src_vserver, self.mock_src_client), 

2726 (self.fake_dest_vserver, 

2727 self.mock_dest_client)])) 

2728 self.mock_object(self.mock_src_client, 'get_cluster_name') 

2729 self.mock_object(self.mock_dest_client, 'get_cluster_name') 

2730 self.mock_object(self.library, '_get_vserver_peers', 

2731 mock.Mock(return_value=True)) 

2732 dm_session_mock = mock.Mock() 

2733 self.mock_object(data_motion, "DataMotionSession", 

2734 mock.Mock(return_value=dm_session_mock)) 

2735 create_snapmirror_mock = self.mock_object( 

2736 dm_session_mock, 'create_snapmirror_svm', 

2737 mock.Mock( 

2738 side_effect=exception.NetAppException(message='fake'))) 

2739 

2740 self.assertRaises(exception.NetAppException, 

2741 self.library._migration_start_using_svm_dr, 

2742 self.fake_src_share_server, 

2743 self.fake_dest_share_server) 

2744 

2745 self.library._get_vserver.assert_has_calls([ 

2746 mock.call(share_server=self.fake_src_share_server, 

2747 backend_name=self.fake_src_backend_name), 

2748 mock.call(share_server=self.fake_dest_share_server, 

2749 backend_name=self.fake_dest_backend_name)]) 

2750 self.assertTrue(self.mock_src_client.get_cluster_name.called) 

2751 self.assertTrue(self.mock_dest_client.get_cluster_name.called) 

2752 self.library._get_vserver_peers.assert_called_once_with( 

2753 self.fake_dest_vserver, self.fake_src_vserver 

2754 ) 

2755 self.assertFalse(self.mock_dest_client.create_vserver_peer.called) 

2756 

2757 create_snapmirror_mock.assert_called_once_with( 

2758 self.fake_src_share_server, self.fake_dest_share_server 

2759 ) 

2760 dm_session_mock.cancel_snapmirror_svm.assert_called_once_with( 

2761 self.fake_src_share_server, self.fake_dest_share_server 

2762 ) 

2763 

2764 @ddt.data( 

2765 {'network_change_during_migration': True}, 

2766 {'network_change_during_migration': False}) 

2767 @ddt.unpack 

2768 def test__migration_start_using_svm_migrate( 

2769 self, network_change_during_migration): 

2770 

2771 self.fake_src_share_server['share_network_subnet_id'] = 'fake_sns_id' 

2772 self.fake_dest_share_server['share_network_subnet_id'] = 'fake_sns_id' 

2773 node_name = fake.CLUSTER_NODES[0] 

2774 expected_server_info = { 

2775 'backend_details': { 

2776 'migration_operation_id': c_fake.FAKE_MIGRATION_POST_ID 

2777 } 

2778 } 

2779 

2780 if not network_change_during_migration: 

2781 self.fake_dest_share_server['network_allocations'] = None 

2782 server_to_get_network_info = ( 

2783 self.fake_dest_share_server 

2784 if network_change_during_migration else self.fake_src_share_server) 

2785 

2786 if network_change_during_migration: 

2787 self.fake_dest_share_server['share_network_subnet_id'] = ( 

2788 'different_sns_id') 

2789 

2790 segmentation_id = ( 

2791 server_to_get_network_info['network_allocations'][0][ 

2792 'segmentation_id']) 

2793 

2794 network_info = { 

2795 'network_allocations': 

2796 server_to_get_network_info['network_allocations'], 

2797 'neutron_subnet_id': 

2798 server_to_get_network_info['share_network_subnets'][0].get( 

2799 'neutron_subnet_id') 

2800 } 

2801 

2802 mock_list_cluster_nodes = self.mock_object( 

2803 self.library._client, 'list_cluster_nodes', 

2804 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2805 mock_get_data_port = self.mock_object( 

2806 self.library, '_get_node_data_port', 

2807 mock.Mock(return_value=fake.NODE_DATA_PORT)) 

2808 mock_get_ipspace = self.mock_object( 

2809 self.library._client, 'get_ipspace_name_for_vlan_port', 

2810 mock.Mock(return_value=fake.IPSPACE)) 

2811 mock_create_port = self.mock_object( 

2812 self.library, '_create_port_and_broadcast_domain') 

2813 mock_get_cluster_name = self.mock_object( 

2814 self.mock_src_client, 'get_cluster_name', 

2815 mock.Mock(return_value=fake.CLUSTER_NAME)) 

2816 mock_get_aggregates = self.mock_object( 

2817 self.library, '_find_matching_aggregates', 

2818 mock.Mock(return_value=fake.AGGREGATES)) 

2819 mock_svm_migration_start = self.mock_object( 

2820 self.mock_dest_client, 'svm_migration_start', 

2821 mock.Mock(return_value=c_fake.FAKE_MIGRATION_RESPONSE_WITH_JOB)) 

2822 mock_get_job = self.mock_object( 

2823 self.mock_dest_client, 'get_job', 

2824 mock.Mock(return_value=c_fake.FAKE_JOB_SUCCESS_STATE)) 

2825 

2826 server_info = self.library._migration_start_using_svm_migrate( 

2827 None, self.fake_src_share_server, self.fake_dest_share_server, 

2828 self.mock_src_client, self.mock_dest_client) 

2829 

2830 self.assertTrue(mock_list_cluster_nodes.called) 

2831 mock_get_data_port.assert_called_once_with(node_name) 

2832 mock_get_ipspace.assert_called_once_with( 

2833 node_name, fake.NODE_DATA_PORT, segmentation_id) 

2834 mock_create_port.assert_called_once_with( 

2835 fake.IPSPACE, network_info) 

2836 self.assertTrue(mock_get_cluster_name.called) 

2837 mock_svm_migration_start.assert_called_once_with( 

2838 fake.CLUSTER_NAME, self.fake_src_vserver, fake.AGGREGATES, 

2839 dest_ipspace=fake.IPSPACE) 

2840 self.assertTrue(mock_get_aggregates.called) 

2841 self.assertEqual(expected_server_info, server_info) 

2842 mock_get_job.assert_called_once_with(c_fake.FAKE_JOB_ID) 

2843 

2844 def test__migration_start_using_svm_migrate_exception(self): 

2845 

2846 self.fake_src_share_server['share_network_subnet_id'] = 'fake_sns_id' 

2847 self.fake_dest_share_server['share_network_subnet_id'] = 'fake_sns_id' 

2848 node_name = fake.CLUSTER_NODES[0] 

2849 

2850 server_to_get_network_info = self.fake_dest_share_server 

2851 

2852 segmentation_id = ( 

2853 server_to_get_network_info['network_allocations'][0][ 

2854 'segmentation_id']) 

2855 

2856 network_info = { 

2857 'network_allocations': 

2858 server_to_get_network_info['network_allocations'], 

2859 'neutron_subnet_id': 

2860 server_to_get_network_info['share_network_subnets'][0].get( 

2861 'neutron_subnet_id') 

2862 } 

2863 

2864 mock_list_cluster_nodes = self.mock_object( 

2865 self.library._client, 'list_cluster_nodes', 

2866 mock.Mock(return_value=fake.CLUSTER_NODES)) 

2867 mock_get_data_port = self.mock_object( 

2868 self.library, '_get_node_data_port', 

2869 mock.Mock(return_value=fake.NODE_DATA_PORT)) 

2870 mock_get_ipspace = self.mock_object( 

2871 self.library._client, 'get_ipspace_name_for_vlan_port', 

2872 mock.Mock(return_value=fake.IPSPACE)) 

2873 mock_create_port = self.mock_object( 

2874 self.library, '_create_port_and_broadcast_domain') 

2875 mock_get_vserver_name = self.mock_object( 

2876 self.library, '_get_vserver_name', 

2877 mock.Mock(return_value=fake.VSERVER1)) 

2878 mock_get_cluster_name = self.mock_object( 

2879 self.mock_src_client, 'get_cluster_name', 

2880 mock.Mock(return_value=fake.CLUSTER_NAME)) 

2881 mock_get_aggregates = self.mock_object( 

2882 self.library, '_find_matching_aggregates', 

2883 mock.Mock(return_value=fake.AGGREGATES)) 

2884 mock_svm_migration_start = self.mock_object( 

2885 self.mock_dest_client, 'svm_migration_start', 

2886 mock.Mock(side_effect=exception.NetAppException())) 

2887 mock_delete_ipspace = self.mock_object( 

2888 self.mock_dest_client, 'delete_ipspace') 

2889 

2890 self.assertRaises( 

2891 exception.NetAppException, 

2892 self.library._migration_start_using_svm_migrate, 

2893 None, 

2894 self.fake_src_share_server, self.fake_dest_share_server, 

2895 self.mock_src_client, self.mock_dest_client) 

2896 

2897 self.assertTrue(mock_list_cluster_nodes.called) 

2898 mock_get_data_port.assert_called_once_with(node_name) 

2899 mock_get_ipspace.assert_called_once_with( 

2900 node_name, fake.NODE_DATA_PORT, segmentation_id) 

2901 mock_create_port.assert_called_once_with( 

2902 fake.IPSPACE, network_info) 

2903 mock_get_vserver_name.assert_not_called() 

2904 self.assertTrue(mock_get_cluster_name.called) 

2905 mock_svm_migration_start.assert_called_once_with( 

2906 fake.CLUSTER_NAME, self.fake_src_vserver, fake.AGGREGATES, 

2907 dest_ipspace=fake.IPSPACE) 

2908 self.assertTrue(mock_get_aggregates.called) 

2909 mock_delete_ipspace.assert_called_once_with(fake.IPSPACE) 

2910 

2911 def test__get_snapmirror_svm(self): 

2912 dm_session_mock = mock.Mock() 

2913 self.mock_object(data_motion, "DataMotionSession", 

2914 mock.Mock(return_value=dm_session_mock)) 

2915 fake_snapmirrors = ['mirror1'] 

2916 self.mock_object(dm_session_mock, 'get_snapmirrors_svm', 

2917 mock.Mock(return_value=fake_snapmirrors)) 

2918 

2919 result = self.library._get_snapmirror_svm( 

2920 self.fake_src_share_server, self.fake_dest_share_server) 

2921 

2922 dm_session_mock.get_snapmirrors_svm.assert_called_once_with( 

2923 self.fake_src_share_server, self.fake_dest_share_server 

2924 ) 

2925 self.assertEqual(fake_snapmirrors, result) 

2926 

2927 def test__get_snapmirror_svm_fail_to_get_snapmirrors(self): 

2928 dm_session_mock = mock.Mock() 

2929 self.mock_object(data_motion, "DataMotionSession", 

2930 mock.Mock(return_value=dm_session_mock)) 

2931 self.mock_object(dm_session_mock, 'get_snapmirrors_svm', 

2932 mock.Mock( 

2933 side_effect=netapp_api.NaApiError(code=0))) 

2934 

2935 self.assertRaises(exception.NetAppException, 

2936 self.library._get_snapmirror_svm, 

2937 self.fake_src_share_server, 

2938 self.fake_dest_share_server) 

2939 

2940 dm_session_mock.get_snapmirrors_svm.assert_called_once_with( 

2941 self.fake_src_share_server, self.fake_dest_share_server 

2942 ) 

2943 

2944 def test_share_server_migration_continue_svm_dr_no_snapmirror(self): 

2945 self.mock_object(self.library, '_get_snapmirror_svm', 

2946 mock.Mock(return_value=[])) 

2947 

2948 self.assertRaises(exception.NetAppException, 

2949 self.library._share_server_migration_continue_svm_dr, 

2950 self.fake_src_share_server, 

2951 self.fake_dest_share_server) 

2952 

2953 self.library._get_snapmirror_svm.assert_called_once_with( 

2954 self.fake_src_share_server, self.fake_dest_share_server 

2955 ) 

2956 

2957 @ddt.data({'mirror_state': 'snapmirrored', 'status': 'idle'}, 

2958 {'mirror_state': 'uninitialized', 'status': 'transferring'}, 

2959 {'mirror_state': 'snapmirrored', 'status': 'quiescing'}, ) 

2960 @ddt.unpack 

2961 def test_share_server_migration_continue_svm_dr(self, mirror_state, 

2962 status): 

2963 fake_snapmirror = { 

2964 'mirror-state': mirror_state, 

2965 'relationship-status': status, 

2966 } 

2967 self.mock_object(self.library, '_get_snapmirror_svm', 

2968 mock.Mock(return_value=[fake_snapmirror])) 

2969 expected = mirror_state == 'snapmirrored' and status == 'idle' 

2970 

2971 result = self.library._share_server_migration_continue_svm_dr( 

2972 self.fake_src_share_server, 

2973 self.fake_dest_share_server 

2974 ) 

2975 

2976 self.assertEqual(expected, result) 

2977 self.library._get_snapmirror_svm.assert_called_once_with( 

2978 self.fake_src_share_server, self.fake_dest_share_server 

2979 ) 

2980 

2981 @ddt.data( 

2982 ('ready_for_cutover', True), 

2983 ('transferring', False) 

2984 ) 

2985 @ddt.unpack 

2986 def test_share_server_migration_continue_svm_migrate( 

2987 self, job_state, first_phase_completed): 

2988 c_fake.FAKE_MIGRATION_JOB_SUCCESS.update({"state": job_state}) 

2989 

2990 self.mock_object(data_motion, 'get_client_for_host', 

2991 mock.Mock(return_value=self.mock_dest_client)) 

2992 self.mock_object( 

2993 self.mock_dest_client, 'svm_migration_get', 

2994 mock.Mock(return_value=c_fake.FAKE_MIGRATION_JOB_SUCCESS)) 

2995 

2996 result = self.library._share_server_migration_continue_svm_migrate( 

2997 self.fake_dest_share_server, c_fake.FAKE_MIGRATION_POST_ID) 

2998 

2999 self.assertEqual(first_phase_completed, result) 

3000 data_motion.get_client_for_host.assert_called_once_with( 

3001 self.fake_dest_share_server['host']) 

3002 self.mock_dest_client.svm_migration_get.assert_called_once_with( 

3003 c_fake.FAKE_MIGRATION_POST_ID) 

3004 

3005 def test_share_server_migration_continue_svm_migrate_exception(self): 

3006 

3007 self.mock_object(data_motion, 'get_client_for_host', 

3008 mock.Mock(return_value=self.mock_dest_client)) 

3009 self.mock_object(self.mock_dest_client, 'svm_migration_get', 

3010 mock.Mock(side_effect=netapp_api.NaApiError())) 

3011 

3012 self.assertRaises( 

3013 exception.NetAppException, 

3014 self.library._share_server_migration_continue_svm_migrate, 

3015 self.fake_dest_share_server, c_fake.FAKE_MIGRATION_POST_ID) 

3016 

3017 data_motion.get_client_for_host.assert_called_once_with( 

3018 self.fake_dest_share_server['host']) 

3019 self.mock_dest_client.svm_migration_get.assert_called_once_with( 

3020 c_fake.FAKE_MIGRATION_POST_ID) 

3021 

3022 @ddt.data(None, 'fake_migration_id') 

3023 def test_share_server_migration_continue(self, migration_id): 

3024 expected_result = True 

3025 self.mock_object( 

3026 self.library, '_get_share_server_migration_id', 

3027 mock.Mock(return_value=migration_id)) 

3028 self.mock_object( 

3029 self.library, '_share_server_migration_continue_svm_migrate', 

3030 mock.Mock(return_value=expected_result)) 

3031 self.mock_object( 

3032 self.library, '_share_server_migration_continue_svm_dr', 

3033 mock.Mock(return_value=expected_result)) 

3034 

3035 result = self.library.share_server_migration_continue( 

3036 None, self.fake_src_share_server, self.fake_dest_share_server, 

3037 [], [] 

3038 ) 

3039 

3040 self.assertEqual(expected_result, result) 

3041 

3042 def test__setup_networking_for_destination_vserver(self): 

3043 self.mock_object(self.mock_dest_client, 'get_vserver_ipspace', 

3044 mock.Mock(return_value=fake.IPSPACE)) 

3045 self.mock_object(self.library, '_setup_network_for_vserver') 

3046 

3047 self.library._setup_networking_for_destination_vserver( 

3048 self.mock_dest_client, self.fake_vserver, 

3049 fake.NETWORK_INFO_LIST) 

3050 

3051 self.mock_dest_client.get_vserver_ipspace.assert_called_once_with( 

3052 self.fake_vserver) 

3053 self.library._setup_network_for_vserver.assert_called_once_with( 

3054 self.fake_vserver, self.mock_dest_client, fake.NETWORK_INFO_LIST, 

3055 fake.IPSPACE, enable_nfs=False, security_services=None) 

3056 

3057 def test__migration_complete_svm_dr(self): 

3058 dm_session_mock = mock.Mock() 

3059 self.mock_object(self.library, '_get_vserver', 

3060 mock.Mock(return_value=(self.fake_dest_vserver, 

3061 self.mock_dest_client))) 

3062 self.mock_object(data_motion, "DataMotionSession", 

3063 mock.Mock(return_value=dm_session_mock)) 

3064 self.mock_object( 

3065 self.library, '_setup_networking_for_destination_vserver') 

3066 

3067 self.library._share_server_migration_complete_svm_dr( 

3068 self.fake_src_share_server, self.fake_dest_share_server, 

3069 self.fake_src_vserver, self.mock_src_client, 

3070 [fake.SHARE_INSTANCE], fake.NETWORK_INFO_LIST 

3071 ) 

3072 

3073 self.library._get_vserver.assert_called_once_with( 

3074 share_server=self.fake_dest_share_server, 

3075 backend_name=self.fake_dest_backend_name 

3076 ) 

3077 dm_session_mock.update_snapmirror_svm.assert_called_once_with( 

3078 self.fake_src_share_server, self.fake_dest_share_server 

3079 ) 

3080 quiesce_break_mock = dm_session_mock.quiesce_and_break_snapmirror_svm 

3081 quiesce_break_mock.assert_called_once_with( 

3082 self.fake_src_share_server, self.fake_dest_share_server 

3083 ) 

3084 dm_session_mock.wait_for_vserver_state.assert_called_once_with( 

3085 self.fake_dest_vserver, self.mock_dest_client, subtype='default', 

3086 state='running', operational_state='stopped', 

3087 timeout=(self.library.configuration. 

3088 netapp_server_migration_state_change_timeout) 

3089 ) 

3090 self.mock_src_client.stop_vserver.assert_called_once_with( 

3091 self.fake_src_vserver 

3092 ) 

3093 (self.library._setup_networking_for_destination_vserver 

3094 .assert_called_once_with( 

3095 self.mock_dest_client, self.fake_dest_vserver, 

3096 fake.NETWORK_INFO_LIST)) 

3097 self.mock_dest_client.start_vserver.assert_called_once_with( 

3098 self.fake_dest_vserver 

3099 ) 

3100 dm_session_mock.delete_snapmirror_svm.assert_called_once_with( 

3101 self.fake_src_share_server, self.fake_dest_share_server 

3102 ) 

3103 

3104 @ddt.data( 

3105 {'is_svm_dr': True, 'network_change': True}, 

3106 {'is_svm_dr': False, 'network_change': True}, 

3107 {'is_svm_dr': False, 'network_change': False}, 

3108 ) 

3109 @ddt.unpack 

3110 def test_share_server_migration_complete(self, is_svm_dr, network_change): 

3111 current_interfaces = ['interface_1', 'interface_2'] 

3112 self.mock_object(self.library, '_get_vserver', 

3113 mock.Mock(side_effect=[ 

3114 (self.fake_src_vserver, self.mock_src_client), 

3115 (self.fake_dest_vserver, self.mock_dest_client)])) 

3116 mock_complete_svm_migrate = self.mock_object( 

3117 self.library, '_share_server_migration_complete_svm_migrate') 

3118 mock_complete_svm_dr = self.mock_object( 

3119 self.library, '_share_server_migration_complete_svm_dr') 

3120 fake_share_name = self.library._get_backend_share_name( 

3121 fake.SHARE_INSTANCE['id']) 

3122 fake_volume = copy.deepcopy(fake.CLIENT_GET_VOLUME_RESPONSE) 

3123 self.mock_object(self.mock_dest_client, 'get_volume', 

3124 mock.Mock(return_value=fake_volume)) 

3125 self.mock_object(self.library, '_create_export', 

3126 mock.Mock(return_value=fake.NFS_EXPORTS)) 

3127 self.mock_object(self.library, '_delete_share') 

3128 mock_update_share_attrs = self.mock_object( 

3129 self.library, '_update_share_attributes_after_server_migration') 

3130 self.mock_object(data_motion, 'get_client_for_host', 

3131 mock.Mock(return_value=self.mock_dest_client)) 

3132 self.mock_object(self.mock_dest_client, 'list_network_interfaces', 

3133 mock.Mock(return_value=current_interfaces)) 

3134 self.mock_object(self.mock_dest_client, 'delete_network_interface') 

3135 self.mock_object(self.library, 

3136 '_setup_networking_for_destination_vserver') 

3137 

3138 sns_id = 'fake_sns_id' 

3139 new_sns_id = 'fake_sns_id_2' 

3140 self.fake_src_share_server['share_network_subnet_id'] = sns_id 

3141 self.fake_dest_share_server['share_network_subnet_id'] = ( 

3142 sns_id if not network_change else new_sns_id) 

3143 share_instances = [fake.SHARE_INSTANCE] 

3144 migration_id = 'fake_migration_id' 

3145 share_host = fake.SHARE_INSTANCE['host'] 

3146 self.fake_src_share_server['backend_details']['ports'] = [] 

3147 

3148 if not is_svm_dr: 

3149 self.fake_dest_share_server['backend_details'][ 

3150 'migration_operation_id'] = ( 

3151 migration_id) 

3152 share_host = share_host.replace( 

3153 share_host.split('#')[1], fake_volume['aggregate']) 

3154 should_recreate_export = is_svm_dr or network_change 

3155 share_server_to_get_vserver_name = ( 

3156 self.fake_dest_share_server 

3157 if is_svm_dr else self.fake_src_share_server) 

3158 

3159 result = self.library.share_server_migration_complete( 

3160 None, 

3161 self.fake_src_share_server, 

3162 self.fake_dest_share_server, 

3163 share_instances, [], 

3164 fake.NETWORK_INFO_LIST 

3165 ) 

3166 

3167 expected_share_updates = { 

3168 fake.SHARE_INSTANCE['id']: { 

3169 'pool_name': fake_volume['aggregate'] 

3170 } 

3171 } 

3172 expected_share_updates[fake.SHARE_INSTANCE['id']].update( 

3173 {'export_locations': fake.NFS_EXPORTS}) 

3174 expected_backend_details = ( 

3175 {} if is_svm_dr else self.fake_src_share_server['backend_details']) 

3176 expected_result = { 

3177 'share_updates': expected_share_updates, 

3178 'server_backend_details': expected_backend_details 

3179 } 

3180 

3181 self.assertEqual(expected_result, result) 

3182 self.library._get_vserver.assert_has_calls([ 

3183 mock.call(share_server=self.fake_src_share_server, 

3184 backend_name=self.fake_src_backend_name), 

3185 mock.call(share_server=share_server_to_get_vserver_name, 

3186 backend_name=self.fake_dest_backend_name)]) 

3187 if is_svm_dr: 

3188 mock_complete_svm_dr.assert_called_once_with( 

3189 self.fake_src_share_server, self.fake_dest_share_server, 

3190 self.fake_src_vserver, self.mock_src_client, 

3191 share_instances, fake.NETWORK_INFO_LIST 

3192 ) 

3193 self.library._delete_share.assert_called_once_with( 

3194 fake.SHARE_INSTANCE, self.fake_src_vserver, 

3195 self.mock_src_client, remove_export=True) 

3196 mock_update_share_attrs.assert_called_once_with( 

3197 fake.SHARE_INSTANCE, self.mock_src_client, 

3198 fake_volume['aggregate'], self.mock_dest_client) 

3199 else: 

3200 mock_complete_svm_migrate.assert_called_once_with( 

3201 migration_id, self.fake_dest_share_server) 

3202 self.mock_dest_client.list_network_interfaces.assert_called_once() 

3203 data_motion.get_client_for_host.assert_has_calls([ 

3204 mock.call(self.fake_dest_share_server['host']), 

3205 mock.call(self.fake_src_share_server['host']), 

3206 ]) 

3207 

3208 self.mock_dest_client.delete_network_interface.assert_has_calls( 

3209 [mock.call(self.fake_src_vserver, interface_name) 

3210 for interface_name in current_interfaces]) 

3211 (self.library._setup_networking_for_destination_vserver. 

3212 assert_called_once_with(self.mock_dest_client, 

3213 self.fake_src_vserver, 

3214 fake.NETWORK_INFO_LIST)) 

3215 if should_recreate_export: 

3216 create_export_calls = [ 

3217 mock.call( 

3218 instance, self.fake_dest_share_server, 

3219 self.fake_dest_vserver, self.mock_dest_client, 

3220 clear_current_export_policy=False, 

3221 ensure_share_already_exists=True, 

3222 share_host=share_host) 

3223 for instance in share_instances 

3224 ] 

3225 self.library._create_export.assert_has_calls(create_export_calls) 

3226 self.mock_dest_client.get_volume.assert_called_once_with( 

3227 fake_share_name) 

3228 

3229 def test_share_server_migration_complete_failure_breaking(self): 

3230 dm_session_mock = mock.Mock() 

3231 self.mock_object(data_motion, "DataMotionSession", 

3232 mock.Mock(return_value=dm_session_mock)) 

3233 self.mock_object( 

3234 self.library, '_get_vserver', 

3235 mock.Mock(return_value=(self.fake_dest_vserver, 

3236 self.mock_dest_client))) 

3237 self.mock_object(dm_session_mock, 'quiesce_and_break_snapmirror_svm', 

3238 mock.Mock(side_effect=exception.NetAppException)) 

3239 self.mock_object(self.library, '_delete_share') 

3240 

3241 self.assertRaises(exception.NetAppException, 

3242 self.library._share_server_migration_complete_svm_dr, 

3243 self.fake_src_share_server, 

3244 self.fake_dest_share_server, 

3245 self.fake_src_vserver, 

3246 self.mock_src_client, [fake.SHARE_INSTANCE], 

3247 [fake.NETWORK_INFO]) 

3248 

3249 dm_session_mock.update_snapmirror_svm.assert_called_once_with( 

3250 self.fake_src_share_server, self.fake_dest_share_server 

3251 ) 

3252 self.library._get_vserver.assert_called_once_with( 

3253 share_server=self.fake_dest_share_server, 

3254 backend_name=self.fake_dest_backend_name) 

3255 quiesce_break_mock = dm_session_mock.quiesce_and_break_snapmirror_svm 

3256 quiesce_break_mock.assert_called_once_with( 

3257 self.fake_src_share_server, self.fake_dest_share_server 

3258 ) 

3259 self.mock_src_client.start_vserver.assert_called_once_with( 

3260 self.fake_src_vserver 

3261 ) 

3262 dm_session_mock.cancel_snapmirror_svm.assert_called_once_with( 

3263 self.fake_src_share_server, self.fake_dest_share_server 

3264 ) 

3265 self.library._delete_share.assert_called_once_with( 

3266 fake.SHARE_INSTANCE, self.fake_dest_vserver, self.mock_dest_client, 

3267 remove_export=False) 

3268 

3269 def test_share_server_migration_complete_failure_get_new_volume(self): 

3270 dm_session_mock = mock.Mock() 

3271 fake_share_name = self.library._get_backend_share_name( 

3272 fake.SHARE_INSTANCE['id']) 

3273 self.mock_object(data_motion, "DataMotionSession", 

3274 mock.Mock(return_value=dm_session_mock)) 

3275 self.mock_object(self.library, '_get_vserver', 

3276 mock.Mock(side_effect=[ 

3277 (self.fake_src_vserver, self.mock_src_client), 

3278 (self.fake_dest_vserver, self.mock_dest_client)])) 

3279 self.mock_object(self.library, 

3280 '_share_server_migration_complete_svm_dr') 

3281 self.mock_object(self.library, '_get_share_server_migration_id', 

3282 mock.Mock(return_value=None)) 

3283 self.mock_object(self.mock_dest_client, 'get_volume', 

3284 mock.Mock(side_effect=exception.NetAppException)) 

3285 

3286 self.assertRaises(exception.NetAppException, 

3287 self.library.share_server_migration_complete, 

3288 None, 

3289 self.fake_src_share_server, 

3290 self.fake_dest_share_server, 

3291 [fake.SHARE_INSTANCE], [], 

3292 fake.NETWORK_INFO_LIST) 

3293 

3294 self.library._get_vserver.assert_has_calls([ 

3295 mock.call(share_server=self.fake_src_share_server, 

3296 backend_name=self.fake_src_backend_name), 

3297 mock.call(share_server=self.fake_dest_share_server, 

3298 backend_name=self.fake_dest_backend_name)]) 

3299 self.mock_dest_client.get_volume.assert_called_once_with( 

3300 fake_share_name) 

3301 

3302 def test__share_server_migration_complete_svm_migrate(self): 

3303 completion_status = na_utils.MIGRATION_STATE_MIGRATE_COMPLETE 

3304 migration_id = 'fake_migration_id' 

3305 fake_complete_job_uuid = 'fake_uuid' 

3306 fake_complete_job = { 

3307 'job': { 

3308 'state': 'cutover_triggered', 

3309 'uuid': fake_complete_job_uuid 

3310 } 

3311 } 

3312 self.mock_object(data_motion, 'get_client_for_host', 

3313 mock.Mock(return_value=self.mock_dest_client)) 

3314 self.mock_object(self.mock_dest_client, 'svm_migrate_complete', 

3315 mock.Mock(return_value=fake_complete_job)) 

3316 self.mock_object(self.library, '_get_job_uuid', 

3317 mock.Mock(return_value=fake_complete_job_uuid)) 

3318 self.mock_object(self.library, '_wait_for_operation_status') 

3319 

3320 self.library._share_server_migration_complete_svm_migrate( 

3321 migration_id, self.fake_dest_share_server) 

3322 

3323 data_motion.get_client_for_host.assert_called_once_with( 

3324 self.fake_dest_share_server['host']) 

3325 self.mock_dest_client.svm_migrate_complete.assert_called_once_with( 

3326 migration_id) 

3327 self.library._get_job_uuid.assert_called_once_with(fake_complete_job) 

3328 self.library._wait_for_operation_status.assert_has_calls( 

3329 [mock.call(fake_complete_job_uuid, self.mock_dest_client.get_job), 

3330 mock.call(migration_id, self.mock_dest_client.svm_migration_get, 

3331 desired_status=completion_status) 

3332 ] 

3333 ) 

3334 

3335 def test__share_server_migration_complete_svm_migrate_failed_to_complete( 

3336 self): 

3337 migration_id = 'fake_migration_id' 

3338 

3339 self.mock_object(data_motion, 'get_client_for_host', 

3340 mock.Mock(return_value=self.mock_dest_client)) 

3341 self.mock_object(self.mock_dest_client, 'svm_migrate_complete', 

3342 mock.Mock(side_effect=exception.NetAppException())) 

3343 

3344 self.assertRaises( 

3345 exception.NetAppException, 

3346 self.library._share_server_migration_complete_svm_migrate, 

3347 migration_id, self.fake_dest_share_server) 

3348 

3349 data_motion.get_client_for_host.assert_called_once_with( 

3350 self.fake_dest_share_server['host']) 

3351 self.mock_dest_client.svm_migrate_complete.assert_called_once_with( 

3352 migration_id) 

3353 

3354 @ddt.data([], ['fake_snapmirror']) 

3355 def test_share_server_migration_cancel_svm_dr(self, snapmirrors): 

3356 dm_session_mock = mock.Mock() 

3357 self.mock_object(data_motion, "DataMotionSession", 

3358 mock.Mock(return_value=dm_session_mock)) 

3359 self.mock_object(self.library, '_get_vserver', 

3360 mock.Mock(return_value=(self.fake_dest_vserver, 

3361 self.mock_dest_client))) 

3362 self.mock_object(self.library, '_get_snapmirror_svm', 

3363 mock.Mock(return_value=snapmirrors)) 

3364 self.mock_object(self.library, '_delete_share') 

3365 

3366 self.library._migration_cancel_using_svm_dr( 

3367 self.fake_src_share_server, 

3368 self.fake_dest_share_server, 

3369 [fake.SHARE_INSTANCE] 

3370 ) 

3371 

3372 self.library._get_vserver.assert_called_once_with( 

3373 share_server=self.fake_dest_share_server, 

3374 backend_name=self.fake_dest_backend_name) 

3375 self.library._get_snapmirror_svm.assert_called_once_with( 

3376 self.fake_src_share_server, self.fake_dest_share_server 

3377 ) 

3378 if snapmirrors: 

3379 dm_session_mock.cancel_snapmirror_svm.assert_called_once_with( 

3380 self.fake_src_share_server, self.fake_dest_share_server 

3381 ) 

3382 self.library._delete_share.assert_called_once_with( 

3383 fake.SHARE_INSTANCE, self.fake_dest_vserver, self.mock_dest_client, 

3384 remove_export=False) 

3385 

3386 @ddt.data(True, False) 

3387 def test__migration_cancel_using_svm_migrate(self, has_ipspace): 

3388 pause_job_uuid = 'fake_pause_job_id' 

3389 cancel_job_uuid = 'fake_cancel_job_id' 

3390 ipspace_name = 'fake_ipspace_name' 

3391 migration_id = 'fake_migration_id' 

3392 pause_job = { 

3393 'uuid': pause_job_uuid 

3394 } 

3395 cancel_job = { 

3396 'uuid': cancel_job_uuid 

3397 } 

3398 migration_information = { 

3399 "destination": { 

3400 "ipspace": { 

3401 "name": ipspace_name 

3402 } 

3403 } 

3404 } 

3405 

3406 if has_ipspace: 

3407 migration_information["destination"]["ipspace"]["name"] = ( 

3408 ipspace_name) 

3409 

3410 self.mock_object(self.library, '_get_job_uuid', 

3411 mock.Mock( 

3412 side_effect=[pause_job_uuid, cancel_job_uuid])) 

3413 self.mock_object(data_motion, 'get_client_for_host', 

3414 mock.Mock(return_value=self.mock_dest_client)) 

3415 self.mock_object(self.mock_dest_client, 'svm_migration_get', 

3416 mock.Mock(return_value=migration_information)) 

3417 self.mock_object(self.mock_dest_client, 'svm_migrate_pause', 

3418 mock.Mock(return_value=pause_job)) 

3419 self.mock_object(self.library, '_wait_for_operation_status') 

3420 self.mock_object(self.mock_dest_client, 'svm_migrate_cancel', 

3421 mock.Mock(return_value=cancel_job)) 

3422 self.mock_object(self.mock_dest_client, 'ipspace_has_data_vservers', 

3423 mock.Mock(return_value=False)) 

3424 self.mock_object(self.mock_dest_client, 'delete_ipspace') 

3425 self.mock_object(self.mock_dest_client, 

3426 'list_cluster_nodes', 

3427 mock.Mock(return_value=fake.CLUSTER_NODES)) 

3428 self.mock_object(self.library, 

3429 '_get_node_data_port', 

3430 mock.Mock(return_value='fake_port')) 

3431 

3432 self.library._migration_cancel_using_svm_migrate( 

3433 migration_id, self.fake_dest_share_server) 

3434 

3435 self.library._get_job_uuid.assert_has_calls( 

3436 [mock.call(pause_job), mock.call(cancel_job)] 

3437 ) 

3438 data_motion.get_client_for_host.assert_called_once_with( 

3439 self.fake_dest_share_server['host']) 

3440 self.mock_dest_client.svm_migration_get.assert_called_once_with( 

3441 migration_id) 

3442 self.mock_dest_client.svm_migrate_pause.assert_called_once_with( 

3443 migration_id) 

3444 self.library._wait_for_operation_status.assert_has_calls( 

3445 [mock.call(pause_job_uuid, self.mock_dest_client.get_job), 

3446 mock.call(migration_id, self.mock_dest_client.svm_migration_get, 

3447 desired_status=na_utils.MIGRATION_STATE_MIGRATE_PAUSED), 

3448 mock.call(cancel_job_uuid, self.mock_dest_client.get_job)] 

3449 ) 

3450 self.mock_dest_client.svm_migrate_cancel.assert_called_once_with( 

3451 migration_id) 

3452 

3453 if has_ipspace: 

3454 self.mock_dest_client.delete_ipspace.assert_called_once_with( 

3455 ipspace_name) 

3456 

3457 @ddt.data( 

3458 (mock.Mock(side_effect=exception.NetAppException()), mock.Mock()), 

3459 (mock.Mock(), mock.Mock(side_effect=exception.NetAppException())) 

3460 ) 

3461 @ddt.unpack 

3462 def test__migration_cancel_using_svm_migrate_error( 

3463 self, mock_pause, mock_cancel): 

3464 pause_job_uuid = 'fake_pause_job_id' 

3465 cancel_job_uuid = 'fake_cancel_job_id' 

3466 migration_id = 'fake_migration_id' 

3467 migration_information = { 

3468 "destination": { 

3469 "ipspace": { 

3470 "name": "ipspace_name" 

3471 } 

3472 } 

3473 } 

3474 

3475 self.mock_object(self.library, '_get_job_uuid', 

3476 mock.Mock( 

3477 side_effect=[pause_job_uuid, cancel_job_uuid])) 

3478 self.mock_object(data_motion, 'get_client_for_host', 

3479 mock.Mock(return_value=self.mock_dest_client)) 

3480 self.mock_object(self.mock_dest_client, 'svm_migration_get', 

3481 mock.Mock(return_value=migration_information)) 

3482 self.mock_object(self.mock_dest_client, 'svm_migrate_pause', 

3483 mock_pause) 

3484 self.mock_object(self.library, '_wait_for_operation_status') 

3485 self.mock_object(self.mock_dest_client, 'svm_migrate_cancel', 

3486 mock_cancel) 

3487 

3488 self.assertRaises( 

3489 exception.NetAppException, 

3490 self.library._migration_cancel_using_svm_migrate, 

3491 migration_id, 

3492 self.fake_dest_share_server 

3493 ) 

3494 

3495 def test_share_server_migration_cancel_svm_dr_snapmirror_failure(self): 

3496 dm_session_mock = mock.Mock() 

3497 self.mock_object(data_motion, "DataMotionSession", 

3498 mock.Mock(return_value=dm_session_mock)) 

3499 self.mock_object(self.library, '_get_vserver', 

3500 mock.Mock(return_value=(self.fake_dest_vserver, 

3501 self.mock_dest_client))) 

3502 self.mock_object(self.library, '_get_snapmirror_svm', 

3503 mock.Mock(return_value=['fake_snapmirror'])) 

3504 self.mock_object(dm_session_mock, 'cancel_snapmirror_svm', 

3505 mock.Mock(side_effect=exception.NetAppException)) 

3506 

3507 self.assertRaises(exception.NetAppException, 

3508 self.library._migration_cancel_using_svm_dr, 

3509 self.fake_src_share_server, 

3510 self.fake_dest_share_server, 

3511 [fake.SHARE_INSTANCE]) 

3512 

3513 self.library._get_vserver.assert_called_once_with( 

3514 share_server=self.fake_dest_share_server, 

3515 backend_name=self.fake_dest_backend_name) 

3516 self.library._get_snapmirror_svm.assert_called_once_with( 

3517 self.fake_src_share_server, self.fake_dest_share_server 

3518 ) 

3519 dm_session_mock.cancel_snapmirror_svm.assert_called_once_with( 

3520 self.fake_src_share_server, self.fake_dest_share_server 

3521 ) 

3522 

3523 @ddt.data(None, 'fake_migration_id') 

3524 def test_share_server_migration_cancel(self, migration_id): 

3525 self.mock_object(self.library, '_get_share_server_migration_id', 

3526 mock.Mock(return_value=migration_id)) 

3527 self.mock_object(self.library, '_migration_cancel_using_svm_migrate') 

3528 self.mock_object(self.library, '_migration_cancel_using_svm_dr') 

3529 

3530 self.library.share_server_migration_cancel( 

3531 None, self.fake_src_share_server, self.fake_dest_share_server, 

3532 [], []) 

3533 

3534 if migration_id: 

3535 (self.library._migration_cancel_using_svm_migrate 

3536 .assert_called_once_with( 

3537 migration_id, self.fake_dest_share_server)) 

3538 else: 

3539 (self.library._migration_cancel_using_svm_dr 

3540 .assert_called_once_with( 

3541 self.fake_src_share_server, self.fake_dest_share_server, 

3542 [])) 

3543 

3544 def test_share_server_migration_get_progress(self): 

3545 fake_vserver_name = fake.VSERVER1 

3546 expected_result = {'total_progress': 50} 

3547 

3548 self.mock_object(self.library._client, 'get_svm_volumes_total_size', 

3549 mock.Mock(return_value=5)) 

3550 

3551 self.mock_object(self.library, '_get_vserver_name', 

3552 mock.Mock(return_value=fake_vserver_name)) 

3553 

3554 result = self.library.share_server_migration_get_progress( 

3555 None, self.fake_src_share_server, self.fake_dest_share_server, 

3556 [self.fake_src_share], None 

3557 ) 

3558 

3559 self.library._client.get_svm_volumes_total_size.assert_called_once_with 

3560 (fake_vserver_name) 

3561 self.library._get_vserver_name.assert_called_once_with 

3562 (self.fake_dest_share_server['source_share_server_id']) 

3563 self.assertEqual(expected_result, result) 

3564 

3565 @ddt.data({'subtype': 'default', 

3566 'share_group': None, 

3567 'compatible': True}, 

3568 {'subtype': 'default', 

3569 'share_group': {'share_server_id': fake.SHARE_SERVER['id']}, 

3570 'compatible': True}, 

3571 {'subtype': 'dp_destination', 

3572 'share_group': None, 

3573 'compatible': False}, 

3574 {'subtype': 'default', 

3575 'share_group': {'share_server_id': 'another_fake_id'}, 

3576 'compatible': False}) 

3577 @ddt.unpack 

3578 def test_choose_share_server_compatible_with_share_vserver_info( 

3579 self, subtype, share_group, compatible): 

3580 self.library.is_nfs_config_supported = False 

3581 mock_client = mock.Mock() 

3582 self.mock_object(self.library, '_get_vserver', 

3583 mock.Mock(return_value=(fake.VSERVER1, 

3584 mock_client))) 

3585 fake_vserver_info = { 

3586 'operational_state': 'running', 

3587 'state': 'running', 

3588 'subtype': subtype 

3589 } 

3590 self.mock_object(mock_client, 'get_vserver_info', 

3591 mock.Mock(return_value=fake_vserver_info)) 

3592 mock_get_extra_spec = self.mock_object( 

3593 share_types, 'get_extra_specs_from_share', 

3594 mock.Mock(return_value='fake_extra_specs')) 

3595 mock_get_provisioning_opts = self.mock_object( 

3596 self.library, '_get_provisioning_options', 

3597 mock.Mock(return_value={})) 

3598 self.mock_object(mock_client, 'list_vserver_aggregates', 

3599 mock.Mock(return_value=fake.AGGREGATES)) 

3600 

3601 result = self.library.choose_share_server_compatible_with_share( 

3602 None, [fake.SHARE_SERVER], fake.SHARE_2, 

3603 None, share_group 

3604 ) 

3605 expected_result = fake.SHARE_SERVER if compatible else None 

3606 self.assertEqual(expected_result, result) 

3607 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

3608 mock_get_provisioning_opts.assert_called_once_with('fake_extra_specs') 

3609 if (share_group and 

3610 share_group['share_server_id'] != fake.SHARE_SERVER['id']): 

3611 mock_client.get_vserver_info.assert_not_called() 

3612 self.library._get_vserver.assert_not_called() 

3613 else: 

3614 mock_client.get_vserver_info.assert_called_once_with( 

3615 fake.VSERVER1, 

3616 ) 

3617 self.library._get_vserver.assert_called_once_with( 

3618 fake.SHARE_SERVER, backend_name=fake.BACKEND_NAME 

3619 ) 

3620 

3621 @ddt.data( 

3622 {'policies': [], 'reusable_scope': None, 'compatible': True}, 

3623 {'policies': "0123456789", 'reusable_scope': {'scope'}, 

3624 'compatible': True}, 

3625 {'policies': "0123456789", 'reusable_scope': None, 

3626 'compatible': False}) 

3627 @ddt.unpack 

3628 def test_choose_share_server_compatible_with_share_fpolicy( 

3629 self, policies, reusable_scope, compatible): 

3630 self.library.is_nfs_config_supported = False 

3631 mock_client = mock.Mock() 

3632 fake_extra_spec = copy.deepcopy(fake.EXTRA_SPEC_WITH_FPOLICY) 

3633 mock_get_extra_spec = self.mock_object( 

3634 share_types, 'get_extra_specs_from_share', 

3635 mock.Mock(return_value=fake_extra_spec)) 

3636 self.mock_object(self.library, '_get_vserver', 

3637 mock.Mock(return_value=(fake.VSERVER1, 

3638 mock_client))) 

3639 self.mock_object(mock_client, 'get_vserver_info', 

3640 mock.Mock(return_value=fake.VSERVER_INFO)) 

3641 self.mock_object(mock_client, 'list_vserver_aggregates', 

3642 mock.Mock(return_value=fake.AGGREGATES)) 

3643 mock_get_policies = self.mock_object( 

3644 mock_client, 'get_fpolicy_policies_status', 

3645 mock.Mock(return_value=policies)) 

3646 mock_reusable_scope = self.mock_object( 

3647 self.library, '_find_reusable_fpolicy_scope', 

3648 mock.Mock(return_value=reusable_scope)) 

3649 

3650 result = self.library.choose_share_server_compatible_with_share( 

3651 None, [fake.SHARE_SERVER], fake.SHARE_2, 

3652 None, None 

3653 ) 

3654 

3655 expected_result = fake.SHARE_SERVER if compatible else None 

3656 self.assertEqual(expected_result, result) 

3657 mock_get_extra_spec.assert_called_once_with(fake.SHARE_2) 

3658 mock_client.get_vserver_info.assert_called_once_with( 

3659 fake.VSERVER1, 

3660 ) 

3661 self.library._get_vserver.assert_called_once_with( 

3662 fake.SHARE_SERVER, backend_name=fake.BACKEND_NAME 

3663 ) 

3664 mock_get_policies.assert_called_once() 

3665 if len(policies) >= self.library.FPOLICY_MAX_VSERVER_POLICIES: 

3666 mock_reusable_scope.assert_called_once_with( 

3667 fake.SHARE_2, mock_client, 

3668 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

3669 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

3670 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

3671 

3672 @ddt.data({'subtype': 'default', 'compatible': True}, 

3673 {'subtype': 'dp_destination', 'compatible': False}) 

3674 @ddt.unpack 

3675 def test_choose_share_server_compatible_with_share_group_vserver_info( 

3676 self, subtype, compatible): 

3677 self.library.is_nfs_config_supported = False 

3678 mock_client = mock.Mock() 

3679 self.mock_object(self.library, '_get_vserver', 

3680 mock.Mock(return_value=(fake.VSERVER1, 

3681 mock_client))) 

3682 fake_vserver_info = { 

3683 'operational_state': 'running', 

3684 'state': 'running', 

3685 'subtype': subtype 

3686 } 

3687 self.mock_object(mock_client, 'get_vserver_info', 

3688 mock.Mock(return_value=fake_vserver_info)) 

3689 

3690 result = self.library.choose_share_server_compatible_with_share_group( 

3691 None, [fake.SHARE_SERVER], None 

3692 ) 

3693 expected_result = fake.SHARE_SERVER if compatible else None 

3694 self.assertEqual(expected_result, result) 

3695 self.library._get_vserver.assert_called_once_with( 

3696 fake.SHARE_SERVER, backend_name=fake.BACKEND_NAME 

3697 ) 

3698 mock_client.get_vserver_info.assert_called_once_with( 

3699 fake.VSERVER1, 

3700 ) 

3701 

3702 def test_choose_share_server_compatible_with_different_aggrs(self): 

3703 self.library.is_nfs_config_supported = False 

3704 mock_client = mock.Mock() 

3705 self.mock_object(self.library, '_get_vserver', 

3706 mock.Mock(return_value=(fake.VSERVER1, 

3707 mock_client))) 

3708 fake_vserver_info = { 

3709 'operational_state': 'running', 

3710 'state': 'running', 

3711 'subtype': 'default' 

3712 } 

3713 self.mock_object(mock_client, 'get_vserver_info', 

3714 mock.Mock(return_value=fake_vserver_info)) 

3715 mock_get_extra_spec = self.mock_object( 

3716 share_types, 'get_extra_specs_from_share', 

3717 mock.Mock(return_value='fake_extra_specs')) 

3718 mock_get_provisioning_opts = self.mock_object( 

3719 self.library, '_get_provisioning_options', 

3720 mock.Mock(return_value={})) 

3721 self.mock_object(mock_client, 'list_vserver_aggregates', 

3722 mock.Mock(return_value=fake.AGGREGATES)) 

3723 result = self.library.choose_share_server_compatible_with_share( 

3724 None, [fake.SHARE_SERVER], fake.SHARE_INSTANCE, None) 

3725 self.assertIsNone(result) 

3726 mock_get_extra_spec.assert_called_once_with(fake.SHARE_INSTANCE) 

3727 mock_get_provisioning_opts.assert_called_once_with('fake_extra_specs') 

3728 

3729 def test_choose_share_server_compatible_with_flexgroups(self): 

3730 self.library.is_nfs_config_supported = False 

3731 mock_client = mock.Mock() 

3732 self.mock_object(self.library, '_get_vserver', 

3733 mock.Mock(return_value=(fake.VSERVER1, 

3734 mock_client))) 

3735 fake_vserver_info = { 

3736 'operational_state': 'running', 

3737 'state': 'running', 

3738 'subtype': 'default' 

3739 } 

3740 self.mock_object(mock_client, 'get_vserver_info', 

3741 mock.Mock(return_value=fake_vserver_info)) 

3742 mock_get_extra_spec = self.mock_object( 

3743 share_types, 'get_extra_specs_from_share', 

3744 mock.Mock(return_value='fake_extra_specs')) 

3745 mock_get_provisioning_opts = self.mock_object( 

3746 self.library, '_get_provisioning_options', 

3747 mock.Mock(return_value={})) 

3748 self.mock_object(mock_client, 'list_vserver_aggregates', 

3749 mock.Mock(return_value=fake.FLEXGROUP_POOL_AGGR)) 

3750 self.mock_object(self.library, '_is_flexgroup_pool', 

3751 mock.Mock(return_value=True)) 

3752 self.mock_object(self.library, '_get_flexgroup_aggregate_list', 

3753 mock.Mock(return_value=fake.FLEXGROUP_POOL_AGGR)) 

3754 result = self.library.choose_share_server_compatible_with_share( 

3755 None, [fake.SHARE_SERVER], fake.SHARE_FLEXGROUP, None) 

3756 expected_result = fake.SHARE_SERVER 

3757 self.assertEqual(expected_result, result) 

3758 self.library._get_vserver.assert_called_once_with( 

3759 fake.SHARE_SERVER, backend_name=fake.BACKEND_NAME 

3760 ) 

3761 mock_client.get_vserver_info.assert_called_once_with( 

3762 fake.VSERVER1, 

3763 ) 

3764 mock_get_extra_spec.assert_called_once_with(fake.SHARE_FLEXGROUP) 

3765 mock_get_provisioning_opts.assert_called_once_with('fake_extra_specs') 

3766 

3767 def test__create_port_and_broadcast_domain(self): 

3768 self.mock_object(self.library._client, 

3769 'list_cluster_nodes', 

3770 mock.Mock(return_value=fake.CLUSTER_NODES)) 

3771 self.mock_object(self.library, 

3772 '_get_node_data_port', 

3773 mock.Mock(return_value='fake_port')) 

3774 

3775 self.library._create_port_and_broadcast_domain(fake.IPSPACE, 

3776 fake.NETWORK_INFO) 

3777 node_network_info = zip(fake.CLUSTER_NODES, 

3778 fake.NETWORK_INFO['network_allocations']) 

3779 get_node_port_calls = [] 

3780 create_port_calls = [] 

3781 for node, alloc in node_network_info: 

3782 get_node_port_calls.append(mock.call(node)) 

3783 create_port_calls.append(mock.call( 

3784 node, 'fake_port', alloc['segmentation_id'], alloc['mtu'], 

3785 fake.IPSPACE 

3786 )) 

3787 

3788 self.library._get_node_data_port.assert_has_calls(get_node_port_calls) 

3789 self.library._client.create_port_and_broadcast_domain.assert_has_calls( 

3790 create_port_calls) 

3791 

3792 def test___update_share_attributes_after_server_migration(self): 

3793 fake_aggregate = 'fake_aggr_0' 

3794 mock_get_extra_spec = self.mock_object( 

3795 share_types, "get_extra_specs_from_share", 

3796 mock.Mock(return_value=fake.EXTRA_SPEC)) 

3797 mock__get_provisioning_opts = self.mock_object( 

3798 self.library, '_get_provisioning_options', 

3799 mock.Mock(return_value=copy.deepcopy(fake.PROVISIONING_OPTIONS))) 

3800 fake_share_name = self.library._get_backend_share_name( 

3801 fake.SHARE_INSTANCE['id']) 

3802 mock_get_vol_autosize_attrs = self.mock_object( 

3803 self.mock_src_client, 'get_volume_autosize_attributes', 

3804 mock.Mock(return_value=fake.VOLUME_AUTOSIZE_ATTRS) 

3805 ) 

3806 fake_provisioning_opts = copy.copy(fake.PROVISIONING_OPTIONS) 

3807 fake_autosize_attrs = copy.copy(fake.VOLUME_AUTOSIZE_ATTRS) 

3808 for key in ('minimum-size', 'maximum-size'): 

3809 fake_autosize_attrs[key] = int(fake_autosize_attrs[key]) * units.Ki 

3810 fake_provisioning_opts['autosize_attributes'] = fake_autosize_attrs 

3811 mock_modify_volume = self.mock_object(self.mock_dest_client, 

3812 'modify_volume') 

3813 fake_provisioning_opts.pop('snapshot_policy', None) 

3814 

3815 self.library._update_share_attributes_after_server_migration( 

3816 fake.SHARE_INSTANCE, self.mock_src_client, fake_aggregate, 

3817 self.mock_dest_client) 

3818 

3819 mock_get_extra_spec.assert_called_once_with(fake.SHARE_INSTANCE) 

3820 mock__get_provisioning_opts.assert_called_once_with(fake.EXTRA_SPEC) 

3821 mock_get_vol_autosize_attrs.assert_called_once_with(fake_share_name) 

3822 mock_modify_volume.assert_called_once_with( 

3823 fake_aggregate, fake_share_name, **fake_provisioning_opts) 

3824 

3825 def test_validate_provisioning_options_for_share(self): 

3826 mock_create_from_snap = self.mock_object( 

3827 lib_base.NetAppCmodeFileStorageLibrary, 

3828 'validate_provisioning_options_for_share') 

3829 

3830 self.library.validate_provisioning_options_for_share( 

3831 fake.PROVISIONING_OPTIONS, extra_specs=fake.EXTRA_SPEC, 

3832 qos_specs=fake.QOS_NORMALIZED_SPEC) 

3833 

3834 mock_create_from_snap.assert_called_once_with( 

3835 fake.PROVISIONING_OPTIONS, extra_specs=fake.EXTRA_SPEC, 

3836 qos_specs=fake.QOS_NORMALIZED_SPEC) 

3837 

3838 def test_validate_provisioning_options_for_share_aqos_not_supported(self): 

3839 self.assertRaises( 

3840 exception.NetAppException, 

3841 self.library.validate_provisioning_options_for_share, 

3842 fake.PROVISIONING_OPTS_WITH_ADAPT_QOS, qos_specs=None) 

3843 

3844 def test__get_different_keys_for_equal_ss_type(self): 

3845 curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) 

3846 new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) 

3847 new_sec_service2 = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_3) 

3848 

3849 expected_keys = ['password', 'user', 'ou', 

3850 'domain', 'dns_ip', 'server'] 

3851 

3852 result = self.library._get_different_keys_for_equal_ss_type( 

3853 curr_sec_service, new_sec_service) 

3854 

3855 self.assertEqual(expected_keys, result) 

3856 

3857 expected_keys = ['password', 'user', 'ou', 

3858 'domain', 'dns_ip', 'server', 'default_ad_site'] 

3859 result = self.library._get_different_keys_for_equal_ss_type( 

3860 curr_sec_service, new_sec_service2) 

3861 

3862 self.assertEqual(expected_keys, result) 

3863 

3864 @ddt.data( 

3865 {'current': None, 

3866 'new': fake.CIFS_SECURITY_SERVICE, 

3867 'existing': []}, 

3868 

3869 {'current': fake.CIFS_SECURITY_SERVICE, 

3870 'new': fake.CIFS_SECURITY_SERVICE_2, 

3871 'existing': [fake.CIFS_SECURITY_SERVICE, 

3872 fake.KERBEROS_SECURITY_SERVICE]}, 

3873 

3874 {'current': fake.KERBEROS_SECURITY_SERVICE, 

3875 'new': fake.KERBEROS_SECURITY_SERVICE_2, 

3876 'existing': [fake.CIFS_SECURITY_SERVICE, 

3877 fake.KERBEROS_SECURITY_SERVICE]}, 

3878 

3879 {'current': fake.CIFS_SECURITY_SERVICE, 

3880 'new': fake.CIFS_SECURITY_SERVICE, 

3881 'existing': [fake.CIFS_SECURITY_SERVICE]}, 

3882 ) 

3883 @ddt.unpack 

3884 def test_update_share_server_security_service(self, current, new, 

3885 existing): 

3886 fake_context = mock.Mock() 

3887 fake_net_info = copy.deepcopy(fake.NETWORK_INFO_LIST) 

3888 new_sec_service = copy.deepcopy(new) 

3889 curr_sec_service = copy.deepcopy(current) if current else None 

3890 new_type = new_sec_service['type'].lower() 

3891 fake_net_info[0]['security_services'] = existing 

3892 

3893 if curr_sec_service: 

3894 # domain modification aren't support 

3895 new_sec_service['domain'] = curr_sec_service['domain'] 

3896 

3897 different_keys = [] 

3898 if curr_sec_service != new_sec_service: 

3899 different_keys = ['dns_ip', 'server', 'domain', 'user', 'password'] 

3900 if new_sec_service.get('ou') is not None: 

3901 different_keys.append('ou') 

3902 

3903 fake_vserver_client = mock.Mock() 

3904 mock_get_vserver = self.mock_object( 

3905 self.library, '_get_vserver', 

3906 mock.Mock(return_value=[fake.VSERVER1, fake_vserver_client])) 

3907 mock_check_update = self.mock_object( 

3908 self.library, 'check_update_share_server_security_service', 

3909 mock.Mock(return_value=True)) 

3910 mock_setup_sec_serv = self.mock_object( 

3911 self.library._client, 'setup_security_services') 

3912 mock_diff_keys = self.mock_object( 

3913 self.library, '_get_different_keys_for_equal_ss_type', 

3914 mock.Mock(return_value=different_keys)) 

3915 mock_dns_update = self.mock_object( 

3916 fake_vserver_client, 'update_dns_configuration') 

3917 mock_update_krealm = self.mock_object( 

3918 fake_vserver_client, 'update_kerberos_realm') 

3919 mock_modify_ad = self.mock_object( 

3920 fake_vserver_client, 'modify_active_directory_security_service') 

3921 

3922 self.library.update_share_server_security_service( 

3923 fake_context, fake.SHARE_SERVER, fake_net_info, 

3924 new_sec_service, current_security_service=curr_sec_service) 

3925 

3926 dns_ips = set() 

3927 domains = set() 

3928 # we don't need to split and strip since we know that fake have only 

3929 # on dns-ip and domain configured 

3930 for ss in existing: 

3931 if ss['type'] != new_sec_service['type']: 

3932 dns_ips.add(ss['dns_ip']) 

3933 domains.add(ss['domain']) 

3934 dns_ips.add(new_sec_service['dns_ip']) 

3935 domains.add(new_sec_service['domain']) 

3936 

3937 mock_get_vserver.assert_called_once_with( 

3938 share_server=fake.SHARE_SERVER) 

3939 mock_check_update.assert_called_once_with( 

3940 fake_context, fake.SHARE_SERVER, fake_net_info, new_sec_service, 

3941 current_security_service=curr_sec_service) 

3942 

3943 if curr_sec_service is None: 

3944 mock_setup_sec_serv.assert_called_once_with( 

3945 [new_sec_service], fake_vserver_client, fake.VSERVER1, False) 

3946 else: 

3947 mock_diff_keys.assert_called_once_with(curr_sec_service, 

3948 new_sec_service) 

3949 if different_keys: 

3950 mock_dns_update.assert_called_once_with(dns_ips, domains) 

3951 if new_type == 'kerberos': 

3952 mock_update_krealm.assert_called_once_with(new_sec_service) 

3953 elif new_type == 'active_directory': 3953 ↛ exitline 3953 didn't return from function 'test_update_share_server_security_service' because the condition on line 3953 was always true

3954 mock_modify_ad.assert_called_once_with( 

3955 fake.VSERVER1, different_keys, new_sec_service, 

3956 curr_sec_service) 

3957 

3958 def test_update_share_server_security_service_check_error(self): 

3959 curr_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE) 

3960 new_sec_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE_2) 

3961 fake_vserver_client = mock.Mock() 

3962 fake_context = mock.Mock() 

3963 fake_net_info = mock.Mock() 

3964 

3965 mock_get_vserver = self.mock_object( 

3966 self.library, '_get_vserver', 

3967 mock.Mock(return_value=[fake.VSERVER1, fake_vserver_client])) 

3968 mock_check_update = self.mock_object( 

3969 self.library, 'check_update_share_server_security_service', 

3970 mock.Mock(return_value=False)) 

3971 

3972 self.assertRaises( 

3973 exception.NetAppException, 

3974 self.library.update_share_server_security_service, 

3975 fake_context, fake.SHARE_SERVER, fake_net_info, 

3976 new_sec_service, current_security_service=curr_sec_service) 

3977 

3978 mock_get_vserver.assert_called_once_with( 

3979 share_server=fake.SHARE_SERVER) 

3980 mock_check_update.assert_called_once_with( 

3981 fake_context, fake.SHARE_SERVER, fake_net_info, 

3982 new_sec_service, current_security_service=curr_sec_service) 

3983 

3984 @ddt.data( 

3985 {'new': fake.LDAP_AD_SECURITY_SERVICE, 

3986 'current': fake.LDAP_LINUX_SECURITY_SERVICE, 

3987 'expected': True}, 

3988 

3989 {'new': fake.CIFS_SECURITY_SERVICE, 

3990 'current': fake.KERBEROS_SECURITY_SERVICE, 

3991 'expected': False}, 

3992 

3993 {'new': fake.CIFS_SECURITY_SERVICE, 

3994 'current': fake.CIFS_SECURITY_SERVICE, 

3995 'expected': True}, 

3996 

3997 {'new': fake.KERBEROS_SECURITY_SERVICE, 

3998 'current': fake.KERBEROS_SECURITY_SERVICE, 

3999 'expected': True}, 

4000 

4001 {'new': fake.CIFS_SECURITY_SERVICE, 

4002 'current': None, 

4003 'expected': True}, 

4004 ) 

4005 @ddt.unpack 

4006 def test_check_update_share_server_security_service(self, new, current, 

4007 expected): 

4008 result = self.library.check_update_share_server_security_service( 

4009 None, None, None, new, current_security_service=current) 

4010 

4011 self.assertEqual(expected, result) 

4012 

4013 def test_check_update_share_server_network_allocations(self): 

4014 net_alloc_seg_id = fake.USER_NETWORK_ALLOCATIONS[0]['segmentation_id'] 

4015 network_segments = [ 

4016 {'segmentation_id': net_alloc_seg_id}, 

4017 {'segmentation_id': fake.SHARE_NETWORK_SUBNET['segmentation_id']} 

4018 ] 

4019 

4020 mock__validate_network_type = self.mock_object( 

4021 self.library, '_validate_network_type') 

4022 mock__validate_share_network_subnets = self.mock_object( 

4023 self.library, '_validate_share_network_subnets') 

4024 

4025 result = self.library.check_update_share_server_network_allocations( 

4026 None, fake.SHARE_SERVER, fake.CURRENT_NETWORK_ALLOCATIONS, 

4027 fake.SHARE_NETWORK_SUBNET, None, None, 

4028 None) 

4029 

4030 self.assertTrue(result) 

4031 mock__validate_network_type.assert_called_once_with( 

4032 [fake.SHARE_NETWORK_SUBNET]) 

4033 mock__validate_share_network_subnets.assert_called_once_with( 

4034 network_segments) 

4035 

4036 def test_check_update_share_server_network_allocations_fail_on_type(self): 

4037 network_exception = exception.NetworkBadConfigurationException( 

4038 reason='fake exception message') 

4039 

4040 mock_validate_network_type = self.mock_object( 

4041 self.library, '_validate_network_type', 

4042 mock.Mock(side_effect=network_exception)) 

4043 

4044 mock_validate_share_network_subnets = self.mock_object( 

4045 self.library, '_validate_share_network_subnets') 

4046 

4047 result = self.library.check_update_share_server_network_allocations( 

4048 None, fake.SHARE_SERVER, fake.CURRENT_NETWORK_ALLOCATIONS, 

4049 fake.SHARE_NETWORK_SUBNET, None, None, None) 

4050 

4051 self.assertFalse(result) 

4052 mock_validate_network_type.assert_called_once_with( 

4053 [fake.SHARE_NETWORK_SUBNET]) 

4054 mock_validate_share_network_subnets.assert_not_called() 

4055 

4056 def test_check_update_share_server_network_allocations_subnets_error(self): 

4057 net_alloc_seg_id = fake.USER_NETWORK_ALLOCATIONS[0]['segmentation_id'] 

4058 network_segments = [ 

4059 {'segmentation_id': net_alloc_seg_id}, 

4060 {'segmentation_id': fake.SHARE_NETWORK_SUBNET['segmentation_id']} 

4061 ] 

4062 network_exception = exception.NetworkBadConfigurationException( 

4063 reason='fake exception message') 

4064 

4065 mock__validate_network_type = self.mock_object( 

4066 self.library, '_validate_network_type') 

4067 mock__validate_share_network_subnets = self.mock_object( 

4068 self.library, '_validate_share_network_subnets', 

4069 mock.Mock(side_effect=network_exception)) 

4070 

4071 result = self.library.check_update_share_server_network_allocations( 

4072 None, fake.SHARE_SERVER, fake.CURRENT_NETWORK_ALLOCATIONS, 

4073 fake.SHARE_NETWORK_SUBNET, None, None, 

4074 None) 

4075 

4076 self.assertFalse(result) 

4077 mock__validate_network_type.assert_called_once_with( 

4078 [fake.SHARE_NETWORK_SUBNET]) 

4079 mock__validate_share_network_subnets.assert_called_once_with( 

4080 network_segments) 

4081 

4082 @ddt.data(True, False) 

4083 def test_build_model_update(self, has_export_locations): 

4084 server_model_update = copy.deepcopy(fake.SERVER_MODEL_UPDATE) 

4085 

4086 export_locations = server_model_update['share_updates'] 

4087 if not has_export_locations: 

4088 export_locations = None 

4089 del server_model_update['share_updates'] 

4090 

4091 result = self.library._build_model_update( 

4092 fake.CURRENT_NETWORK_ALLOCATIONS, fake.NEW_NETWORK_ALLOCATIONS, 

4093 export_locations=export_locations) 

4094 

4095 self.assertEqual(server_model_update, result) 

4096 

4097 @ddt.data('active', 'dr') 

4098 def test_update_share_server_network_allocations(self, replica_state): 

4099 fake_context = mock.Mock() 

4100 fake_share_server = fake.SHARE_SERVER 

4101 fake_current_network_allocations = fake.USER_NETWORK_ALLOCATIONS 

4102 fake_new_network_allocations = fake.USER_NETWORK_ALLOCATIONS 

4103 fake_share_instances = [copy.deepcopy(fake.SHARE_INSTANCE)] 

4104 fake_share_instances[0]['replica_state'] = replica_state 

4105 fake_vserver_name = fake.VSERVER1 

4106 fake_vserver_client = mock.Mock() 

4107 fake_ipspace_name = fake.IPSPACE 

4108 fake_export_locations = fake.NFS_EXPORTS[0] 

4109 fake_updates = fake.SERVER_MODEL_UPDATE 

4110 fake_updated_export_locations = { 

4111 fake_share_instances[0]['id']: fake_export_locations, 

4112 } 

4113 

4114 self.mock_object(self.library, '_get_vserver_name', 

4115 mock.Mock(return_value=fake_vserver_name)) 

4116 self.mock_object(self.library, '_get_api_client', 

4117 mock.Mock(return_value=fake_vserver_client)) 

4118 self.mock_object(self.library._client, 'get_vserver_ipspace', 

4119 mock.Mock(return_value=fake_ipspace_name)) 

4120 self.mock_object(self.library, '_setup_network_for_vserver') 

4121 self.mock_object(self.library, '_create_export', 

4122 mock.Mock(return_value=fake_export_locations)) 

4123 self.mock_object(self.library, '_build_model_update', 

4124 mock.Mock(return_value=fake_updates)) 

4125 

4126 self.assertEqual( 

4127 fake_updates, 

4128 self.library.update_share_server_network_allocations( 

4129 fake_context, fake_share_server, 

4130 fake_current_network_allocations, fake_new_network_allocations, 

4131 None, fake_share_instances, None)) 

4132 self.library._get_vserver_name.assert_called_once_with( 

4133 fake_share_server['id']) 

4134 self.library._get_api_client.assert_called_once_with( 

4135 vserver=fake_vserver_name) 

4136 self.library._client.get_vserver_ipspace.assert_called_once_with( 

4137 fake_vserver_name) 

4138 self.library._setup_network_for_vserver.assert_called_once_with( 

4139 fake_vserver_name, fake_vserver_client, 

4140 [fake_new_network_allocations], fake_ipspace_name, 

4141 enable_nfs=False, security_services=None, nfs_config=None) 

4142 if replica_state == 'active': 

4143 self.library._create_export.assert_called_once_with( 

4144 fake_share_instances[0], fake_share_server, 

4145 fake_vserver_name, fake_vserver_client, 

4146 clear_current_export_policy=False, 

4147 ensure_share_already_exists=True, 

4148 share_host=fake_share_instances[0]['host']) 

4149 else: 

4150 self.library._create_export.assert_not_called() 

4151 fake_updated_export_locations = {} 

4152 

4153 self.library._build_model_update.assert_called_once_with( 

4154 fake_current_network_allocations, fake_new_network_allocations, 

4155 fake_updated_export_locations) 

4156 

4157 def test_update_share_server_network_allocations_setup_network_fail(self): 

4158 fake_context = mock.Mock() 

4159 fake_share_server = fake.SHARE_SERVER 

4160 fake_current_network_allocations = fake.USER_NETWORK_ALLOCATIONS 

4161 fake_new_network_allocations = fake.USER_NETWORK_ALLOCATIONS 

4162 fake_share_instances = [fake.SHARE_INSTANCE] 

4163 fake_updates = fake.SERVER_MODEL_UPDATE 

4164 

4165 self.mock_object(self.library, '_get_vserver_name') 

4166 self.mock_object(self.library, '_get_api_client') 

4167 self.mock_object(self.library._client, 'get_vserver_ipspace') 

4168 self.mock_object(self.library, '_setup_network_for_vserver', 

4169 mock.Mock(side_effect=netapp_api.NaApiError)) 

4170 self.mock_object(self.library, '_build_model_update', 

4171 mock.Mock(return_value=fake_updates)) 

4172 

4173 self.assertRaises(netapp_api.NaApiError, 

4174 self.library.update_share_server_network_allocations, 

4175 fake_context, fake_share_server, 

4176 fake_current_network_allocations, 

4177 fake_new_network_allocations, None, 

4178 fake_share_instances, None) 

4179 self.library._build_model_update.assert_called_once_with( 

4180 fake_current_network_allocations, fake_new_network_allocations, 

4181 export_locations=None) 

4182 

4183 def test__get_backup_vserver(self): 

4184 mock_dest_client = mock.Mock() 

4185 self.mock_object(self.library, 

4186 '_get_backend', 

4187 mock.Mock(return_value=fake.BACKEND_NAME)) 

4188 self.mock_object(data_motion, 

4189 'get_backend_configuration', 

4190 mock.Mock(return_value=_get_config())) 

4191 self.mock_object(self.library, 

4192 '_get_api_client_for_backend', 

4193 mock.Mock(return_value=mock_dest_client)) 

4194 self.mock_object(mock_dest_client, 

4195 'list_non_root_aggregates', 

4196 mock.Mock(return_value=['aggr1', 'aggr2'])) 

4197 self.mock_object(mock_dest_client, 

4198 'create_vserver', 

4199 mock.Mock(side_effect=netapp_api.NaApiError( 

4200 message='Vserver name is already used by another' 

4201 ' Vserver'))) 

4202 self.library._get_backup_vserver(fake.SHARE_BACKUP, fake.SHARE_SERVER) 

4203 

4204 def test__delete_backup_vserver(self): 

4205 mock_api_client = mock.Mock() 

4206 self.mock_object(self.library, 

4207 '_get_backend', 

4208 mock.Mock(return_value=fake.BACKEND_NAME)) 

4209 self.mock_object(self.library, 

4210 '_get_api_client_for_backend', 

4211 mock.Mock(return_value=mock_api_client)) 

4212 des_vserver = fake.VSERVER2 

4213 msg = (f"Cannot delete Vserver. Vserver {des_vserver} " 

4214 f"has shares.") 

4215 self.mock_object(mock_api_client, 

4216 'delete_vserver', 

4217 mock.Mock( 

4218 side_effect=exception.NetAppException( 

4219 message=msg))) 

4220 self.library._delete_backup_vserver(fake.SHARE_BACKUP, des_vserver) 

4221 

4222 def test__check_data_lif_count_limit_reached_for_ha_pair_false(self): 

4223 nodes = ["node1", "node2"] 

4224 lif_detail = [{'node': "node1", 

4225 'count-for-node': '44', 

4226 'limit-for-node': '512'}, 

4227 {'node': "node2", 

4228 'count-for-node': '50', 

4229 'limit-for-node': '512'}] 

4230 

4231 self.mock_object(self.client, 

4232 'get_storage_failover_partner', 

4233 mock.Mock(return_value="node2")) 

4234 self.mock_object(self.client, 

4235 'list_cluster_nodes', 

4236 mock.Mock(return_value=nodes)) 

4237 

4238 self.mock_object(self.client, 

4239 'get_data_lif_details_for_nodes', 

4240 mock.Mock(return_value=lif_detail)) 

4241 self.mock_object(self.client, 

4242 'get_migratable_data_lif_for_node', 

4243 mock.Mock(return_value=["data_lif_1", "data_lif_2"])) 

4244 self.library._check_data_lif_count_limit_reached_for_ha_pair( 

4245 self.client) 

4246 

4247 def test__check_data_lif_count_limit_reached_for_ha_pair_true(self): 

4248 nodes = ["node1", "node2"] 

4249 lif_detail = [{'node': "node1", 

4250 'count-for-node': '511', 

4251 'limit-for-node': '512'}, 

4252 {'node': "node2", 

4253 'count-for-node': '250', 

4254 'limit-for-node': '512'}] 

4255 self.mock_object(self.client, 

4256 'get_storage_failover_partner', 

4257 mock.Mock(return_value="node2")) 

4258 self.mock_object(self.client, 

4259 'list_cluster_nodes', 

4260 mock.Mock(return_value=nodes)) 

4261 

4262 self.mock_object(self.client, 

4263 'get_data_lif_details_for_nodes', 

4264 mock.Mock(return_value=lif_detail)) 

4265 self.mock_object(self.client, 

4266 'get_migratable_data_lif_for_node', 

4267 mock.Mock(return_value=["data_lif_1", "data_lif_2"])) 

4268 

4269 self.assertRaises( 

4270 exception.NetAppException, 

4271 self.library._check_data_lif_count_limit_reached_for_ha_pair, 

4272 self.client, 

4273 )