-# Copyright (c) 2021 Cisco and/or its affiliates.
+# Copyright (c) 2022 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
"""Generation of Continuous Performance Trending and Analysis.
"""
-
import re
import logging
import csv
from collections import OrderedDict
from datetime import datetime
from copy import deepcopy
+from os import listdir
import prettytable
import plotly.offline as ploff
else:
hover_str = hover_str.replace(u"<stdev>", u"")
if incl_tests == u"pdr-lat":
- hover_str = hover_str.replace(
- u"throughput [Mpps]", u"latency [s]"
- )
hover_str = hover_str.replace(u"<val>", u"{value:.1e}")
else:
hover_str = hover_str.replace(u"<val>", u"{value:.3f}")
if u"-cps" in name:
hover_str = hover_str.replace(u"[Mpps]", u"[Mcps]").\
replace(u"throughput", u"connection rate")
- if u"dpdk" in job_name:
- hover_text.append(hover_str.format(
+ if u"vpp" in job_name:
+ hover_str = hover_str.format(
+ date=date,
+ property=u"average" if incl_tests == u"mrr" else u"throughput",
+ value=data_y_mpps[index],
+ sut=u"vpp",
+ build=build_info[job_name][str_key][1].rsplit(u'~', 1)[0],
+ test=incl_tests,
+ period=u"daily" if incl_tests == u"mrr" else u"weekly",
+ build_nr=str_key,
+ testbed=build_info[job_name][str_key][2])
+ elif u"dpdk" in job_name:
+ hover_str = hover_str.format(
date=date,
property=u"average" if incl_tests == u"mrr" else u"throughput",
value=data_y_mpps[index],
test=incl_tests,
period=u"weekly",
build_nr=str_key,
- testbed=build_info[job_name][str_key][2]))
- elif u"vpp" in job_name:
- hover_text.append(hover_str.format(
+ testbed=build_info[job_name][str_key][2])
+ elif u"trex" in job_name:
+ hover_str = hover_str.format(
date=date,
property=u"average" if incl_tests == u"mrr" else u"throughput",
value=data_y_mpps[index],
- sut=u"vpp",
- build=build_info[job_name][str_key][1].rsplit(u'~', 1)[0],
+ sut=u"trex",
+ build=u"",
test=incl_tests,
period=u"daily" if incl_tests == u"mrr" else u"weekly",
build_nr=str_key,
- testbed=build_info[job_name][str_key][2]))
-
+ testbed=build_info[job_name][str_key][2])
+ if incl_tests == u"pdr-lat":
+ hover_str = hover_str.replace(
+ u"throughput [Mpps]", u"latency [s]"
+ )
+ hover_text.append(hover_str)
xaxis.append(datetime(int(date[0:4]), int(date[4:6]), int(date[6:8]),
int(date[9:11]), int(date[12:])))
# Evaluate result:
if anomaly_classifications:
result = u"PASS"
+
+ class MaxLens:
+ """Class to store the max lengths of strings displayed in
+ regressions and progressions.
+ """
+
+ def __init__(self, tst, nic, frmsize, trend, run, ltc):
+ """Initialisation.
+
+ :param tst: Name of the test.
+ :param nic: NIC used in the test.
+ :param frmsize: Frame size used in the test.
+ :param trend: Trend Change.
+ :param run: Number of runs for last trend.
+ :param ltc: Regression or Progression
+ """
+ self.tst = tst
+ self.nic = nic
+ self.frmsize = frmsize
+ self.trend = trend
+ self.run = run
+ self.ltc = ltc
+
for job_name, job_data in anomaly_classifications.items():
+ data = []
+ test_reg_lst = []
+ nic_reg_lst = []
+ frmsize_reg_lst = []
+ trend_reg_lst = []
+ number_reg_lst = []
+ ltc_reg_lst = []
+ test_prog_lst = []
+ nic_prog_lst = []
+ frmsize_prog_lst = []
+ trend_prog_lst = []
+ number_prog_lst = []
+ ltc_prog_lst = []
+ max_len = MaxLens(0, 0, 0, 0, 0, 0)
+
+ # tb - testbed (2n-skx, 3n-dnv, etc)
+ tb = u"-".join(job_name.split(u"-")[-2:])
+ # data - read all txt dashboard files for tb
+ for file in listdir(f"{spec.cpta[u'output-file']}"):
+ if tb in file and u"performance-trending-dashboard" in \
+ file and u"txt" in file:
+ file_to_read = f"{spec.cpta[u'output-file']}/{file}"
+ with open(f"{file_to_read}", u"rt") as f_in:
+ data = data + f_in.readlines()
+
+ for test_name, classification in job_data.items():
+ if classification != u"normal":
+ if u"2n" in test_name:
+ test_name = test_name.split("-", 2)
+ tst = test_name[2].split(".")[-1]
+ nic = test_name[1]
+ else:
+ test_name = test_name.split("-", 1)
+ tst = test_name[1].split(".")[-1]
+ nic = test_name[0].split(".")[-1]
+ frmsize = tst.split("-")[0]
+ tst = u"-".join(tst.split("-")[1:])
+ tst_name = f"{nic}-{frmsize}-{tst}"
+ if len(tst) > max_len.tst:
+ max_len.tst = len(tst)
+ if len(nic) > max_len.nic:
+ max_len.nic = len(nic)
+ if len(frmsize) > max_len.frmsize:
+ max_len.frmsize = len(frmsize)
+
+ for line in data:
+ if tst_name in line:
+ line = line.replace(" ", "")
+ trend = line.split("|")[2]
+ if len(str(trend)) > max_len.trend:
+ max_len.trend = len(str(trend))
+ number = line.split("|")[3]
+ if len(str(number)) > max_len.run:
+ max_len.run = len(str(number))
+ ltc = line.split("|")[4]
+ if len(str(ltc)) > max_len.ltc:
+ max_len.ltc = len(str(ltc))
+ if classification == u'regression':
+ test_reg_lst.append(tst)
+ nic_reg_lst.append(nic)
+ frmsize_reg_lst.append(frmsize)
+ trend_reg_lst.append(trend)
+ number_reg_lst.append(number)
+ ltc_reg_lst.append(ltc)
+ elif classification == u'progression':
+ test_prog_lst.append(tst)
+ nic_prog_lst.append(nic)
+ frmsize_prog_lst.append(frmsize)
+ trend_prog_lst.append(trend)
+ number_prog_lst.append(number)
+ ltc_prog_lst.append(ltc)
+
+ text = u""
+ for idx in range(len(test_reg_lst)):
+ text += (
+ f"{test_reg_lst[idx]}"
+ f"{u' ' * (max_len.tst - len(test_reg_lst[idx]))} "
+ f"{nic_reg_lst[idx]}"
+ f"{u' ' * (max_len.nic - len(nic_reg_lst[idx]))} "
+ f"{frmsize_reg_lst[idx].upper()}"
+ f"{u' ' * (max_len.frmsize - len(frmsize_reg_lst[idx]))} "
+ f"{trend_reg_lst[idx]}"
+ f"{u' ' * (max_len.trend - len(str(trend_reg_lst[idx])))} "
+ f"{number_reg_lst[idx]}"
+ f"{u' ' * (max_len.run - len(str(number_reg_lst[idx])))} "
+ f"{ltc_reg_lst[idx]}"
+ f"{u' ' * (max_len.ltc - len(str(ltc_reg_lst[idx])))} "
+ f"\n"
+ )
+
file_name = \
f"{spec.cpta[u'output-file']}/regressions-{job_name}.txt"
- with open(file_name, u'w') as txt_file:
- for test_name, classification in job_data.items():
- if classification == u"regression":
- txt_file.write(test_name + u'\n')
- if classification in (u"regression", u"outlier"):
- result = u"FAIL"
+
+ try:
+ with open(f"{file_name}", u'w') as txt_file:
+ txt_file.write(text)
+ except IOError:
+ logging.error(
+ f"Not possible to write the file {file_name}.")
+
+ text = u""
+ for idx in range(len(test_prog_lst)):
+ text += (
+ f"{test_prog_lst[idx]}"
+ f"{u' ' * (max_len.tst - len(test_prog_lst[idx]))} "
+ f"{nic_prog_lst[idx]}"
+ f"{u' ' * (max_len.nic - len(nic_prog_lst[idx]))} "
+ f"{frmsize_prog_lst[idx].upper()}"
+ f"{u' ' * (max_len.frmsize - len(frmsize_prog_lst[idx]))} "
+ f"{trend_prog_lst[idx]}"
+ f"{u' ' * (max_len.trend -len(str(trend_prog_lst[idx])))} "
+ f"{number_prog_lst[idx]}"
+ f"{u' ' * (max_len.run - len(str(number_prog_lst[idx])))} "
+ f"{ltc_prog_lst[idx]}"
+ f"{u' ' * (max_len.ltc - len(str(ltc_prog_lst[idx])))} "
+ f"\n"
+ )
+
file_name = \
f"{spec.cpta[u'output-file']}/progressions-{job_name}.txt"
- with open(file_name, u'w') as txt_file:
- for test_name, classification in job_data.items():
- if classification == u"progression":
- txt_file.write(test_name + u'\n')
+ try:
+ with open(f"{file_name}", u'w') as txt_file:
+ txt_file.write(text)
+ except IOError:
+ logging.error(f"Not possible to write the file {file_name}.")
+
else:
result = u"FAIL"