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

4271 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# Copyright (c) 2015 Tom Barron. All rights reserved. 

3# 

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

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

6# a copy of the License at 

7# 

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

9# 

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

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

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

13# License for the specific language governing permissions and limitations 

14# under the License. 

15""" 

16Unit tests for the NetApp Data ONTAP cDOT base storage driver library. 

17""" 

18 

19import copy 

20import json 

21import math 

22import socket 

23import time 

24from unittest import mock 

25 

26import ddt 

27from oslo_config import cfg 

28from oslo_log import log 

29from oslo_service import loopingcall 

30from oslo_utils import timeutils 

31from oslo_utils import units 

32from oslo_utils import uuidutils 

33 

34from manila.common import constants 

35from manila import exception 

36from manila.share import configuration 

37from manila.share import driver 

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

39from manila.share.drivers.netapp.dataontap.client import client_cmode 

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

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

42from manila.share.drivers.netapp.dataontap.cluster_mode import performance 

43from manila.share.drivers.netapp.dataontap.protocols import cifs_cmode 

44from manila.share.drivers.netapp.dataontap.protocols import nfs_cmode 

45from manila.share.drivers.netapp import options as na_opts 

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

47from manila.share import share_types 

48from manila.share import utils as share_utils 

49from manila import test 

50from manila.tests import fake_share 

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

52from manila.tests.share.drivers.netapp import fakes as na_fakes 

53from manila.tests import utils 

54 

55CONF = cfg.CONF 

56 

57 

58def fake_replica(**kwargs): 

59 return fake_share.fake_replica(for_manager=True, **kwargs) 

60 

61 

62def _get_config(): 

63 backup_config = 'backup_config' 

64 config = configuration.Configuration(driver.share_opts, 

65 config_group=backup_config) 

66 config.append_config_values(na_opts.netapp_backup_opts) 

67 config.append_config_values(na_opts.netapp_proxy_opts) 

68 config.append_config_values(na_opts.netapp_connection_opts) 

69 config.append_config_values(na_opts.netapp_basicauth_opts) 

70 config.append_config_values(na_opts.netapp_certificateauth_opts) 

71 config.append_config_values(na_opts.netapp_provisioning_opts) 

72 config.append_config_values(na_opts.netapp_support_opts) 

73 config.append_config_values(na_opts.netapp_data_motion_opts) 

74 config.append_config_values(na_opts.netapp_cluster_opts) 

75 

76 CONF.set_override("netapp_enabled_backup_types", 

77 [fake.BACKUP_TYPE, "backup2"], 

78 group=backup_config) 

79 CONF.set_override("netapp_backup_backend_section_name", 

80 fake.BACKEND_NAME, 

81 group=backup_config) 

82 CONF.set_override("netapp_backup_vserver", 

83 "fake_backup_share", 

84 group=backup_config) 

85 CONF.set_override("netapp_backup_volume", 

86 "fake_share_server", 

87 group=backup_config) 

88 return config 

89 

90 

91@ddt.ddt 

92class NetAppFileStorageLibraryTestCase(test.TestCase): 

93 

94 def setUp(self): 

95 super(NetAppFileStorageLibraryTestCase, self).setUp() 

96 

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

98 self.sleep_patcher.start() 

99 self.addCleanup(self.sleep_patcher.stop) 

100 

101 self.mock_object(na_utils, 'validate_driver_instantiation') 

102 self.mock_object(na_utils, 'setup_tracing') 

103 

104 # Mock loggers as themselves to allow logger arg validation 

105 mock_logger = log.getLogger('mock_logger') 

106 self.mock_object(lib_base.LOG, 

107 'info', 

108 mock.Mock(side_effect=mock_logger.info)) 

109 self.mock_object(lib_base.LOG, 

110 'warning', 

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

112 self.mock_object(lib_base.LOG, 

113 'error', 

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

115 self.mock_object(lib_base.LOG, 

116 'debug', 

117 mock.Mock(side_effect=mock_logger.debug)) 

118 

119 kwargs = { 

120 'configuration': fake.get_config_cmode(), 

121 'private_storage': mock.Mock(), 

122 'app_version': fake.APP_VERSION 

123 } 

124 self.library = lib_base.NetAppCmodeFileStorageLibrary(fake.DRIVER_NAME, 

125 **kwargs) 

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

127 self.library._perf_library = mock.Mock() 

128 self.client = self.library._client 

129 self.context = mock.Mock() 

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

131 self.fake_replica_2 = copy.deepcopy(fake.SHARE) 

132 self.fake_replica_2['id'] = fake.SHARE_ID2 

133 self.fake_replica_2['replica_state'] = ( 

134 constants.REPLICA_STATE_OUT_OF_SYNC) 

135 self.mock_dm_session = mock.Mock() 

136 self.mock_object(data_motion, "DataMotionSession", 

137 mock.Mock(return_value=self.mock_dm_session)) 

138 self.mock_object(data_motion, 'get_client_for_backend') 

139 

140 def _mock_api_error(self, code='fake', message='fake'): 

141 return mock.Mock(side_effect=netapp_api.NaApiError(code=code, 

142 message=message)) 

143 

144 def test_init(self): 

145 self.assertEqual(fake.DRIVER_NAME, self.library.driver_name) 

146 self.assertEqual(1, na_utils.validate_driver_instantiation.call_count) 

147 self.assertEqual(1, na_utils.setup_tracing.call_count) 

148 self.assertListEqual([], self.library._licenses) 

149 self.assertDictEqual({}, self.library._clients) 

150 self.assertDictEqual({}, self.library._ssc_stats) 

151 self.assertIsNotNone(self.library._app_version) 

152 

153 def test_do_setup(self): 

154 mock_get_api_client = self.mock_object(self.library, '_get_api_client') 

155 self.mock_object( 

156 performance, 'PerformanceLibrary', 

157 mock.Mock(return_value='fake_perf_library')) 

158 self.mock_object( 

159 self.library._client, 'check_for_cluster_credentials', 

160 mock.Mock(return_value=True)) 

161 self.mock_object( 

162 self.library._client, 'get_nfs_config_default', 

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

164 self.mock_object(self.library._client, 

165 'list_cluster_nodes', 

166 mock.Mock(return_value=['node1', 'node2'])) 

167 self.mock_object( 

168 self.library, '_check_snaprestore_license', 

169 mock.Mock(return_value=True)) 

170 self.mock_object( 

171 self.library, 

172 '_get_licenses', 

173 mock.Mock(return_value=fake.LICENSES)) 

174 

175 mock_get_api_client.features.TRANSFER_LIMIT_NFS_CONFIG = True 

176 self.library.do_setup(self.context) 

177 self.assertEqual(fake.LICENSES, self.library._licenses) 

178 mock_get_api_client.assert_called_once_with() 

179 (self.library._client.check_for_cluster_credentials. 

180 assert_called_once_with()) 

181 (self.library._client.get_nfs_config_default. 

182 assert_called_once_with( 

183 list(self.library.NFS_CONFIG_EXTRA_SPECS_MAP.values()))) 

184 self.assertEqual('fake_perf_library', self.library._perf_library) 

185 self.mock_object(self.library._client, 

186 'check_for_cluster_credentials', 

187 mock.Mock(return_value=True)) 

188 self.mock_object(self.library._client, 

189 'list_cluster_nodes', 

190 mock.Mock(return_value=['node1', 'node2'])) 

191 self.mock_object( 

192 self.library, '_check_snaprestore_license', 

193 mock.Mock(return_value=True)) 

194 mock_set_cluster_info = self.mock_object( 

195 self.library, '_set_cluster_info') 

196 self.library.do_setup(self.context) 

197 mock_set_cluster_info.assert_called_once() 

198 

199 def test_set_cluster_info(self): 

200 self.library._client.is_nve_supported.return_value = True 

201 self.library._client.features.FLEXVOL_ENCRYPTION = True 

202 self.library._set_cluster_info() 

203 self.assertTrue(self.library._cluster_info['nve_support']) 

204 

205 def test_check_for_setup_error(self): 

206 mock_start_periodic_tasks = self.mock_object(self.library, 

207 '_start_periodic_tasks') 

208 self.library.check_for_setup_error() 

209 

210 mock_start_periodic_tasks.assert_called_once_with() 

211 

212 def test_get_vserver(self): 

213 self.assertRaises(NotImplementedError, self.library._get_vserver) 

214 

215 def test_get_api_client(self): 

216 

217 client_kwargs = fake.CLIENT_KWARGS.copy() 

218 

219 # First call should proceed normally. 

220 mock_client_constructor = self.mock_object(client_cmode, 

221 'NetAppCmodeClient') 

222 client1 = self.library._get_api_client() 

223 self.assertIsNotNone(client1) 

224 mock_client_constructor.assert_called_once_with(**client_kwargs) 

225 

226 # Second call should yield the same object. 

227 mock_client_constructor = self.mock_object(client_cmode, 

228 'NetAppCmodeClient') 

229 client2 = self.library._get_api_client() 

230 self.assertEqual(client1, client2) 

231 self.assertFalse(mock_client_constructor.called) 

232 

233 def test_get_api_client_with_vserver(self): 

234 

235 client_kwargs = fake.CLIENT_KWARGS.copy() 

236 client_kwargs['vserver'] = fake.VSERVER1 

237 

238 # First call should proceed normally. 

239 mock_client_constructor = self.mock_object(client_cmode, 

240 'NetAppCmodeClient') 

241 client1 = self.library._get_api_client(vserver=fake.VSERVER1) 

242 self.assertIsNotNone(client1) 

243 mock_client_constructor.assert_called_once_with(**client_kwargs) 

244 

245 # Second call should yield the same object. 

246 mock_client_constructor = self.mock_object(client_cmode, 

247 'NetAppCmodeClient') 

248 client2 = self.library._get_api_client(vserver=fake.VSERVER1) 

249 self.assertEqual(client1, client2) 

250 self.assertFalse(mock_client_constructor.called) 

251 

252 # A different vserver should work normally without caching. 

253 mock_client_constructor = self.mock_object(client_cmode, 

254 'NetAppCmodeClient') 

255 client3 = self.library._get_api_client(vserver=fake.VSERVER2) 

256 self.assertNotEqual(client1, client3) 

257 client_kwargs['vserver'] = fake.VSERVER2 

258 mock_client_constructor.assert_called_once_with(**client_kwargs) 

259 

260 def test_get_licenses_both_protocols(self): 

261 self.library._have_cluster_creds = True 

262 self.mock_object(self.client, 

263 'get_licenses', 

264 mock.Mock(return_value=fake.LICENSES)) 

265 

266 result = self.library._get_licenses() 

267 

268 self.assertSequenceEqual(fake.LICENSES, result) 

269 self.assertEqual(0, lib_base.LOG.error.call_count) 

270 self.assertEqual(1, lib_base.LOG.info.call_count) 

271 

272 def test_get_licenses_one_protocol(self): 

273 self.library._have_cluster_creds = True 

274 licenses = list(fake.LICENSES) 

275 licenses.remove('nfs') 

276 self.mock_object(self.client, 

277 'get_licenses', 

278 mock.Mock(return_value=licenses)) 

279 

280 result = self.library._get_licenses() 

281 

282 self.assertListEqual(licenses, result) 

283 self.assertEqual(0, lib_base.LOG.error.call_count) 

284 self.assertEqual(1, lib_base.LOG.info.call_count) 

285 

286 def test_get_licenses_no_protocols(self): 

287 self.library._have_cluster_creds = True 

288 licenses = list(fake.LICENSES) 

289 licenses.remove('nfs') 

290 licenses.remove('cifs') 

291 self.mock_object(self.client, 

292 'get_licenses', 

293 mock.Mock(return_value=licenses)) 

294 

295 result = self.library._get_licenses() 

296 

297 self.assertListEqual(licenses, result) 

298 self.assertEqual(1, lib_base.LOG.error.call_count) 

299 self.assertEqual(1, lib_base.LOG.info.call_count) 

300 

301 def test_get_licenses_no_cluster_creds(self): 

302 self.library._have_cluster_creds = False 

303 

304 result = self.library._get_licenses() 

305 

306 self.assertListEqual([], result) 

307 self.assertEqual(1, lib_base.LOG.debug.call_count) 

308 

309 def test_start_periodic_tasks(self): 

310 

311 mock_update_ssc_info = self.mock_object(self.library, 

312 '_update_ssc_info') 

313 mock_handle_ems_logging = self.mock_object(self.library, 

314 '_handle_ems_logging') 

315 mock_handle_housekeeping_tasks = self.mock_object( 

316 self.library, '_handle_housekeeping_tasks') 

317 mock_ssc_periodic_task = mock.Mock() 

318 mock_ems_periodic_task = mock.Mock() 

319 mock_housekeeping_periodic_task = mock.Mock() 

320 mock_loopingcall = self.mock_object( 

321 loopingcall, 

322 'FixedIntervalLoopingCall', 

323 mock.Mock(side_effect=[mock_ssc_periodic_task, 

324 mock_ems_periodic_task, 

325 mock_housekeeping_periodic_task])) 

326 

327 self.library._start_periodic_tasks() 

328 

329 self.assertTrue(mock_update_ssc_info.called) 

330 self.assertFalse(mock_handle_ems_logging.called) 

331 self.assertFalse(mock_housekeeping_periodic_task.called) 

332 mock_loopingcall.assert_has_calls( 

333 [mock.call(mock_update_ssc_info), 

334 mock.call(mock_handle_ems_logging), 

335 mock.call(mock_handle_housekeeping_tasks)]) 

336 self.assertTrue(mock_ssc_periodic_task.start.called) 

337 self.assertTrue(mock_ems_periodic_task.start.called) 

338 self.assertTrue(mock_housekeeping_periodic_task.start.called) 

339 

340 def test_get_backend_share_name(self): 

341 

342 result = self.library._get_backend_share_name(fake.SHARE_ID) 

343 expected = (fake.VOLUME_NAME_TEMPLATE % 

344 {'share_id': fake.SHARE_ID.replace('-', '_')}) 

345 

346 self.assertEqual(expected, result) 

347 

348 def test_get_backend_snapshot_name(self): 

349 

350 result = self.library._get_backend_snapshot_name(fake.SNAPSHOT_ID) 

351 expected = 'share_snapshot_' + fake.SNAPSHOT_ID.replace('-', '_') 

352 

353 self.assertEqual(expected, result) 

354 

355 def test_get_backend_cg_snapshot_name(self): 

356 

357 result = self.library._get_backend_cg_snapshot_name(fake.SNAPSHOT_ID) 

358 expected = 'share_cg_snapshot_' + fake.SNAPSHOT_ID.replace('-', '_') 

359 

360 self.assertEqual(expected, result) 

361 

362 def test__get_backend_snapmirror_policy_name_svm(self): 

363 result = self.library._get_backend_snapmirror_policy_name_svm( 

364 fake.SERVER_ID) 

365 expected = 'snapmirror_policy_' + fake.SERVER_ID.replace('-', '_') 

366 

367 self.assertEqual(expected, result) 

368 

369 def test_get_aggregate_space_cluster_creds(self): 

370 

371 self.library._have_cluster_creds = True 

372 self.mock_object(self.library._client, 

373 'get_cluster_aggregate_capacities', 

374 mock.Mock(return_value=fake.AGGREGATE_CAPACITIES)) 

375 

376 result = self.library._get_aggregate_space(fake.AGGREGATES) 

377 

378 (self.library._client.get_cluster_aggregate_capacities. 

379 assert_called_once_with(fake.AGGREGATES)) 

380 self.assertDictEqual(fake.AGGREGATE_CAPACITIES, result) 

381 

382 def test_get_aggregate_space_no_cluster_creds(self): 

383 

384 self.library._have_cluster_creds = False 

385 self.mock_object(self.library._client, 

386 'get_vserver_aggregate_capacities', 

387 mock.Mock(return_value=fake.AGGREGATE_CAPACITIES)) 

388 

389 result = self.library._get_aggregate_space(fake.AGGREGATES) 

390 

391 (self.library._client.get_vserver_aggregate_capacities. 

392 assert_called_once_with(fake.AGGREGATES)) 

393 self.assertDictEqual(fake.AGGREGATE_CAPACITIES, result) 

394 

395 def test_check_snaprestore_license_admin_notfound(self): 

396 self.library._have_cluster_creds = True 

397 licenses = list(fake.LICENSES) 

398 licenses.remove('snaprestore') 

399 self.mock_object(self.client, 

400 'get_licenses', 

401 mock.Mock(return_value=licenses)) 

402 result = self.library._check_snaprestore_license() 

403 self.assertIs(False, result) 

404 

405 def test_check_snaprestore_license_admin_found(self): 

406 self.library._have_cluster_creds = True 

407 self.library._licenses = fake.LICENSES 

408 result = self.library._check_snaprestore_license() 

409 self.assertIs(True, result) 

410 

411 def test_check_snaprestore_license_svm_scoped(self): 

412 self.library._have_cluster_creds = False 

413 self.mock_object(self.library._client, 

414 'check_snaprestore_license', 

415 mock.Mock(return_value=True)) 

416 

417 result = self.library._check_snaprestore_license() 

418 

419 self.assertIs(True, result) 

420 

421 def test_get_aggregate_node_cluster_creds(self): 

422 

423 self.library._have_cluster_creds = True 

424 self.mock_object(self.library._client, 

425 'get_node_for_aggregate', 

426 mock.Mock(return_value=fake.CLUSTER_NODE)) 

427 

428 result = self.library._get_aggregate_node(fake.AGGREGATE) 

429 

430 (self.library._client.get_node_for_aggregate. 

431 assert_called_once_with(fake.AGGREGATE)) 

432 self.assertEqual(fake.CLUSTER_NODE, result) 

433 

434 def test_get_aggregate_node_no_cluster_creds(self): 

435 

436 self.library._have_cluster_creds = False 

437 self.mock_object(self.library._client, 'get_node_for_aggregate') 

438 

439 result = self.library._get_aggregate_node(fake.AGGREGATE) 

440 

441 self.assertFalse(self.library._client.get_node_for_aggregate.called) 

442 self.assertIsNone(result) 

443 

444 def test_get_default_filter_function(self): 

445 

446 result = self.library.get_default_filter_function() 

447 

448 self.assertEqual(self.library.DEFAULT_FILTER_FUNCTION, result) 

449 

450 def test_get_default_filter_function_flexgroup(self): 

451 mock_is_flexgroup = self.mock_object( 

452 self.library, '_is_flexgroup_pool', 

453 mock.Mock(return_value=True)) 

454 mock_get_min = self.mock_object( 

455 self.library, '_get_minimum_flexgroup_size', 

456 mock.Mock(return_value=self.library.FLEXGROUP_MIN_SIZE_PER_AGGR)) 

457 

458 result = self.library.get_default_filter_function(pool=fake.POOL_NAME) 

459 

460 expected_filer = (self.library.DEFAULT_FLEXGROUP_FILTER_FUNCTION % 

461 self.library.FLEXGROUP_MIN_SIZE_PER_AGGR) 

462 self.assertEqual(expected_filer, result) 

463 mock_is_flexgroup.assert_called_once_with(fake.POOL_NAME) 

464 mock_get_min.assert_called_once_with(fake.POOL_NAME) 

465 

466 def test_get_default_goodness_function(self): 

467 

468 result = self.library.get_default_goodness_function() 

469 

470 self.assertEqual(self.library.DEFAULT_GOODNESS_FUNCTION, result) 

471 

472 @ddt.data( 

473 {'replication': True, 'flexgroup': False}, 

474 {'replication': True, 'flexgroup': True}, 

475 {'replication': False, 'flexgroup': False}, 

476 {'replication': False, 'flexgroup': True}, 

477 ) 

478 @ddt.unpack 

479 def test_get_share_stats(self, replication, flexgroup): 

480 

481 if replication: 

482 self.library.configuration.replication_domain = "fake_domain" 

483 if flexgroup: 

484 self.library._flexgroup_pools = {'pool': ['aggr']} 

485 

486 mock_get_pools = self.mock_object( 

487 self.library, '_get_pools', 

488 mock.Mock(return_value=fake.POOLS)) 

489 

490 result = self.library.get_share_stats(get_filter_function='filter', 

491 goodness_function='goodness') 

492 

493 expected = { 

494 'share_backend_name': fake.BACKEND_NAME, 

495 'driver_name': fake.DRIVER_NAME, 

496 'vendor_name': 'NetApp', 

497 'driver_version': '1.0', 

498 'netapp_storage_family': 'ontap_cluster', 

499 'storage_protocol': 'NFS_CIFS', 

500 'pools': fake.POOLS, 

501 'share_group_stats': {'consistent_snapshot_support': 'host'}, 

502 } 

503 if flexgroup: 

504 expected['share_group_stats']['consistent_snapshot_support'] = None 

505 if replication: 

506 expected['replication_type'] = ['dr', 'readable'] 

507 expected['replication_domain'] = 'fake_domain' 

508 

509 self.assertDictEqual(expected, result) 

510 mock_get_pools.assert_called_once_with(get_filter_function='filter', 

511 goodness_function='goodness') 

512 

513 def test_get_share_server_pools(self): 

514 

515 self.mock_object(self.library, 

516 '_get_pools', 

517 mock.Mock(return_value=fake.POOLS)) 

518 self.library._cache_pool_status = na_utils.DataCache(60) 

519 

520 result = self.library.get_share_server_pools(fake.SHARE_SERVER) 

521 

522 self.assertListEqual(fake.POOLS, result) 

523 

524 def test_get_pools(self): 

525 

526 fake_total = 1.0 

527 fake_free = 1.0 

528 fake_used = 1.0 

529 fake_pool = copy.deepcopy(fake.POOLS) 

530 fake_pool.append(fake.FLEXGROUP_POOL) 

531 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

532 mock_find_aggr = self.mock_object( 

533 self.library, '_find_matching_aggregates', 

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

535 mock_get_flexgroup_aggr = self.mock_object( 

536 self.library, '_get_flexgroup_aggr_set', 

537 mock.Mock(return_value=fake.FLEXGROUP_AGGR_SET)) 

538 mock_get_aggregate_space = self.mock_object( 

539 self.library, '_get_aggregate_space', 

540 mock.Mock(return_value=fake.AGGREGATE_CAPACITIES)) 

541 mock_get_flexvol_space = self.mock_object( 

542 self.library, '_get_flexvol_pool_space', 

543 mock.Mock(return_value=(fake_total, fake_free, fake_used))) 

544 mock_get_pool = self.mock_object( 

545 self.library, '_get_pool', 

546 mock.Mock(side_effect=fake_pool)) 

547 mock_get_flexgroup_space = self.mock_object( 

548 self.library, '_get_flexgroup_pool_space', 

549 mock.Mock(return_value=(fake_total, fake_free, fake_used))) 

550 mock_get_cluster_name = self.mock_object( 

551 self.library._client, 'get_cluster_name', 

552 mock.Mock(return_value='fake_cluster_name')) 

553 

554 self.library._cache_pool_status = na_utils.DataCache(60) 

555 self.library._have_cluster_creds = True 

556 result = self.library._get_pools( 

557 get_filter_function=fake.fake_get_filter_function, 

558 goodness_function='goodness') 

559 self.assertListEqual(fake_pool, result) 

560 mock_find_aggr.assert_called_once_with() 

561 mock_get_flexgroup_aggr.assert_called_once_with() 

562 mock_get_aggregate_space.assert_called_once_with(set(fake.AGGREGATES)) 

563 mock_get_flexvol_space.assert_has_calls([ 

564 mock.call(fake.AGGREGATE_CAPACITIES, fake.AGGREGATES[0]), 

565 mock.call(fake.AGGREGATE_CAPACITIES, fake.AGGREGATES[1])]) 

566 mock_get_flexgroup_space.assert_has_calls([ 

567 mock.call(fake.AGGREGATE_CAPACITIES, 

568 fake.FLEXGROUP_POOL_OPT[fake.FLEXGROUP_POOL_NAME])]) 

569 mock_get_cluster_name.assert_called_once_with() 

570 mock_get_pool.assert_has_calls([ 

571 mock.call(fake.AGGREGATES[0], fake_total, fake_free, fake_used), 

572 mock.call(fake.AGGREGATES[1], fake_total, fake_free, fake_used), 

573 mock.call(fake.FLEXGROUP_POOL_NAME, fake_total, fake_free, 

574 fake_used)]) 

575 

576 def test_get_pool_vserver_creds(self): 

577 

578 fake_pool = fake.POOLS_VSERVER_CREDS[0] 

579 self.library._have_cluster_creds = False 

580 self.library._revert_to_snapshot_support = True 

581 self.library._cluster_info = fake.CLUSTER_INFO 

582 self.library._ssc_stats = fake.SSC_INFO_VSERVER_CREDS 

583 self.library._perf_library.get_node_utilization_for_pool = ( 

584 mock.Mock(return_value=50.0)) 

585 self.mock_object(self.library, 

586 '_get_aggregate_snaplock_type', 

587 mock.Mock(return_value="compliance")) 

588 result = self.library._get_pool( 

589 fake_pool['pool_name'], fake_pool['total_capacity_gb'], 

590 fake_pool['free_capacity_gb'], fake_pool['allocated_capacity_gb']) 

591 

592 self.assertEqual(fake_pool, result) 

593 

594 def test_get_pool_cluster_creds(self): 

595 

596 fake_pool = copy.deepcopy(fake.POOLS[0]) 

597 fake_pool['filter_function'] = None 

598 fake_pool['goodness_function'] = None 

599 fake_pool['netapp_cluster_name'] = '' 

600 self.library._have_cluster_creds = True 

601 self.library._revert_to_snapshot_support = True 

602 self.library._cluster_info = fake.CLUSTER_INFO 

603 self.library._ssc_stats = fake.SSC_INFO 

604 self.library._perf_library.get_node_utilization_for_pool = ( 

605 mock.Mock(return_value=30.0)) 

606 self.mock_object(self.library, 

607 '_get_aggregate_snaplock_type', 

608 mock.Mock(return_value="compliance")) 

609 

610 result = self.library._get_pool( 

611 fake_pool['pool_name'], fake_pool['total_capacity_gb'], 

612 fake_pool['free_capacity_gb'], fake_pool['allocated_capacity_gb']) 

613 

614 self.assertEqual(fake_pool, result) 

615 

616 def test_get_flexvol_pool_space(self): 

617 

618 total_gb, free_gb, used_gb = self.library._get_flexvol_pool_space( 

619 fake.AGGREGATE_CAPACITIES, fake.AGGREGATES[0]) 

620 self.mock_object(self.library, 

621 '_get_aggregate_snaplock_type', 

622 mock.Mock(return_value="compliance")) 

623 

624 self.assertEqual(total_gb, fake.POOLS[0]['total_capacity_gb']) 

625 self.assertEqual(free_gb, fake.POOLS[0]['free_capacity_gb']) 

626 self.assertEqual(used_gb, fake.POOLS[0]['allocated_capacity_gb']) 

627 

628 def test_get_flexgroup_pool_space(self): 

629 

630 total_gb, free_gb, used_gb = self.library._get_flexgroup_pool_space( 

631 fake.AGGREGATE_CAPACITIES, fake.FLEXGROUP_POOL_AGGR) 

632 

633 self.assertEqual(total_gb, fake.FLEXGROUP_POOL['total_capacity_gb']) 

634 self.assertEqual(free_gb, fake.FLEXGROUP_POOL['free_capacity_gb']) 

635 self.assertEqual(used_gb, fake.FLEXGROUP_POOL['allocated_capacity_gb']) 

636 

637 @ddt.data( 

638 {'aggr_space': fake.AGGREGATE_CAPACITIES, 'aggr_pool': []}, 

639 {'aggr_space': fake.AGGREGATE_CAPACITIES, 'aggr_pool': ['fake']}, 

640 {'aggr_space': {fake.AGGREGATES[0]: {}}, 

641 'aggr_pool': [fake.AGGREGATES[0]]}) 

642 @ddt.unpack 

643 def test_get_flexgroup_pool_space_zero(self, aggr_space, aggr_pool): 

644 

645 total_gb, free_gb, used_gb = self.library._get_flexgroup_pool_space( 

646 aggr_space, aggr_pool) 

647 

648 self.assertEqual(total_gb, 0.0) 

649 self.assertEqual(free_gb, 0.0) 

650 self.assertEqual(used_gb, 0.0) 

651 

652 def test_get_flexgroup_aggr_set(self): 

653 

654 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

655 

656 result = self.library._get_flexgroup_aggr_set() 

657 

658 self.assertSetEqual(result, set(fake.FLEXGROUP_POOL_AGGR)) 

659 

660 def test_handle_ems_logging(self): 

661 

662 self.mock_object(self.library, 

663 '_build_ems_log_message_0', 

664 mock.Mock(return_value=fake.EMS_MESSAGE_0)) 

665 self.mock_object(self.library, 

666 '_build_ems_log_message_1', 

667 mock.Mock(return_value=fake.EMS_MESSAGE_1)) 

668 

669 self.library._handle_ems_logging() 

670 

671 self.library._client.send_ems_log_message.assert_has_calls([ 

672 mock.call(fake.EMS_MESSAGE_0), 

673 mock.call(fake.EMS_MESSAGE_1), 

674 ]) 

675 

676 def test_build_ems_log_message_0(self): 

677 

678 self.mock_object(socket, 

679 'gethostname', 

680 mock.Mock(return_value=fake.HOST_NAME)) 

681 

682 result = self.library._build_ems_log_message_0() 

683 

684 self.assertDictEqual(fake.EMS_MESSAGE_0, result) 

685 

686 def test_build_ems_log_message_1(self): 

687 

688 pool_info = { 

689 'pools': { 

690 'vserver': 'fake_vserver', 

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

692 }, 

693 } 

694 self.mock_object(socket, 

695 'gethostname', 

696 mock.Mock(return_value=fake.HOST_NAME)) 

697 self.mock_object(self.library, 

698 '_get_ems_pool_info', 

699 mock.Mock(return_value=pool_info)) 

700 

701 result = self.library._build_ems_log_message_1() 

702 

703 self.assertDictEqual(pool_info, 

704 json.loads(result['event-description'])) 

705 result['event-description'] = '' 

706 self.assertDictEqual(fake.EMS_MESSAGE_1, result) 

707 

708 def test_get_ems_pool_info(self): 

709 self.assertRaises(NotImplementedError, 

710 self.library._get_ems_pool_info) 

711 

712 def test_find_matching_aggregates(self): 

713 self.assertRaises(NotImplementedError, 

714 self.library._find_matching_aggregates) 

715 

716 @ddt.data(('NFS', nfs_cmode.NetAppCmodeNFSHelper), 

717 ('nfs', nfs_cmode.NetAppCmodeNFSHelper), 

718 ('CIFS', cifs_cmode.NetAppCmodeCIFSHelper), 

719 ('cifs', cifs_cmode.NetAppCmodeCIFSHelper)) 

720 @ddt.unpack 

721 def test_get_helper(self, protocol, helper_type): 

722 

723 fake_share = fake.SHARE.copy() 

724 fake_share['share_proto'] = protocol 

725 mock_check_license_for_protocol = self.mock_object( 

726 self.library, '_check_license_for_protocol') 

727 

728 result = self.library._get_helper(fake_share) 

729 

730 mock_check_license_for_protocol.assert_called_once_with( 

731 protocol.lower()) 

732 self.assertEqual(helper_type, type(result)) 

733 

734 def test_get_helper_invalid_protocol(self): 

735 

736 fake_share = fake.SHARE.copy() 

737 fake_share['share_proto'] = 'iSCSI' 

738 self.mock_object(self.library, '_check_license_for_protocol') 

739 

740 self.assertRaises(exception.NetAppException, 

741 self.library._get_helper, 

742 fake_share) 

743 

744 def test_check_license_for_protocol_no_cluster_creds(self): 

745 

746 self.library._have_cluster_creds = False 

747 

748 result = self.library._check_license_for_protocol('fake_protocol') 

749 

750 self.assertIsNone(result) 

751 

752 def test_check_license_for_protocol_have_license(self): 

753 

754 self.library._have_cluster_creds = True 

755 self.library._licenses = ['base', 'fake_protocol'] 

756 

757 result = self.library._check_license_for_protocol('FAKE_PROTOCOL') 

758 

759 self.assertIsNone(result) 

760 

761 def test_check_license_for_protocol_newly_licensed_protocol(self): 

762 

763 self.library._have_cluster_creds = True 

764 self.mock_object(self.library, 

765 '_get_licenses', 

766 mock.Mock(return_value=['base', 'nfs'])) 

767 self.library._licenses = ['base'] 

768 

769 result = self.library._check_license_for_protocol('NFS') 

770 

771 self.assertIsNone(result) 

772 self.assertTrue(self.library._get_licenses.called) 

773 

774 def test_check_license_for_protocol_unlicensed_protocol(self): 

775 

776 self.library._have_cluster_creds = True 

777 self.mock_object(self.library, 

778 '_get_licenses', 

779 mock.Mock(return_value=['base'])) 

780 self.library._licenses = ['base'] 

781 

782 self.assertRaises(exception.NetAppException, 

783 self.library._check_license_for_protocol, 

784 'NFS') 

785 

786 def test_get_pool_has_pool(self): 

787 result = self.library.get_pool(fake.SHARE) 

788 self.assertEqual(fake.POOL_NAME, result) 

789 self.assertFalse(self.client.get_aggregate_for_volume.called) 

790 

791 @ddt.data(True, False) 

792 def test_get_pool_no_pool(self, is_flexgroup): 

793 

794 fake_share = copy.deepcopy(fake.SHARE) 

795 fake_share['host'] = '%(host)s@%(backend)s' % { 

796 'host': fake.HOST_NAME, 'backend': fake.BACKEND_NAME} 

797 self.mock_object(self.library, 

798 '_get_flexgroup_pool_name', 

799 mock.Mock(return_value=fake.POOL_NAME)) 

800 if is_flexgroup: 

801 self.client.get_aggregate_for_volume.return_value = [ 

802 fake.POOL_NAME] 

803 else: 

804 self.client.get_aggregate_for_volume.return_value = fake.POOL_NAME 

805 

806 result = self.library.get_pool(fake_share) 

807 

808 self.assertEqual(fake.POOL_NAME, result) 

809 self.assertTrue(self.client.get_aggregate_for_volume.called) 

810 self.assertEqual(is_flexgroup, 

811 self.library._get_flexgroup_pool_name.called) 

812 

813 @ddt.data(True, False) 

814 def test_get_pool_raises(self, is_flexgroup): 

815 

816 fake_share = copy.deepcopy(fake.SHARE) 

817 fake_share['host'] = '%(host)s@%(backend)s' % { 

818 'host': fake.HOST_NAME, 'backend': fake.BACKEND_NAME} 

819 self.mock_object(self.library, 

820 '_get_flexgroup_pool_name', 

821 mock.Mock(return_value=None)) 

822 if is_flexgroup: 

823 self.client.get_aggregate_for_volume.return_value = [] 

824 else: 

825 self.client.get_aggregate_for_volume.return_value = None 

826 

827 self.assertRaises(exception.NetAppException, 

828 self.library.get_pool, 

829 fake_share) 

830 

831 def test_create_share(self): 

832 

833 vserver_client = mock.Mock() 

834 self.mock_object(self.library, 

835 '_get_vserver', 

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

837 vserver_client))) 

838 mock_allocate_container = self.mock_object(self.library, 

839 '_allocate_container') 

840 mock_create_export = self.mock_object( 

841 self.library, 

842 '_create_export', 

843 mock.Mock(return_value='fake_export_location')) 

844 

845 result = self.library.create_share(self.context, 

846 fake.SHARE, 

847 share_server=fake.SHARE_SERVER) 

848 

849 mock_allocate_container.assert_called_once_with(fake.SHARE, 

850 fake.VSERVER1, 

851 vserver_client) 

852 mock_create_export.assert_called_once_with(fake.SHARE, 

853 fake.SHARE_SERVER, 

854 fake.VSERVER1, 

855 vserver_client) 

856 self.assertEqual('fake_export_location', result) 

857 

858 @ddt.data(None, fake.CG_SNAPSHOT_MEMBER_ID1) 

859 def test_create_share_from_snapshot(self, share_group_id): 

860 

861 share = copy.deepcopy(fake.SHARE) 

862 share['source_share_group_snapshot_member_id'] = share_group_id 

863 vserver_client = mock.Mock() 

864 self.mock_object(self.library, 

865 '_get_vserver', 

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

867 vserver_client))) 

868 mock_allocate_container_from_snapshot = self.mock_object( 

869 self.library, 

870 '_allocate_container_from_snapshot') 

871 mock_create_export = self.mock_object( 

872 self.library, 

873 '_create_export', 

874 mock.Mock(return_value='fake_export_location')) 

875 

876 result = self.library.create_share_from_snapshot( 

877 self.context, 

878 share, 

879 fake.SNAPSHOT, 

880 share_server=fake.SHARE_SERVER, 

881 parent_share=share) 

882 

883 mock_allocate_container_from_snapshot.assert_called_once_with( 

884 share, 

885 fake.SNAPSHOT, 

886 fake.VSERVER1, 

887 vserver_client) 

888 mock_create_export.assert_called_once_with(share, 

889 fake.SHARE_SERVER, 

890 fake.VSERVER1, 

891 vserver_client) 

892 self.assertEqual('fake_export_location', result) 

893 

894 def _setup_mocks_for_create_share_from_snapshot( 

895 self, allocate_attr=None, dest_cluster=fake.CLUSTER_NAME, 

896 is_flexgroup=False, flexgroup_error=False): 

897 class FakeDBObj(dict): 

898 def to_dict(self): 

899 return self 

900 

901 if allocate_attr is None: 

902 allocate_attr = mock.Mock() 

903 

904 self.src_vserver_client = mock.Mock() 

905 self.mock_dm_session = mock.Mock() 

906 self.fake_share = FakeDBObj(fake.SHARE) 

907 self.fake_share_server = FakeDBObj(fake.SHARE_SERVER) 

908 

909 self.mock_dm_constr = self.mock_object( 

910 data_motion, "DataMotionSession", 

911 mock.Mock(return_value=self.mock_dm_session)) 

912 self.mock_dm_backend = self.mock_object( 

913 self.mock_dm_session, 'get_backend_info_for_share', 

914 mock.Mock(return_value=(None, 

915 fake.VSERVER1, fake.BACKEND_NAME))) 

916 self.mock_dm_get_src_client = self.mock_object( 

917 data_motion, 'get_client_for_backend', 

918 mock.Mock(return_value=self.src_vserver_client)) 

919 self.mock_get_src_cluster = self.mock_object( 

920 self.src_vserver_client, 'get_cluster_name', 

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

922 self.dest_vserver_client = mock.Mock() 

923 self.mock_get_vserver = self.mock_object( 

924 self.library, '_get_vserver', 

925 mock.Mock(return_value=(fake.VSERVER2, self.dest_vserver_client))) 

926 self.mock_get_dest_cluster = self.mock_object( 

927 self.dest_vserver_client, 'get_cluster_name', 

928 mock.Mock(return_value=dest_cluster)) 

929 self.mock_extract_host = self.mock_object( 

930 share_utils, 'extract_host', 

931 mock.Mock(return_value=fake.POOL_NAME)) 

932 self.mock_is_flexgroup_share = self.mock_object( 

933 self.library, '_is_flexgroup_share', 

934 mock.Mock(return_value=is_flexgroup)) 

935 self.mock_is_flexgroup_pool = self.mock_object( 

936 self.library, '_is_flexgroup_pool', 

937 mock.Mock(return_value=(not is_flexgroup if flexgroup_error 

938 else is_flexgroup))) 

939 self.mock_get_aggregate_for_volume = self.mock_object( 

940 self.src_vserver_client, 'get_aggregate_for_volume', 

941 mock.Mock(return_value=[fake.POOL_NAME])) 

942 self.mock_get_flexgroup_aggregate_list = self.mock_object( 

943 self.library, '_get_flexgroup_aggregate_list', 

944 mock.Mock(return_value=[fake.POOL_NAME])) 

945 self.mock_allocate_container_from_snapshot = self.mock_object( 

946 self.library, '_allocate_container_from_snapshot', allocate_attr) 

947 self.mock_allocate_container = self.mock_object( 

948 self.library, '_allocate_container') 

949 self.mock_get_relationship_type = self.mock_object( 

950 na_utils, 'get_relationship_type', 

951 mock.Mock(return_value=(na_utils.EXTENDED_DATA_PROTECTION_TYPE 

952 if is_flexgroup 

953 else na_utils.DATA_PROTECTION_TYPE))) 

954 self.mock_dm_create_snapmirror = self.mock_object( 

955 self.mock_dm_session, 'create_snapmirror') 

956 self.mock_storage_update = self.mock_object( 

957 self.library.private_storage, 'update') 

958 self.mock_generate_uuid = self.mock_object( 

959 uuidutils, 'generate_uuid', mock.Mock(return_value=fake.SHARE_ID5)) 

960 

961 # Parent share on MANILA_HOST_2 

962 self.parent_share = copy.copy(fake.SHARE) 

963 self.parent_share['share_server'] = fake.SHARE_SERVER_2 

964 self.parent_share['host'] = fake.MANILA_HOST_NAME_2 

965 self.parent_share_server = {} 

966 ss_keys = ['id', 'identifier', 'backend_details', 'host'] 

967 for key in ss_keys: 

968 self.parent_share_server[key] = ( 

969 self.parent_share['share_server'].get(key, None)) 

970 self.temp_src_share = { 

971 'id': self.fake_share['id'], 

972 'host': self.parent_share['host'], 

973 'share_server': self.parent_share_server or None 

974 } 

975 

976 @ddt.data({'dest_cluster': fake.CLUSTER_NAME, 'is_flexgroup': False, 

977 'have_cluster_creds': False}, 

978 {'dest_cluster': fake.CLUSTER_NAME, 'is_flexgroup': False, 

979 'have_cluster_creds': True}, 

980 {'dest_cluster': fake.CLUSTER_NAME, 'is_flexgroup': True, 

981 'have_cluster_creds': False}, 

982 {'dest_cluster': fake.CLUSTER_NAME_2, 'is_flexgroup': False, 

983 'have_cluster_creds': False}, 

984 {'dest_cluster': fake.CLUSTER_NAME_2, 'is_flexgroup': False, 

985 'have_cluster_creds': True}, 

986 ) 

987 @ddt.unpack 

988 def test_create_share_from_snapshot_another_host(self, dest_cluster, 

989 is_flexgroup, 

990 have_cluster_creds): 

991 self.library._have_cluster_creds = have_cluster_creds 

992 self._setup_mocks_for_create_share_from_snapshot( 

993 dest_cluster=dest_cluster, is_flexgroup=is_flexgroup) 

994 mock_get_backend_shr_name = self.mock_object( 

995 self.library, '_get_backend_share_name', 

996 mock.Mock(return_value=fake.SHARE_NAME)) 

997 result = self.library.create_share_from_snapshot( 

998 self.context, 

999 self.fake_share, 

1000 fake.SNAPSHOT, 

1001 share_server=self.fake_share_server, 

1002 parent_share=self.parent_share) 

1003 

1004 self.fake_share['share_server'] = self.fake_share_server 

1005 

1006 self.mock_dm_constr.assert_called_once() 

1007 self.mock_dm_backend.assert_called_once_with(self.parent_share) 

1008 self.mock_dm_get_src_client.assert_called_once_with( 

1009 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1010 

1011 self.mock_get_vserver.assert_called_once_with(self.fake_share_server) 

1012 if have_cluster_creds: 

1013 self.mock_get_dest_cluster.assert_called_once() 

1014 self.mock_get_src_cluster.assert_called_once() 

1015 else: 

1016 self.mock_get_dest_cluster.assert_not_called() 

1017 self.mock_get_src_cluster.assert_not_called() 

1018 mock_get_backend_shr_name.assert_called_once() 

1019 self.mock_is_flexgroup_share.assert_called_once() 

1020 self.mock_is_flexgroup_pool.assert_called_once() 

1021 self.assertEqual(is_flexgroup, 

1022 self.mock_get_aggregate_for_volume.called) 

1023 self.assertEqual(is_flexgroup, 

1024 self.mock_get_flexgroup_aggregate_list.called) 

1025 

1026 if (dest_cluster != fake.CLUSTER_NAME 

1027 or is_flexgroup or not have_cluster_creds): 

1028 temp_share = copy.deepcopy(self.fake_share) 

1029 temp_share["id"] = fake.SHARE_ID5 

1030 self.mock_allocate_container_from_snapshot.assert_called_once_with( 

1031 temp_share, fake.SNAPSHOT, fake.VSERVER1, 

1032 self.src_vserver_client, split=False, create_fpolicy=False) 

1033 self.mock_allocate_container.assert_called_once_with( 

1034 self.fake_share, fake.VSERVER2, 

1035 self.dest_vserver_client, replica=True, set_qos=False) 

1036 self.mock_dm_create_snapmirror.assert_called_once() 

1037 self.temp_src_share['replica_state'] = ( 

1038 constants.REPLICA_STATE_ACTIVE) 

1039 state = self.library.STATE_SNAPMIRROR_DATA_COPYING 

1040 else: 

1041 self.mock_allocate_container_from_snapshot.assert_called_once_with( 

1042 self.fake_share, fake.SNAPSHOT, fake.VSERVER1, 

1043 self.src_vserver_client, split=True) 

1044 state = self.library.STATE_SPLITTING_VOLUME_CLONE 

1045 

1046 self.temp_src_share['aggregate'] = ([fake.POOL_NAME] 

1047 if is_flexgroup 

1048 else fake.POOL_NAME) 

1049 self.temp_src_share['internal_state'] = state 

1050 self.temp_src_share['status'] = constants.STATUS_ACTIVE 

1051 str_temp_src_share = json.dumps(self.temp_src_share) 

1052 self.mock_storage_update.assert_called_once_with( 

1053 self.fake_share['id'], { 

1054 'source_share': str_temp_src_share 

1055 }) 

1056 expected_return = {'status': 

1057 constants.STATUS_CREATING_FROM_SNAPSHOT} 

1058 self.assertEqual(expected_return, result) 

1059 

1060 @ddt.data(True, False) 

1061 def test_create_share_from_snapshot_another_host_driver_error( 

1062 self, have_cluster_creds): 

1063 self.library._have_cluster_creds = have_cluster_creds 

1064 self._setup_mocks_for_create_share_from_snapshot( 

1065 allocate_attr=mock.Mock(side_effect=exception.NetAppException)) 

1066 mock_delete_snapmirror = self.mock_object( 

1067 self.mock_dm_session, 'delete_snapmirror') 

1068 

1069 mock_delete_share = self.mock_object( 

1070 self.library, '_delete_share') 

1071 

1072 self.assertRaises(exception.NetAppException, 

1073 self.library.create_share_from_snapshot, 

1074 self.context, 

1075 self.fake_share, 

1076 fake.SNAPSHOT, 

1077 share_server=self.fake_share_server, 

1078 parent_share=self.parent_share) 

1079 

1080 self.fake_share['share_server'] = self.fake_share_server 

1081 

1082 self.mock_dm_constr.assert_called_once() 

1083 self.mock_dm_backend.assert_called_once_with(self.parent_share) 

1084 self.mock_dm_get_src_client.assert_called_once_with( 

1085 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1086 self.mock_get_vserver.assert_called_once_with(self.fake_share_server) 

1087 if have_cluster_creds: 

1088 self.mock_get_dest_cluster.assert_called_once() 

1089 self.mock_get_src_cluster.assert_called_once() 

1090 else: 

1091 self.mock_get_dest_cluster.assert_not_called() 

1092 self.mock_get_src_cluster.assert_not_called() 

1093 

1094 if have_cluster_creds: 

1095 self.mock_allocate_container_from_snapshot.assert_called_once_with( 

1096 self.fake_share, fake.SNAPSHOT, fake.VSERVER1, 

1097 self.src_vserver_client, split=True) 

1098 else: 

1099 self.mock_generate_uuid.assert_called_once() 

1100 temp_share = copy.deepcopy(self.fake_share) 

1101 temp_share["id"] = fake.SHARE_ID5 

1102 self.mock_allocate_container_from_snapshot.assert_called_once_with( 

1103 temp_share, fake.SNAPSHOT, fake.VSERVER1, 

1104 self.src_vserver_client, split=False, create_fpolicy=False) 

1105 

1106 mock_delete_snapmirror.assert_called_once_with( 

1107 self.temp_src_share, self.fake_share) 

1108 

1109 mock_delete_share.assert_called_once_with( 

1110 self.temp_src_share, fake.VSERVER1, self.src_vserver_client, 

1111 remove_export=False) 

1112 

1113 def test_create_share_from_snapshot_different_pool_types(self): 

1114 

1115 self._setup_mocks_for_create_share_from_snapshot( 

1116 dest_cluster=fake.CLUSTER_NAME_2, is_flexgroup=True, 

1117 flexgroup_error=True) 

1118 self.assertRaises(exception.NetAppException, 

1119 self.library.create_share_from_snapshot, 

1120 self.context, 

1121 self.fake_share, 

1122 fake.SNAPSHOT, 

1123 share_server=self.fake_share_server, 

1124 parent_share=self.parent_share) 

1125 

1126 def test_create_share_from_snapshot_mismatch_flexgroup_pools_len(self): 

1127 

1128 self._setup_mocks_for_create_share_from_snapshot( 

1129 dest_cluster=fake.CLUSTER_NAME_2, is_flexgroup=True) 

1130 self.mock_object( 

1131 self.library, '_get_flexgroup_aggregate_list', 

1132 mock.Mock(return_value=[])) 

1133 self.library._is_flexgroup_auto = False 

1134 self.assertRaises(exception.NetAppException, 

1135 self.library.create_share_from_snapshot, 

1136 self.context, 

1137 self.fake_share, 

1138 fake.SNAPSHOT, 

1139 share_server=self.fake_share_server, 

1140 parent_share=self.parent_share) 

1141 

1142 def test__update_create_from_snapshot_status(self): 

1143 fake_result = mock.Mock() 

1144 mock_pvt_storage_get = self.mock_object( 

1145 self.library.private_storage, 'get', 

1146 mock.Mock(return_value=fake.SHARE)) 

1147 mock__create_continue = self.mock_object( 

1148 self.library, '_create_from_snapshot_continue', 

1149 mock.Mock(return_value=fake_result)) 

1150 

1151 result = self.library._update_create_from_snapshot_status( 

1152 fake.SHARE, fake.SHARE_SERVER) 

1153 

1154 mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1155 'source_share') 

1156 mock__create_continue.assert_called_once_with(fake.SHARE, 

1157 fake.SHARE_SERVER) 

1158 self.assertEqual(fake_result, result) 

1159 

1160 def test__update_create_from_snapshot_status_missing_source_share(self): 

1161 mock_pvt_storage_get = self.mock_object( 

1162 self.library.private_storage, 'get', 

1163 mock.Mock(return_value=None)) 

1164 expected_result = {'status': constants.STATUS_ERROR} 

1165 result = self.library._update_create_from_snapshot_status( 

1166 fake.SHARE, fake.SHARE_SERVER) 

1167 mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1168 'source_share') 

1169 self.assertEqual(expected_result, result) 

1170 

1171 def test__update_create_from_snapshot_status_driver_error(self): 

1172 fake_src_share = { 

1173 'id': fake.SHARE['id'], 

1174 'host': fake.SHARE['host'], 

1175 'internal_state': 'fake_internal_state', 

1176 } 

1177 copy_fake_src_share = copy.deepcopy(fake_src_share) 

1178 src_vserver_client = mock.Mock() 

1179 mock_dm_session = mock.Mock() 

1180 mock_pvt_storage_get = self.mock_object( 

1181 self.library.private_storage, 'get', 

1182 mock.Mock(return_value=json.dumps(copy_fake_src_share))) 

1183 mock__create_continue = self.mock_object( 

1184 self.library, '_create_from_snapshot_continue', 

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

1186 mock_dm_constr = self.mock_object( 

1187 data_motion, "DataMotionSession", 

1188 mock.Mock(return_value=mock_dm_session)) 

1189 mock_delete_snapmirror = self.mock_object( 

1190 mock_dm_session, 'delete_snapmirror') 

1191 mock_dm_backend = self.mock_object( 

1192 mock_dm_session, 'get_backend_info_for_share', 

1193 mock.Mock(return_value=(None, 

1194 fake.VSERVER1, fake.BACKEND_NAME))) 

1195 mock_dm_get_src_client = self.mock_object( 

1196 data_motion, 'get_client_for_backend', 

1197 mock.Mock(return_value=src_vserver_client)) 

1198 mock_get_backend_shr_name = self.mock_object( 

1199 self.library, '_get_backend_share_name', 

1200 mock.Mock(return_value=fake.SHARE_NAME)) 

1201 mock_share_exits = self.mock_object( 

1202 self.library, '_share_exists', 

1203 mock.Mock(return_value=True)) 

1204 mock_deallocate_container = self.mock_object( 

1205 self.library, '_deallocate_container') 

1206 mock_pvt_storage_delete = self.mock_object( 

1207 self.library.private_storage, 'delete') 

1208 mock_delete_policy = self.mock_object(self.library, 

1209 '_delete_fpolicy_for_share') 

1210 

1211 result = self.library._update_create_from_snapshot_status( 

1212 fake.SHARE, fake.SHARE_SERVER) 

1213 expected_result = {'status': constants.STATUS_ERROR} 

1214 

1215 mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1216 'source_share') 

1217 mock__create_continue.assert_called_once_with(fake.SHARE, 

1218 fake.SHARE_SERVER) 

1219 mock_dm_constr.assert_called_once() 

1220 mock_delete_snapmirror.assert_called_once_with(fake_src_share, 

1221 fake.SHARE) 

1222 mock_dm_backend.assert_called_once_with(fake_src_share) 

1223 mock_dm_get_src_client.assert_called_once_with( 

1224 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1225 mock_get_backend_shr_name.assert_called_once_with(fake_src_share['id']) 

1226 mock_share_exits.assert_called_once_with(fake.SHARE_NAME, 

1227 src_vserver_client) 

1228 mock_deallocate_container.assert_called_once_with(fake.SHARE_NAME, 

1229 src_vserver_client) 

1230 mock_pvt_storage_delete.assert_called_once_with(fake.SHARE['id']) 

1231 mock_delete_policy.assert_called_once_with(fake_src_share, 

1232 fake.VSERVER1, 

1233 src_vserver_client) 

1234 self.assertEqual(expected_result, result) 

1235 

1236 def _setup_mocks_for_create_from_snapshot_continue( 

1237 self, src_host=fake.MANILA_HOST_NAME, 

1238 dest_host=fake.MANILA_HOST_NAME, split_completed_result=True, 

1239 move_completed_result=True, share_internal_state='fake_state', 

1240 replica_state='in_sync', is_flexgroup=False): 

1241 self.fake_export_location = 'fake_export_location' 

1242 self.fake_src_share = { 

1243 'id': fake.SHARE['id'], 

1244 'host': src_host, 

1245 'aggregate': src_host.split('#')[1], 

1246 'internal_state': share_internal_state, 

1247 } 

1248 self.copy_fake_src_share = copy.deepcopy(self.fake_src_share) 

1249 dest_pool = dest_host.split('#')[1] 

1250 self.src_vserver_client = mock.Mock() 

1251 self.dest_vserver_client = mock.Mock() 

1252 self.mock_dm_session = mock.Mock() 

1253 

1254 self.mock_dm_constr = self.mock_object( 

1255 data_motion, "DataMotionSession", 

1256 mock.Mock(return_value=self.mock_dm_session)) 

1257 self.mock_pvt_storage_get = self.mock_object( 

1258 self.library.private_storage, 'get', 

1259 mock.Mock(return_value=json.dumps(self.copy_fake_src_share))) 

1260 self.mock_dm_backend = self.mock_object( 

1261 self.mock_dm_session, 'get_backend_info_for_share', 

1262 mock.Mock(return_value=(None, 

1263 fake.VSERVER1, fake.BACKEND_NAME))) 

1264 self.mock_extract_host = self.mock_object( 

1265 share_utils, 'extract_host', 

1266 mock.Mock(return_value=dest_pool)) 

1267 self.mock_is_flexgroup_pool = self.mock_object( 

1268 self.library, '_is_flexgroup_pool', 

1269 mock.Mock(return_value=is_flexgroup)) 

1270 self.mock_get_flexgroup_aggregate_list = self.mock_object( 

1271 self.library, '_get_flexgroup_aggregate_list', 

1272 mock.Mock(return_value=dest_pool)) 

1273 self.mock_dm_get_src_client = self.mock_object( 

1274 data_motion, 'get_client_for_backend', 

1275 mock.Mock(return_value=self.src_vserver_client)) 

1276 self.mock_get_vserver = self.mock_object( 

1277 self.library, '_get_vserver', 

1278 mock.Mock(return_value=(fake.VSERVER2, self.dest_vserver_client))) 

1279 self.mock_split_completed = self.mock_object( 

1280 self.library, '_check_volume_clone_split_completed', 

1281 mock.Mock(return_value=split_completed_result)) 

1282 self.mock_rehost_vol = self.mock_object( 

1283 self.library, '_rehost_and_mount_volume') 

1284 self.mock_move_vol = self.mock_object(self.library, 

1285 '_move_volume_after_splitting') 

1286 self.mock_move_completed = self.mock_object( 

1287 self.library, '_check_volume_move_completed', 

1288 mock.Mock(return_value=move_completed_result)) 

1289 self.mock_update_rep_state = self.mock_object( 

1290 self.library, 'update_replica_state', 

1291 mock.Mock(return_value=replica_state) 

1292 ) 

1293 self.mock_update_snapmirror = self.mock_object( 

1294 self.mock_dm_session, 'update_snapmirror') 

1295 self.mock_break_snapmirror = self.mock_object( 

1296 self.mock_dm_session, 'break_snapmirror') 

1297 self.mock_delete_snapmirror = self.mock_object( 

1298 self.mock_dm_session, 'delete_snapmirror') 

1299 self.mock_get_backend_shr_name = self.mock_object( 

1300 self.library, '_get_backend_share_name', 

1301 mock.Mock(return_value=fake.SHARE_NAME)) 

1302 self.mock__delete_share = self.mock_object(self.library, 

1303 '_delete_share') 

1304 self.mock_set_vol_size_fixes = self.mock_object( 

1305 self.dest_vserver_client, 'set_volume_filesys_size_fixed') 

1306 self.mock_create_export = self.mock_object( 

1307 self.library, '_create_export', 

1308 mock.Mock(return_value=self.fake_export_location)) 

1309 self.mock_pvt_storage_update = self.mock_object( 

1310 self.library.private_storage, 'update') 

1311 self.mock_pvt_storage_delete = self.mock_object( 

1312 self.library.private_storage, 'delete') 

1313 self.mock_get_extra_specs_qos = self.mock_object( 

1314 share_types, 'get_extra_specs_from_share', 

1315 mock.Mock(return_value=fake.EXTRA_SPEC_WITH_QOS)) 

1316 self.mock__get_provisioning_opts = self.mock_object( 

1317 self.library, '_get_provisioning_options', 

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

1319 ) 

1320 self.mock_modify_create_qos = self.mock_object( 

1321 self.library, '_modify_or_create_qos_for_existing_share', 

1322 mock.Mock(return_value=fake.QOS_POLICY_GROUP_NAME)) 

1323 self.mock_modify_vol = self.mock_object(self.dest_vserver_client, 

1324 'modify_volume') 

1325 self.mock_get_backend_qos_name = self.mock_object( 

1326 self.library, '_get_backend_qos_policy_group_name', 

1327 mock.Mock(return_value=fake.QOS_POLICY_GROUP_NAME)) 

1328 self.mock_mark_qos_deletion = self.mock_object( 

1329 self.src_vserver_client, 'mark_qos_policy_group_for_deletion') 

1330 

1331 @ddt.data(fake.MANILA_HOST_NAME, fake.MANILA_HOST_NAME_2) 

1332 def test__create_from_snapshot_continue_state_splitting(self, src_host): 

1333 self._setup_mocks_for_create_from_snapshot_continue( 

1334 src_host=src_host, 

1335 share_internal_state=self.library.STATE_SPLITTING_VOLUME_CLONE) 

1336 

1337 result = self.library._create_from_snapshot_continue(fake.SHARE, 

1338 fake.SHARE_SERVER) 

1339 fake.SHARE['share_server'] = fake.SHARE_SERVER 

1340 self.mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1341 'source_share') 

1342 self.mock_dm_backend.assert_called_once_with(self.fake_src_share) 

1343 self.mock_extract_host.assert_has_calls([ 

1344 mock.call(fake.SHARE['host'], level='pool')]) 

1345 self.mock_dm_get_src_client.assert_called_once_with( 

1346 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1347 self.mock_get_vserver.assert_called_once_with(fake.SHARE_SERVER) 

1348 self.mock_split_completed.assert_called_once_with( 

1349 self.fake_src_share, self.src_vserver_client) 

1350 self.mock_get_backend_qos_name.assert_called_once_with(fake.SHARE_ID) 

1351 self.mock_mark_qos_deletion.assert_called_once_with( 

1352 fake.QOS_POLICY_GROUP_NAME) 

1353 self.mock_rehost_vol.assert_called_once_with( 

1354 fake.SHARE, fake.VSERVER1, self.src_vserver_client, 

1355 fake.VSERVER2, self.dest_vserver_client) 

1356 if src_host != fake.MANILA_HOST_NAME: 

1357 expected_result = { 

1358 'status': constants.STATUS_CREATING_FROM_SNAPSHOT 

1359 } 

1360 self.mock_move_vol.assert_called_once_with( 

1361 self.fake_src_share, fake.SHARE, fake.SHARE_SERVER, 

1362 cutover_action='defer') 

1363 self.fake_src_share['internal_state'] = ( 

1364 self.library.STATE_MOVING_VOLUME) 

1365 self.mock_pvt_storage_update.assert_called_once_with( 

1366 fake.SHARE['id'], 

1367 {'source_share': json.dumps(self.fake_src_share)} 

1368 ) 

1369 self.assertEqual(expected_result, result) 

1370 else: 

1371 self.mock_get_extra_specs_qos.assert_called_once_with(fake.SHARE) 

1372 self.mock__get_provisioning_opts.assert_called_once_with( 

1373 fake.EXTRA_SPEC_WITH_QOS) 

1374 self.mock_modify_create_qos.assert_called_once_with( 

1375 fake.SHARE, fake.EXTRA_SPEC_WITH_QOS, fake.VSERVER2, 

1376 self.dest_vserver_client) 

1377 self.mock_get_backend_shr_name.assert_called_once_with( 

1378 fake.SHARE_ID) 

1379 self.mock_modify_vol.assert_called_once_with( 

1380 fake.POOL_NAME, fake.SHARE_NAME, 

1381 **fake.PROVISIONING_OPTIONS_WITH_QOS) 

1382 self.mock_pvt_storage_delete.assert_called_once_with( 

1383 fake.SHARE['id']) 

1384 self.mock_create_export.assert_called_once_with( 

1385 fake.SHARE, fake.SHARE_SERVER, fake.VSERVER2, 

1386 self.dest_vserver_client, clear_current_export_policy=False) 

1387 expected_result = { 

1388 'status': constants.STATUS_AVAILABLE, 

1389 'export_locations': self.fake_export_location, 

1390 } 

1391 self.assertEqual(expected_result, result) 

1392 

1393 @ddt.data(True, False) 

1394 def test__create_from_snapshot_continue_state_moving(self, move_completed): 

1395 self._setup_mocks_for_create_from_snapshot_continue( 

1396 share_internal_state=self.library.STATE_MOVING_VOLUME, 

1397 move_completed_result=move_completed) 

1398 

1399 result = self.library._create_from_snapshot_continue(fake.SHARE, 

1400 fake.SHARE_SERVER) 

1401 expect_result = { 

1402 'status': constants.STATUS_CREATING_FROM_SNAPSHOT 

1403 } 

1404 fake.SHARE['share_server'] = fake.SHARE_SERVER 

1405 self.mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1406 'source_share') 

1407 self.mock_dm_backend.assert_called_once_with(self.fake_src_share) 

1408 self.mock_extract_host.assert_has_calls([ 

1409 mock.call(fake.SHARE['host'], level='pool'), 

1410 ]) 

1411 self.mock_dm_get_src_client.assert_called_once_with( 

1412 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1413 self.mock_get_vserver.assert_called_once_with(fake.SHARE_SERVER) 

1414 

1415 self.mock_move_completed.assert_called_once_with( 

1416 fake.SHARE, fake.SHARE_SERVER) 

1417 if move_completed: 

1418 expect_result['status'] = constants.STATUS_AVAILABLE 

1419 self.mock_pvt_storage_delete.assert_called_once_with( 

1420 fake.SHARE['id']) 

1421 self.mock_create_export.assert_called_once_with( 

1422 fake.SHARE, fake.SHARE_SERVER, fake.VSERVER2, 

1423 self.dest_vserver_client, clear_current_export_policy=False) 

1424 expect_result['export_locations'] = self.fake_export_location 

1425 self.assertEqual(expect_result, result) 

1426 else: 

1427 self.mock_pvt_storage_update.assert_called_once_with( 

1428 fake.SHARE['id'], 

1429 {'source_share': json.dumps(self.fake_src_share)} 

1430 ) 

1431 self.assertEqual(expect_result, result) 

1432 

1433 @ddt.data({'replica_state': 'in_sync', 'is_flexgroup': False}, 

1434 {'replica_state': 'out_of_sync', 'is_flexgroup': False}, 

1435 {'replica_state': 'out_of_sync', 'is_flexgroup': True}) 

1436 @ddt.unpack 

1437 def test__create_from_snapshot_continue_state_snapmirror(self, 

1438 replica_state, 

1439 is_flexgroup): 

1440 self._setup_mocks_for_create_from_snapshot_continue( 

1441 share_internal_state=self.library.STATE_SNAPMIRROR_DATA_COPYING, 

1442 replica_state=replica_state, is_flexgroup=is_flexgroup) 

1443 

1444 result = self.library._create_from_snapshot_continue(fake.SHARE, 

1445 fake.SHARE_SERVER) 

1446 expect_result = { 

1447 'status': constants.STATUS_CREATING_FROM_SNAPSHOT 

1448 } 

1449 fake.SHARE['share_server'] = fake.SHARE_SERVER 

1450 self.mock_pvt_storage_get.assert_called_once_with(fake.SHARE['id'], 

1451 'source_share') 

1452 self.mock_dm_backend.assert_called_once_with(self.fake_src_share) 

1453 self.mock_extract_host.assert_has_calls([ 

1454 mock.call(fake.SHARE['host'], level='pool')]) 

1455 self.mock_dm_get_src_client.assert_called_once_with( 

1456 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

1457 self.mock_get_vserver.assert_called_once_with(fake.SHARE_SERVER) 

1458 

1459 self.mock_update_rep_state.assert_called_once_with( 

1460 None, [self.fake_src_share], fake.SHARE, [], [], fake.SHARE_SERVER, 

1461 replication=False 

1462 ) 

1463 self.assertEqual(is_flexgroup, 

1464 self.mock_get_flexgroup_aggregate_list.called) 

1465 if replica_state == constants.REPLICA_STATE_IN_SYNC: 

1466 self.mock_update_snapmirror.assert_called_once_with( 

1467 self.fake_src_share, fake.SHARE) 

1468 self.mock_break_snapmirror.assert_called_once_with( 

1469 self.fake_src_share, fake.SHARE) 

1470 self.mock_delete_snapmirror.assert_called_once_with( 

1471 self.fake_src_share, fake.SHARE) 

1472 self.mock_get_backend_shr_name.assert_has_calls( 

1473 [mock.call(self.fake_src_share['id']), 

1474 mock.call(fake.SHARE_ID)]) 

1475 self.mock__delete_share.assert_called_once_with( 

1476 self.fake_src_share, fake.VSERVER1, self.src_vserver_client, 

1477 remove_export=False) 

1478 self.mock_set_vol_size_fixes.assert_called_once_with( 

1479 fake.SHARE_NAME, filesys_size_fixed=False) 

1480 self.mock_get_extra_specs_qos.assert_called_once_with(fake.SHARE) 

1481 self.mock__get_provisioning_opts.assert_called_once_with( 

1482 fake.EXTRA_SPEC_WITH_QOS) 

1483 self.mock_modify_create_qos.assert_called_once_with( 

1484 fake.SHARE, fake.EXTRA_SPEC_WITH_QOS, fake.VSERVER2, 

1485 self.dest_vserver_client) 

1486 self.mock_modify_vol.assert_called_once_with( 

1487 fake.POOL_NAME, fake.SHARE_NAME, 

1488 **fake.PROVISIONING_OPTIONS_WITH_QOS) 

1489 expect_result['status'] = constants.STATUS_AVAILABLE 

1490 self.mock_pvt_storage_delete.assert_called_once_with( 

1491 fake.SHARE['id']) 

1492 self.mock_create_export.assert_called_once_with( 

1493 fake.SHARE, fake.SHARE_SERVER, fake.VSERVER2, 

1494 self.dest_vserver_client, clear_current_export_policy=False) 

1495 expect_result['export_locations'] = self.fake_export_location 

1496 self.assertEqual(expect_result, result) 

1497 elif replica_state not in [constants.STATUS_ERROR, None]: 1497 ↛ exitline 1497 didn't return from function 'test__create_from_snapshot_continue_state_snapmirror' because the condition on line 1497 was always true

1498 self.mock_pvt_storage_update.assert_called_once_with( 

1499 fake.SHARE['id'], 

1500 {'source_share': json.dumps(self.fake_src_share)} 

1501 ) 

1502 self.assertEqual(expect_result, result) 

1503 

1504 def test__create_from_snapshot_continue_state_unknown(self): 

1505 self._setup_mocks_for_create_from_snapshot_continue( 

1506 share_internal_state='unknown_state') 

1507 

1508 self.assertRaises(exception.NetAppException, 

1509 self.library._create_from_snapshot_continue, 

1510 fake.SHARE, 

1511 fake.SHARE_SERVER) 

1512 

1513 self.mock_pvt_storage_delete.assert_called_once_with(fake.SHARE_ID) 

1514 

1515 @ddt.data({'hide_snapdir': False, 'create_fpolicy': True, 'is_fg': True, 

1516 'with_encryption': True}, 

1517 {'hide_snapdir': True, 'create_fpolicy': False, 'is_fg': True, 

1518 'with_encryption': False}, 

1519 {'hide_snapdir': False, 'create_fpolicy': True, 'is_fg': False, 

1520 'with_encryption': True}, 

1521 {'hide_snapdir': True, 'create_fpolicy': False, 'is_fg': False, 

1522 'with_encryption': False}) 

1523 @ddt.unpack 

1524 def test_allocate_container(self, hide_snapdir, create_fpolicy, is_fg, 

1525 with_encryption): 

1526 

1527 provisioning_options = copy.deepcopy( 

1528 fake.PROVISIONING_OPTIONS_WITH_FPOLICY) 

1529 provisioning_options['hide_snapdir'] = hide_snapdir 

1530 provisioning_options['snaplock_type'] = "compliance" 

1531 self.mock_object(self.library, '_get_backend_share_name', mock.Mock( 

1532 return_value=fake.SHARE_NAME)) 

1533 self.mock_object(share_utils, 'extract_host', mock.Mock( 

1534 return_value=fake.POOL_NAME)) 

1535 mock_get_provisioning_opts = self.mock_object( 

1536 self.library, '_get_provisioning_options_for_share', 

1537 mock.Mock(return_value=provisioning_options)) 

1538 mock_create_fpolicy = self.mock_object( 

1539 self.library, '_create_fpolicy_for_share') 

1540 self.mock_object( 

1541 self.library, '_is_flexgroup_pool', mock.Mock(return_value=is_fg)) 

1542 mock_create_flexgroup = self.mock_object(self.library, 

1543 '_create_flexgroup_share') 

1544 mock_get_aggr_flexgroup = self.mock_object( 

1545 self.library, '_get_flexgroup_aggregate_list', 

1546 mock.Mock(return_value=[fake.AGGREGATE])) 

1547 vserver_client = mock.Mock() 

1548 

1549 fake_share = ( 

1550 fake.SHARE_INSTANCE_WITH_ENCRYPTION 

1551 if with_encryption else fake.SHARE_INSTANCE) 

1552 

1553 self.library._allocate_container(fake_share, 

1554 fake.VSERVER1, 

1555 vserver_client, 

1556 create_fpolicy=create_fpolicy) 

1557 

1558 mock_get_provisioning_opts.assert_called_once_with( 

1559 fake_share, fake.VSERVER1, vserver_client=vserver_client, 

1560 set_qos=True) 

1561 

1562 if is_fg: 

1563 mock_get_aggr_flexgroup.assert_called_once_with(fake.POOL_NAME) 

1564 mock_create_flexgroup.assert_called_once_with( 

1565 vserver_client, [fake.AGGREGATE], fake.SHARE_NAME, 

1566 fake.SHARE['size'], 8, mount_point_name=fake.MOUNT_POINT_NAME, 

1567 **provisioning_options) 

1568 else: 

1569 mock_get_aggr_flexgroup.assert_not_called() 

1570 vserver_client.create_volume.assert_called_once_with( 

1571 fake.POOL_NAME, fake.SHARE_NAME, fake.SHARE['size'], 

1572 snapshot_reserve=8, mount_point_name=fake.MOUNT_POINT_NAME, 

1573 **provisioning_options) 

1574 

1575 if hide_snapdir: 

1576 vserver_client.set_volume_snapdir_access.assert_called_once_with( 

1577 fake.SHARE_NAME, hide_snapdir) 

1578 else: 

1579 vserver_client.set_volume_snapdir_access.assert_not_called() 

1580 

1581 if create_fpolicy: 

1582 mock_create_fpolicy.assert_called_once_with( 

1583 fake_share, fake.VSERVER1, vserver_client, 

1584 **provisioning_options) 

1585 else: 

1586 mock_create_fpolicy.assert_not_called() 

1587 

1588 def test_remap_standard_boolean_extra_specs(self): 

1589 

1590 extra_specs = copy.deepcopy(fake.OVERLAPPING_EXTRA_SPEC) 

1591 

1592 result = self.library._remap_standard_boolean_extra_specs(extra_specs) 

1593 

1594 self.assertDictEqual(fake.REMAPPED_OVERLAPPING_EXTRA_SPEC, result) 

1595 

1596 def test_allocate_container_as_replica(self): 

1597 self.mock_object(self.library, '_get_backend_share_name', mock.Mock( 

1598 return_value=fake.SHARE_NAME)) 

1599 self.mock_object(share_utils, 'extract_host', mock.Mock( 

1600 return_value=fake.POOL_NAME)) 

1601 mock_get_provisioning_opts = self.mock_object( 

1602 self.library, '_get_provisioning_options_for_share', 

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

1604 vserver_client = mock.Mock() 

1605 

1606 self.library._allocate_container(fake.SHARE_INSTANCE, fake.VSERVER1, 

1607 vserver_client, replica=True) 

1608 

1609 mock_get_provisioning_opts.assert_called_once_with( 

1610 fake.SHARE_INSTANCE, fake.VSERVER1, vserver_client=vserver_client, 

1611 set_qos=True) 

1612 

1613 vserver_client.create_volume.assert_called_once_with( 

1614 fake.POOL_NAME, fake.SHARE_NAME, fake.SHARE['size'], 

1615 thin_provisioned=True, snapshot_policy='default', 

1616 language='en-US', dedup_enabled=True, split=True, 

1617 compression_enabled=False, max_files=5000, encrypt=False, 

1618 snapshot_reserve=8, mount_point_name=fake.MOUNT_POINT_NAME, 

1619 volume_type='dp', adaptive_qos_policy_group=None) 

1620 

1621 def test_allocate_container_no_pool_name(self): 

1622 self.mock_object(self.library, '_get_backend_share_name', mock.Mock( 

1623 return_value=fake.SHARE_NAME)) 

1624 self.mock_object(share_utils, 'extract_host', mock.Mock( 

1625 return_value=None)) 

1626 self.mock_object(self.library, '_check_extra_specs_validity') 

1627 self.mock_object(self.library, '_get_provisioning_options') 

1628 vserver_client = mock.Mock() 

1629 

1630 self.assertRaises(exception.InvalidHost, 

1631 self.library._allocate_container, 

1632 fake.SHARE_INSTANCE, fake.VSERVER1, vserver_client) 

1633 

1634 self.library._get_backend_share_name.assert_called_once_with( 

1635 fake.SHARE_INSTANCE['id']) 

1636 share_utils.extract_host.assert_called_once_with( 

1637 fake.SHARE_INSTANCE['host'], level='pool') 

1638 self.assertEqual(0, 

1639 self.library._check_extra_specs_validity.call_count) 

1640 self.assertEqual(0, self.library._get_provisioning_options.call_count) 

1641 

1642 @ddt.data(None, 1000) 

1643 def test_create_flexgroup_share(self, max_files): 

1644 self.library.configuration.netapp_flexgroup_volume_online_timeout = 2 

1645 vserver_client = mock.Mock() 

1646 vserver_client.get_job_state.return_value = "success" 

1647 mock_wait_for_start = self.mock_object( 

1648 self.library, 'wait_for_start_create_flexgroup', 

1649 mock.Mock(return_value={'jobid': fake.JOB_ID, 'error-code': None})) 

1650 mock_wait_for_flexgroup_deployment = self.mock_object( 

1651 self.library, 'wait_for_flexgroup_deployment') 

1652 aggr_list = [fake.AGGREGATE] 

1653 options = {'efficiency_policy': fake.VOLUME_EFFICIENCY_POLICY_NAME} 

1654 self.library._create_flexgroup_share(vserver_client, aggr_list, 

1655 fake.SHARE_NAME, 100, 10, 

1656 max_files=max_files, 

1657 snaplock_type="compliance", 

1658 **options) 

1659 start_timeout = (self.library.configuration. 

1660 netapp_flexgroup_aggregate_not_busy_timeout) 

1661 mock_wait_for_start.assert_called_once_with( 

1662 start_timeout, vserver_client, aggr_list, fake.SHARE_NAME, 100, 

1663 10, None, "compliance", 

1664 efficiency_policy=fake.VOLUME_EFFICIENCY_POLICY_NAME) 

1665 mock_wait_for_flexgroup_deployment.assert_called_once_with( 

1666 vserver_client, fake.JOB_ID, 2) 

1667 vserver_client.update_volume_efficiency_attributes.assert_called_once_with( # noqa 

1668 fake.SHARE_NAME, False, False, 

1669 is_flexgroup=True, 

1670 efficiency_policy=fake.VOLUME_EFFICIENCY_POLICY_NAME 

1671 ) 

1672 if max_files: 

1673 vserver_client.set_volume_max_files.assert_called_once_with( 

1674 fake.SHARE_NAME, max_files) 

1675 else: 

1676 self.assertFalse(vserver_client.set_volume_max_files.called) 

1677 

1678 @ddt.data( 

1679 {'jobid': fake.JOB_ID, 'error-code': 'fake', 'error-message': 'fake'}, 

1680 {'jobid': None, 'error-code': None, 'error-message': 'fake'}) 

1681 def test_create_flexgroup_share_raise_error_job(self, job): 

1682 vserver_client = mock.Mock() 

1683 self.mock_object(self.library, 'wait_for_start_create_flexgroup', 

1684 mock.Mock(return_value=job)) 

1685 aggr_list = [fake.AGGREGATE] 

1686 

1687 self.assertRaises( 

1688 exception.NetAppException, self.library._create_flexgroup_share, 

1689 vserver_client, aggr_list, fake.SHARE_NAME, 100, 10) 

1690 

1691 def test_wait_for_start_create_flexgroup(self): 

1692 vserver_client = mock.Mock() 

1693 job = {'jobid': fake.JOB_ID, 'error-code': None} 

1694 vserver_client.create_volume_async.return_value = job 

1695 aggr_list = [fake.AGGREGATE] 

1696 

1697 result = self.library.wait_for_start_create_flexgroup( 

1698 20, vserver_client, aggr_list, fake.SHARE_NAME, 1, 10, 

1699 fake.MOUNT_POINT_NAME, "compliance") 

1700 

1701 self.assertEqual(job, result) 

1702 vserver_client.create_volume_async.assert_called_once_with( 

1703 aggr_list, fake.SHARE_NAME, 1, is_flexgroup=True, 

1704 snapshot_reserve=10, 

1705 auto_provisioned=self.library._is_flexgroup_auto, 

1706 mount_point_name=fake.MOUNT_POINT_NAME, 

1707 snaplock_type="compliance") 

1708 

1709 def test_wait_for_start_create_flexgroup_timeout(self): 

1710 vserver_client = mock.Mock() 

1711 vserver_client.create_volume_async.side_effect = ( 

1712 netapp_api.NaApiError(code=netapp_api.EAPIERROR, 

1713 message="try the command again")) 

1714 aggr_list = [fake.AGGREGATE] 

1715 

1716 self.assertRaises( 

1717 exception.NetAppException, 

1718 self.library.wait_for_start_create_flexgroup, 10, 

1719 vserver_client, aggr_list, fake.SHARE_NAME, 1, 10, 

1720 fake.MOUNT_POINT_NAME, "compliance") 

1721 

1722 def test_wait_for_flexgroup_deployment(self): 

1723 vserver_client = mock.Mock() 

1724 vserver_client.get_job_state.return_value = 'success' 

1725 

1726 result = self.library.wait_for_flexgroup_deployment( 

1727 vserver_client, fake.JOB_ID, 20) 

1728 

1729 self.assertIsNone(result) 

1730 vserver_client.get_job_state.assert_called_once_with(fake.JOB_ID) 

1731 

1732 def test_wait_for_flexgroup_deployment_timeout(self): 

1733 vserver_client = mock.Mock() 

1734 vserver_client.get_job_state.return_value = 'queued' 

1735 

1736 self.assertRaises( 

1737 exception.NetAppException, 

1738 self.library.wait_for_flexgroup_deployment, 

1739 vserver_client, fake.JOB_ID, 10) 

1740 

1741 @ddt.data('failure', 'error') 

1742 def test_wai_for_flexgroup_deployment_job_error(self, error_state): 

1743 vserver_client = mock.Mock() 

1744 vserver_client.get_job_state.return_value = error_state 

1745 

1746 self.assertRaises( 

1747 exception.NetAppException, 

1748 self.library.wait_for_flexgroup_deployment, 

1749 vserver_client, fake.JOB_ID, 10) 

1750 

1751 def test_check_extra_specs_validity(self): 

1752 boolean_extra_spec_keys = list( 

1753 self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP) 

1754 mock_bool_check = self.mock_object( 

1755 self.library, '_check_boolean_extra_specs_validity') 

1756 mock_string_check = self.mock_object( 

1757 self.library, '_check_string_extra_specs_validity') 

1758 

1759 self.library._check_extra_specs_validity( 

1760 fake.SHARE_INSTANCE, fake.EXTRA_SPEC) 

1761 

1762 mock_bool_check.assert_called_once_with( 

1763 fake.SHARE_INSTANCE, fake.EXTRA_SPEC, boolean_extra_spec_keys) 

1764 mock_string_check.assert_called_once_with( 

1765 fake.SHARE_INSTANCE, fake.EXTRA_SPEC) 

1766 

1767 def test_check_extra_specs_validity_empty_spec(self): 

1768 result = self.library._check_extra_specs_validity( 

1769 fake.SHARE_INSTANCE, fake.EMPTY_EXTRA_SPEC) 

1770 

1771 self.assertIsNone(result) 

1772 

1773 def test_check_extra_specs_validity_invalid_value(self): 

1774 self.assertRaises( 

1775 exception.Invalid, self.library._check_extra_specs_validity, 

1776 fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC) 

1777 

1778 def test_check_string_extra_specs_validity(self): 

1779 result = self.library._check_string_extra_specs_validity( 

1780 fake.SHARE_INSTANCE, fake.EXTRA_SPEC_WITH_FPOLICY) 

1781 

1782 self.assertIsNone(result) 

1783 

1784 def test_check_string_extra_specs_validity_empty_spec(self): 

1785 result = self.library._check_string_extra_specs_validity( 

1786 fake.SHARE_INSTANCE, fake.EMPTY_EXTRA_SPEC) 

1787 

1788 self.assertIsNone(result) 

1789 

1790 def test_check_string_extra_specs_validity_invalid_value(self): 

1791 self.assertRaises( 

1792 exception.NetAppException, 

1793 self.library._check_string_extra_specs_validity, 

1794 fake.SHARE_INSTANCE, fake.INVALID_MAX_FILE_EXTRA_SPEC) 

1795 

1796 def test_check_boolean_extra_specs_validity_invalid_value(self): 

1797 self.assertRaises( 

1798 exception.Invalid, 

1799 self.library._check_boolean_extra_specs_validity, 

1800 fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC, 

1801 list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)) 

1802 

1803 def test_check_extra_specs_validity_invalid_combination(self): 

1804 self.assertRaises( 

1805 exception.Invalid, 

1806 self.library._check_boolean_extra_specs_validity, 

1807 fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC_COMBO, 

1808 list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)) 

1809 

1810 @ddt.data({'extra_specs': fake.EXTRA_SPEC, 'set_qos': True}, 

1811 {'extra_specs': fake.EXTRA_SPEC_WITH_QOS, 'set_qos': False}, 

1812 {'extra_specs': fake.EXTRA_SPEC, 'set_qos': True}, 

1813 {'extra_specs': fake.EXTRA_SPEC_WITH_QOS, 'set_qos': False}) 

1814 @ddt.unpack 

1815 def test_get_provisioning_options_for_share(self, extra_specs, set_qos): 

1816 

1817 qos = True if fake.QOS_MAX_EXTRA_SPEC in extra_specs else False 

1818 vserver_client = mock.Mock() 

1819 self.library._have_cluster_creds = True 

1820 mock_get_extra_specs_from_share = self.mock_object( 

1821 share_types, 'get_extra_specs_from_share', 

1822 mock.Mock(return_value=extra_specs)) 

1823 mock_remap_standard_boolean_extra_specs = self.mock_object( 

1824 self.library, '_remap_standard_boolean_extra_specs', 

1825 mock.Mock(return_value=extra_specs)) 

1826 mock_check_extra_specs_validity = self.mock_object( 

1827 self.library, '_check_extra_specs_validity') 

1828 mock_get_provisioning_options = self.mock_object( 

1829 self.library, '_get_provisioning_options', 

1830 mock.Mock(return_value=fake.PROVISIONING_OPTIONS)) 

1831 mock_get_normalized_qos_specs = self.mock_object( 

1832 self.library, '_get_normalized_qos_specs', 

1833 mock.Mock(return_value={fake.QOS_NORMALIZED_SPEC: 3000})) 

1834 mock_create_qos_policy_group = self.mock_object( 

1835 self.library, '_create_qos_policy_group', mock.Mock( 

1836 return_value=fake.QOS_POLICY_GROUP_NAME)) 

1837 

1838 result = self.library._get_provisioning_options_for_share( 

1839 fake.SHARE_INSTANCE, fake.VSERVER1, vserver_client=vserver_client, 

1840 set_qos=set_qos) 

1841 

1842 if qos and not set_qos: 

1843 expected_provisioning_opts = fake.PROVISIONING_OPTIONS 

1844 self.assertFalse(mock_create_qos_policy_group.called) 

1845 else: 

1846 expected_provisioning_opts = fake.PROVISIONING_OPTIONS_WITH_QOS 

1847 mock_create_qos_policy_group.assert_called_once_with( 

1848 fake.SHARE_INSTANCE, fake.VSERVER1, 

1849 {fake.QOS_NORMALIZED_SPEC: 3000}, vserver_client) 

1850 

1851 self.assertEqual(expected_provisioning_opts, result) 

1852 mock_get_extra_specs_from_share.assert_called_once_with( 

1853 fake.SHARE_INSTANCE) 

1854 mock_remap_standard_boolean_extra_specs.assert_called_once_with( 

1855 extra_specs) 

1856 mock_check_extra_specs_validity.assert_called_once_with( 

1857 fake.SHARE_INSTANCE, extra_specs) 

1858 mock_get_provisioning_options.assert_called_once_with(extra_specs) 

1859 mock_get_normalized_qos_specs.assert_called_once_with(extra_specs) 

1860 

1861 def test_get_provisioning_options_for_share_qos_conflict(self): 

1862 vserver_client = mock.Mock() 

1863 extra_specs = fake.EXTRA_SPEC_WITH_QOS 

1864 mock_get_extra_specs_from_share = self.mock_object( 

1865 share_types, 'get_extra_specs_from_share', 

1866 mock.Mock(return_value=extra_specs)) 

1867 mock_remap_standard_boolean_extra_specs = self.mock_object( 

1868 self.library, '_remap_standard_boolean_extra_specs', 

1869 mock.Mock(return_value=extra_specs)) 

1870 mock_check_extra_specs_validity = self.mock_object( 

1871 self.library, '_check_extra_specs_validity') 

1872 mock_get_provisioning_options = self.mock_object( 

1873 self.library, '_get_provisioning_options', 

1874 mock.Mock(return_value=fake.PROVISIONING_OPTS_WITH_ADAPT_QOS)) 

1875 mock_get_normalized_qos_specs = self.mock_object( 

1876 self.library, '_get_normalized_qos_specs', 

1877 mock.Mock(return_value={fake.QOS_NORMALIZED_SPEC: 3000})) 

1878 

1879 self.assertRaises(exception.NetAppException, 

1880 self.library._get_provisioning_options_for_share, 

1881 fake.SHARE_INSTANCE, fake.VSERVER1, 

1882 vserver_client=vserver_client, 

1883 set_qos=True) 

1884 

1885 mock_get_extra_specs_from_share.assert_called_once_with( 

1886 fake.SHARE_INSTANCE) 

1887 mock_remap_standard_boolean_extra_specs.assert_called_once_with( 

1888 extra_specs) 

1889 mock_check_extra_specs_validity.assert_called_once_with( 

1890 fake.SHARE_INSTANCE, extra_specs) 

1891 mock_get_provisioning_options.assert_called_once_with(extra_specs) 

1892 mock_get_normalized_qos_specs.assert_called_once_with(extra_specs) 

1893 

1894 def test_get_provisioning_options_implicit_false(self): 

1895 result = self.library._get_provisioning_options( 

1896 fake.EMPTY_EXTRA_SPEC) 

1897 

1898 expected = { 

1899 'adaptive_qos_policy_group': None, 

1900 'language': None, 

1901 'max_files': None, 

1902 'max_files_multiplier': None, 

1903 'snapshot_policy': None, 

1904 'thin_provisioned': False, 

1905 'compression_enabled': False, 

1906 'dedup_enabled': False, 

1907 'split': False, 

1908 'encrypt': False, 

1909 'hide_snapdir': False, 

1910 'fpolicy_extensions_to_exclude': None, 

1911 'fpolicy_extensions_to_include': None, 

1912 'fpolicy_file_operations': None, 

1913 'efficiency_policy': None, 

1914 'snaplock_type': None, 

1915 'snaplock_autocommit_period': None, 

1916 'snaplock_min_retention_period': None, 

1917 'snaplock_max_retention_period': None, 

1918 'snaplock_default_retention_period': None, 

1919 } 

1920 

1921 self.assertEqual(expected, result) 

1922 

1923 def test_get_boolean_provisioning_options(self): 

1924 result = self.library._get_boolean_provisioning_options( 

1925 fake.SHORT_BOOLEAN_EXTRA_SPEC, 

1926 self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP) 

1927 

1928 self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result) 

1929 

1930 def test_get_boolean_provisioning_options_missing_spec(self): 

1931 result = self.library._get_boolean_provisioning_options( 

1932 fake.SHORT_BOOLEAN_EXTRA_SPEC, 

1933 self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP) 

1934 

1935 self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result) 

1936 

1937 def test_get_boolean_provisioning_options_implicit_false(self): 

1938 expected = { 

1939 'thin_provisioned': False, 

1940 'dedup_enabled': False, 

1941 'compression_enabled': False, 

1942 'split': False, 

1943 'hide_snapdir': False, 

1944 } 

1945 

1946 result = self.library._get_boolean_provisioning_options( 

1947 fake.EMPTY_EXTRA_SPEC, 

1948 self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP) 

1949 

1950 self.assertEqual(expected, result) 

1951 

1952 def test_get_string_provisioning_options(self): 

1953 result = self.library.get_string_provisioning_options( 

1954 fake.STRING_EXTRA_SPEC, 

1955 self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP) 

1956 

1957 self.assertEqual(fake.PROVISIONING_OPTIONS_STRING, result) 

1958 

1959 def test_get_string_provisioning_options_missing_spec(self): 

1960 result = self.library.get_string_provisioning_options( 

1961 fake.SHORT_STRING_EXTRA_SPEC, 

1962 self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP) 

1963 

1964 self.assertEqual(fake.PROVISIONING_OPTIONS_STRING_MISSING_SPECS, 

1965 result) 

1966 

1967 def test_get_string_provisioning_options_implicit_false(self): 

1968 result = self.library.get_string_provisioning_options( 

1969 fake.EMPTY_EXTRA_SPEC, 

1970 self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP) 

1971 

1972 self.assertEqual(fake.PROVISIONING_OPTIONS_STRING_DEFAULT, result) 

1973 

1974 @ddt.data({}, {'foo': 'bar'}, {'netapp:maxiops': '3000'}, 

1975 {'qos': True, 'netapp:absiops': '3000'}, 

1976 {'qos': True, 'netapp:maxiops:': '3000'}) 

1977 def test_get_normalized_qos_specs_no_qos_specs(self, extra_specs): 

1978 if 'qos' in extra_specs: 

1979 self.assertRaises(exception.NetAppException, 

1980 self.library._get_normalized_qos_specs, 

1981 extra_specs) 

1982 else: 

1983 self.assertDictEqual( 

1984 {}, self.library._get_normalized_qos_specs(extra_specs)) 

1985 

1986 @ddt.data({'qos': True, 'netapp:maxiops': '3000', 'netapp:maxbps': '9000'}, 

1987 {'qos': True, 'netapp:maxiopspergib': '1000', 

1988 'netapp:maxiops': '1000'}) 

1989 def test_get_normalized_qos_specs_multiple_max_qos_specs(self, 

1990 extra_specs): 

1991 self.assertRaises(exception.NetAppException, 

1992 self.library._get_normalized_qos_specs, 

1993 extra_specs) 

1994 

1995 @ddt.data({'qos': True, 'netapp:miniops': '1000', 'netapp:minbps': '1000'}, 

1996 {'qos': True, 'netapp:miniopspergib': '1000', 

1997 'netapp:miniops': '1000'}) 

1998 def test_get_normalized_qos_specs_multiple_min_qos_specs(self, 

1999 extra_specs): 

2000 self.assertRaises(exception.NetAppException, 

2001 self.library._get_normalized_qos_specs, 

2002 extra_specs) 

2003 

2004 @ddt.data({'qos': True, 'netapp:maxIOPS': '3000'}, 

2005 {'qos': True, 'netapp:MAxBPs': '3000', 'clem': 'son'}, 

2006 {'qos': True, 'netapp:maxbps': '3000', 'tig': 'ers'}, 

2007 {'qos': True, 'netapp:MAXiopSPerGib': '3000', 'kin': 'gsof'}, 

2008 {'qos': True, 'netapp:maxiopspergib': '3000', 'coll': 'ege'}, 

2009 {'qos': True, 'netapp:maxBPSperGiB': '3000', 'foot': 'ball'}, 

2010 {'qos': True, 'netapp:minIOPS': '3000'}, 

2011 {'qos': True, 'netapp:MinBPs': '3000', 'clem': 'son'}, 

2012 {'qos': True, 'netapp:Minbps': '3000', 'tig': 'ers'}, 

2013 {'qos': True, 'netapp:MINiopSPerGib': '3000', 'kin': 'gsof'}, 

2014 {'qos': True, 'netapp:MINbpSPerGib': '3000', 'kin': 'gsof'}) 

2015 def test_get_normalized_qos_specs(self, extra_specs): 

2016 expected_normalized_spec = { 

2017 key.lower().split('netapp:')[1]: value 

2018 for key, value in extra_specs.items() if 'netapp:' in key 

2019 } 

2020 

2021 qos_specs = self.library._get_normalized_qos_specs(extra_specs) 

2022 

2023 self.assertDictEqual(expected_normalized_spec, qos_specs) 

2024 self.assertEqual(1, len(qos_specs)) 

2025 

2026 @ddt.data({'qos': {'maxiops': '3000'}, 'expected': '3000iops'}, 

2027 {'qos': {'maxbps': '3000'}, 'expected': '3000B/s'}, 

2028 {'qos': {'maxbpspergib': '3000'}, 'expected': '12000B/s'}, 

2029 {'qos': {'maxiopspergib': '3000'}, 'expected': '12000iops'}) 

2030 @ddt.unpack 

2031 def test_get_max_throughput(self, qos, expected): 

2032 

2033 throughput = self.library._get_max_throughput(4, qos) 

2034 

2035 self.assertEqual(expected, throughput) 

2036 

2037 @ddt.data({'qos': {'miniops': '1000'}, 'expected': '1000iops'}, 

2038 {'qos': {'minbps': '1000'}, 'expected': '1000B/s'}, 

2039 {'qos': {'minbpspergib': '1000'}, 'expected': '4000B/s'}, 

2040 {'qos': {'miniopspergib': '1000'}, 'expected': '4000iops'}) 

2041 @ddt.unpack 

2042 def test_get_min_throughput(self, qos, expected): 

2043 

2044 throughput = self.library._get_min_throughput(4, qos) 

2045 

2046 self.assertEqual(expected, throughput) 

2047 

2048 def test_create_qos_policy_group(self): 

2049 mock_qos_policy_create = self.mock_object( 

2050 self.library._client, 'qos_policy_group_create') 

2051 

2052 self.library._create_qos_policy_group( 

2053 fake.SHARE, fake.VSERVER1, {'maxiops': '3000'}) 

2054 

2055 expected_policy_name = 'qos_share_' + fake.SHARE['id'].replace( 

2056 '-', '_') 

2057 mock_qos_policy_create.assert_called_once_with( 

2058 expected_policy_name, fake.VSERVER1, max_throughput='3000iops', 

2059 min_throughput=None) 

2060 

2061 def test_check_if_max_files_is_valid_with_negative_integer(self): 

2062 self.assertRaises(exception.NetAppException, 

2063 self.library._check_if_max_files_is_valid, 

2064 fake.SHARE, -1) 

2065 

2066 def test_check_if_max_files_is_valid_with_string(self): 

2067 self.assertRaises(ValueError, 

2068 self.library._check_if_max_files_is_valid, 

2069 fake.SHARE, 'abc') 

2070 

2071 def test__check_fpolicy_file_operations(self): 

2072 result = self.library._check_fpolicy_file_operations( 

2073 fake.SHARE, fake.FPOLICY_FILE_OPERATIONS) 

2074 

2075 self.assertIsNone(result) 

2076 

2077 def test__check_fpolicy_file_operations_invalid_operation(self): 

2078 invalid_ops = copy.deepcopy(fake.FPOLICY_FILE_OPERATIONS) 

2079 invalid_ops += ',fake_op' 

2080 

2081 self.assertRaises(exception.NetAppException, 

2082 self.library._check_fpolicy_file_operations, 

2083 fake.SHARE, 

2084 invalid_ops) 

2085 

2086 @ddt.data('15minutes', '4hours', "8days", "5months", "2years") 

2087 def test__check_snaplock_attributes_autocommit_period(self, duration): 

2088 result = self.library._check_snaplock_attributes( 

2089 fake.SHARE, "netapp:snaplock_autocommit_period", duration) 

2090 self.assertIsNone(result) 

2091 

2092 @ddt.data('15minutes', '4hours', "8days", "5months", "2years") 

2093 def test__check_snaplock_attributes_min_retention_period(self, duration): 

2094 result = self.library._check_snaplock_attributes( 

2095 fake.SHARE, "netapp:snaplock_min_retention_period", duration) 

2096 self.assertIsNone(result) 

2097 

2098 @ddt.data('15minutes', '4hours', "8days", "5months", "2years", 

2099 "infinite") 

2100 def test__check_snaplock_attributes_max_retention_period(self, duration): 

2101 result = self.library._check_snaplock_attributes( 

2102 fake.SHARE, "netapp:snaplock_max_retention_period", duration) 

2103 self.assertIsNone(result) 

2104 

2105 @ddt.data('15minutes', '4hours', "8days", "5months", "2years", 

2106 "infinite", "min", "max") 

2107 def test__check_snaplock_attributes_default_retention_period(self, 

2108 duration): 

2109 result = self.library._check_snaplock_attributes( 

2110 fake.SHARE, "netapp:snaplock_default_retention_period", duration) 

2111 self.assertIsNone(result) 

2112 

2113 def test__check_snaplock_attributes_autocommit_period_negative(self): 

2114 self.assertRaises(exception.NetAppException, 

2115 self.library._check_snaplock_attributes, 

2116 fake.SHARE, 

2117 "netapp:snaplock_autocommit_period", 

2118 "invalid_period", 

2119 ) 

2120 

2121 def test__check_snaplock_attributes_min_retention_period_negative(self): 

2122 self.assertRaises(exception.NetAppException, 

2123 self.library._check_snaplock_attributes, 

2124 fake.SHARE, 

2125 "netapp:snaplock_min_retention_period", 

2126 "invalid_period", 

2127 ) 

2128 

2129 def test__check_snaplock_attributes_max_retention_period_negative(self): 

2130 self.assertRaises(exception.NetAppException, 

2131 self.library._check_snaplock_attributes, 

2132 fake.SHARE, 

2133 "netapp:snaplock_max_retention_period", 

2134 "invalid_period", 

2135 ) 

2136 

2137 def test__check_snaplock_attributes_default_retention_period_neg(self): 

2138 self.assertRaises(exception.NetAppException, 

2139 self.library._check_snaplock_attributes, 

2140 fake.SHARE, 

2141 "netapp:snaplock_default_retention_period", 

2142 "invalid_period", 

2143 ) 

2144 

2145 def test__check_snaplock_compatibility_true(self): 

2146 self.library._have_cluster_creds = True 

2147 self.library._is_snaplock_compliance_configured = True 

2148 self.mock_object(self.client, 

2149 'list_cluster_nodes', 

2150 mock.Mock(return_value=(["node1", "node2"]))) 

2151 result = self.library._check_snaplock_compatibility() 

2152 self.assertIsNone(result) 

2153 

2154 def test__check_snaplock_compatibility_false(self): 

2155 self.library._have_cluster_creds = True 

2156 self.library._is_snaplock_compliance_configured = False 

2157 self.mock_object(self.client, 

2158 'list_cluster_nodes', 

2159 mock.Mock(return_value=(["node1", "node2"]))) 

2160 self.assertRaises(exception.NetAppException, 

2161 self.library._check_snaplock_compatibility) 

2162 

2163 def test__check_snaplock_compatibility_not_cluster_scope(self): 

2164 self.library._have_cluster_creds = False 

2165 self.library._check_snaplock_compatibility() 

2166 

2167 def test_allocate_container_no_pool(self): 

2168 

2169 vserver_client = mock.Mock() 

2170 fake_share_inst = copy.deepcopy(fake.SHARE_INSTANCE) 

2171 fake_share_inst['host'] = fake_share_inst['host'].split('#')[0] 

2172 

2173 self.assertRaises(exception.InvalidHost, 

2174 self.library._allocate_container, 

2175 fake_share_inst, 

2176 fake.VSERVER1, 

2177 vserver_client) 

2178 

2179 def test_check_aggregate_extra_specs_validity(self): 

2180 

2181 self.library._have_cluster_creds = True 

2182 self.library._ssc_stats = fake.SSC_INFO 

2183 

2184 result = self.library._check_aggregate_extra_specs_validity( 

2185 fake.AGGREGATES[0], fake.EXTRA_SPEC) 

2186 

2187 self.assertIsNone(result) 

2188 

2189 def test_check_aggregate_extra_specs_validity_no_match(self): 

2190 

2191 self.library._have_cluster_creds = True 

2192 self.library._ssc_stats = fake.SSC_INFO 

2193 

2194 self.assertRaises(exception.NetAppException, 

2195 self.library._check_aggregate_extra_specs_validity, 

2196 fake.AGGREGATES[1], 

2197 fake.EXTRA_SPEC) 

2198 

2199 @ddt.data({'provider_location': None, 'size': 50, 'hide_snapdir': True, 

2200 'split': None, 'create_fpolicy': False}, 

2201 {'provider_location': 'fake_location', 'size': 30, 

2202 'hide_snapdir': False, 'split': True, 'create_fpolicy': True}, 

2203 {'provider_location': 'fake_location', 'size': 20, 

2204 'hide_snapdir': True, 'split': False, 'create_fpolicy': True}) 

2205 @ddt.unpack 

2206 def test_allocate_container_from_snapshot( 

2207 self, provider_location, size, hide_snapdir, split, 

2208 create_fpolicy): 

2209 provisioning_options = copy.deepcopy( 

2210 fake.PROVISIONING_OPTIONS_WITH_FPOLICY) 

2211 provisioning_options['hide_snapdir'] = hide_snapdir 

2212 mock_get_provisioning_opts = self.mock_object( 

2213 self.library, '_get_provisioning_options_for_share', 

2214 mock.Mock(return_value=provisioning_options)) 

2215 mock_create_fpolicy = self.mock_object( 

2216 self.library, '_create_fpolicy_for_share') 

2217 

2218 vserver = fake.VSERVER1 

2219 vserver_client = mock.Mock() 

2220 original_snapshot_size = 20 

2221 

2222 fake_share_inst = copy.deepcopy(fake.SHARE_INSTANCE) 

2223 fake_share_inst['size'] = size 

2224 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

2225 fake_snapshot['provider_location'] = provider_location 

2226 fake_snapshot['size'] = original_snapshot_size 

2227 mock_rename_snapshot_and_split_clones = self.mock_object( 

2228 vserver_client, 

2229 'rename_snapshot_and_split_clones' 

2230 ) 

2231 

2232 self.library._allocate_container_from_snapshot( 

2233 fake_share_inst, 

2234 fake_snapshot, 

2235 vserver, 

2236 vserver_client, 

2237 split=split, 

2238 create_fpolicy=create_fpolicy) 

2239 

2240 share_name = self.library._get_backend_share_name( 

2241 fake_share_inst['id']) 

2242 parent_share_name = self.library._get_backend_share_name( 

2243 fake_snapshot['share_id']) 

2244 parent_snapshot_name = self.library._get_backend_snapshot_name( 

2245 fake_snapshot['id']) if not provider_location else 'fake_location' 

2246 mock_get_provisioning_opts.assert_called_once_with( 

2247 fake_share_inst, fake.VSERVER1, vserver_client=vserver_client) 

2248 vserver_client.create_volume_clone.assert_called_once_with( 

2249 share_name, parent_share_name, parent_snapshot_name, 

2250 mount_point_name=fake_share_inst["mount_point_name"], 

2251 **provisioning_options) 

2252 if size > original_snapshot_size: 

2253 vserver_client.set_volume_size.assert_called_once_with( 

2254 share_name, size) 

2255 else: 

2256 vserver_client.set_volume_size.assert_not_called() 

2257 

2258 if hide_snapdir: 

2259 vserver_client.set_volume_snapdir_access.assert_called_once_with( 

2260 fake.SHARE_INSTANCE_NAME, hide_snapdir) 

2261 else: 

2262 vserver_client.set_volume_snapdir_access.assert_not_called() 

2263 

2264 if create_fpolicy: 

2265 mock_create_fpolicy.assert_called_once_with( 

2266 fake_share_inst, vserver, vserver_client, 

2267 **provisioning_options) 

2268 else: 

2269 mock_create_fpolicy.assert_not_called() 

2270 

2271 if split or split is None: 

2272 mock_rename_snapshot_and_split_clones.assert_called_once_with( 

2273 fake.SHARE_INSTANCE_NAME, 

2274 parent_snapshot_name, 

2275 ) 

2276 vserver_client.volume_clone_split_start.assert_called_once_with( 

2277 fake.SHARE_INSTANCE_NAME) 

2278 if split is False: 

2279 vserver_client.volume_clone_split_start.assert_not_called() 

2280 

2281 def test_share_exists(self): 

2282 

2283 vserver_client = mock.Mock() 

2284 vserver_client.volume_exists.return_value = True 

2285 

2286 result = self.library._share_exists(fake.SHARE_NAME, vserver_client) 

2287 

2288 self.assertTrue(result) 

2289 

2290 def test_share_exists_not_found(self): 

2291 

2292 vserver_client = mock.Mock() 

2293 vserver_client.volume_exists.return_value = False 

2294 

2295 result = self.library._share_exists(fake.SHARE_NAME, vserver_client) 

2296 

2297 self.assertFalse(result) 

2298 

2299 def test_delete_share(self): 

2300 

2301 vserver_client = mock.Mock() 

2302 self.mock_object(self.library, 

2303 '_get_vserver', 

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

2305 vserver_client))) 

2306 mock_share_exists = self.mock_object(self.library, 

2307 '_share_exists', 

2308 mock.Mock(return_value=True)) 

2309 mock_remove_export = self.mock_object(self.library, '_remove_export') 

2310 mock_deallocate_container = self.mock_object(self.library, 

2311 '_deallocate_container') 

2312 mock_delete_policy = self.mock_object(self.library, 

2313 '_delete_fpolicy_for_share') 

2314 

2315 self.library.delete_share(self.context, 

2316 fake.SHARE, 

2317 share_server=fake.SHARE_SERVER) 

2318 

2319 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

2320 qos_policy_name = self.library._get_backend_qos_policy_group_name( 

2321 fake.SHARE['id']) 

2322 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

2323 mock_remove_export.assert_called_once_with(fake.SHARE, vserver_client) 

2324 mock_deallocate_container.assert_called_once_with(share_name, 

2325 vserver_client) 

2326 mock_delete_policy.assert_called_once_with(fake.SHARE, fake.VSERVER1, 

2327 vserver_client) 

2328 (vserver_client.mark_qos_policy_group_for_deletion 

2329 .assert_called_once_with(qos_policy_name)) 

2330 self.assertEqual(0, lib_base.LOG.info.call_count) 

2331 

2332 def test__delete_share_no_remove_qos_and_export(self): 

2333 

2334 vserver_client = mock.Mock() 

2335 mock_share_exists = self.mock_object(self.library, 

2336 '_share_exists', 

2337 mock.Mock(return_value=True)) 

2338 mock_remove_export = self.mock_object(self.library, '_remove_export') 

2339 mock_deallocate_container = self.mock_object(self.library, 

2340 '_deallocate_container') 

2341 mock_delete_policy = self.mock_object(self.library, 

2342 '_delete_fpolicy_for_share') 

2343 mock_get_backend_qos = self.mock_object( 

2344 self.library, '_get_backend_qos_policy_group_name') 

2345 mock_get_share_name = self.mock_object( 

2346 self.library, '_get_backend_share_name', 

2347 mock.Mock(return_value=fake.SHARE_NAME)) 

2348 

2349 self.library._delete_share(fake.SHARE, 

2350 fake.VSERVER1, 

2351 vserver_client, 

2352 remove_export=False, 

2353 remove_qos=False) 

2354 

2355 mock_get_share_name.assert_called_once_with(fake.SHARE_ID) 

2356 mock_delete_policy.assert_called_once_with(fake.SHARE, fake.VSERVER1, 

2357 vserver_client) 

2358 mock_share_exists.assert_called_once_with(fake.SHARE_NAME, 

2359 vserver_client) 

2360 

2361 mock_deallocate_container.assert_called_once_with(fake.SHARE_NAME, 

2362 vserver_client) 

2363 mock_remove_export.assert_not_called() 

2364 mock_get_backend_qos.assert_not_called() 

2365 vserver_client.mark_qos_policy_group_for_deletion.assert_not_called() 

2366 

2367 @ddt.data(exception.InvalidInput(reason='fake_reason'), 

2368 exception.VserverNotSpecified(), 

2369 exception.VserverNotFound(vserver='fake_vserver')) 

2370 def test_delete_share_no_share_server(self, get_vserver_exception): 

2371 

2372 self.mock_object(self.library, 

2373 '_get_vserver', 

2374 mock.Mock(side_effect=get_vserver_exception)) 

2375 mock_share_exists = self.mock_object(self.library, 

2376 '_share_exists', 

2377 mock.Mock(return_value=False)) 

2378 mock_remove_export = self.mock_object(self.library, '_remove_export') 

2379 mock_deallocate_container = self.mock_object(self.library, 

2380 '_deallocate_container') 

2381 

2382 self.library.delete_share(self.context, 

2383 fake.SHARE, 

2384 share_server=fake.SHARE_SERVER) 

2385 

2386 self.assertFalse(mock_share_exists.called) 

2387 self.assertFalse(mock_remove_export.called) 

2388 self.assertFalse(mock_deallocate_container.called) 

2389 self.assertFalse( 

2390 self.library._client.mark_qos_policy_group_for_deletion.called) 

2391 self.assertEqual(1, lib_base.LOG.warning.call_count) 

2392 

2393 def test_delete_share_not_found(self): 

2394 

2395 vserver_client = mock.Mock() 

2396 self.mock_object(self.library, 

2397 '_get_vserver', 

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

2399 vserver_client))) 

2400 mock_share_exists = self.mock_object(self.library, 

2401 '_share_exists', 

2402 mock.Mock(return_value=False)) 

2403 mock_remove_export = self.mock_object(self.library, '_remove_export') 

2404 mock_deallocate_container = self.mock_object(self.library, 

2405 '_deallocate_container') 

2406 mock_delete_fpolicy = self.mock_object(self.library, 

2407 '_delete_fpolicy_for_share') 

2408 

2409 self.library.delete_share(self.context, 

2410 fake.SHARE, 

2411 share_server=fake.SHARE_SERVER) 

2412 

2413 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

2414 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

2415 mock_delete_fpolicy.assert_called_once_with(fake.SHARE, fake.VSERVER1, 

2416 vserver_client) 

2417 self.assertFalse(mock_remove_export.called) 

2418 self.assertFalse(mock_deallocate_container.called) 

2419 self.assertFalse( 

2420 self.library._client.mark_qos_policy_group_for_deletion.called) 

2421 self.assertEqual(1, lib_base.LOG.info.call_count) 

2422 

2423 def test_delete_share_clears_private_storage(self): 

2424 vserver_client = mock.Mock() 

2425 self.mock_object( 

2426 self.library, 

2427 '_get_vserver', 

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

2429 vserver_client)) 

2430 ) 

2431 mock_share_exists = self.mock_object( 

2432 self.library, 

2433 '_share_exists', 

2434 mock.Mock(return_value=True) 

2435 ) 

2436 mock_remove_export = self.mock_object(self.library, '_remove_export') 

2437 mock_deallocate_container = self.mock_object(self.library, 

2438 '_deallocate_container') 

2439 mock_delete_fpolicy = self.mock_object( 

2440 self.library, '_delete_fpolicy_for_share') 

2441 mock_get_qos = self.mock_object( 

2442 self.library, 

2443 '_get_backend_qos_policy_group_name', 

2444 mock.Mock(return_value='fake_qos_policy') 

2445 ) 

2446 mock_mark_qos = self.mock_object( 

2447 vserver_client, 

2448 'mark_qos_policy_group_for_deletion' 

2449 ) 

2450 mock_private_storage_delete = self.mock_object( 

2451 self.library.private_storage, 

2452 'delete', 

2453 ) 

2454 self.library.delete_share(self.context, fake.SHARE, 

2455 share_server=fake.SHARE_SERVER) 

2456 

2457 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

2458 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

2459 mock_remove_export.assert_called_once_with(fake.SHARE, vserver_client) 

2460 mock_deallocate_container.assert_called_once_with(share_name, 

2461 vserver_client) 

2462 mock_delete_fpolicy.assert_called_once_with( 

2463 fake.SHARE, fake.VSERVER1, vserver_client) 

2464 mock_get_qos.assert_called_once_with( 

2465 fake.SHARE['id']) 

2466 mock_mark_qos.assert_called_once_with('fake_qos_policy') 

2467 mock_private_storage_delete.assert_called_once_with(fake.SHARE['id']) 

2468 

2469 self.assertEqual(0, lib_base.LOG.info.call_count) 

2470 

2471 def test_delete_share_nonexistent_does_not_delete_private_storage(self): 

2472 vserver_client = mock.Mock() 

2473 self.mock_object( 

2474 self.library, 

2475 '_get_vserver', 

2476 mock.Mock(return_value=(fake.VSERVER1, vserver_client)) 

2477 ) 

2478 mock_share_exists = self.mock_object( 

2479 self.library, 

2480 '_share_exists', 

2481 mock.Mock(return_value=False) 

2482 ) 

2483 mock_delete_fpolicy = self.mock_object( 

2484 self.library, 

2485 '_delete_fpolicy_for_share' 

2486 ) 

2487 mock_private_storage_delete = self.mock_object( 

2488 self.library.private_storage, 'delete' 

2489 ) 

2490 self.library.delete_share( 

2491 self.context, fake.SHARE, share_server=fake.SHARE_SERVER) 

2492 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

2493 mock_share_exists.assert_called_once_with( 

2494 share_name, vserver_client) 

2495 mock_delete_fpolicy.assert_called_once_with( 

2496 fake.SHARE, fake.VSERVER1, vserver_client) 

2497 mock_private_storage_delete.assert_called_once_with( 

2498 fake.SHARE['id']) 

2499 

2500 def test_deallocate_container(self): 

2501 

2502 vserver_client = mock.Mock() 

2503 

2504 self.library._deallocate_container(fake.SHARE_NAME, vserver_client) 

2505 

2506 vserver_client.unmount_volume.assert_called_with(fake.SHARE_NAME, 

2507 force=True) 

2508 vserver_client.offline_volume.assert_called_with(fake.SHARE_NAME) 

2509 vserver_client.delete_volume.assert_called_with(fake.SHARE_NAME) 

2510 

2511 @ddt.data(None, fake.MANILA_HOST_NAME_2) 

2512 def test_create_export(self, share_host): 

2513 

2514 protocol_helper = mock.Mock() 

2515 callback = (lambda export_address, export_path='fake_export_path': 

2516 ':'.join([export_address, export_path])) 

2517 protocol_helper.create_share.return_value = callback 

2518 expected_host = share_host if share_host else fake.SHARE['host'] 

2519 self.mock_object(self.library, 

2520 '_get_helper', 

2521 mock.Mock(return_value=protocol_helper)) 

2522 self.mock_object(self.library, 

2523 '_is_flexgroup_pool', mock.Mock(return_value=False)) 

2524 vserver_client = mock.Mock() 

2525 cluster_client = mock.Mock() 

2526 vserver_client.get_network_interfaces.return_value = fake.LIFS 

2527 fake_interface_addresses_with_metadata = copy.deepcopy( 

2528 fake.INTERFACE_ADDRESSES_WITH_METADATA) 

2529 mock_get_export_addresses_with_metadata = self.mock_object( 

2530 self.library, '_get_export_addresses_with_metadata', 

2531 mock.Mock(return_value=fake_interface_addresses_with_metadata)) 

2532 

2533 result = self.library._create_export(fake.SHARE, 

2534 fake.SHARE_SERVER, 

2535 fake.VSERVER1, 

2536 vserver_client, 

2537 cluster_client=cluster_client, 

2538 share_host=share_host) 

2539 

2540 self.assertEqual(fake.NFS_EXPORTS, result) 

2541 mock_get_export_addresses_with_metadata.assert_called_once_with( 

2542 fake.SHARE, fake.SHARE_SERVER, fake.LIFS, expected_host, 

2543 cluster_client) 

2544 protocol_helper.create_share.assert_called_once_with( 

2545 fake.SHARE, fake.SHARE_NAME, clear_current_export_policy=True, 

2546 ensure_share_already_exists=False, replica=False, 

2547 is_flexgroup=False) 

2548 

2549 def test_create_export_lifs_not_found(self): 

2550 

2551 self.mock_object(self.library, '_get_helper') 

2552 vserver_client = mock.Mock() 

2553 vserver_client.get_network_interfaces.return_value = [] 

2554 

2555 self.assertRaises(exception.NetAppException, 

2556 self.library._create_export, 

2557 fake.SHARE, 

2558 fake.SHARE_SERVER, 

2559 fake.VSERVER1, 

2560 vserver_client) 

2561 

2562 @ddt.data(True, False) 

2563 def test_get_export_addresses_with_metadata(self, is_flexgroup): 

2564 

2565 self.mock_object( 

2566 self.library, '_is_flexgroup_pool', 

2567 mock.Mock(return_value=is_flexgroup)) 

2568 mock_get_aggr_flexgroup = self.mock_object( 

2569 self.library, '_get_flexgroup_aggregate_list', 

2570 mock.Mock(return_value=[fake.AGGREGATE])) 

2571 mock_get_aggregate_node = self.mock_object( 

2572 self.library, '_get_aggregate_node', 

2573 mock.Mock(return_value=fake.CLUSTER_NODES[0])) 

2574 mock_get_admin_addresses_for_share_server = self.mock_object( 

2575 self.library, '_get_admin_addresses_for_share_server', 

2576 mock.Mock(return_value=[fake.LIF_ADDRESSES[1]])) 

2577 

2578 result = self.library._get_export_addresses_with_metadata( 

2579 fake.SHARE, fake.SHARE_SERVER, fake.LIFS, fake.SHARE['host']) 

2580 

2581 self.assertEqual(fake.INTERFACE_ADDRESSES_WITH_METADATA, result) 

2582 mock_get_admin_addresses_for_share_server.assert_called_once_with( 

2583 fake.SHARE_SERVER) 

2584 if is_flexgroup: 

2585 mock_get_aggr_flexgroup.assert_called_once_with(fake.POOL_NAME) 

2586 mock_get_aggregate_node.assert_called_once_with( 

2587 fake.AGGREGATE, None) 

2588 else: 

2589 mock_get_aggregate_node.assert_called_once_with( 

2590 fake.POOL_NAME, None) 

2591 

2592 def test_get_export_addresses_with_metadata_node_unknown(self): 

2593 

2594 self.mock_object( 

2595 self.library, '_is_flexgroup_pool', mock.Mock(return_value=False)) 

2596 mock_get_aggregate_node = self.mock_object( 

2597 self.library, '_get_aggregate_node', 

2598 mock.Mock(return_value=None)) 

2599 mock_get_admin_addresses_for_share_server = self.mock_object( 

2600 self.library, '_get_admin_addresses_for_share_server', 

2601 mock.Mock(return_value=[fake.LIF_ADDRESSES[1]])) 

2602 

2603 result = self.library._get_export_addresses_with_metadata( 

2604 fake.SHARE, fake.SHARE_SERVER, fake.LIFS, fake.SHARE['host']) 

2605 

2606 expected = copy.deepcopy(fake.INTERFACE_ADDRESSES_WITH_METADATA) 

2607 for key, value in expected.items(): 

2608 value['preferred'] = False 

2609 

2610 self.assertEqual(expected, result) 

2611 mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME, None) 

2612 mock_get_admin_addresses_for_share_server.assert_called_once_with( 

2613 fake.SHARE_SERVER) 

2614 

2615 def test_get_admin_addresses_for_share_server(self): 

2616 

2617 result = self.library._get_admin_addresses_for_share_server( 

2618 fake.SHARE_SERVER) 

2619 

2620 self.assertEqual([fake.ADMIN_NETWORK_ALLOCATIONS[0]['ip_address']], 

2621 result) 

2622 

2623 def test_get_admin_addresses_for_share_server_no_share_server(self): 

2624 

2625 result = self.library._get_admin_addresses_for_share_server(None) 

2626 

2627 self.assertEqual([], result) 

2628 

2629 @ddt.data(True, False) 

2630 def test_sort_export_locations_by_preferred_paths(self, reverse): 

2631 

2632 export_locations = copy.copy(fake.NFS_EXPORTS) 

2633 if reverse: 

2634 export_locations.reverse() 

2635 

2636 result = self.library._sort_export_locations_by_preferred_paths( 

2637 export_locations) 

2638 

2639 self.assertEqual(fake.NFS_EXPORTS, result) 

2640 

2641 def test_remove_export(self): 

2642 

2643 protocol_helper = mock.Mock() 

2644 protocol_helper.get_target.return_value = 'fake_target' 

2645 self.mock_object(self.library, 

2646 '_get_helper', 

2647 mock.Mock(return_value=protocol_helper)) 

2648 vserver_client = mock.Mock() 

2649 

2650 self.library._remove_export(fake.SHARE, vserver_client) 

2651 

2652 protocol_helper.set_client.assert_called_once_with(vserver_client) 

2653 protocol_helper.get_target.assert_called_once_with(fake.SHARE) 

2654 protocol_helper.delete_share.assert_called_once_with(fake.SHARE, 

2655 fake.SHARE_NAME) 

2656 

2657 def test_remove_export_target_not_found(self): 

2658 

2659 protocol_helper = mock.Mock() 

2660 protocol_helper.get_target.return_value = None 

2661 self.mock_object(self.library, 

2662 '_get_helper', 

2663 mock.Mock(return_value=protocol_helper)) 

2664 vserver_client = mock.Mock() 

2665 

2666 self.library._remove_export(fake.SHARE, vserver_client) 

2667 

2668 protocol_helper.set_client.assert_called_once_with(vserver_client) 

2669 protocol_helper.get_target.assert_called_once_with(fake.SHARE) 

2670 self.assertFalse(protocol_helper.delete_share.called) 

2671 

2672 def test_create_snapshot(self): 

2673 

2674 vserver_client = mock.Mock() 

2675 self.mock_object(self.library, 

2676 '_get_vserver', 

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

2678 vserver_client))) 

2679 

2680 model_update = self.library.create_snapshot( 

2681 self.context, fake.SNAPSHOT, share_server=fake.SHARE_SERVER) 

2682 

2683 share_name = self.library._get_backend_share_name( 

2684 fake.SNAPSHOT['share_id']) 

2685 snapshot_name = self.library._get_backend_snapshot_name( 

2686 fake.SNAPSHOT['id']) 

2687 vserver_client.create_snapshot.assert_called_once_with(share_name, 

2688 snapshot_name) 

2689 self.assertEqual(snapshot_name, model_update['provider_location']) 

2690 

2691 @ddt.data(True, False) 

2692 def test_revert_to_snapshot(self, use_snap_provider_location): 

2693 

2694 vserver_client = mock.Mock() 

2695 self.mock_object(self.library, 

2696 '_get_vserver', 

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

2698 vserver_client))) 

2699 vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE 

2700 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

2701 if use_snap_provider_location: 

2702 fake_snapshot['provider_location'] = 'fake-provider-location' 

2703 else: 

2704 del fake_snapshot['provider_location'] 

2705 

2706 result = self.library.revert_to_snapshot( 

2707 self.context, fake_snapshot, share_server=fake.SHARE_SERVER) 

2708 

2709 self.assertIsNotNone(result) 

2710 share_name = self.library._get_backend_share_name( 

2711 fake_snapshot['share_id']) 

2712 snapshot_name = (self.library._get_backend_snapshot_name( 

2713 fake_snapshot['id']) if not use_snap_provider_location 

2714 else 'fake-provider-location') 

2715 vserver_client.restore_snapshot.assert_called_once_with(share_name, 

2716 snapshot_name) 

2717 

2718 def test_delete_snapshot(self): 

2719 

2720 vserver_client = mock.Mock() 

2721 self.mock_object(self.library, 

2722 '_get_vserver', 

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

2724 vserver_client))) 

2725 mock_is_flexgroup_share = self.mock_object( 

2726 self.library, '_is_flexgroup_share', mock.Mock(return_value=False)) 

2727 mock_delete_snapshot = self.mock_object(self.library, 

2728 '_delete_snapshot') 

2729 

2730 self.library.delete_snapshot(self.context, 

2731 fake.SNAPSHOT, 

2732 share_server=fake.SHARE_SERVER) 

2733 

2734 share_name = self.library._get_backend_share_name( 

2735 fake.SNAPSHOT['share_id']) 

2736 snapshot_name = self.library._get_backend_snapshot_name( 

2737 fake.SNAPSHOT['id']) 

2738 mock_is_flexgroup_share.assert_called_once_with(vserver_client, 

2739 share_name) 

2740 mock_delete_snapshot.assert_called_once_with( 

2741 vserver_client, share_name, snapshot_name, is_flexgroup=False) 

2742 

2743 def test_delete_snapshot_with_provider_location(self): 

2744 vserver_client = mock.Mock() 

2745 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

2746 self.mock_object(self.library, 

2747 '_get_vserver', 

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

2749 vserver_client))) 

2750 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

2751 fake_snapshot['provider_location'] = 'fake_provider_location' 

2752 

2753 self.library.delete_snapshot(self.context, 

2754 fake_snapshot, 

2755 share_server=fake.SHARE_SERVER) 

2756 

2757 share_name = self.library._get_backend_share_name( 

2758 fake_snapshot['share_id']) 

2759 vserver_client.delete_snapshot.assert_called_once_with( 

2760 share_name, fake_snapshot['provider_location']) 

2761 

2762 @ddt.data(exception.InvalidInput(reason='fake_reason'), 

2763 exception.VserverNotSpecified(), 

2764 exception.VserverNotFound(vserver='fake_vserver')) 

2765 def test_delete_snapshot_no_share_server(self, get_vserver_exception): 

2766 

2767 self.mock_object(self.library, 

2768 '_get_vserver', 

2769 mock.Mock(side_effect=get_vserver_exception)) 

2770 mock_is_flexgroup_share = self.mock_object( 

2771 self.library, '_is_flexgroup_share', mock.Mock(return_value=False)) 

2772 mock_delete_snapshot = self.mock_object(self.library, 

2773 '_delete_snapshot') 

2774 

2775 self.library.delete_snapshot(self.context, 

2776 fake.SNAPSHOT, 

2777 share_server=fake.SHARE_SERVER) 

2778 

2779 self.assertFalse(mock_is_flexgroup_share.called) 

2780 self.assertFalse(mock_delete_snapshot.called) 

2781 

2782 def test_delete_snapshot_not_found(self): 

2783 

2784 vserver_client = mock.Mock() 

2785 self.mock_object(self.library, 

2786 '_get_vserver', 

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

2788 vserver_client))) 

2789 mock_is_flexgroup_share = self.mock_object( 

2790 self.library, '_is_flexgroup_share', mock.Mock(return_value=False)) 

2791 mock_delete_snapshot = self.mock_object( 

2792 self.library, '_delete_snapshot', 

2793 mock.Mock(side_effect=exception.SnapshotResourceNotFound( 

2794 name=fake.SNAPSHOT_NAME))) 

2795 

2796 self.library.delete_snapshot(self.context, 

2797 fake.SNAPSHOT, 

2798 share_server=fake.SHARE_SERVER) 

2799 

2800 share_name = self.library._get_backend_share_name( 

2801 fake.SNAPSHOT['share_id']) 

2802 snapshot_name = self.library._get_backend_snapshot_name( 

2803 fake.SNAPSHOT['id']) 

2804 mock_is_flexgroup_share.assert_called_once_with( 

2805 vserver_client, share_name) 

2806 mock_delete_snapshot.assert_called_once_with( 

2807 vserver_client, share_name, snapshot_name, is_flexgroup=False) 

2808 

2809 def test_delete_snapshot_not_unique(self): 

2810 

2811 vserver_client = mock.Mock() 

2812 self.mock_object(self.library, 

2813 '_get_vserver', 

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

2815 vserver_client))) 

2816 mock_is_flexgroup_share = self.mock_object( 

2817 self.library, '_is_flexgroup_share', mock.Mock(return_value=False)) 

2818 mock_delete_snapshot = self.mock_object( 

2819 self.library, '_delete_snapshot', 

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

2821 

2822 self.assertRaises(exception.NetAppException, 

2823 self.library.delete_snapshot, 

2824 self.context, 

2825 fake.SNAPSHOT, 

2826 share_server=fake.SHARE_SERVER) 

2827 

2828 share_name = self.library._get_backend_share_name( 

2829 fake.SNAPSHOT['share_id']) 

2830 snapshot_name = self.library._get_backend_snapshot_name( 

2831 fake.SNAPSHOT['id']) 

2832 mock_is_flexgroup_share.assert_called_once_with( 

2833 vserver_client, share_name) 

2834 mock_delete_snapshot.assert_called_once_with( 

2835 vserver_client, share_name, snapshot_name, is_flexgroup=False) 

2836 

2837 def test__delete_snapshot(self): 

2838 

2839 vserver_client = mock.Mock() 

2840 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

2841 

2842 self.library._delete_snapshot(vserver_client, 

2843 fake.SHARE_NAME, 

2844 fake.SNAPSHOT_NAME) 

2845 

2846 vserver_client.delete_snapshot.assert_called_once_with( 

2847 fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2848 self.assertFalse(vserver_client.get_clone_children_for_snapshot.called) 

2849 self.assertFalse(vserver_client.volume_clone_split_start.called) 

2850 self.assertFalse(vserver_client.soft_delete_snapshot.called) 

2851 

2852 @ddt.data(True, False) 

2853 def test__delete_snapshot_busy_volume_clone(self, is_flexgroup): 

2854 

2855 vserver_client = mock.Mock() 

2856 vserver_client.get_snapshot.return_value = ( 

2857 fake.CDOT_SNAPSHOT_BUSY_VOLUME_CLONE) 

2858 vserver_client.get_clone_children_for_snapshot.return_value = ( 

2859 fake.CDOT_CLONE_CHILDREN) 

2860 mock_is_flexgroup_share = self.mock_object( 

2861 self.library, '_delete_busy_snapshot') 

2862 

2863 self.library._delete_snapshot(vserver_client, 

2864 fake.SHARE_NAME, 

2865 fake.SNAPSHOT_NAME, 

2866 is_flexgroup=is_flexgroup) 

2867 

2868 self.assertFalse(vserver_client.delete_snapshot.called) 

2869 if is_flexgroup: 

2870 (vserver_client. 

2871 get_clone_children_for_snapshot.assert_called_once_with( 

2872 fake.SHARE_NAME, fake.SNAPSHOT_NAME)) 

2873 vserver_client.volume_clone_split_start.assert_has_calls([ 

2874 mock.call(fake.CDOT_CLONE_CHILD_1), 

2875 mock.call(fake.CDOT_CLONE_CHILD_2), 

2876 ]) 

2877 mock_is_flexgroup_share.assert_called_once_with( 

2878 vserver_client, fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2879 vserver_client.soft_delete_snapshot.assert_not_called() 

2880 else: 

2881 mock_is_flexgroup_share.assert_not_called() 

2882 vserver_client.soft_delete_snapshot.assert_called_once_with( 

2883 fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2884 

2885 def test__delete_snapshot_busy_snapmirror(self): 

2886 

2887 vserver_client = mock.Mock() 

2888 vserver_client.get_snapshot.return_value = ( 

2889 fake.CDOT_SNAPSHOT_BUSY_SNAPMIRROR) 

2890 mock_is_flexgroup_share = self.mock_object( 

2891 self.library, '_delete_busy_snapshot') 

2892 

2893 self.assertRaises(exception.ShareSnapshotIsBusy, 

2894 self.library._delete_snapshot, 

2895 vserver_client, 

2896 fake.SHARE_NAME, 

2897 fake.SNAPSHOT_NAME) 

2898 

2899 self.assertFalse(vserver_client.delete_snapshot.called) 

2900 self.assertFalse(vserver_client.get_clone_children_for_snapshot.called) 

2901 self.assertFalse(vserver_client.volume_clone_split_start.called) 

2902 self.assertFalse(mock_is_flexgroup_share.called) 

2903 self.assertFalse(vserver_client.soft_delete_snapshot.called) 

2904 

2905 def test_delete_busy_snapshot(self): 

2906 (self.library.configuration. 

2907 netapp_delete_busy_flexgroup_snapshot_timeout) = 2 

2908 vserver_client = mock.Mock() 

2909 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

2910 

2911 self.library._delete_busy_snapshot(vserver_client, 

2912 fake.SHARE_NAME, 

2913 fake.SNAPSHOT_NAME) 

2914 

2915 vserver_client.get_snapshot.assert_called_once_with( 

2916 fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2917 vserver_client.delete_snapshot.assert_called_once_with( 

2918 fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2919 

2920 def test_delete_busy_snapshot_raise_timeout(self): 

2921 (self.library.configuration. 

2922 netapp_delete_busy_flexgroup_snapshot_timeout) = 2 

2923 vserver_client = mock.Mock() 

2924 vserver_client.get_snapshot.return_value = ( 

2925 fake.CDOT_SNAPSHOT_BUSY_VOLUME_CLONE) 

2926 

2927 self.assertRaises( 

2928 exception.NetAppException, self.library._delete_busy_snapshot, 

2929 vserver_client, fake.SHARE_NAME, fake.SNAPSHOT_NAME) 

2930 

2931 @ddt.data(None, fake.VSERVER1) 

2932 def test_manage_existing(self, fake_vserver): 

2933 

2934 vserver_client = mock.Mock() 

2935 mock__get_vserver = self.mock_object( 

2936 self.library, '_get_vserver', 

2937 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

2938 mock_manage_container = self.mock_object( 

2939 self.library, 

2940 '_manage_container', 

2941 mock.Mock(return_value=fake.SHARE_SIZE)) 

2942 mock_create_export = self.mock_object( 

2943 self.library, 

2944 '_create_export', 

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

2946 

2947 result = self.library.manage_existing(fake.SHARE, {}, 

2948 share_server=fake_vserver) 

2949 

2950 expected = { 

2951 'size': fake.SHARE_SIZE, 

2952 'export_locations': fake.NFS_EXPORTS 

2953 } 

2954 

2955 mock__get_vserver.assert_called_once_with(share_server=fake_vserver) 

2956 mock_manage_container.assert_called_once_with(fake.SHARE, 

2957 fake.VSERVER1, 

2958 vserver_client) 

2959 

2960 mock_create_export.assert_called_once_with(fake.SHARE, 

2961 fake_vserver, 

2962 fake.VSERVER1, 

2963 vserver_client) 

2964 self.assertDictEqual(expected, result) 

2965 

2966 @ddt.data(None, fake.VSERVER1) 

2967 def test_unmanage(self, fake_vserver): 

2968 

2969 result = self.library.unmanage(fake.SHARE, share_server=fake_vserver) 

2970 

2971 self.assertIsNone(result) 

2972 

2973 @ddt.data({'qos': True, 'fpolicy': False, 'is_flexgroup': False}, 

2974 {'qos': False, 'fpolicy': True, 'is_flexgroup': False}, 

2975 {'qos': True, 'fpolicy': False, 'is_flexgroup': True}, 

2976 {'qos': False, 'fpolicy': True, 'is_flexgroup': True}) 

2977 @ddt.unpack 

2978 def test_manage_container(self, qos, fpolicy, is_flexgroup): 

2979 

2980 vserver_client = mock.Mock() 

2981 self.library._have_cluster_creds = True 

2982 qos_policy_group_name = fake.QOS_POLICY_GROUP_NAME if qos else None 

2983 if qos: 

2984 extra_specs = copy.deepcopy(fake.EXTRA_SPEC_WITH_QOS) 

2985 elif fpolicy: 2985 ↛ 2988line 2985 didn't jump to line 2988 because the condition on line 2985 was always true

2986 extra_specs = copy.deepcopy(fake.EXTRA_SPEC_WITH_FPOLICY) 

2987 else: 

2988 extra_specs = copy.deepcopy(fake.EXTRA_SPEC) 

2989 provisioning_opts = self.library._get_provisioning_options(extra_specs) 

2990 if qos: 

2991 provisioning_opts['qos_policy_group'] = fake.QOS_POLICY_GROUP_NAME 

2992 

2993 share_to_manage = copy.deepcopy(fake.SHARE) 

2994 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

2995 

2996 mock_helper = mock.Mock() 

2997 mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME 

2998 self.mock_object(self.library, 

2999 '_get_helper', 

3000 mock.Mock(return_value=mock_helper)) 

3001 

3002 fake_aggr = [fake.POOL_NAME] if is_flexgroup else fake.POOL_NAME 

3003 mock_is_flexgroup_pool = self.mock_object( 

3004 self.library, '_is_flexgroup_pool', 

3005 mock.Mock(return_value=is_flexgroup)) 

3006 mock_get_flexgroup_aggregate_list = self.mock_object( 

3007 self.library, '_get_flexgroup_aggregate_list', 

3008 mock.Mock(return_value=fake_aggr)) 

3009 mock_is_flexgroup_share = self.mock_object( 

3010 self.library, '_is_flexgroup_share', 

3011 mock.Mock(return_value=is_flexgroup)) 

3012 

3013 mock_get_volume_to_manage = self.mock_object( 

3014 vserver_client, 

3015 'get_volume_to_manage', 

3016 mock.Mock(return_value=fake.FLEXVOL_TO_MANAGE)) 

3017 mock_validate_volume_for_manage = self.mock_object( 

3018 self.library, 

3019 '_validate_volume_for_manage') 

3020 self.mock_object(share_types, 

3021 'get_extra_specs_from_share', 

3022 mock.Mock(return_value=extra_specs)) 

3023 mock_check_extra_specs_validity = self.mock_object( 

3024 self.library, 

3025 '_check_extra_specs_validity') 

3026 mock_check_aggregate_extra_specs_validity = self.mock_object( 

3027 self.library, 

3028 '_check_aggregate_extra_specs_validity') 

3029 mock_modify_or_create_qos_policy = self.mock_object( 

3030 self.library, '_modify_or_create_qos_for_existing_share', 

3031 mock.Mock(return_value=qos_policy_group_name)) 

3032 mock_get_volume_snapshot_attributes = self.mock_object( 

3033 vserver_client, 'get_volume_snapshot_attributes', 

3034 mock.Mock(return_value={'snapshot-policy': 'fake_policy'})) 

3035 fake_fpolicy_scope = { 

3036 'policy-name': fake.FPOLICY_POLICY_NAME, 

3037 'shares-to-include': [fake.FLEXVOL_NAME] 

3038 } 

3039 mock_find_scope = self.mock_object( 

3040 self.library, '_find_reusable_fpolicy_scope', 

3041 mock.Mock(return_value=fake_fpolicy_scope)) 

3042 mock_modify_fpolicy = self.mock_object( 

3043 vserver_client, 'modify_fpolicy_scope') 

3044 

3045 result = self.library._manage_container(share_to_manage, 

3046 fake.VSERVER1, 

3047 vserver_client) 

3048 

3049 mock_is_flexgroup_pool.assert_called_once_with(fake.POOL_NAME) 

3050 if is_flexgroup: 

3051 mock_get_flexgroup_aggregate_list.assert_called_once_with( 

3052 fake.POOL_NAME) 

3053 else: 

3054 mock_get_flexgroup_aggregate_list.assert_not_called() 

3055 mock_is_flexgroup_share.assert_called_once_with(vserver_client, 

3056 fake.FLEXVOL_NAME) 

3057 mock_get_volume_to_manage.assert_called_once_with( 

3058 fake_aggr, fake.FLEXVOL_NAME) 

3059 mock_check_extra_specs_validity.assert_called_once_with( 

3060 share_to_manage, extra_specs) 

3061 mock_check_aggregate_extra_specs_validity.assert_called_once_with( 

3062 fake.POOL_NAME, extra_specs) 

3063 vserver_client.unmount_volume.assert_called_once_with( 

3064 fake.FLEXVOL_NAME) 

3065 vserver_client.set_volume_name.assert_called_once_with( 

3066 fake.FLEXVOL_NAME, fake.SHARE_NAME) 

3067 vserver_client.mount_volume.assert_called_once_with( 

3068 fake.SHARE_NAME, fake.MOUNT_POINT_NAME) 

3069 vserver_client.modify_volume.assert_called_once_with( 

3070 fake_aggr, fake.SHARE_NAME, **provisioning_opts) 

3071 mock_modify_or_create_qos_policy.assert_called_once_with( 

3072 share_to_manage, extra_specs, fake.VSERVER1, vserver_client) 

3073 mock_get_volume_snapshot_attributes.assert_called_once_with( 

3074 fake.SHARE_NAME) 

3075 mock_validate_volume_for_manage.assert_called() 

3076 if fpolicy: 

3077 mock_find_scope.assert_called_once_with( 

3078 share_to_manage, vserver_client, 

3079 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

3080 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

3081 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS, 

3082 shares_to_include=[fake.FLEXVOL_NAME]) 

3083 mock_modify_fpolicy.assert_called_once_with( 

3084 fake.SHARE_NAME, 

3085 fake.FPOLICY_POLICY_NAME, shares_to_include=[fake.SHARE_NAME]) 

3086 else: 

3087 mock_find_scope.assert_not_called() 

3088 mock_modify_fpolicy.assert_not_called() 

3089 

3090 original_data = { 

3091 'original_name': fake.FLEXVOL_TO_MANAGE['name'], 

3092 'original_junction_path': fake.FLEXVOL_TO_MANAGE['junction-path'], 

3093 } 

3094 self.library.private_storage.update.assert_called_once_with( 

3095 fake.SHARE['id'], original_data) 

3096 

3097 expected_size = int( 

3098 math.ceil(float(fake.FLEXVOL_TO_MANAGE['size']) / units.Gi)) 

3099 self.assertEqual(expected_size, result) 

3100 

3101 def test_manage_container_invalid_export_location(self): 

3102 

3103 vserver_client = mock.Mock() 

3104 

3105 share_to_manage = copy.deepcopy(fake.SHARE) 

3106 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

3107 

3108 mock_helper = mock.Mock() 

3109 mock_helper.get_share_name_for_share.return_value = None 

3110 self.mock_object(self.library, 

3111 '_get_helper', 

3112 mock.Mock(return_value=mock_helper)) 

3113 

3114 self.assertRaises(exception.ManageInvalidShare, 

3115 self.library._manage_container, 

3116 share_to_manage, 

3117 fake.VSERVER1, 

3118 vserver_client) 

3119 

3120 def test_manage_container_not_found(self): 

3121 

3122 vserver_client = mock.Mock() 

3123 

3124 share_to_manage = copy.deepcopy(fake.SHARE) 

3125 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

3126 

3127 mock_helper = mock.Mock() 

3128 mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME 

3129 self.mock_object(self.library, 

3130 '_get_helper', 

3131 mock.Mock(return_value=mock_helper)) 

3132 

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

3134 mock.Mock(return_value=False)) 

3135 self.mock_object(self.library, '_is_flexgroup_share', 

3136 mock.Mock(return_value=False)) 

3137 

3138 self.mock_object(vserver_client, 

3139 'get_volume_to_manage', 

3140 mock.Mock(return_value=None)) 

3141 

3142 self.assertRaises(exception.ManageInvalidShare, 

3143 self.library._manage_container, 

3144 share_to_manage, 

3145 fake.VSERVER1, 

3146 vserver_client) 

3147 

3148 def test_manage_container_invalid_extra_specs(self): 

3149 

3150 vserver_client = mock.Mock() 

3151 

3152 share_to_manage = copy.deepcopy(fake.SHARE) 

3153 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

3154 

3155 mock_helper = mock.Mock() 

3156 mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME 

3157 self.mock_object(self.library, 

3158 '_get_helper', 

3159 mock.Mock(return_value=mock_helper)) 

3160 

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

3162 mock.Mock(return_value=False)) 

3163 self.mock_object(self.library, '_is_flexgroup_share', 

3164 mock.Mock(return_value=False)) 

3165 

3166 self.mock_object(vserver_client, 

3167 'get_volume_to_manage', 

3168 mock.Mock(return_value=fake.FLEXVOL_TO_MANAGE)) 

3169 self.mock_object(self.library, '_validate_volume_for_manage') 

3170 self.mock_object(share_types, 

3171 'get_extra_specs_from_share', 

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

3173 self.mock_object(self.library, 

3174 '_check_extra_specs_validity', 

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

3176 

3177 self.assertRaises(exception.ManageExistingShareTypeMismatch, 

3178 self.library._manage_container, 

3179 share_to_manage, 

3180 fake.VSERVER1, 

3181 vserver_client) 

3182 

3183 def test_manage_container_invalid_fpolicy(self): 

3184 vserver_client = mock.Mock() 

3185 extra_spec = copy.deepcopy(fake.EXTRA_SPEC_WITH_FPOLICY) 

3186 share_to_manage = copy.deepcopy(fake.SHARE) 

3187 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

3188 

3189 mock_helper = mock.Mock() 

3190 mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME 

3191 self.mock_object(self.library, 

3192 '_get_helper', 

3193 mock.Mock(return_value=mock_helper)) 

3194 

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

3196 mock.Mock(return_value=False)) 

3197 self.mock_object(self.library, '_is_flexgroup_share', 

3198 mock.Mock(return_value=False)) 

3199 

3200 self.mock_object(vserver_client, 

3201 'get_volume_to_manage', 

3202 mock.Mock(return_value=fake.FLEXVOL_TO_MANAGE)) 

3203 self.mock_object(self.library, '_validate_volume_for_manage') 

3204 self.mock_object(share_types, 

3205 'get_extra_specs_from_share', 

3206 mock.Mock(return_value=extra_spec)) 

3207 self.mock_object(self.library, '_check_extra_specs_validity') 

3208 self.mock_object(self.library, '_find_reusable_fpolicy_scope', 

3209 mock.Mock(return_value=None)) 

3210 

3211 self.assertRaises(exception.ManageExistingShareTypeMismatch, 

3212 self.library._manage_container, 

3213 share_to_manage, 

3214 fake.VSERVER1, 

3215 vserver_client) 

3216 

3217 def test_manage_container_wrong_pool_style(self): 

3218 

3219 vserver_client = mock.Mock() 

3220 

3221 share_to_manage = copy.deepcopy(fake.SHARE) 

3222 share_to_manage['export_location'] = fake.EXPORT_LOCATION 

3223 

3224 mock_helper = mock.Mock() 

3225 mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME 

3226 self.mock_object(self.library, 

3227 '_get_helper', 

3228 mock.Mock(return_value=mock_helper)) 

3229 

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

3231 mock.Mock(return_value=False)) 

3232 self.mock_object(self.library, '_is_flexgroup_share', 

3233 mock.Mock(return_value=True)) 

3234 

3235 self.assertRaises(exception.ManageInvalidShare, 

3236 self.library._manage_container, 

3237 share_to_manage, 

3238 fake.VSERVER1, 

3239 vserver_client) 

3240 

3241 def test_validate_volume_for_manage(self): 

3242 

3243 vserver_client = mock.Mock() 

3244 vserver_client.volume_has_luns = mock.Mock(return_value=False) 

3245 vserver_client.volume_has_junctioned_volumes = mock.Mock( 

3246 return_value=False) 

3247 vserver_client.volume_has_snapmirror_relationships = mock.Mock( 

3248 return_value=False) 

3249 

3250 result = self.library._validate_volume_for_manage( 

3251 fake.FLEXVOL_TO_MANAGE, vserver_client) 

3252 

3253 self.assertIsNone(result) 

3254 

3255 @ddt.data({ 

3256 'attribute': 'type', 

3257 'value': 'dp', 

3258 }, { 

3259 'attribute': 'style', 

3260 'value': 'infinitevol', 

3261 }) 

3262 @ddt.unpack 

3263 def test_validate_volume_for_manage_invalid_volume(self, attribute, value): 

3264 

3265 flexvol_to_manage = copy.deepcopy(fake.FLEXVOL_TO_MANAGE) 

3266 flexvol_to_manage[attribute] = value 

3267 

3268 vserver_client = mock.Mock() 

3269 vserver_client.volume_has_luns = mock.Mock(return_value=False) 

3270 vserver_client.volume_has_junctioned_volumes = mock.Mock( 

3271 return_value=False) 

3272 vserver_client.volume_has_snapmirror_relationships = mock.Mock( 

3273 return_value=False) 

3274 

3275 self.assertRaises(exception.ManageInvalidShare, 

3276 self.library._validate_volume_for_manage, 

3277 flexvol_to_manage, 

3278 vserver_client) 

3279 

3280 def test_validate_volume_for_manage_luns_present(self): 

3281 

3282 vserver_client = mock.Mock() 

3283 vserver_client.volume_has_luns = mock.Mock(return_value=True) 

3284 vserver_client.volume_has_junctioned_volumes = mock.Mock( 

3285 return_value=False) 

3286 vserver_client.volume_has_snapmirror_relationships = mock.Mock( 

3287 return_value=False) 

3288 

3289 self.assertRaises(exception.ManageInvalidShare, 

3290 self.library._validate_volume_for_manage, 

3291 fake.FLEXVOL_TO_MANAGE, 

3292 vserver_client) 

3293 

3294 def test_validate_volume_for_manage_junctioned_volumes_present(self): 

3295 

3296 vserver_client = mock.Mock() 

3297 vserver_client.volume_has_luns = mock.Mock(return_value=False) 

3298 vserver_client.volume_has_junctioned_volumes = mock.Mock( 

3299 return_value=True) 

3300 vserver_client.volume_has_snapmirror_relationships = mock.Mock( 

3301 return_value=False) 

3302 

3303 self.assertRaises(exception.ManageInvalidShare, 

3304 self.library._validate_volume_for_manage, 

3305 fake.FLEXVOL_TO_MANAGE, 

3306 vserver_client) 

3307 

3308 @ddt.data( 

3309 {'fake_vserver': None, 'is_flexgroup': False}, 

3310 {'fake_vserver': fake.VSERVER1, 'is_flexgroup': False}, 

3311 {'fake_vserver': None, 'is_flexgroup': True}, 

3312 {'fake_vserver': fake.VSERVER1, 'is_flexgroup': True}) 

3313 @ddt.unpack 

3314 def test_manage_existing_snapshot(self, fake_vserver, is_flexgroup): 

3315 

3316 vserver_client = mock.Mock() 

3317 mock_get_vserver = self.mock_object( 

3318 self.library, '_get_vserver', 

3319 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3320 vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE 

3321 vserver_client.snapshot_exists.return_value = True 

3322 vserver_client.volume_has_snapmirror_relationships.return_value = False 

3323 

3324 result = self.library.manage_existing_snapshot( 

3325 fake.SNAPSHOT_TO_MANAGE, {}, share_server=fake_vserver) 

3326 

3327 share_name = self.library._get_backend_share_name( 

3328 fake.SNAPSHOT['share_id']) 

3329 mock_get_vserver.assert_called_once_with(share_server=fake_vserver) 

3330 vserver_client.snapshot_exists.assert_called_once_with( 

3331 fake.SNAPSHOT_NAME, share_name) 

3332 (vserver_client.volume_has_snapmirror_relationships. 

3333 assert_called_once_with(fake.FLEXVOL_TO_MANAGE)) 

3334 expected_result = {'size': 2} 

3335 self.assertEqual(expected_result, result) 

3336 

3337 def test_manage_existing_snapshot_no_snapshot_name(self): 

3338 

3339 vserver_client = mock.Mock() 

3340 self.mock_object(self.library, 

3341 '_get_vserver', 

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

3343 vserver_client))) 

3344 vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE 

3345 vserver_client.snapshot_exists.return_value = True 

3346 vserver_client.volume_has_snapmirror_relationships.return_value = False 

3347 fake_snapshot = copy.deepcopy(fake.SNAPSHOT_TO_MANAGE) 

3348 fake_snapshot['provider_location'] = '' 

3349 

3350 self.assertRaises(exception.ManageInvalidShareSnapshot, 

3351 self.library.manage_existing_snapshot, 

3352 fake_snapshot, {}) 

3353 

3354 @ddt.data(netapp_api.NaApiError, 

3355 exception.NetAppException) 

3356 def test_manage_existing_snapshot_get_volume_error(self, exception_type): 

3357 

3358 vserver_client = mock.Mock() 

3359 self.mock_object(self.library, 

3360 '_get_vserver', 

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

3362 vserver_client))) 

3363 vserver_client.get_volume.side_effect = exception_type 

3364 self.mock_object(self.client, 

3365 'volume_has_snapmirror_relationships', 

3366 mock.Mock(return_value=False)) 

3367 

3368 self.assertRaises(exception.ShareNotFound, 

3369 self.library.manage_existing_snapshot, 

3370 fake.SNAPSHOT_TO_MANAGE, {}) 

3371 

3372 def test_manage_existing_snapshot_not_from_share(self): 

3373 

3374 vserver_client = mock.Mock() 

3375 self.mock_object(self.library, 

3376 '_get_vserver', 

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

3378 vserver_client))) 

3379 vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE 

3380 vserver_client.snapshot_exists.return_value = False 

3381 

3382 self.assertRaises(exception.ManageInvalidShareSnapshot, 

3383 self.library.manage_existing_snapshot, 

3384 fake.SNAPSHOT_TO_MANAGE, {}) 

3385 

3386 def test_manage_existing_snapshot_mirrors_present(self): 

3387 

3388 vserver_client = mock.Mock() 

3389 self.mock_object(self.library, 

3390 '_get_vserver', 

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

3392 vserver_client))) 

3393 vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE 

3394 vserver_client.snapshot_exists.return_value = True 

3395 vserver_client.volume_has_snapmirror_relationships.return_value = True 

3396 

3397 self.assertRaises(exception.ManageInvalidShareSnapshot, 

3398 self.library.manage_existing_snapshot, 

3399 fake.SNAPSHOT_TO_MANAGE, {}) 

3400 

3401 @ddt.data(None, fake.VSERVER1) 

3402 def test_unmanage_snapshot(self, fake_vserver): 

3403 

3404 result = self.library.unmanage_snapshot(fake.SNAPSHOT, fake_vserver) 

3405 

3406 self.assertIsNone(result) 

3407 

3408 def test_validate_volume_for_manage_snapmirror_relationships_present(self): 

3409 

3410 vserver_client = mock.Mock() 

3411 vserver_client.volume_has_luns.return_value = False 

3412 vserver_client.volume_has_junctioned_volumes.return_value = False 

3413 vserver_client.volume_has_snapmirror_relationships.return_value = True 

3414 

3415 self.assertRaises(exception.ManageInvalidShare, 

3416 self.library._validate_volume_for_manage, 

3417 fake.FLEXVOL_TO_MANAGE, 

3418 vserver_client) 

3419 

3420 def test_create_consistency_group_from_cgsnapshot(self): 

3421 

3422 vserver_client = mock.Mock() 

3423 mock_get_vserver = self.mock_object( 

3424 self.library, '_get_vserver', 

3425 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3426 mock_allocate_container_from_snapshot = self.mock_object( 

3427 self.library, '_allocate_container_from_snapshot') 

3428 mock_create_export = self.mock_object( 

3429 self.library, '_create_export', 

3430 mock.Mock(side_effect=[['loc3'], ['loc4']])) 

3431 

3432 result = self.library.create_consistency_group_from_cgsnapshot( 

3433 self.context, 

3434 fake.CONSISTENCY_GROUP_DEST, 

3435 fake.CG_SNAPSHOT, 

3436 share_server=fake.SHARE_SERVER) 

3437 

3438 share_update_list = [ 

3439 {'id': fake.SHARE_ID3, 'export_locations': ['loc3']}, 

3440 {'id': fake.SHARE_ID4, 'export_locations': ['loc4']} 

3441 ] 

3442 expected = (None, share_update_list) 

3443 self.assertEqual(expected, result) 

3444 

3445 mock_allocate_container_from_snapshot.assert_has_calls([ 

3446 mock.call(fake.COLLATED_CGSNAPSHOT_INFO[0]['share'], 

3447 fake.COLLATED_CGSNAPSHOT_INFO[0]['snapshot'], 

3448 fake.VSERVER1, 

3449 vserver_client, 

3450 mock.ANY), 

3451 mock.call(fake.COLLATED_CGSNAPSHOT_INFO[1]['share'], 

3452 fake.COLLATED_CGSNAPSHOT_INFO[1]['snapshot'], 

3453 fake.VSERVER1, 

3454 vserver_client, 

3455 mock.ANY), 

3456 ]) 

3457 mock_create_export.assert_has_calls([ 

3458 mock.call(fake.COLLATED_CGSNAPSHOT_INFO[0]['share'], 

3459 fake.SHARE_SERVER, 

3460 fake.VSERVER1, 

3461 vserver_client), 

3462 mock.call(fake.COLLATED_CGSNAPSHOT_INFO[1]['share'], 

3463 fake.SHARE_SERVER, 

3464 fake.VSERVER1, 

3465 vserver_client), 

3466 ]) 

3467 mock_get_vserver.assert_called_once_with( 

3468 share_server=fake.SHARE_SERVER) 

3469 

3470 def test_create_consistency_group_from_cgsnapshot_no_members(self): 

3471 

3472 vserver_client = mock.Mock() 

3473 mock_get_vserver = self.mock_object( 

3474 self.library, '_get_vserver', 

3475 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3476 mock_allocate_container_from_snapshot = self.mock_object( 

3477 self.library, '_allocate_container_from_snapshot') 

3478 mock_create_export = self.mock_object( 

3479 self.library, '_create_export', 

3480 mock.Mock(side_effect=[['loc3'], ['loc4']])) 

3481 

3482 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 

3483 fake_cg_snapshot['share_group_snapshot_members'] = [] 

3484 

3485 result = self.library.create_consistency_group_from_cgsnapshot( 

3486 self.context, 

3487 fake.CONSISTENCY_GROUP_DEST, 

3488 fake_cg_snapshot, 

3489 share_server=fake.SHARE_SERVER) 

3490 

3491 self.assertEqual((None, None), result) 

3492 

3493 self.assertFalse(mock_allocate_container_from_snapshot.called) 

3494 self.assertFalse(mock_create_export.called) 

3495 mock_get_vserver.assert_called_once_with( 

3496 share_server=fake.SHARE_SERVER) 

3497 

3498 def test_collate_cg_snapshot_info(self): 

3499 

3500 result = self.library._collate_cg_snapshot_info( 

3501 fake.CONSISTENCY_GROUP_DEST, fake.CG_SNAPSHOT) 

3502 

3503 self.assertEqual(fake.COLLATED_CGSNAPSHOT_INFO, result) 

3504 

3505 def test_collate_cg_snapshot_info_invalid(self): 

3506 

3507 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 

3508 fake_cg_snapshot['share_group_snapshot_members'] = [] 

3509 

3510 self.assertRaises(exception.InvalidShareGroup, 

3511 self.library._collate_cg_snapshot_info, 

3512 fake.CONSISTENCY_GROUP_DEST, fake_cg_snapshot) 

3513 

3514 def test_create_cgsnapshot(self): 

3515 

3516 vserver_client = mock.Mock() 

3517 mock_get_vserver = self.mock_object( 

3518 self.library, '_get_vserver', 

3519 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3520 

3521 result = self.library.create_cgsnapshot( 

3522 self.context, 

3523 fake.CG_SNAPSHOT, 

3524 share_server=fake.SHARE_SERVER) 

3525 

3526 share_names = [ 

3527 self.library._get_backend_share_name( 

3528 fake.CG_SNAPSHOT_MEMBER_1['share_id']), 

3529 self.library._get_backend_share_name( 

3530 fake.CG_SNAPSHOT_MEMBER_2['share_id']) 

3531 ] 

3532 snapshot_name = self.library._get_backend_cg_snapshot_name( 

3533 fake.CG_SNAPSHOT['id']) 

3534 vserver_client.create_cg_snapshot.assert_called_once_with( 

3535 share_names, snapshot_name) 

3536 self.assertEqual((None, None), result) 

3537 mock_get_vserver.assert_called_once_with( 

3538 share_server=fake.SHARE_SERVER) 

3539 

3540 def test_create_cgsnapshot_no_members(self): 

3541 

3542 vserver_client = mock.Mock() 

3543 mock_get_vserver = self.mock_object( 

3544 self.library, '_get_vserver', 

3545 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3546 

3547 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 

3548 fake_cg_snapshot['share_group_snapshot_members'] = [] 

3549 

3550 result = self.library.create_cgsnapshot( 

3551 self.context, 

3552 fake_cg_snapshot, 

3553 share_server=fake.SHARE_SERVER) 

3554 

3555 self.assertFalse(vserver_client.create_cg_snapshot.called) 

3556 self.assertEqual((None, None), result) 

3557 mock_get_vserver.assert_called_once_with( 

3558 share_server=fake.SHARE_SERVER) 

3559 

3560 def test_delete_cgsnapshot(self): 

3561 

3562 vserver_client = mock.Mock() 

3563 mock_get_vserver = self.mock_object( 

3564 self.library, '_get_vserver', 

3565 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3566 mock_delete_snapshot = self.mock_object(self.library, 

3567 '_delete_snapshot') 

3568 

3569 result = self.library.delete_cgsnapshot( 

3570 self.context, 

3571 fake.CG_SNAPSHOT, 

3572 share_server=fake.SHARE_SERVER) 

3573 

3574 share_names = [ 

3575 self.library._get_backend_share_name( 

3576 fake.CG_SNAPSHOT_MEMBER_1['share_id']), 

3577 self.library._get_backend_share_name( 

3578 fake.CG_SNAPSHOT_MEMBER_2['share_id']) 

3579 ] 

3580 snapshot_name = self.library._get_backend_cg_snapshot_name( 

3581 fake.CG_SNAPSHOT['id']) 

3582 

3583 mock_delete_snapshot.assert_has_calls([ 

3584 mock.call(vserver_client, share_names[0], snapshot_name), 

3585 mock.call(vserver_client, share_names[1], snapshot_name) 

3586 ]) 

3587 self.assertEqual((None, None), result) 

3588 mock_get_vserver.assert_called_once_with( 

3589 share_server=fake.SHARE_SERVER) 

3590 

3591 def test_delete_cgsnapshot_no_members(self): 

3592 

3593 vserver_client = mock.Mock() 

3594 mock_get_vserver = self.mock_object( 

3595 self.library, '_get_vserver', 

3596 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3597 mock_delete_snapshot = self.mock_object(self.library, 

3598 '_delete_snapshot') 

3599 

3600 fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT) 

3601 fake_cg_snapshot['share_group_snapshot_members'] = [] 

3602 

3603 result = self.library.delete_cgsnapshot( 

3604 self.context, 

3605 fake_cg_snapshot, 

3606 share_server=fake.SHARE_SERVER) 

3607 

3608 self.assertFalse(mock_delete_snapshot.called) 

3609 self.assertEqual((None, None), result) 

3610 mock_get_vserver.assert_called_once_with( 

3611 share_server=fake.SHARE_SERVER) 

3612 

3613 def test_delete_cgsnapshot_snapshots_not_found(self): 

3614 

3615 vserver_client = mock.Mock() 

3616 mock_get_vserver = self.mock_object( 

3617 self.library, '_get_vserver', 

3618 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3619 mock_delete_snapshot = self.mock_object( 

3620 self.library, '_delete_snapshot', 

3621 mock.Mock(side_effect=exception.SnapshotResourceNotFound( 

3622 name='fake'))) 

3623 

3624 result = self.library.delete_cgsnapshot( 

3625 self.context, 

3626 fake.CG_SNAPSHOT, 

3627 share_server=fake.SHARE_SERVER) 

3628 

3629 share_names = [ 

3630 self.library._get_backend_share_name( 

3631 fake.CG_SNAPSHOT_MEMBER_1['share_id']), 

3632 self.library._get_backend_share_name( 

3633 fake.CG_SNAPSHOT_MEMBER_2['share_id']) 

3634 ] 

3635 snapshot_name = self.library._get_backend_cg_snapshot_name( 

3636 fake.CG_SNAPSHOT['id']) 

3637 

3638 mock_delete_snapshot.assert_has_calls([ 

3639 mock.call(vserver_client, share_names[0], snapshot_name), 

3640 mock.call(vserver_client, share_names[1], snapshot_name) 

3641 ]) 

3642 self.assertEqual((None, None), result) 

3643 mock_get_vserver.assert_called_once_with( 

3644 share_server=fake.SHARE_SERVER) 

3645 

3646 @ddt.data(exception.InvalidInput(reason='fake_reason'), 

3647 exception.VserverNotSpecified(), 

3648 exception.VserverNotFound(vserver='fake_vserver')) 

3649 def test_delete_cgsnapshot_no_share_server(self, 

3650 get_vserver_exception): 

3651 

3652 mock_get_vserver = self.mock_object( 

3653 self.library, '_get_vserver', 

3654 mock.Mock(side_effect=get_vserver_exception)) 

3655 

3656 result = self.library.delete_cgsnapshot( 

3657 self.context, 

3658 fake.EMPTY_CONSISTENCY_GROUP, 

3659 share_server=fake.SHARE_SERVER) 

3660 

3661 self.assertEqual((None, None), result) 

3662 self.assertEqual(1, lib_base.LOG.warning.call_count) 

3663 mock_get_vserver.assert_called_once_with( 

3664 share_server=fake.SHARE_SERVER) 

3665 

3666 def test_adjust_qos_policy_with_volume_resize_no_cluster_creds(self): 

3667 self.library._have_cluster_creds = False 

3668 self.mock_object(share_types, 'get_extra_specs_from_share') 

3669 

3670 retval = self.library._adjust_qos_policy_with_volume_resize( 

3671 fake.SHARE, 10, mock.Mock()) 

3672 

3673 self.assertIsNone(retval) 

3674 share_types.get_extra_specs_from_share.assert_not_called() 

3675 

3676 def test_adjust_qos_policy_with_volume_resize_no_qos_on_share(self): 

3677 self.library._have_cluster_creds = True 

3678 self.mock_object(share_types, 'get_extra_specs_from_share') 

3679 vserver_client = mock.Mock() 

3680 self.mock_object(vserver_client, 'get_volume', 

3681 mock.Mock(return_value=fake.FLEXVOL_WITHOUT_QOS)) 

3682 

3683 retval = self.library._adjust_qos_policy_with_volume_resize( 

3684 fake.SHARE, 10, vserver_client) 

3685 

3686 self.assertIsNone(retval) 

3687 share_types.get_extra_specs_from_share.assert_not_called() 

3688 

3689 def test_adjust_qos_policy_with_volume_resize_no_size_dependent_qos(self): 

3690 self.library._have_cluster_creds = True 

3691 self.mock_object(share_types, 'get_extra_specs_from_share', 

3692 mock.Mock(return_value=fake.EXTRA_SPEC_WITH_QOS)) 

3693 vserver_client = mock.Mock() 

3694 self.mock_object(vserver_client, 'get_volume', 

3695 mock.Mock(return_value=fake.FLEXVOL_WITH_QOS)) 

3696 self.mock_object(self.library, '_get_max_throughput') 

3697 self.mock_object(self.library._client, 'qos_policy_group_modify') 

3698 

3699 retval = self.library._adjust_qos_policy_with_volume_resize( 

3700 fake.SHARE, 10, vserver_client) 

3701 

3702 self.assertIsNone(retval) 

3703 share_types.get_extra_specs_from_share.assert_called_once_with( 

3704 fake.SHARE) 

3705 self.library._get_max_throughput.assert_not_called() 

3706 self.library._client.qos_policy_group_modify.assert_not_called() 

3707 

3708 def test_adjust_qos_policy_with_volume_resize(self): 

3709 self.library._have_cluster_creds = True 

3710 self.mock_object( 

3711 share_types, 'get_extra_specs_from_share', 

3712 mock.Mock(return_value=fake.EXTRA_SPEC_WITH_SIZE_DEPENDENT_QOS)) 

3713 vserver_client = mock.Mock() 

3714 self.mock_object(vserver_client, 'get_volume', 

3715 mock.Mock(return_value=fake.FLEXVOL_WITH_QOS)) 

3716 self.mock_object(self.library._client, 'qos_policy_group_modify') 

3717 

3718 retval = self.library._adjust_qos_policy_with_volume_resize( 

3719 fake.SHARE, 10, vserver_client) 

3720 

3721 expected_max_throughput = '10000B/s' 

3722 self.assertIsNone(retval) 

3723 share_types.get_extra_specs_from_share.assert_called_once_with( 

3724 fake.SHARE) 

3725 self.library._client.qos_policy_group_modify.assert_called_once_with( 

3726 fake.QOS_POLICY_GROUP_NAME, expected_max_throughput, None) 

3727 

3728 def test_extend_share(self): 

3729 

3730 vserver_client = mock.Mock() 

3731 self.mock_object(self.library, 

3732 '_get_vserver', 

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

3734 vserver_client))) 

3735 self.mock_object( 

3736 share_types, 'get_extra_specs_from_share', 

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

3738 mock_adjust_qos_policy = self.mock_object( 

3739 self.library, '_adjust_qos_policy_with_volume_resize') 

3740 

3741 mock_set_volume_size = self.mock_object(vserver_client, 

3742 'set_volume_size') 

3743 new_size = fake.SHARE['size'] * 2 

3744 

3745 self.library.extend_share(fake.SHARE, new_size) 

3746 

3747 mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size) 

3748 mock_adjust_qos_policy.assert_called_once_with( 

3749 fake.SHARE, new_size, vserver_client) 

3750 

3751 def test_shrink_share(self): 

3752 

3753 vserver_client = mock.Mock() 

3754 self.mock_object(self.library, 

3755 '_get_vserver', 

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

3757 vserver_client))) 

3758 self.mock_object(share_types, 'get_extra_specs_from_share') 

3759 self.mock_object(self.library, '_get_provisioning_options', 

3760 mock.Mock(return_value={})) 

3761 mock_adjust_qos_policy = self.mock_object( 

3762 self.library, '_adjust_qos_policy_with_volume_resize') 

3763 mock_set_volume_size = self.mock_object(vserver_client, 

3764 'set_volume_size') 

3765 new_size = fake.SHARE['size'] - 1 

3766 

3767 self.library.shrink_share(fake.SHARE, new_size) 

3768 

3769 mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size) 

3770 mock_adjust_qos_policy.assert_called_once_with( 

3771 fake.SHARE, new_size, vserver_client) 

3772 

3773 def test_shrinking_possible_data_loss(self): 

3774 

3775 naapi_error = self._mock_api_error(code=netapp_api.EVOLOPNOTSUPP, 

3776 message='Possible data loss') 

3777 

3778 vserver_client = mock.Mock() 

3779 self.mock_object(self.library, 

3780 '_get_vserver', 

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

3782 vserver_client))) 

3783 

3784 mock_set_volume_size = self.mock_object( 

3785 vserver_client, 'set_volume_size', naapi_error) 

3786 self.mock_object(share_types, 'get_extra_specs_from_share') 

3787 self.mock_object(self.library, '_get_provisioning_options', 

3788 mock.Mock(return_value={})) 

3789 

3790 new_size = fake.SHARE['size'] - 1 

3791 

3792 self.assertRaises(exception.ShareShrinkingPossibleDataLoss, 

3793 self.library.shrink_share, 

3794 fake.SHARE, new_size) 

3795 

3796 self.library._get_vserver.assert_called_once_with(share_server=None) 

3797 mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size) 

3798 

3799 def test_update_access(self): 

3800 

3801 vserver_client = mock.Mock() 

3802 mock_get_vserver = self.mock_object( 

3803 self.library, '_get_vserver', 

3804 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3805 protocol_helper = mock.Mock() 

3806 protocol_helper.update_access.return_value = None 

3807 self.mock_object(self.library, 

3808 '_get_helper', 

3809 mock.Mock(return_value=protocol_helper)) 

3810 self.mock_object(self.library, 

3811 '_is_readable_replica', 

3812 mock.Mock(return_value=True)) 

3813 mock_share_exists = self.mock_object(self.library, 

3814 '_share_exists', 

3815 mock.Mock(return_value=True)) 

3816 

3817 self.library.update_access(self.context, 

3818 fake.SHARE, 

3819 [fake.SHARE_ACCESS], 

3820 [], 

3821 [], 

3822 [], 

3823 share_server=fake.SHARE_SERVER) 

3824 

3825 mock_get_vserver.assert_called_once_with( 

3826 share_server=fake.SHARE_SERVER) 

3827 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

3828 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

3829 protocol_helper.set_client.assert_called_once_with(vserver_client) 

3830 protocol_helper.update_access.assert_called_once_with( 

3831 fake.SHARE, fake.SHARE_NAME, [fake.SHARE_ACCESS]) 

3832 

3833 @ddt.data(exception.InvalidInput(reason='fake_reason'), 

3834 exception.VserverNotSpecified(), 

3835 exception.VserverNotFound(vserver='fake_vserver')) 

3836 def test_update_access_no_share_server(self, get_vserver_exception): 

3837 

3838 mock_get_vserver = self.mock_object( 

3839 self.library, '_get_vserver', 

3840 mock.Mock(side_effect=get_vserver_exception)) 

3841 protocol_helper = mock.Mock() 

3842 protocol_helper.update_access.return_value = None 

3843 self.mock_object(self.library, 

3844 '_get_helper', 

3845 mock.Mock(return_value=protocol_helper)) 

3846 self.mock_object(self.library, 

3847 '_is_readable_replica', 

3848 mock.Mock(return_value=True)) 

3849 mock_share_exists = self.mock_object(self.library, '_share_exists') 

3850 

3851 self.library.update_access(self.context, 

3852 fake.SHARE, 

3853 [fake.SHARE_ACCESS], 

3854 [], 

3855 [], 

3856 [], 

3857 share_server=fake.SHARE_SERVER) 

3858 

3859 mock_get_vserver.assert_called_once_with( 

3860 share_server=fake.SHARE_SERVER) 

3861 self.assertFalse(mock_share_exists.called) 

3862 self.assertFalse(protocol_helper.set_client.called) 

3863 self.assertFalse(protocol_helper.update_access.called) 

3864 

3865 def test_update_access_share_not_found(self): 

3866 

3867 vserver_client = mock.Mock() 

3868 mock_get_vserver = self.mock_object( 

3869 self.library, '_get_vserver', 

3870 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3871 protocol_helper = mock.Mock() 

3872 protocol_helper.update_access.return_value = None 

3873 self.mock_object(self.library, 

3874 '_get_helper', 

3875 mock.Mock(return_value=protocol_helper)) 

3876 self.mock_object(self.library, 

3877 '_is_readable_replica', 

3878 mock.Mock(return_value=True)) 

3879 mock_share_exists = self.mock_object(self.library, 

3880 '_share_exists', 

3881 mock.Mock(return_value=False)) 

3882 

3883 self.assertRaises(exception.ShareResourceNotFound, 

3884 self.library.update_access, 

3885 self.context, 

3886 fake.SHARE, 

3887 [fake.SHARE_ACCESS], 

3888 [], 

3889 [], 

3890 [], 

3891 share_server=fake.SHARE_SERVER) 

3892 

3893 mock_get_vserver.assert_called_once_with( 

3894 share_server=fake.SHARE_SERVER) 

3895 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

3896 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

3897 self.assertFalse(protocol_helper.set_client.called) 

3898 self.assertFalse(protocol_helper.update_access.called) 

3899 

3900 def test_update_access_to_active_replica(self): 

3901 fake_share_copy = copy.deepcopy(fake.SHARE) 

3902 fake_share_copy['replica_state'] = constants.REPLICA_STATE_ACTIVE 

3903 vserver_client = mock.Mock() 

3904 mock_get_vserver = self.mock_object( 

3905 self.library, '_get_vserver', 

3906 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3907 self.mock_object(self.library, 

3908 '_is_readable_replica', 

3909 mock.Mock(return_value=True)) 

3910 protocol_helper = mock.Mock() 

3911 protocol_helper.update_access.return_value = None 

3912 self.mock_object(self.library, 

3913 '_get_helper', 

3914 mock.Mock(return_value=protocol_helper)) 

3915 mock_share_exists = self.mock_object(self.library, 

3916 '_share_exists', 

3917 mock.Mock(return_value=True)) 

3918 

3919 self.library.update_access(self.context, 

3920 fake_share_copy, 

3921 [fake.SHARE_ACCESS], 

3922 [], 

3923 [], 

3924 [], 

3925 share_server=fake.SHARE_SERVER) 

3926 

3927 mock_get_vserver.assert_called_once_with( 

3928 share_server=fake.SHARE_SERVER) 

3929 share_name = self.library._get_backend_share_name(fake.SHARE['id']) 

3930 mock_share_exists.assert_called_once_with(share_name, vserver_client) 

3931 protocol_helper.set_client.assert_called_once_with(vserver_client) 

3932 protocol_helper.update_access.assert_called_once_with( 

3933 fake.SHARE, fake.SHARE_NAME, [fake.SHARE_ACCESS]) 

3934 

3935 @ddt.data(True, False) 

3936 def test_update_access_to_in_sync_replica(self, is_readable): 

3937 

3938 fake_share_copy = copy.deepcopy(fake.SHARE) 

3939 self.mock_object(self.library, 

3940 '_is_readable_replica', 

3941 mock.Mock(return_value=is_readable)) 

3942 fake_share_copy['replica_state'] = constants.REPLICA_STATE_IN_SYNC 

3943 vserver_client = mock.Mock() 

3944 mock_get_vserver = self.mock_object( 

3945 self.library, '_get_vserver', 

3946 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

3947 protocol_helper = mock.Mock() 

3948 protocol_helper.update_access.return_value = None 

3949 self.mock_object(self.library, 

3950 '_get_helper', 

3951 mock.Mock(return_value=protocol_helper)) 

3952 self.mock_object(self.library, '_share_exists', 

3953 mock.Mock(return_value=True)) 

3954 

3955 self.library.update_access(self.context, 

3956 fake_share_copy, 

3957 [fake.SHARE_ACCESS], 

3958 [], 

3959 [], 

3960 [], 

3961 share_server=fake.SHARE_SERVER) 

3962 

3963 if is_readable: 

3964 mock_get_vserver.assert_called_once_with( 

3965 share_server=fake.SHARE_SERVER) 

3966 else: 

3967 mock_get_vserver.assert_not_called() 

3968 

3969 def test_setup_server(self): 

3970 self.assertRaises(NotImplementedError, 

3971 self.library.setup_server, 

3972 fake.NETWORK_INFO) 

3973 

3974 def test_teardown_server(self): 

3975 self.assertRaises(NotImplementedError, 

3976 self.library.teardown_server, 

3977 fake.SHARE_SERVER['backend_details']) 

3978 

3979 def test_get_network_allocations_number(self): 

3980 self.assertRaises(NotImplementedError, 

3981 self.library.get_network_allocations_number) 

3982 

3983 def test_update_ssc_info(self): 

3984 

3985 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

3986 self.library._have_cluster_creds = True 

3987 self.mock_object(self.library, 

3988 '_find_matching_aggregates', 

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

3990 self.mock_object(self.library, 

3991 '_get_flexgroup_aggr_set', 

3992 mock.Mock(return_value=fake.FLEXGROUP_AGGR_SET)) 

3993 self.mock_object(self.library, 

3994 '_get_aggregate_info', 

3995 mock.Mock(return_value=fake.SSC_INFO_MAP)) 

3996 

3997 self.library._update_ssc_info() 

3998 

3999 expected = { 

4000 fake.AGGREGATES[0]: { 

4001 'netapp_aggregate': fake.AGGREGATES[0], 

4002 'netapp_flexgroup': False, 

4003 'netapp_raid_type': 'raid4', 

4004 'netapp_disk_type': ['FCAL'], 

4005 'netapp_hybrid_aggregate': 'false', 

4006 'netapp_snaplock_type': ['compliance', 'enterprise'], 

4007 }, 

4008 fake.AGGREGATES[1]: { 

4009 'netapp_aggregate': fake.AGGREGATES[1], 

4010 'netapp_flexgroup': False, 

4011 'netapp_raid_type': 'raid_dp', 

4012 'netapp_disk_type': ['SATA', 'SSD'], 

4013 'netapp_hybrid_aggregate': 'true', 

4014 'netapp_snaplock_type': ['compliance', 'enterprise'], 

4015 }, 

4016 fake.FLEXGROUP_POOL_NAME: { 

4017 'netapp_aggregate': fake.FLEXGROUP_POOL['netapp_aggregate'], 

4018 'netapp_flexgroup': True, 

4019 'netapp_raid_type': 'raid4 raid_dp', 

4020 'netapp_disk_type': ['FCAL', 'SATA', 'SSD'], 

4021 'netapp_hybrid_aggregate': 'false true', 

4022 'netapp_snaplock_type': fake.FLEXGROUP_POOL[ 

4023 'netapp_snaplock_type'] 

4024 }, 

4025 } 

4026 

4027 self.assertEqual(expected, self.library._ssc_stats) 

4028 

4029 def test_update_ssc_info_non_unified_aggr(self): 

4030 

4031 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

4032 self.library._client.features.UNIFIED_AGGR = False 

4033 self.library._have_cluster_creds = True 

4034 self.mock_object(self.library, 

4035 '_find_matching_aggregates', 

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

4037 self.mock_object(self.library, 

4038 '_get_flexgroup_aggr_set', 

4039 mock.Mock(return_value=fake.FLEXGROUP_AGGR_SET)) 

4040 self.mock_object(self.library, 

4041 '_get_aggregate_info', 

4042 mock.Mock(return_value=fake.SSC_INFO_MAP)) 

4043 

4044 self.library._update_ssc_info() 

4045 

4046 expected = { 

4047 fake.AGGREGATES[0]: { 

4048 'netapp_aggregate': fake.AGGREGATES[0], 

4049 'netapp_flexgroup': False, 

4050 'netapp_raid_type': 'raid4', 

4051 'netapp_disk_type': ['FCAL'], 

4052 'netapp_hybrid_aggregate': 'false', 

4053 'netapp_snaplock_type': 'compliance', 

4054 }, 

4055 fake.AGGREGATES[1]: { 

4056 'netapp_aggregate': fake.AGGREGATES[1], 

4057 'netapp_flexgroup': False, 

4058 'netapp_raid_type': 'raid_dp', 

4059 'netapp_disk_type': ['SATA', 'SSD'], 

4060 'netapp_hybrid_aggregate': 'true', 

4061 'netapp_snaplock_type': 'enterprise', 

4062 }, 

4063 fake.FLEXGROUP_POOL_NAME: { 

4064 'netapp_aggregate': fake.FLEXGROUP_POOL['netapp_aggregate'], 

4065 'netapp_flexgroup': True, 

4066 'netapp_raid_type': 'raid4 raid_dp', 

4067 'netapp_disk_type': ['FCAL', 'SATA', 'SSD'], 

4068 'netapp_hybrid_aggregate': 'false true', 

4069 'netapp_snaplock_type': 'compliance enterprise', 

4070 }, 

4071 } 

4072 self.assertEqual(expected, self.library._ssc_stats) 

4073 

4074 def test_update_ssc_info_no_aggregates(self): 

4075 

4076 self.library._flexgroup_pools = {} 

4077 self.mock_object(self.library, 

4078 '_find_matching_aggregates', 

4079 mock.Mock(return_value=[])) 

4080 

4081 self.library._update_ssc_info() 

4082 

4083 self.assertDictEqual({}, self.library._ssc_stats) 

4084 

4085 def test_update_ssc_info_no_cluster_creds(self): 

4086 

4087 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

4088 self.library._have_cluster_creds = False 

4089 self.mock_object(self.library, 

4090 '_find_matching_aggregates', 

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

4092 self.mock_object(self.library, 

4093 '_get_flexgroup_aggr_set', 

4094 mock.Mock(return_value=fake.FLEXGROUP_AGGR_SET)) 

4095 self.mock_object(self.library, 

4096 '_get_aggregate_info', 

4097 mock.Mock(return_value=fake.SSC_INFO_MAP)) 

4098 self.mock_object(self.client, 

4099 'get_vserver_aggr_snaplock_type', 

4100 mock.Mock(return_value='compliance')) 

4101 

4102 self.library._update_ssc_info() 

4103 

4104 expected = { 

4105 fake.AGGREGATES[0]: { 

4106 'netapp_aggregate': fake.AGGREGATES[0], 

4107 'netapp_flexgroup': False, 

4108 'netapp_snaplock_type': ['compliance', 'enterprise'], 

4109 }, 

4110 fake.AGGREGATES[1]: { 

4111 'netapp_aggregate': fake.AGGREGATES[1], 

4112 'netapp_flexgroup': False, 

4113 'netapp_snaplock_type': ['compliance', 'enterprise'], 

4114 }, 

4115 fake.FLEXGROUP_POOL_NAME: { 

4116 'netapp_aggregate': fake.FLEXGROUP_POOL['netapp_aggregate'], 

4117 'netapp_flexgroup': True, 

4118 }, 

4119 } 

4120 

4121 self.assertDictEqual(self.library._ssc_stats, expected) 

4122 

4123 def test_get_aggregate_info(self): 

4124 mock_get_aggregate = self.mock_object( 

4125 self.client, 'get_aggregate', 

4126 mock.Mock(side_effect=fake.SSC_AGGREGATES)) 

4127 mock_get_aggregate_disk_types = self.mock_object( 

4128 self.client, 'get_aggregate_disk_types', 

4129 mock.Mock(side_effect=fake.SSC_DISK_TYPES)) 

4130 

4131 result = self.library._get_aggregate_info(fake.AGGREGATES) 

4132 

4133 expected = { 

4134 fake.AGGREGATES[0]: { 

4135 'netapp_raid_type': 'raid4', 

4136 'netapp_disk_type': 'FCAL', 

4137 'netapp_hybrid_aggregate': 'false', 

4138 'netapp_is_home': False, 

4139 'netapp_snaplock_type': 'compliance', 

4140 }, 

4141 fake.AGGREGATES[1]: { 

4142 'netapp_raid_type': 'raid_dp', 

4143 'netapp_disk_type': ['SATA', 'SSD'], 

4144 'netapp_hybrid_aggregate': 'true', 

4145 'netapp_is_home': True, 

4146 'netapp_snaplock_type': 'enterprise', 

4147 }, 

4148 } 

4149 

4150 self.assertDictEqual(result, expected) 

4151 mock_get_aggregate.assert_has_calls([ 

4152 mock.call(fake.AGGREGATES[0]), 

4153 mock.call(fake.AGGREGATES[1]), 

4154 ]) 

4155 mock_get_aggregate_disk_types.assert_has_calls([ 

4156 mock.call(fake.AGGREGATES[0]), 

4157 mock.call(fake.AGGREGATES[1]), 

4158 ]) 

4159 

4160 @ddt.data( 

4161 {'is_readable': True, 'rules_status': constants.STATUS_ACTIVE}, 

4162 {'is_readable': True, 'rules_status': ( 

4163 constants.SHARE_INSTANCE_RULES_ERROR)}, 

4164 {'is_readable': False, 'rules_status': constants.STATUS_ACTIVE}) 

4165 @ddt.unpack 

4166 def test_create_replica(self, is_readable, rules_status): 

4167 

4168 vserver_client = mock.Mock() 

4169 self.mock_object(self.library, 

4170 '_allocate_container') 

4171 mock_dm_session = mock.Mock() 

4172 self.mock_object(data_motion, "DataMotionSession", 

4173 mock.Mock(return_value=mock_dm_session)) 

4174 self.mock_object(data_motion, 'get_client_for_backend', 

4175 mock.Mock(return_value=vserver_client)) 

4176 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4178 self.mock_object(self.library, '_get_backend_share_name', 

4179 mock.Mock(return_value=fake.SHARE_NAME)) 

4180 mock_is_readable = self.mock_object( 

4181 self.library, '_is_readable_replica', 

4182 mock.Mock(return_value=is_readable)) 

4183 

4184 mock_create_export = self.mock_object( 

4185 self.library, '_create_export', mock.Mock(return_value=[])) 

4186 protocol_helper = mock.Mock() 

4187 if rules_status == constants.STATUS_ACTIVE: 

4188 protocol_helper.update_access.return_value = None 

4189 else: 

4190 protocol_helper.update_access.side_effect = ( 

4191 netapp_api.NaApiError(code=0)) 

4192 mock_get_helper = self.mock_object( 

4193 self.library, '_get_helper', 

4194 mock.Mock(return_value=protocol_helper)) 

4195 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

4196 mock.Mock(return_value=(fake.SHARE_NAME, 

4197 fake.VSERVER1, 

4198 fake.BACKEND_NAME))) 

4199 self.mock_object(self.library, '_is_flexgroup_share', 

4200 mock.Mock(return_value=False)) 

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

4202 mock.Mock(return_value=False)) 

4203 self.mock_object(na_utils, 'get_relationship_type', 

4204 mock.Mock(return_value=na_utils.DATA_PROTECTION_TYPE)) 

4205 expected_model_update = { 

4206 'export_locations': [], 

4207 'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC, 

4208 'access_rules_status': rules_status, 

4209 } 

4210 

4211 model_update = self.library.create_replica( 

4212 None, [fake.SHARE], fake.SHARE, [fake.SHARE_ACCESS], [], 

4213 share_server=None) 

4214 

4215 self.assertDictEqual(expected_model_update, model_update) 

4216 mock_dm_session.create_snapmirror.assert_called_once_with( 

4217 fake.SHARE, fake.SHARE, na_utils.DATA_PROTECTION_TYPE, 

4218 mount=is_readable) 

4219 mock_is_readable.assert_called_once_with(fake.SHARE) 

4220 if is_readable: 

4221 mock_create_export.assert_called_once_with( 

4222 fake.SHARE, None, fake.VSERVER1, vserver_client, replica=True) 

4223 mock_get_helper.assert_called_once_with(fake.SHARE) 

4224 protocol_helper.update_access.assert_called_once_with( 

4225 fake.SHARE, fake.SHARE_NAME, [fake.SHARE_ACCESS]) 

4226 else: 

4227 mock_create_export.assert_not_called() 

4228 mock_get_helper.assert_not_called() 

4229 protocol_helper.update_access.assert_not_called() 

4230 

4231 data_motion.get_client_for_backend.assert_has_calls( 

4232 [mock.call(fake.BACKEND_NAME, vserver_name=fake.VSERVER1), 

4233 mock.call(fake.BACKEND_NAME, vserver_name=fake.VSERVER1)]) 

4234 self.library._is_flexgroup_pool.assert_called_once_with(fake.POOL_NAME) 

4235 na_utils.get_relationship_type.assert_called_once_with(False) 

4236 

4237 def test_create_replica_with_share_server(self): 

4238 self.mock_object(self.library, 

4239 '_allocate_container', 

4240 mock.Mock()) 

4241 mock_dm_session = mock.Mock() 

4242 self.mock_object(data_motion, "DataMotionSession", 

4243 mock.Mock(return_value=mock_dm_session)) 

4244 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

4245 mock.Mock(return_value=(fake.SHARE_NAME, 

4246 fake.VSERVER1, 

4247 fake.BACKEND_NAME))) 

4248 self.mock_object(self.library, '_is_flexgroup_share', 

4249 mock.Mock(return_value=False)) 

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

4251 mock.Mock(return_value=False)) 

4252 self.mock_object(data_motion, 'get_client_for_backend') 

4253 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4255 self.mock_object(self.library, 

4256 '_is_readable_replica', 

4257 mock.Mock(return_value=False)) 

4258 expected_model_update = { 

4259 'export_locations': [], 

4260 'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC, 

4261 'access_rules_status': constants.STATUS_ACTIVE, 

4262 } 

4263 

4264 model_update = self.library.create_replica( 

4265 None, [fake.SHARE], fake.SHARE, [], [], 

4266 share_server=fake.SHARE_SERVER) 

4267 

4268 self.assertDictEqual(expected_model_update, model_update) 

4269 mock_dm_session.create_snapmirror.assert_called_once_with( 

4270 fake.SHARE, fake.SHARE, na_utils.DATA_PROTECTION_TYPE, 

4271 mount=False) 

4272 data_motion.get_client_for_backend.assert_has_calls( 

4273 [mock.call(fake.BACKEND_NAME, vserver_name=fake.VSERVER1), 

4274 mock.call(fake.BACKEND_NAME, vserver_name=fake.VSERVER1)]) 

4275 self.library._is_flexgroup_pool.assert_called_once_with(fake.POOL_NAME) 

4276 

4277 def test_create_replica_raise_different_type(self): 

4278 

4279 mock_dm_session = mock.Mock() 

4280 self.mock_object(data_motion, "DataMotionSession", 

4281 mock.Mock(return_value=mock_dm_session)) 

4282 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

4283 mock.Mock(return_value=(fake.SHARE_NAME, 

4284 fake.VSERVER1, 

4285 fake.BACKEND_NAME))) 

4286 self.mock_object(self.library, '_is_flexgroup_share', 

4287 mock.Mock(return_value=True)) 

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

4289 mock.Mock(return_value=False)) 

4290 self.mock_object(data_motion, 'get_client_for_backend') 

4291 

4292 self.assertRaises(exception.NetAppException, 

4293 self.library.create_replica, 

4294 None, [fake.SHARE], fake.SHARE, [], [], 

4295 share_server=None) 

4296 

4297 def test_create_replica_raise_flexgroup_no_fan_out_limit(self): 

4298 

4299 mock_dm_session = mock.Mock() 

4300 self.mock_object(data_motion, "DataMotionSession", 

4301 mock.Mock(return_value=mock_dm_session)) 

4302 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

4303 mock.Mock(return_value=(fake.SHARE_NAME, 

4304 fake.VSERVER1, 

4305 fake.BACKEND_NAME))) 

4306 self.mock_object(self.library, '_is_flexgroup_share', 

4307 mock.Mock(return_value=True)) 

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

4309 mock.Mock(return_value=True)) 

4310 

4311 mock_src_client = mock.Mock() 

4312 self.mock_object(mock_src_client, 

4313 'is_flexgroup_fan_out_supported', 

4314 mock.Mock(return_value=False)) 

4315 self.mock_object(self.library._client, 

4316 'is_flexgroup_fan_out_supported', 

4317 mock.Mock(return_value=False)) 

4318 self.mock_object(data_motion, 'get_client_for_backend', 

4319 mock.Mock(return_value=mock_src_client)) 

4320 

4321 self.assertRaises(exception.NetAppException, 

4322 self.library.create_replica, 

4323 None, [fake.SHARE, fake.SHARE, fake.SHARE], 

4324 fake.SHARE, [], [], share_server=None) 

4325 

4326 def test_delete_replica(self): 

4327 

4328 active_replica = fake_replica( 

4329 replica_state=constants.REPLICA_STATE_ACTIVE) 

4330 replica_1 = fake_replica( 

4331 replica_state=constants.REPLICA_STATE_IN_SYNC, 

4332 host=fake.MANILA_HOST_NAME) 

4333 replica_2 = fake_replica( 

4334 replica_state=constants.REPLICA_STATE_OUT_OF_SYNC) 

4335 replica_list = [active_replica, replica_1, replica_2] 

4336 

4337 self.mock_object(self.library, 

4338 '_delete_share', 

4339 mock.Mock()) 

4340 mock_dm_session = mock.Mock() 

4341 self.mock_object(data_motion, "DataMotionSession", 

4342 mock.Mock(return_value=mock_dm_session)) 

4343 self.mock_object(data_motion, 'get_client_for_backend') 

4344 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4346 self.mock_object(self.library, 

4347 '_is_readable_replica', 

4348 mock.Mock(return_value=False)) 

4349 

4350 result = self.library.delete_replica(None, 

4351 replica_list, 

4352 replica_1, 

4353 [], 

4354 share_server=None) 

4355 self.assertIsNone(result) 

4356 mock_dm_session.delete_snapmirror.assert_has_calls([ 

4357 mock.call(active_replica, replica_1), 

4358 mock.call(replica_2, replica_1), 

4359 mock.call(replica_1, replica_2), 

4360 mock.call(replica_1, active_replica)], 

4361 any_order=True) 

4362 self.assertEqual(4, mock_dm_session.delete_snapmirror.call_count) 

4363 data_motion.get_client_for_backend.assert_called_with( 

4364 fake.BACKEND_NAME, vserver_name=mock.ANY) 

4365 self.assertEqual(1, data_motion.get_client_for_backend.call_count) 

4366 

4367 def test_delete_replica_with_share_server(self): 

4368 

4369 active_replica = fake_replica( 

4370 replica_state=constants.REPLICA_STATE_ACTIVE) 

4371 replica = fake_replica(replica_state=constants.REPLICA_STATE_IN_SYNC, 

4372 host=fake.MANILA_HOST_NAME) 

4373 replica_list = [active_replica, replica] 

4374 

4375 self.mock_object(self.library, 

4376 '_is_readable_replica', 

4377 mock.Mock(return_value=False)) 

4378 self.mock_object(self.library, 

4379 '_delete_share', 

4380 mock.Mock()) 

4381 mock_dm_session = mock.Mock() 

4382 self.mock_object(data_motion, "DataMotionSession", 

4383 mock.Mock(return_value=mock_dm_session)) 

4384 self.mock_object(data_motion, 'get_client_for_backend') 

4385 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4387 

4388 result = self.library.delete_replica(None, 

4389 replica_list, 

4390 replica, 

4391 [], 

4392 share_server=fake.SHARE_SERVER) 

4393 self.assertIsNone(result) 

4394 mock_dm_session.delete_snapmirror.assert_has_calls([ 

4395 mock.call(active_replica, replica), 

4396 mock.call(replica, active_replica)], 

4397 any_order=True) 

4398 data_motion.get_client_for_backend.assert_called_once_with( 

4399 fake.BACKEND_NAME, vserver_name=fake.VSERVER1) 

4400 

4401 @ddt.data({'seconds': 3600, 'schedule': 'hourly'}, 

4402 {'seconds': (5 * 3600), 'schedule': '5hourly'}, 

4403 {'seconds': (30 * 60), 'schedule': '30minute'}, 

4404 {'seconds': (2 * 24 * 3600), 'schedule': '2DAY'}, 

4405 {'seconds': 3600, 'schedule': 'fake_shedule'}, 

4406 {'seconds': 3600, 'schedule': 'fake2'}, 

4407 {'seconds': 3600, 'schedule': '10fake'}) 

4408 @ddt.unpack 

4409 def test__convert_schedule_to_seconds(self, seconds, schedule): 

4410 expected_return = seconds 

4411 actual_return = self.library._convert_schedule_to_seconds(schedule) 

4412 self.assertEqual(expected_return, actual_return) 

4413 

4414 def test_update_replica_state_no_snapmirror_share_creating(self): 

4415 vserver_client = mock.Mock() 

4416 self.mock_object(vserver_client, 'volume_exists', 

4417 mock.Mock(return_value=True)) 

4418 self.mock_object(self.library, 

4419 '_get_vserver', 

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

4421 vserver_client))) 

4422 self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[]) 

4423 self.mock_object(self.library, 

4424 '_is_readable_replica', 

4425 mock.Mock(return_value=False)) 

4426 replica = copy.deepcopy(fake.SHARE) 

4427 replica['status'] = constants.STATUS_CREATING 

4428 

4429 result = self.library.update_replica_state( 

4430 None, [replica], replica, None, [], share_server=None) 

4431 

4432 self.assertFalse(self.mock_dm_session.create_snapmirror.called) 

4433 self.assertEqual(constants.STATUS_OUT_OF_SYNC, result) 

4434 

4435 def test_update_replica_state_share_reverting_to_snapshot(self): 

4436 vserver_client = mock.Mock() 

4437 self.mock_object(vserver_client, 'volume_exists', 

4438 mock.Mock(return_value=True)) 

4439 self.mock_object(self.library, 

4440 '_get_vserver', 

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

4442 vserver_client))) 

4443 self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[]) 

4444 

4445 replica = copy.deepcopy(fake.SHARE) 

4446 replica['status'] = constants.STATUS_REVERTING 

4447 

4448 result = self.library.update_replica_state( 

4449 None, [replica], replica, None, [], share_server=None) 

4450 

4451 self.assertFalse(self.mock_dm_session.get_snapmirrors.called) 

4452 self.assertFalse(self.mock_dm_session.create_snapmirror.called) 

4453 self.assertIsNone(result) 

4454 

4455 def test_update_replica_state_no_snapmirror_create_failed(self): 

4456 vserver_client = mock.Mock() 

4457 self.mock_object(vserver_client, 'volume_exists', 

4458 mock.Mock(return_value=True)) 

4459 self.mock_object(self.library, 

4460 '_get_vserver', 

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

4462 vserver_client))) 

4463 self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[]) 

4464 self.mock_object(self.library, 

4465 '_is_readable_replica', 

4466 mock.Mock(return_value=False)) 

4467 self.mock_object(share_utils, 

4468 'extract_host', 

4469 mock.Mock(return_value=fake.POOL_NAME)) 

4470 self.mock_object(self.library, 

4471 '_is_flexgroup_pool', 

4472 mock.Mock(return_value=False)) 

4473 self.mock_object(na_utils, 

4474 'get_relationship_type', 

4475 mock.Mock(return_value=na_utils.DATA_PROTECTION_TYPE)) 

4476 self.mock_dm_session.create_snapmirror.side_effect = ( 

4477 netapp_api.NaApiError(code=0)) 

4478 

4479 replica = copy.deepcopy(fake.SHARE) 

4480 replica['status'] = constants.REPLICA_STATE_OUT_OF_SYNC 

4481 

4482 result = self.library.update_replica_state( 

4483 None, [replica], replica, None, [], share_server=None) 

4484 

4485 self.assertTrue(self.mock_dm_session.create_snapmirror.called) 

4486 self.assertEqual(constants.STATUS_ERROR, result) 

4487 

4488 @ddt.data(constants.STATUS_ERROR, constants.STATUS_AVAILABLE) 

4489 def test_update_replica_state_no_snapmirror(self, status): 

4490 vserver_client = mock.Mock() 

4491 self.mock_object(vserver_client, 'volume_exists', 

4492 mock.Mock(return_value=True)) 

4493 self.mock_object(self.library, 

4494 '_get_vserver', 

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

4496 vserver_client))) 

4497 self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[]) 

4498 self.mock_object(self.library, 

4499 '_is_readable_replica', 

4500 mock.Mock(return_value=False)) 

4501 self.mock_object(share_utils, 

4502 'extract_host', 

4503 mock.Mock(return_value=fake.POOL_NAME)) 

4504 self.mock_object(self.library, 

4505 '_is_flexgroup_pool', 

4506 mock.Mock(return_value=False)) 

4507 self.mock_object(na_utils, 

4508 'get_relationship_type', 

4509 mock.Mock(return_value=na_utils.DATA_PROTECTION_TYPE)) 

4510 

4511 replica = copy.deepcopy(fake.SHARE) 

4512 replica['status'] = status 

4513 

4514 result = self.library.update_replica_state( 

4515 None, [replica], replica, None, [], share_server=None) 

4516 

4517 self.assertEqual(1, 

4518 self.mock_dm_session.create_snapmirror.call_count) 

4519 self.assertEqual(constants.STATUS_OUT_OF_SYNC, result) 

4520 

4521 def test_update_replica_state_broken_snapmirror(self): 

4522 fake_snapmirror = { 

4523 'mirror-state': 'broken-off', 

4524 'relationship-status': 'idle', 

4525 'source-vserver': fake.VSERVER2, 

4526 'source-volume': 'fake_volume', 

4527 'last-transfer-end-timestamp': '%s' % float(time.time() - 10000) 

4528 } 

4529 vserver_client = mock.Mock() 

4530 self.mock_object(vserver_client, 'volume_exists', 

4531 mock.Mock(return_value=True)) 

4532 self.mock_object(self.library, 

4533 '_get_vserver', 

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

4535 vserver_client))) 

4536 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4537 return_value=[fake_snapmirror]) 

4538 self.mock_object(self.library, 

4539 '_is_readable_replica', 

4540 mock.Mock(return_value=False)) 

4541 

4542 result = self.library.update_replica_state(None, [fake.SHARE], 

4543 fake.SHARE, None, [], 

4544 share_server=None) 

4545 

4546 vserver_client.resync_snapmirror_vol.assert_called_once_with( 

4547 fake.VSERVER2, 'fake_volume', fake.VSERVER1, fake.SHARE['name'] 

4548 ) 

4549 

4550 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result) 

4551 

4552 def test_update_replica_state_snapmirror_still_initializing(self): 

4553 fake_snapmirror = { 

4554 'mirror-state': 'uninitialized', 

4555 'relationship-status': 'transferring', 

4556 'source-vserver': fake.VSERVER2, 

4557 'source-volume': 'fake_volume', 

4558 'last-transfer-end-timestamp': '%s' % float(time.time() - 10000) 

4559 } 

4560 vserver_client = mock.Mock() 

4561 self.mock_object(vserver_client, 'volume_exists', 

4562 mock.Mock(return_value=True)) 

4563 self.mock_object(self.library, 

4564 '_get_vserver', 

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

4566 vserver_client))) 

4567 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4568 return_value=[fake_snapmirror]) 

4569 self.mock_object(self.library, 

4570 '_is_readable_replica', 

4571 mock.Mock(return_value=False)) 

4572 

4573 result = self.library.update_replica_state(None, [fake.SHARE], 

4574 fake.SHARE, None, [], 

4575 share_server=None) 

4576 

4577 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result) 

4578 

4579 def test_update_replica_state_fail_to_get_snapmirrors(self): 

4580 vserver_client = mock.Mock() 

4581 self.mock_object(vserver_client, 'volume_exists', 

4582 mock.Mock(return_value=True)) 

4583 self.mock_object(self.library, 

4584 '_get_vserver', 

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

4586 vserver_client))) 

4587 self.mock_dm_session.get_snapmirrors.side_effect = ( 

4588 netapp_api.NaApiError(code=0)) 

4589 

4590 result = self.library.update_replica_state(None, [fake.SHARE], 

4591 fake.SHARE, None, [], 

4592 share_server=None) 

4593 self.assertTrue(self.mock_dm_session.get_snapmirrors.called) 

4594 self.assertEqual(constants.STATUS_ERROR, result) 

4595 

4596 def test_update_replica_state_broken_snapmirror_resync_error(self): 

4597 fake_snapmirror = { 

4598 'mirror-state': 'broken-off', 

4599 'relationship-status': 'idle', 

4600 'source-vserver': fake.VSERVER2, 

4601 'source-volume': 'fake_volume', 

4602 'last-transfer-end-timestamp': '%s' % float(time.time() - 10000) 

4603 } 

4604 vserver_client = mock.Mock() 

4605 self.mock_object(vserver_client, 'volume_exists', 

4606 mock.Mock(return_value=True)) 

4607 self.mock_object(self.library, 

4608 '_get_vserver', 

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

4610 vserver_client))) 

4611 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4612 return_value=[fake_snapmirror]) 

4613 self.mock_object(self.library, 

4614 '_is_readable_replica', 

4615 mock.Mock(return_value=False)) 

4616 vserver_client.resync_snapmirror_vol.side_effect = ( 

4617 netapp_api.NaApiError) 

4618 

4619 result = self.library.update_replica_state(None, [fake.SHARE], 

4620 fake.SHARE, None, [], 

4621 share_server=None) 

4622 

4623 vserver_client.resync_snapmirror_vol.assert_called_once_with( 

4624 fake.VSERVER2, 'fake_volume', fake.VSERVER1, fake.SHARE['name'] 

4625 ) 

4626 

4627 self.assertEqual(constants.STATUS_ERROR, result) 

4628 

4629 def test_update_replica_state_stale_snapmirror(self): 

4630 fake_snapmirror = { 

4631 'mirror-state': 'snapmirrored', 

4632 'schedule': self.library.configuration.netapp_snapmirror_schedule, 

4633 'last-transfer-end-timestamp': '%s' % float( 

4634 timeutils.utcnow_ts() - 10000) 

4635 } 

4636 vserver_client = mock.Mock() 

4637 self.mock_object(vserver_client, 'volume_exists', 

4638 mock.Mock(return_value=True)) 

4639 self.mock_object(self.library, 

4640 '_get_vserver', 

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

4642 vserver_client))) 

4643 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4644 return_value=[fake_snapmirror]) 

4645 self.mock_object(self.library, 

4646 '_is_readable_replica', 

4647 mock.Mock(return_value=False)) 

4648 mock_backend_config = fake.get_config_cmode() 

4649 self.mock_object(data_motion, 'get_backend_configuration', 

4650 mock.Mock(return_value=mock_backend_config)) 

4651 

4652 result = self.library.update_replica_state(None, [fake.SHARE], 

4653 fake.SHARE, None, [], 

4654 share_server=None) 

4655 

4656 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result) 

4657 

4658 def test_update_replica_state_in_sync(self): 

4659 fake_snapmirror = { 

4660 'mirror-state': 'snapmirrored', 

4661 'schedule': self.library.configuration.netapp_snapmirror_schedule, 

4662 'relationship-status': 'idle', 

4663 'last-transfer-end-timestamp': '%s' % float(time.time()) 

4664 } 

4665 vserver_client = mock.Mock() 

4666 self.mock_object(vserver_client, 'volume_exists', 

4667 mock.Mock(return_value=True)) 

4668 self.mock_object(self.library, 

4669 '_get_vserver', 

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

4671 vserver_client))) 

4672 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4673 return_value=[fake_snapmirror]) 

4674 self.mock_object(self.library, 

4675 '_is_readable_replica', 

4676 mock.Mock(return_value=False)) 

4677 mock_backend_config = fake.get_config_cmode() 

4678 self.mock_object(data_motion, 'get_backend_configuration', 

4679 mock.Mock(return_value=mock_backend_config)) 

4680 

4681 result = self.library.update_replica_state(None, [fake.SHARE], 

4682 fake.SHARE, None, [], 

4683 share_server=None) 

4684 

4685 (self.mock_dm_session.cleanup_previous_snapmirror_relationships 

4686 .assert_not_called()) 

4687 self.assertEqual(constants.REPLICA_STATE_IN_SYNC, result) 

4688 

4689 def test_update_replica_state_replica_change_to_in_sycn(self): 

4690 fake_snapmirror = { 

4691 'mirror-state': 'snapmirrored', 

4692 'relationship-status': 'idle', 

4693 'last-transfer-end-timestamp': '%s' % float(time.time()) 

4694 } 

4695 # fake SHARE has replica_state set to active already 

4696 active_replica = fake.SHARE 

4697 out_of_sync_replica = copy.deepcopy(fake.SHARE) 

4698 out_of_sync_replica['replica_state'] = ( 

4699 constants.REPLICA_STATE_OUT_OF_SYNC) 

4700 replica_list = [out_of_sync_replica, active_replica] 

4701 vserver_client = mock.Mock() 

4702 self.mock_object(vserver_client, 'volume_exists', 

4703 mock.Mock(return_value=True)) 

4704 self.mock_object(self.library, 

4705 '_get_vserver', 

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

4707 vserver_client))) 

4708 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4709 return_value=[fake_snapmirror]) 

4710 mock_config = mock.Mock() 

4711 mock_config.safe_get = mock.Mock(return_value=0) 

4712 self.mock_object(data_motion, 'get_backend_configuration', 

4713 mock.Mock(return_value=mock_config)) 

4714 self.mock_object(self.library, 

4715 '_is_readable_replica', 

4716 mock.Mock(return_value=False)) 

4717 

4718 result = self.library.update_replica_state( 

4719 None, replica_list, out_of_sync_replica, 

4720 None, [], share_server=None) 

4721 

4722 # Expect a snapmirror cleanup as replica was in out of sync state 

4723 (self.mock_dm_session.cleanup_previous_snapmirror_relationships 

4724 .assert_called_once_with(out_of_sync_replica, replica_list)) 

4725 self.assertEqual(constants.REPLICA_STATE_IN_SYNC, result) 

4726 

4727 def test_update_replica_state_backend_volume_absent(self): 

4728 vserver_client = mock.Mock() 

4729 self.mock_object(vserver_client, 'volume_exists', 

4730 mock.Mock(return_value=False)) 

4731 self.mock_object(self.library, 

4732 '_get_vserver', 

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

4734 vserver_client))) 

4735 

4736 self.assertRaises(exception.ShareResourceNotFound, 

4737 self.library.update_replica_state, 

4738 None, [fake.SHARE], fake.SHARE, None, [], 

4739 share_server=None) 

4740 

4741 def test_update_replica_state_in_sync_with_snapshots(self): 

4742 fake_snapmirror = { 

4743 'mirror-state': 'snapmirrored', 

4744 'schedule': self.library.configuration.netapp_snapmirror_schedule, 

4745 'relationship-status': 'idle', 

4746 'last-transfer-end-timestamp': '%s' % float(time.time()) 

4747 } 

4748 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

4749 fake_snapshot['share_id'] = fake.SHARE['id'] 

4750 fake_snapshot['provider_location'] = 'fake' 

4751 snapshots = [{'share_replica_snapshot': fake_snapshot}] 

4752 vserver_client = mock.Mock() 

4753 self.mock_object(vserver_client, 'snapshot_exists', mock.Mock( 

4754 return_value=True)) 

4755 self.mock_object(self.library, 

4756 '_get_vserver', 

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

4758 vserver_client))) 

4759 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4760 return_value=[fake_snapmirror]) 

4761 self.mock_object(self.library, 

4762 '_is_readable_replica', 

4763 mock.Mock(return_value=False)) 

4764 mock_backend_config = fake.get_config_cmode() 

4765 self.mock_object(data_motion, 'get_backend_configuration', 

4766 mock.Mock(return_value=mock_backend_config)) 

4767 

4768 result = self.library.update_replica_state(None, [fake.SHARE], 

4769 fake.SHARE, None, snapshots, 

4770 share_server=None) 

4771 

4772 (self.mock_dm_session.cleanup_previous_snapmirror_relationships 

4773 .assert_not_called()) 

4774 self.assertEqual(constants.REPLICA_STATE_IN_SYNC, result) 

4775 

4776 def test_update_replica_state_missing_snapshot(self): 

4777 fake_snapmirror = { 

4778 'mirror-state': 'snapmirrored', 

4779 'relationship-status': 'idle', 

4780 'last-transfer-end-timestamp': '%s' % float(time.time()) 

4781 } 

4782 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

4783 fake_snapshot['share_id'] = fake.SHARE['id'] 

4784 snapshots = [{'share_replica_snapshot': fake_snapshot}] 

4785 vserver_client = mock.Mock() 

4786 self.mock_object(vserver_client, 'snapshot_exists', mock.Mock( 

4787 return_value=False)) 

4788 self.mock_object(self.library, 

4789 '_get_vserver', 

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

4791 vserver_client))) 

4792 self.mock_dm_session.get_snapmirrors = mock.Mock( 

4793 return_value=[fake_snapmirror]) 

4794 self.mock_object(self.library, 

4795 '_is_readable_replica', 

4796 mock.Mock(return_value=False)) 

4797 mock_backend_config = fake.get_config_cmode() 

4798 self.mock_object(data_motion, 'get_backend_configuration', 

4799 mock.Mock(return_value=mock_backend_config)) 

4800 

4801 result = self.library.update_replica_state(None, [fake.SHARE], 

4802 fake.SHARE, None, snapshots, 

4803 share_server=None) 

4804 

4805 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result) 

4806 

4807 @ddt.data(True, False) 

4808 def test_promote_replica(self, is_readable): 

4809 self.mock_object(self.library, 

4810 '_get_vserver', 

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

4812 mock.Mock()))) 

4813 protocol_helper = mock.Mock() 

4814 self.mock_object(self.library, 

4815 '_get_helper', 

4816 mock.Mock(return_value=protocol_helper)) 

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

4818 mock.Mock(return_value='fake_export_location')) 

4819 self.mock_object(self.library, '_unmount_orig_active_replica') 

4820 self.mock_object(self.library, '_handle_qos_on_replication_change') 

4821 self.mock_object(self.library, 

4822 '_is_flexgroup_pool', 

4823 mock.Mock(return_value=False)) 

4824 self.mock_object(share_types, 'get_extra_specs_from_share') 

4825 self.mock_object(self.library, '_get_provisioning_options', 

4826 mock.Mock(return_value={})) 

4827 

4828 mock_dm_session = mock.Mock() 

4829 self.mock_object(data_motion, "DataMotionSession", 

4830 mock.Mock(return_value=mock_dm_session)) 

4831 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4833 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

4834 mock.Mock(return_value=(fake.SHARE_NAME, 

4835 fake.VSERVER1, 

4836 fake.BACKEND_NAME))) 

4837 mock_client = mock.Mock() 

4838 self.mock_object(data_motion, "get_client_for_backend", 

4839 mock.Mock(return_value=mock_client)) 

4840 mock_backend_config = fake.get_config_cmode() 

4841 self.mock_object(data_motion, 'get_backend_configuration', 

4842 mock.Mock(return_value=mock_backend_config)) 

4843 self.mock_object(self.library, '_get_api_client_for_backend', 

4844 mock.Mock(return_value=mock_client)) 

4845 self.mock_object(self.client, 'cleanup_demoted_replica') 

4846 self.mock_object(self.library, 

4847 '_is_readable_replica', 

4848 mock.Mock(return_value=is_readable)) 

4849 self.mock_object(self.library, 

4850 '_update_autosize_attributes_after_promote_replica') 

4851 replicas = self.library.promote_replica( 

4852 None, [self.fake_replica, self.fake_replica_2], 

4853 self.fake_replica_2, [], share_server=None) 

4854 

4855 mock_dm_session.change_snapmirror_source.assert_called_once_with( 

4856 self.fake_replica, self.fake_replica, self.fake_replica_2, 

4857 mock.ANY, is_flexgroup=False 

4858 ) 

4859 self.assertEqual(2, len(replicas)) 

4860 actual_replica_1 = list(filter( 

4861 lambda x: x['id'] == self.fake_replica['id'], replicas))[0] 

4862 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, 

4863 actual_replica_1['replica_state']) 

4864 actual_replica_2 = list(filter( 

4865 lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0] 

4866 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

4867 actual_replica_2['replica_state']) 

4868 self.assertEqual('fake_export_location', 

4869 actual_replica_2['export_locations']) 

4870 self.assertEqual(constants.STATUS_ACTIVE, 

4871 actual_replica_2['access_rules_status']) 

4872 if is_readable: 

4873 self.library._unmount_orig_active_replica.assert_not_called() 

4874 protocol_helper.cleanup_demoted_replica.assert_not_called() 

4875 self.assertEqual('fake_export_location', 

4876 actual_replica_1['export_locations']) 

4877 else: 

4878 self.library._unmount_orig_active_replica.assert_called_once_with( 

4879 self.fake_replica, fake.VSERVER1) 

4880 protocol_helper.cleanup_demoted_replica.assert_called_once_with( 

4881 self.fake_replica, fake.SHARE['name']) 

4882 self.assertEqual([], actual_replica_1['export_locations']) 

4883 self.library._handle_qos_on_replication_change.assert_called_once() 

4884 

4885 def test_promote_replica_cleanup_demoted_storage_error(self): 

4886 self.mock_object(self.library, 

4887 '_get_vserver', 

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

4889 mock.Mock()))) 

4890 protocol_helper = mock.Mock() 

4891 self.mock_object(self.library, 

4892 '_get_helper', 

4893 mock.Mock(return_value=protocol_helper)) 

4894 self.mock_object(self.library, 

4895 '_is_readable_replica', 

4896 mock.Mock(return_value=False)) 

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

4898 mock.Mock(return_value='fake_export_location')) 

4899 self.mock_object(self.library, '_unmount_orig_active_replica') 

4900 self.mock_object(self.library, '_handle_qos_on_replication_change') 

4901 self.mock_object(self.library, 

4902 '_is_flexgroup_pool', 

4903 mock.Mock(return_value=False)) 

4904 

4905 mock_dm_session = mock.Mock() 

4906 self.mock_object(data_motion, "DataMotionSession", 

4907 mock.Mock(return_value=mock_dm_session)) 

4908 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4910 self.mock_object( 

4911 protocol_helper, 'cleanup_demoted_replica', 

4912 mock.Mock(side_effect=exception.StorageCommunicationException)) 

4913 self.mock_object(self.library, 

4914 '_update_autosize_attributes_after_promote_replica') 

4915 self.mock_object(share_types, 'get_extra_specs_from_share') 

4916 self.mock_object(self.library, '_get_provisioning_options', 

4917 mock.Mock(return_value={})) 

4918 mock_log = self.mock_object(lib_base.LOG, 'exception') 

4919 

4920 self.library.promote_replica( 

4921 None, [self.fake_replica, self.fake_replica_2], 

4922 self.fake_replica_2, [], share_server=None) 

4923 

4924 mock_dm_session.change_snapmirror_source.assert_called_once_with( 

4925 self.fake_replica, self.fake_replica, self.fake_replica_2, 

4926 mock.ANY, is_flexgroup=False 

4927 ) 

4928 protocol_helper.cleanup_demoted_replica.assert_called_once_with( 

4929 self.fake_replica, fake.SHARE['name']) 

4930 mock_log.assert_called_once() 

4931 

4932 def test_promote_replica_destination_unreachable(self): 

4933 self.mock_object(self.library, 

4934 '_get_vserver', 

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

4936 mock.Mock()))) 

4937 self.mock_object(self.library, 

4938 '_get_helper', 

4939 mock.Mock(return_value=mock.Mock())) 

4940 self.mock_object(self.library, '_unmount_orig_active_replica') 

4941 self.mock_object(self.library, '_handle_qos_on_replication_change') 

4942 

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

4944 mock.Mock(return_value='fake_export_location')) 

4945 self.mock_object( 

4946 self.library, '_convert_destination_replica_to_independent', 

4947 mock.Mock(side_effect=exception.StorageCommunicationException)) 

4948 self.mock_object(self.library, 

4949 '_update_autosize_attributes_after_promote_replica') 

4950 self.mock_object(share_types, 'get_extra_specs_from_share') 

4951 self.mock_object(self.library, '_get_provisioning_options', 

4952 mock.Mock(return_value={})) 

4953 

4954 replicas = self.library.promote_replica( 

4955 None, [self.fake_replica, self.fake_replica_2], 

4956 self.fake_replica_2, [], share_server=None) 

4957 

4958 self.assertEqual(1, len(replicas)) 

4959 actual_replica = replicas[0] 

4960 self.assertEqual(constants.STATUS_ERROR, 

4961 actual_replica['replica_state']) 

4962 self.assertEqual(constants.STATUS_ERROR, 

4963 actual_replica['status']) 

4964 self.assertFalse( 

4965 self.library._unmount_orig_active_replica.called) 

4966 self.assertFalse( 

4967 self.library._handle_qos_on_replication_change.called) 

4968 

4969 def test_promote_replica_more_than_two_replicas(self): 

4970 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

4971 fake_replica_3['id'] = fake.SHARE_ID3 

4972 fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC 

4973 self.mock_object(self.library, 

4974 '_get_vserver', 

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

4976 mock.Mock()))) 

4977 self.mock_object(self.library, '_unmount_orig_active_replica') 

4978 self.mock_object(self.library, '_handle_qos_on_replication_change') 

4979 self.mock_object(self.library, 

4980 '_get_helper', 

4981 mock.Mock(return_value=mock.Mock())) 

4982 

4983 self.mock_object(self.library, 

4984 '_is_flexgroup_pool', 

4985 mock.Mock(return_value=False)) 

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

4987 mock.Mock(return_value='fake_export_location')) 

4988 mock_dm_session = mock.Mock() 

4989 self.mock_object(data_motion, "DataMotionSession", 

4990 mock.Mock(return_value=mock_dm_session)) 

4991 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

4993 self.mock_object(self.library, 

4994 '_is_readable_replica', 

4995 mock.Mock(return_value=False)) 

4996 self.mock_object(self.library, 

4997 '_update_autosize_attributes_after_promote_replica') 

4998 self.mock_object(share_types, 'get_extra_specs_from_share') 

4999 self.mock_object(self.library, '_get_provisioning_options', 

5000 mock.Mock(return_value={})) 

5001 

5002 replicas = self.library.promote_replica( 

5003 None, [self.fake_replica, self.fake_replica_2, fake_replica_3], 

5004 self.fake_replica_2, [], share_server=None) 

5005 

5006 mock_dm_session.change_snapmirror_source.assert_has_calls([ 

5007 mock.call(fake_replica_3, self.fake_replica, self.fake_replica_2, 

5008 mock.ANY, is_flexgroup=False), 

5009 mock.call(self.fake_replica, self.fake_replica, 

5010 self.fake_replica_2, mock.ANY, is_flexgroup=False) 

5011 ], any_order=True) 

5012 

5013 self.assertEqual(3, len(replicas)) 

5014 actual_replica_1 = list(filter( 

5015 lambda x: x['id'] == self.fake_replica['id'], replicas))[0] 

5016 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, 

5017 actual_replica_1['replica_state']) 

5018 actual_replica_2 = list(filter( 

5019 lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0] 

5020 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5021 actual_replica_2['replica_state']) 

5022 self.assertEqual('fake_export_location', 

5023 actual_replica_2['export_locations']) 

5024 actual_replica_3 = list(filter( 

5025 lambda x: x['id'] == fake_replica_3['id'], replicas))[0] 

5026 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, 

5027 actual_replica_3['replica_state']) 

5028 self.library._unmount_orig_active_replica.assert_called_once_with( 

5029 self.fake_replica, fake.VSERVER1) 

5030 self.library._handle_qos_on_replication_change.assert_called_once() 

5031 

5032 def test_promote_replica_with_access_rules(self): 

5033 self.mock_object(self.library, 

5034 '_get_vserver', 

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

5036 mock.Mock()))) 

5037 self.mock_object(self.library, '_unmount_orig_active_replica') 

5038 self.mock_object(self.library, '_handle_qos_on_replication_change') 

5039 mock_helper = mock.Mock() 

5040 self.mock_object(self.library, 

5041 '_get_helper', 

5042 mock.Mock(return_value=mock_helper)) 

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

5044 mock.Mock(return_value='fake_export_location')) 

5045 self.mock_object(self.library, 

5046 '_is_flexgroup_pool', 

5047 mock.Mock(return_value=False)) 

5048 

5049 mock_dm_session = mock.Mock() 

5050 self.mock_object(data_motion, "DataMotionSession", 

5051 mock.Mock(return_value=mock_dm_session)) 

5052 self.mock_object(mock_dm_session, 'get_vserver_from_share', 

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

5054 self.mock_object(self.library, 

5055 '_is_readable_replica', 

5056 mock.Mock(return_value=False)) 

5057 self.mock_object(self.library, 

5058 '_update_autosize_attributes_after_promote_replica') 

5059 self.mock_object(share_types, 'get_extra_specs_from_share') 

5060 self.mock_object(self.library, '_get_provisioning_options', 

5061 mock.Mock(return_value={})) 

5062 

5063 replicas = self.library.promote_replica( 

5064 None, [self.fake_replica, self.fake_replica_2], 

5065 self.fake_replica_2, [fake.SHARE_ACCESS], share_server=None) 

5066 

5067 mock_dm_session.change_snapmirror_source.assert_has_calls([ 

5068 mock.call(self.fake_replica, self.fake_replica, 

5069 self.fake_replica_2, mock.ANY, is_flexgroup=False) 

5070 ], any_order=True) 

5071 self.assertEqual(2, len(replicas)) 

5072 share_name = self.library._get_backend_share_name( 

5073 self.fake_replica_2['id']) 

5074 mock_helper.update_access.assert_called_once_with(self.fake_replica_2, 

5075 share_name, 

5076 [fake.SHARE_ACCESS]) 

5077 self.library._unmount_orig_active_replica.assert_called_once_with( 

5078 self.fake_replica, fake.VSERVER1) 

5079 self.library._handle_qos_on_replication_change.assert_called_once() 

5080 

5081 def test_unmount_orig_active_replica(self): 

5082 self.mock_object(share_utils, 'extract_host', mock.Mock( 

5083 return_value=fake.MANILA_HOST_NAME)) 

5084 self.mock_object(data_motion, 'get_client_for_backend') 

5085 self.mock_object(self.library, '_get_backend_share_name', mock.Mock( 

5086 return_value=fake.SHARE_NAME)) 

5087 

5088 result = self.library._unmount_orig_active_replica(fake.SHARE) 

5089 self.assertIsNone(result) 

5090 

5091 @ddt.data({'extra_specs': {'netapp:snapshot_policy': 'none'}, 

5092 'have_cluster_creds': True}, 

5093 {'extra_specs': {'netapp:snapshot_policy': 'none'}, 

5094 'have_cluster_creds': True}, 

5095 # Test Case 2 isn't possible input 

5096 {'extra_specs': {'qos': True, 'netapp:maxiops': '3000'}, 

5097 'have_cluster_creds': False}) 

5098 @ddt.unpack 

5099 def test_handle_qos_on_replication_change_nothing_to_handle( 

5100 self, extra_specs, have_cluster_creds): 

5101 

5102 self.library._have_cluster_creds = have_cluster_creds 

5103 self.mock_object(lib_base.LOG, 'exception') 

5104 self.mock_object(lib_base.LOG, 'info') 

5105 self.mock_object(share_types, 'get_extra_specs_from_share', 

5106 mock.Mock(return_value=extra_specs)) 

5107 

5108 retval = self.library._handle_qos_on_replication_change( 

5109 self.mock_dm_session, self.fake_replica_2, self.fake_replica, 

5110 True, share_server=fake.SHARE_SERVER) 

5111 

5112 self.assertIsNone(retval) 

5113 lib_base.LOG.exception.assert_not_called() 

5114 lib_base.LOG.info.assert_not_called() 

5115 if have_cluster_creds: 

5116 share_types.get_extra_specs_from_share.assert_called_once_with( 

5117 self.fake_replica) 

5118 else: 

5119 share_types.get_extra_specs_from_share.assert_not_called() 

5120 

5121 def test_handle_qos_on_replication_change_exception(self): 

5122 self.library._have_cluster_creds = True 

5123 extra_specs = {'qos': True, fake.QOS_MAX_EXTRA_SPEC: '3000'} 

5124 vserver_client = mock.Mock() 

5125 self.mock_object(lib_base.LOG, 'exception') 

5126 self.mock_object(lib_base.LOG, 'info') 

5127 self.mock_object(share_types, 'get_extra_specs_from_share', 

5128 mock.Mock(return_value=extra_specs)) 

5129 self.mock_object(self.library, '_get_vserver', mock.Mock( 

5130 return_value=(fake.VSERVER1, vserver_client))) 

5131 self.mock_object(self.library._client, 'qos_policy_group_exists', 

5132 mock.Mock(return_value=True)) 

5133 self.mock_object(self.library._client, 'qos_policy_group_modify', 

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

5135 

5136 retval = self.library._handle_qos_on_replication_change( 

5137 self.mock_dm_session, self.fake_replica_2, self.fake_replica, True, 

5138 share_server=fake.SHARE_SERVER) 

5139 

5140 self.assertIsNone(retval) 

5141 (self.mock_dm_session.remove_qos_on_old_active_replica 

5142 .assert_called_once_with(self.fake_replica)) 

5143 lib_base.LOG.exception.assert_called_once() 

5144 lib_base.LOG.info.assert_not_called() 

5145 vserver_client.set_qos_policy_group_for_volume.assert_not_called() 

5146 

5147 @ddt.data(True, False) 

5148 def test_handle_qos_on_replication_change_modify_existing_policy(self, 

5149 is_dr): 

5150 self.library._have_cluster_creds = True 

5151 extra_specs = {'qos': True, fake.QOS_MAX_EXTRA_SPEC: '3000'} 

5152 vserver_client = mock.Mock() 

5153 volume_name_on_backend = self.library._get_backend_share_name( 

5154 self.fake_replica_2['id']) 

5155 self.mock_object(lib_base.LOG, 'exception') 

5156 self.mock_object(lib_base.LOG, 'info') 

5157 self.mock_object(share_types, 'get_extra_specs_from_share', 

5158 mock.Mock(return_value=extra_specs)) 

5159 self.mock_object(self.library, '_get_vserver', mock.Mock( 

5160 return_value=(fake.VSERVER1, vserver_client))) 

5161 self.mock_object(self.library._client, 'qos_policy_group_exists', 

5162 mock.Mock(return_value=True)) 

5163 self.mock_object(self.library._client, 'qos_policy_group_modify') 

5164 self.mock_object(self.library, '_create_qos_policy_group') 

5165 

5166 retval = self.library._handle_qos_on_replication_change( 

5167 self.mock_dm_session, self.fake_replica_2, self.fake_replica, 

5168 is_dr, share_server=fake.SHARE_SERVER) 

5169 

5170 self.assertIsNone(retval) 

5171 if is_dr: 

5172 (self.mock_dm_session.remove_qos_on_old_active_replica. 

5173 assert_called_once_with(self.fake_replica)) 

5174 else: 

5175 (self.mock_dm_session.remove_qos_on_old_active_replica. 

5176 assert_not_called()) 

5177 self.library._client.qos_policy_group_modify.assert_called_once_with( 

5178 'qos_' + volume_name_on_backend, '3000iops', None) 

5179 vserver_client.set_qos_policy_group_for_volume.assert_called_once_with( 

5180 volume_name_on_backend, 'qos_' + volume_name_on_backend) 

5181 self.library._create_qos_policy_group.assert_not_called() 

5182 lib_base.LOG.exception.assert_not_called() 

5183 lib_base.LOG.info.assert_called_once() 

5184 

5185 def test_handle_qos_on_replication_change_create_new_policy(self): 

5186 self.library._have_cluster_creds = True 

5187 extra_specs = {'qos': True, fake.QOS_MAX_EXTRA_SPEC: '3000'} 

5188 vserver_client = mock.Mock() 

5189 self.mock_object(lib_base.LOG, 'exception') 

5190 self.mock_object(lib_base.LOG, 'info') 

5191 self.mock_object(share_types, 'get_extra_specs_from_share', 

5192 mock.Mock(return_value=extra_specs)) 

5193 self.mock_object(self.library, '_get_vserver', mock.Mock( 

5194 return_value=(fake.VSERVER1, vserver_client))) 

5195 self.mock_object(self.library._client, 'qos_policy_group_exists', 

5196 mock.Mock(return_value=False)) 

5197 self.mock_object(self.library._client, 'qos_policy_group_modify') 

5198 self.mock_object(self.library, '_create_qos_policy_group') 

5199 

5200 retval = self.library._handle_qos_on_replication_change( 

5201 self.mock_dm_session, self.fake_replica_2, self.fake_replica, True, 

5202 share_server=fake.SHARE_SERVER) 

5203 

5204 self.assertIsNone(retval) 

5205 self.library._create_qos_policy_group.assert_called_once_with( 

5206 self.fake_replica_2, fake.VSERVER1, {'maxiops': '3000'}) 

5207 self.library._client.qos_policy_group_modify.assert_not_called() 

5208 lib_base.LOG.exception.assert_not_called() 

5209 lib_base.LOG.info.assert_called_once() 

5210 

5211 def test_convert_destination_replica_to_independent(self): 

5212 self.mock_object(self.library, 

5213 '_get_vserver', 

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

5215 mock.Mock()))) 

5216 self.mock_object(self.library, 

5217 '_get_helper', 

5218 mock.Mock(return_value=mock.Mock())) 

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

5220 mock.Mock(return_value='fake_export_location')) 

5221 

5222 replica = self.library._convert_destination_replica_to_independent( 

5223 None, self.mock_dm_session, self.fake_replica, 

5224 self.fake_replica_2, [], share_server=None) 

5225 

5226 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5227 self.fake_replica, self.fake_replica_2) 

5228 self.mock_dm_session.break_snapmirror.assert_called_once_with( 

5229 self.fake_replica, self.fake_replica_2, 

5230 quiesce_wait_time=None) 

5231 

5232 self.assertEqual('fake_export_location', 

5233 replica['export_locations']) 

5234 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5235 replica['replica_state']) 

5236 

5237 def test_convert_destination_replica_to_independent_update_failed(self): 

5238 self.mock_object(self.library, 

5239 '_get_vserver', 

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

5241 mock.Mock()))) 

5242 self.mock_object(self.library, 

5243 '_get_helper', 

5244 mock.Mock(return_value=mock.Mock())) 

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

5246 mock.Mock(return_value='fake_export_location')) 

5247 self.mock_object( 

5248 self.mock_dm_session, 'update_snapmirror', 

5249 mock.Mock(side_effect=exception.StorageCommunicationException)) 

5250 

5251 replica = self.library._convert_destination_replica_to_independent( 

5252 None, self.mock_dm_session, self.fake_replica, 

5253 self.fake_replica_2, [], share_server=None) 

5254 

5255 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5256 self.fake_replica, self.fake_replica_2) 

5257 self.mock_dm_session.break_snapmirror.assert_called_once_with( 

5258 self.fake_replica, self.fake_replica_2, 

5259 quiesce_wait_time=None) 

5260 

5261 self.assertEqual('fake_export_location', 

5262 replica['export_locations']) 

5263 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5264 replica['replica_state']) 

5265 

5266 def test_promote_replica_fail_to_set_access_rules(self): 

5267 fake_helper = mock.Mock() 

5268 fake_helper.update_access.side_effect = Exception 

5269 fake_access_rules = [ 

5270 {'access_to': "0.0.0.0", 

5271 'access_level': constants.ACCESS_LEVEL_RO}, 

5272 {'access_to': "10.10.10.10", 

5273 'access_level': constants.ACCESS_LEVEL_RW}, 

5274 ] 

5275 self.mock_object(self.library, 

5276 '_get_vserver', 

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

5278 mock.Mock()))) 

5279 self.mock_object(self.library, '_handle_qos_on_replication_change') 

5280 self.mock_object(self.library, 

5281 '_get_helper', 

5282 mock.Mock(return_value=fake_helper)) 

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

5284 mock.Mock(return_value='fake_export_location')) 

5285 self.mock_object(self.library, 

5286 '_is_flexgroup_pool', 

5287 mock.Mock(return_value=False)) 

5288 self.mock_object(self.library, 

5289 '_is_readable_replica', 

5290 mock.Mock(return_value=False)) 

5291 self.mock_object(self.library, 

5292 '_update_autosize_attributes_after_promote_replica') 

5293 self.mock_object(share_types, 'get_extra_specs_from_share') 

5294 self.mock_object(self.library, '_get_provisioning_options', 

5295 mock.Mock(return_value={})) 

5296 replicas = self.library.promote_replica( 

5297 None, [self.fake_replica, self.fake_replica_2], 

5298 self.fake_replica_2, fake_access_rules, share_server=None) 

5299 

5300 self.mock_dm_session.change_snapmirror_source.assert_called_once_with( 

5301 self.fake_replica, self.fake_replica, self.fake_replica_2, 

5302 mock.ANY, is_flexgroup=False 

5303 ) 

5304 

5305 self.assertEqual(2, len(replicas)) 

5306 actual_replica_1 = list(filter( 

5307 lambda x: x['id'] == self.fake_replica['id'], replicas))[0] 

5308 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, 

5309 actual_replica_1['replica_state']) 

5310 actual_replica_2 = list(filter( 

5311 lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0] 

5312 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5313 actual_replica_2['replica_state']) 

5314 self.assertEqual('fake_export_location', 

5315 actual_replica_2['export_locations']) 

5316 self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING, 

5317 actual_replica_2['access_rules_status']) 

5318 self.library._handle_qos_on_replication_change.assert_called_once() 

5319 

5320 def test_convert_destination_replica_to_independent_with_access_rules( 

5321 self): 

5322 fake_helper = mock.Mock() 

5323 fake_helper.update_access.side_effect = Exception 

5324 fake_access_rules = [ 

5325 {'access_to': "0.0.0.0", 

5326 'access_level': constants.ACCESS_LEVEL_RO}, 

5327 {'access_to': "10.10.10.10", 

5328 'access_level': constants.ACCESS_LEVEL_RW}, 

5329 ] 

5330 self.mock_object(self.library, 

5331 '_get_vserver', 

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

5333 mock.Mock()))) 

5334 self.mock_object(self.library, 

5335 '_get_helper', 

5336 mock.Mock(return_value=fake_helper)) 

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

5338 mock.Mock(return_value='fake_export_location')) 

5339 

5340 replica = self.library._convert_destination_replica_to_independent( 

5341 None, self.mock_dm_session, self.fake_replica, 

5342 self.fake_replica_2, fake_access_rules, share_server=None) 

5343 

5344 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5345 self.fake_replica, self.fake_replica_2) 

5346 self.mock_dm_session.break_snapmirror.assert_called_once_with( 

5347 self.fake_replica, self.fake_replica_2, 

5348 quiesce_wait_time=None) 

5349 

5350 self.assertEqual('fake_export_location', 

5351 replica['export_locations']) 

5352 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5353 replica['replica_state']) 

5354 self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING, 

5355 replica['access_rules_status']) 

5356 

5357 def test_convert_destination_replica_to_independent_failed_access_rules( 

5358 self): 

5359 fake_helper = mock.Mock() 

5360 fake_access_rules = [ 

5361 {'access_to': "0.0.0.0", 

5362 'access_level': constants.ACCESS_LEVEL_RO}, 

5363 {'access_to': "10.10.10.10", 

5364 'access_level': constants.ACCESS_LEVEL_RW}, 

5365 ] 

5366 self.mock_object(self.library, 

5367 '_get_vserver', 

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

5369 mock.Mock()))) 

5370 self.mock_object(self.library, 

5371 '_get_helper', 

5372 mock.Mock(return_value=fake_helper)) 

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

5374 mock.Mock(return_value='fake_export_location')) 

5375 

5376 replica = self.library._convert_destination_replica_to_independent( 

5377 None, self.mock_dm_session, self.fake_replica, 

5378 self.fake_replica_2, fake_access_rules, share_server=None) 

5379 

5380 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5381 self.fake_replica, self.fake_replica_2) 

5382 self.mock_dm_session.break_snapmirror.assert_called_once_with( 

5383 self.fake_replica, self.fake_replica_2, 

5384 quiesce_wait_time=None) 

5385 

5386 fake_helper.assert_has_calls([ 

5387 mock.call.set_client(mock.ANY), 

5388 mock.call.update_access(mock.ANY, mock.ANY, fake_access_rules), 

5389 ]) 

5390 

5391 self.assertEqual('fake_export_location', 

5392 replica['export_locations']) 

5393 self.assertEqual(constants.REPLICA_STATE_ACTIVE, 

5394 replica['replica_state']) 

5395 self.assertEqual(constants.STATUS_ACTIVE, 

5396 replica['access_rules_status']) 

5397 

5398 @ddt.data(True, False) 

5399 def test_safe_change_replica_source(self, is_dr): 

5400 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5401 fake_replica_3['id'] = fake.SHARE_ID3 

5402 fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC 

5403 protocol_helper = mock.Mock() 

5404 self.mock_object(self.library, 

5405 '_get_helper', 

5406 mock.Mock(return_value=protocol_helper)) 

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

5408 mock.Mock(return_value='fake_export_location')) 

5409 self.mock_object(self.library, '_unmount_orig_active_replica') 

5410 self.mock_object(self.library, '_handle_qos_on_replication_change') 

5411 

5412 mock_dm_session = mock.Mock() 

5413 mock_dm_session.wait_for_mount_replica.return_value = None 

5414 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

5415 mock.Mock(return_value=(fake.SHARE_NAME, 

5416 fake.VSERVER1, 

5417 fake.BACKEND_NAME))) 

5418 mock_client = mock.Mock() 

5419 self.mock_object(data_motion, "get_client_for_backend", 

5420 mock.Mock(return_value=mock_client)) 

5421 mock_backend_config = fake.get_config_cmode() 

5422 mock_backend_config.netapp_mount_replica_timeout = 30 

5423 self.mock_object(data_motion, 'get_backend_configuration', 

5424 mock.Mock(return_value=mock_backend_config)) 

5425 self.mock_object(self.library, '_get_api_client_for_backend', 

5426 mock.Mock(return_value=mock_client)) 

5427 

5428 replica = self.library._safe_change_replica_source( 

5429 mock_dm_session, self.fake_replica, self.fake_replica_2, 

5430 fake_replica_3, [self.fake_replica, self.fake_replica_2, 

5431 fake_replica_3], is_dr, [fake.SHARE_ACCESS] 

5432 ) 

5433 

5434 self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, 

5435 replica['replica_state']) 

5436 if is_dr: 

5437 self.assertEqual([], replica['export_locations']) 

5438 mock_dm_session.wait_for_mount_replica.assert_not_called() 

5439 else: 

5440 self.assertEqual('fake_export_location', 

5441 replica['export_locations']) 

5442 mock_dm_session.wait_for_mount_replica.assert_called_once_with( 

5443 mock_client, fake.SHARE_NAME, timeout=30) 

5444 

5445 @ddt.data({'fail_create_export': False, 'fail_mount': True}, 

5446 {'fail_create_export': True, 'fail_mount': False}) 

5447 @ddt.unpack 

5448 def test_safe_change_replica_source_fail_recover_readable( 

5449 self, fail_create_export, fail_mount): 

5450 

5451 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5452 fake_replica_3['id'] = fake.SHARE_ID3 

5453 fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC 

5454 protocol_helper = mock.Mock() 

5455 self.mock_object(self.library, 

5456 '_get_helper', 

5457 mock.Mock(return_value=protocol_helper)) 

5458 if fail_create_export: 

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

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

5461 else: 

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

5463 mock.Mock(return_value='fake_export_location')) 

5464 self.mock_object(self.library, '_unmount_orig_active_replica') 

5465 self.mock_object(self.library, '_handle_qos_on_replication_change') 

5466 mock_dm_session = mock.Mock() 

5467 if fail_mount: 

5468 mock_dm_session.wait_for_mount_replica.side_effect = ( 

5469 netapp_api.NaApiError()) 

5470 else: 

5471 mock_dm_session.wait_for_mount_replica.return_value = None 

5472 self.mock_object(mock_dm_session, 'get_backend_info_for_share', 

5473 mock.Mock(return_value=(fake.SHARE_NAME, 

5474 fake.VSERVER1, 

5475 fake.BACKEND_NAME))) 

5476 mock_client = mock.Mock() 

5477 self.mock_object(data_motion, "get_client_for_backend", 

5478 mock.Mock(return_value=mock_client)) 

5479 mock_backend_config = fake.get_config_cmode() 

5480 mock_backend_config.netapp_mount_replica_timeout = 30 

5481 self.mock_object(data_motion, 'get_backend_configuration', 

5482 mock.Mock(return_value=mock_backend_config)) 

5483 

5484 replica = self.library._safe_change_replica_source( 

5485 mock_dm_session, self.fake_replica, self.fake_replica_2, 

5486 fake_replica_3, [self.fake_replica, self.fake_replica_2, 

5487 fake_replica_3], False, [fake.SHARE_ACCESS] 

5488 ) 

5489 

5490 self.assertEqual(constants.STATUS_ERROR, 

5491 replica['replica_state']) 

5492 self.assertEqual(constants.STATUS_ERROR, 

5493 replica['status']) 

5494 

5495 def test_safe_change_replica_source_destination_unreachable(self): 

5496 self.mock_dm_session.change_snapmirror_source.side_effect = ( 

5497 exception.StorageCommunicationException 

5498 ) 

5499 

5500 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5501 fake_replica_3['id'] = fake.SHARE_ID3 

5502 fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC 

5503 replica = self.library._safe_change_replica_source( 

5504 self.mock_dm_session, self.fake_replica, self.fake_replica_2, 

5505 fake_replica_3, [self.fake_replica, self.fake_replica_2, 

5506 fake_replica_3], True, [], 

5507 ) 

5508 self.assertEqual([], replica['export_locations']) 

5509 self.assertEqual(constants.STATUS_ERROR, 

5510 replica['replica_state']) 

5511 self.assertEqual(constants.STATUS_ERROR, 

5512 replica['status']) 

5513 

5514 def test_safe_change_replica_source_error(self): 

5515 self.mock_dm_session.change_snapmirror_source.side_effect = ( 

5516 netapp_api.NaApiError(code=0) 

5517 ) 

5518 

5519 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5520 fake_replica_3['id'] = fake.SHARE_ID3 

5521 fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC 

5522 replica = self.library._safe_change_replica_source( 

5523 self.mock_dm_session, self.fake_replica, self.fake_replica_2, 

5524 fake_replica_3, [self.fake_replica, self.fake_replica_2, 

5525 fake_replica_3], True, [] 

5526 ) 

5527 self.assertEqual([], replica['export_locations']) 

5528 self.assertEqual(constants.STATUS_ERROR, 

5529 replica['replica_state']) 

5530 

5531 def test_create_replicated_snapshot(self): 

5532 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5533 fake_replica_3['id'] = fake.SHARE_ID3 

5534 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5535 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5536 fake_snapshot['share_id'] = self.fake_replica['id'] 

5537 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5538 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5539 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5540 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5541 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5542 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5543 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5544 

5545 vserver_client = mock.Mock() 

5546 self.mock_object(self.library, 

5547 '_get_vserver', 

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

5549 vserver_client))) 

5550 

5551 model_list = self.library.create_replicated_snapshot( 

5552 self.context, replica_list, snapshot_list, 

5553 share_server=fake.SHARE_SERVER) 

5554 

5555 share_name = self.library._get_backend_share_name( 

5556 fake_snapshot['share_id']) 

5557 snapshot_name = self.library._get_backend_snapshot_name( 

5558 fake_snapshot['id']) 

5559 vserver_client.create_snapshot.assert_called_once_with(share_name, 

5560 snapshot_name) 

5561 self.assertEqual(3, len(model_list)) 

5562 for snapshot in model_list: 

5563 self.assertEqual(snapshot['provider_location'], snapshot_name) 

5564 actual_active_snapshot = list(filter( 

5565 lambda x: x['id'] == fake_snapshot['id'], model_list))[0] 

5566 self.assertEqual(constants.STATUS_AVAILABLE, 

5567 actual_active_snapshot['status']) 

5568 actual_non_active_snapshot_list = list(filter( 

5569 lambda x: x['id'] != fake_snapshot['id'], model_list)) 

5570 for snapshot in actual_non_active_snapshot_list: 

5571 self.assertEqual(constants.STATUS_CREATING, snapshot['status']) 

5572 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5573 [mock.call(self.fake_replica, self.fake_replica_2), 

5574 mock.call(self.fake_replica, fake_replica_3)], 

5575 any_order=True 

5576 ) 

5577 

5578 def test_create_replicated_snapshot_with_creating_replica(self): 

5579 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5580 fake_replica_3['id'] = fake.SHARE_ID3 

5581 fake_replica_3['host'] = None 

5582 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5583 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5584 fake_snapshot['share_id'] = self.fake_replica['id'] 

5585 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5586 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5587 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5588 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5589 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5590 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5591 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5592 

5593 vserver_client = mock.Mock() 

5594 self.mock_object(self.library, 

5595 '_get_vserver', 

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

5597 vserver_client))) 

5598 

5599 model_list = self.library.create_replicated_snapshot( 

5600 self.context, replica_list, snapshot_list, 

5601 share_server=fake.SHARE_SERVER) 

5602 

5603 share_name = self.library._get_backend_share_name( 

5604 fake_snapshot['share_id']) 

5605 snapshot_name = self.library._get_backend_snapshot_name( 

5606 fake_snapshot['id']) 

5607 vserver_client.create_snapshot.assert_called_once_with(share_name, 

5608 snapshot_name) 

5609 self.assertEqual(3, len(model_list)) 

5610 for snapshot in model_list: 

5611 self.assertEqual(snapshot['provider_location'], snapshot_name) 

5612 actual_active_snapshot = list(filter( 

5613 lambda x: x['id'] == fake_snapshot['id'], model_list))[0] 

5614 self.assertEqual(constants.STATUS_AVAILABLE, 

5615 actual_active_snapshot['status']) 

5616 actual_non_active_snapshot_list = list(filter( 

5617 lambda x: x['id'] != fake_snapshot['id'], model_list)) 

5618 for snapshot in actual_non_active_snapshot_list: 

5619 self.assertEqual(constants.STATUS_CREATING, snapshot['status']) 

5620 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5621 [mock.call(self.fake_replica, self.fake_replica_2)], 

5622 any_order=True 

5623 ) 

5624 

5625 @ddt.data( 

5626 netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND), 

5627 netapp_api.NaApiError(message='not initialized')) 

5628 def test_create_replicated_snapshot_no_snapmirror(self, api_exception): 

5629 self.mock_dm_session.update_snapmirror.side_effect = [ 

5630 None, 

5631 api_exception 

5632 ] 

5633 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5634 fake_replica_3['id'] = fake.SHARE_ID3 

5635 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5636 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5637 fake_snapshot['share_id'] = self.fake_replica['id'] 

5638 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5639 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5640 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5641 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5642 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5643 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5644 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5645 

5646 vserver_client = mock.Mock() 

5647 self.mock_object(self.library, 

5648 '_get_vserver', 

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

5650 vserver_client))) 

5651 

5652 model_list = self.library.create_replicated_snapshot( 

5653 self.context, replica_list, snapshot_list, 

5654 share_server=fake.SHARE_SERVER) 

5655 

5656 share_name = self.library._get_backend_share_name( 

5657 fake_snapshot['share_id']) 

5658 snapshot_name = self.library._get_backend_snapshot_name( 

5659 fake_snapshot['id']) 

5660 vserver_client.create_snapshot.assert_called_once_with(share_name, 

5661 snapshot_name) 

5662 self.assertEqual(3, len(model_list)) 

5663 for snapshot in model_list: 

5664 self.assertEqual(snapshot['provider_location'], snapshot_name) 

5665 actual_active_snapshot = list(filter( 

5666 lambda x: x['id'] == fake_snapshot['id'], model_list))[0] 

5667 self.assertEqual(constants.STATUS_AVAILABLE, 

5668 actual_active_snapshot['status']) 

5669 actual_non_active_snapshot_list = list(filter( 

5670 lambda x: x['id'] != fake_snapshot['id'], model_list)) 

5671 for snapshot in actual_non_active_snapshot_list: 

5672 self.assertEqual(constants.STATUS_CREATING, snapshot['status']) 

5673 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5674 [mock.call(self.fake_replica, self.fake_replica_2), 

5675 mock.call(self.fake_replica, fake_replica_3)], 

5676 any_order=True 

5677 ) 

5678 

5679 def test_create_replicated_snapshot_update_error(self): 

5680 self.mock_dm_session.update_snapmirror.side_effect = [ 

5681 None, 

5682 netapp_api.NaApiError() 

5683 ] 

5684 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5685 fake_replica_3['id'] = fake.SHARE_ID3 

5686 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5687 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5688 fake_snapshot['share_id'] = self.fake_replica['id'] 

5689 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5690 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5691 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5692 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5693 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5694 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5695 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5696 

5697 vserver_client = mock.Mock() 

5698 self.mock_object(self.library, 

5699 '_get_vserver', 

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

5701 vserver_client))) 

5702 

5703 self.assertRaises(netapp_api.NaApiError, 

5704 self.library.create_replicated_snapshot, 

5705 self.context, replica_list, snapshot_list, 

5706 share_server=fake.SHARE_SERVER) 

5707 

5708 def test_delete_replicated_snapshot(self): 

5709 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5710 fake_replica_3['id'] = fake.SHARE_ID3 

5711 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5712 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5713 fake_snapshot['share_id'] = self.fake_replica['id'] 

5714 share_name = self.library._get_backend_share_name( 

5715 fake_snapshot['share_id']) 

5716 snapshot_name = self.library._get_backend_snapshot_name( 

5717 fake_snapshot['id']) 

5718 fake_snapshot['provider_location'] = snapshot_name 

5719 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5720 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5721 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5722 fake_snapshot_2['provider_location'] = snapshot_name 

5723 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5724 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5725 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5726 fake_snapshot_3['provider_location'] = snapshot_name 

5727 

5728 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5729 

5730 vserver_client = mock.Mock() 

5731 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

5732 self.mock_object(self.library, 

5733 '_get_vserver', 

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

5735 vserver_client))) 

5736 

5737 self.library.delete_replicated_snapshot( 

5738 self.context, replica_list, snapshot_list, 

5739 share_server=fake.SHARE_SERVER) 

5740 

5741 vserver_client.delete_snapshot.assert_called_once_with(share_name, 

5742 snapshot_name) 

5743 

5744 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5745 [mock.call(self.fake_replica, self.fake_replica_2), 

5746 mock.call(self.fake_replica, fake_replica_3)], 

5747 any_order=True 

5748 ) 

5749 

5750 def test_delete_replicated_snapshot_replica_still_creating(self): 

5751 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5752 fake_replica_3['id'] = fake.SHARE_ID3 

5753 fake_replica_3['host'] = None 

5754 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5755 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5756 fake_snapshot['share_id'] = self.fake_replica['id'] 

5757 share_name = self.library._get_backend_share_name( 

5758 fake_snapshot['share_id']) 

5759 snapshot_name = self.library._get_backend_snapshot_name( 

5760 fake_snapshot['id']) 

5761 fake_snapshot['provider_location'] = snapshot_name 

5762 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5763 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5764 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5765 fake_snapshot_2['provider_location'] = snapshot_name 

5766 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5767 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5768 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5769 fake_snapshot_3['provider_location'] = snapshot_name 

5770 

5771 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5772 

5773 vserver_client = mock.Mock() 

5774 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

5775 self.mock_object(self.library, 

5776 '_get_vserver', 

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

5778 vserver_client))) 

5779 

5780 self.library.delete_replicated_snapshot( 

5781 self.context, replica_list, snapshot_list, 

5782 share_server=fake.SHARE_SERVER) 

5783 

5784 vserver_client.delete_snapshot.assert_called_once_with(share_name, 

5785 snapshot_name) 

5786 

5787 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5788 [mock.call(self.fake_replica, self.fake_replica_2)], 

5789 any_order=True 

5790 ) 

5791 

5792 @ddt.data( 

5793 netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND), 

5794 netapp_api.NaApiError(message='not initialized')) 

5795 def test_delete_replicated_snapshot_missing_snapmirror(self, 

5796 api_exception): 

5797 self.mock_dm_session.update_snapmirror.side_effect = [ 

5798 None, 

5799 api_exception 

5800 ] 

5801 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5802 fake_replica_3['id'] = fake.SHARE_ID3 

5803 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5804 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5805 fake_snapshot['share_id'] = self.fake_replica['id'] 

5806 share_name = self.library._get_backend_share_name( 

5807 fake_snapshot['share_id']) 

5808 snapshot_name = self.library._get_backend_snapshot_name( 

5809 fake_snapshot['id']) 

5810 fake_snapshot['provider_location'] = snapshot_name 

5811 fake_snapshot['busy'] = False 

5812 

5813 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5814 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5815 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5816 fake_snapshot_2['provider_location'] = snapshot_name 

5817 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5818 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5819 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5820 fake_snapshot_3['provider_location'] = snapshot_name 

5821 

5822 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5823 

5824 vserver_client = mock.Mock() 

5825 vserver_client.get_snapshot.return_value = fake_snapshot 

5826 self.mock_object(self.library, 

5827 '_get_vserver', 

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

5829 vserver_client))) 

5830 

5831 self.library.delete_replicated_snapshot( 

5832 self.context, replica_list, snapshot_list, 

5833 share_server=fake.SHARE_SERVER) 

5834 

5835 vserver_client.delete_snapshot.assert_called_once_with(share_name, 

5836 snapshot_name) 

5837 

5838 self.mock_dm_session.update_snapmirror.assert_has_calls( 

5839 [mock.call(self.fake_replica, self.fake_replica_2), 

5840 mock.call(self.fake_replica, fake_replica_3)], 

5841 any_order=True 

5842 ) 

5843 

5844 def test_delete_replicated_snapshot_update_error(self): 

5845 self.mock_dm_session.update_snapmirror.side_effect = [ 

5846 None, 

5847 netapp_api.NaApiError() 

5848 ] 

5849 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

5850 fake_replica_3['id'] = fake.SHARE_ID3 

5851 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

5852 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5853 fake_snapshot['share_id'] = self.fake_replica['id'] 

5854 snapshot_name = self.library._get_backend_snapshot_name( 

5855 fake_snapshot['id']) 

5856 fake_snapshot['provider_location'] = snapshot_name 

5857 fake_snapshot['busy'] = False 

5858 

5859 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

5860 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

5861 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

5862 fake_snapshot_2['provider_location'] = snapshot_name 

5863 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

5864 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

5865 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

5866 fake_snapshot_3['provider_location'] = snapshot_name 

5867 

5868 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

5869 

5870 vserver_client = mock.Mock() 

5871 vserver_client.get_snapshot.return_value = fake_snapshot 

5872 self.mock_object(self.library, 

5873 '_get_vserver', 

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

5875 vserver_client))) 

5876 

5877 self.assertRaises(netapp_api.NaApiError, 

5878 self.library.delete_replicated_snapshot, 

5879 self.context, replica_list, snapshot_list, 

5880 share_server=fake.SHARE_SERVER) 

5881 

5882 def test_update_replicated_snapshot_still_creating(self): 

5883 vserver_client = mock.Mock() 

5884 vserver_client.snapshot_exists.return_value = False 

5885 self.mock_object(self.library, 

5886 '_get_vserver', 

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

5888 vserver_client))) 

5889 replica_list = [self.fake_replica, self.fake_replica_2] 

5890 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5891 fake_snapshot['status'] = constants.STATUS_CREATING 

5892 fake_snapshot['share_id'] = self.fake_replica_2['id'] 

5893 snapshot_name = self.library._get_backend_snapshot_name( 

5894 fake_snapshot['id']) 

5895 fake_snapshot['provider_location'] = snapshot_name 

5896 

5897 model_update = self.library.update_replicated_snapshot( 

5898 replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot) 

5899 

5900 self.assertIsNone(model_update) 

5901 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5902 self.fake_replica, self.fake_replica_2 

5903 ) 

5904 

5905 def test_update_replicated_snapshot_still_creating_no_host(self): 

5906 self.fake_replica_2['host'] = None 

5907 vserver_client = mock.Mock() 

5908 vserver_client.snapshot_exists.return_value = False 

5909 self.mock_object(self.library, 

5910 '_get_vserver', 

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

5912 vserver_client))) 

5913 replica_list = [self.fake_replica, self.fake_replica_2] 

5914 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5915 fake_snapshot['status'] = constants.STATUS_CREATING 

5916 fake_snapshot['share_id'] = self.fake_replica_2['id'] 

5917 snapshot_name = self.library._get_backend_snapshot_name( 

5918 fake_snapshot['id']) 

5919 fake_snapshot['provider_location'] = snapshot_name 

5920 

5921 model_update = self.library.update_replicated_snapshot( 

5922 replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot) 

5923 

5924 self.assertIsNone(model_update) 

5925 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5926 self.fake_replica, self.fake_replica_2 

5927 ) 

5928 

5929 @ddt.data( 

5930 netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND), 

5931 netapp_api.NaApiError(message='not initialized')) 

5932 def test_update_replicated_snapshot_no_snapmirror(self, api_exception): 

5933 vserver_client = mock.Mock() 

5934 vserver_client.snapshot_exists.return_value = False 

5935 self.mock_dm_session.update_snapmirror.side_effect = api_exception 

5936 self.mock_object(self.library, 

5937 '_get_vserver', 

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

5939 vserver_client))) 

5940 replica_list = [self.fake_replica, self.fake_replica_2] 

5941 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5942 fake_snapshot['status'] = constants.STATUS_CREATING 

5943 fake_snapshot['share_id'] = self.fake_replica_2['id'] 

5944 snapshot_name = self.library._get_backend_snapshot_name( 

5945 fake_snapshot['id']) 

5946 fake_snapshot['provider_location'] = snapshot_name 

5947 

5948 model_update = self.library.update_replicated_snapshot( 

5949 replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot) 

5950 

5951 self.assertIsNone(model_update) 

5952 self.mock_dm_session.update_snapmirror.assert_called_once_with( 

5953 self.fake_replica, self.fake_replica_2 

5954 ) 

5955 

5956 def test_update_replicated_snapshot_update_error(self): 

5957 vserver_client = mock.Mock() 

5958 vserver_client.snapshot_exists.return_value = False 

5959 self.mock_dm_session.update_snapmirror.side_effect = ( 

5960 netapp_api.NaApiError() 

5961 ) 

5962 self.mock_object(self.library, 

5963 '_get_vserver', 

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

5965 vserver_client))) 

5966 replica_list = [self.fake_replica, self.fake_replica_2] 

5967 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5968 fake_snapshot['status'] = constants.STATUS_CREATING 

5969 fake_snapshot['share_id'] = self.fake_replica_2['id'] 

5970 snapshot_name = self.library._get_backend_snapshot_name( 

5971 fake_snapshot['id']) 

5972 fake_snapshot['provider_location'] = snapshot_name 

5973 

5974 self.assertRaises(netapp_api.NaApiError, 

5975 self.library.update_replicated_snapshot, 

5976 replica_list, self.fake_replica_2, 

5977 [fake_snapshot], fake_snapshot) 

5978 

5979 def test_update_replicated_snapshot_still_deleting(self): 

5980 vserver_client = mock.Mock() 

5981 vserver_client.snapshot_exists.return_value = True 

5982 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

5983 self.mock_object(self.library, 

5984 '_get_vserver', 

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

5986 vserver_client))) 

5987 

5988 replica_list = [self.fake_replica] 

5989 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

5990 fake_snapshot['status'] = constants.STATUS_DELETING 

5991 fake_snapshot['share_id'] = self.fake_replica['id'] 

5992 snapshot_name = self.library._get_backend_snapshot_name( 

5993 fake_snapshot['id']) 

5994 fake_snapshot['provider_location'] = snapshot_name 

5995 

5996 model_update = self.library.update_replicated_snapshot( 

5997 replica_list, self.fake_replica, [fake_snapshot], fake_snapshot) 

5998 

5999 self.assertIsNone(model_update) 

6000 

6001 def test_update_replicated_snapshot_created(self): 

6002 vserver_client = mock.Mock() 

6003 vserver_client.snapshot_exists.return_value = True 

6004 self.mock_object(self.library, 

6005 '_get_vserver', 

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

6007 vserver_client))) 

6008 replica_list = [self.fake_replica] 

6009 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

6010 fake_snapshot['status'] = constants.STATUS_CREATING 

6011 fake_snapshot['share_id'] = self.fake_replica['id'] 

6012 snapshot_name = self.library._get_backend_snapshot_name( 

6013 fake_snapshot['id']) 

6014 fake_snapshot['provider_location'] = snapshot_name 

6015 

6016 model_update = self.library.update_replicated_snapshot( 

6017 replica_list, self.fake_replica, [fake_snapshot], fake_snapshot) 

6018 

6019 self.assertEqual(constants.STATUS_AVAILABLE, model_update['status']) 

6020 self.assertEqual(snapshot_name, model_update['provider_location']) 

6021 

6022 def test_update_replicated_snapshot_created_no_provider_location(self): 

6023 vserver_client = mock.Mock() 

6024 vserver_client.snapshot_exists.return_value = True 

6025 self.mock_object(self.library, 

6026 '_get_vserver', 

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

6028 vserver_client))) 

6029 replica_list = [self.fake_replica, self.fake_replica_2] 

6030 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

6031 fake_snapshot['status'] = constants.STATUS_ACTIVE 

6032 fake_snapshot['share_id'] = self.fake_replica['id'] 

6033 snapshot_name = self.library._get_backend_snapshot_name( 

6034 fake_snapshot['id']) 

6035 fake_snapshot['provider_location'] = snapshot_name 

6036 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

6037 fake_snapshot_2['status'] = constants.STATUS_CREATING 

6038 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

6039 

6040 model_update = self.library.update_replicated_snapshot( 

6041 replica_list, self.fake_replica_2, 

6042 [fake_snapshot, fake_snapshot_2], fake_snapshot_2) 

6043 

6044 self.assertEqual(constants.STATUS_AVAILABLE, model_update['status']) 

6045 self.assertEqual(snapshot_name, model_update['provider_location']) 

6046 

6047 def test_update_replicated_snapshot_deleted(self): 

6048 vserver_client = mock.Mock() 

6049 vserver_client.snapshot_exists.return_value = False 

6050 self.mock_object(self.library, 

6051 '_get_vserver', 

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

6053 vserver_client))) 

6054 replica_list = [self.fake_replica] 

6055 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

6056 fake_snapshot['status'] = constants.STATUS_DELETING 

6057 fake_snapshot['share_id'] = self.fake_replica['id'] 

6058 snapshot_name = self.library._get_backend_snapshot_name( 

6059 fake_snapshot['id']) 

6060 fake_snapshot['provider_location'] = snapshot_name 

6061 

6062 self.assertRaises(exception.SnapshotResourceNotFound, 

6063 self.library.update_replicated_snapshot, 

6064 replica_list, self.fake_replica, [fake_snapshot], 

6065 fake_snapshot) 

6066 

6067 def test_update_replicated_snapshot_no_provider_locations(self): 

6068 vserver_client = mock.Mock() 

6069 vserver_client.snapshot_exists.return_value = True 

6070 self.mock_object(self.library, 

6071 '_get_vserver', 

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

6073 vserver_client))) 

6074 replica_list = [self.fake_replica] 

6075 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

6076 fake_snapshot['status'] = constants.STATUS_CREATING 

6077 fake_snapshot['share_id'] = self.fake_replica['id'] 

6078 fake_snapshot['provider_location'] = None 

6079 

6080 model_update = self.library.update_replicated_snapshot( 

6081 replica_list, self.fake_replica, [fake_snapshot], fake_snapshot) 

6082 

6083 self.assertIsNone(model_update) 

6084 

6085 def _get_fake_replicas_and_snapshots(self): 

6086 

6087 fake_replica_3 = copy.deepcopy(self.fake_replica_2) 

6088 fake_replica_3['id'] = fake.SHARE_ID3 

6089 fake_snapshot = copy.deepcopy(fake.SNAPSHOT) 

6090 fake_snapshot['share_id'] = self.fake_replica['id'] 

6091 snapshot_name = self.library._get_backend_snapshot_name( 

6092 fake_snapshot['id']) 

6093 fake_snapshot['provider_location'] = snapshot_name 

6094 fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT) 

6095 fake_snapshot_2['id'] = uuidutils.generate_uuid() 

6096 fake_snapshot_2['share_id'] = self.fake_replica_2['id'] 

6097 fake_snapshot_2['provider_location'] = snapshot_name 

6098 fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT) 

6099 fake_snapshot_3['id'] = uuidutils.generate_uuid() 

6100 fake_snapshot_3['share_id'] = fake_replica_3['id'] 

6101 fake_snapshot_3['provider_location'] = snapshot_name 

6102 replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3] 

6103 snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3] 

6104 return replica_list, snapshot_list 

6105 

6106 @ddt.data(True, False) 

6107 def test_revert_to_replicated_snapshot(self, use_snap_provider_location): 

6108 

6109 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6110 fake_replica, fake_replica_2, fake_replica_3 = replica_list 

6111 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6112 

6113 if not use_snap_provider_location: 

6114 del fake_snapshot['provider_location'] 

6115 del fake_snapshot_2['provider_location'] 

6116 del fake_snapshot_3['provider_location'] 

6117 

6118 share_name = self.library._get_backend_share_name( 

6119 fake_snapshot['share_id']) 

6120 snapshot_name = self.library._get_backend_snapshot_name( 

6121 fake_snapshot['id']) 

6122 

6123 vserver_client = mock.Mock() 

6124 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

6125 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6126 self.mock_object(self.library, 

6127 '_get_vserver', 

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

6129 vserver_client))) 

6130 

6131 self.library.revert_to_replicated_snapshot( 

6132 self.context, self.fake_replica, replica_list, fake_snapshot, 

6133 snapshot_list, share_server=fake.SHARE_SERVER) 

6134 

6135 vserver_client.get_snapshot.assert_called_once_with( 

6136 share_name, snapshot_name) 

6137 vserver_client.list_snapmirror_snapshots.assert_called_once_with( 

6138 share_name) 

6139 vserver_client.delete_snapshot.assert_called_once_with( 

6140 share_name, 'sm_snap', ignore_owners=True) 

6141 vserver_client.restore_snapshot.assert_called_once_with( 

6142 share_name, snapshot_name) 

6143 

6144 self.mock_dm_session.break_snapmirror.assert_has_calls( 

6145 [mock.call(self.fake_replica, self.fake_replica_2, mount=False), 

6146 mock.call(self.fake_replica, fake_replica_3, mount=False)], 

6147 any_order=True) 

6148 self.mock_dm_session.resync_snapmirror.assert_has_calls( 

6149 [mock.call(self.fake_replica, self.fake_replica_2), 

6150 mock.call(self.fake_replica, fake_replica_3)], 

6151 any_order=True) 

6152 

6153 def test_revert_to_replicated_snapshot_not_found(self): 

6154 

6155 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6156 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6157 share_name = self.library._get_backend_share_name( 

6158 fake_snapshot['share_id']) 

6159 snapshot_name = self.library._get_backend_snapshot_name( 

6160 fake_snapshot['id']) 

6161 

6162 vserver_client = mock.Mock() 

6163 vserver_client.get_snapshot.side_effect = netapp_api.NaApiError 

6164 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6165 self.mock_object(self.library, 

6166 '_get_vserver', 

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

6168 vserver_client))) 

6169 

6170 self.assertRaises( 

6171 netapp_api.NaApiError, self.library.revert_to_replicated_snapshot, 

6172 self.context, self.fake_replica, replica_list, fake_snapshot, 

6173 snapshot_list, share_server=fake.SHARE_SERVER) 

6174 

6175 vserver_client.get_snapshot.assert_called_once_with( 

6176 share_name, snapshot_name) 

6177 self.assertFalse(vserver_client.list_snapmirror_snapshots.called) 

6178 self.assertFalse(vserver_client.delete_snapshot.called) 

6179 self.assertFalse(vserver_client.restore_snapshot.called) 

6180 self.assertFalse(self.mock_dm_session.break_snapmirror.called) 

6181 self.assertFalse(self.mock_dm_session.resync_snapmirror.called) 

6182 

6183 def test_revert_to_replicated_snapshot_snapmirror_break_error(self): 

6184 

6185 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6186 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6187 

6188 vserver_client = mock.Mock() 

6189 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

6190 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6191 self.mock_object(self.library, 

6192 '_get_vserver', 

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

6194 vserver_client))) 

6195 self.mock_dm_session.break_snapmirror.side_effect = ( 

6196 netapp_api.NaApiError) 

6197 

6198 self.assertRaises( 

6199 netapp_api.NaApiError, self.library.revert_to_replicated_snapshot, 

6200 self.context, self.fake_replica, replica_list, fake_snapshot, 

6201 snapshot_list, share_server=fake.SHARE_SERVER) 

6202 

6203 def test_revert_to_replicated_snapshot_snapmirror_break_not_found(self): 

6204 

6205 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6206 fake_replica, fake_replica_2, fake_replica_3 = replica_list 

6207 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6208 share_name = self.library._get_backend_share_name( 

6209 fake_snapshot['share_id']) 

6210 snapshot_name = self.library._get_backend_snapshot_name( 

6211 fake_snapshot['id']) 

6212 

6213 vserver_client = mock.Mock() 

6214 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

6215 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6216 self.mock_object(self.library, 

6217 '_get_vserver', 

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

6219 vserver_client))) 

6220 self.mock_dm_session.break_snapmirror.side_effect = ( 

6221 netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)) 

6222 

6223 self.library.revert_to_replicated_snapshot( 

6224 self.context, self.fake_replica, replica_list, fake_snapshot, 

6225 snapshot_list, share_server=fake.SHARE_SERVER) 

6226 

6227 vserver_client.get_snapshot.assert_called_once_with( 

6228 share_name, snapshot_name) 

6229 vserver_client.list_snapmirror_snapshots.assert_called_once_with( 

6230 share_name) 

6231 vserver_client.delete_snapshot.assert_called_once_with( 

6232 share_name, 'sm_snap', ignore_owners=True) 

6233 vserver_client.restore_snapshot.assert_called_once_with( 

6234 share_name, snapshot_name) 

6235 

6236 self.mock_dm_session.break_snapmirror.assert_has_calls( 

6237 [mock.call(self.fake_replica, self.fake_replica_2, mount=False), 

6238 mock.call(self.fake_replica, fake_replica_3, mount=False)], 

6239 any_order=True) 

6240 self.mock_dm_session.resync_snapmirror.assert_has_calls( 

6241 [mock.call(self.fake_replica, self.fake_replica_2), 

6242 mock.call(self.fake_replica, fake_replica_3)], 

6243 any_order=True) 

6244 

6245 def test_revert_to_replicated_snapshot_snapmirror_resync_error(self): 

6246 

6247 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6248 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6249 

6250 vserver_client = mock.Mock() 

6251 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

6252 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6253 self.mock_object(self.library, 

6254 '_get_vserver', 

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

6256 vserver_client))) 

6257 self.mock_dm_session.resync_snapmirror.side_effect = ( 

6258 netapp_api.NaApiError) 

6259 

6260 self.assertRaises( 

6261 netapp_api.NaApiError, self.library.revert_to_replicated_snapshot, 

6262 self.context, self.fake_replica, replica_list, fake_snapshot, 

6263 snapshot_list, share_server=fake.SHARE_SERVER) 

6264 

6265 def test_revert_to_replicated_snapshot_snapmirror_resync_not_found(self): 

6266 

6267 replica_list, snapshot_list = self._get_fake_replicas_and_snapshots() 

6268 fake_replica, fake_replica_2, fake_replica_3 = replica_list 

6269 fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list 

6270 share_name = self.library._get_backend_share_name( 

6271 fake_snapshot['share_id']) 

6272 snapshot_name = self.library._get_backend_snapshot_name( 

6273 fake_snapshot['id']) 

6274 

6275 vserver_client = mock.Mock() 

6276 vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT 

6277 vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap'] 

6278 self.mock_object(self.library, 

6279 '_get_vserver', 

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

6281 vserver_client))) 

6282 self.mock_dm_session.resync_snapmirror.side_effect = ( 

6283 netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)) 

6284 

6285 self.library.revert_to_replicated_snapshot( 

6286 self.context, self.fake_replica, replica_list, fake_snapshot, 

6287 snapshot_list, share_server=fake.SHARE_SERVER) 

6288 

6289 vserver_client.get_snapshot.assert_called_once_with( 

6290 share_name, snapshot_name) 

6291 vserver_client.list_snapmirror_snapshots.assert_called_once_with( 

6292 share_name) 

6293 vserver_client.delete_snapshot.assert_called_once_with( 

6294 share_name, 'sm_snap', ignore_owners=True) 

6295 vserver_client.restore_snapshot.assert_called_once_with( 

6296 share_name, snapshot_name) 

6297 

6298 self.mock_dm_session.break_snapmirror.assert_has_calls( 

6299 [mock.call(self.fake_replica, self.fake_replica_2, mount=False), 

6300 mock.call(self.fake_replica, fake_replica_3, mount=False)], 

6301 any_order=True) 

6302 self.mock_dm_session.resync_snapmirror.assert_has_calls( 

6303 [mock.call(self.fake_replica, self.fake_replica_2), 

6304 mock.call(self.fake_replica, fake_replica_3)], 

6305 any_order=True) 

6306 

6307 @ddt.data( 

6308 {'replication_type': constants.REPLICATION_TYPE_READABLE, 

6309 'is_readable': True}, 

6310 {'replication_type': constants.REPLICATION_TYPE_DR, 

6311 'is_readable': False}, 

6312 {'replication_type': constants.REPLICATION_TYPE_WRITABLE, 

6313 'is_readable': False}, 

6314 {'replication_type': None, 

6315 'is_readable': False}) 

6316 @ddt.unpack 

6317 def test__is_readable_replica(self, replication_type, is_readable): 

6318 extra_specs = {} 

6319 if replication_type: 

6320 extra_specs['replication_type'] = replication_type 

6321 mock_get_extra_spec = self.mock_object( 

6322 share_types, 'get_extra_specs_from_share', 

6323 mock.Mock(return_value=extra_specs)) 

6324 

6325 result = self.library._is_readable_replica(fake.SHARE) 

6326 

6327 self.assertEqual(is_readable, result) 

6328 mock_get_extra_spec.assert_called_once_with(fake.SHARE) 

6329 

6330 def test_migration_check_compatibility_no_cluster_credentials(self): 

6331 self.library._have_cluster_creds = False 

6332 self.mock_object(data_motion, 'get_backend_configuration') 

6333 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

6334 

6335 migration_compatibility = self.library.migration_check_compatibility( 

6336 self.context, fake_share.fake_share_instance(), 

6337 fake_share.fake_share_instance(), share_server=None, 

6338 destination_share_server=fake.SHARE_SERVER) 

6339 

6340 expected_compatibility = { 

6341 'compatible': False, 

6342 'writable': False, 

6343 'nondisruptive': False, 

6344 'preserve_metadata': False, 

6345 'preserve_snapshots': False, 

6346 } 

6347 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6348 mock_warning_log.assert_called_once() 

6349 self.assertFalse(data_motion.get_backend_configuration.called) 

6350 

6351 @ddt.data( 

6352 {'src_flexgroup': True, 'dest_flexgroup': False}, 

6353 {'src_flexgroup': False, 'dest_flexgroup': True}) 

6354 @ddt.unpack 

6355 def test_migration_check_compatibility_flexgroup(self, src_flexgroup, 

6356 dest_flexgroup): 

6357 self.library._have_cluster_creds = True 

6358 mock_dm = mock.Mock() 

6359 self.mock_object(data_motion, 'DataMotionSession', 

6360 mock.Mock(return_value=mock_dm)) 

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

6362 mock.Mock(return_value=dest_flexgroup)) 

6363 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6364 self.mock_object(share_utils, 'extract_host', 

6365 mock.Mock(return_value=fake.POOL_NAME)) 

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

6367 mock.Mock(return_value=src_flexgroup)) 

6368 

6369 migration_compatibility = self.library.migration_check_compatibility( 

6370 self.context, fake_share.fake_share_instance(), 

6371 fake_share.fake_share_instance(), share_server=None, 

6372 destination_share_server=fake.SHARE_SERVER) 

6373 

6374 expected_compatibility = { 

6375 'compatible': False, 

6376 'writable': False, 

6377 'nondisruptive': False, 

6378 'preserve_metadata': False, 

6379 'preserve_snapshots': False, 

6380 } 

6381 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6382 mock_exception_log.assert_called_once() 

6383 self.library._is_flexgroup_pool.assert_called_once_with(fake.POOL_NAME) 

6384 if src_flexgroup: 

6385 self.library.is_flexgroup_destination_host.assert_not_called() 

6386 

6387 @ddt.data((None, exception.NetAppException), 

6388 (exception.Invalid, None)) 

6389 @ddt.unpack 

6390 def test_migration_check_compatibility_extra_specs_invalid( 

6391 self, side_effect_1, side_effect_2): 

6392 self.library._have_cluster_creds = True 

6393 mock_dm = mock.Mock() 

6394 self.mock_object(data_motion, 'DataMotionSession', 

6395 mock.Mock(return_value=mock_dm)) 

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

6397 mock.Mock(return_value=False)) 

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

6399 mock.Mock(return_value=False)) 

6400 self.mock_object(self.library, '_get_backend_share_name', 

6401 mock.Mock(return_value=fake.SHARE_NAME)) 

6402 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6403 side_effect=[ 

6404 'destination_backend', 'destination_pool', 'source_pool'])) 

6405 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6406 self.mock_object(share_types, 'get_extra_specs_from_share') 

6407 self.mock_object(self.library, '_check_extra_specs_validity', 

6408 mock.Mock(side_effect=side_effect_1)) 

6409 self.mock_object(self.library, 

6410 '_check_aggregate_extra_specs_validity', 

6411 mock.Mock(side_effect=side_effect_2)) 

6412 self.mock_object(data_motion, 'get_backend_configuration') 

6413 

6414 migration_compatibility = self.library.migration_check_compatibility( 

6415 self.context, fake_share.fake_share_instance(), 

6416 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6417 destination_share_server=None) 

6418 

6419 expected_compatibility = { 

6420 'compatible': False, 

6421 'writable': False, 

6422 'nondisruptive': False, 

6423 'preserve_metadata': False, 

6424 'preserve_snapshots': False, 

6425 } 

6426 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6427 mock_exception_log.assert_called_once() 

6428 self.assertFalse(data_motion.get_backend_configuration.called) 

6429 

6430 def test_migration_check_compatibility_invalid_qos_configuration(self): 

6431 self.library._have_cluster_creds = True 

6432 mock_dm = mock.Mock() 

6433 self.mock_object(data_motion, 'DataMotionSession', 

6434 mock.Mock(return_value=mock_dm)) 

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

6436 mock.Mock(return_value=False)) 

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

6438 mock.Mock(return_value=False)) 

6439 self.mock_object(self.library, '_get_backend_share_name', 

6440 mock.Mock(return_value=fake.SHARE_NAME)) 

6441 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6442 side_effect=[ 

6443 'destination_backend', 'destination_pool', 'source_pool'])) 

6444 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6445 self.mock_object(share_types, 'get_extra_specs_from_share') 

6446 self.mock_object(self.library, '_check_extra_specs_validity') 

6447 self.mock_object( 

6448 self.library, '_get_provisioning_options', 

6449 mock.Mock(return_value=fake.PROVISIONING_OPTS_WITH_ADAPT_QOS)) 

6450 self.mock_object(self.library, '_get_normalized_qos_specs', 

6451 mock.Mock(return_value=fake.QOS_NORMALIZED_SPEC)) 

6452 

6453 migration_compatibility = self.library.migration_check_compatibility( 

6454 self.context, fake_share.fake_share_instance(), 

6455 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6456 destination_share_server=None) 

6457 

6458 expected_compatibility = { 

6459 'compatible': False, 

6460 'writable': False, 

6461 'nondisruptive': False, 

6462 'preserve_metadata': False, 

6463 'preserve_snapshots': False, 

6464 } 

6465 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6466 mock_exception_log.assert_called_once() 

6467 

6468 def test_migration_check_compatibility_destination_not_configured(self): 

6469 self.library._have_cluster_creds = True 

6470 mock_dm = mock.Mock() 

6471 mock_dm = mock.Mock() 

6472 self.mock_object(data_motion, 'DataMotionSession', 

6473 mock.Mock(return_value=mock_dm)) 

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

6475 mock.Mock(return_value=False)) 

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

6477 mock.Mock(return_value=False)) 

6478 self.mock_object(self.library, '_get_backend_share_name', 

6479 mock.Mock(return_value=fake.SHARE_NAME)) 

6480 self.mock_object( 

6481 data_motion, 'get_backend_configuration', 

6482 mock.Mock(side_effect=exception.BadConfigurationException( 

6483 reason='fake_reason'))) 

6484 self.mock_object(self.library, '_get_vserver') 

6485 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6486 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6487 return_value='destination_backend')) 

6488 self.mock_object(share_types, 'get_extra_specs_from_share') 

6489 self.mock_object(self.library, '_check_extra_specs_validity') 

6490 self.mock_object(self.library, '_check_aggregate_extra_specs_validity') 

6491 self.mock_object(self.library, '_get_provisioning_options', 

6492 mock.Mock(return_value={})) 

6493 self.mock_object(self.library, '_get_normalized_qos_specs') 

6494 self.mock_object(self.library, 

6495 'validate_provisioning_options_for_share') 

6496 mock_vserver_compatibility_check = self.mock_object( 

6497 self.library, '_check_destination_vserver_for_vol_move') 

6498 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6499 mock.Mock(return_value=False)) 

6500 

6501 migration_compatibility = self.library.migration_check_compatibility( 

6502 self.context, fake_share.fake_share_instance(), 

6503 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6504 destination_share_server=None) 

6505 

6506 expected_compatibility = { 

6507 'compatible': False, 

6508 'writable': False, 

6509 'nondisruptive': False, 

6510 'preserve_metadata': False, 

6511 'preserve_snapshots': False, 

6512 } 

6513 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6514 mock_exception_log.assert_called_once() 

6515 data_motion.get_backend_configuration.assert_called_once_with( 

6516 'destination_backend') 

6517 self.assertFalse(mock_vserver_compatibility_check.called) 

6518 self.assertFalse(self.library._get_vserver.called) 

6519 

6520 @ddt.data( 

6521 utils.annotated( 

6522 'dest_share_server_not_expected', 

6523 (('src_vserver', None), exception.InvalidParameterValue( 

6524 err='fake_err'))), 

6525 utils.annotated( 

6526 'src_share_server_not_expected', 

6527 (exception.InvalidParameterValue(err='fake_err'), 

6528 ('dest_vserver', None)))) 

6529 def test_migration_check_compatibility_errors(self, side_effects): 

6530 self.library._have_cluster_creds = True 

6531 mock_dm = mock.Mock() 

6532 self.mock_object(data_motion, 'DataMotionSession', 

6533 mock.Mock(return_value=mock_dm)) 

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

6535 mock.Mock(return_value=False)) 

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

6537 mock.Mock(return_value=False)) 

6538 self.mock_object(share_types, 'get_extra_specs_from_share') 

6539 self.mock_object(self.library, '_check_extra_specs_validity') 

6540 self.mock_object(self.library, '_check_aggregate_extra_specs_validity') 

6541 self.mock_object(self.library, '_get_backend_share_name', 

6542 mock.Mock(return_value=fake.SHARE_NAME)) 

6543 self.mock_object(self.library, '_get_provisioning_options', 

6544 mock.Mock(return_value={})) 

6545 self.mock_object(self.library, '_get_normalized_qos_specs') 

6546 self.mock_object(self.library, 

6547 'validate_provisioning_options_for_share') 

6548 self.mock_object(data_motion, 'get_backend_configuration') 

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

6550 mock.Mock(side_effect=side_effects)) 

6551 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6552 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6553 return_value='destination_backend')) 

6554 mock_compatibility_check = self.mock_object( 

6555 self.client, 'check_volume_move') 

6556 

6557 migration_compatibility = self.library.migration_check_compatibility( 

6558 self.context, fake_share.fake_share_instance(), 

6559 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6560 destination_share_server=None) 

6561 

6562 expected_compatibility = { 

6563 'compatible': False, 

6564 'writable': False, 

6565 'nondisruptive': False, 

6566 'preserve_metadata': False, 

6567 'preserve_snapshots': False, 

6568 } 

6569 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6570 mock_exception_log.assert_called_once() 

6571 data_motion.get_backend_configuration.assert_called_once_with( 

6572 'destination_backend') 

6573 self.assertFalse(mock_compatibility_check.called) 

6574 

6575 def test_migration_check_compatibility_incompatible_vservers(self): 

6576 self.library._have_cluster_creds = True 

6577 mock_dm = mock.Mock() 

6578 self.mock_object(data_motion, 'DataMotionSession', 

6579 mock.Mock(return_value=mock_dm)) 

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

6581 mock.Mock(return_value=False)) 

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

6583 mock.Mock(return_value=False)) 

6584 self.mock_object(share_types, 'get_extra_specs_from_share') 

6585 self.mock_object(self.library, '_check_extra_specs_validity') 

6586 self.mock_object(self.library, '_check_aggregate_extra_specs_validity') 

6587 self.mock_object(self.library, '_get_backend_share_name', 

6588 mock.Mock(return_value=fake.SHARE_NAME)) 

6589 self.mock_object(data_motion, 'get_backend_configuration') 

6590 self.mock_object(self.library, '_get_provisioning_options', 

6591 mock.Mock(return_value={})) 

6592 self.mock_object(self.library, '_get_normalized_qos_specs') 

6593 self.mock_object(self.library, 

6594 'validate_provisioning_options_for_share') 

6595 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6596 get_vserver_returns = [ 

6597 (fake.VSERVER1, mock.Mock()), 

6598 (fake.VSERVER2, mock.Mock()), 

6599 ] 

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

6601 mock.Mock(side_effect=get_vserver_returns)) 

6602 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6603 side_effect=[ 

6604 'destination_backend', 'destination_pool', 'source_pool'])) 

6605 mock_move_check = self.mock_object(self.client, 'check_volume_move') 

6606 

6607 migration_compatibility = self.library.migration_check_compatibility( 

6608 self.context, fake_share.fake_share_instance(), 

6609 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6610 destination_share_server='dst_srv') 

6611 

6612 expected_compatibility = { 

6613 'compatible': False, 

6614 'writable': False, 

6615 'nondisruptive': False, 

6616 'preserve_metadata': False, 

6617 'preserve_snapshots': False, 

6618 } 

6619 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6620 mock_exception_log.assert_called_once() 

6621 data_motion.get_backend_configuration.assert_called_once_with( 

6622 'destination_backend') 

6623 self.assertFalse(mock_move_check.called) 

6624 self.library._get_vserver.assert_has_calls( 

6625 [mock.call(share_server=fake.SHARE_SERVER), 

6626 mock.call(share_server='dst_srv')]) 

6627 

6628 def test_migration_check_compatibility_client_error(self): 

6629 self.library._have_cluster_creds = True 

6630 mock_dm = mock.Mock() 

6631 self.mock_object(data_motion, 'DataMotionSession', 

6632 mock.Mock(return_value=mock_dm)) 

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

6634 mock.Mock(return_value=False)) 

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

6636 mock.Mock(return_value=False)) 

6637 self.mock_object(share_types, 'get_extra_specs_from_share') 

6638 self.mock_object(self.library, '_check_extra_specs_validity') 

6639 self.mock_object(self.library, '_check_aggregate_extra_specs_validity') 

6640 self.mock_object(self.library, '_get_provisioning_options', 

6641 mock.Mock(return_value={})) 

6642 self.mock_object(self.library, '_get_normalized_qos_specs') 

6643 self.mock_object(self.library, 

6644 'validate_provisioning_options_for_share') 

6645 self.mock_object(self.library, '_get_backend_share_name', 

6646 mock.Mock(return_value=fake.SHARE_NAME)) 

6647 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

6648 self.mock_object(data_motion, 'get_backend_configuration') 

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

6650 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6651 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6652 side_effect=[ 

6653 'destination_backend', 'destination_pool', 'source_pool'])) 

6654 mock_move_check = self.mock_object( 

6655 self.client, 'check_volume_move', 

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

6657 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6658 mock.Mock(return_value=False)) 

6659 

6660 migration_compatibility = self.library.migration_check_compatibility( 

6661 self.context, fake_share.fake_share_instance(), 

6662 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6663 destination_share_server='dst_srv') 

6664 

6665 expected_compatibility = { 

6666 'compatible': False, 

6667 'writable': False, 

6668 'nondisruptive': False, 

6669 'preserve_metadata': False, 

6670 'preserve_snapshots': False, 

6671 } 

6672 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6673 mock_exception_log.assert_called_once() 

6674 data_motion.get_backend_configuration.assert_called_once_with( 

6675 'destination_backend') 

6676 mock_move_check.assert_called_once_with( 

6677 fake.SHARE_NAME, fake.VSERVER1, 'destination_pool', 

6678 encrypt_destination=False) 

6679 self.library._get_vserver.assert_has_calls( 

6680 [mock.call(share_server=fake.SHARE_SERVER), 

6681 mock.call(share_server='dst_srv')]) 

6682 

6683 @ddt.data(False, True) 

6684 def test_migration_check_compatibility(self, fpolicy): 

6685 self.library._have_cluster_creds = True 

6686 mock_dm = mock.Mock() 

6687 self.mock_object(data_motion, 'DataMotionSession', 

6688 mock.Mock(return_value=mock_dm)) 

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

6690 mock.Mock(return_value=False)) 

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

6692 mock.Mock(return_value=False)) 

6693 mock_dest_client = mock.Mock() 

6694 if fpolicy: 

6695 provisioning_options = copy.deepcopy( 

6696 fake.PROVISIONING_OPTIONS_WITH_FPOLICY) 

6697 get_vserver_side_effect = [(mock.Mock(), mock_dest_client), 

6698 (fake.VSERVER1, mock.Mock())] 

6699 else: 

6700 get_vserver_side_effect = [(fake.VSERVER1, mock.Mock())] 

6701 provisioning_options = {} 

6702 self.mock_object(share_types, 'get_extra_specs_from_share') 

6703 self.mock_object(self.library, '_check_extra_specs_validity') 

6704 self.mock_object(self.library, '_check_aggregate_extra_specs_validity') 

6705 self.mock_object(self.library, '_get_backend_share_name', 

6706 mock.Mock(return_value=fake.SHARE_NAME)) 

6707 self.mock_object(data_motion, 'get_backend_configuration') 

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

6709 mock.Mock(side_effect=get_vserver_side_effect)) 

6710 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6711 side_effect=[ 

6712 'destination_backend', 'destination_pool', 'source_pool'])) 

6713 mock_move_check = self.mock_object(self.client, 'check_volume_move') 

6714 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6715 mock.Mock(return_value=False)) 

6716 self.mock_object(self.library, '_get_provisioning_options', 

6717 mock.Mock(return_value=provisioning_options)) 

6718 self.mock_object(self.library, '_get_normalized_qos_specs') 

6719 self.mock_object(self.library, 

6720 'validate_provisioning_options_for_share') 

6721 self.mock_object(self.library, 

6722 '_check_destination_vserver_for_vol_move') 

6723 fpolicies = [ 

6724 x for x in range(1, self.library.FPOLICY_MAX_VSERVER_POLICIES + 1)] 

6725 mock_fpolicy_status = self.mock_object( 

6726 mock_dest_client, 'get_fpolicy_policies_status', 

6727 mock.Mock(return_value=fpolicies)) 

6728 mock_reusable_fpolicy = self.mock_object( 

6729 self.library, '_find_reusable_fpolicy_scope', 

6730 mock.Mock(return_value={'fake'})) 

6731 

6732 src_instance = fake_share.fake_share_instance() 

6733 dst_instance = fake_share.fake_share_instance() 

6734 migration_compatibility = self.library.migration_check_compatibility( 

6735 self.context, src_instance, dst_instance, 

6736 share_server=fake.SHARE_SERVER, destination_share_server='dst_srv') 

6737 

6738 expected_compatibility = { 

6739 'compatible': True, 

6740 'writable': True, 

6741 'nondisruptive': True, 

6742 'preserve_metadata': True, 

6743 'preserve_snapshots': True, 

6744 } 

6745 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6746 data_motion.get_backend_configuration.assert_called_once_with( 

6747 'destination_backend') 

6748 mock_move_check.assert_called_once_with( 

6749 fake.SHARE_NAME, fake.VSERVER1, 'destination_pool', 

6750 encrypt_destination=False) 

6751 if fpolicy: 

6752 self.library._get_vserver.assert_has_calls( 

6753 [mock.call(share_server='dst_srv'), 

6754 mock.call(share_server=fake.SHARE_SERVER)]) 

6755 mock_fpolicy_status.assert_called_once() 

6756 mock_reusable_fpolicy.assert_called_once_with( 

6757 dst_instance, mock_dest_client, 

6758 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

6759 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

6760 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS 

6761 ) 

6762 else: 

6763 self.library._get_vserver.assert_called_once_with( 

6764 share_server=fake.SHARE_SERVER) 

6765 

6766 def test_migration_check_compatibility_destination_type_is_encrypted(self): 

6767 self.library._have_cluster_creds = True 

6768 mock_dm = mock.Mock() 

6769 self.mock_object(data_motion, 'DataMotionSession', 

6770 mock.Mock(return_value=mock_dm)) 

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

6772 mock.Mock(return_value=False)) 

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

6774 mock.Mock(return_value=False)) 

6775 self.mock_object(self.library, '_get_backend_share_name', 

6776 mock.Mock(return_value=fake.SHARE_NAME)) 

6777 self.mock_object(data_motion, 'get_backend_configuration') 

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

6779 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6780 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6781 side_effect=[ 

6782 'destination_backend', 'destination_pool', 'source_pool'])) 

6783 mock_move_check = self.mock_object(self.client, 'check_volume_move') 

6784 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6785 mock.Mock(return_value=True)) 

6786 self.mock_object(share_types, 'get_extra_specs_from_share', 

6787 mock.Mock(return_value={'spec1': 'spec-data'})) 

6788 self.mock_object(self.library, 

6789 '_check_extra_specs_validity') 

6790 self.mock_object(self.library, 

6791 '_check_aggregate_extra_specs_validity') 

6792 self.mock_object(self.library, '_get_provisioning_options', 

6793 mock.Mock(return_value={})) 

6794 self.mock_object(self.library, '_get_normalized_qos_specs') 

6795 self.mock_object(self.library, 

6796 'validate_provisioning_options_for_share') 

6797 

6798 migration_compatibility = self.library.migration_check_compatibility( 

6799 self.context, fake_share.fake_share_instance(), 

6800 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6801 destination_share_server='dst_srv') 

6802 

6803 expected_compatibility = { 

6804 'compatible': True, 

6805 'writable': True, 

6806 'nondisruptive': True, 

6807 'preserve_metadata': True, 

6808 'preserve_snapshots': True, 

6809 } 

6810 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6811 data_motion.get_backend_configuration.assert_called_once_with( 

6812 'destination_backend') 

6813 

6814 mock_move_check.assert_called_once_with( 

6815 fake.SHARE_NAME, fake.VSERVER1, 'destination_pool', 

6816 encrypt_destination=True) 

6817 self.library._get_vserver.assert_has_calls( 

6818 [mock.call(share_server=fake.SHARE_SERVER), 

6819 mock.call(share_server='dst_srv')]) 

6820 

6821 def test_migration_check_compatibility_snaplock_not_compatible(self): 

6822 self.library._have_cluster_creds = True 

6823 self.mock_object(self.library, '_get_backend_share_name', 

6824 mock.Mock(return_value=fake.SHARE_NAME)) 

6825 self.mock_object(data_motion, 'get_backend_configuration') 

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

6827 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6828 self.mock_object(share_utils, 'extract_host', mock.Mock( 

6829 side_effect=[ 

6830 'destination_backend', 'destination_pool', 'source_pool'])) 

6831 mock_dm = mock.Mock() 

6832 self.mock_object(data_motion, 'DataMotionSession', 

6833 mock.Mock(return_value=mock_dm)) 

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

6835 mock.Mock(return_value=False)) 

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

6837 mock.Mock(return_value=False)) 

6838 self.mock_object(self.library, 

6839 '_is_snaplock_compatible_for_migration', 

6840 mock.Mock(return_value=False) 

6841 ) 

6842 migration_compatibility = self.library.migration_check_compatibility( 

6843 self.context, fake_share.fake_share_instance(), 

6844 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6845 destination_share_server='dst_srv') 

6846 

6847 expected_compatibility = { 

6848 'compatible': False, 

6849 'writable': False, 

6850 'nondisruptive': False, 

6851 'preserve_metadata': False, 

6852 'preserve_snapshots': False, 

6853 } 

6854 self.assertDictEqual(expected_compatibility, migration_compatibility) 

6855 

6856 def test_migration_start(self): 

6857 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

6858 source_snapshots = mock.Mock() 

6859 snapshot_mappings = mock.Mock() 

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

6861 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6862 self.mock_object(self.library, '_get_backend_share_name', 

6863 mock.Mock(return_value=fake.SHARE_NAME)) 

6864 self.mock_object(share_utils, 'extract_host', 

6865 mock.Mock(return_value='destination_pool')) 

6866 mock_move = self.mock_object(self.client, 'start_volume_move') 

6867 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6868 mock.Mock(return_value=False)) 

6869 

6870 retval = self.library.migration_start( 

6871 self.context, fake_share.fake_share_instance(), 

6872 fake_share.fake_share_instance(), 

6873 source_snapshots, snapshot_mappings, 

6874 share_server=fake.SHARE_SERVER, destination_share_server='dst_srv') 

6875 

6876 self.assertIsNone(retval) 

6877 self.assertTrue(mock_info_log.called) 

6878 mock_move.assert_called_once_with( 

6879 fake.SHARE_NAME, fake.VSERVER1, 'destination_pool', 

6880 cutover_action='wait', encrypt_destination=False) 

6881 

6882 def test_migration_start_encrypted_destination(self): 

6883 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

6884 source_snapshots = mock.Mock() 

6885 snapshot_mappings = mock.Mock() 

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

6887 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6888 self.mock_object(self.library, '_get_backend_share_name', 

6889 mock.Mock(return_value=fake.SHARE_NAME)) 

6890 self.mock_object(share_utils, 'extract_host', 

6891 mock.Mock(return_value='destination_pool')) 

6892 mock_move = self.mock_object(self.client, 'start_volume_move') 

6893 self.mock_object(self.library, '_get_dest_flexvol_encryption_value', 

6894 mock.Mock(return_value=True)) 

6895 

6896 retval = self.library.migration_start( 

6897 self.context, fake_share.fake_share_instance(), 

6898 fake_share.fake_share_instance(), 

6899 source_snapshots, snapshot_mappings, 

6900 share_server=fake.SHARE_SERVER, destination_share_server='dst_srv') 

6901 

6902 self.assertIsNone(retval) 

6903 self.assertTrue(mock_info_log.called) 

6904 mock_move.assert_called_once_with( 

6905 fake.SHARE_NAME, fake.VSERVER1, 'destination_pool', 

6906 cutover_action='wait', encrypt_destination=True) 

6907 

6908 def test_migration_continue_volume_move_failed(self): 

6909 source_snapshots = mock.Mock() 

6910 snapshot_mappings = mock.Mock() 

6911 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

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

6913 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6914 self.mock_object(self.library, '_get_backend_share_name', 

6915 mock.Mock(return_value=fake.SHARE_NAME)) 

6916 mock_status_check = self.mock_object( 

6917 self.client, 'get_volume_move_status', 

6918 mock.Mock(return_value={'phase': 'failed', 'details': 'unknown'})) 

6919 

6920 self.assertRaises(exception.NetAppException, 

6921 self.library.migration_continue, 

6922 self.context, fake_share.fake_share_instance(), 

6923 fake_share.fake_share_instance(), 

6924 source_snapshots, snapshot_mappings, 

6925 share_server=None, destination_share_server=None) 

6926 

6927 mock_status_check.assert_called_once_with( 

6928 fake.SHARE_NAME, fake.VSERVER1) 

6929 mock_exception_log.assert_called_once() 

6930 

6931 @ddt.data({'phase': 'Queued', 'completed': False}, 

6932 {'phase': 'Finishing', 'completed': False}, 

6933 {'phase': 'cutover_hard_deferred', 'completed': True}, 

6934 {'phase': 'cutover_soft_deferred', 'completed': True}, 

6935 {'phase': 'completed', 'completed': True}) 

6936 @ddt.unpack 

6937 def test_migration_continue(self, phase, completed): 

6938 source_snapshots = mock.Mock() 

6939 snapshot_mappings = mock.Mock() 

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

6941 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6942 self.mock_object(self.library, '_get_backend_share_name', 

6943 mock.Mock(return_value=fake.SHARE_NAME)) 

6944 self.mock_object(self.client, 'get_volume_move_status', 

6945 mock.Mock(return_value={'phase': phase})) 

6946 

6947 migration_completed = self.library.migration_continue( 

6948 self.context, fake_share.fake_share_instance(), 

6949 fake_share.fake_share_instance(), source_snapshots, 

6950 snapshot_mappings, share_server=fake.SHARE_SERVER, 

6951 destination_share_server='dst_srv') 

6952 

6953 self.assertEqual(completed, migration_completed) 

6954 

6955 @ddt.data('cutover_hard_deferred', 'cutover_soft_deferred', 

6956 'Queued', 'Replicating') 

6957 def test_migration_get_progress_at_phase(self, phase): 

6958 source_snapshots = mock.Mock() 

6959 snapshot_mappings = mock.Mock() 

6960 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

6961 status = { 

6962 'state': 'healthy', 

6963 'details': '%s:: Volume move job in progress' % phase, 

6964 'phase': phase, 

6965 'estimated-completion-time': '1481919246', 

6966 'percent-complete': 80, 

6967 } 

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

6969 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

6970 self.mock_object(self.library, '_get_backend_share_name', 

6971 mock.Mock(return_value=fake.SHARE_NAME)) 

6972 self.mock_object(self.client, 'get_volume_move_status', 

6973 mock.Mock(return_value=status)) 

6974 

6975 migration_progress = self.library.migration_get_progress( 

6976 self.context, fake_share.fake_share_instance(), 

6977 source_snapshots, snapshot_mappings, 

6978 fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER, 

6979 destination_share_server='dst_srv') 

6980 

6981 expected_progress = { 

6982 'total_progress': 100 if phase.startswith('cutover') else 80, 

6983 'state': 'healthy', 

6984 'estimated_completion_time': '1481919246', 

6985 'details': '%s:: Volume move job in progress' % phase, 

6986 'phase': phase, 

6987 } 

6988 self.assertDictEqual(expected_progress, migration_progress) 

6989 mock_info_log.assert_called_once() 

6990 

6991 @ddt.data({'state': 'failed'}, 

6992 {'state': 'healthy'}) 

6993 @ddt.unpack 

6994 def test_migration_cancel(self, state): 

6995 source_snapshots = mock.Mock() 

6996 snapshot_mappings = mock.Mock() 

6997 self.library.configuration.netapp_migration_cancel_timeout = 15 

6998 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

6999 

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

7001 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

7002 self.mock_object(self.library, '_get_backend_share_name', 

7003 mock.Mock(return_value=fake.SHARE_NAME)) 

7004 self.mock_object(self.client, 'abort_volume_move') 

7005 self.mock_object(self.client, 'get_volume_move_status', 

7006 mock.Mock(return_value={'state': state})) 

7007 

7008 if state == 'failed': 

7009 retval = self.library.migration_cancel( 

7010 self.context, fake_share.fake_share_instance(), 

7011 fake_share.fake_share_instance(), source_snapshots, 

7012 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7013 destination_share_server='dst_srv') 

7014 

7015 self.assertIsNone(retval) 

7016 mock_info_log.assert_called_once() 

7017 else: 

7018 self.assertRaises( 

7019 (exception.NetAppException), 

7020 self.library.migration_cancel, self.context, 

7021 fake_share.fake_share_instance(), 

7022 fake_share.fake_share_instance, source_snapshots, 

7023 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7024 destination_share_server='dst_srv') 

7025 

7026 @ddt.data({'already_canceled': True, 'effect': exception.NetAppException}, 

7027 {'already_canceled': False, 'effect': 

7028 (None, exception.NetAppException)}) 

7029 @ddt.unpack 

7030 def test_migration_cancel_exception_volume_status(self, already_canceled, 

7031 effect): 

7032 source_snapshots = mock.Mock() 

7033 snapshot_mappings = mock.Mock() 

7034 self.library.configuration.netapp_migration_cancel_timeout = 1 

7035 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

7036 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

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

7038 mock.Mock(return_value=(fake.VSERVER1, mock.Mock()))) 

7039 self.mock_object(self.library, '_get_backend_share_name', 

7040 mock.Mock(return_value=fake.SHARE_NAME)) 

7041 self.mock_object(self.client, 'abort_volume_move') 

7042 self.mock_object(self.client, 'get_volume_move_status', 

7043 mock.Mock(side_effect=effect)) 

7044 self.library.migration_cancel( 

7045 self.context, fake_share.fake_share_instance(), 

7046 fake_share.fake_share_instance(), source_snapshots, 

7047 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7048 destination_share_server='dst_srv') 

7049 

7050 mock_exception_log.assert_called_once() 

7051 if not already_canceled: 

7052 mock_info_log.assert_called_once() 

7053 

7054 self.assertEqual(not already_canceled, 

7055 self.client.abort_volume_move.called) 

7056 

7057 def test_migration_complete_invalid_phase(self): 

7058 source_snapshots = mock.Mock() 

7059 snapshot_mappings = mock.Mock() 

7060 status = { 

7061 'state': 'healthy', 

7062 'phase': 'Replicating', 

7063 'details': 'Replicating:: Volume move operation is in progress.', 

7064 } 

7065 mock_exception_log = self.mock_object(lib_base.LOG, 'exception') 

7066 vserver_client = mock.Mock() 

7067 self.mock_object( 

7068 self.library, '_get_vserver', 

7069 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

7070 self.mock_object( 

7071 self.library, '_get_backend_share_name', 

7072 mock.Mock(side_effect=[fake.SHARE_NAME, 'new_share_name'])) 

7073 self.mock_object(self.library, '_get_volume_move_status', 

7074 mock.Mock(return_value=status)) 

7075 self.mock_object(self.library, '_create_export') 

7076 

7077 self.assertRaises( 

7078 exception.NetAppException, self.library.migration_complete, 

7079 self.context, fake_share.fake_share_instance(), 

7080 fake_share.fake_share_instance, source_snapshots, 

7081 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7082 destination_share_server='dst_srv') 

7083 self.assertFalse(vserver_client.set_volume_name.called) 

7084 self.assertFalse(self.library._create_export.called) 

7085 mock_exception_log.assert_called_once() 

7086 

7087 def test_migration_complete_timeout(self): 

7088 source_snapshots = mock.Mock() 

7089 snapshot_mappings = mock.Mock() 

7090 self.library.configuration.netapp_volume_move_cutover_timeout = 15 

7091 vol_move_side_effects = [ 

7092 {'phase': 'cutover_hard_deferred'}, 

7093 {'phase': 'Cutover'}, 

7094 {'phase': 'Finishing'}, 

7095 {'phase': 'Finishing'}, 

7096 ] 

7097 self.mock_object(time, 'sleep') 

7098 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

7099 vserver_client = mock.Mock() 

7100 self.mock_object( 

7101 self.library, '_get_vserver', 

7102 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

7103 self.mock_object( 

7104 self.library, '_get_backend_share_name', 

7105 mock.Mock(side_effect=[fake.SHARE_NAME, 'new_share_name'])) 

7106 self.mock_object(self.library, '_get_volume_move_status', mock.Mock( 

7107 side_effect=vol_move_side_effects)) 

7108 self.mock_object(self.library, '_create_export') 

7109 src_share = fake_share.fake_share_instance(id='source-share-instance') 

7110 dest_share = fake_share.fake_share_instance(id='dest-share-instance') 

7111 

7112 self.assertRaises( 

7113 exception.NetAppException, self.library.migration_complete, 

7114 self.context, src_share, dest_share, source_snapshots, 

7115 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7116 destination_share_server='dst_srv') 

7117 self.assertFalse(vserver_client.set_volume_name.called) 

7118 self.assertFalse(self.library._create_export.called) 

7119 self.assertEqual(3, mock_warning_log.call_count) 

7120 

7121 @ddt.data({'phase': 'cutover_hard_deferred', 

7122 'provisioning_options': fake.PROVISIONING_OPTIONS_WITH_QOS, 

7123 'policy_group_name': fake.QOS_POLICY_GROUP_NAME}, 

7124 {'phase': 'cutover_soft_deferred', 

7125 'provisioning_options': fake.PROVISIONING_OPTIONS_WITH_QOS, 

7126 'policy_group_name': fake.QOS_POLICY_GROUP_NAME}, 

7127 {'phase': 'completed', 

7128 'provisioning_options': fake.PROVISIONING_OPTIONS, 

7129 'policy_group_name': False}, 

7130 {'phase': 'completed', 

7131 'provisioning_options': fake.PROVISIONING_OPTIONS_WITH_FPOLICY, 

7132 'policy_group_name': False}) 

7133 @ddt.unpack 

7134 def test_migration_complete(self, phase, provisioning_options, 

7135 policy_group_name): 

7136 snap = fake_share.fake_snapshot_instance( 

7137 id='src-snapshot', provider_location='test-src-provider-location') 

7138 dest_snap = fake_share.fake_snapshot_instance(id='dest-snapshot', 

7139 as_primitive=True) 

7140 extra_specs = copy.deepcopy(fake.EXTRA_SPEC) 

7141 source_snapshots = [snap] 

7142 snapshot_mappings = {snap['id']: dest_snap} 

7143 self.library.configuration.netapp_volume_move_cutover_timeout = 15 

7144 vol_move_side_effects = [ 

7145 {'phase': phase}, 

7146 {'phase': 'Cutover'}, 

7147 {'phase': 'Finishing'}, 

7148 {'phase': 'completed'}, 

7149 ] 

7150 self.mock_object(time, 'sleep') 

7151 mock_debug_log = self.mock_object(lib_base.LOG, 'debug') 

7152 mock_info_log = self.mock_object(lib_base.LOG, 'info') 

7153 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

7154 vserver_client = mock.Mock() 

7155 self.mock_object( 

7156 self.library, '_get_vserver', 

7157 mock.Mock(return_value=(fake.VSERVER1, vserver_client))) 

7158 self.mock_object( 

7159 self.library, '_get_backend_share_name', 

7160 mock.Mock(side_effect=[fake.SHARE_NAME, 'new_share_name'])) 

7161 self.mock_object(self.library, '_create_export', mock.Mock( 

7162 return_value=fake.NFS_EXPORTS)) 

7163 mock_move_status_check = self.mock_object( 

7164 self.library, '_get_volume_move_status', 

7165 mock.Mock(side_effect=vol_move_side_effects)) 

7166 self.mock_object(share_types, 'get_extra_specs_from_share', 

7167 mock.Mock(return_value=extra_specs)) 

7168 self.mock_object(self.library, '_check_fpolicy_file_operations') 

7169 self.mock_object( 

7170 self.library, '_get_provisioning_options', 

7171 mock.Mock(return_value=provisioning_options)) 

7172 self.mock_object( 

7173 self.library, '_modify_or_create_qos_for_existing_share', 

7174 mock.Mock(return_value=policy_group_name)) 

7175 mock_get_volume_snapshot_attributes = self.mock_object( 

7176 vserver_client, 'get_volume_snapshot_attributes', 

7177 mock.Mock(return_value={'snapshot-policy': 'fake_policy'})) 

7178 self.mock_object(vserver_client, 'modify_volume') 

7179 mock_create_new_fpolicy = self.mock_object( 

7180 self.library, '_create_fpolicy_for_share') 

7181 

7182 mock_delete_policy = self.mock_object(self.library, 

7183 '_delete_fpolicy_for_share') 

7184 

7185 src_share = fake_share.fake_share_instance(id='source-share-instance') 

7186 dest_share = fake_share.fake_share_instance(id='dest-share-instance') 

7187 dest_aggr = share_utils.extract_host(dest_share['host'], level='pool') 

7188 

7189 data_updates = self.library.migration_complete( 

7190 self.context, src_share, dest_share, source_snapshots, 

7191 snapshot_mappings, share_server=fake.SHARE_SERVER, 

7192 destination_share_server='dst_srv') 

7193 

7194 self.assertEqual(fake.NFS_EXPORTS, data_updates['export_locations']) 

7195 expected_dest_snap_updates = { 

7196 'provider_location': snap['provider_location'], 

7197 } 

7198 self.assertIn(dest_snap['id'], data_updates['snapshot_updates']) 

7199 self.assertEqual(expected_dest_snap_updates, 

7200 data_updates['snapshot_updates'][dest_snap['id']]) 

7201 vserver_client.set_volume_name.assert_called_once_with( 

7202 fake.SHARE_NAME, 'new_share_name') 

7203 self.library._create_export.assert_called_once_with( 

7204 dest_share, fake.SHARE_SERVER, fake.VSERVER1, vserver_client, 

7205 clear_current_export_policy=False) 

7206 mock_get_volume_snapshot_attributes.assert_called_once_with( 

7207 'new_share_name') 

7208 vserver_client.modify_volume.assert_called_once_with( 

7209 dest_aggr, 'new_share_name', **provisioning_options) 

7210 mock_info_log.assert_called_once() 

7211 mock_delete_policy.assert_called_once_with(src_share, fake.VSERVER1, 

7212 vserver_client) 

7213 if phase != 'completed': 

7214 self.assertEqual(2, mock_warning_log.call_count) 

7215 self.assertFalse(mock_debug_log.called) 

7216 self.assertEqual(4, mock_move_status_check.call_count) 

7217 else: 

7218 self.assertFalse(mock_warning_log.called) 

7219 mock_debug_log.assert_called_once() 

7220 mock_move_status_check.assert_called_once() 

7221 if provisioning_options.get( 

7222 'fpolicy_extensions_to_include') is not None: 

7223 mock_create_new_fpolicy.assert_called_once_with( 

7224 dest_share, fake.VSERVER1, vserver_client, 

7225 **provisioning_options) 

7226 else: 

7227 mock_create_new_fpolicy.assert_not_called() 

7228 

7229 def test_modify_or_create_qos_for_existing_share_no_qos_extra_specs(self): 

7230 vserver_client = mock.Mock() 

7231 self.mock_object(self.library, '_get_backend_qos_policy_group_name') 

7232 self.mock_object(vserver_client, 'get_volume') 

7233 self.mock_object(self.library, '_create_qos_policy_group') 

7234 

7235 retval = self.library._modify_or_create_qos_for_existing_share( 

7236 fake.SHARE, fake.EXTRA_SPEC, fake.VSERVER1, vserver_client) 

7237 

7238 self.assertIsNone(retval) 

7239 self.library._get_backend_qos_policy_group_name.assert_not_called() 

7240 vserver_client.get_volume.assert_not_called() 

7241 self.library._create_qos_policy_group.assert_not_called() 

7242 

7243 def test_modify_or_create_qos_for_existing_share_no_existing_qos(self): 

7244 vserver_client = mock.Mock() 

7245 self.mock_object(self.library, '_get_backend_qos_policy_group_name') 

7246 self.mock_object(vserver_client, 'get_volume', 

7247 mock.Mock(return_value=fake.FLEXVOL_WITHOUT_QOS)) 

7248 self.mock_object(self.library, '_create_qos_policy_group') 

7249 self.mock_object(self.library._client, 'qos_policy_group_modify') 

7250 qos_policy_name = self.library._get_backend_qos_policy_group_name( 

7251 fake.SHARE['id']) 

7252 

7253 retval = self.library._modify_or_create_qos_for_existing_share( 

7254 fake.SHARE, fake.EXTRA_SPEC_WITH_QOS, fake.VSERVER1, 

7255 vserver_client) 

7256 

7257 share_obj = { 

7258 'size': 2, 

7259 'id': fake.SHARE['id'], 

7260 } 

7261 self.assertEqual(qos_policy_name, retval) 

7262 self.library._client.qos_policy_group_modify.assert_not_called() 

7263 self.library._create_qos_policy_group.assert_called_once_with( 

7264 share_obj, fake.VSERVER1, {'maxiops': '3000', 'miniops': '20'}, 

7265 vserver_client=vserver_client) 

7266 

7267 @ddt.data(utils.annotated('volume_has_shared_qos_policy', 

7268 (2, False, False)), 

7269 utils.annotated('volume_has_shared_qos_policy', 

7270 (2, False, True)), 

7271 utils.annotated('volume_has_shared_qos_policy', 

7272 (2, True, False)), 

7273 utils.annotated('volume_has_shared_qos_policy_iops_change', 

7274 (2, False, False)), 

7275 utils.annotated('volume_has_shared_qos_policy_iops_change', 

7276 (2, True, False)), 

7277 utils.annotated('volume_has_shared_qos_policy_iops_change', 

7278 (2, False, True)), 

7279 utils.annotated('volume_has_nonshared_qos_policy', 

7280 (1, False, False)), 

7281 utils.annotated('volume_has_nonshared_qos_policy', 

7282 (1, False, True)), 

7283 utils.annotated('volume_has_nonshared_qos_policy', 

7284 (1, True, False)), 

7285 utils.annotated('volume_has_nonshared_qos_policy_iops_change', 

7286 (1, False, False)), 

7287 utils.annotated('volume_has_nonshared_qos_policy_iops_change', 

7288 (1, False, True)), 

7289 utils.annotated('volume_has_nonshared_qos_policy_iops_change', 

7290 (1, True, False))) 

7291 @ddt.unpack 

7292 def test_modify_or_create_qos_for_existing_share(self, num_workloads, 

7293 qos_max_iops_change, 

7294 qos_min_iops_change): 

7295 vserver_client = mock.Mock() 

7296 qos_policy = copy.deepcopy(fake.QOS_POLICY_GROUP) 

7297 qos_policy['num-workloads'] = num_workloads 

7298 extra_specs = copy.deepcopy(fake.EXTRA_SPEC_WITH_QOS) 

7299 expected_max_iops = '3000' 

7300 expected_min_iops = '20' 

7301 if qos_max_iops_change: 

7302 expected_max_iops = '4000' 

7303 extra_specs[fake.QOS_MAX_EXTRA_SPEC] = expected_max_iops 

7304 if qos_min_iops_change: 

7305 expected_min_iops = '50' 

7306 extra_specs[fake.QOS_MIN_EXTRA_SPEC] = expected_min_iops 

7307 

7308 self.mock_object(vserver_client, 'get_volume', 

7309 mock.Mock(return_value=fake.FLEXVOL_WITH_QOS)) 

7310 self.mock_object(self.library._client, 'qos_policy_group_get', 

7311 mock.Mock(return_value=qos_policy)) 

7312 mock_qos_policy_modify = self.mock_object( 

7313 self.library._client, 'qos_policy_group_modify') 

7314 mock_qos_policy_rename = self.mock_object( 

7315 self.library._client, 'qos_policy_group_rename') 

7316 mock_create_qos_policy = self.mock_object( 

7317 self.library, '_create_qos_policy_group') 

7318 new_qos_policy_name = self.library._get_backend_qos_policy_group_name( 

7319 fake.SHARE['id']) 

7320 

7321 retval = self.library._modify_or_create_qos_for_existing_share( 

7322 fake.SHARE, extra_specs, fake.VSERVER1, vserver_client) 

7323 

7324 self.assertEqual(new_qos_policy_name, retval) 

7325 if num_workloads == 1: 

7326 mock_create_qos_policy.assert_not_called() 

7327 if qos_max_iops_change or qos_min_iops_change: 

7328 mock_qos_policy_modify.assert_called_once_with( 

7329 fake.QOS_POLICY_GROUP_NAME, expected_max_iops + 'iops', 

7330 expected_min_iops + 'iops') 

7331 else: 

7332 mock_qos_policy_modify.assert_not_called() 

7333 

7334 mock_qos_policy_rename.assert_called_once_with( 

7335 fake.QOS_POLICY_GROUP_NAME, new_qos_policy_name) 

7336 else: 

7337 share_obj = { 

7338 'size': 2, 

7339 'id': fake.SHARE['id'], 

7340 } 

7341 mock_create_qos_policy.assert_called_once_with( 

7342 share_obj, fake.VSERVER1, 

7343 {'maxiops': expected_max_iops, 'miniops': expected_min_iops}, 

7344 vserver_client=vserver_client) 

7345 self.library._client.qos_policy_group_modify.assert_not_called() 

7346 self.library._client.qos_policy_group_rename.assert_not_called() 

7347 

7348 @ddt.data(('host', True), ('pool', False), (None, False), ('fake', False)) 

7349 @ddt.unpack 

7350 def test__is_group_cg(self, css, is_cg): 

7351 share_group = mock.Mock() 

7352 share_group.consistent_snapshot_support = css 

7353 self.assertEqual(is_cg, 

7354 self.library._is_group_cg(self.context, share_group)) 

7355 

7356 def test_create_group_snapshot_cg(self): 

7357 share_group = mock.Mock() 

7358 share_group.consistent_snapshot_support = 'host' 

7359 snap_dict = {'share_group': share_group} 

7360 fallback_create = mock.Mock() 

7361 mock_create_cgsnapshot = self.mock_object(self.library, 

7362 'create_cgsnapshot') 

7363 self.library.create_group_snapshot(self.context, snap_dict, 

7364 fallback_create, 

7365 share_server=fake.SHARE_SERVER) 

7366 mock_create_cgsnapshot.assert_called_once_with( 

7367 self.context, snap_dict, share_server=fake.SHARE_SERVER) 

7368 fallback_create.assert_not_called() 

7369 

7370 @ddt.data('pool', None, 'fake') 

7371 def test_create_group_snapshot_fallback(self, css): 

7372 share_group = mock.Mock() 

7373 share_group.consistent_snapshot_support = css 

7374 snap_dict = {'share_group': share_group} 

7375 fallback_create = mock.Mock() 

7376 mock_create_cgsnapshot = self.mock_object(self.library, 

7377 'create_cgsnapshot') 

7378 self.library.create_group_snapshot(self.context, snap_dict, 

7379 fallback_create, 

7380 share_server=fake.SHARE_SERVER) 

7381 mock_create_cgsnapshot.assert_not_called() 

7382 fallback_create.assert_called_once_with(self.context, 

7383 snap_dict, 

7384 share_server=fake.SHARE_SERVER) 

7385 

7386 def test_delete_group_snapshot_cg(self): 

7387 share_group = mock.Mock() 

7388 share_group.consistent_snapshot_support = 'host' 

7389 snap_dict = {'share_group': share_group} 

7390 fallback_delete = mock.Mock() 

7391 mock_delete_cgsnapshot = self.mock_object(self.library, 

7392 'delete_cgsnapshot') 

7393 self.library.delete_group_snapshot(self.context, snap_dict, 

7394 fallback_delete, 

7395 share_server=fake.SHARE_SERVER) 

7396 mock_delete_cgsnapshot.assert_called_once_with( 

7397 self.context, snap_dict, share_server=fake.SHARE_SERVER) 

7398 fallback_delete.assert_not_called() 

7399 

7400 @ddt.data('pool', None, 'fake') 

7401 def test_delete_group_snapshot_fallback(self, css): 

7402 share_group = mock.Mock() 

7403 share_group.consistent_snapshot_support = css 

7404 snap_dict = {'share_group': share_group} 

7405 fallback_delete = mock.Mock() 

7406 mock_delete_cgsnapshot = self.mock_object(self.library, 

7407 'delete_cgsnapshot') 

7408 self.library.delete_group_snapshot(self.context, snap_dict, 

7409 fallback_delete, 

7410 share_server=fake.SHARE_SERVER) 

7411 mock_delete_cgsnapshot.assert_not_called() 

7412 fallback_delete.assert_called_once_with(self.context, 

7413 snap_dict, 

7414 share_server=fake.SHARE_SERVER) 

7415 

7416 def test_create_group_from_snapshot_cg(self): 

7417 share_group = mock.Mock() 

7418 share_group.consistent_snapshot_support = 'host' 

7419 snap_dict = {'share_group': share_group} 

7420 fallback_create = mock.Mock() 

7421 mock_create_cg_from_snapshot = self.mock_object( 

7422 self.library, 'create_consistency_group_from_cgsnapshot') 

7423 self.library.create_group_from_snapshot(self.context, share_group, 

7424 snap_dict, fallback_create, 

7425 share_server=fake.SHARE_SERVER) 

7426 mock_create_cg_from_snapshot.assert_called_once_with( 

7427 self.context, share_group, snap_dict, 

7428 share_server=fake.SHARE_SERVER) 

7429 fallback_create.assert_not_called() 

7430 

7431 @ddt.data('pool', None, 'fake') 

7432 def test_create_group_from_snapshot_fallback(self, css): 

7433 share_group = mock.Mock() 

7434 share_group.consistent_snapshot_support = css 

7435 snap_dict = {'share_group': share_group} 

7436 fallback_create = mock.Mock() 

7437 mock_create_cg_from_snapshot = self.mock_object( 

7438 self.library, 'create_consistency_group_from_cgsnapshot') 

7439 self.library.create_group_from_snapshot(self.context, share_group, 

7440 snap_dict, fallback_create, 

7441 share_server=fake.SHARE_SERVER) 

7442 mock_create_cg_from_snapshot.assert_not_called() 

7443 fallback_create.assert_called_once_with(self.context, share_group, 

7444 snap_dict, 

7445 share_server=fake.SHARE_SERVER) 

7446 

7447 @ddt.data('default', 'hidden', 'visible') 

7448 def test_get_backend_info(self, snapdir): 

7449 

7450 self.library.configuration.netapp_reset_snapdir_visibility = snapdir 

7451 expected = {'snapdir_visibility': snapdir} 

7452 

7453 result = self.library.get_backend_info(self.context) 

7454 self.assertEqual(expected, result) 

7455 

7456 @ddt.data('default', 'hidden') 

7457 def test_ensure_shares(self, snapdir_cfg): 

7458 shares = [ 

7459 fake_share.fake_share_instance(id='s-1', 

7460 share_server='fake_server_1'), 

7461 fake_share.fake_share_instance(id='s-2', 

7462 share_server='fake_server_2'), 

7463 fake_share.fake_share_instance(id='s-3', 

7464 share_server='fake_server_2') 

7465 ] 

7466 

7467 vserver_client = mock.Mock() 

7468 self.mock_object( 

7469 self.library, '_get_vserver', 

7470 mock.Mock(side_effect=[ 

7471 (fake.VSERVER1, vserver_client), 

7472 (fake.VSERVER2, vserver_client), 

7473 (fake.VSERVER2, vserver_client) 

7474 ])) 

7475 (self.library.configuration. 

7476 netapp_reset_snapdir_visibility) = snapdir_cfg 

7477 

7478 self.library.ensure_shares(self.context, shares) 

7479 

7480 if snapdir_cfg == 'default': 

7481 self.library._get_vserver.assert_not_called() 

7482 vserver_client.set_volume_snapdir_access.assert_not_called() 

7483 

7484 else: 

7485 self.library._get_vserver.assert_has_calls([ 

7486 mock.call(share_server='fake_server_1'), 

7487 mock.call(share_server='fake_server_2'), 

7488 mock.call(share_server='fake_server_2'), 

7489 ]) 

7490 

7491 vserver_client.set_volume_snapdir_access.assert_has_calls([ 

7492 mock.call('share_s_1', True), 

7493 mock.call('share_s_2', True), 

7494 mock.call('share_s_3', True), 

7495 ]) 

7496 

7497 def test__check_volume_clone_split_completed(self): 

7498 vserver_client = mock.Mock() 

7499 mock_share_name = self.mock_object( 

7500 self.library, '_get_backend_share_name', 

7501 mock.Mock(return_value=fake.SHARE_NAME)) 

7502 vserver_client.check_volume_clone_split_completed.return_value = ( 

7503 fake.CDOT_SNAPSHOT_BUSY_SNAPMIRROR) 

7504 

7505 self.library._check_volume_clone_split_completed(fake.SHARE, 

7506 vserver_client) 

7507 

7508 mock_share_name.assert_called_once_with(fake.SHARE_ID) 

7509 check_call = vserver_client.check_volume_clone_split_completed 

7510 check_call.assert_called_once_with(fake.SHARE_NAME) 

7511 

7512 @ddt.data(constants.STATUS_ACTIVE, constants.STATUS_CREATING_FROM_SNAPSHOT) 

7513 def test_get_share_status(self, status): 

7514 mock_update_from_snap = self.mock_object( 

7515 self.library, '_update_create_from_snapshot_status') 

7516 fake.SHARE['status'] = status 

7517 

7518 self.library.get_share_status(fake.SHARE, fake.SHARE_SERVER) 

7519 

7520 if status == constants.STATUS_CREATING_FROM_SNAPSHOT: 

7521 mock_update_from_snap.assert_called_once_with(fake.SHARE, 

7522 fake.SHARE_SERVER) 

7523 else: 

7524 mock_update_from_snap.assert_not_called() 

7525 

7526 def test_volume_rehost(self): 

7527 mock_share_name = self.mock_object( 

7528 self.library, '_get_backend_share_name', 

7529 mock.Mock(return_value=fake.SHARE_NAME)) 

7530 mock_rehost = self.mock_object(self.client, 'rehost_volume') 

7531 

7532 self.library.volume_rehost(fake.SHARE, fake.VSERVER1, fake.VSERVER2) 

7533 

7534 mock_share_name.assert_called_once_with(fake.SHARE_ID) 

7535 mock_rehost.assert_called_once_with(fake.SHARE_NAME, fake.VSERVER1, 

7536 fake.VSERVER2) 

7537 

7538 def test__rehost_and_mount_volume(self): 

7539 mock_share_name = self.mock_object( 

7540 self.library, '_get_backend_share_name', 

7541 mock.Mock(return_value=fake.SHARE_NAME)) 

7542 mock_rehost = self.mock_object(self.library, 'volume_rehost', 

7543 mock.Mock()) 

7544 src_vserver_client = mock.Mock() 

7545 mock_unmount = self.mock_object(src_vserver_client, 'unmount_volume') 

7546 dst_vserver_client = mock.Mock() 

7547 mock_mount = self.mock_object(dst_vserver_client, 'mount_volume') 

7548 

7549 self.library._rehost_and_mount_volume( 

7550 fake.SHARE, fake.VSERVER1, src_vserver_client, fake.VSERVER2, 

7551 dst_vserver_client) 

7552 

7553 mock_share_name.assert_called_once_with(fake.SHARE_ID) 

7554 mock_unmount.assert_called_once_with(fake.SHARE_NAME) 

7555 mock_rehost.assert_called_once_with(fake.SHARE, fake.VSERVER1, 

7556 fake.VSERVER2) 

7557 mock_mount.assert_called_once_with(fake.SHARE_NAME, 

7558 fake.MOUNT_POINT_NAME) 

7559 

7560 def test__move_volume_after_splitting(self): 

7561 src_share = fake_share.fake_share_instance(id='source-share-instance') 

7562 dest_share = fake_share.fake_share_instance(id='dest-share-instance') 

7563 cutover_action = 'defer' 

7564 self.library.configuration.netapp_start_volume_move_timeout = 15 

7565 

7566 self.mock_object(time, 'sleep') 

7567 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

7568 mock_vol_move = self.mock_object(self.library, '_move_volume') 

7569 

7570 self.library._move_volume_after_splitting( 

7571 src_share, dest_share, share_server=fake.SHARE_SERVER, 

7572 cutover_action=cutover_action) 

7573 

7574 mock_vol_move.assert_called_once_with(src_share, dest_share, 

7575 fake.SHARE_SERVER, 

7576 cutover_action) 

7577 self.assertEqual(0, mock_warning_log.call_count) 

7578 

7579 def test__move_volume_after_splitting_timeout(self): 

7580 src_share = fake_share.fake_share_instance(id='source-share-instance') 

7581 dest_share = fake_share.fake_share_instance(id='dest-share-instance') 

7582 self.library.configuration.netapp_start_volume_move_timeout = 15 

7583 cutover_action = 'defer' 

7584 

7585 self.mock_object(time, 'sleep') 

7586 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

7587 undergoing_split_op_msg = ( 

7588 'The volume is undergoing a clone split operation.') 

7589 na_api_error = netapp_api.NaApiError(code=netapp_api.EAPIERROR, 

7590 message=undergoing_split_op_msg) 

7591 mock_move_vol = self.mock_object( 

7592 self.library, '_move_volume', mock.Mock(side_effect=na_api_error)) 

7593 

7594 self.assertRaises(exception.NetAppException, 

7595 self.library._move_volume_after_splitting, 

7596 src_share, dest_share, 

7597 share_server=fake.SHARE_SERVER, 

7598 cutover_action=cutover_action) 

7599 

7600 self.assertEqual(3, mock_move_vol.call_count) 

7601 self.assertEqual(3, mock_warning_log.call_count) 

7602 

7603 def test__move_volume_after_splitting_api_not_found(self): 

7604 src_share = fake_share.fake_share_instance(id='source-share-instance') 

7605 dest_share = fake_share.fake_share_instance(id='dest-share-instance') 

7606 self.library.configuration.netapp_start_volume_move_timeout = 15 

7607 cutover_action = 'defer' 

7608 

7609 self.mock_object(time, 'sleep') 

7610 mock_warning_log = self.mock_object(lib_base.LOG, 'warning') 

7611 na_api_error = netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND) 

7612 mock_move_vol = self.mock_object( 

7613 self.library, '_move_volume', mock.Mock(side_effect=na_api_error)) 

7614 

7615 self.assertRaises(exception.NetAppException, 

7616 self.library._move_volume_after_splitting, 

7617 src_share, dest_share, 

7618 share_server=fake.SHARE_SERVER, 

7619 cutover_action=cutover_action) 

7620 

7621 mock_move_vol.assert_called_once_with(src_share, dest_share, 

7622 fake.SHARE_SERVER, 

7623 cutover_action) 

7624 mock_warning_log.assert_not_called() 

7625 

7626 @ddt.data({'total': 20, 'free': 5, 'reserved': 10, 'thin': False, 

7627 'over_sub': 0, 'size': 3, 'compatible': True, 'nb_pools': 1}, 

7628 {'total': 20, 'free': 5, 'reserved': 10, 'thin': False, 

7629 'over_sub': 0, 'size': 4, 'compatible': False, 'nb_pools': 1}, 

7630 {'total': 20, 'free': 5, 'reserved': 20, 'thin': False, 

7631 'over_sub': 1.1, 'size': 3, 'compatible': False, 'nb_pools': 1}, 

7632 {'total': 20, 'free': 5, 'reserved': 10, 'thin': True, 

7633 'over_sub': 2.0, 'size': 6, 'compatible': True, 'nb_pools': 1}, 

7634 {'total': 20, 'free': 5, 'reserved': 10, 'thin': True, 

7635 'over_sub': 1.0, 'size': 4, 'compatible': False, 'nb_pools': 1}, 

7636 {'total': 'unknown', 'free': 5, 'reserved': 0, 'thin': False, 

7637 'over_sub': 3.0, 'size': 1, 'compatible': False, 'nb_pools': 1}, 

7638 {'total': 20, 'free': 5, 'reserved': 10, 'thin': True, 

7639 'over_sub': 1.0, 'size': 6, 'compatible': True, 'nb_pools': 2}, 

7640 {'total': 20, 'free': 5, 'reserved': 10, 'thin': True, 

7641 'over_sub': 1.0, 'size': 7, 'compatible': False, 'nb_pools': 2}, 

7642 ) 

7643 @ddt.unpack 

7644 def test__check_capacity_compatibility(self, total, free, reserved, thin, 

7645 over_sub, size, compatible, 

7646 nb_pools): 

7647 pools = [] 

7648 for p in range(nb_pools): 

7649 pool = copy.deepcopy(fake.POOLS[0]) 

7650 pool['total_capacity_gb'] = total 

7651 pool['free_capacity_gb'] = free 

7652 pool['reserved_percentage'] = reserved 

7653 pool['max_over_subscription_ratio'] = over_sub 

7654 pools.append(pool) 

7655 

7656 result = self.library._check_capacity_compatibility(pools, thin, size) 

7657 

7658 self.assertEqual(compatible, result) 

7659 

7660 @ddt.data({'provisioning_opts': fake.PROVISIONING_OPTS_WITH_ADAPT_QOS, 

7661 'qos_specs': {fake.QOS_NORMALIZED_SPEC: 3000}, 

7662 'extra_specs': None, 

7663 'cluster_credentials': True}, 

7664 {'provisioning_opts': fake.PROVISIONING_OPTS_WITH_ADAPT_QOS, 

7665 'qos_specs': None, 

7666 'extra_specs': fake.EXTRA_SPEC_WITH_REPLICATION, 

7667 'cluster_credentials': True}, 

7668 {'provisioning_opts': fake.PROVISIONING_OPTIONS, 

7669 'qos_specs': {fake.QOS_NORMALIZED_SPEC: 3000}, 

7670 'extra_specs': None, 

7671 'cluster_credentials': False}, 

7672 {'provisioning_opts': fake.PROVISIONING_OPTS_WITH_ADAPT_QOS, 

7673 'qos_specs': None, 

7674 'extra_specs': None, 

7675 'cluster_credentials': False}, 

7676 {'provisioning_opts': fake.PROVISIONING_OPTIONS_INVALID_FPOLICY, 

7677 'qos_specs': None, 

7678 'extra_specs': None, 

7679 'cluster_credentials': False}, 

7680 {'provisioning_opts': fake.PROVISIONING_OPTIONS_WITH_FPOLICY, 

7681 'qos_specs': None, 

7682 'extra_specs': {'replication_type': 'dr'}, 

7683 'cluster_credentials': False} 

7684 ) 

7685 @ddt.unpack 

7686 def test_validate_provisioning_options_for_share_invalid_params( 

7687 self, provisioning_opts, qos_specs, extra_specs, 

7688 cluster_credentials): 

7689 self.library._have_cluster_creds = cluster_credentials 

7690 

7691 self.assertRaises(exception.NetAppException, 

7692 self.library.validate_provisioning_options_for_share, 

7693 provisioning_opts, extra_specs=extra_specs, 

7694 qos_specs=qos_specs) 

7695 

7696 def test__get_backend_fpolicy_policy_name(self): 

7697 result = self.library._get_backend_fpolicy_policy_name( 

7698 fake.SHARE_ID) 

7699 expected = 'fpolicy_policy_' + fake.SHARE_ID.replace('-', '_') 

7700 

7701 self.assertEqual(expected, result) 

7702 

7703 def test__get_backend_fpolicy_event_name(self): 

7704 result = self.library._get_backend_fpolicy_event_name( 

7705 fake.SHARE_ID, 'NFS') 

7706 expected = 'fpolicy_event_nfs_' + fake.SHARE_ID.replace('-', '_') 

7707 

7708 self.assertEqual(expected, result) 

7709 

7710 @ddt.data({}, 

7711 {'policy-name': fake.FPOLICY_POLICY_NAME, 

7712 'shares-to-include': [fake.SHARE_NAME]}) 

7713 def test__create_fpolicy_for_share(self, reusable_scope): 

7714 vserver_client = mock.Mock() 

7715 vserver_name = fake.VSERVER1 

7716 new_fake_share = copy.deepcopy(fake.SHARE) 

7717 new_fake_share['id'] = 'new_fake_id' 

7718 new_fake_share['share_proto'] = 'CIFS' 

7719 event_name = 'fpolicy_event_cifs_new_fake_id' 

7720 events = [event_name] 

7721 policy_name = 'fpolicy_policy_new_fake_id' 

7722 shares_to_include = [] 

7723 if reusable_scope: 

7724 shares_to_include = copy.deepcopy( 

7725 reusable_scope.get('shares-to-include')) 

7726 shares_to_include.append('share_new_fake_id') 

7727 

7728 mock_reusable_scope = self.mock_object( 

7729 self.library, '_find_reusable_fpolicy_scope', 

7730 mock.Mock(return_value=reusable_scope)) 

7731 mock_modify_policy = self.mock_object( 

7732 vserver_client, 'modify_fpolicy_scope') 

7733 mock_get_policies = self.mock_object( 

7734 vserver_client, 'get_fpolicy_policies_status', 

7735 mock.Mock(return_value=[])) 

7736 mock_create_event = self.mock_object( 

7737 vserver_client, 'create_fpolicy_event') 

7738 mock_enable_fpolicy = self.mock_object( 

7739 vserver_client, 'enable_fpolicy_policy') 

7740 mock_create_fpolicy_policy_with_scope = self.mock_object( 

7741 vserver_client, 'create_fpolicy_policy_with_scope') 

7742 

7743 self.library._create_fpolicy_for_share( 

7744 new_fake_share, vserver_name, vserver_client, 

7745 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7746 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7747 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7748 

7749 mock_reusable_scope.assert_called_once_with( 

7750 new_fake_share, vserver_client, 

7751 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7752 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7753 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7754 

7755 if reusable_scope: 

7756 mock_modify_policy.assert_called_once_with( 

7757 'share_new_fake_id', fake.FPOLICY_POLICY_NAME, 

7758 shares_to_include=shares_to_include) 

7759 mock_get_policies.assert_not_called() 

7760 mock_create_event.assert_not_called() 

7761 mock_create_fpolicy_policy_with_scope.assert_not_called() 

7762 mock_enable_fpolicy.assert_not_called() 

7763 else: 

7764 mock_modify_policy.assert_not_called() 

7765 

7766 mock_get_policies.assert_called_once() 

7767 mock_create_event.assert_called_once_with( 

7768 'share_new_fake_id', 

7769 event_name, new_fake_share['share_proto'].lower(), 

7770 fake.FPOLICY_FILE_OPERATIONS_LIST) 

7771 mock_create_fpolicy_policy_with_scope.assert_called_once_with( 

7772 policy_name, 'share_new_fake_id', events, 

7773 extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7774 extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE 

7775 ) 

7776 mock_enable_fpolicy.assert_called_once_with( 

7777 'share_new_fake_id', policy_name, 1) 

7778 

7779 def test__create_fpolicy_for_share_max_policies_error(self): 

7780 fake_client = mock.Mock() 

7781 vserver_name = fake.VSERVER1 

7782 mock_reusable_scope = self.mock_object( 

7783 self.library, '_find_reusable_fpolicy_scope', 

7784 mock.Mock(return_value=None)) 

7785 policies = [ 

7786 x for x in range(1, self.library.FPOLICY_MAX_VSERVER_POLICIES + 1)] 

7787 mock_get_policies = self.mock_object( 

7788 fake_client, 'get_fpolicy_policies_status', 

7789 mock.Mock(return_value=policies)) 

7790 

7791 self.assertRaises( 

7792 exception.NetAppException, 

7793 self.library._create_fpolicy_for_share, 

7794 fake.SHARE, vserver_name, fake_client, 

7795 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7796 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7797 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7798 

7799 mock_reusable_scope.assert_called_once_with( 

7800 fake.SHARE, fake_client, 

7801 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7802 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7803 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7804 mock_get_policies.assert_called_once() 

7805 

7806 def test__create_fpolicy_for_share_client_error(self): 

7807 fake_client = mock.Mock() 

7808 vserver_name = fake.VSERVER1 

7809 new_fake_share = copy.deepcopy(fake.SHARE) 

7810 new_fake_share['id'] = 'new_fake_id' 

7811 new_fake_share['share_proto'] = 'CIFS' 

7812 event_name = 'fpolicy_event_cifs_new_fake_id' 

7813 events = [event_name] 

7814 policy_name = 'fpolicy_policy_new_fake_id' 

7815 

7816 mock_reusable_scope = self.mock_object( 

7817 self.library, '_find_reusable_fpolicy_scope', 

7818 mock.Mock(return_value=None)) 

7819 mock_get_policies = self.mock_object( 

7820 fake_client, 'get_fpolicy_policies_status', 

7821 mock.Mock(return_value=[])) 

7822 mock_create_event = self.mock_object( 

7823 fake_client, 'create_fpolicy_event') 

7824 mock_create_fpolicy_policy_with_scope = self.mock_object( 

7825 fake_client, 'create_fpolicy_policy_with_scope', 

7826 mock.Mock(side_effect=self._mock_api_error())) 

7827 mock_delete_fpolicy = self.mock_object( 

7828 fake_client, 'delete_fpolicy_policy') 

7829 mock_delete_event = self.mock_object( 

7830 fake_client, 'delete_fpolicy_event') 

7831 

7832 self.assertRaises( 

7833 exception.NetAppException, 

7834 self.library._create_fpolicy_for_share, 

7835 new_fake_share, vserver_name, fake_client, 

7836 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7837 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7838 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7839 

7840 mock_reusable_scope.assert_called_once_with( 

7841 new_fake_share, fake_client, 

7842 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7843 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7844 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7845 mock_get_policies.assert_called_once() 

7846 mock_create_event.assert_called_once_with( 

7847 'share_new_fake_id', event_name, 

7848 new_fake_share['share_proto'].lower(), 

7849 fake.FPOLICY_FILE_OPERATIONS_LIST) 

7850 mock_create_fpolicy_policy_with_scope.assert_called_once_with( 

7851 policy_name, 'share_new_fake_id', events, 

7852 extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7853 extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE) 

7854 mock_delete_fpolicy.assert_called_once_with( 

7855 'share_new_fake_id', policy_name) 

7856 mock_delete_event.assert_called_once_with( 

7857 'share_new_fake_id', event_name) 

7858 

7859 def test__find_reusable_fpolicy_scope(self): 

7860 vserver_client = mock.Mock() 

7861 new_fake_share = copy.deepcopy(fake.SHARE) 

7862 new_fake_share['share_proto'] = 'CIFS' 

7863 reusable_scopes = [{ 

7864 'policy-name': fake.FPOLICY_POLICY_NAME, 

7865 'file-extensions-to-include': fake.FPOLICY_EXT_TO_INCLUDE_LIST, 

7866 'file-extensions-to-exclude': fake.FPOLICY_EXT_TO_EXCLUDE_LIST, 

7867 'shares-to-include': ['any_other_fake_share'], 

7868 }] 

7869 reusable_policies = [{ 

7870 'policy-name': fake.FPOLICY_POLICY_NAME, 

7871 'engine-name': fake.FPOLICY_ENGINE, 

7872 'events': [fake.FPOLICY_EVENT_NAME] 

7873 }] 

7874 reusable_events = [{ 

7875 'event-name': fake.FPOLICY_EVENT_NAME, 

7876 'protocol': new_fake_share['share_proto'].lower(), 

7877 'file-operations': fake.FPOLICY_FILE_OPERATIONS_LIST 

7878 }] 

7879 mock_get_scopes = self.mock_object( 

7880 vserver_client, 'get_fpolicy_scopes', 

7881 mock.Mock(return_value=reusable_scopes)) 

7882 mock_get_policies = self.mock_object( 

7883 vserver_client, 'get_fpolicy_policies', 

7884 mock.Mock(return_value=reusable_policies)) 

7885 mocke_get_events = self.mock_object( 

7886 vserver_client, 'get_fpolicy_events', 

7887 mock.Mock(return_value=reusable_events) 

7888 ) 

7889 

7890 result = self.library._find_reusable_fpolicy_scope( 

7891 new_fake_share, vserver_client, 

7892 fpolicy_extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7893 fpolicy_extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7894 fpolicy_file_operations=fake.FPOLICY_FILE_OPERATIONS) 

7895 

7896 self.assertEqual(reusable_scopes[0], result) 

7897 

7898 mock_get_scopes.assert_called_once_with( 

7899 share_name=fake.SHARE_NAME, 

7900 extensions_to_include=fake.FPOLICY_EXT_TO_INCLUDE, 

7901 extensions_to_exclude=fake.FPOLICY_EXT_TO_EXCLUDE, 

7902 shares_to_include=None) 

7903 mock_get_policies.assert_called_once_with( 

7904 share_name=fake.SHARE_NAME, 

7905 policy_name=fake.FPOLICY_POLICY_NAME) 

7906 mocke_get_events.assert_called_once_with( 

7907 share_name=fake.SHARE_NAME, 

7908 event_name=fake.FPOLICY_EVENT_NAME) 

7909 

7910 @ddt.data(False, True) 

7911 def test__delete_fpolicy_for_share(self, last_share): 

7912 fake_vserver_client = mock.Mock() 

7913 fake_vserver_name = fake.VSERVER1 

7914 fake_share = copy.deepcopy(fake.SHARE) 

7915 share_name = self.library._get_backend_share_name(fake.SHARE_ID) 

7916 existing_shares = [share_name] 

7917 if not last_share: 

7918 existing_shares.append('any_other_share') 

7919 scopes = [{ 

7920 'policy-name': fake.FPOLICY_POLICY_NAME, 

7921 'file-extensions-to-include': fake.FPOLICY_EXT_TO_INCLUDE_LIST, 

7922 'file-extensions-to-exclude': fake.FPOLICY_EXT_TO_EXCLUDE_LIST, 

7923 'shares-to-include': existing_shares, 

7924 }] 

7925 shares_to_include = copy.copy(scopes[0].get('shares-to-include')) 

7926 shares_to_include.remove(share_name) 

7927 policies = [{ 

7928 'policy-name': fake.FPOLICY_POLICY_NAME, 

7929 'engine-name': fake.FPOLICY_ENGINE, 

7930 'events': [fake.FPOLICY_EVENT_NAME] 

7931 }] 

7932 

7933 mock_get_scopes = self.mock_object( 

7934 fake_vserver_client, 'get_fpolicy_scopes', 

7935 mock.Mock(return_value=scopes)) 

7936 mock_modify_scope = self.mock_object( 

7937 fake_vserver_client, 'modify_fpolicy_scope') 

7938 

7939 mock_disable_policy = self.mock_object( 

7940 fake_vserver_client, 'disable_fpolicy_policy') 

7941 mock_get_policies = self.mock_object( 

7942 fake_vserver_client, 'get_fpolicy_policies', 

7943 mock.Mock(return_value=policies)) 

7944 mock_delete_scope = self.mock_object( 

7945 fake_vserver_client, 'delete_fpolicy_scope') 

7946 mock_delete_policy = self.mock_object( 

7947 fake_vserver_client, 'delete_fpolicy_policy') 

7948 mock_delete_event = self.mock_object( 

7949 fake_vserver_client, 'delete_fpolicy_event') 

7950 

7951 self.library._delete_fpolicy_for_share(fake_share, fake_vserver_name, 

7952 fake_vserver_client) 

7953 

7954 mock_get_scopes.assert_called_once_with( 

7955 share_name=fake.SHARE_NAME, 

7956 shares_to_include=[share_name]) 

7957 if shares_to_include: 

7958 mock_modify_scope.assert_called_once_with( 

7959 fake.SHARE_NAME, 

7960 fake.FPOLICY_POLICY_NAME, shares_to_include=shares_to_include) 

7961 else: 

7962 mock_disable_policy.assert_called_once_with( 

7963 fake.FPOLICY_POLICY_NAME) 

7964 mock_get_policies.assert_called_once_with( 

7965 share_name=fake.SHARE_NAME, 

7966 policy_name=fake.FPOLICY_POLICY_NAME) 

7967 mock_delete_scope.assert_called_once_with( 

7968 fake.FPOLICY_POLICY_NAME) 

7969 mock_delete_policy.assert_called_once_with( 

7970 fake.SHARE_NAME, 

7971 fake.FPOLICY_POLICY_NAME) 

7972 mock_delete_event.assert_called_once_with( 

7973 fake.FPOLICY_EVENT_NAME) 

7974 

7975 @ddt.data(True, False) 

7976 def test_initialize_flexgroup_pools(self, auto_provision): 

7977 self.library.configuration.netapp_enable_flexgroup = True 

7978 pool = None if auto_provision else [fake.FLEXGROUP_POOL_OPT_RAW] 

7979 mock_safe_get = self.mock_object( 

7980 self.library.configuration, 'safe_get', 

7981 mock.Mock(return_value=pool)) 

7982 mock_is_flex_support = self.mock_object( 

7983 self.library._client, 'is_flexgroup_supported', 

7984 mock.Mock(return_value=True)) 

7985 mock_parse = self.mock_object( 

7986 na_utils, 'parse_flexgroup_pool_config', 

7987 mock.Mock(return_value=fake.FLEXGROUP_POOL_OPT)) 

7988 aggr_set = set(fake.FLEXGROUP_POOL_AGGR) 

7989 

7990 self.library._initialize_flexgroup_pools(aggr_set) 

7991 

7992 mock_safe_get.assert_called_once_with('netapp_flexgroup_pools') 

7993 mock_is_flex_support.assert_called_once_with() 

7994 if auto_provision: 

7995 self.assertEqual(self.library._flexgroup_pools, 

7996 {na_utils.FLEXGROUP_DEFAULT_POOL_NAME: sorted( 

7997 aggr_set)}) 

7998 self.assertTrue(self.library._is_flexgroup_auto) 

7999 mock_parse.assert_not_called() 

8000 else: 

8001 self.assertEqual(self.library._flexgroup_pools, 

8002 fake.FLEXGROUP_POOL_OPT) 

8003 self.assertFalse(self.library._is_flexgroup_auto) 

8004 mock_parse.assert_called_once_with( 

8005 [fake.FLEXGROUP_POOL_OPT_RAW], 

8006 cluster_aggr_set=set(fake.FLEXGROUP_POOL_AGGR), check=True) 

8007 

8008 def test_initialize_flexgroup_pools_no_opt(self): 

8009 self.library.configuration.netapp_enable_flexgroup = False 

8010 self.mock_object(self.library.configuration, 

8011 'safe_get', 

8012 mock.Mock(return_value=None)) 

8013 

8014 self.library._initialize_flexgroup_pools(set(fake.FLEXGROUP_POOL_AGGR)) 

8015 

8016 self.assertEqual(self.library._flexgroup_pools, {}) 

8017 

8018 def test_initialize_flexgroup_pools_raise_version(self): 

8019 self.library.configuration.netapp_enable_flexgroup = True 

8020 self.mock_object(self.library.configuration, 

8021 'safe_get', 

8022 mock.Mock(return_value=[fake.FLEXGROUP_POOL_OPT_RAW])) 

8023 self.mock_object(self.library._client, 

8024 'is_flexgroup_supported', 

8025 mock.Mock(return_value=False)) 

8026 

8027 self.assertRaises(exception.NetAppException, 

8028 self.library._initialize_flexgroup_pools, 

8029 set(fake.FLEXGROUP_POOL_AGGR)) 

8030 

8031 def test_initialize_flexgroup_pools_raise_no_enable_with_pool(self): 

8032 self.library.configuration.netapp_enable_flexgroup = False 

8033 self.mock_object(self.library.configuration, 

8034 'safe_get', 

8035 mock.Mock(return_value=[fake.FLEXGROUP_POOL_OPT_RAW])) 

8036 

8037 self.assertRaises(exception.NetAppException, 

8038 self.library._initialize_flexgroup_pools, 

8039 set(fake.FLEXGROUP_POOL_AGGR)) 

8040 

8041 @ddt.data(True, False) 

8042 def test_get_flexgroup_pool_name(self, auto_provisioned): 

8043 

8044 self.library._is_flexgroup_auto = auto_provisioned 

8045 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

8046 

8047 result = self.library._get_flexgroup_pool_name( 

8048 fake.FLEXGROUP_POOL_AGGR) 

8049 

8050 if auto_provisioned: 

8051 self.assertEqual(na_utils.FLEXGROUP_DEFAULT_POOL_NAME, result) 

8052 else: 

8053 self.assertEqual(fake.FLEXGROUP_POOL_NAME, result) 

8054 

8055 def test_get_flexgroup_pool_name_not_found(self): 

8056 

8057 self.library._is_flexgroup_auto = False 

8058 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

8059 

8060 result = self.library._get_flexgroup_pool_name([]) 

8061 

8062 self.assertEqual('', result) 

8063 

8064 def test_is_flexgroup_pool(self): 

8065 

8066 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

8067 

8068 result = self.library._is_flexgroup_pool(fake.FLEXGROUP_POOL_NAME) 

8069 

8070 self.assertTrue(result) 

8071 

8072 @ddt.data({'pool_name': fake.FLEXGROUP_POOL_NAME, 

8073 'aggr_list': fake.FLEXGROUP_POOL_AGGR}, 

8074 {'pool_name': '', 

8075 'aggr_list': []}) 

8076 @ddt.unpack 

8077 def test_get_flexgroup_aggregate_list(self, pool_name, aggr_list): 

8078 

8079 self.library._flexgroup_pools = fake.FLEXGROUP_POOL_OPT 

8080 

8081 result = self.library._get_flexgroup_aggregate_list(pool_name) 

8082 

8083 self.assertEqual(aggr_list, result) 

8084 

8085 def test_is_flexgroup_share(self): 

8086 vserver_client = mock.Mock() 

8087 vserver_client.is_flexgroup_volume.return_value = True 

8088 

8089 result = self.library._is_flexgroup_share(vserver_client, 

8090 fake.SHARE_NAME) 

8091 

8092 vserver_client.is_flexgroup_volume.assert_called_once_with( 

8093 fake.SHARE_NAME) 

8094 self.assertTrue(result) 

8095 

8096 def test_is_flexgroup_share_raise(self): 

8097 vserver_client = mock.Mock() 

8098 vserver_client.is_flexgroup_volume.side_effect = ( 

8099 exception.NetAppException) 

8100 

8101 self.assertRaises(exception.ShareNotFound, 

8102 self.library._is_flexgroup_share, 

8103 vserver_client, fake.SHARE_NAME) 

8104 

8105 vserver_client.is_flexgroup_volume.assert_called_once_with( 

8106 fake.SHARE_NAME) 

8107 

8108 @ddt.data( 

8109 {'enabled': True, 'flexgroup_only': False, 'is_flexvol': True}, 

8110 {'enabled': False, 'flexgroup_only': False, 'is_flexvol': True}, 

8111 {'enabled': True, 'flexgroup_only': True, 'is_flexvol': False}, 

8112 {'enabled': False, 'flexgroup_only': True, 'is_flexvol': True}) 

8113 @ddt.unpack 

8114 def test_is_flexvol_pool_configured(self, enabled, flexgroup_only, 

8115 is_flexvol): 

8116 

8117 self.library.configuration.netapp_enable_flexgroup = enabled 

8118 self.library.configuration.netapp_flexgroup_pool_only = flexgroup_only 

8119 

8120 result = self.library.is_flexvol_pool_configured() 

8121 

8122 self.assertEqual(is_flexvol, result) 

8123 

8124 def test_get_minimum_flexgroup_size(self): 

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

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

8127 

8128 result = self.library._get_minimum_flexgroup_size(fake.POOL_NAME) 

8129 

8130 expected = (len(fake.AGGREGATES) * 

8131 self.library.FLEXGROUP_MIN_SIZE_PER_AGGR) 

8132 self.assertEqual(expected, result) 

8133 self.library._get_flexgroup_aggregate_list.assert_called_once_with( 

8134 fake.POOL_NAME) 

8135 

8136 def test_is_flexgroup_destination_host_not_enabled(self): 

8137 mock_config = mock.Mock() 

8138 dm_session = mock.Mock() 

8139 mock_get_backend = self.mock_object( 

8140 dm_session, 'get_backend_name_and_config_obj', 

8141 mock.Mock(return_value=('fake', mock_config))) 

8142 mock_safe_get = self.mock_object( 

8143 mock_config, 'safe_get', mock.Mock(return_value=False)) 

8144 

8145 result = self.library.is_flexgroup_destination_host(fake.HOST_NAME, 

8146 dm_session) 

8147 

8148 self.assertFalse(result) 

8149 mock_get_backend.assert_called_once_with(fake.HOST_NAME) 

8150 mock_safe_get.assert_called_once_with('netapp_enable_flexgroup') 

8151 

8152 @ddt.data(None, [{'fg1': fake.AGGREGATE}]) 

8153 def test_is_flexgroup_destination_host_false(self, flexgroup_pools): 

8154 mock_config = mock.Mock() 

8155 dm_session = mock.Mock() 

8156 mock_get_backend = self.mock_object( 

8157 dm_session, 'get_backend_name_and_config_obj', 

8158 mock.Mock(return_value=('fake', mock_config))) 

8159 mock_safe_get = self.mock_object( 

8160 mock_config, 'safe_get', 

8161 mock.Mock(side_effect=[True, flexgroup_pools])) 

8162 mock_extract = self.mock_object( 

8163 share_utils, 'extract_host', 

8164 mock.Mock(return_value=fake.POOL_NAME)) 

8165 mock_parse = self.mock_object( 

8166 na_utils, 'parse_flexgroup_pool_config', 

8167 mock.Mock(return_value={})) 

8168 

8169 result = self.library.is_flexgroup_destination_host(fake.HOST_NAME, 

8170 dm_session) 

8171 

8172 self.assertFalse(result) 

8173 mock_get_backend.assert_called_once_with(fake.HOST_NAME) 

8174 mock_safe_get.assert_has_calls([ 

8175 mock.call('netapp_enable_flexgroup'), 

8176 mock.call('netapp_flexgroup_pools'), 

8177 ]) 

8178 mock_extract.assert_called_once_with(fake.HOST_NAME, level='pool') 

8179 if flexgroup_pools: 

8180 mock_parse.assert_called_once_with(flexgroup_pools) 

8181 else: 

8182 mock_parse.assert_not_called() 

8183 

8184 def test_is_flexgroup_destination_host_true(self): 

8185 flexgroup_pools = [{fake.POOL_NAME: fake.AGGREGATE}] 

8186 mock_config = mock.Mock() 

8187 dm_session = mock.Mock() 

8188 mock_get_backend = self.mock_object( 

8189 dm_session, 'get_backend_name_and_config_obj', 

8190 mock.Mock(return_value=('fake', mock_config))) 

8191 mock_safe_get = self.mock_object( 

8192 mock_config, 'safe_get', 

8193 mock.Mock(side_effect=[True, flexgroup_pools])) 

8194 mock_extract = self.mock_object( 

8195 share_utils, 'extract_host', 

8196 mock.Mock(return_value=fake.POOL_NAME)) 

8197 mock_parse = self.mock_object( 

8198 na_utils, 'parse_flexgroup_pool_config', 

8199 mock.Mock(return_value=flexgroup_pools[0])) 

8200 

8201 result = self.library.is_flexgroup_destination_host(fake.HOST_NAME, 

8202 dm_session) 

8203 

8204 self.assertTrue(result) 

8205 mock_get_backend.assert_called_once_with(fake.HOST_NAME) 

8206 mock_safe_get.assert_has_calls([ 

8207 mock.call('netapp_enable_flexgroup'), 

8208 mock.call('netapp_flexgroup_pools'), 

8209 ]) 

8210 mock_extract.assert_called_once_with(fake.HOST_NAME, level='pool') 

8211 mock_parse.assert_called_once_with(flexgroup_pools) 

8212 

8213 def test_create_backup_first_backup(self): 

8214 vserver_client = mock.Mock() 

8215 mock_dest_client = mock.Mock() 

8216 self.mock_object(self.library, 

8217 '_get_vserver', 

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

8219 vserver_client))) 

8220 self._backup_mock_common_method(mock_dest_client) 

8221 self.mock_object(vserver_client, 

8222 'get_snapmirror_destinations', 

8223 mock.Mock(return_value=[])) 

8224 

8225 vserver_peer_info = [{'vserver': fake.VSERVER1, 

8226 'peer-vserver': fake.VSERVER2}] 

8227 self.mock_object(vserver_client, 

8228 'get_vserver_peers', 

8229 mock.Mock(return_value=vserver_peer_info)) 

8230 snap_list = ["snap1", "snap2", "snap3"] 

8231 self.mock_object(mock_dest_client, 

8232 'list_volume_snapshots', 

8233 mock.Mock(return_value=snap_list)) 

8234 

8235 share_instance = fake.SHARE_INSTANCE 

8236 backup = fake.SHARE_BACKUP 

8237 self.library.create_backup(self.context, share_instance, backup) 

8238 (mock_dest_client.create_snapmirror_policy. 

8239 assert_called_once_with(mock.ANY, 

8240 policy_type='vault', 

8241 discard_network_info=False, 

8242 snapmirror_label=mock.ANY, 

8243 keep=mock.ANY)) 

8244 

8245 (mock_dest_client.create_snapmirror_vol. 

8246 assert_called_once_with(mock.ANY, 

8247 mock.ANY, 

8248 mock.ANY, 

8249 mock.ANY, 

8250 'extended_data_protection', 

8251 policy=mock.ANY 

8252 )) 

8253 dm_session = data_motion.DataMotionSession() 

8254 (dm_session.initialize_and_wait_snapmirror_vol. 

8255 assert_called_once_with(mock.ANY, 

8256 mock.ANY, 

8257 mock.ANY, 

8258 mock.ANY, 

8259 mock.ANY, 

8260 timeout=mock.ANY, 

8261 )) 

8262 (mock_dest_client.update_snapmirror_vol. 

8263 assert_called_once_with(mock.ANY, 

8264 mock.ANY, 

8265 mock.ANY, 

8266 mock.ANY, 

8267 )) 

8268 

8269 def test_create_backup_second_backup(self): 

8270 vserver_client = mock.Mock() 

8271 mock_dest_client = mock.Mock() 

8272 self._backup_mock_common_method(mock_dest_client) 

8273 self.mock_object(self.library, 

8274 '_get_vserver', 

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

8276 vserver_client))) 

8277 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

8278 self.mock_object(vserver_client, 

8279 'get_snapmirror_destinations', 

8280 mock.Mock(return_value=snapmirror_info)) 

8281 

8282 share_instance = fake.SHARE_INSTANCE 

8283 backup = fake.SHARE_BACKUP 

8284 self.library.create_backup(self.context, share_instance, backup) 

8285 mock_dest_client.create_snapmirror_policy.assert_not_called() 

8286 mock_dest_client.create_snapmirror_vol.assert_not_called() 

8287 (data_motion.DataMotionSession(). 

8288 initialize_and_wait_snapmirror_vol.assert_not_called()) 

8289 (mock_dest_client.update_snapmirror_vol. 

8290 assert_called_once_with(mock.ANY, 

8291 mock.ANY, 

8292 mock.ANY, 

8293 mock.ANY, 

8294 )) 

8295 

8296 def test_create_backup_continue(self): 

8297 vserver_client = mock.Mock() 

8298 mock_dest_client = mock.Mock() 

8299 self._backup_mock_common_method(mock_dest_client) 

8300 self.mock_object(self.library, 

8301 '_get_vserver', 

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

8303 vserver_client))) 

8304 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

8305 self.mock_object(mock_dest_client, 

8306 'get_snapmirrors', 

8307 mock.Mock(return_value=snapmirror_info)) 

8308 snap_list = ["snap1", "snap2", "snap3"] 

8309 self.mock_object(self.library, 

8310 '_get_des_volume_backup_snapshots', 

8311 mock.Mock(return_value=snap_list)) 

8312 share_instance = fake.SHARE_INSTANCE 

8313 backup = fake.SHARE_BACKUP 

8314 self.library.create_backup_continue(self.context, share_instance, 

8315 backup) 

8316 

8317 def test_restore_backup(self): 

8318 vserver_client = mock.Mock() 

8319 mock_dest_client = mock.Mock() 

8320 self._backup_mock_common_method(mock_dest_client) 

8321 self.mock_object(self.library, 

8322 '_get_vserver', 

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

8324 vserver_client))) 

8325 share_instance = fake.SHARE_INSTANCE 

8326 backup = fake.SHARE_BACKUP 

8327 self.library.restore_backup(self.context, backup, share_instance) 

8328 vserver_client.snapmirror_restore_vol.assert_called_once_with( 

8329 source_path=mock.ANY, 

8330 dest_path=mock.ANY, 

8331 source_snapshot=mock.ANY, 

8332 des_cluster=mock.ANY, 

8333 ) 

8334 

8335 def test_restore_backup_continue(self): 

8336 vserver_client = mock.Mock() 

8337 self.mock_object(self.library, 

8338 '_get_vserver', 

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

8340 vserver_client))) 

8341 self.mock_object(vserver_client, 

8342 'get_snapmirrors', 

8343 mock.Mock(return_value=[])) 

8344 snap_list = ["restored_snap1", "snap2", "snap3"] 

8345 self.mock_object(vserver_client, 

8346 'list_volume_snapshots', 

8347 mock.Mock(return_value=snap_list)) 

8348 self.mock_object(self.library, 

8349 '_get_backup_snapshot_name', 

8350 mock.Mock(return_value="restored_snap1")) 

8351 share_instance = fake.SHARE_INSTANCE 

8352 backup = fake.SHARE_BACKUP 

8353 self.library.restore_backup_continue(self.context, backup, 

8354 share_instance) 

8355 

8356 def test_delete_backup(self): 

8357 vserver_client = mock.Mock() 

8358 mock_dest_client = mock.Mock() 

8359 self._backup_mock_common_method(mock_dest_client) 

8360 self.mock_object(self.library, 

8361 '_get_vserver', 

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

8363 vserver_client))) 

8364 self.mock_object(mock_dest_client, 

8365 'get_snapmirrors', 

8366 mock.Mock(return_value=[])) 

8367 snap_list = ["snap1", "snap2", "snap3"] 

8368 self.mock_object(self.library, 

8369 '_get_des_volume_backup_snapshots', 

8370 mock.Mock(return_value=snap_list)) 

8371 self.mock_object( 

8372 self.library, '_is_snapshot_deleted', 

8373 mock.Mock(return_value=True)) 

8374 share_instance = fake.SHARE_INSTANCE 

8375 backup = fake.SHARE_BACKUP 

8376 self.library.delete_backup(self.context, share_instance, backup) 

8377 

8378 def test_delete_backup_with_resource_cleanup(self): 

8379 vserver_client = mock.Mock() 

8380 mock_dest_client = mock.Mock() 

8381 self._backup_mock_common_method(mock_dest_client) 

8382 self.mock_object(self.library, 

8383 '_get_vserver', 

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

8385 vserver_client))) 

8386 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

8387 self.mock_object(mock_dest_client, 

8388 'get_snapmirrors', 

8389 mock.Mock(return_value=snapmirror_info)) 

8390 snap_list = ["snap1", "snap2", "snap3"] 

8391 self.mock_object(self.library, 

8392 '_get_des_volume_backup_snapshots', 

8393 mock.Mock(return_value=snap_list)) 

8394 self.mock_object( 

8395 self.library, '_is_snapshot_deleted', 

8396 mock.Mock(return_value=True)) 

8397 share_instance = fake.SHARE_INSTANCE 

8398 backup = fake.SHARE_BACKUP 

8399 self.library.delete_backup(self.context, share_instance, backup) 

8400 

8401 def test__get_backup_snapshot_name(self): 

8402 backup = fake.SHARE_BACKUP 

8403 actual_result = self.library._get_backup_snapshot_name(backup, 

8404 fake.SHARE_ID) 

8405 backup_id = backup.get('id', "") 

8406 expected_result = f"backup_{fake.SHARE_ID}_{backup_id}" 

8407 self.assertEqual(actual_result, expected_result) 

8408 

8409 def test__get_backend(self): 

8410 backup = fake.SHARE_BACKUP 

8411 self.mock_object(data_motion, 

8412 'get_backup_configuration', 

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

8414 

8415 actual_result = self.library._get_backend(backup) 

8416 self.assertEqual(actual_result, fake.BACKEND_NAME) 

8417 

8418 def test__get_des_volume_backup_snapshots(self): 

8419 mock_dest_client = mock.Mock() 

8420 share_id = fake.SHARE_ID 

8421 snap_list = [f"backup_{share_id}_snap1", 

8422 f"backup_{share_id}_snap2", "snap3"] 

8423 self.mock_object(mock_dest_client, 

8424 'list_volume_snapshots', 

8425 mock.Mock(return_value=snap_list)) 

8426 expected_snap_list = [f"backup_{share_id}_snap1", 

8427 f"backup_{share_id}_snap2"] 

8428 actual_result = self.library._get_des_volume_backup_snapshots( 

8429 mock_dest_client, 

8430 fake.FLEXVOL_NAME, 

8431 share_id) 

8432 self.assertEqual(expected_snap_list, actual_result) 

8433 

8434 def test__get_volume_for_backup(self): 

8435 mock_dest_client = mock.Mock() 

8436 mock_src_client = mock.Mock() 

8437 self.mock_object(data_motion, 

8438 'get_backup_configuration', 

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

8440 self.library._get_volume_for_backup(fake.SHARE_BACKUP, 

8441 fake.SHARE_INSTANCE, 

8442 mock_src_client, mock_dest_client) 

8443 

8444 def test__get_volume_for_backup_create_new_vol(self): 

8445 mock_dest_client = mock.Mock() 

8446 mock_src_client = mock.Mock() 

8447 _get_config() 

8448 backup_config = 'backup_config' 

8449 fake_config = configuration.Configuration(driver.share_opts, 

8450 config_group=backup_config) 

8451 CONF.set_override("netapp_backup_volume", "", 

8452 group=backup_config) 

8453 CONF.set_override("netapp_backup_vserver", "", 

8454 group=backup_config) 

8455 self.mock_object(data_motion, 

8456 'get_backup_configuration', 

8457 mock.Mock(return_value=fake_config)) 

8458 vol_attr = {'name': 'fake_vol', 'size': 12345} 

8459 self.mock_object(mock_src_client, 

8460 'get_volume', 

8461 mock.Mock(return_value=vol_attr)) 

8462 self.library._get_volume_for_backup(fake.SHARE_BACKUP, 

8463 fake.SHARE_INSTANCE, 

8464 mock_src_client, mock_dest_client) 

8465 

8466 def test__get_volume_for_backup_aggr_not_found_negative(self): 

8467 mock_dest_client = mock.Mock() 

8468 mock_src_client = mock.Mock() 

8469 _get_config() 

8470 backup_config = 'backup_config' 

8471 fake_config = configuration.Configuration(driver.share_opts, 

8472 config_group=backup_config) 

8473 CONF.set_override("netapp_backup_volume", "", 

8474 group=backup_config) 

8475 CONF.set_override("netapp_backup_vserver", "", 

8476 group=backup_config) 

8477 self.mock_object(data_motion, 

8478 'get_backup_configuration', 

8479 mock.Mock(return_value=fake_config)) 

8480 self.mock_object(self.mock_dm_session, 

8481 'get_most_available_aggr_of_vserver', 

8482 mock.Mock(return_value=None)) 

8483 self.assertRaises( 

8484 exception.NetAppException, 

8485 self.library._get_volume_for_backup, 

8486 fake.SHARE_BACKUP, 

8487 fake.SHARE_INSTANCE, 

8488 mock_src_client, 

8489 mock_dest_client, 

8490 ) 

8491 

8492 def test__get_vserver_for_backup(self): 

8493 mock_dest_client = mock.Mock() 

8494 self.mock_object(data_motion, 

8495 'get_backup_configuration', 

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

8497 

8498 mock_backend_config = na_fakes.create_configuration() 

8499 self.mock_object(data_motion, 

8500 'get_backend_configuration', 

8501 mock.Mock(return_value=mock_backend_config)) 

8502 self.mock_object(self.library, 

8503 '_get_api_client_for_backend', 

8504 mock.Mock(return_value=mock_dest_client)) 

8505 

8506 self.library._get_vserver_for_backup(fake.SHARE_INSTANCE, 

8507 fake.SHARE_BACKUP) 

8508 

8509 def test__get_destination_vserver_and_vol(self): 

8510 mock_dest_client = mock.Mock() 

8511 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

8512 source_path = f"{fake.VSERVER1}:{fake.FLEXVOL_NAME}" 

8513 self.mock_object(mock_dest_client, 

8514 'get_snapmirror_destinations', 

8515 mock.Mock(return_value=snapmirror_info)) 

8516 actual_result = self.library._get_destination_vserver_and_vol( 

8517 mock_dest_client, 

8518 source_path, validate_relation=True) 

8519 expected_result = (fake.VSERVER2, fake.FLEXVOL_NAME_1) 

8520 self.assertEqual(actual_result, expected_result) 

8521 

8522 def test__get_destination_vserver_and_vol_negative(self): 

8523 mock_dest_client = mock.Mock() 

8524 snapmirror_info = [{'source-vserver': fake.VSERVER1, 

8525 'source-volume': fake.FLEXVOL_NAME, 

8526 'destination-vserver': fake.VSERVER2, 

8527 'destination-volume': fake.FLEXVOL_NAME_1 

8528 }, 

8529 {'source-vserver': 'fake_vs_1', 

8530 'source-volume': 'fake_vol_1', 

8531 'destination-vserver': 'fake_vs_2', 

8532 'destination-volume': 'fake_vol_2' 

8533 } 

8534 ] 

8535 source_path = f"{fake.VSERVER1}:{fake.FLEXVOL_NAME}" 

8536 self.mock_object(mock_dest_client, 

8537 'get_snapmirror_destinations', 

8538 mock.Mock(return_value=snapmirror_info)) 

8539 self.assertRaises( 

8540 exception.NetAppException, 

8541 self.library._get_destination_vserver_and_vol, 

8542 mock_dest_client, 

8543 source_path, 

8544 validate_relation=True 

8545 ) 

8546 

8547 def test_verify_and_wait_for_snapshot_to_transfer(self): 

8548 vserver_client = mock.Mock() 

8549 self.mock_object(vserver_client, 

8550 'get_snapshot', 

8551 mock.Mock(return_value=fake.SNAPSHOT_NAME)) 

8552 result = self.library._verify_and_wait_for_snapshot_to_transfer( 

8553 vserver_client, 

8554 fake.FLEXVOL_NAME, 

8555 fake.SNAPSHOT_NAME, 

8556 ) 

8557 self.assertIsNone(result) 

8558 

8559 def test_verify_and_wait_for_snapshot_to_transfer_negative(self): 

8560 vserver_client = mock.Mock() 

8561 self.mock_object(vserver_client, 

8562 'get_snapshot', 

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

8564 self.assertRaises( 

8565 exception.NetAppException, 

8566 self.library._verify_and_wait_for_snapshot_to_transfer, 

8567 vserver_client, 

8568 fake.FLEXVOL_NAME, 

8569 fake.SNAPSHOT_NAME, 

8570 timeout=10, 

8571 ) 

8572 

8573 def test__resource_cleanup_for_backup(self): 

8574 src_vserver_client = mock.Mock() 

8575 des_vserver_client = mock.Mock() 

8576 share_instance = fake.SHARE_INSTANCE 

8577 backup = fake.SHARE_BACKUP 

8578 self.mock_object(data_motion, 

8579 'get_backup_configuration', 

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

8581 mock_backend_config = na_fakes.create_configuration() 

8582 self.mock_object(data_motion, 

8583 'get_backend_configuration', 

8584 mock.Mock(return_value=mock_backend_config)) 

8585 self.mock_object(self.library, 

8586 '_get_vserver', 

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

8588 src_vserver_client))) 

8589 self.mock_object(self.library, 

8590 '_get_api_client_for_backend', 

8591 mock.Mock(return_value=des_vserver_client)) 

8592 self.mock_object(self.library, 

8593 '_get_backend_share_name', 

8594 mock.Mock(return_value=fake.FLEXVOL_NAME)) 

8595 

8596 self.library._resource_cleanup_for_backup(backup, 

8597 share_instance, 

8598 fake.VSERVER2, 

8599 fake.FLEXVOL_NAME_1, 

8600 ) 

8601 (des_vserver_client.abort_snapmirror_vol. 

8602 assert_called_once_with(fake.VSERVER1, 

8603 fake.FLEXVOL_NAME, 

8604 fake.VSERVER2, 

8605 fake.FLEXVOL_NAME_1, 

8606 clear_checkpoint=False 

8607 )) 

8608 (des_vserver_client.delete_snapmirror_vol. 

8609 assert_called_once_with(fake.VSERVER1, 

8610 fake.FLEXVOL_NAME, 

8611 fake.VSERVER2, 

8612 fake.FLEXVOL_NAME_1, 

8613 )) 

8614 db_session = data_motion.DataMotionSession() 

8615 (db_session.wait_for_snapmirror_release_vol. 

8616 assert_called_once_with(fake.VSERVER1, 

8617 fake.VSERVER2, 

8618 fake.FLEXVOL_NAME, 

8619 fake.FLEXVOL_NAME_1, 

8620 False, src_vserver_client, 

8621 timeout=mock.ANY 

8622 )) 

8623 

8624 def test__resource_cleanup_for_backup_with_exception(self): 

8625 mock_src_vserver_client = mock.Mock() 

8626 mock_des_vserver_client = mock.Mock() 

8627 self.mock_object(self.library, 

8628 '_get_vserver', 

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

8630 mock_src_vserver_client))) 

8631 self._backup_mock_common_method(mock_des_vserver_client) 

8632 self.mock_object(mock_des_vserver_client, 

8633 'abort_snapmirror_vol', 

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

8635 self.mock_object(mock_des_vserver_client, 

8636 'delete_snapmirror_vol', 

8637 mock.Mock(side_effect=netapp_api.NaApiError( 

8638 code=netapp_api.EOBJECTNOTFOUND))) 

8639 self.mock_object(mock_des_vserver_client, 

8640 'delete_snapmirror_policy', 

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

8642 self.mock_object(mock_src_vserver_client, 

8643 'delete_vserver_peer', 

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

8645 self.library._resource_cleanup_for_backup(fake.SHARE_BACKUP, 

8646 fake.SHARE_INSTANCE, 

8647 fake.VSERVER2, 

8648 fake.FLEXVOL_NAME_1, 

8649 ) 

8650 

8651 def test__resource_cleanup_for_backup_vserver_volume_none(self): 

8652 mock_src_vserver_client = mock.Mock() 

8653 mock_des_vserver_client = mock.Mock() 

8654 self.mock_object(self.library, 

8655 '_get_vserver', 

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

8657 mock_src_vserver_client))) 

8658 self.mock_object(self.library, 

8659 '_delete_backup_vserver', 

8660 mock.Mock(return_value=None)) 

8661 

8662 self.mock_object(mock_des_vserver_client, 

8663 'delete_volume', 

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

8665 

8666 self._backup_mock_common_method(mock_des_vserver_client) 

8667 backup_config = 'backup_config' 

8668 CONF.set_override("netapp_backup_volume", "", 

8669 group=backup_config) 

8670 CONF.set_override("netapp_backup_vserver", "", 

8671 group=backup_config) 

8672 self.library._resource_cleanup_for_backup( 

8673 fake.SHARE_BACKUP, 

8674 fake.SHARE_INSTANCE, 

8675 fake.VSERVER2, 

8676 fake.FLEXVOL_NAME_1, 

8677 share_server=fake.SHARE_SERVER, 

8678 ) 

8679 

8680 def test_create_backup_with_backup_type_none_negative(self): 

8681 vserver_client = mock.Mock() 

8682 self.mock_object(self.library, 

8683 '_get_vserver', 

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

8685 vserver_client))) 

8686 backup = {'id': '242ff47e-518d-4b07-b3c3-0a51e6744149', 

8687 'backup_options': {'backend': 'fake_ontap', 

8688 'backup_type': None 

8689 }, 

8690 } 

8691 self.assertRaises( 

8692 exception.BackupException, 

8693 self.library.create_backup, 

8694 self.context, 

8695 fake.SHARE_INSTANCE, 

8696 backup, 

8697 ) 

8698 

8699 def test_create_backup_with_non_netapp_backend_negative(self): 

8700 self.mock_object(data_motion, 

8701 'get_backup_configuration', 

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

8703 self.mock_object(self.library, 

8704 '_get_vserver', 

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

8706 mock.Mock()))) 

8707 fake_config = configuration.Configuration( 

8708 driver.share_opts, config_group='backup_config') 

8709 CONF.set_override("netapp_storage_family", None, 

8710 group='backup_config') 

8711 self.mock_object(data_motion, 

8712 'get_backend_configuration', 

8713 mock.Mock(return_value=fake_config)) 

8714 self.assertRaises( 

8715 exception.BackupException, 

8716 self.library.create_backup, 

8717 self.context, 

8718 fake.SHARE_INSTANCE, 

8719 fake.SHARE_BACKUP, 

8720 ) 

8721 

8722 def test_create_backup_when_enabled_backup_types_none_negative(self): 

8723 vserver_src_client = mock.Mock() 

8724 vserver_dest_client = mock.Mock() 

8725 self.mock_object(self.library, 

8726 '_get_vserver', 

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

8728 vserver_src_client))) 

8729 self._backup_mock_common_method(vserver_dest_client) 

8730 fake_config = configuration.Configuration(driver.share_opts, 

8731 config_group='backup_config') 

8732 CONF.set_override("netapp_enabled_backup_types", None, 

8733 group='backup_config') 

8734 self.mock_object(data_motion, 

8735 'get_backend_configuration', 

8736 mock.Mock(return_value=fake_config)) 

8737 self.assertRaises( 

8738 exception.BackupException, 

8739 self.library.create_backup, 

8740 self.context, 

8741 fake.SHARE_INSTANCE, 

8742 fake.SHARE_BACKUP, 

8743 ) 

8744 

8745 def test_create_backup_source_has_2_more_relationships_negative(self): 

8746 vserver_client = mock.Mock() 

8747 mock_dest_client = mock.Mock() 

8748 self._backup_mock_common_method(mock_dest_client) 

8749 self.mock_object(self.library, 

8750 '_get_vserver', 

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

8752 vserver_client))) 

8753 snapmirror_info = [{'source-vserver': fake.VSERVER1, 

8754 'source-volume': fake.FLEXVOL_NAME, 

8755 'destination-vserver': fake.VSERVER2, 

8756 'destination-volume': fake.FLEXVOL_NAME_1 

8757 }, 

8758 {'source-vserver': 'fake_vs_1', 

8759 'source-volume': 'fake_vol_1', 

8760 'destination-vserver': 'fake_vs_2', 

8761 'destination-volume': 'fake_vol_2' 

8762 } 

8763 ] 

8764 self.mock_object(vserver_client, 

8765 'get_snapmirror_destinations', 

8766 mock.Mock(return_value=snapmirror_info)) 

8767 self.assertRaises( 

8768 exception.NetAppException, 

8769 self.library.create_backup, 

8770 self.context, 

8771 fake.SHARE_INSTANCE, 

8772 fake.SHARE_BACKUP, 

8773 ) 

8774 

8775 def test_create_backup_bad_backup_config_negative(self): 

8776 mock_src_client = mock.Mock() 

8777 mock_des_client = mock.Mock() 

8778 self._backup_mock_common_method_for_negative(mock_src_client, 

8779 mock_des_client) 

8780 fake_config = configuration.Configuration( 

8781 driver.share_opts, config_group='backup_config') 

8782 CONF.set_override("netapp_backup_vserver", None, 

8783 group='backup_config') 

8784 self.mock_object(data_motion, 

8785 'get_backup_configuration', 

8786 mock.Mock(return_value=fake_config)) 

8787 self.assertRaises( 

8788 exception.BadConfigurationException, 

8789 self.library.create_backup, 

8790 self.context, 

8791 fake.SHARE_INSTANCE, 

8792 fake.SHARE_BACKUP, 

8793 ) 

8794 

8795 def test_create_backup_when_cluster_are_not_peered_negative(self): 

8796 mock_src_client = mock.Mock() 

8797 mock_des_client = mock.Mock() 

8798 self._backup_mock_common_method_for_negative(mock_src_client, 

8799 mock_des_client) 

8800 self.mock_object(self.client, 

8801 'get_cluster_peers', 

8802 mock.Mock(return_value=[])) 

8803 self.mock_object(mock_src_client, 

8804 'get_cluster_name', 

8805 mock.Mock(return_value='fake_src_cluster')) 

8806 

8807 self.assertRaises( 

8808 exception.NetAppException, 

8809 self.library.create_backup, 

8810 self.context, 

8811 fake.SHARE_INSTANCE, 

8812 fake.SHARE_BACKUP, 

8813 ) 

8814 

8815 def test_create_backup_when_des_vol_creation_fail_negative(self): 

8816 mock_src_client = mock.Mock() 

8817 mock_des_client = mock.Mock() 

8818 self._backup_mock_common_method_for_negative(mock_src_client, 

8819 mock_des_client) 

8820 self.mock_object(self.library, 

8821 '_get_volume_for_backup', 

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

8823 self.mock_object(self.library, 

8824 '_delete_backup_vserver', 

8825 mock.Mock(return_value=[])) 

8826 self.assertRaises( 

8827 exception.NetAppException, 

8828 self.library.create_backup, 

8829 self.context, 

8830 fake.SHARE_INSTANCE, 

8831 fake.SHARE_BACKUP, 

8832 ) 

8833 

8834 def test_create_backup_when_vserver_not_peered(self): 

8835 mock_src_client = mock.Mock() 

8836 mock_des_client = mock.Mock() 

8837 mock_cluster_client = mock.Mock() 

8838 self._backup_mock_common_method_for_negative(mock_src_client, 

8839 mock_des_client) 

8840 self.mock_object(mock_cluster_client, 

8841 'get_cluster_name', 

8842 mock.Mock(return_value='fake_src_cluster')) 

8843 self.mock_object(mock_src_client, 

8844 'get_vserver_peers', 

8845 mock.Mock(return_value=[])) 

8846 share_instance = fake.SHARE_INSTANCE 

8847 backup = fake.SHARE_BACKUP 

8848 self.library.create_backup(self.context, share_instance, backup) 

8849 

8850 def test_create_backup_when_policy_creation_failed_negative(self): 

8851 mock_src_client = mock.Mock() 

8852 mock_des_client = mock.Mock() 

8853 self._backup_mock_common_method_for_negative(mock_src_client, 

8854 mock_des_client) 

8855 

8856 self.mock_object(mock_des_client, 

8857 'create_snapmirror_policy', 

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

8859 self.assertRaises( 

8860 netapp_api.NaApiError, 

8861 self.library.create_backup, 

8862 self.context, 

8863 fake.SHARE_INSTANCE, 

8864 fake.SHARE_BACKUP, 

8865 ) 

8866 

8867 def test_create_backup_when_duplicate_policy_created(self): 

8868 mock_src_client = mock.Mock() 

8869 mock_des_client = mock.Mock() 

8870 self._backup_mock_common_method_for_negative(mock_src_client, 

8871 mock_des_client) 

8872 msg = 'policy with this name already exists' 

8873 self.mock_object(mock_des_client, 

8874 'create_snapmirror_policy', 

8875 mock.Mock(side_effect=netapp_api.NaApiError( 

8876 message=msg))) 

8877 share_instance = fake.SHARE_INSTANCE 

8878 backup = fake.SHARE_BACKUP 

8879 self.library.create_backup(self.context, share_instance, backup) 

8880 

8881 def test_create_backup_when_snapmirror_creation_failed_negative(self): 

8882 mock_src_client = mock.Mock() 

8883 mock_des_client = mock.Mock() 

8884 self._backup_mock_common_method_for_negative(mock_src_client, 

8885 mock_des_client) 

8886 self.mock_object(mock_des_client, 

8887 'create_snapmirror_vol', 

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

8889 self.assertRaises( 

8890 exception.NetAppException, 

8891 self.library.create_backup, 

8892 self.context, 

8893 fake.SHARE_INSTANCE, 

8894 fake.SHARE_BACKUP, 

8895 ) 

8896 

8897 def test_create_backup_when_invalid_backup_type_negative(self): 

8898 mock_src_client = mock.Mock() 

8899 self.mock_object(self.library, 

8900 '_get_vserver', 

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

8902 mock_src_client))) 

8903 self.mock_object(self.mock_dm_session, 

8904 'get_backup_configuration', 

8905 mock.Mock( 

8906 side_effect=exception.BadConfigurationException, 

8907 )) 

8908 self.assertRaises( 

8909 exception.BadConfigurationException, 

8910 self.library.create_backup, 

8911 self.context, 

8912 fake.SHARE_INSTANCE, 

8913 fake.SHARE_BACKUP, 

8914 ) 

8915 

8916 def test_create_backup_when_invalid_backend_negative(self): 

8917 mock_src_client = mock.Mock() 

8918 self.mock_object(self.library, 

8919 '_get_vserver', 

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

8921 mock_src_client))) 

8922 self.mock_object(data_motion, 

8923 'get_backup_configuration', 

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

8925 

8926 self.mock_object(self.mock_dm_session, 

8927 'get_backend_configuration', 

8928 mock.Mock( 

8929 side_effect=exception.BadConfigurationException, 

8930 )) 

8931 self.assertRaises( 

8932 exception.BadConfigurationException, 

8933 self.library.create_backup, 

8934 self.context, 

8935 fake.SHARE_INSTANCE, 

8936 fake.SHARE_BACKUP, 

8937 ) 

8938 

8939 def test_create_backup_continue_with_status_inprogress(self): 

8940 vserver_client = mock.Mock() 

8941 mock_dest_client = mock.Mock() 

8942 self._backup_mock_common_method(mock_dest_client) 

8943 self.mock_object(self.library, 

8944 '_get_vserver', 

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

8946 vserver_client))) 

8947 snapmirror_info = [{'source-vserver': fake.VSERVER1, 

8948 'source-volume': fake.FLEXVOL_NAME, 

8949 'destination-vserver': fake.VSERVER2, 

8950 'destination-volume': fake.FLEXVOL_NAME_1, 

8951 'relationship-status': "inprogress", 

8952 'last-transfer-type': "update", 

8953 }] 

8954 self.mock_object(mock_dest_client, 

8955 'get_snapmirrors', 

8956 mock.Mock(return_value=snapmirror_info)) 

8957 snap_list = ["snap1", "snap2", "snap3"] 

8958 self.mock_object(self.library, 

8959 '_get_des_volume_backup_snapshots', 

8960 mock.Mock(return_value=snap_list)) 

8961 share_instance = fake.SHARE_INSTANCE 

8962 backup = fake.SHARE_BACKUP 

8963 self.library.create_backup_continue(self.context, share_instance, 

8964 backup) 

8965 

8966 def test_create_backup_continue_with_state_not_update(self): 

8967 vserver_client = mock.Mock() 

8968 mock_dest_client = mock.Mock() 

8969 self._backup_mock_common_method(mock_dest_client) 

8970 self.mock_object(self.library, 

8971 '_get_vserver', 

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

8973 vserver_client))) 

8974 snapmirror_info = [{'source-vserver': fake.VSERVER1, 

8975 'source-volume': fake.FLEXVOL_NAME, 

8976 'destination-vserver': fake.VSERVER2, 

8977 'destination-volume': fake.FLEXVOL_NAME_1, 

8978 'relationship-status': "idle", 

8979 'last-transfer-type': "initialize", 

8980 }] 

8981 self.mock_object(mock_dest_client, 

8982 'get_snapmirrors', 

8983 mock.Mock(return_value=snapmirror_info)) 

8984 snap_list = ["snap1", "snap2", "snap3"] 

8985 self.mock_object(self.library, 

8986 '_get_des_volume_backup_snapshots', 

8987 mock.Mock(return_value=snap_list)) 

8988 share_instance = fake.SHARE_INSTANCE 

8989 backup = fake.SHARE_BACKUP 

8990 self.library.create_backup_continue(self.context, share_instance, 

8991 backup) 

8992 

8993 def test_create_backup_continue_snapmirror_none(self): 

8994 vserver_client = mock.Mock() 

8995 mock_dest_client = mock.Mock() 

8996 self._backup_mock_common_method(mock_dest_client) 

8997 self.mock_object(self.library, 

8998 '_get_vserver', 

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

9000 vserver_client))) 

9001 self.mock_object(vserver_client, 

9002 'get_snapmirror_destinations', 

9003 mock.Mock(return_value=None)) 

9004 share_instance = fake.SHARE_INSTANCE 

9005 backup = fake.SHARE_BACKUP 

9006 self.library.create_backup_continue(self.context, share_instance, 

9007 backup) 

9008 

9009 def test_create_backup_continue_snapmirror_none_from_destination(self): 

9010 vserver_client = mock.Mock() 

9011 mock_dest_client = mock.Mock() 

9012 self._backup_mock_common_method(mock_dest_client) 

9013 self.mock_object(self.library, 

9014 '_get_vserver', 

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

9016 vserver_client))) 

9017 self.mock_object(mock_dest_client, 

9018 'get_snapmirrors', 

9019 mock.Mock(return_value=None)) 

9020 share_instance = fake.SHARE_INSTANCE 

9021 backup = fake.SHARE_BACKUP 

9022 self.library.create_backup_continue(self.context, share_instance, 

9023 backup) 

9024 

9025 def test_create_backup_continue_des_vserver_vol_none_negative(self): 

9026 vserver_client = mock.Mock() 

9027 mock_des_vserver = mock.Mock() 

9028 self._backup_mock_common_method(mock_des_vserver) 

9029 self.mock_object(self.library, 

9030 '_get_vserver', 

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

9032 vserver_client))) 

9033 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

9034 self.mock_object(vserver_client, 

9035 'get_snapmirror_destinations', 

9036 mock.Mock(return_value=snapmirror_info)) 

9037 self.mock_object(self.library, 

9038 '_get_destination_vserver_and_vol', 

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

9040 self.assertRaises( 

9041 exception.NetAppException, 

9042 self.library.create_backup_continue, 

9043 self.context, 

9044 fake.SHARE_INSTANCE, 

9045 fake.SHARE_BACKUP, 

9046 ) 

9047 

9048 def test_create_backup_continue_snapshot_left_from_old_relationship(self): 

9049 vserver_client = mock.Mock() 

9050 mock_dest_client = mock.Mock() 

9051 self._backup_mock_common_method(mock_dest_client) 

9052 self.mock_object(self.library, 

9053 '_get_vserver', 

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

9055 vserver_client))) 

9056 snapmirror_info = [fake.SNAP_MIRROR_INFO] 

9057 self.mock_object(mock_dest_client, 

9058 'get_snapmirrors', 

9059 mock.Mock(return_value=snapmirror_info)) 

9060 snap_list = ["snap1", "snap2"] 

9061 self.mock_object(self.library, 

9062 '_get_des_volume_backup_snapshots', 

9063 mock.Mock(return_value=snap_list)) 

9064 

9065 self.library._set_volume_has_backup_before(True) 

9066 share_instance = fake.SHARE_INSTANCE 

9067 backup = fake.SHARE_BACKUP 

9068 self.library.create_backup_continue(self.context, share_instance, 

9069 backup) 

9070 self.library._set_volume_has_backup_before(False) 

9071 

9072 def test_create_backup_continue_relationship_not_healthy_negative(self): 

9073 vserver_client = mock.Mock() 

9074 mock_dest_client = mock.Mock() 

9075 self._backup_mock_common_method(mock_dest_client) 

9076 self.mock_object(self.library, 

9077 '_get_vserver', 

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

9079 vserver_client))) 

9080 snapmirror_info = [ 

9081 { 

9082 'source-vserver': fake.VSERVER1, 

9083 'source-volume': fake.FLEXVOL_NAME, 

9084 'destination-vserver': fake.VSERVER2, 

9085 'destination-volume': fake.FLEXVOL_NAME_1, 

9086 'relationship-status': "idle", 

9087 'last-transfer-type': "update", 

9088 'is-healthy': "false", 

9089 } 

9090 ] 

9091 self.mock_object(mock_dest_client, 

9092 'get_snapmirrors', 

9093 mock.Mock(return_value=snapmirror_info)) 

9094 self.assertRaises( 

9095 exception.NetAppException, 

9096 self.library.create_backup_continue, 

9097 self.context, 

9098 fake.SHARE_INSTANCE, 

9099 fake.SHARE_BACKUP, 

9100 ) 

9101 

9102 def test_restore_backup_with_vserver_volume_none(self): 

9103 vserver_client = mock.Mock() 

9104 self.mock_object(self.library, 

9105 '_get_vserver', 

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

9107 vserver_client))) 

9108 self.mock_object(self.library, 

9109 '_get_destination_vserver_and_vol', 

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

9111 self.assertRaises( 

9112 exception.NetAppException, 

9113 self.library.restore_backup, 

9114 self.context, 

9115 fake.SHARE_INSTANCE, 

9116 fake.SHARE_BACKUP, 

9117 ) 

9118 

9119 def test_restore_backup_continue_with_rst_relationship(self): 

9120 vserver_client = mock.Mock() 

9121 self.mock_object(self.library, 

9122 '_get_vserver', 

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

9124 vserver_client))) 

9125 self.mock_object(vserver_client, 

9126 'get_snapmirrors', 

9127 mock.Mock(return_value=fake.SNAP_MIRROR_INFO)) 

9128 snap_list = ["restored_snap1", "snap2", "snap3"] 

9129 self.mock_object(self.library, 

9130 '_get_des_volume_backup_snapshots', 

9131 mock.Mock(return_value=snap_list)) 

9132 share_instance = fake.SHARE_INSTANCE 

9133 backup = fake.SHARE_BACKUP 

9134 self.library.restore_backup_continue(self.context, backup, 

9135 share_instance) 

9136 

9137 def test_restore_backup_continue_restore_failed_negative(self): 

9138 vserver_client = mock.Mock() 

9139 self.mock_object(self.library, 

9140 '_get_vserver', 

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

9142 vserver_client))) 

9143 self.mock_object(vserver_client, 

9144 'get_snapmirrors', 

9145 mock.Mock(return_value=[])) 

9146 snap_list = ["restored_snap1", "snap2", "snap3"] 

9147 self.mock_object(vserver_client, 

9148 'list_volume_snapshots', 

9149 mock.Mock(return_value=snap_list)) 

9150 self.mock_object(self.library, 

9151 '_get_backup_snapshot_name', 

9152 mock.Mock(return_value="restored_snap_test1")) 

9153 self.assertRaises( 

9154 exception.NetAppException, 

9155 self.library.restore_backup_continue, 

9156 self.context, 

9157 fake.SHARE_INSTANCE, 

9158 fake.SHARE_BACKUP, 

9159 ) 

9160 

9161 def test_delete_backup_vserver_vol_none_negative(self): 

9162 vserver_client = mock.Mock() 

9163 self.mock_object(self.library, 

9164 '_get_vserver', 

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

9166 vserver_client))) 

9167 self.mock_object(self.library, 

9168 '_get_destination_vserver_and_vol', 

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

9170 self.mock_object(self.library, 

9171 '_get_backend', 

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

9173 share_instance = fake.SHARE_INSTANCE 

9174 backup = fake.SHARE_BACKUP 

9175 self.library.delete_backup(self.context, backup, 

9176 share_instance) 

9177 

9178 def test_delete_backup_snapshot_not_found_negative(self): 

9179 vserver_client = mock.Mock() 

9180 mock_dest_client = mock.Mock() 

9181 self.mock_object(self.library, 

9182 '_get_vserver', 

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

9184 vserver_client))) 

9185 self.mock_object(self.library, 

9186 '_get_destination_vserver_and_vol', 

9187 mock.Mock(return_value=(fake.VSERVER2, 

9188 fake.FLEXVOL_NAME_1))) 

9189 self.mock_object(self.library, 

9190 '_get_backend', 

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

9192 self.mock_object(self.library, 

9193 '_get_des_volume_backup_snapshots', 

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

9195 self.mock_object(self.library, 

9196 '_get_api_client_for_backend', 

9197 mock.Mock(return_value=mock_dest_client)) 

9198 share_instance = fake.SHARE_INSTANCE 

9199 backup = fake.SHARE_BACKUP 

9200 self.library.delete_backup(self.context, backup, 

9201 share_instance) 

9202 

9203 def test_delete_backup_cleanup_resource(self): 

9204 vserver_client = mock.Mock() 

9205 mock_des_client = mock.Mock() 

9206 self._backup_mock_common_method(mock_des_client) 

9207 self.mock_object(self.library, 

9208 '_get_vserver', 

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

9210 vserver_client))) 

9211 self.mock_object(mock_des_client, 

9212 'get_snapmirrors', 

9213 mock.Mock(return_value=fake.SNAP_MIRROR_INFO)) 

9214 self.mock_object(self.library, 

9215 '_get_des_volume_backup_snapshots', 

9216 mock.Mock(return_value=['fake_snapshot'])) 

9217 share_instance = fake.SHARE_INSTANCE 

9218 backup = fake.SHARE_BACKUP 

9219 self.library.delete_backup(self.context, backup, 

9220 share_instance) 

9221 

9222 def test_delete_backup_snapshot_delete_fail_negative(self): 

9223 vserver_client = mock.Mock() 

9224 mock_des_client = mock.Mock() 

9225 self._backup_mock_common_method(mock_des_client) 

9226 self.mock_object(self.library, 

9227 '_get_vserver', 

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

9229 vserver_client))) 

9230 self.mock_object(mock_des_client, 

9231 'get_snapmirrors', 

9232 mock.Mock(return_value=fake.SNAP_MIRROR_INFO)) 

9233 self.mock_object(self.library, 

9234 '_get_des_volume_backup_snapshots', 

9235 mock.Mock(return_value=['fake_snapshot1', 

9236 'fake_snapshot2'])) 

9237 self.mock_object(mock_des_client, 

9238 'get_snapshot', 

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

9240 self.mock_object(self.library, 

9241 '_is_snapshot_deleted', 

9242 mock.Mock(return_value=False)) 

9243 self.assertRaises( 

9244 exception.NetAppException, 

9245 self.library.delete_backup, 

9246 self.context, 

9247 fake.SHARE_INSTANCE, 

9248 fake.SHARE_BACKUP, 

9249 ) 

9250 

9251 def test_delete_backup_snapshot_not_exist(self): 

9252 vserver_client = mock.Mock() 

9253 mock_des_client = mock.Mock() 

9254 self._backup_mock_common_method(mock_des_client) 

9255 self._backup_mock_common_method_for_negative(vserver_client, 

9256 mock_des_client) 

9257 self.mock_object(self.library, 

9258 '_get_des_volume_backup_snapshots', 

9259 mock.Mock(return_value=['fake_snapshot1', 

9260 'fake_snapshot2'])) 

9261 self.mock_object(self.library, 

9262 '_is_snapshot_deleted', 

9263 mock.Mock(return_value=True)) 

9264 msg = "entry doesn't exist" 

9265 self.mock_object(mock_des_client, 

9266 'delete_snapshot', 

9267 mock.Mock(side_effect=netapp_api.NaApiError( 

9268 message=msg))) 

9269 self.library.delete_backup(self.context, fake.SHARE_BACKUP, 

9270 fake.SHARE_INSTANCE) 

9271 

9272 def test__get_backup_progress_status(self): 

9273 mock_dest_client = mock.Mock() 

9274 vol_attr = {'name': 'fake_vol', 'size-used': '123454'} 

9275 self.mock_object(mock_dest_client, 

9276 'get_volume', 

9277 mock.Mock(return_value=vol_attr)) 

9278 snapmirror_info = {'source-vserver': fake.VSERVER1, 

9279 'source-volume': fake.FLEXVOL_NAME, 

9280 'destination-vserver': fake.VSERVER2, 

9281 'destination-volume': fake.FLEXVOL_NAME_1, 

9282 'relationship-status': "idle", 

9283 'last-transfer-size': '3456', 

9284 } 

9285 self.library._get_backup_progress_status(mock_dest_client, 

9286 [snapmirror_info]) 

9287 

9288 def _backup_mock_common_method(self, mock_dest_client): 

9289 self.mock_object(mock_dest_client, 

9290 'get_cluster_name', 

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

9292 self.mock_object(self.library, 

9293 '_get_backend_share_name', 

9294 mock.Mock(return_value=fake.SHARE_NAME)) 

9295 self.mock_object(self.library, 

9296 '_get_api_client_for_backend', 

9297 mock.Mock(return_value=mock_dest_client)) 

9298 self.mock_object(data_motion, 

9299 'get_backend_configuration', 

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

9301 self.mock_object(data_motion, 

9302 'get_backup_configuration', 

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

9304 

9305 self.mock_object(self.library, 

9306 '_get_destination_vserver_and_vol', 

9307 mock.Mock(return_value=(fake.VSERVER2, 

9308 fake.FLEXVOL_NAME))) 

9309 self.mock_object(self.library, 

9310 '_get_backend', 

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

9312 

9313 def _backup_mock_common_method_for_negative(self, 

9314 mock_src_client, 

9315 mock_des_client): 

9316 self.mock_object(self.library, 

9317 '_get_vserver', 

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

9319 mock_src_client))) 

9320 self._backup_mock_common_method(mock_des_client) 

9321 self.mock_object(mock_src_client, 

9322 'get_snapmirror_destinations', 

9323 mock.Mock(return_value=[])) 

9324 vserver_peer_info = [{'vserver': fake.VSERVER1, 

9325 'peer-vserver': fake.VSERVER2}] 

9326 self.mock_object(mock_src_client, 

9327 'get_vserver_peers', 

9328 mock.Mock(return_value=vserver_peer_info)) 

9329 snap_list = ["snap1", "snap2", "snap3"] 

9330 self.mock_object(mock_des_client, 

9331 'list_volume_snapshots', 

9332 mock.Mock(return_value=snap_list)) 

9333 

9334 def test_update_share_from_metadata(self): 

9335 metadata = { 

9336 "snapshot_policy": "daily", 

9337 } 

9338 

9339 share_instance = fake.SHARE_INSTANCE 

9340 mock_update_volume_snapshot_policy = self.mock_object( 

9341 self.library, 'update_volume_snapshot_policy') 

9342 

9343 self.library.update_share_from_metadata(self.context, share_instance, 

9344 metadata) 

9345 

9346 mock_update_volume_snapshot_policy.assert_called_once_with( 

9347 share_instance, "daily", share_server=None) 

9348 

9349 def test_update_share_network_subnet_from_metadata(self): 

9350 metadata = { 

9351 "showmount": "true", 

9352 } 

9353 

9354 mock_update_showmount = self.mock_object( 

9355 self.library, 'update_showmount') 

9356 

9357 self.library.update_share_network_subnet_from_metadata( 

9358 self.context, 

9359 'fake_share_network', 

9360 'fake_share_network_subnet', 

9361 fake.SHARE_SERVER, 

9362 metadata) 

9363 

9364 mock_update_showmount.assert_called_once_with( 

9365 "true", share_server=fake.SHARE_SERVER) 

9366 

9367 def test__get_aggregate_snaplock_type_cluster_scope(self): 

9368 self.library._have_cluster_creds = True 

9369 self.mock_object(self.client, 

9370 'get_aggregate', 

9371 mock.Mock(return_value={ 

9372 'snaplock-type': 'compliance' 

9373 })) 

9374 result = self.library._get_aggregate_snaplock_type(fake.AGGREGATE) 

9375 self.assertEqual(result, "compliance") 

9376 

9377 def test__get_aggregate_snaplock_type_vserver_scope(self): 

9378 self.library._have_cluster_creds = False 

9379 self.mock_object(self.client, 

9380 'get_vserver_aggr_snaplock_type', 

9381 mock.Mock(return_value='enterprise')) 

9382 result = self.library._get_aggregate_snaplock_type(fake.AGGREGATE) 

9383 self.assertEqual(result, "enterprise") 

9384 

9385 def test__is_snaplock_compatible_for_migration_for_unified_aggr(self): 

9386 self.library._client.features.UNIFIED_AGGR = True 

9387 result = self.library._is_snaplock_compatible_for_migration( 

9388 fake.AGGREGATE, 

9389 fake.AGGR_POOL_NAME 

9390 ) 

9391 self.assertTrue(result) 

9392 

9393 def test__is_snaplock_compatible_for_migration_for_non_snaplock(self): 

9394 self.library._client.features.UNIFIED_AGGR = False 

9395 self.library._client.features.SNAPLOCK = False 

9396 

9397 result = self.library._is_snaplock_compatible_for_migration( 

9398 fake.AGGREGATE, 

9399 fake.AGGR_POOL_NAME 

9400 ) 

9401 self.assertTrue(result) 

9402 

9403 def test__is_snaplock_compatible_for_migration_non_unified_aggr(self): 

9404 self.library._client.features.UNIFIED_AGGR = False 

9405 self.library._client.features.SNAPLOCK = True 

9406 result = self.library._is_snaplock_compatible_for_migration( 

9407 fake.AGGREGATE, 

9408 fake.AGGR_POOL_NAME 

9409 ) 

9410 self.assertTrue(result)