Coverage for manila/tests/share/drivers/netapp/test_utils.py: 100%
312 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« 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"""
16Mock unit tests for the NetApp driver utility module
17"""
19import platform
20from unittest import mock
22import ddt
23from oslo_concurrency import processutils as putils
24from oslo_log import log
26from manila import exception
27from manila.share.drivers.netapp import utils as na_utils
28from manila import test
29from manila.tests.share.drivers.netapp.dataontap import fakes as fake
30from manila import version
33@ddt.ddt
34class NetAppDriverUtilsTestCase(test.TestCase):
36 def setUp(self):
37 super(NetAppDriverUtilsTestCase, self).setUp()
39 # Mock loggers as themselves to allow logger arg validation
40 mock_logger = log.getLogger('mock_logger')
41 self.mock_object(na_utils.LOG,
42 'warning',
43 mock.Mock(side_effect=mock_logger.warning))
44 self.mock_object(na_utils.LOG,
45 'debug',
46 mock.Mock(side_effect=mock_logger.debug))
48 na_utils.setup_tracing(None)
50 def test_round_down(self):
51 self.assertAlmostEqual(na_utils.round_down(5.567), 5.56)
52 self.assertAlmostEqual(na_utils.round_down(5.567, '0.00'), 5.56)
53 self.assertAlmostEqual(na_utils.round_down(5.567, '0.0'), 5.5)
54 self.assertAlmostEqual(na_utils.round_down(5.567, '0'), 5)
55 self.assertAlmostEqual(na_utils.round_down(0, '0.00'), 0)
56 self.assertAlmostEqual(na_utils.round_down(-5.567), -5.56)
57 self.assertAlmostEqual(na_utils.round_down(-5.567, '0.00'), -5.56)
58 self.assertAlmostEqual(na_utils.round_down(-5.567, '0.0'), -5.5)
59 self.assertAlmostEqual(na_utils.round_down(-5.567, '0'), -5)
61 def test_setup_tracing(self):
62 na_utils.setup_tracing(None, api_trace_pattern='(.*)')
63 self.assertFalse(na_utils.TRACE_API)
64 self.assertFalse(na_utils.TRACE_METHOD)
65 self.assertEqual('(.*)', na_utils.API_TRACE_PATTERN)
66 self.assertEqual(0, na_utils.LOG.warning.call_count)
68 na_utils.setup_tracing('method')
69 self.assertFalse(na_utils.TRACE_API)
70 self.assertTrue(na_utils.TRACE_METHOD)
71 self.assertEqual('(.*)', na_utils.API_TRACE_PATTERN)
72 self.assertEqual(0, na_utils.LOG.warning.call_count)
74 na_utils.setup_tracing('method,api', api_trace_pattern='(^fancy-api$)')
75 self.assertTrue(na_utils.TRACE_API)
76 self.assertTrue(na_utils.TRACE_METHOD)
77 self.assertEqual('(^fancy-api$)', na_utils.API_TRACE_PATTERN)
78 self.assertEqual(0, na_utils.LOG.warning.call_count)
80 def test_setup_tracing_invalid_key(self):
81 na_utils.setup_tracing('method,fake')
83 self.assertFalse(na_utils.TRACE_API)
84 self.assertTrue(na_utils.TRACE_METHOD)
85 self.assertEqual(1, na_utils.LOG.warning.call_count)
87 @ddt.data('?!(bad', '(reg]+', 'eX?!)')
88 def test_setup_tracing_invalid_regex(self, regex):
89 self.assertRaises(exception.BadConfigurationException,
90 na_utils.setup_tracing, 'method,api',
91 api_trace_pattern=regex)
93 @na_utils.trace
94 def _trace_test_method(self, *args, **kwargs):
95 return 'OK'
97 def test_trace_no_tracing(self):
98 result = self._trace_test_method()
100 self.assertEqual('OK', result)
101 self.assertEqual(0, na_utils.LOG.debug.call_count)
103 na_utils.setup_tracing('method')
105 def test_trace_method_tracing(self):
106 na_utils.setup_tracing('method')
108 result = self._trace_test_method()
109 self.assertEqual('OK', result)
110 self.assertEqual(2, na_utils.LOG.debug.call_count)
112 def test_validate_driver_instantiation_proxy(self):
113 kwargs = {'netapp_mode': 'proxy'}
115 na_utils.validate_driver_instantiation(**kwargs)
117 self.assertEqual(0, na_utils.LOG.warning.call_count)
119 def test_validate_driver_instantiation_no_proxy(self):
120 kwargs = {'netapp_mode': 'asdf'}
122 na_utils.validate_driver_instantiation(**kwargs)
124 self.assertEqual(1, na_utils.LOG.warning.call_count)
126 def test_check_flags(self):
127 configuration = type('Fake',
128 (object,),
129 {'flag1': 'value1', 'flag2': 'value2'})
131 self.assertIsNone(na_utils.check_flags(['flag1', 'flag2'],
132 configuration))
134 def test_check_flags_missing_flag(self):
135 configuration = type('Fake',
136 (object,),
137 {'flag1': 'value1', 'flag3': 'value3'})
139 self.assertRaises(exception.InvalidInput,
140 na_utils.check_flags,
141 ['flag1', 'flag2'],
142 configuration)
144 def test_convert_to_list(self):
145 self.assertListEqual([], na_utils.convert_to_list(None))
146 self.assertListEqual(['test'], na_utils.convert_to_list('test'))
147 self.assertListEqual(['a'], na_utils.convert_to_list(['a']))
148 self.assertListEqual(['a', 'b'], na_utils.convert_to_list(['a', 'b']))
149 self.assertListEqual([1, 2, 3], na_utils.convert_to_list((1, 2, 3)))
150 self.assertListEqual([5], na_utils.convert_to_list(5))
151 self.assertListEqual(
152 sorted(['key1', 'key2']),
153 sorted(na_utils.convert_to_list({'key1': 'value1',
154 'key2': 'value2'})))
156 @ddt.data({'is_fg': True, 'type': na_utils.EXTENDED_DATA_PROTECTION_TYPE},
157 {'is_fg': False, 'type': na_utils.DATA_PROTECTION_TYPE})
158 @ddt.unpack
159 def test_get_relationship_type(self, is_fg, type):
160 relationship_type = na_utils.get_relationship_type(is_fg)
162 self.assertEqual(type, relationship_type)
164 @ddt.data({'is_style': True, 'style': na_utils.FLEXGROUP_STYLE_EXTENDED},
165 {'is_style': False, 'style': na_utils.FLEXVOL_STYLE_EXTENDED})
166 @ddt.unpack
167 def test_is_style_extended_flexgroup(self, is_style, style):
168 res = na_utils.is_style_extended_flexgroup(style)
170 self.assertEqual(is_style, res)
172 @ddt.data(True, False)
173 def test_parse_flexgroup_pool_config(self, check):
175 result = na_utils.parse_flexgroup_pool_config(
176 [fake.FLEXGROUP_POOL_OPT_RAW],
177 cluster_aggr_set=set(fake.FLEXGROUP_POOL_AGGR),
178 check=check)
180 self.assertEqual(fake.FLEXGROUP_POOL_OPT, result)
182 def test_parse_flexgroup_pool_config_raise_invalid_aggr(self):
184 self.assertRaises(exception.NetAppException,
185 na_utils.parse_flexgroup_pool_config,
186 [fake.FLEXGROUP_POOL_OPT_RAW],
187 cluster_aggr_set=set(),
188 check=True)
190 def test_parse_flexgroup_pool_config_raise_duplicated_pool(self):
192 fake_pool = {
193 'flexgroup1': fake.FLEXGROUP_POOL_AGGR[0],
194 'flexgroup2': fake.FLEXGROUP_POOL_AGGR[0],
195 }
197 self.assertRaises(exception.NetAppException,
198 na_utils.parse_flexgroup_pool_config,
199 [fake_pool],
200 cluster_aggr_set=set(fake.FLEXGROUP_POOL_AGGR),
201 check=True)
203 def test_parse_flexgroup_pool_config_raise_repeated_aggr(self):
205 aggr_pool = '%s %s' % (fake.FLEXGROUP_POOL_AGGR[0],
206 fake.FLEXGROUP_POOL_AGGR[0])
208 self.assertRaises(exception.NetAppException,
209 na_utils.parse_flexgroup_pool_config,
210 [{'flexgroup1': aggr_pool}],
211 cluster_aggr_set=set(fake.FLEXGROUP_POOL_AGGR),
212 check=True)
214 def test_parse_flexgroup_pool_config_raise_invalid_pool_name(self):
216 aggr_pool = '%s %s' % (fake.FLEXGROUP_POOL_AGGR[0],
217 fake.FLEXGROUP_POOL_AGGR[0])
218 self.assertRaises(exception.NetAppException,
219 na_utils.parse_flexgroup_pool_config,
220 [{fake.FLEXGROUP_POOL_AGGR[0]: aggr_pool}],
221 cluster_aggr_set=set(fake.FLEXGROUP_POOL_AGGR),
222 check=True)
225class OpenstackInfoTestCase(test.TestCase):
227 UNKNOWN_VERSION = 'unknown version'
228 UNKNOWN_RELEASE = 'unknown release'
229 UNKNOWN_VENDOR = 'unknown vendor'
230 UNKNOWN_PLATFORM = 'unknown platform'
231 VERSION_STRING_RET_VAL = 'fake_version_1'
232 RELEASE_STRING_RET_VAL = 'fake_release_1'
233 PLATFORM_RET_VAL = 'fake_platform_1'
234 VERSION_INFO_VERSION = 'fake_version_2'
235 VERSION_INFO_RELEASE = 'fake_release_2'
236 RPM_INFO_VERSION = 'fake_version_3'
237 RPM_INFO_RELEASE = 'fake_release_3'
238 RPM_INFO_VENDOR = 'fake vendor 3'
239 PUTILS_RPM_RET_VAL = ('fake_version_3 fake_release_3 fake vendor 3', '')
240 NO_PKG_FOUND = ('', 'whatever')
241 PUTILS_DPKG_RET_VAL = ('epoch:upstream_version-debian_revision', '')
242 DEB_RLS = 'upstream_version-debian_revision'
243 DEB_VENDOR = 'debian_revision'
245 def test_openstack_info_init(self):
246 info = na_utils.OpenStackInfo()
248 self.assertEqual(self.UNKNOWN_VERSION, info._version)
249 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
250 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
251 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
253 @mock.patch.object(version.version_info, 'version_string',
254 mock.Mock(return_value=VERSION_STRING_RET_VAL))
255 def test_update_version_from_version_string(self):
256 info = na_utils.OpenStackInfo()
257 info._update_version_from_version_string()
259 self.assertEqual(self.VERSION_STRING_RET_VAL, info._version)
260 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
261 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
262 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
264 @mock.patch.object(version.version_info, 'version_string',
265 mock.Mock(side_effect=Exception))
266 def test_exception_in_update_version_from_version_string(self):
267 info = na_utils.OpenStackInfo()
268 info._update_version_from_version_string()
270 self.assertEqual(self.UNKNOWN_VERSION, info._version)
271 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
272 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
273 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
275 @mock.patch.object(version.version_info, 'release_string',
276 mock.Mock(return_value=RELEASE_STRING_RET_VAL))
277 def test_update_release_from_release_string(self):
278 info = na_utils.OpenStackInfo()
279 info._update_release_from_release_string()
281 self.assertEqual(self.UNKNOWN_VERSION, info._version)
282 self.assertEqual(self.RELEASE_STRING_RET_VAL, info._release)
283 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
284 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
286 @mock.patch.object(version.version_info, 'release_string',
287 mock.Mock(side_effect=Exception))
288 def test_exception_in_update_release_from_release_string(self):
289 info = na_utils.OpenStackInfo()
290 info._update_release_from_release_string()
292 self.assertEqual(self.UNKNOWN_VERSION, info._version)
293 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
294 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
295 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
297 @mock.patch.object(platform, 'platform',
298 mock.Mock(return_value=PLATFORM_RET_VAL))
299 def test_update_platform(self):
300 info = na_utils.OpenStackInfo()
301 info._update_platform()
303 self.assertEqual(self.UNKNOWN_VERSION, info._version)
304 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
305 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
306 self.assertEqual(self.PLATFORM_RET_VAL, info._platform)
308 @mock.patch.object(platform, 'platform',
309 mock.Mock(side_effect=Exception))
310 def test_exception_in_update_platform(self):
311 info = na_utils.OpenStackInfo()
312 info._update_platform()
314 self.assertEqual(self.UNKNOWN_VERSION, info._version)
315 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
316 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
317 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
319 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
320 mock.Mock(return_value=VERSION_INFO_VERSION))
321 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
322 mock.Mock(return_value=VERSION_INFO_RELEASE))
323 def test_update_info_from_version_info(self):
324 info = na_utils.OpenStackInfo()
325 info._update_info_from_version_info()
327 self.assertEqual(self.VERSION_INFO_VERSION, info._version)
328 self.assertEqual(self.VERSION_INFO_RELEASE, info._release)
329 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
330 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
332 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
333 mock.Mock(return_value=''))
334 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
335 mock.Mock(return_value=None))
336 def test_no_info_from_version_info(self):
337 info = na_utils.OpenStackInfo()
338 info._update_info_from_version_info()
340 self.assertEqual(self.UNKNOWN_VERSION, info._version)
341 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
342 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
343 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
345 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
346 mock.Mock(return_value=VERSION_INFO_VERSION))
347 @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
348 mock.Mock(side_effect=Exception))
349 def test_exception_in_info_from_version_info(self):
350 info = na_utils.OpenStackInfo()
351 info._update_info_from_version_info()
353 self.assertEqual(self.VERSION_INFO_VERSION, info._version)
354 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
355 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
356 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
358 @mock.patch.object(putils, 'execute',
359 mock.Mock(return_value=PUTILS_RPM_RET_VAL))
360 def test_update_info_from_rpm(self):
361 info = na_utils.OpenStackInfo()
362 found_package = info._update_info_from_rpm()
364 self.assertEqual(self.RPM_INFO_VERSION, info._version)
365 self.assertEqual(self.RPM_INFO_RELEASE, info._release)
366 self.assertEqual(self.RPM_INFO_VENDOR, info._vendor)
367 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
368 self.assertTrue(found_package)
370 @mock.patch.object(putils, 'execute',
371 mock.Mock(return_value=NO_PKG_FOUND))
372 def test_update_info_from_rpm_no_pkg_found(self):
373 info = na_utils.OpenStackInfo()
374 found_package = info._update_info_from_rpm()
376 self.assertEqual(self.UNKNOWN_VERSION, info._version)
377 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
378 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
379 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
380 self.assertFalse(found_package)
382 @mock.patch.object(putils, 'execute',
383 mock.Mock(side_effect=Exception))
384 def test_exception_in_update_info_from_rpm(self):
385 info = na_utils.OpenStackInfo()
386 found_package = info._update_info_from_rpm()
388 self.assertEqual(self.UNKNOWN_VERSION, info._version)
389 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
390 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
391 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
392 self.assertFalse(found_package)
394 @mock.patch.object(putils, 'execute',
395 mock.Mock(return_value=PUTILS_DPKG_RET_VAL))
396 def test_update_info_from_dpkg(self):
397 info = na_utils.OpenStackInfo()
398 found_package = info._update_info_from_dpkg()
400 self.assertEqual(self.UNKNOWN_VERSION, info._version)
401 self.assertEqual(self.DEB_RLS, info._release)
402 self.assertEqual(self.DEB_VENDOR, info._vendor)
403 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
404 self.assertTrue(found_package)
406 @mock.patch.object(putils, 'execute',
407 mock.Mock(return_value=NO_PKG_FOUND))
408 def test_update_info_from_dpkg_no_pkg_found(self):
409 info = na_utils.OpenStackInfo()
410 found_package = info._update_info_from_dpkg()
412 self.assertEqual(self.UNKNOWN_VERSION, info._version)
413 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
414 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
415 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
416 self.assertFalse(found_package)
418 @mock.patch.object(putils, 'execute',
419 mock.Mock(side_effect=Exception))
420 def test_exception_in_update_info_from_dpkg(self):
421 info = na_utils.OpenStackInfo()
422 found_package = info._update_info_from_dpkg()
424 self.assertEqual(self.UNKNOWN_VERSION, info._version)
425 self.assertEqual(self.UNKNOWN_RELEASE, info._release)
426 self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
427 self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
428 self.assertFalse(found_package)
430 @mock.patch.object(na_utils.OpenStackInfo,
431 '_update_version_from_version_string', mock.Mock())
432 @mock.patch.object(na_utils.OpenStackInfo,
433 '_update_release_from_release_string', mock.Mock())
434 @mock.patch.object(na_utils.OpenStackInfo,
435 '_update_platform', mock.Mock())
436 @mock.patch.object(na_utils.OpenStackInfo,
437 '_update_info_from_version_info', mock.Mock())
438 @mock.patch.object(na_utils.OpenStackInfo,
439 '_update_info_from_rpm', mock.Mock(return_value=True))
440 @mock.patch.object(na_utils.OpenStackInfo,
441 '_update_info_from_dpkg')
442 def test_update_openstack_info_rpm_pkg_found(self, mock_updt_from_dpkg):
443 info = na_utils.OpenStackInfo()
444 info._update_openstack_info()
446 self.assertFalse(mock_updt_from_dpkg.called)
448 @mock.patch.object(na_utils.OpenStackInfo,
449 '_update_version_from_version_string', mock.Mock())
450 @mock.patch.object(na_utils.OpenStackInfo,
451 '_update_release_from_release_string', mock.Mock())
452 @mock.patch.object(na_utils.OpenStackInfo,
453 '_update_platform', mock.Mock())
454 @mock.patch.object(na_utils.OpenStackInfo,
455 '_update_info_from_version_info', mock.Mock())
456 @mock.patch.object(na_utils.OpenStackInfo,
457 '_update_info_from_rpm', mock.Mock(return_value=False))
458 @mock.patch.object(na_utils.OpenStackInfo,
459 '_update_info_from_dpkg')
460 def test_update_openstack_info_rpm_pkg_not_found(self,
461 mock_updt_from_dpkg):
462 info = na_utils.OpenStackInfo()
463 info._update_openstack_info()
465 self.assertTrue(mock_updt_from_dpkg.called)
468@ddt.ddt
469class DataCacheTestCase(test.TestCase):
471 def setUp(self):
472 super(DataCacheTestCase, self).setUp()
474 self.cache = na_utils.DataCache(60)
475 self.cache._stop_watch = mock.Mock()
477 @ddt.data(True, False)
478 def test_is_expired(self, is_expired):
479 not_expired = not is_expired
480 self.mock_object(
481 self.cache._stop_watch, 'has_started',
482 mock.Mock(return_value=not_expired))
484 self.mock_object(
485 self.cache._stop_watch, 'expired',
486 mock.Mock(return_value=is_expired))
488 self.assertEqual(is_expired, self.cache.is_expired())
490 def test_get_data(self):
491 fake_data = 10
492 self.cache._cached_data = fake_data
493 self.assertEqual(fake_data, self.cache.get_data())
495 @ddt.data(True, False)
496 def test_update_data(self, started):
497 self.mock_object(
498 self.cache._stop_watch, 'has_started',
499 mock.Mock(return_value=started))
500 mock_start = self.mock_object(self.cache._stop_watch, 'start',
501 mock.Mock())
502 mock_restart = self.mock_object(self.cache._stop_watch, 'restart',
503 mock.Mock())
504 fake_data = 10
506 self.cache.update_data(fake_data)
508 self.assertEqual(self.cache._cached_data, fake_data)
509 if not started:
510 mock_start.assert_called_once()
511 else:
512 mock_restart.assert_called_once()