Coverage for manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_single_svm.py: 100%

163 statements  

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

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

2# 

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

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

5# a copy of the License at 

6# 

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

8# 

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

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

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

12# License for the specific language governing permissions and limitations 

13# under the License. 

14""" 

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

16""" 

17 

18from unittest import mock 

19 

20import ddt 

21from oslo_log import log 

22 

23from manila import exception 

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

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

26from manila.share.drivers.netapp.dataontap.cluster_mode import lib_single_svm 

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

28from manila import test 

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

30 import _get_config 

31import manila.tests.share.drivers.netapp.dataontap.fakes as fake 

32 

33 

34@ddt.ddt 

35class NetAppFileStorageLibraryTestCase(test.TestCase): 

36 

37 def setUp(self): 

38 super(NetAppFileStorageLibraryTestCase, self).setUp() 

39 

40 self.mock_object(na_utils, 'validate_driver_instantiation') 

41 

42 # Mock loggers as themselves to allow logger arg validation 

43 mock_logger = log.getLogger('mock_logger') 

44 self.mock_object(lib_single_svm.LOG, 

45 'info', 

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

47 

48 config = fake.get_config_cmode() 

49 config.netapp_vserver = fake.VSERVER1 

50 

51 kwargs = { 

52 'configuration': config, 

53 'private_storage': mock.Mock(), 

54 'app_version': fake.APP_VERSION 

55 } 

56 

57 self.library = lib_single_svm.NetAppCmodeSingleSVMFileStorageLibrary( 

58 fake.DRIVER_NAME, **kwargs) 

59 

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

61 self.client = self.library._client 

62 

63 def test_init(self): 

64 self.assertEqual(fake.VSERVER1, self.library._vserver) 

65 

66 def test_check_for_setup_error(self): 

67 

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

69 self.library._have_cluster_creds = True 

70 mock_client = mock.Mock() 

71 mock_client.list_vserver_aggregates.return_value = fake.AGGREGATES 

72 self.mock_object(self.library, 

73 '_get_api_client', 

74 mock.Mock(return_value=mock_client)) 

75 mock_init_flexgroup = self.mock_object(self.library, 

76 '_initialize_flexgroup_pools') 

77 self.mock_object(self.library, 

78 'is_flexvol_pool_configured', 

79 mock.Mock(return_value=True)) 

80 self.mock_object(self.library, 

81 '_find_matching_aggregates', 

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

83 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

84 'check_for_setup_error') 

85 

86 self.library.check_for_setup_error() 

87 

88 self.assertTrue(lib_single_svm.LOG.info.called) 

89 mock_super.assert_called_once_with() 

90 mock_client.list_vserver_aggregates.assert_called_once_with() 

91 self.assertTrue(self.library._get_api_client.called) 

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

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

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

95 

96 def test_check_for_setup_error_no_vserver(self): 

97 self.library._vserver = None 

98 

99 self.assertRaises(exception.InvalidInput, 

100 self.library.check_for_setup_error) 

101 

102 def test_check_for_setup_error_vserver_not_found(self): 

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

104 

105 self.assertRaises(exception.VserverNotFound, 

106 self.library.check_for_setup_error) 

107 

108 def test_check_for_setup_error_cluster_creds_vserver_match(self): 

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

110 self.library._have_cluster_creds = False 

111 self.library._client.list_vservers.return_value = [fake.VSERVER1] 

112 mock_client = mock.Mock() 

113 mock_client.list_vserver_aggregates.return_value = fake.AGGREGATES 

114 self.mock_object(self.library, 

115 '_get_api_client', 

116 mock.Mock(return_value=mock_client)) 

117 mock_init_flexgroup = self.mock_object(self.library, 

118 '_initialize_flexgroup_pools') 

119 self.mock_object(self.library, 

120 'is_flexvol_pool_configured', 

121 mock.Mock(return_value=True)) 

122 self.mock_object(self.library, 

123 '_find_matching_aggregates', 

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

125 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

126 'check_for_setup_error') 

127 

128 self.library.check_for_setup_error() 

129 

130 mock_super.assert_called_once_with() 

131 mock_client.list_vserver_aggregates.assert_called_once_with() 

132 self.assertTrue(self.library._get_api_client.called) 

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

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

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

136 

137 def test_check_for_setup_error_no_aggregates_no_flexvol_pool(self): 

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

139 self.library._have_cluster_creds = True 

140 mock_client = mock.Mock() 

141 mock_client.list_vserver_aggregates.return_value = fake.AGGREGATES 

142 self.mock_object(self.library, 

143 '_get_api_client', 

144 mock.Mock(return_value=mock_client)) 

145 self.mock_object(self.library, '_initialize_flexgroup_pools') 

146 self.mock_object(self.library, 

147 'is_flexvol_pool_configured', 

148 mock.Mock(return_value=False)) 

149 self.mock_object(self.library, 

150 '_find_matching_aggregates', 

151 mock.Mock(return_value=[])) 

152 

153 self.library.check_for_setup_error() 

154 

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

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

157 

158 def test_check_for_setup_error_cluster_creds_vserver_mismatch(self): 

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

160 self.library._have_cluster_creds = False 

161 self.library._client.list_vservers.return_value = [fake.VSERVER2] 

162 

163 self.assertRaises(exception.InvalidInput, 

164 self.library.check_for_setup_error) 

165 

166 def test_check_for_setup_error_no_aggregates(self): 

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

168 self.library._have_cluster_creds = True 

169 mock_client = mock.Mock() 

170 mock_client.list_vserver_aggregates.return_value = fake.AGGREGATES 

171 self.mock_object(self.library, 

172 '_get_api_client', 

173 mock.Mock(return_value=mock_client)) 

174 self.mock_object(self.library, '_initialize_flexgroup_pools') 

175 self.mock_object(self.library, 

176 'is_flexvol_pool_configured', 

177 mock.Mock(return_value=True)) 

178 self.mock_object(self.library, 

179 '_find_matching_aggregates', 

180 mock.Mock(return_value=[])) 

181 

182 self.assertRaises(exception.NetAppException, 

183 self.library.check_for_setup_error) 

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

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

186 

187 def test_get_vserver(self): 

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

189 self.mock_object(self.library, 

190 '_get_api_client', 

191 mock.Mock(return_value='fake_client')) 

192 

193 result_vserver, result_vserver_client = self.library._get_vserver() 

194 

195 self.assertEqual(fake.VSERVER1, result_vserver) 

196 self.assertEqual('fake_client', result_vserver_client) 

197 

198 def test_get_vserver_share_server_specified(self): 

199 self.assertRaises(exception.InvalidParameterValue, 

200 self.library._get_vserver, 

201 share_server=fake.SHARE_SERVER) 

202 

203 def test_get_vserver_no_vserver(self): 

204 self.library._vserver = None 

205 

206 self.assertRaises(exception.InvalidInput, 

207 self.library._get_vserver) 

208 

209 def test_get_vserver_vserver_not_found(self): 

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

211 

212 self.assertRaises(exception.VserverNotFound, 

213 self.library._get_vserver) 

214 

215 def test_get_ems_pool_info(self): 

216 

217 self.mock_object(self.library, 

218 '_find_matching_aggregates', 

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

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

221 

222 result = self.library._get_ems_pool_info() 

223 

224 expected = { 

225 'pools': { 

226 'vserver': fake.VSERVER1, 

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

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

229 }, 

230 } 

231 self.assertEqual(expected, result) 

232 

233 @ddt.data(True, False) 

234 def test_handle_housekeeping_tasks_with_cluster_creds(self, have_creds): 

235 self.library._have_cluster_creds = have_creds 

236 mock_vserver_client = mock.Mock() 

237 self.mock_object(self.library, 

238 '_get_api_client', 

239 mock.Mock(return_value=mock_vserver_client)) 

240 mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary, 

241 '_handle_housekeeping_tasks') 

242 

243 self.library._handle_housekeeping_tasks() 

244 

245 self.assertTrue( 

246 mock_vserver_client.prune_deleted_nfs_export_policies.called) 

247 self.assertTrue(mock_vserver_client.prune_deleted_snapshots.called) 

248 self.assertIs( 

249 have_creds, 

250 mock_vserver_client.remove_unused_qos_policy_groups.called) 

251 self.assertTrue(mock_super.called) 

252 

253 @ddt.data(True, False) 

254 def test_find_matching_aggregates(self, have_cluster_creds): 

255 

256 self.mock_object(self.library, 

257 'is_flexvol_pool_configured', 

258 mock.Mock(return_value=True)) 

259 self.library._have_cluster_creds = have_cluster_creds 

260 aggregates = fake.AGGREGATES + fake.ROOT_AGGREGATES 

261 mock_vserver_client = mock.Mock() 

262 mock_vserver_client.list_vserver_aggregates.return_value = aggregates 

263 self.mock_object(self.library, 

264 '_get_api_client', 

265 mock.Mock(return_value=mock_vserver_client)) 

266 mock_client = mock.Mock() 

267 mock_client.list_root_aggregates.return_value = fake.ROOT_AGGREGATES 

268 self.library._client = mock_client 

269 

270 self.library.configuration.netapp_aggregate_name_search_pattern = ( 

271 '.*_aggr_1') 

272 

273 result = self.library._find_matching_aggregates() 

274 

275 if have_cluster_creds: 

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

277 mock_client.list_root_aggregates.assert_called_once_with() 

278 else: 

279 self.assertListEqual([fake.AGGREGATES[0], fake.ROOT_AGGREGATES[0]], 

280 result) 

281 self.assertFalse(mock_client.list_root_aggregates.called) 

282 

283 def test_find_matching_aggregates_no_flexvol_pool(self): 

284 

285 self.mock_object(self.library, 

286 'is_flexvol_pool_configured', 

287 mock.Mock(return_value=False)) 

288 

289 result = self.library._find_matching_aggregates() 

290 

291 self.assertListEqual([], result) 

292 

293 def test_get_network_allocations_number(self): 

294 self.assertEqual(0, self.library.get_network_allocations_number()) 

295 

296 def test_get_admin_network_allocations_number(self): 

297 

298 result = self.library.get_admin_network_allocations_number() 

299 

300 self.assertEqual(0, result) 

301 

302 def test__get_backup_vserver(self): 

303 self.mock_object(self.library, 

304 '_get_backend', 

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

306 self.mock_object(data_motion, 

307 'get_backend_configuration', 

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

309 self.library._get_backup_vserver(fake.SHARE_BACKUP) 

310 

311 def test__get_backup_vserver_with_share_server_negative(self): 

312 self.mock_object(self.library, 

313 '_get_backend', 

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

315 self.mock_object(data_motion, 

316 'get_backend_configuration', 

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

318 self.assertRaises( 

319 exception.InvalidParameterValue, 

320 self.library._get_backup_vserver, 

321 fake.SHARE_BACKUP, 

322 fake.SHARE_SERVER, 

323 )