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

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. 

15 

16from unittest import mock 

17 

18import ddt 

19 

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 

25 

26 

27@ddt.ddt 

28class PerformanceLibraryTestCase(test.TestCase): 

29 

30 def setUp(self): 

31 super(PerformanceLibraryTestCase, self).setUp() 

32 

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') 

41 

42 self._set_up_fake_pools() 

43 

44 def _set_up_fake_pools(self): 

45 

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 } 

66 

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 } 

74 

75 def _get_fake_counters(self): 

76 

77 return { 

78 'node1': list(range(11, 21)), 

79 'node2': list(range(21, 31)), 

80 } 

81 

82 def test_init(self): 

83 

84 mock_zapi_client = mock.Mock() 

85 mock_init_counter_info = self.mock_object( 

86 performance.PerformanceLibrary, '_init_counter_info') 

87 

88 library = performance.PerformanceLibrary(mock_zapi_client) 

89 

90 self.assertEqual(mock_zapi_client, library.zapi_client) 

91 mock_init_counter_info.assert_called_once_with() 

92 

93 def test_init_counter_info_not_supported(self): 

94 

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') 

99 

100 self.perf_library._init_counter_info() 

101 

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) 

106 

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): 

117 

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)) 

124 

125 self.perf_library._init_counter_info() 

126 

127 self.assertEqual( 

128 base_counter, 

129 self.perf_library.avg_processor_busy_base_counter_name) 

130 

131 def test_init_counter_info_system(self): 

132 

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')) 

138 

139 self.perf_library._init_counter_info() 

140 

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') 

147 

148 def test_init_counter_info_system_constituent(self): 

149 

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')) 

155 

156 self.perf_library._init_counter_info() 

157 

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') 

165 

166 def test_update_performance_cache(self): 

167 

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])) 

182 

183 self.perf_library.update_performance_cache(self.fake_volumes, 

184 self.fake_aggregates) 

185 

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) 

192 

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) 

202 

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')]) 

211 

212 def test_update_performance_cache_first_pass(self): 

213 

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])) 

227 

228 self.perf_library.update_performance_cache(self.fake_volumes, 

229 self.fake_aggregates) 

230 

231 expected_performance_counters = {'node1': [11], 'node2': [21]} 

232 self.assertEqual(expected_performance_counters, 

233 self.perf_library.performance_counters) 

234 

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) 

244 

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) 

252 

253 def test_update_performance_cache_unknown_nodes(self): 

254 

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])) 

268 

269 self.perf_library.update_performance_cache(self.fake_volumes, 

270 self.fake_aggregates) 

271 

272 self.assertEqual(self._get_fake_counters(), 

273 self.perf_library.performance_counters) 

274 

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) 

284 

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) 

291 

292 def test_update_performance_cache_counters_unavailable(self): 

293 

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])) 

308 

309 self.perf_library.update_performance_cache(self.fake_volumes, 

310 self.fake_aggregates) 

311 

312 self.assertEqual(self._get_fake_counters(), 

313 self.perf_library.performance_counters) 

314 

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) 

324 

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) 

332 

333 def test_update_performance_cache_not_supported(self): 

334 

335 self.zapi_client.features.SYSTEM_METRICS = False 

336 self.zapi_client.features.SYSTEM_CONSTITUENT_METRICS = False 

337 

338 mock_get_aggregates_for_pools = self.mock_object( 

339 self.perf_library, '_get_aggregates_for_pools') 

340 

341 self.perf_library.update_performance_cache(self.fake_volumes, 

342 self.fake_aggregates) 

343 

344 expected_performance_counters = {} 

345 self.assertEqual(expected_performance_counters, 

346 self.perf_library.performance_counters) 

347 

348 expected_pool_utilization = {} 

349 self.assertEqual(expected_pool_utilization, 

350 self.perf_library.pool_utilization) 

351 

352 self.assertFalse(mock_get_aggregates_for_pools.called) 

353 

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): 

358 

359 self.perf_library.pool_utilization = {'pool1': 10.0, 'pool2': 15.0} 

360 

361 result = self.perf_library.get_node_utilization_for_pool(pool) 

362 

363 self.assertAlmostEqual(expected, result) 

364 

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') 

368 

369 self.perf_library.update_for_failover(mock_client, 

370 self.fake_volumes, 

371 self.fake_aggregates) 

372 

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) 

376 

377 def test_get_aggregates_for_pools(self): 

378 

379 result = self.perf_library._get_aggregates_for_pools( 

380 self.fake_volumes, self.fake_aggregates) 

381 

382 expected_aggregate_names = ['aggr1', 'aggr2', 'aggr3'] 

383 self.assertEqual(sorted(expected_aggregate_names), sorted(result)) 

384 

385 def test_get_nodes_for_aggregates(self): 

386 

387 aggregate_names = ['aggr1', 'aggr2', 'aggr3'] 

388 aggregate_nodes = ['node1', 'node2', 'node2'] 

389 

390 mock_get_node_for_aggregate = self.mock_object( 

391 self.zapi_client, 'get_node_for_aggregate', 

392 mock.Mock(side_effect=aggregate_nodes)) 

393 

394 result = self.perf_library._get_nodes_for_aggregates(aggregate_names) 

395 

396 self.assertEqual(2, len(result)) 

397 result_node_names, result_aggr_node_map = result 

398 

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')]) 

406 

407 def test_get_node_utilization_kahuna_overutilized(self): 

408 

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)) 

415 

416 result = self.perf_library._get_node_utilization('fake1', 

417 'fake2', 

418 'fake_node') 

419 

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) 

423 

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): 

429 

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') 

447 

448 result = self.perf_library._get_node_utilization('fake1', 

449 'fake2', 

450 'fake_node') 

451 

452 expected = max(min(100.0, 100.0 * cpu), 0) 

453 self.assertEqual(expected, result) 

454 

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) 

466 

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): 

472 

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)) 

491 

492 result = self.perf_library._get_node_utilization('fake1', 

493 'fake2', 

494 'fake_node') 

495 

496 self.assertEqual(expected, result) 

497 

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) 

510 

511 def test_get_node_utilization_calculation_error(self): 

512 

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)) 

531 

532 result = self.perf_library._get_node_utilization('fake1', 

533 'fake2', 

534 'fake_node') 

535 

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)) 

539 

540 def test_get_kahuna_utilization(self): 

541 

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])) 

546 

547 result = self.perf_library._get_kahuna_utilization('fake_t1', 

548 'fake_t2') 

549 

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') 

554 

555 def test_get_average_cpu_utilization(self): 

556 

557 mock_get_performance_counter_average = self.mock_object( 

558 self.perf_library, '_get_performance_counter_average', 

559 mock.Mock(return_value=0.45)) 

560 

561 result = self.perf_library._get_average_cpu_utilization('fake_t1', 

562 'fake_t2') 

563 

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') 

567 

568 def test_get_total_consistency_point_time(self): 

569 

570 mock_get_performance_counter_delta = self.mock_object( 

571 self.perf_library, '_get_performance_counter_delta', 

572 mock.Mock(return_value=500)) 

573 

574 result = self.perf_library._get_total_consistency_point_time( 

575 'fake_t1', 'fake_t2') 

576 

577 self.assertEqual(500, result) 

578 mock_get_performance_counter_delta.assert_called_once_with( 

579 'fake_t1', 'fake_t2', 'total_cp_msecs') 

580 

581 def test_get_consistency_point_p2_flush_time(self): 

582 

583 mock_get_performance_counter_delta = self.mock_object( 

584 self.perf_library, '_get_performance_counter_delta', 

585 mock.Mock(return_value=500)) 

586 

587 result = self.perf_library._get_consistency_point_p2_flush_time( 

588 'fake_t1', 'fake_t2') 

589 

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') 

593 

594 def test_get_total_time(self): 

595 

596 mock_find_performance_counter_timestamp = self.mock_object( 

597 self.perf_library, '_find_performance_counter_timestamp', 

598 mock.Mock(side_effect=[100, 105])) 

599 

600 result = self.perf_library._get_total_time('fake_t1', 

601 'fake_t2', 

602 'fake_counter') 

603 

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')]) 

608 

609 def test_get_adjusted_consistency_point_time(self): 

610 

611 result = self.perf_library._get_adjusted_consistency_point_time( 

612 500, 200) 

613 

614 self.assertAlmostEqual(360.0, result) 

615 

616 def test_get_performance_counter_delta(self): 

617 

618 result = self.perf_library._get_performance_counter_delta( 

619 fake.COUNTERS_T1, fake.COUNTERS_T2, 'total_cp_msecs') 

620 

621 self.assertEqual(1482, result) 

622 

623 def test_get_performance_counter_average(self): 

624 

625 result = self.perf_library._get_performance_counter_average( 

626 fake.COUNTERS_T1, fake.COUNTERS_T2, 'domain_busy:kahuna', 

627 'processor_elapsed_time', 'processor0') 

628 

629 self.assertAlmostEqual(0.00281954360981, result) 

630 

631 def test_get_performance_counter_average_multi_instance(self): 

632 

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')) 

637 

638 expected = [0.002819543609809441, 0.0033421611147606135] 

639 self.assertAlmostEqual(expected, result) 

640 

641 def test_find_performance_counter_value(self): 

642 

643 result = self.perf_library._find_performance_counter_value( 

644 fake.COUNTERS_T1, 'domain_busy:kahuna', 

645 instance_name='processor0') 

646 

647 self.assertEqual('2712467226', result) 

648 

649 def test_find_performance_counter_value_not_found(self): 

650 

651 self.assertRaises( 

652 exception.NotFound, 

653 self.perf_library._find_performance_counter_value, 

654 fake.COUNTERS_T1, 'invalid', instance_name='processor0') 

655 

656 def test_find_performance_counter_timestamp(self): 

657 

658 result = self.perf_library._find_performance_counter_timestamp( 

659 fake.COUNTERS_T1, 'domain_busy') 

660 

661 self.assertEqual('1453573777', result) 

662 

663 def test_find_performance_counter_timestamp_not_found(self): 

664 

665 self.assertRaises( 

666 exception.NotFound, 

667 self.perf_library._find_performance_counter_timestamp, 

668 fake.COUNTERS_T1, 'invalid', instance_name='processor0') 

669 

670 def test_expand_performance_array(self): 

671 

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) 

678 

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) 

689 

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) 

702 

703 def test_get_base_counter_name(self): 

704 

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) 

712 

713 result = self.perf_library._get_base_counter_name( 

714 'system:constituent', 'avg_processor_busy') 

715 

716 self.assertEqual('cpu_elapsed_time', result) 

717 

718 def test_get_node_utilization_counters(self): 

719 

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'])) 

729 

730 result = self.perf_library._get_node_utilization_counters(fake.NODE) 

731 

732 expected = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'] 

733 self.assertEqual(expected, result) 

734 

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) 

741 

742 def test_get_node_utilization_counters_api_error(self): 

743 

744 self.mock_object(self.perf_library, 

745 '_get_node_utilization_system_counters', 

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

747 

748 result = self.perf_library._get_node_utilization_counters(fake.NODE) 

749 

750 self.assertIsNone(result) 

751 

752 def test_get_node_utilization_system_counters(self): 

753 

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)) 

760 

761 result = self.perf_library._get_node_utilization_system_counters( 

762 fake.NODE) 

763 

764 self.assertEqual(fake.SYSTEM_COUNTERS, result) 

765 

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']) 

771 

772 def test_get_node_utilization_wafl_counters(self): 

773 

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)) 

783 

784 result = self.perf_library._get_node_utilization_wafl_counters( 

785 fake.NODE) 

786 

787 self.assertEqual(fake.EXPANDED_WAFL_COUNTERS, result) 

788 

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') 

796 

797 def test_get_node_utilization_processor_counters(self): 

798 

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)) 

808 

809 result = self.perf_library._get_node_utilization_processor_counters( 

810 fake.NODE) 

811 

812 self.assertEqual(fake.EXPANDED_PROCESSOR_COUNTERS, result) 

813 

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'])