X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Ftools%2Fpresentation%2Fgenerator_tables.py;h=2d4f87fc95617a6d7cdbeb5c47dd265239739075;hp=c745be81cdde508265a8ef19f284674c3047f9eb;hb=7bcbdcb30d2eea8fe7e1fb60696e39abef897920;hpb=a487639f5c0405ba8afadc1887d14f3cb7960e89 diff --git a/resources/tools/presentation/generator_tables.py b/resources/tools/presentation/generator_tables.py index c745be81cd..2d4f87fc95 100644 --- a/resources/tools/presentation/generator_tables.py +++ b/resources/tools/presentation/generator_tables.py @@ -594,6 +594,7 @@ def _tpc_generate_html_table(header, data, out_file_name, legend=u"", path = u"_tmp/src/vpp_performance_tests/comparisons/" else: path = u"_tmp/src/dpdk_performance_tests/comparisons/" + logging.info(f" Writing the HTML file to {path}{file_name}.rst") with open(f"{path}{file_name}.rst", u"wt") as rst_file: rst_file.write( u"\n" @@ -612,11 +613,22 @@ def _tpc_generate_html_table(header, data, out_file_name, legend=u"", f'\n\n' ) - # TODO: Use html (rst) list for legend and footnote if legend: - rst_file.write(legend[1:].replace(u"\n", u" |br| ")) + try: + itm_lst = legend[1:-2].split(u"\n") + rst_file.write( + f"{itm_lst[0]}\n\n- " + u'\n- '.join(itm_lst[1:]) + u"\n\n" + ) + except IndexError as err: + logging.error(f"Legend cannot be written to html file\n{err}") if footnote: - rst_file.write(footnote.replace(u"\n", u" |br| ")[1:]) + try: + itm_lst = footnote[1:].split(u"\n") + rst_file.write( + f"{itm_lst[0]}\n\n- " + u'\n- '.join(itm_lst[1:]) + u"\n\n" + ) + except IndexError as err: + logging.error(f"Footnote cannot be written to html file\n{err}") def table_soak_vs_ndr(table, input_data): @@ -777,17 +789,17 @@ def table_soak_vs_ndr(table, input_data): tbl_lst.sort(key=lambda rel: rel[-1], reverse=True) # Generate csv tables: - csv_file = f"{table[u'output-file']}.csv" - with open(csv_file, u"wt") as file_handler: + csv_file_name = f"{table[u'output-file']}.csv" + with open(csv_file_name, u"wt") as file_handler: file_handler.write(header_str) for test in tbl_lst: file_handler.write(u";".join([str(item) for item in test]) + u"\n") convert_csv_to_pretty_txt( - csv_file, f"{table[u'output-file']}.txt", delimiter=u";" + csv_file_name, f"{table[u'output-file']}.txt", delimiter=u";" ) - with open(f"{table[u'output-file']}.txt", u'a') as txt_file: - txt_file.write(legend) + with open(f"{table[u'output-file']}.txt", u'a') as file_handler: + file_handler.write(legend) # Generate html table: _tpc_generate_html_table( @@ -908,13 +920,14 @@ def table_perf_trending_dash(table, input_data): classification_lst[-win_size+1:].count(u"progression")]) tbl_lst.sort(key=lambda rel: rel[0]) + tbl_lst.sort(key=lambda rel: rel[3]) + tbl_lst.sort(key=lambda rel: rel[2]) tbl_sorted = list() for nrr in range(table[u"window"], -1, -1): tbl_reg = [item for item in tbl_lst if item[4] == nrr] for nrp in range(table[u"window"], -1, -1): tbl_out = [item for item in tbl_reg if item[5] == nrp] - tbl_out.sort(key=lambda rel: rel[2]) tbl_sorted.extend(tbl_out) file_name = f"{table[u'output-file']}{table[u'output-file-ext']}" @@ -1015,11 +1028,35 @@ def _generate_url(testbed, test_name): else: driver = u"dpdk" - if u"acl" in test_name or \ - u"macip" in test_name or \ - u"nat" in test_name or \ - u"policer" in test_name or \ - u"cop" in test_name: + if u"macip-iacl1s" in test_name: + bsf = u"features-macip-iacl1" + elif u"macip-iacl10s" in test_name: + bsf = u"features-macip-iacl01" + elif u"macip-iacl50s" in test_name: + bsf = u"features-macip-iacl50" + elif u"iacl1s" in test_name: + bsf = u"features-iacl1" + elif u"iacl10s" in test_name: + bsf = u"features-iacl10" + elif u"iacl50s" in test_name: + bsf = u"features-iacl50" + elif u"oacl1s" in test_name: + bsf = u"features-oacl1" + elif u"oacl10s" in test_name: + bsf = u"features-oacl10" + elif u"oacl50s" in test_name: + bsf = u"features-oacl50" + elif u"udpsrcscale" in test_name: + bsf = u"features-udp" + elif u"iacl" in test_name: + bsf = u"features" + elif u"policer" in test_name: + bsf = u"features" + elif u"cop" in test_name: + bsf = u"features" + elif u"nat" in test_name: + bsf = u"features" + elif u"macip" in test_name: bsf = u"features" elif u"scale" in test_name: bsf = u"scale" @@ -1093,10 +1130,25 @@ def table_perf_trending_dash_html(table, input_data): if not table.get(u"testbed", None): logging.error( f"The testbed is not defined for the table " - f"{table.get(u'title', u'')}." + f"{table.get(u'title', u'')}. Skipping." ) return + test_type = table.get(u"test-type", u"MRR") + if test_type not in (u"MRR", u"NDR", u"PDR"): + logging.error( + f"Test type {table.get(u'test-type', u'MRR')} is not defined. " + f"Skipping." + ) + return + + if test_type in (u"NDR", u"PDR"): + lnk_dir = u"../ndrpdr_trending/" + lnk_sufix = f"-{test_type.lower()}" + else: + lnk_dir = u"../trending/" + lnk_sufix = u"" + logging.info(f" Generating the table {table.get(u'title', u'')} ...") try: @@ -1161,8 +1213,9 @@ def table_perf_trending_dash_html(table, input_data): tdata, u"a", attrib=dict( - href=f"../trending/" + href=f"{lnk_dir}" f"{_generate_url(table.get(u'testbed', ''), item)}" + f"{lnk_sufix}" ) ) ref.text = item @@ -1260,6 +1313,10 @@ def table_failed_tests(table, input_data): ) data = input_data.filter_data(table, continue_on_error=True) + test_type = u"MRR" + if u"NDRPDR" in table.get(u"filter", list()): + test_type = u"NDRPDR" + # Prepare the header of the tables header = [ u"Test Case", @@ -1323,15 +1380,14 @@ def table_failed_tests(table, input_data): 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[u"name"], - fails_nr, - fails_last_date, - fails_last_vpp, - f"mrr-daily-build-{fails_last_csit}" - ] - ) + tbl_lst.append([ + tst_data[u"name"], + fails_nr, + fails_last_date, + fails_last_vpp, + f"{u'mrr-daily' if test_type == u'MRR' else u'ndrpdr-weekly'}" + f"-build-{fails_last_csit}" + ]) tbl_lst.sort(key=lambda rel: rel[2], reverse=True) tbl_sorted = list() @@ -1365,10 +1421,25 @@ def table_failed_tests_html(table, input_data): if not table.get(u"testbed", None): logging.error( f"The testbed is not defined for the table " - f"{table.get(u'title', u'')}." + f"{table.get(u'title', u'')}. Skipping." + ) + return + + test_type = table.get(u"test-type", u"MRR") + if test_type not in (u"MRR", u"NDR", u"PDR", u"NDRPDR"): + logging.error( + f"Test type {table.get(u'test-type', u'MRR')} is not defined. " + f"Skipping." ) return + if test_type in (u"NDRPDR", u"NDR", u"PDR"): + lnk_dir = u"../ndrpdr_trending/" + lnk_sufix = u"-pdr" + else: + lnk_dir = u"../trending/" + lnk_sufix = u"" + logging.info(f" Generating the table {table.get(u'title', u'')} ...") try: @@ -1410,13 +1481,14 @@ def table_failed_tests_html(table, input_data): attrib=dict(align=u"left" if c_idx == 0 else u"center") ) # Name: - if c_idx == 0: + if c_idx == 0 and table.get(u"add-links", True): ref = ET.SubElement( tdata, u"a", attrib=dict( - href=f"../trending/" + href=f"{lnk_dir}" f"{_generate_url(table.get(u'testbed', ''), item)}" + f"{lnk_sufix}" ) ) ref.text = item @@ -1569,6 +1641,7 @@ def table_comparison(table, input_data): tbl_lst.append(row) comparisons = table.get(u"comparisons", None) + rcas = list() if comparisons and isinstance(comparisons, list): for idx, comp in enumerate(comparisons): try: @@ -1578,19 +1651,38 @@ def table_comparison(table, input_data): logging.warning(u"Comparison: No references defined! Skipping.") comparisons.pop(idx) continue - if not (0 < col_ref <= len(cols) and - 0 < col_cmp <= len(cols)) or \ - col_ref == col_cmp: + if not (0 < col_ref <= len(cols) and 0 < col_cmp <= len(cols) or + col_ref == col_cmp): logging.warning(f"Wrong values of reference={col_ref} " f"and/or compare={col_cmp}. Skipping.") comparisons.pop(idx) continue + rca_file_name = comp.get(u"rca-file", None) + if rca_file_name: + try: + with open(rca_file_name, u"r") as file_handler: + rcas.append( + { + u"title": f"RCA{idx + 1}", + u"data": load(file_handler, Loader=FullLoader) + } + ) + except (YAMLError, IOError) as err: + logging.warning( + f"The RCA file {rca_file_name} does not exist or " + f"it is corrupted!" + ) + logging.debug(repr(err)) + rcas.append(None) + else: + rcas.append(None) + else: + comparisons = None tbl_cmp_lst = list() if comparisons: for row in tbl_lst: new_row = deepcopy(row) - add_to_tbl = False for comp in comparisons: ref_itm = row[int(comp[u"reference"])] if ref_itm is None and \ @@ -1606,51 +1698,38 @@ def table_comparison(table, input_data): ref_itm[u"mean"], cmp_itm[u"mean"], ref_itm[u"stdev"], cmp_itm[u"stdev"] ) - new_row.append( - { - u"mean": delta * 1e6, - u"stdev": d_stdev * 1e6 - } - ) - add_to_tbl = True + if delta is None: + break + new_row.append({ + u"mean": delta * 1e6, + u"stdev": d_stdev * 1e6 + }) else: - new_row.append(None) - if add_to_tbl: + break + else: tbl_cmp_lst.append(new_row) - tbl_cmp_lst.sort(key=lambda rel: rel[0], reverse=False) - tbl_cmp_lst.sort(key=lambda rel: rel[-1][u'mean'], reverse=True) - - rcas = list() - rca_in = table.get(u"rca", None) - if rca_in and isinstance(rca_in, list): - for idx, itm in enumerate(rca_in): - try: - with open(itm.get(u"data", u""), u"r") as rca_file: - rcas.append( - { - u"title": itm.get(u"title", f"RCA{idx}"), - u"data": load(rca_file, Loader=FullLoader) - } - ) - except (YAMLError, IOError) as err: - logging.warning( - f"The RCA file {itm.get(u'data', u'')} does not exist or " - f"it is corrupted!" - ) - logging.debug(repr(err)) + try: + tbl_cmp_lst.sort(key=lambda rel: rel[0], reverse=False) + tbl_cmp_lst.sort(key=lambda rel: rel[-1][u'mean'], reverse=True) + except TypeError as err: + logging.warning(f"Empty data element in table\n{tbl_cmp_lst}\n{err}") tbl_for_csv = list() for line in tbl_cmp_lst: row = [line[0], ] for idx, itm in enumerate(line[1:]): - if itm is None: + if itm is None or not isinstance(itm, dict) or\ + itm.get(u'mean', None) is None or \ + itm.get(u'stdev', None) is None: row.append(u"NT") row.append(u"NT") else: row.append(round(float(itm[u'mean']) / 1e6, 3)) row.append(round(float(itm[u'stdev']) / 1e6, 3)) for rca in rcas: + if rca is None: + continue rca_nr = rca[u"data"].get(row[0], u"-") row.append(f"[{rca_nr}]" if rca_nr != u"-" else u"-") tbl_for_csv.append(row) @@ -1666,7 +1745,9 @@ def table_comparison(table, input_data): header_csv.append( f"Stdev({comp.get(u'title', u'')})" ) - header_csv.extend([rca[u"title"] for rca in rcas]) + for rca in rcas: + if rca: + header_csv.append(rca[u"title"]) legend_lst = table.get(u"legend", None) if legend_lst is None: @@ -1675,12 +1756,14 @@ def table_comparison(table, input_data): legend = u"\n" + u"\n".join(legend_lst) + u"\n" footnote = u"" - for rca in rcas: - footnote += f"\n{rca[u'title']}:\n" - footnote += rca[u"data"].get(u"footnote", u"") + if rcas and any(rcas): + footnote += u"\nRoot Cause Analysis:\n" + for rca in rcas: + if rca: + footnote += f"{rca[u'data'].get(u'footnote', u'')}\n" - csv_file = f"{table[u'output-file']}-csv.csv" - with open(csv_file, u"wt", encoding='utf-8') as file_handler: + csv_file_name = f"{table[u'output-file']}-csv.csv" + with open(csv_file_name, u"wt", encoding='utf-8') as file_handler: file_handler.write( u",".join([f'"{itm}"' for itm in header_csv]) + u"\n" ) @@ -1700,7 +1783,9 @@ def table_comparison(table, input_data): for line in tbl_cmp_lst: row = [line[0], ] for idx, itm in enumerate(line[1:]): - if itm is None: + if itm is None or not isinstance(itm, dict) or \ + itm.get(u'mean', None) is None or \ + itm.get(u'stdev', None) is None: new_itm = u"NT" else: if idx < len(cols): @@ -1721,6 +1806,10 @@ def table_comparison(table, input_data): tbl_tmp.append(row) + header = [u"Test Case", ] + header.extend([col[u"title"] for col in cols]) + header.extend([comp.get(u"title", u"") for comp in comparisons]) + tbl_final = list() for line in tbl_tmp: row = [line[0], ] @@ -1731,32 +1820,43 @@ def table_comparison(table, input_data): itm_lst = itm.rsplit(u"\u00B1", 1) itm_lst[-1] = \ f"{u' ' * (max_lens[idx] - len(itm_lst[-1]))}{itm_lst[-1]}" - row.append(u"\u00B1".join(itm_lst)) - for rca in rcas: - rca_nr = rca[u"data"].get(row[0], u"-") - row.append(f"[{rca_nr}]" if rca_nr != u"-" else u"-") - + itm_str = u"\u00B1".join(itm_lst) + + if idx >= len(cols): + # Diffs + rca = rcas[idx - len(cols)] + if rca: + # Add rcas to diffs + rca_nr = rca[u"data"].get(row[0], None) + if rca_nr: + hdr_len = len(header[idx + 1]) - 1 + if hdr_len < 19: + hdr_len = 19 + rca_nr = f"[{rca_nr}]" + itm_str = ( + f"{u' ' * (4 - len(rca_nr))}{rca_nr}" + f"{u' ' * (hdr_len - 4 - len(itm_str))}" + f"{itm_str}" + ) + row.append(itm_str) tbl_final.append(row) - header = [u"Test Case", ] - header.extend([col[u"title"] for col in cols]) - header.extend([comp.get(u"title", u"") for comp in comparisons]) - header.extend([rca[u"title"] for rca in rcas]) - # Generate csv tables: - csv_file = f"{table[u'output-file']}.csv" - with open(csv_file, u"wt", encoding='utf-8') as file_handler: + csv_file_name = f"{table[u'output-file']}.csv" + logging.info(f" Writing the file {csv_file_name}") + with open(csv_file_name, u"wt", encoding='utf-8') as file_handler: file_handler.write(u";".join(header) + u"\n") for test in tbl_final: file_handler.write(u";".join([str(item) for item in test]) + u"\n") # Generate txt table: txt_file_name = f"{table[u'output-file']}.txt" - convert_csv_to_pretty_txt(csv_file, txt_file_name, delimiter=u";") + logging.info(f" Writing the file {txt_file_name}") + convert_csv_to_pretty_txt(csv_file_name, txt_file_name, delimiter=u";") - with open(txt_file_name, u'a', encoding='utf-8') as txt_file: - txt_file.write(legend) - txt_file.write(footnote) + with open(txt_file_name, u'a', encoding='utf-8') as file_handler: + file_handler.write(legend) + file_handler.write(footnote) # Generate html table: _tpc_generate_html_table( @@ -1872,12 +1972,13 @@ def table_weekly_comparison(table, in_data): ref_data = tst_data.get(idx_ref, None) cmp_data = tst_data.get(idx_cmp, None) if ref_data is None or cmp_data is None: - cmp_dict[tst_name].append(float('nan')) + cmp_dict[tst_name].append(float(u'nan')) else: cmp_dict[tst_name].append( relative_change(ref_data, cmp_data) ) + tbl_lst_none = list() tbl_lst = list() for tst_name, tst_data in tbl_dict.items(): itm_lst = [tst_data[u"name"], ] @@ -1893,14 +1994,20 @@ def table_weekly_comparison(table, in_data): for itm in cmp_dict[tst_name] ] ) - tbl_lst.append(itm_lst) + if str(itm_lst[-1]) == u"nan" or itm_lst[-1] is None: + tbl_lst_none.append(itm_lst) + else: + tbl_lst.append(itm_lst) + tbl_lst_none.sort(key=lambda rel: rel[0], reverse=False) tbl_lst.sort(key=lambda rel: rel[0], reverse=False) - tbl_lst.sort(key=lambda rel: rel[-1], reverse=True) + tbl_lst.sort(key=lambda rel: rel[-1], reverse=False) + tbl_lst.extend(tbl_lst_none) # Generate csv table: - csv_file = f"{table[u'output-file']}.csv" - with open(csv_file, u"wt", encoding='utf-8') as file_handler: + csv_file_name = f"{table[u'output-file']}.csv" + logging.info(f" Writing the file {csv_file_name}") + with open(csv_file_name, u"wt", encoding='utf-8') as file_handler: for hdr in header: file_handler.write(u",".join(hdr) + u"\n") for test in tbl_lst: @@ -1911,17 +2018,18 @@ def table_weekly_comparison(table, in_data): ] ) + u"\n") - txt_file = f"{table[u'output-file']}.txt" - convert_csv_to_pretty_txt(csv_file, txt_file, delimiter=u",") + txt_file_name = f"{table[u'output-file']}.txt" + logging.info(f" Writing the file {txt_file_name}") + convert_csv_to_pretty_txt(csv_file_name, txt_file_name, delimiter=u",") # Reorganize header in txt table txt_table = list() - with open(txt_file, u"rt", encoding='utf-8') as file_handler: + with open(txt_file_name, u"rt", encoding='utf-8') as file_handler: for line in file_handler: txt_table.append(line) try: txt_table.insert(5, txt_table.pop(2)) - with open(txt_file, u"wt", encoding='utf-8') as file_handler: + with open(txt_file_name, u"wt", encoding='utf-8') as file_handler: file_handler.writelines(txt_table) except IndexError: pass