Coverage for manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_performance.py: 100%
308 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) 2016 Clinton Knight
2# 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.
16from unittest import mock
18import ddt
20from manila import exception
21from manila.share.drivers.netapp.dataontap.client import api as netapp_api
22from manila.share.drivers.netapp.dataontap.cluster_mode import performance
23from manila import test
24from manila.tests.share.drivers.netapp.dataontap import fakes as fake
27@ddt.ddt
28class PerformanceLibraryTestCase(test.TestCase):
30 def setUp(self):
31 super(PerformanceLibraryTestCase, self).setUp()
33 with mock.patch.object(performance.PerformanceLibrary,
34 '_init_counter_info'):
35 self.zapi_client = mock.Mock()
36 self.perf_library = performance.PerformanceLibrary(
37 self.zapi_client)
38 self.perf_library.system_object_name = 'system'
39 self.perf_library.avg_processor_busy_base_counter_name = (
40 'cpu_elapsed_time1')
42 self._set_up_fake_pools()
44 def _set_up_fake_pools(self):
46 self.fake_volumes = {
47 'pool1': {
48 'netapp_aggregate': 'aggr1',
49 },
50 'pool2': {
51 'netapp_aggregate': 'aggr2',
52 },
53 'pool3': {
54 'netapp_aggregate': 'aggr2',
55 },
56 }
57 self.fake_aggregates = {
58 'pool4': {
59 'netapp_aggregate': 'aggr3',
60 },
61 'flexgroup_pool': {
62 'netapp_aggregate': 'aggr1 aggr2',
63 'netapp_flexgroup': True,
64 },
65 }
67 self.fake_aggr_names = ['aggr1', 'aggr2', 'aggr3']
68 self.fake_nodes = ['node1', 'node2']
69 self.fake_aggr_node_map = {
70 'aggr1': 'node1',
71 'aggr2': 'node2',
72 'aggr3': 'node2',
73 }
75 def _get_fake_counters(self):
77 return {
78 'node1': list(range(11, 21)),
79 'node2': list(range(21, 31)),
80 }
82 def test_init(self):
84 mock_zapi_client = mock.Mock()
85 mock_init_counter_info = self.mock_object(
86 performance.PerformanceLibrary, '_init_counter_info')
88 library = performance.PerformanceLibrary(mock_zapi_client)
90 self.assertEqual(mock_zapi_client, library.zapi_client)
91 mock_init_counter_info.assert_called_once_with()
93 def test_init_counter_info_not_supported(self):
95 self.zapi_client.features.SYSTEM_METRICS = False
96 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = False
97 mock_get_base_counter_name = self.mock_object(
98 self.perf_library, '_get_base_counter_name')
100 self.perf_library._init_counter_info()
102 self.assertIsNone(self.perf_library.system_object_name)
103 self.assertIsNone(
104 self.perf_library.avg_processor_busy_base_counter_name)
105 self.assertFalse(mock_get_base_counter_name.called)
107 @ddt.data({
108 'system_constituent': False,
109 'base_counter': 'cpu_elapsed_time1',
110 }, {
111 'system_constituent': True,
112 'base_counter': 'cpu_elapsed_time',
113 })
114 @ddt.unpack
115 def test_init_counter_info_api_error(self, system_constituent,
116 base_counter):
118 self.zapi_client.features.SYSTEM_METRICS = True
119 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = (
120 system_constituent)
121 self.mock_object(self.perf_library,
122 '_get_base_counter_name',
123 mock.Mock(side_effect=netapp_api.NaApiError))
125 self.perf_library._init_counter_info()
127 self.assertEqual(
128 base_counter,
129 self.perf_library.avg_processor_busy_base_counter_name)
131 def test_init_counter_info_system(self):
133 self.zapi_client.features.SYSTEM_METRICS = True
134 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = False
135 mock_get_base_counter_name = self.mock_object(
136 self.perf_library, '_get_base_counter_name',
137 mock.Mock(return_value='cpu_elapsed_time1'))
139 self.perf_library._init_counter_info()
141 self.assertEqual('system', self.perf_library.system_object_name)
142 self.assertEqual(
143 'cpu_elapsed_time1',
144 self.perf_library.avg_processor_busy_base_counter_name)
145 mock_get_base_counter_name.assert_called_once_with(
146 'system', 'avg_processor_busy')
148 def test_init_counter_info_system_constituent(self):
150 self.zapi_client.features.SYSTEM_METRICS = False
151 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = True
152 mock_get_base_counter_name = self.mock_object(
153 self.perf_library, '_get_base_counter_name',
154 mock.Mock(return_value='cpu_elapsed_time'))
156 self.perf_library._init_counter_info()
158 self.assertEqual('system:constituent',
159 self.perf_library.system_object_name)
160 self.assertEqual(
161 'cpu_elapsed_time',
162 self.perf_library.avg_processor_busy_base_counter_name)
163 mock_get_base_counter_name.assert_called_once_with(
164 'system:constituent', 'avg_processor_busy')
166 def test_update_performance_cache(self):
168 self.perf_library.performance_counters = self._get_fake_counters()
169 mock_get_aggregates_for_pools = self.mock_object(
170 self.perf_library, '_get_aggregates_for_pools',
171 mock.Mock(return_value=self.fake_aggr_names))
172 mock_get_nodes_for_aggregates = self.mock_object(
173 self.perf_library, '_get_nodes_for_aggregates',
174 mock.Mock(return_value=(self.fake_nodes,
175 self.fake_aggr_node_map)))
176 mock_get_node_utilization_counters = self.mock_object(
177 self.perf_library, '_get_node_utilization_counters',
178 mock.Mock(side_effect=[21, 31]))
179 mock_get_node_utilization = self.mock_object(
180 self.perf_library, '_get_node_utilization',
181 mock.Mock(side_effect=[25, 75]))
183 self.perf_library.update_performance_cache(self.fake_volumes,
184 self.fake_aggregates)
186 expected_performance_counters = {
187 'node1': list(range(12, 22)),
188 'node2': list(range(22, 32)),
189 }
190 self.assertEqual(expected_performance_counters,
191 self.perf_library.performance_counters)
193 expected_pool_utilization = {
194 'pool1': 25,
195 'pool2': 75,
196 'pool3': 75,
197 'pool4': 75,
198 'flexgroup_pool': performance.DEFAULT_UTILIZATION,
199 }
200 self.assertEqual(expected_pool_utilization,
201 self.perf_library.pool_utilization)
203 mock_get_aggregates_for_pools.assert_called_once_with(
204 self.fake_volumes, self.fake_aggregates)
205 mock_get_nodes_for_aggregates.assert_called_once_with(
206 self.fake_aggr_names)
207 mock_get_node_utilization_counters.assert_has_calls([
208 mock.call('node1'), mock.call('node2')])
209 mock_get_node_utilization.assert_has_calls([
210 mock.call(12, 21, 'node1'), mock.call(22, 31, 'node2')])
212 def test_update_performance_cache_first_pass(self):
214 mock_get_aggregates_for_pools = self.mock_object(
215 self.perf_library, '_get_aggregates_for_pools',
216 mock.Mock(return_value=self.fake_aggr_names))
217 mock_get_nodes_for_aggregates = self.mock_object(
218 self.perf_library, '_get_nodes_for_aggregates',
219 mock.Mock(return_value=(self.fake_nodes,
220 self.fake_aggr_node_map)))
221 mock_get_node_utilization_counters = self.mock_object(
222 self.perf_library, '_get_node_utilization_counters',
223 mock.Mock(side_effect=[11, 21]))
224 mock_get_node_utilization = self.mock_object(
225 self.perf_library, '_get_node_utilization',
226 mock.Mock(side_effect=[25, 75]))
228 self.perf_library.update_performance_cache(self.fake_volumes,
229 self.fake_aggregates)
231 expected_performance_counters = {'node1': [11], 'node2': [21]}
232 self.assertEqual(expected_performance_counters,
233 self.perf_library.performance_counters)
235 expected_pool_utilization = {
236 'pool1': performance.DEFAULT_UTILIZATION,
237 'pool2': performance.DEFAULT_UTILIZATION,
238 'pool3': performance.DEFAULT_UTILIZATION,
239 'pool4': performance.DEFAULT_UTILIZATION,
240 'flexgroup_pool': performance.DEFAULT_UTILIZATION,
241 }
242 self.assertEqual(expected_pool_utilization,
243 self.perf_library.pool_utilization)
245 mock_get_aggregates_for_pools.assert_called_once_with(
246 self.fake_volumes, self.fake_aggregates)
247 mock_get_nodes_for_aggregates.assert_called_once_with(
248 self.fake_aggr_names)
249 mock_get_node_utilization_counters.assert_has_calls([
250 mock.call('node1'), mock.call('node2')])
251 self.assertFalse(mock_get_node_utilization.called)
253 def test_update_performance_cache_unknown_nodes(self):
255 self.perf_library.performance_counters = self._get_fake_counters()
256 mock_get_aggregates_for_pools = self.mock_object(
257 self.perf_library, '_get_aggregates_for_pools',
258 mock.Mock(return_value=self.fake_aggr_names))
259 mock_get_nodes_for_aggregates = self.mock_object(
260 self.perf_library, '_get_nodes_for_aggregates',
261 mock.Mock(return_value=([], {})))
262 mock_get_node_utilization_counters = self.mock_object(
263 self.perf_library, '_get_node_utilization_counters',
264 mock.Mock(side_effect=[11, 21]))
265 mock_get_node_utilization = self.mock_object(
266 self.perf_library, '_get_node_utilization',
267 mock.Mock(side_effect=[25, 75]))
269 self.perf_library.update_performance_cache(self.fake_volumes,
270 self.fake_aggregates)
272 self.assertEqual(self._get_fake_counters(),
273 self.perf_library.performance_counters)
275 expected_pool_utilization = {
276 'pool1': performance.DEFAULT_UTILIZATION,
277 'pool2': performance.DEFAULT_UTILIZATION,
278 'pool3': performance.DEFAULT_UTILIZATION,
279 'pool4': performance.DEFAULT_UTILIZATION,
280 'flexgroup_pool': performance.DEFAULT_UTILIZATION,
281 }
282 self.assertEqual(expected_pool_utilization,
283 self.perf_library.pool_utilization)
285 mock_get_aggregates_for_pools.assert_called_once_with(
286 self.fake_volumes, self.fake_aggregates)
287 mock_get_nodes_for_aggregates.assert_called_once_with(
288 self.fake_aggr_names)
289 self.assertFalse(mock_get_node_utilization_counters.called)
290 self.assertFalse(mock_get_node_utilization.called)
292 def test_update_performance_cache_counters_unavailable(self):
294 self.perf_library.performance_counters = self._get_fake_counters()
295 mock_get_aggregates_for_pools = self.mock_object(
296 self.perf_library, '_get_aggregates_for_pools',
297 mock.Mock(return_value=self.fake_aggr_names))
298 mock_get_nodes_for_aggregates = self.mock_object(
299 self.perf_library, '_get_nodes_for_aggregates',
300 mock.Mock(return_value=(self.fake_nodes,
301 self.fake_aggr_node_map)))
302 mock_get_node_utilization_counters = self.mock_object(
303 self.perf_library, '_get_node_utilization_counters',
304 mock.Mock(side_effect=[None, None]))
305 mock_get_node_utilization = self.mock_object(
306 self.perf_library, '_get_node_utilization',
307 mock.Mock(side_effect=[25, 75]))
309 self.perf_library.update_performance_cache(self.fake_volumes,
310 self.fake_aggregates)
312 self.assertEqual(self._get_fake_counters(),
313 self.perf_library.performance_counters)
315 expected_pool_utilization = {
316 'pool1': performance.DEFAULT_UTILIZATION,
317 'pool2': performance.DEFAULT_UTILIZATION,
318 'pool3': performance.DEFAULT_UTILIZATION,
319 'pool4': performance.DEFAULT_UTILIZATION,
320 'flexgroup_pool': performance.DEFAULT_UTILIZATION,
321 }
322 self.assertEqual(expected_pool_utilization,
323 self.perf_library.pool_utilization)
325 mock_get_aggregates_for_pools.assert_called_once_with(
326 self.fake_volumes, self.fake_aggregates)
327 mock_get_nodes_for_aggregates.assert_called_once_with(
328 self.fake_aggr_names)
329 mock_get_node_utilization_counters.assert_has_calls([
330 mock.call('node1'), mock.call('node2')])
331 self.assertFalse(mock_get_node_utilization.called)
333 def test_update_performance_cache_not_supported(self):
335 self.zapi_client.features.SYSTEM_METRICS = False
336 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = False
338 mock_get_aggregates_for_pools = self.mock_object(
339 self.perf_library, '_get_aggregates_for_pools')
341 self.perf_library.update_performance_cache(self.fake_volumes,
342 self.fake_aggregates)
344 expected_performance_counters = {}
345 self.assertEqual(expected_performance_counters,
346 self.perf_library.performance_counters)
348 expected_pool_utilization = {}
349 self.assertEqual(expected_pool_utilization,
350 self.perf_library.pool_utilization)
352 self.assertFalse(mock_get_aggregates_for_pools.called)
354 @ddt.data({'pool': 'pool1', 'expected': 10.0},
355 {'pool': 'pool3', 'expected': performance.DEFAULT_UTILIZATION})
356 @ddt.unpack
357 def test_get_node_utilization_for_pool(self, pool, expected):
359 self.perf_library.pool_utilization = {'pool1': 10.0, 'pool2': 15.0}
361 result = self.perf_library.get_node_utilization_for_pool(pool)
363 self.assertAlmostEqual(expected, result)
365 def test__update_for_failover(self):
366 self.mock_object(self.perf_library, 'update_performance_cache')
367 mock_client = mock.Mock(name='FAKE_ZAPI_CLIENT')
369 self.perf_library.update_for_failover(mock_client,
370 self.fake_volumes,
371 self.fake_aggregates)
373 self.assertEqual(mock_client, self.perf_library.zapi_client)
374 self.perf_library.update_performance_cache.assert_called_once_with(
375 self.fake_volumes, self.fake_aggregates)
377 def test_get_aggregates_for_pools(self):
379 result = self.perf_library._get_aggregates_for_pools(
380 self.fake_volumes, self.fake_aggregates)
382 expected_aggregate_names = ['aggr1', 'aggr2', 'aggr3']
383 self.assertEqual(sorted(expected_aggregate_names), sorted(result))
385 def test_get_nodes_for_aggregates(self):
387 aggregate_names = ['aggr1', 'aggr2', 'aggr3']
388 aggregate_nodes = ['node1', 'node2', 'node2']
390 mock_get_node_for_aggregate = self.mock_object(
391 self.zapi_client, 'get_node_for_aggregate',
392 mock.Mock(side_effect=aggregate_nodes))
394 result = self.perf_library._get_nodes_for_aggregates(aggregate_names)
396 self.assertEqual(2, len(result))
397 result_node_names, result_aggr_node_map = result
399 expected_node_names = ['node1', 'node2']
400 expected_aggr_node_map = dict(zip(aggregate_names, aggregate_nodes))
401 self.assertEqual(sorted(expected_node_names),
402 sorted(result_node_names))
403 self.assertEqual(expected_aggr_node_map, result_aggr_node_map)
404 mock_get_node_for_aggregate.assert_has_calls([
405 mock.call('aggr1'), mock.call('aggr2'), mock.call('aggr3')])
407 def test_get_node_utilization_kahuna_overutilized(self):
409 mock_get_kahuna_utilization = self.mock_object(
410 self.perf_library, '_get_kahuna_utilization',
411 mock.Mock(return_value=61.0))
412 mock_get_average_cpu_utilization = self.mock_object(
413 self.perf_library, '_get_average_cpu_utilization',
414 mock.Mock(return_value=25.0))
416 result = self.perf_library._get_node_utilization('fake1',
417 'fake2',
418 'fake_node')
420 self.assertAlmostEqual(100.0, result)
421 mock_get_kahuna_utilization.assert_called_once_with('fake1', 'fake2')
422 self.assertFalse(mock_get_average_cpu_utilization.called)
424 @ddt.data({'cpu': -0.01, 'cp_time': 10000, 'poll_time': 0},
425 {'cpu': 1.01, 'cp_time': 0, 'poll_time': 1000},
426 {'cpu': 0.50, 'cp_time': 0, 'poll_time': 0})
427 @ddt.unpack
428 def test_get_node_utilization_zero_time(self, cpu, cp_time, poll_time):
430 mock_get_kahuna_utilization = self.mock_object(
431 self.perf_library, '_get_kahuna_utilization',
432 mock.Mock(return_value=59.0))
433 mock_get_average_cpu_utilization = self.mock_object(
434 self.perf_library, '_get_average_cpu_utilization',
435 mock.Mock(return_value=cpu))
436 mock_get_total_consistency_point_time = self.mock_object(
437 self.perf_library, '_get_total_consistency_point_time',
438 mock.Mock(return_value=cp_time))
439 mock_get_consistency_point_p2_flush_time = self.mock_object(
440 self.perf_library, '_get_consistency_point_p2_flush_time',
441 mock.Mock(return_value=cp_time))
442 mock_get_total_time = self.mock_object(
443 self.perf_library, '_get_total_time',
444 mock.Mock(return_value=poll_time))
445 mock_get_adjusted_consistency_point_time = self.mock_object(
446 self.perf_library, '_get_adjusted_consistency_point_time')
448 result = self.perf_library._get_node_utilization('fake1',
449 'fake2',
450 'fake_node')
452 expected = max(min(100.0, 100.0 * cpu), 0)
453 self.assertEqual(expected, result)
455 mock_get_kahuna_utilization.assert_called_once_with('fake1', 'fake2')
456 mock_get_average_cpu_utilization.assert_called_once_with('fake1',
457 'fake2')
458 mock_get_total_consistency_point_time.assert_called_once_with('fake1',
459 'fake2')
460 mock_get_consistency_point_p2_flush_time.assert_called_once_with(
461 'fake1', 'fake2')
462 mock_get_total_time.assert_called_once_with('fake1',
463 'fake2',
464 'total_cp_msecs')
465 self.assertFalse(mock_get_adjusted_consistency_point_time.called)
467 @ddt.data({'cpu': 0.75, 'adjusted_cp_time': 8000, 'expected': 80},
468 {'cpu': 0.80, 'adjusted_cp_time': 7500, 'expected': 80},
469 {'cpu': 0.50, 'adjusted_cp_time': 11000, 'expected': 100})
470 @ddt.unpack
471 def test_get_node_utilization(self, cpu, adjusted_cp_time, expected):
473 mock_get_kahuna_utilization = self.mock_object(
474 self.perf_library, '_get_kahuna_utilization',
475 mock.Mock(return_value=59.0))
476 mock_get_average_cpu_utilization = self.mock_object(
477 self.perf_library, '_get_average_cpu_utilization',
478 mock.Mock(return_value=cpu))
479 mock_get_total_consistency_point_time = self.mock_object(
480 self.perf_library, '_get_total_consistency_point_time',
481 mock.Mock(return_value=90.0))
482 mock_get_consistency_point_p2_flush_time = self.mock_object(
483 self.perf_library, '_get_consistency_point_p2_flush_time',
484 mock.Mock(return_value=50.0))
485 mock_get_total_time = self.mock_object(
486 self.perf_library, '_get_total_time',
487 mock.Mock(return_value=10000))
488 mock_get_adjusted_consistency_point_time = self.mock_object(
489 self.perf_library, '_get_adjusted_consistency_point_time',
490 mock.Mock(return_value=adjusted_cp_time))
492 result = self.perf_library._get_node_utilization('fake1',
493 'fake2',
494 'fake_node')
496 self.assertEqual(expected, result)
498 mock_get_kahuna_utilization.assert_called_once_with('fake1', 'fake2')
499 mock_get_average_cpu_utilization.assert_called_once_with('fake1',
500 'fake2')
501 mock_get_total_consistency_point_time.assert_called_once_with('fake1',
502 'fake2')
503 mock_get_consistency_point_p2_flush_time.assert_called_once_with(
504 'fake1', 'fake2')
505 mock_get_total_time.assert_called_once_with('fake1',
506 'fake2',
507 'total_cp_msecs')
508 mock_get_adjusted_consistency_point_time.assert_called_once_with(
509 90.0, 50.0)
511 def test_get_node_utilization_calculation_error(self):
513 self.mock_object(self.perf_library,
514 '_get_kahuna_utilization',
515 mock.Mock(return_value=59.0))
516 self.mock_object(self.perf_library,
517 '_get_average_cpu_utilization',
518 mock.Mock(return_value=25.0))
519 self.mock_object(self.perf_library,
520 '_get_total_consistency_point_time',
521 mock.Mock(return_value=90.0))
522 self.mock_object(self.perf_library,
523 '_get_consistency_point_p2_flush_time',
524 mock.Mock(return_value=50.0))
525 self.mock_object(self.perf_library,
526 '_get_total_time',
527 mock.Mock(return_value=10000))
528 self.mock_object(self.perf_library,
529 '_get_adjusted_consistency_point_time',
530 mock.Mock(side_effect=ZeroDivisionError))
532 result = self.perf_library._get_node_utilization('fake1',
533 'fake2',
534 'fake_node')
536 self.assertEqual(performance.DEFAULT_UTILIZATION, result)
537 (self.perf_library._get_adjusted_consistency_point_time.
538 assert_called_once_with(mock.ANY, mock.ANY))
540 def test_get_kahuna_utilization(self):
542 mock_get_performance_counter = self.mock_object(
543 self.perf_library,
544 '_get_performance_counter_average_multi_instance',
545 mock.Mock(return_value=[0.2, 0.3]))
547 result = self.perf_library._get_kahuna_utilization('fake_t1',
548 'fake_t2')
550 self.assertAlmostEqual(50.0, result)
551 mock_get_performance_counter.assert_called_once_with(
552 'fake_t1', 'fake_t2', 'domain_busy:kahuna',
553 'processor_elapsed_time')
555 def test_get_average_cpu_utilization(self):
557 mock_get_performance_counter_average = self.mock_object(
558 self.perf_library, '_get_performance_counter_average',
559 mock.Mock(return_value=0.45))
561 result = self.perf_library._get_average_cpu_utilization('fake_t1',
562 'fake_t2')
564 self.assertAlmostEqual(0.45, result)
565 mock_get_performance_counter_average.assert_called_once_with(
566 'fake_t1', 'fake_t2', 'avg_processor_busy', 'cpu_elapsed_time1')
568 def test_get_total_consistency_point_time(self):
570 mock_get_performance_counter_delta = self.mock_object(
571 self.perf_library, '_get_performance_counter_delta',
572 mock.Mock(return_value=500))
574 result = self.perf_library._get_total_consistency_point_time(
575 'fake_t1', 'fake_t2')
577 self.assertEqual(500, result)
578 mock_get_performance_counter_delta.assert_called_once_with(
579 'fake_t1', 'fake_t2', 'total_cp_msecs')
581 def test_get_consistency_point_p2_flush_time(self):
583 mock_get_performance_counter_delta = self.mock_object(
584 self.perf_library, '_get_performance_counter_delta',
585 mock.Mock(return_value=500))
587 result = self.perf_library._get_consistency_point_p2_flush_time(
588 'fake_t1', 'fake_t2')
590 self.assertEqual(500, result)
591 mock_get_performance_counter_delta.assert_called_once_with(
592 'fake_t1', 'fake_t2', 'cp_phase_times:p2_flush')
594 def test_get_total_time(self):
596 mock_find_performance_counter_timestamp = self.mock_object(
597 self.perf_library, '_find_performance_counter_timestamp',
598 mock.Mock(side_effect=[100, 105]))
600 result = self.perf_library._get_total_time('fake_t1',
601 'fake_t2',
602 'fake_counter')
604 self.assertEqual(5000, result)
605 mock_find_performance_counter_timestamp.assert_has_calls([
606 mock.call('fake_t1', 'fake_counter'),
607 mock.call('fake_t2', 'fake_counter')])
609 def test_get_adjusted_consistency_point_time(self):
611 result = self.perf_library._get_adjusted_consistency_point_time(
612 500, 200)
614 self.assertAlmostEqual(360.0, result)
616 def test_get_performance_counter_delta(self):
618 result = self.perf_library._get_performance_counter_delta(
619 fake.COUNTERS_T1, fake.COUNTERS_T2, 'total_cp_msecs')
621 self.assertEqual(1482, result)
623 def test_get_performance_counter_average(self):
625 result = self.perf_library._get_performance_counter_average(
626 fake.COUNTERS_T1, fake.COUNTERS_T2, 'domain_busy:kahuna',
627 'processor_elapsed_time', 'processor0')
629 self.assertAlmostEqual(0.00281954360981, result)
631 def test_get_performance_counter_average_multi_instance(self):
633 result = (
634 self.perf_library._get_performance_counter_average_multi_instance(
635 fake.COUNTERS_T1, fake.COUNTERS_T2, 'domain_busy:kahuna',
636 'processor_elapsed_time'))
638 expected = [0.002819543609809441, 0.0033421611147606135]
639 self.assertAlmostEqual(expected, result)
641 def test_find_performance_counter_value(self):
643 result = self.perf_library._find_performance_counter_value(
644 fake.COUNTERS_T1, 'domain_busy:kahuna',
645 instance_name='processor0')
647 self.assertEqual('2712467226', result)
649 def test_find_performance_counter_value_not_found(self):
651 self.assertRaises(
652 exception.NotFound,
653 self.perf_library._find_performance_counter_value,
654 fake.COUNTERS_T1, 'invalid', instance_name='processor0')
656 def test_find_performance_counter_timestamp(self):
658 result = self.perf_library._find_performance_counter_timestamp(
659 fake.COUNTERS_T1, 'domain_busy')
661 self.assertEqual('1453573777', result)
663 def test_find_performance_counter_timestamp_not_found(self):
665 self.assertRaises(
666 exception.NotFound,
667 self.perf_library._find_performance_counter_timestamp,
668 fake.COUNTERS_T1, 'invalid', instance_name='processor0')
670 def test_expand_performance_array(self):
672 counter_info = {
673 'labels': ['idle', 'kahuna', 'storage', 'exempt'],
674 'name': 'domain_busy',
675 }
676 self.zapi_client.get_performance_counter_info = mock.Mock(
677 return_value=counter_info)
679 counter = {
680 'node-name': 'cluster1-01',
681 'instance-uuid': 'cluster1-01:kernel:processor0',
682 'domain_busy': '969142314286,2567571412,2131582146,5383861579',
683 'instance-name': 'processor0',
684 'timestamp': '1453512244',
685 }
686 self.perf_library._expand_performance_array('wafl',
687 'domain_busy',
688 counter)
690 modified_counter = {
691 'node-name': 'cluster1-01',
692 'instance-uuid': 'cluster1-01:kernel:processor0',
693 'domain_busy': '969142314286,2567571412,2131582146,5383861579',
694 'instance-name': 'processor0',
695 'timestamp': '1453512244',
696 'domain_busy:idle': '969142314286',
697 'domain_busy:kahuna': '2567571412',
698 'domain_busy:storage': '2131582146',
699 'domain_busy:exempt': '5383861579',
700 }
701 self.assertEqual(modified_counter, counter)
703 def test_get_base_counter_name(self):
705 counter_info = {
706 'base-counter': 'cpu_elapsed_time',
707 'labels': [],
708 'name': 'avg_processor_busy',
709 }
710 self.zapi_client.get_performance_counter_info = mock.Mock(
711 return_value=counter_info)
713 result = self.perf_library._get_base_counter_name(
714 'system:constituent', 'avg_processor_busy')
716 self.assertEqual('cpu_elapsed_time', result)
718 def test_get_node_utilization_counters(self):
720 mock_get_node_utilization_system_counters = self.mock_object(
721 self.perf_library, '_get_node_utilization_system_counters',
722 mock.Mock(return_value=['A', 'B', 'C']))
723 mock_get_node_utilization_wafl_counters = self.mock_object(
724 self.perf_library, '_get_node_utilization_wafl_counters',
725 mock.Mock(return_value=['D', 'E', 'F']))
726 mock_get_node_utilization_processor_counters = self.mock_object(
727 self.perf_library, '_get_node_utilization_processor_counters',
728 mock.Mock(return_value=['G', 'H', 'I']))
730 result = self.perf_library._get_node_utilization_counters(fake.NODE)
732 expected = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
733 self.assertEqual(expected, result)
735 mock_get_node_utilization_system_counters.assert_called_once_with(
736 fake.NODE)
737 mock_get_node_utilization_wafl_counters.assert_called_once_with(
738 fake.NODE)
739 mock_get_node_utilization_processor_counters.assert_called_once_with(
740 fake.NODE)
742 def test_get_node_utilization_counters_api_error(self):
744 self.mock_object(self.perf_library,
745 '_get_node_utilization_system_counters',
746 mock.Mock(side_effect=netapp_api.NaApiError))
748 result = self.perf_library._get_node_utilization_counters(fake.NODE)
750 self.assertIsNone(result)
752 def test_get_node_utilization_system_counters(self):
754 mock_get_performance_instance_uuids = self.mock_object(
755 self.zapi_client, 'get_performance_instance_uuids',
756 mock.Mock(return_value=fake.SYSTEM_INSTANCE_UUIDS))
757 mock_get_performance_counters = self.mock_object(
758 self.zapi_client, 'get_performance_counters',
759 mock.Mock(return_value=fake.SYSTEM_COUNTERS))
761 result = self.perf_library._get_node_utilization_system_counters(
762 fake.NODE)
764 self.assertEqual(fake.SYSTEM_COUNTERS, result)
766 mock_get_performance_instance_uuids.assert_called_once_with(
767 'system', fake.NODE)
768 mock_get_performance_counters.assert_called_once_with(
769 'system', fake.SYSTEM_INSTANCE_UUIDS,
770 ['avg_processor_busy', 'cpu_elapsed_time1', 'cpu_elapsed_time'])
772 def test_get_node_utilization_wafl_counters(self):
774 mock_get_performance_instance_uuids = self.mock_object(
775 self.zapi_client, 'get_performance_instance_uuids',
776 mock.Mock(return_value=fake.WAFL_INSTANCE_UUIDS))
777 mock_get_performance_counters = self.mock_object(
778 self.zapi_client, 'get_performance_counters',
779 mock.Mock(return_value=fake.WAFL_COUNTERS))
780 mock_get_performance_counter_info = self.mock_object(
781 self.zapi_client, 'get_performance_counter_info',
782 mock.Mock(return_value=fake.WAFL_CP_PHASE_TIMES_COUNTER_INFO))
784 result = self.perf_library._get_node_utilization_wafl_counters(
785 fake.NODE)
787 self.assertEqual(fake.EXPANDED_WAFL_COUNTERS, result)
789 mock_get_performance_instance_uuids.assert_called_once_with(
790 'wafl', fake.NODE)
791 mock_get_performance_counters.assert_called_once_with(
792 'wafl', fake.WAFL_INSTANCE_UUIDS,
793 ['total_cp_msecs', 'cp_phase_times'])
794 mock_get_performance_counter_info.assert_called_once_with(
795 'wafl', 'cp_phase_times')
797 def test_get_node_utilization_processor_counters(self):
799 mock_get_performance_instance_uuids = self.mock_object(
800 self.zapi_client, 'get_performance_instance_uuids',
801 mock.Mock(return_value=fake.PROCESSOR_INSTANCE_UUIDS))
802 mock_get_performance_counters = self.mock_object(
803 self.zapi_client, 'get_performance_counters',
804 mock.Mock(return_value=fake.PROCESSOR_COUNTERS))
805 self.mock_object(
806 self.zapi_client, 'get_performance_counter_info',
807 mock.Mock(return_value=fake.PROCESSOR_DOMAIN_BUSY_COUNTER_INFO))
809 result = self.perf_library._get_node_utilization_processor_counters(
810 fake.NODE)
812 self.assertEqual(fake.EXPANDED_PROCESSOR_COUNTERS, result)
814 mock_get_performance_instance_uuids.assert_called_once_with(
815 'processor', fake.NODE)
816 mock_get_performance_counters.assert_called_once_with(
817 'processor', fake.PROCESSOR_INSTANCE_UUIDS,
818 ['domain_busy', 'processor_elapsed_time'])