1 ##############################################################################
2 # Copyright (c) 2017 Rajesh Kudaka.
3 # Copyright (c) 2018-2019 Intel Corporation.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
16 from api.utils import influx
17 from yardstick.benchmark.core import report
18 from yardstick.cmd.commands import change_osloobj_to_paras
20 GOOD_YAML_NAME = 'fake_name'
21 GOOD_TASK_ID = str(uuid.uuid4())
22 GOOD_DB_FIELDKEYS = [{'fieldKey': 'fake_key'}]
25 'time': '0000-00-00T12:34:56.789012Z',
27 GOOD_TIMESTAMP = ['12:34:56.789012']
28 BAD_YAML_NAME = 'F@KE_NAME'
29 BAD_TASK_ID = 'aaaaaa-aaaaaaaa-aaaaaaaaaa-aaaaaa'
31 {'fieldKey': 'fake_key'},
32 {'fieldKey': 'str_str'},
33 {'fieldKey': u'str_unicode'},
34 {u'fieldKey': 'unicode_str'},
35 {u'fieldKey': u'unicode_unicode'},
39 'time': '0000-00-00T00:00:00.000000Z',
42 'time': '0000-00-00T00:00:01.000000Z',
45 'time': '0000-00-00T00:00:02.000000Z',
47 'fake_key': 9876543210987654321,
48 'time': '0000-00-00T00:00:03.000000Z',
50 'fake_key': 'str_str value',
51 'time': '0000-00-00T00:00:04.000000Z',
53 'fake_key': u'str_unicode value',
54 'time': '0000-00-00T00:00:05.000000Z',
56 u'fake_key': 'unicode_str value',
57 'time': '0000-00-00T00:00:06.000000Z',
59 u'fake_key': u'unicode_unicode value',
60 'time': '0000-00-00T00:00:07.000000Z',
63 'time': '0000-00-00T00:00:08.000000Z',
66 'time': '0000-00-00T00:00:09.000000Z',
68 'fake_key': '9876543210123456789',
69 'time': '0000-00-00T00:00:10.000000Z',
71 MORE_TIMESTAMP = ['00:00:%02d.000000' % n for n in range(len(MORE_DB_METRICS))]
72 MORE_EMPTY_DATA = [None] * len(MORE_DB_METRICS)
73 MORE_EXPECTED_TABLE_VALS = {
74 'Timestamp': MORE_TIMESTAMP,
79 9876543210987654321 if six.PY3 else 9.876543210987655e+18,
86 9876543210123456789 if six.PY3 else 9.876543210123457e+18,
88 'str_str': MORE_EMPTY_DATA,
89 'str_unicode': MORE_EMPTY_DATA,
90 'unicode_str': MORE_EMPTY_DATA,
91 'unicode_unicode': MORE_EMPTY_DATA,
93 MORE_EXPECTED_DATASETS = [{
95 'data': MORE_EXPECTED_TABLE_VALS[key],
97 for key in map(str, [field['fieldKey'] for field in MORE_DB_FIELDKEYS])
101 class JSTreeTestCase(unittest.TestCase):
104 self.jstree = report.JSTree()
106 def test__create_node(self):
107 _id = "tg__0.DropPackets"
110 {"id": "tg__0", "text": "tg__0", "parent": "#"},
111 {"id": "tg__0.DropPackets", "text": "DropPackets", "parent": "tg__0"}
113 self.jstree._create_node(_id)
115 self.assertEqual(self.jstree._created_nodes, ['#', 'tg__0', 'tg__0.DropPackets'])
116 self.assertEqual(self.jstree.jstree_data, expected_data)
118 def test_format_for_jstree(self):
121 'tg__0.LatencyAvg.5', 'tg__0.LatencyAvg.6',
122 'tg__0.LatencyMax.5', 'tg__0.LatencyMax.6',
123 'tg__0.RxThroughput', 'tg__0.TxThroughput',
125 'tg__1.LatencyAvg.5', 'tg__1.LatencyAvg.6',
126 'tg__1.LatencyMax.5', 'tg__1.LatencyMax.6',
127 'tg__1.RxThroughput', 'tg__1.TxThroughput',
128 'vnf__0.curr_packets_in', 'vnf__0.packets_dropped', 'vnf__0.packets_fwd',
132 {"id": "tg__0", "text": "tg__0", "parent": "#"},
133 {"id": "tg__0.DropPackets", "text": "DropPackets", "parent": "tg__0"},
134 {"id": "tg__0.LatencyAvg", "text": "LatencyAvg", "parent": "tg__0"},
135 {"id": "tg__0.LatencyAvg.5", "text": "5", "parent": "tg__0.LatencyAvg"},
136 {"id": "tg__0.LatencyAvg.6", "text": "6", "parent": "tg__0.LatencyAvg"},
137 {"id": "tg__0.LatencyMax", "text": "LatencyMax", "parent": "tg__0"},
138 {"id": "tg__0.LatencyMax.5", "text": "5", "parent": "tg__0.LatencyMax"},
139 {"id": "tg__0.LatencyMax.6", "text": "6", "parent": "tg__0.LatencyMax"},
140 {"id": "tg__0.RxThroughput", "text": "RxThroughput", "parent": "tg__0"},
141 {"id": "tg__0.TxThroughput", "text": "TxThroughput", "parent": "tg__0"},
142 {"id": "tg__1", "text": "tg__1", "parent": "#"},
143 {"id": "tg__1.DropPackets", "text": "DropPackets", "parent": "tg__1"},
144 {"id": "tg__1.LatencyAvg", "text": "LatencyAvg", "parent": "tg__1"},
145 {"id": "tg__1.LatencyAvg.5", "text": "5", "parent": "tg__1.LatencyAvg"},
146 {"id": "tg__1.LatencyAvg.6", "text": "6", "parent": "tg__1.LatencyAvg"},
147 {"id": "tg__1.LatencyMax", "text": "LatencyMax", "parent": "tg__1"},
148 {"id": "tg__1.LatencyMax.5", "text": "5", "parent": "tg__1.LatencyMax"},
149 {"id": "tg__1.LatencyMax.6", "text": "6", "parent": "tg__1.LatencyMax"},
150 {"id": "tg__1.RxThroughput", "text": "RxThroughput", "parent": "tg__1"},
151 {"id": "tg__1.TxThroughput", "text": "TxThroughput", "parent": "tg__1"},
152 {"id": "vnf__0", "text": "vnf__0", "parent": "#"},
153 {"id": "vnf__0.curr_packets_in", "text": "curr_packets_in", "parent": "vnf__0"},
154 {"id": "vnf__0.packets_dropped", "text": "packets_dropped", "parent": "vnf__0"},
155 {"id": "vnf__0.packets_fwd", "text": "packets_fwd", "parent": "vnf__0"},
158 result = self.jstree.format_for_jstree(data)
159 self.assertEqual(expected_output, result)
162 class ReportTestCase(unittest.TestCase):
165 super(ReportTestCase, self).setUp()
166 self.param = change_osloobj_to_paras({})
167 self.param.yaml_name = [GOOD_YAML_NAME]
168 self.param.task_id = [GOOD_TASK_ID]
169 self.rep = report.Report()
171 def test___init__(self):
172 self.assertEqual([], self.rep.Timestamp)
173 self.assertEqual("", self.rep.yaml_name)
174 self.assertEqual("", self.rep.task_id)
176 def test__validate(self):
177 self.rep._validate(GOOD_YAML_NAME, GOOD_TASK_ID)
178 self.assertEqual(GOOD_YAML_NAME, self.rep.yaml_name)
179 self.assertEqual(GOOD_TASK_ID, str(self.rep.task_id))
181 def test__validate_invalid_yaml_name(self):
182 with six.assertRaisesRegex(self, ValueError, "yaml*"):
183 self.rep._validate(BAD_YAML_NAME, GOOD_TASK_ID)
185 def test__validate_invalid_task_id(self):
186 with six.assertRaisesRegex(self, ValueError, "task*"):
187 self.rep._validate(GOOD_YAML_NAME, BAD_TASK_ID)
189 @mock.patch.object(influx, 'query')
190 def test__get_fieldkeys(self, mock_query):
191 mock_query.return_value = GOOD_DB_FIELDKEYS
192 self.rep.yaml_name = GOOD_YAML_NAME
193 self.rep.task_id = GOOD_TASK_ID
194 self.assertEqual(GOOD_DB_FIELDKEYS, self.rep._get_fieldkeys())
196 @mock.patch.object(influx, 'query')
197 def test__get_fieldkeys_nodbclient(self, mock_query):
198 mock_query.side_effect = RuntimeError
199 self.assertRaises(RuntimeError, self.rep._get_fieldkeys)
201 @mock.patch.object(influx, 'query')
202 def test__get_fieldkeys_testcase_not_found(self, mock_query):
203 mock_query.return_value = []
204 self.rep.yaml_name = GOOD_YAML_NAME
205 self.rep.task_id = GOOD_TASK_ID
206 six.assertRaisesRegex(self, KeyError, "Test case", self.rep._get_fieldkeys)
208 @mock.patch.object(influx, 'query')
209 def test__get_metrics(self, mock_query):
210 mock_query.return_value = GOOD_DB_METRICS
211 self.rep.yaml_name = GOOD_YAML_NAME
212 self.rep.task_id = GOOD_TASK_ID
213 self.assertEqual(GOOD_DB_METRICS, self.rep._get_metrics())
215 @mock.patch.object(influx, 'query')
216 def test__get_metrics_task_not_found(self, mock_query):
217 mock_query.return_value = []
218 self.rep.yaml_name = GOOD_YAML_NAME
219 self.rep.task_id = GOOD_TASK_ID
220 six.assertRaisesRegex(self, KeyError, "Task ID", self.rep._get_metrics)
222 @mock.patch.object(influx, 'query')
223 def test__get_task_start_time(self, mock_query):
224 self.rep.yaml_name = GOOD_YAML_NAME
225 self.rep.task_id = GOOD_TASK_ID
226 mock_query.return_value = [{
227 u'free.memory0.used': u'9789088',
228 u'free.memory0.available': u'22192984',
229 u'free.memory0.shared': u'219152',
230 u'time': u'2019-01-22T16:20:14.568075776Z',
232 expected = "2019-01-22T16:20:14.568075776Z"
236 self.rep._get_task_start_time()
239 def test__get_task_start_time_task_not_found(self):
242 @mock.patch.object(influx, 'query')
243 def test__get_task_end_time(self, mock_query):
244 self.rep.yaml_name = GOOD_YAML_NAME
245 self.rep.task_id = GOOD_TASK_ID
246 # TODO(elfoley): write this test!
247 mock_query.return_value = [{
251 @mock.patch.object(influx, 'query')
252 def test__get_baro_metrics(self, mock_query):
253 self.rep.yaml_name = GOOD_YAML_NAME
254 self.rep.task_id = GOOD_TASK_ID
255 self.rep._get_task_start_time = mock.Mock(return_value=0)
256 self.rep._get_task_end_time = mock.Mock(return_value=0)
258 influx_return_values = ([{
259 u'value': 324050, u'instance': u'0', u'host': u'myhostname',
260 u'time': u'2018-12-19T14:11:25.383698038Z',
261 u'type_instance': u'user', u'type': u'cpu',
263 u'value': 193798, u'instance': u'0', u'host': u'myhostname',
264 u'time': u'2018-12-19T14:11:25.383712594Z',
265 u'type_instance': u'system', u'type': u'cpu',
267 u'value': 324051, u'instance': u'0', u'host': u'myhostname',
268 u'time': u'2018-12-19T14:11:35.383696624Z',
269 u'type_instance': u'user', u'type': u'cpu',
271 u'value': 193800, u'instance': u'0', u'host': u'myhostname',
272 u'time': u'2018-12-19T14:11:35.383713481Z',
273 u'type_instance': u'system', u'type': u'cpu',
275 u'value': 324054, u'instance': u'0', u'host': u'myhostname',
276 u'time': u'2018-12-19T14:11:45.3836966789Z',
277 u'type_instance': u'user', u'type': u'cpu',
279 u'value': 193801, u'instance': u'0', u'host': u'myhostname',
280 u'time': u'2018-12-19T14:11:45.383716296Z',
281 u'type_instance': u'system', u'type': u'cpu',
284 u'value': 3598453000, u'host': u'myhostname',
285 u'time': u'2018-12-19T14:11:25.383698038Z',
286 u'type_instance': u'0', u'type': u'cpufreq',
288 u'value': 3530250000, u'type_instance': u'0', u'host': u'myhostname',
289 u'time': u'2018-12-19T14:11:35.383712594Z', u'type': u'cpufreq',
291 u'value': 3600281000, u'type_instance': u'0', u'host': u'myhostname',
292 u'time': u'2018-12-19T14:11:45.383696624Z', u'type': u'cpufreq',
302 mock_query.side_effect = ret_vals(influx_return_values)
304 BARO_EXPECTED_METRICS = {
306 '14:11:25.3836', '14:11:25.3837',
307 '14:11:35.3836', '14:11:35.3837',
308 '14:11:45.3836', '14:11:45.3837'],
309 'myhostname.cpu_value.cpu.user.0': {
310 '14:11:25.3836': 324050,
311 '14:11:35.3836': 324051,
312 '14:11:45.3836': 324054,
314 'myhostname.cpu_value.cpu.system.0': {
315 '14:11:25.3837': 193798,
316 '14:11:35.3837': 193800,
317 '14:11:45.3837': 193801,
319 'myhostname.cpufreq_value.cpufreq.0': {
320 '14:11:25.3836': 3598453000,
321 '14:11:35.3837': 3530250000,
322 '14:11:45.3836': 3600281000,
326 BARO_EXPECTED_METRICS,
327 self.rep._get_baro_metrics()
330 def test__get_timestamps(self):
332 metrics = MORE_DB_METRICS
335 self.rep._get_timestamps(metrics)
338 def test__format_datasets(self):
339 metric_name = "free.memory0.used"
341 u'free.memory1.free': u'1958664',
342 u'free.memory0.used': u'9789560',
344 u'free.memory1.free': u'1958228',
345 u'free.memory0.used': u'9789790',
347 u'free.memory1.free': u'1956156',
348 u'free.memory0.used': u'9791092',
350 u'free.memory1.free': u'1956280',
351 u'free.memory0.used': u'9790796',
354 [9789560, 9789790, 9791092, 9790796,],
355 self.rep._format_datasets(metric_name, metrics)
358 def test__format_datasets_val_none(self):
359 metric_name = "free.memory0.used"
361 u'free.memory1.free': u'1958664',
362 u'free.memory0.used': 9876543109876543210,
364 u'free.memory1.free': u'1958228',
366 u'free.memory1.free': u'1956156',
367 u'free.memory0.used': u'9791092',
369 u'free.memory1.free': u'1956280',
370 u'free.memory0.used': u'9790796',
373 exp0 = 9876543109876543210 if six.PY3 else 9.876543109876543e+18
375 [exp0, None, 9791092, 9790796],
376 self.rep._format_datasets(metric_name, metrics)
379 def test__format_datasets_val_incompatible(self):
380 metric_name = "free.memory0.used"
382 u'free.memory0.used': "some incompatible value",
387 self.rep._format_datasets(metric_name, metrics)
390 def test__combine_times(self):
421 actual_combo = self.rep._combine_times(yard_times, baro_times)
422 self.assertEqual(len(expected_combo), len(actual_combo))
429 def test__combine_times_2(self):
430 time1 = ['14:11:25.383698', '14:11:25.383712', '14:11:35.383696',]
432 '16:20:14.568075', '16:20:24.575083',
433 '16:20:34.580989', '16:20:44.586801', ]
435 '14:11:25.383698', '14:11:25.383712', '14:11:35.383696',
436 '16:20:14.568075', '16:20:24.575083', '16:20:34.580989',
439 self.assertEqual(time_exp, self.rep._combine_times(time1, time2))
441 def test__combine_metrics(self):
443 'myhostname.cpu_value.cpu.user.0': {
444 '14:11:25.3836': 324050, '14:11:35.3836': 324051,
445 '14:11:45.3836': 324054,
447 'myhostname.cpu_value.cpu.system.0': {
448 '14:11:25.3837': 193798, '14:11:35.3837': 193800,
449 '14:11:45.3837': 193801,
453 '14:11:25.3836', '14:11:25.3837', '14:11:35.3836',
454 '14:11:35.3837', '14:11:45.3836', '14:11:45.3837',
457 'free.memory9.free': {
458 '16:20:14.5680': 1958244, '16:20:24.5750': 1955964,
459 '16:20:34.5809': 1956040, '16:20:44.5868': 1956428,
461 'free.memory7.used': {
462 '16:20:14.5680': 9789068, '16:20:24.5750': 9791284,
463 '16:20:34.5809': 9791228, '16:20:44.5868': 9790692,
465 'free.memory2.total':{
466 '16:20:14.5680': 32671288, '16:20:24.5750': 32671288,
467 '16:20:34.5809': 32671288, '16:20:44.5868': 32671288,
469 'free.memory7.free': {
470 '16:20:14.5680': 1958368, '16:20:24.5750': 1956104,
471 '16:20:34.5809': 1956040, '16:20:44.5868': 1956552,
473 'free.memory1.used': {
474 '16:20:14.5680': 9788872, '16:20:24.5750': 9789212,
475 '16:20:34.5809': 9791168, '16:20:44.5868': 9790996,
479 '16:20:14.5680', '16:20:24.5750',
480 '16:20:34.5809', '16:20:44.5868',
484 'myhostname.cpu_value.cpu.user.0': [{
485 'x': '14:11:25.3836', 'y': 324050, }, {
486 'x': '14:11:35.3836', 'y': 324051, }, {
487 'x': '14:11:45.3836', 'y': 324054, }],
488 'myhostname.cpu_value.cpu.system.0' : [{
489 'x': '14:11:25.3837', 'y': 193798, }, {
490 'x': '14:11:35.3837', 'y': 193800, }, {
491 'x': '14:11:45.3837', 'y': 193801, }],
492 'free.memory9.free': [{
493 'x': '16:20:14.5680', 'y': 1958244, }, {
494 'x': '16:20:24.5750', 'y': 1955964, }, {
495 'x': '16:20:34.5809', 'y': 1956040, }, {
496 'x': '16:20:44.5868', 'y': 1956428, }],
497 'free.memory7.used': [{
498 'x': '16:20:14.5680', 'y': 9789068, }, {
499 'x': '16:20:24.5750', 'y': 9791284, }, {
500 'x': '16:20:34.5809', 'y': 9791228, }, {
501 'x': '16:20:44.5868', 'y': 9790692, }],
502 'free.memory2.total': [{
503 'x': '16:20:14.5680', 'y': 32671288, }, {
504 'x': '16:20:24.5750', 'y': 32671288, }, {
505 'x': '16:20:34.5809', 'y': 32671288, }, {
506 'x': '16:20:44.5868', 'y': 32671288, }],
507 'free.memory7.free': [{
508 'x': '16:20:14.5680', 'y': 1958368, }, {
509 'x': '16:20:24.5750', 'y': 1956104, }, {
510 'x': '16:20:34.5809', 'y': 1956040, }, {
511 'x': '16:20:44.5868', 'y': 1956552, }],
512 'free.memory1.used': [{
513 'x': '16:20:14.5680', 'y': 9788872, }, {
514 'x': '16:20:24.5750', 'y': 9789212, }, {
515 'x': '16:20:34.5809', 'y': 9791168, }, {
516 'x': '16:20:44.5868', 'y': 9790996, }],
519 actual_output, _, _ = self.rep._combine_metrics(
520 BARO_METRICS, BARO_TIMES, YARD_METRICS, YARD_TIMES
523 sorted(expected_output.keys()),
524 sorted(actual_output.keys())
532 @mock.patch.object(report.Report, '_get_metrics')
533 @mock.patch.object(report.Report, '_get_fieldkeys')
534 def test__generate_common(self, mock_keys, mock_metrics):
535 mock_metrics.return_value = MORE_DB_METRICS
536 mock_keys.return_value = MORE_DB_FIELDKEYS
537 datasets, table_vals = self.rep._generate_common(self.param)
538 self.assertEqual(MORE_EXPECTED_DATASETS, datasets)
539 self.assertEqual(MORE_EXPECTED_TABLE_VALS, table_vals)
541 @mock.patch.object(report.Report, '_get_metrics')
542 @mock.patch.object(report.Report, '_get_fieldkeys')
543 @mock.patch.object(report.Report, '_validate')
544 def test_generate(self, mock_valid, mock_keys, mock_metrics):
545 mock_metrics.return_value = GOOD_DB_METRICS
546 mock_keys.return_value = GOOD_DB_FIELDKEYS
547 self.rep.generate(self.param)
548 mock_valid.assert_called_once_with(GOOD_YAML_NAME, GOOD_TASK_ID)
549 mock_metrics.assert_called_once_with()
550 mock_keys.assert_called_once_with()
551 self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp)
553 @mock.patch.object(report.Report, '_get_baro_metrics')
554 @mock.patch.object(report.Report, '_get_metrics')
555 @mock.patch.object(report.Report, '_get_fieldkeys')
556 @mock.patch.object(report.Report, '_validate')
557 def test_generate_nsb(
558 self, mock_valid, mock_keys, mock_metrics, mock_baro_metrics):
560 mock_metrics.return_value = GOOD_DB_METRICS
561 mock_keys.return_value = GOOD_DB_FIELDKEYS
563 # TODO: is timestamp needed here?
565 '14:11:25.383698', '14:11:25.383712', '14:11:35.383696',
566 '14:11:35.383713', '14:11:45.383700', '14:11:45.383716'],
567 'myhostname.cpu_value.cpu.user.0': {
568 '14:11:25.383698': 324050,
569 '14:11:35.383696': 324051,
570 '14:11:45.383700': 324054,
572 'myhostname.cpu_value.cpu.system.0': {
573 '14:11:25.383712': 193798,
574 '14:11:35.383713': 193800,
575 '14:11:45.383716': 193801,
578 mock_baro_metrics.return_value = BARO_METRICS
580 self.rep.generate_nsb(self.param)
581 mock_valid.assert_called_once_with(GOOD_YAML_NAME, GOOD_TASK_ID)
582 mock_metrics.assert_called_once_with()
583 mock_keys.assert_called_once_with()
584 self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp)