X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Ftools%2Fpresentation%2Fgenerator_tables.py;h=3ad1e3c75680d116df8bb926494ca39716e4cd3d;hp=fccfd9299a520349ced250e025f53bd000680a4f;hb=6c3d971c8b529d094f7c7355e685ea5ab63904e5;hpb=dadb06ada83c7f25f9cf884d54d3a30fad979b29 diff --git a/resources/tools/presentation/generator_tables.py b/resources/tools/presentation/generator_tables.py index fccfd9299a..3ad1e3c756 100644 --- a/resources/tools/presentation/generator_tables.py +++ b/resources/tools/presentation/generator_tables.py @@ -17,17 +17,22 @@ import logging import csv +import re from string import replace from collections import OrderedDict from numpy import nan, isnan from xml.etree import ElementTree as ET +from datetime import datetime as dt +from datetime import timedelta -from errors import PresentationError from utils import mean, stdev, relative_change, classify_anomalies, \ convert_csv_to_pretty_txt +REGEX_NIC = re.compile(r'\d*ge\dp\d\D*\d*') + + def generate_tables(spec, data): """Generate all tables specified in the specification file. @@ -237,10 +242,18 @@ def table_performance_comparison(table, input_data): replace("1t1c", "1c").replace("2t1c", "1c").\ replace("2t2c", "2c").replace("4t2c", "2c").\ replace("4t4c", "4c").replace("8t4c", "4c") + if "across topologies" in table["title"].lower(): + tst_name_mod = tst_name_mod.replace("2n1l-", "") if tbl_dict.get(tst_name_mod, None) is None: name = "{0}-{1}".format(tst_data["parent"].split("-")[0], "-".join(tst_data["name"]. split("-")[:-1])) + if "across testbeds" in table["title"].lower() or \ + "across topologies" in table["title"].lower(): + name = name.\ + replace("1t1c", "1c").replace("2t1c", "1c").\ + replace("2t2c", "2c").replace("4t2c", "2c").\ + replace("4t4c", "4c").replace("8t4c", "4c") tbl_dict[tst_name_mod] = {"name": name, "ref-data": list(), "cmp-data": list()} @@ -278,6 +291,8 @@ def table_performance_comparison(table, input_data): replace("1t1c", "1c").replace("2t1c", "1c").\ replace("2t2c", "2c").replace("4t2c", "2c").\ replace("4t4c", "4c").replace("8t4c", "4c") + if "across topologies" in table["title"].lower(): + tst_name_mod = tst_name_mod.replace("2n1l-", "") try: # TODO: Re-work when NDRPDRDISC tests are not used if table["include-tests"] == "MRR": @@ -315,6 +330,8 @@ def table_performance_comparison(table, input_data): replace("1t1c", "1c").replace("2t1c", "1c").\ replace("2t2c", "2c").replace("4t2c", "2c").\ replace("4t4c", "4c").replace("8t4c", "4c") + if "across topologies" in table["title"].lower(): + tst_name_mod = tst_name_mod.replace("2n1l-", "") if tbl_dict.get(tst_name_mod, None) is None: continue if tbl_dict[tst_name_mod].get("history", None) is None: @@ -432,10 +449,13 @@ def table_performance_trending_dashboard(table, input_data): if tst_name.lower() in table["ignore-list"]: continue if tbl_dict.get(tst_name, None) is None: - name = "{0}-{1}".format(tst_data["parent"].split("-")[0], - tst_data["name"]) - tbl_dict[tst_name] = {"name": name, - "data": OrderedDict()} + groups = re.search(REGEX_NIC, tst_data["parent"]) + if not groups: + continue + nic = groups.group(0) + tbl_dict[tst_name] = { + "name": "{0}-{1}".format(nic, tst_data["name"]), + "data": OrderedDict()} try: tbl_dict[tst_name]["data"][str(build)] = \ tst_data["result"]["receive-rate"] @@ -477,12 +497,15 @@ def table_performance_trending_dashboard(table, input_data): if classification_lst: if isnan(rel_change_last) and isnan(rel_change_long): continue + if (isnan(last_avg) or + isnan(rel_change_last) or + isnan(rel_change_long)): + continue tbl_lst.append( [tbl_dict[tst_name]["name"], - '-' if isnan(last_avg) else round(last_avg / 1000000, 2), - '-' if isnan(rel_change_last) else rel_change_last, - '-' if isnan(rel_change_long) else rel_change_long, + rel_change_last, + rel_change_long, classification_lst[-win_size:].count("regression"), classification_lst[-win_size:].count("progression")]) @@ -509,12 +532,14 @@ def table_performance_trending_dashboard(table, input_data): convert_csv_to_pretty_txt(file_name, txt_file_name) -def _generate_url(base, test_name): +def _generate_url(base, testbed, test_name): """Generate URL to a trending plot from the name of the test case. :param base: The base part of URL common to all test cases. + :param testbed: The testbed used for testing. :param test_name: The name of the test case. :type base: str + :type testbed: str :type test_name: str :returns: The URL to the plot with the trending data for the given test case. @@ -523,65 +548,105 @@ def _generate_url(base, test_name): url = base file_name = "" - anchor = "#" + anchor = ".html#" feature = "" if "lbdpdk" in test_name or "lbvpp" in test_name: - file_name = "link_bonding.html" + file_name = "link_bonding" + + elif "114b" in test_name and "vhost" in test_name: + file_name = "vts" elif "testpmd" in test_name or "l3fwd" in test_name: - file_name = "dpdk.html" + file_name = "dpdk" elif "memif" in test_name: - file_name = "container_memif.html" + file_name = "container_memif" + feature = "-base" elif "srv6" in test_name: - file_name = "srv6.html" + file_name = "srv6" elif "vhost" in test_name: if "l2xcbase" in test_name or "l2bdbasemaclrn" in test_name: - file_name = "vm_vhost_l2.html" + file_name = "vm_vhost_l2" + if "114b" in test_name: + feature = "" + elif "l2xcbase" in test_name: + feature = "-base-l2xc" + elif "l2bdbasemaclrn" in test_name: + feature = "-base-l2bd" + else: + feature = "-base" elif "ip4base" in test_name: - file_name = "vm_vhost_ip4.html" + file_name = "vm_vhost_ip4" + feature = "-base" elif "ipsec" in test_name: - file_name = "ipsec.html" + file_name = "ipsec" + feature = "-base-scale" elif "ethip4lispip" in test_name or "ethip4vxlan" in test_name: - file_name = "ip4_tunnels.html" + file_name = "ip4_tunnels" + feature = "-base" elif "ip4base" in test_name or "ip4scale" in test_name: - file_name = "ip4.html" - if "iacl" in test_name or "snat" in test_name or "cop" in test_name: + file_name = "ip4" + if "xl710" in test_name: + feature = "-base-scale-features" + elif "iacl" in test_name: + feature = "-features-iacl" + elif "oacl" in test_name: + feature = "-features-oacl" + elif "snat" in test_name or "cop" in test_name: feature = "-features" + else: + feature = "-base-scale" elif "ip6base" in test_name or "ip6scale" in test_name: - file_name = "ip6.html" + file_name = "ip6" + feature = "-base-scale" elif "l2xcbase" in test_name or "l2xcscale" in test_name \ or "l2bdbasemaclrn" in test_name or "l2bdscale" in test_name \ or "l2dbbasemaclrn" in test_name or "l2dbscale" in test_name: - file_name = "l2.html" - if "iacl" in test_name: - feature = "-features" + file_name = "l2" + if "macip" in test_name: + feature = "-features-macip" + elif "iacl" in test_name: + feature = "-features-iacl" + elif "oacl" in test_name: + feature = "-features-oacl" + else: + feature = "-base-scale" if "x520" in test_name: - anchor += "x520-" + nic = "x520-" elif "x710" in test_name: - anchor += "x710-" + nic = "x710-" elif "xl710" in test_name: - anchor += "xl710-" + nic = "xl710-" + elif "xxv710" in test_name: + nic = "xxv710-" + else: + nic = "" + anchor += nic if "64b" in test_name: - anchor += "64b-" + framesize = "64b" elif "78b" in test_name: - anchor += "78b-" + framesize = "78b" elif "imix" in test_name: - anchor += "imix-" + framesize = "imix" elif "9000b" in test_name: - anchor += "9000b-" - elif "1518" in test_name: - anchor += "1518b-" + framesize = "9000b" + elif "1518b" in test_name: + framesize = "1518b" + elif "114b" in test_name: + framesize = "114b" + else: + framesize = "" + anchor += framesize + '-' if "1t1c" in test_name: anchor += "1t1c" @@ -589,8 +654,15 @@ def _generate_url(base, test_name): anchor += "2t2c" elif "4t4c" in test_name: anchor += "4t4c" + elif "2t1c" in test_name: + anchor += "2t1c" + elif "4t2c" in test_name: + anchor += "4t2c" + elif "8t4c" in test_name: + anchor += "8t4c" - return url + file_name + anchor + feature + return url + file_name + '-' + testbed + '-' + nic + framesize + feature + \ + anchor + feature def table_performance_trending_dashboard_html(table, input_data): @@ -600,10 +672,16 @@ def table_performance_trending_dashboard_html(table, input_data): :param table: Table to generate. :param input_data: Data to process. - :type table: pandas.Series + :type table: dict :type input_data: InputData """ + testbed = table.get("testbed", None) + if testbed is None: + logging.error("The testbed is not defined for the table '{0}'.". + format(table.get("title", ""))) + return + logging.info(" Generating the table {0} ...". format(table.get("title", ""))) @@ -649,7 +727,7 @@ def table_performance_trending_dashboard_html(table, input_data): td = ET.SubElement(tr, "td", attrib=dict(align=alignment)) # Name: if c_idx == 0: - url = _generate_url("../trending/", item) + url = _generate_url("../trending/", testbed, item) ref = ET.SubElement(td, "a", attrib=dict(href=url)) ref.text = item else: @@ -692,6 +770,10 @@ def table_failed_tests(table, input_data): # Generate the data for the table according to the model in the table # specification + + now = dt.utcnow() + timeperiod = timedelta(int(table.get("window", 7))) + tbl_dict = dict() for job, builds in table["data"].items(): for build in builds: @@ -700,30 +782,41 @@ def table_failed_tests(table, input_data): if tst_name.lower() in table["ignore-list"]: continue if tbl_dict.get(tst_name, None) is None: - name = "{0}-{1}".format(tst_data["parent"].split("-")[0], - tst_data["name"]) - tbl_dict[tst_name] = {"name": name, - "data": OrderedDict()} + groups = re.search(REGEX_NIC, tst_data["parent"]) + if not groups: + continue + nic = groups.group(0) + tbl_dict[tst_name] = { + "name": "{0}-{1}".format(nic, tst_data["name"]), + "data": OrderedDict()} try: - tbl_dict[tst_name]["data"][build] = ( - tst_data["status"], - input_data.metadata(job, build).get("generated", ""), - input_data.metadata(job, build).get("version", ""), - build) - except (TypeError, KeyError): - pass # No data in output.xml for this test - + generated = input_data.metadata(job, build).\ + get("generated", "") + if not generated: + continue + then = dt.strptime(generated, "%Y%m%d %H:%M") + if (now - then) <= timeperiod: + tbl_dict[tst_name]["data"][build] = ( + tst_data["status"], + generated, + input_data.metadata(job, build).get("version", ""), + build) + except (TypeError, KeyError) as err: + logging.warning("tst_name: {} - err: {}". + format(tst_name, repr(err))) + + max_fails = 0 tbl_lst = list() for tst_data in tbl_dict.values(): - win_size = min(len(tst_data["data"]), table["window"]) fails_nr = 0 - for val in tst_data["data"].values()[-win_size:]: + for val in tst_data["data"].values(): if val[0] == "FAIL": fails_nr += 1 fails_last_date = val[1] fails_last_vpp = val[2] fails_last_csit = val[3] if fails_nr: + max_fails = fails_nr if fails_nr > max_fails else max_fails tbl_lst.append([tst_data["name"], fails_nr, fails_last_date, @@ -732,7 +825,7 @@ def table_failed_tests(table, input_data): tbl_lst.sort(key=lambda rel: rel[2], reverse=True) tbl_sorted = list() - for nrf in range(table["window"], -1, -1): + for nrf in range(max_fails, -1, -1): tbl_fails = [item for item in tbl_lst if item[1] == nrf] tbl_sorted.extend(tbl_fails) file_name = "{0}{1}".format(table["output-file"], table["output-file-ext"]) @@ -758,6 +851,12 @@ def table_failed_tests_html(table, input_data): :type input_data: InputData """ + testbed = table.get("testbed", None) + if testbed is None: + logging.error("The testbed is not defined for the table '{0}'.". + format(table.get("title", ""))) + return + logging.info(" Generating the table {0} ...". format(table.get("title", ""))) @@ -795,7 +894,7 @@ def table_failed_tests_html(table, input_data): td = ET.SubElement(tr, "td", attrib=dict(align=alignment)) # Name: if c_idx == 0: - url = _generate_url("../trending/", item) + url = _generate_url("../trending/", testbed, item) ref = ET.SubElement(td, "a", attrib=dict(href=url)) ref.text = item else: