diff options
Diffstat (limited to 'csit.infra.dash/app')
33 files changed, 654 insertions, 334 deletions
diff --git a/csit.infra.dash/app/cdash/comparisons/layout.py b/csit.infra.dash/app/cdash/comparisons/layout.py index 57a1c2a1b4..735f199158 100644 --- a/csit.infra.dash/app/cdash/comparisons/layout.py +++ b/csit.infra.dash/app/cdash/comparisons/layout.py @@ -33,7 +33,8 @@ from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.url_processing import url_decode from ..utils.utils import generate_options, gen_new_url, navbar_report, \ - filter_table_data, sort_table_data, show_iterative_graph_data, show_tooltip + filter_table_data, sort_table_data, show_iterative_graph_data, \ + show_tooltip, get_topo_arch from .tables import comparison_table from ..report.graphs import graph_iterative @@ -124,7 +125,7 @@ class Layout: lst_job = row["job"].split("-") dut = lst_job[1] dver = f"{row['release']}-{row['dut_version']}" - tbed = "-".join(lst_job[-2:]) + tbed = get_topo_arch(lst_job) lst_test_id = row["test_id"].split(".") suite = lst_test_id[-2].replace("2n1l-", "").replace("1n1l-", "").\ diff --git a/csit.infra.dash/app/cdash/comparisons/tables.py b/csit.infra.dash/app/cdash/comparisons/tables.py index 0e32f38b6c..fa92f3da7f 100644 --- a/csit.infra.dash/app/cdash/comparisons/tables.py +++ b/csit.infra.dash/app/cdash/comparisons/tables.py @@ -232,7 +232,7 @@ def comparison_table( :returns: A list of simple items. :rtype: list """ - l_infra = sel["infra"].split("-") + l_infra = sel["infra"].rsplit("-", maxsplit=2) selection = list() for core in sel["core"]: for fsize in sel["frmsize"]: @@ -240,8 +240,8 @@ def comparison_table( selection.append({ "dut": sel["dut"], "dutver": sel["dutver"], - "tbed": f"{l_infra[0]}-{l_infra[1]}", - "nic": l_infra[2], + "tbed": l_infra[0], + "nic": l_infra[1], "driver": l_infra[-1].replace("_", "-"), "core": core, "frmsize": fsize, @@ -315,11 +315,13 @@ def comparison_table( else: c_row = c_data[c_data["name"] == row["name"]] if not c_row.empty: - unit.add(f"{s_unit_factor}{row['unit']}") r_mean = row["mean"] r_std = row["stdev"] c_mean = c_row["mean"].values[0] c_std = c_row["stdev"].values[0] + if r_mean == 0.0 or c_mean == 0.0: + continue + unit.add(f"{s_unit_factor}{row['unit']}") l_name.append(row["name"]) l_r_mean.append(r_mean / unit_factor) l_r_std.append(r_std / unit_factor) diff --git a/csit.infra.dash/app/cdash/coverage/layout.py b/csit.infra.dash/app/cdash/coverage/layout.py index b8fa0236a5..7442891198 100644 --- a/csit.infra.dash/app/cdash/coverage/layout.py +++ b/csit.infra.dash/app/cdash/coverage/layout.py @@ -32,7 +32,7 @@ from ..utils.constants import Constants as C from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.utils import label, gen_new_url, generate_options, navbar_report, \ - show_tooltip + show_tooltip, get_topo_arch from ..utils.url_processing import url_decode from .tables import coverage_tables, select_coverage_data @@ -96,7 +96,7 @@ class Layout: lst_job = row["job"].split("-") dut = lst_job[1] d_ver = row["dut_version"] - tbed = "-".join(lst_job[-2:]) + tbed = get_topo_arch(lst_job) lst_test_id = row["test_id"].split(".") if dut == "dpdk": area = "dpdk" diff --git a/csit.infra.dash/app/cdash/coverage/tables.py b/csit.infra.dash/app/cdash/coverage/tables.py index 84adb091a1..d38e51e243 100644 --- a/csit.infra.dash/app/cdash/coverage/tables.py +++ b/csit.infra.dash/app/cdash/coverage/tables.py @@ -52,9 +52,9 @@ def select_coverage_data( l_data = list() # Filter data selected by the user. - phy = selected["phy"].split("-") - if len(phy) == 4: - topo, arch, nic, drv = phy + phy = selected["phy"].rsplit("-", maxsplit=2) + if len(phy) == 3: + topo_arch, nic, drv = phy drv_str = "" if drv == "dpdk" else drv.replace("_", "-") else: return l_data, None @@ -66,7 +66,7 @@ def select_coverage_data( (data["release"] == selected["rls"]) )]) df = df[ - (df.job.str.endswith(f"{topo}-{arch}")) & + (df.job.str.endswith(topo_arch)) & (df.test_id.str.contains( f"^.*\.{selected['area']}\..*{nic}.*{drv_str}.*$", regex=True diff --git a/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2306_device b/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2306_device Binary files differdeleted file mode 100644 index f619ce8a8e..0000000000 --- a/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2306_device +++ /dev/null diff --git a/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2406_device b/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2406_device Binary files differnew file mode 100644 index 0000000000..011ebba41f --- /dev/null +++ b/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2406_device diff --git a/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2306_ndrpdr b/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2406_ndrpdr Binary files differindex 06bc618bea..06bc618bea 100644 --- a/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2306_ndrpdr +++ b/csit.infra.dash/app/cdash/data/_metadata/coverage_rls2406_ndrpdr diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_hoststack b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_hoststack Binary files differdeleted file mode 100644 index 993d16c18c..0000000000 --- a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_hoststack +++ /dev/null diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_mrr b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_mrr Binary files differdeleted file mode 100644 index 96832850b1..0000000000 --- a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_mrr +++ /dev/null diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_ndrpdr b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_ndrpdr Binary files differdeleted file mode 100644 index 2291bb8349..0000000000 --- a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2306_ndrpdr +++ /dev/null diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_hoststack b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_hoststack Binary files differnew file mode 100644 index 0000000000..1e9c708253 --- /dev/null +++ b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_hoststack diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_mrr b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_mrr Binary files differnew file mode 100644 index 0000000000..ced78967c5 --- /dev/null +++ b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_mrr diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_ndrpdr b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_ndrpdr Binary files differnew file mode 100644 index 0000000000..cf2b8a116b --- /dev/null +++ b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_ndrpdr diff --git a/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_soak b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_soak Binary files differnew file mode 100644 index 0000000000..4502ca4f59 --- /dev/null +++ b/csit.infra.dash/app/cdash/data/_metadata/iterative_rls2406_soak diff --git a/csit.infra.dash/app/cdash/data/_metadata/trending_mrr b/csit.infra.dash/app/cdash/data/_metadata/trending_mrr Binary files differindex 9d4e126e59..06ddbca659 100644 --- a/csit.infra.dash/app/cdash/data/_metadata/trending_mrr +++ b/csit.infra.dash/app/cdash/data/_metadata/trending_mrr diff --git a/csit.infra.dash/app/cdash/data/_metadata/trending_ndrpdr b/csit.infra.dash/app/cdash/data/_metadata/trending_ndrpdr Binary files differindex 3f8b85c66e..870d8a9f9b 100644 --- a/csit.infra.dash/app/cdash/data/_metadata/trending_ndrpdr +++ b/csit.infra.dash/app/cdash/data/_metadata/trending_ndrpdr diff --git a/csit.infra.dash/app/cdash/data/data.py b/csit.infra.dash/app/cdash/data/data.py index 2c49992bf8..41033a7758 100644 --- a/csit.infra.dash/app/cdash/data/data.py +++ b/csit.infra.dash/app/cdash/data/data.py @@ -400,11 +400,16 @@ class Data: ) for key in self._data.keys(): logging.info(f"\n\nDataframe {key}:\n") - self._data[key] = pd.concat( - data_lists[key], - ignore_index=True, - copy=False - ) + if len(data_lists[key]) == 0: + self._data[key] = pd.DataFrame() + elif len(data_lists[key]) == 1: + self._data[key] = data_lists[key][0] + else: + self._data[key] = pd.concat( + data_lists[key], + ignore_index=True, + copy=False + ) self._data[key].info(verbose=True, memory_usage="deep") err_msg = self._validate_columns(key) if err_msg: diff --git a/csit.infra.dash/app/cdash/data/data.yaml b/csit.infra.dash/app/cdash/data/data.yaml index ed5fc0b269..c1b45536b7 100644 --- a/csit.infra.dash/app/cdash/data/data.yaml +++ b/csit.infra.dash/app/cdash/data/data.yaml @@ -19,6 +19,7 @@ - dut_type - dut_version - hosts + - tg_type - start_time - passed - test_id @@ -26,9 +27,11 @@ - result_receive_rate_rate_avg - result_receive_rate_rate_stdev - result_receive_rate_rate_unit + - result_receive_rate_rate_values - result_receive_rate_bandwidth_avg - result_receive_rate_bandwidth_stdev - result_receive_rate_bandwidth_unit + - result_receive_rate_bandwidth_values - telemetry - data_type: trending partition: test_type @@ -41,6 +44,7 @@ - dut_type - dut_version - hosts + - tg_type - start_time - passed - test_id @@ -111,9 +115,9 @@ - data_type: iterative partition: test_type partition_name: mrr - release: rls2306 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2306 - schema: iterative_rls2306_mrr + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 + schema: iterative_rls2310_mrr columns: - job - build @@ -130,9 +134,9 @@ - data_type: iterative partition: test_type partition_name: ndrpdr - release: rls2306 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2306 - schema: iterative_rls2306_ndrpdr + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 + schema: iterative_rls2310_ndrpdr columns: - job - build @@ -146,6 +150,10 @@ - result_pdr_lower_rate_value - result_ndr_lower_rate_unit - result_ndr_lower_rate_value + - result_pdr_lower_bandwidth_unit + - result_pdr_lower_bandwidth_value + - result_ndr_lower_bandwidth_unit + - result_ndr_lower_bandwidth_value - result_latency_reverse_pdr_90_hdrh - result_latency_reverse_pdr_50_hdrh - result_latency_reverse_pdr_10_hdrh @@ -159,9 +167,9 @@ - data_type: iterative partition: test_type partition_name: hoststack - release: rls2306 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2306 - schema: iterative_rls2306_hoststack + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 + schema: iterative_rls2310_hoststack columns: - job - build @@ -179,9 +187,9 @@ - data_type: coverage partition: test_type partition_name: ndrpdr - release: rls2306 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2306 - schema: coverage_rls2306_ndrpdr + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 + schema: coverage_rls2310_ndrpdr columns: - job - build @@ -205,10 +213,28 @@ - result_latency_forward_pdr_10_hdrh - data_type: coverage partition: test_type + partition_name: mrr + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 + schema: iterative_rls2310_mrr + columns: + - job + - build + - dut_type + - dut_version + - start_time + - passed + - test_id + - version + - result_receive_rate_rate_avg + - result_receive_rate_rate_stdev + - result_receive_rate_rate_unit +- data_type: coverage + partition: test_type partition_name: device - release: rls2306 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2306 - schema: coverage_rls2306_device + release: rls2310 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 + schema: coverage_rls2310_device columns: - job - build @@ -220,9 +246,9 @@ - data_type: iterative partition: test_type partition_name: mrr - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 - schema: iterative_rls2310_mrr + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 + schema: iterative_rls2402_mrr columns: - job - build @@ -235,13 +261,15 @@ - result_receive_rate_rate_avg - result_receive_rate_rate_stdev - result_receive_rate_rate_unit - - result_receive_rate_rate_values + - result_receive_rate_bandwidth_avg + - result_receive_rate_bandwidth_stdev + - result_receive_rate_bandwidth_unit - data_type: iterative partition: test_type partition_name: ndrpdr - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 - schema: iterative_rls2310_ndrpdr + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 + schema: iterative_rls2402_ndrpdr columns: - job - build @@ -272,14 +300,15 @@ - data_type: iterative partition: test_type partition_name: hoststack - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2310 - schema: iterative_rls2310_hoststack + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 + schema: iterative_rls2402_hoststack columns: - job - build - dut_type - dut_version + - hosts - tg_type - result_bandwidth_unit - result_bandwidth_value @@ -292,9 +321,9 @@ - data_type: coverage partition: test_type partition_name: ndrpdr - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 - schema: coverage_rls2310_ndrpdr + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 + schema: coverage_rls2402_ndrpdr columns: - job - build @@ -319,9 +348,9 @@ - data_type: coverage partition: test_type partition_name: mrr - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 - schema: iterative_rls2310_mrr + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 + schema: iterative_rls2402_mrr columns: - job - build @@ -337,9 +366,9 @@ - data_type: coverage partition: test_type partition_name: device - release: rls2310 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2310 - schema: coverage_rls2310_device + release: rls2402 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 + schema: coverage_rls2402_device columns: - job - build @@ -351,15 +380,16 @@ - data_type: iterative partition: test_type partition_name: mrr - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 - schema: iterative_rls2402_mrr + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2406 + schema: iterative_rls2406_mrr columns: - job - build - dut_type - dut_version - # - hosts + - tg_type + - hosts - start_time - passed - test_id @@ -367,23 +397,22 @@ - result_receive_rate_rate_avg - result_receive_rate_rate_stdev - result_receive_rate_rate_unit - - result_receive_rate_rate_values - result_receive_rate_bandwidth_avg - result_receive_rate_bandwidth_stdev - result_receive_rate_bandwidth_unit - - result_receive_rate_bandwidth_values - data_type: iterative partition: test_type partition_name: ndrpdr - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 - schema: iterative_rls2402_ndrpdr + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2406 + schema: iterative_rls2406_ndrpdr columns: - job - build - dut_type - dut_version - # - hosts + - tg_type + - hosts - start_time - passed - test_id @@ -409,9 +438,9 @@ - data_type: iterative partition: test_type partition_name: hoststack - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2402 - schema: iterative_rls2402_hoststack + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2406 + schema: iterative_rls2406_hoststack columns: - job - build @@ -427,12 +456,34 @@ - passed - test_id - version +- data_type: iterative + partition: test_type + partition_name: soak + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/iterative_rls2406 + schema: iterative_rls2406_soak + columns: + - job + - build + - dut_type + - dut_version + - hosts + - tg_type + - result_critical_rate_lower_bandwidth_unit + - result_critical_rate_lower_bandwidth_value + - result_critical_rate_lower_rate_unit + - result_critical_rate_lower_rate_value + - start_time + - passed + - telemetry + - test_id + - version - data_type: coverage partition: test_type partition_name: ndrpdr - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 - schema: coverage_rls2402_ndrpdr + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2406 + schema: coverage_rls2406_ndrpdr columns: - job - build @@ -457,14 +508,15 @@ - data_type: coverage partition: test_type partition_name: mrr - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 - schema: iterative_rls2402_mrr + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2406 + schema: iterative_rls2406_mrr columns: - job - build - dut_type - dut_version + - tg_type - start_time - passed - test_id @@ -475,14 +527,15 @@ - data_type: coverage partition: test_type partition_name: device - release: rls2402 - path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2402 - schema: coverage_rls2402_device + release: rls2406 + path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2406 + schema: coverage_rls2406_device columns: - job - build - dut_type - dut_version + - tg_type - passed - test_id - version diff --git a/csit.infra.dash/app/cdash/news/layout.py b/csit.infra.dash/app/cdash/news/layout.py index ba4fc85163..8fe3d35e6a 100644 --- a/csit.infra.dash/app/cdash/news/layout.py +++ b/csit.infra.dash/app/cdash/news/layout.py @@ -24,7 +24,7 @@ from dash import callback_context from dash import Input, Output, State from ..utils.constants import Constants as C -from ..utils.utils import gen_new_url, navbar_trending +from ..utils.utils import gen_new_url, navbar_trending, get_topo_arch from ..utils.anomalies import classify_anomalies from ..utils.url_processing import url_decode from .tables import table_summary @@ -78,7 +78,7 @@ class Layout: d_job_info["dut"].append(lst_job[1]) d_job_info["ttype"].append(lst_job[3]) d_job_info["cadence"].append(lst_job[4]) - d_job_info["tbed"].append("-".join(lst_job[-2:])) + d_job_info["tbed"].append(get_topo_arch(lst_job)) self.job_info = pd.DataFrame.from_dict(d_job_info) # Pre-process the data: diff --git a/csit.infra.dash/app/cdash/report/graphs.py b/csit.infra.dash/app/cdash/report/graphs.py index 02202ea155..5e57713f11 100644 --- a/csit.infra.dash/app/cdash/report/graphs.py +++ b/csit.infra.dash/app/cdash/report/graphs.py @@ -24,7 +24,7 @@ from ..utils.constants import Constants as C from ..utils.utils import get_color, get_hdrh_latencies -def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame: +def select_iterative_data(data: pd.DataFrame, itm: dict) -> pd.DataFrame: """Select the data for graphs and tables from the provided data frame. :param data: Data frame with data for graphs and tables. @@ -36,9 +36,9 @@ def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame: :rtype: pandas.DataFrame """ - phy = itm["phy"].split("-") - if len(phy) == 4: - topo, arch, nic, drv = phy + phy = itm["phy"].rsplit("-", maxsplit=2) + if len(phy) == 3: + topo_arch, nic, drv = phy if drv == "dpdk": drv = "" else: @@ -61,12 +61,12 @@ def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame: (data["passed"] == True) )] - core = str() if itm["dut"] == "trex" else f"{itm['core']}" + core = str() if itm["dut"] == "trex" else itm["core"] ttype = "ndrpdr" if itm["testtype"] in ("ndr", "pdr") else itm["testtype"] regex_test = \ f"^.*[.|-]{nic}.*{itm['framesize']}-{core}-{drv}{itm['test']}-{ttype}$" df = df[ - (df.job.str.endswith(f"{topo}-{arch}")) & + (df.job.str.endswith(topo_arch)) & (df.dut_version.str.contains(itm["dutver"].replace(".r", "-r").\ replace("rls", "release"))) & (df.test_id.str.contains(regex_test, regex=True)) @@ -96,16 +96,9 @@ def graph_iterative(data: pd.DataFrame, sel: list, layout: dict, :rtype: tuple(plotly.graph_objects.Figure, plotly.graph_objects.Figure) """ - def get_y_values(data, y_data_max, param, norm_factor, release=str(), + def get_y_values(data, y_data_max, param, norm_factor, remove_outliers=False): - if param == "result_receive_rate_rate_values": - if release == "rls2402": - y_vals_raw = data["result_receive_rate_rate_avg"].to_list() - else: - y_vals_raw = data[param].to_list()[0] - else: - y_vals_raw = data[param].to_list() - y_data = [(y * norm_factor) for y in y_vals_raw] + y_data = [(y * norm_factor) for y in data[param].to_list()] if remove_outliers: try: @@ -146,9 +139,9 @@ def graph_iterative(data: pd.DataFrame, sel: list, layout: dict, if itm_data.empty: continue - phy = itm["phy"].split("-") - topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str() - norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY[topo_arch]) \ + phy = itm["phy"].rsplit("-", maxsplit=2) + topo_arch = phy[0] if len(phy) == 3 else str() + norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY.get(topo_arch, 1.0)) \ if normalize else 1.0 if itm["area"] == "hoststack": @@ -163,7 +156,6 @@ def graph_iterative(data: pd.DataFrame, sel: list, layout: dict, y_tput_max, C.VALUE_ITER[ttype], norm_factor, - itm["rls"], remove_outliers ) @@ -181,28 +173,19 @@ def graph_iterative(data: pd.DataFrame, sel: list, layout: dict, ) } - if itm["testtype"] == "mrr" and itm["rls"] in ("rls2306", "rls2310"): - trial_run = "trial" - metadata["csit-ref"] = ( - f"{itm_data['job'].to_list()[0]}/", - f"{itm_data['build'].to_list()[0]}" - ) - customdata = [{"metadata": metadata}, ] * nr_of_samples - else: - trial_run = "run" - for _, row in itm_data.iterrows(): - metadata["csit-ref"] = f"{row['job']}/{row['build']}" - try: - metadata["hosts"] = ", ".join(row["hosts"]) - except (KeyError, TypeError): - pass - customdata.append({"metadata": deepcopy(metadata)}) + for _, row in itm_data.iterrows(): + metadata["csit-ref"] = f"{row['job']}/{row['build']}" + try: + metadata["hosts"] = ", ".join(row["hosts"]) + except (KeyError, TypeError): + pass + customdata.append({"metadata": deepcopy(metadata)}) tput_kwargs = dict( y=y_data, name=( f"{idx + 1}. " f"({nr_of_samples:02d} " - f"{trial_run}{'s' if nr_of_samples > 1 else ''}) " + f"run{'s' if nr_of_samples > 1 else ''}) " f"{itm['id']}" ), hoverinfo=u"y+name", diff --git a/csit.infra.dash/app/cdash/report/layout.py b/csit.infra.dash/app/cdash/report/layout.py index f485894d78..cd16bfbca0 100644 --- a/csit.infra.dash/app/cdash/report/layout.py +++ b/csit.infra.dash/app/cdash/report/layout.py @@ -32,7 +32,7 @@ from ..utils.constants import Constants as C from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.utils import show_tooltip, label, sync_checklists, gen_new_url, \ - generate_options, get_list_group_items, navbar_report, \ + generate_options, get_list_group_items, navbar_report, get_topo_arch, \ show_iterative_graph_data from ..utils.url_processing import url_decode from .graphs import graph_iterative, select_iterative_data @@ -122,7 +122,7 @@ class Layout: lst_job = row["job"].split("-") dut = lst_job[1] d_ver = row["dut_version"] - tbed = "-".join(lst_job[-2:]) + tbed = get_topo_arch(lst_job) lst_test_id = row["test_id"].split(".") if dut == "dpdk": area = "dpdk" @@ -348,7 +348,7 @@ class Layout: :returns: Control panel. :rtype: list """ - return [ + test_selection = [ dbc.Row( class_name="g-0 p-1", children=[ @@ -604,52 +604,36 @@ class Layout: dbc.Row( class_name="g-0 p-1", children=[ - dbc.InputGroup( - [ - dbc.InputGroupText( - children=show_tooltip( - self._tooltips, - "help-normalize", - "Normalization" - ) - ), - dbc.Col( - children=[ - dbc.Checklist( - id="normalize", - options=[{ - "value": "normalize", - "label": ( - "Normalize to CPU frequency " - "2GHz" - ) - }], - value=[], - inline=True, - class_name="ms-2" - ) - ] - ) - ], - style={"align-items": "center"}, - size="sm" + dbc.Button( + id={"type": "ctrl-btn", "index": "add-test"}, + children="Add Selected", + color="info", + class_name="p-1" ) ] - ), + ) + ] + processing = [ dbc.Row( class_name="g-0 p-1", children=[ - dbc.Button( - id={"type": "ctrl-btn", "index": "add-test"}, - children="Add Selected", - color="info" + dbc.Checklist( + id="normalize", + options=[{ + "value": "normalize", + "label": "Normalize to 2GHz CPU frequency" + }], + value=[], + inline=True, + class_name="ms-2" ) ] - ), + ) + ] + test_list = [ dbc.Row( id="row-card-sel-tests", class_name="g-0 p-1", - style=C.STYLE_DISABLED, children=[ dbc.ListGroup( class_name="overflow-auto p-0", @@ -663,21 +647,20 @@ class Layout: dbc.Stack( id="row-btns-sel-tests", class_name="g-0 p-1", - style=C.STYLE_DISABLED, gap=2, children=[ dbc.ButtonGroup(children=[ dbc.Button( id={"type": "ctrl-btn", "index": "rm-test"}, children="Remove Selected", - class_name="w-100", + class_name="w-100 p-1", color="info", disabled=False ), dbc.Button( id={"type": "ctrl-btn", "index": "rm-test-all"}, children="Remove All", - class_name="w-100", + class_name="w-100 p-1", color="info", disabled=False ) @@ -686,14 +669,14 @@ class Layout: dbc.Button( id="plot-btn-url", children="Show URL", - class_name="w-100", + class_name="w-100 p-1", color="info", disabled=False ), dbc.Button( id="plot-btn-download", children="Download Data", - class_name="w-100", + class_name="w-100 p-1", color="info", disabled=False ) @@ -702,6 +685,59 @@ class Layout: ) ] + return [ + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Test Selection") + ), + dbc.CardBody( + children=test_selection, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + class_name="g-0 p-1" + ), + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Data Manipulations") + ), + dbc.CardBody( + children=processing, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + class_name="g-0 p-1" + ), + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Selected Tests") + ), + dbc.CardBody( + children=test_list, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + id = "row-selected-tests", + class_name="g-0 p-1", + style=C.STYLE_DISABLED, + ) + ] + def _get_plotting_area( self, tests: list, @@ -798,8 +834,7 @@ class Layout: Output("store-control-panel", "data"), Output("store-selected-tests", "data"), Output("plotting-area", "children"), - Output("row-card-sel-tests", "style"), - Output("row-btns-sel-tests", "style"), + Output("row-selected-tests", "style"), Output("lg-selected", "children"), Output({"type": "ctrl-dd", "index": "rls"}, "value"), @@ -869,8 +904,7 @@ class Layout: url_params = None plotting_area = no_update - row_card_sel_tests = no_update - row_btns_sel_tests = no_update + row_sel_tests = no_update lg_selected = no_update trigger = Trigger(callback_context.triggered) @@ -882,8 +916,7 @@ class Layout: except (KeyError, IndexError, AttributeError): pass if store_sel: - row_card_sel_tests = C.STYLE_ENABLED - row_btns_sel_tests = C.STYLE_ENABLED + row_sel_tests = C.STYLE_ENABLED last_test = store_sel[-1] test = self._spec_tbs[last_test["rls"]][last_test["dut"]]\ [last_test["dutver"]][last_test["area"]]\ @@ -1235,20 +1268,17 @@ class Layout: {"store_sel": store_sel, "norm": normalize} ) ) - row_card_sel_tests = C.STYLE_ENABLED - row_btns_sel_tests = C.STYLE_ENABLED + row_sel_tests = C.STYLE_ENABLED else: plotting_area = C.PLACEHOLDER - row_card_sel_tests = C.STYLE_DISABLED - row_btns_sel_tests = C.STYLE_DISABLED + row_sel_tests = C.STYLE_DISABLED store_sel = list() ret_val = [ ctrl_panel.panel, store_sel, plotting_area, - row_card_sel_tests, - row_btns_sel_tests, + row_sel_tests, lg_selected ] ret_val.extend(ctrl_panel.values) diff --git a/csit.infra.dash/app/cdash/search/layout.py b/csit.infra.dash/app/cdash/search/layout.py index aa4dd53d5b..8dd244a3c1 100644 --- a/csit.infra.dash/app/cdash/search/layout.py +++ b/csit.infra.dash/app/cdash/search/layout.py @@ -33,7 +33,7 @@ from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.utils import gen_new_url, generate_options, navbar_trending, \ filter_table_data, sort_table_data, show_trending_graph_data, \ - show_iterative_graph_data, show_tooltip + show_iterative_graph_data, show_tooltip, get_topo_arch from ..utils.url_processing import url_decode from .tables import search_table from ..coverage.tables import coverage_tables @@ -110,7 +110,7 @@ class Layout: l_id = row["test_id"].split(".") suite = l_id[-2].replace("2n1l-", "").replace("1n1l-", "").\ replace("2n-", "") - tb = "-".join(row["job"].split("-")[-2:]) + tb = get_topo_arch(row["job"].split("-")) nic = suite.split("-")[0] for driver in C.DRIVERS: if driver in suite: @@ -644,7 +644,7 @@ class Layout: "release-dis": C.STYLE_DONT_DISPLAY, "release-val": str(), "help-dis": disabled, - "help-val": "<testbed> <nic> <driver> " + \ + "help-val": "<topo> <arch> <nic> <driver> " + \ "<framesize> <cores> <test>", "search-dis": disabled, "search-val": str() @@ -664,7 +664,7 @@ class Layout: ctrl_panel.set({ "release-val": trigger.value, "help-dis": C.STYLE_DISPLAY, - "help-val": "<DUT version> <testbed> <nic> " + \ + "help-val": "<DUT version> <topo> <arch> <nic> " + \ "<driver> <framesize> <core> <test>", "search-dis": C.STYLE_DISPLAY, "search-val": str() @@ -758,7 +758,6 @@ class Layout: (data["dut_version"] == dutver) & (data["release"] == rls) )]) - df = df[df.full_id.str.contains( f".*{tb}.*{nic}.*{test_name}", regex=True diff --git a/csit.infra.dash/app/cdash/search/tables.py b/csit.infra.dash/app/cdash/search/tables.py index a5ffd76d3d..3492fba16f 100644 --- a/csit.infra.dash/app/cdash/search/tables.py +++ b/csit.infra.dash/app/cdash/search/tables.py @@ -18,6 +18,7 @@ import pandas as pd from ..utils.constants import Constants as C +from ..utils.utils import get_topo_arch def select_search_data(data: pd.DataFrame, selection: list) -> pd.DataFrame: @@ -80,7 +81,7 @@ def search_table(data: pd.DataFrame, selection: list) -> pd.DataFrame: l_id = row["test_id"].split(".") suite = l_id[-2].replace("2n1l-", "").replace("1n1l-", "").\ replace("2n-", "") - l_tb.append("-".join(row["job"].split("-")[-2:])) + l_tb.append(get_topo_arch(row["job"].split("-"))) l_nic.append(suite.split("-")[0]) if selection["datatype"] != "trending": l_dutver.append(row["dut_version"]) diff --git a/csit.infra.dash/app/cdash/stats/graphs.py b/csit.infra.dash/app/cdash/stats/graphs.py index 4b25396680..61eef41115 100644 --- a/csit.infra.dash/app/cdash/stats/graphs.py +++ b/csit.infra.dash/app/cdash/stats/graphs.py @@ -17,6 +17,9 @@ import plotly.graph_objects as go import pandas as pd +from datetime import datetime +from pytz import UTC + from ..utils.constants import Constants as C @@ -86,6 +89,7 @@ def graph_statistics(df: pd.DataFrame, job: str, layout: dict) -> tuple: ) ) + x_range = [data["start_time"][0], datetime.now(tz=UTC).strftime("%Y-%m-%d")] tickvals = [0, ] step = max(data["duration"]) / 5 for i in range(5): @@ -97,6 +101,7 @@ def graph_statistics(df: pd.DataFrame, job: str, layout: dict) -> tuple: f"{(val // 3600):02d}:{((val % 3600) // 60):02d}" \ for val in tickvals ] + layout_duration["xaxis"]["range"] = x_range fig_duration.update_layout(layout_duration) # Passed / failed: @@ -124,6 +129,7 @@ def graph_statistics(df: pd.DataFrame, job: str, layout: dict) -> tuple: ) layout_pf = layout.get("plot-stats-passed", dict()) if layout_pf: + layout_pf["xaxis"]["range"] = x_range fig_passed.update_layout(layout_pf) return fig_passed, fig_duration diff --git a/csit.infra.dash/app/cdash/stats/layout.py b/csit.infra.dash/app/cdash/stats/layout.py index 616a4028e6..4aae11a06b 100644 --- a/csit.infra.dash/app/cdash/stats/layout.py +++ b/csit.infra.dash/app/cdash/stats/layout.py @@ -29,7 +29,8 @@ from yaml import load, FullLoader, YAMLError from ..utils.constants import Constants as C from ..utils.control_panel import ControlPanel from ..utils.utils import show_tooltip, gen_new_url, get_ttypes, get_cadences, \ - get_test_beds, get_job, generate_options, set_job_params, navbar_trending + get_test_beds, get_job, generate_options, set_job_params, navbar_trending, \ + get_url_job, get_url_logs, get_topo_arch from ..utils.url_processing import url_decode from .graphs import graph_statistics, select_data @@ -97,10 +98,10 @@ class Layout: d_job_info["dut"].append(lst_job[1]) d_job_info["ttype"].append(lst_job[3]) d_job_info["cadence"].append(lst_job[4]) - d_job_info["tbed"].append("-".join(lst_job[-2:])) + d_job_info["tbed"].append(get_topo_arch(lst_job)) self._job_info = pd.DataFrame.from_dict(d_job_info) - self._default = set_job_params(self._job_info, C.STATS_DEFAULT_JOB) + self._default = set_job_params(self._job_info, d_job_info["job"][0]) tst_info = { "job": list(), @@ -196,7 +197,7 @@ class Layout: "dd-tbeds-value": self._default["tbed"], "al-job-children": html.A( self._default["job"], - href=f"{C.URL_CICD}{self._default['job']}", + href=get_url_job(self._default["job"]), target="_blank" ) } @@ -630,10 +631,7 @@ class Layout: "dd-tbeds-value": job_params["tbed"], "al-job-children": html.A( self._default["job"], - href=( - f"{C.URL_CICD}" - f"{self._default['job']}" - ), + href=get_url_job(self._default["job"]), target="_blank" ) }, @@ -654,7 +652,7 @@ class Layout: { "al-job-children": html.A( job, - href=f"{C.URL_CICD}{job}", + href=get_url_job(job), target="_blank" ) } @@ -784,7 +782,7 @@ class Layout: dbc.Badge(lst_itm[0]), html.A( lst_itm[1], - href=f"{C.URL_LOGS}{lst_itm[1]}", + href=get_url_logs(lst_itm[1]), target="_blank" ) ]) diff --git a/csit.infra.dash/app/cdash/stats/layout.yaml b/csit.infra.dash/app/cdash/stats/layout.yaml index 488654640f..70ba940910 100644 --- a/csit.infra.dash/app/cdash/stats/layout.yaml +++ b/csit.infra.dash/app/cdash/stats/layout.yaml @@ -15,7 +15,7 @@ plot-stats-passed: xaxis: title: 'Date [MMDD]' type: "date" - autorange: True + autorange: False fixedrange: False showgrid: True gridcolor: "rgb(238, 238, 238)" @@ -56,7 +56,7 @@ plot-stats-duration: xaxis: title: 'Date [MMDD]' type: "date" - autorange: True + autorange: False fixedrange: False showgrid: True gridcolor: "rgb(238, 238, 238)" diff --git a/csit.infra.dash/app/cdash/trending/graphs.py b/csit.infra.dash/app/cdash/trending/graphs.py index 1a507dfeea..512a9d8de9 100644 --- a/csit.infra.dash/app/cdash/trending/graphs.py +++ b/csit.infra.dash/app/cdash/trending/graphs.py @@ -18,6 +18,10 @@ import logging import plotly.graph_objects as go import pandas as pd +from numpy import nan +from datetime import datetime +from pytz import UTC + from ..utils.constants import Constants as C from ..utils.utils import get_color, get_hdrh_latencies from ..utils.anomalies import classify_anomalies @@ -35,9 +39,9 @@ def select_trending_data(data: pd.DataFrame, itm: dict) -> pd.DataFrame: :rtype: pandas.DataFrame """ - phy = itm["phy"].split("-") - if len(phy) == 4: - topo, arch, nic, drv = phy + phy = itm["phy"].rsplit("-", maxsplit=2) + if len(phy) == 3: + topo_arch, nic, drv = phy if drv == "dpdk": drv = "" else: @@ -58,8 +62,8 @@ def select_trending_data(data: pd.DataFrame, itm: dict) -> pd.DataFrame: (data["test_type"] == test_type) & (data["passed"] == True) )] - df = df[df.job.str.endswith(f"{topo}-{arch}")] - core = str() if itm["dut"] == "trex" else f"{itm['core']}" + df = df[df.job.str.endswith(topo_arch)] + core = str() if itm["dut"] == "trex" else itm["core"] ttype = "ndrpdr" if itm["testtype"] in ("ndr", "pdr") else itm["testtype"] df = df[df.test_id.str.contains( f"^.*[.|-]{nic}.*{itm['framesize']}-{core}-{drv}{itm['test']}-{ttype}$", @@ -73,7 +77,8 @@ def graph_trending( data: pd.DataFrame, sel: dict, layout: dict, - normalize: bool=False + normalize: bool=False, + trials: bool=False ) -> tuple: """Generate the trending graph(s) - MRR, NDR, PDR and for PDR also Latences (result_latency_forward_pdr_50_avg). @@ -83,10 +88,12 @@ def graph_trending( :param layout: Layout of plot.ly graph. :param normalize: If True, the data is normalized to CPU frquency Constants.NORM_FREQUENCY. + :param trials: If True, MRR trials are displayed in the trending graph. :type data: pandas.DataFrame :type sel: dict :type layout: dict :type normalize: bool + :type: trials: bool :returns: Trending graph(s) :rtype: tuple(plotly.graph_objects.Figure, plotly.graph_objects.Figure) """ @@ -128,7 +135,8 @@ def graph_trending( customdata_samples = list() name_lst = name.split("-") for _, row in df.iterrows(): - h_tput, h_band, h_lat = str(), str(), str() + h_tput, h_band, h_lat, h_tput_trials, h_band_trials = \ + str(), str(), str(), str(), str() if ttype in ("mrr", "mrr-bandwidth"): h_tput = ( f"tput avg [{row['result_receive_rate_rate_unit']}]: " @@ -147,6 +155,23 @@ def graph_trending( f"{row['result_receive_rate_bandwidth_stdev']* nf:,.0f}" "<br>" ) + if trials: + h_tput_trials = ( + f"tput trials " + f"[{row['result_receive_rate_rate_unit']}]: " + ) + for itm in row["result_receive_rate_rate_values"]: + h_tput_trials += f"{itm * nf:,.0f}; " + h_tput_trials = h_tput_trials[:-2] + "<br>" + if pd.notna(row["result_receive_rate_bandwidth_avg"]): + h_band_trials = ( + f"bandwidth trials " + f"[{row['result_receive_rate_bandwidth_unit']}]: " + ) + for itm in row["result_receive_rate_bandwidth_values"]: + h_band_trials += f"{itm * nf:,.0f}; " + h_band_trials = h_band_trials[:-2] + "<br>" + elif ttype in ("ndr", "ndr-bandwidth"): h_tput = ( f"tput [{row['result_ndr_lower_rate_unit']}]: " @@ -214,12 +239,19 @@ def graph_trending( hosts = f"<br>hosts: {', '.join(row['hosts'])}" except (KeyError, TypeError): hosts = str() + + for drv in C.DRIVERS: + if drv in name_lst: + split_idx = name_lst.index(drv) + 1 + break + else: + split_idx = 5 hover_itm = ( f"dut: {name_lst[0]}<br>" - f"infra: {'-'.join(name_lst[1:5])}<br>" - f"test: {'-'.join(name_lst[5:])}<br>" + f"infra: {'-'.join(name_lst[1:split_idx])}<br>" + f"test: {'-'.join(name_lst[split_idx:])}<br>" f"date: {row['start_time'].strftime('%Y-%m-%d %H:%M:%S')}<br>" - f"{h_tput}{h_band}{h_lat}" + f"{h_tput}{h_tput_trials}{h_band}{h_band_trials}{h_lat}" f"{row['dut_type']}-ref: {row['dut_version']}<br>" f"csit-ref: {row['job']}/{row['build']}" f"{hosts}" @@ -279,7 +311,7 @@ def graph_trending( marker={ "size": 5, "color": color, - "symbol": "circle", + "symbol": "circle" }, text=hover, hoverinfo="text", @@ -369,18 +401,71 @@ def graph_trending( return traces, units + def _add_mrr_trials_traces( + ttype: str, + name: str, + df: pd.DataFrame, + color: str, + nf: float + ) -> list: + """Add the traces with mrr trials. + + :param ttype: Test type (mrr, mrr-bandwidth). + :param name: The test name to be displayed in hover. + :param df: Data frame with test data. + :param color: The color of the trace. + :param nf: The factor used for normalization of the results to + CPU frequency set to Constants.NORM_FREQUENCY. + :type ttype: str + :type name: str + :type df: pandas.DataFrame + :type color: str + :type nf: float + :returns: list of Traces + :rtype: list + """ + traces = list() + x_axis = df["start_time"].tolist() + y_data = df[C.VALUE[ttype].replace("avg", "values")].tolist() + + for idx_trial in range(10): + y_axis = list() + for idx_run in range(len(x_axis)): + try: + y_axis.append(y_data[idx_run][idx_trial] * nf) + except (IndexError, TypeError, ValueError): + y_axis.append(nan) + traces.append(go.Scatter( + x=x_axis, + y=y_axis, + name=name, + mode="markers", + marker={ + "size": 2, + "color": color, + "symbol": "circle" + }, + showlegend=True, + legendgroup=name, + hoverinfo="skip" + )) + return traces + + fig_tput = None fig_lat = None fig_band = None + start_times = list() y_units = set() for idx, itm in enumerate(sel): df = select_trending_data(data, itm) if df is None or df.empty: continue + start_times.append(df["start_time"][0]) if normalize: - phy = itm["phy"].split("-") - topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str() + phy = itm["phy"].rsplit("-", maxsplit=2) + topo_arch = phy[0] if len(phy) == 3 else str() norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY.get(topo_arch, 1.0)) \ if topo_arch else 1.0 else: @@ -401,6 +486,14 @@ def graph_trending( if traces: if not fig_tput: fig_tput = go.Figure() + if trials and "mrr" in ttype: + traces.extend(_add_mrr_trials_traces( + ttype, + itm["id"], + df, + get_color(idx), + norm_factor + )) fig_tput.add_traces(traces) if ttype in C.TESTS_WITH_BANDWIDTH: @@ -414,6 +507,14 @@ def graph_trending( if traces: if not fig_band: fig_band = go.Figure() + if trials and "mrr" in ttype: + traces.extend(_add_mrr_trials_traces( + f"{ttype}-bandwidth", + itm["id"], + df, + get_color(idx), + norm_factor + )) fig_band.add_traces(traces) if ttype in C.TESTS_WITH_LATENCY: @@ -431,15 +532,21 @@ def graph_trending( y_units.update(units) + x_range = [min(start_times), datetime.now(tz=UTC).strftime("%Y-%m-%d")] if fig_tput: - fig_layout = layout.get("plot-trending-tput", dict()) - fig_layout["yaxis"]["title"] = \ + layout_tput = layout.get("plot-trending-tput", dict()) + layout_tput["yaxis"]["title"] = \ f"Throughput [{'|'.join(sorted(y_units))}]" - fig_tput.update_layout(fig_layout) + layout_tput["xaxis"]["range"] = x_range + fig_tput.update_layout(layout_tput) if fig_band: - fig_band.update_layout(layout.get("plot-trending-bandwidth", dict())) + layout_band = layout.get("plot-trending-bandwidth", dict()) + layout_band["xaxis"]["range"] = x_range + fig_band.update_layout(layout_band) if fig_lat: - fig_lat.update_layout(layout.get("plot-trending-lat", dict())) + layout_lat = layout.get("plot-trending-lat", dict()) + layout_lat["xaxis"]["range"] = x_range + fig_lat.update_layout(layout_lat) return fig_tput, fig_band, fig_lat diff --git a/csit.infra.dash/app/cdash/trending/layout.py b/csit.infra.dash/app/cdash/trending/layout.py index da90ae26f9..1e2d4cdbd2 100644 --- a/csit.infra.dash/app/cdash/trending/layout.py +++ b/csit.infra.dash/app/cdash/trending/layout.py @@ -34,7 +34,7 @@ from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.telemetry_data import TelemetryData from ..utils.utils import show_tooltip, label, sync_checklists, gen_new_url, \ - generate_options, get_list_group_items, navbar_trending, \ + generate_options, get_list_group_items, navbar_trending, get_topo_arch, \ show_trending_graph_data from ..utils.url_processing import url_decode from .graphs import graph_trending, select_trending_data, graph_tm_trending @@ -65,7 +65,8 @@ CP_PARAMS = { "cl-tsttype-all-val": list(), "cl-tsttype-all-opt": C.CL_ALL_DISABLED, "btn-add-dis": True, - "cl-normalize-val": list() + "cl-normalize-val": list(), + "cl-show-trials": list() } @@ -115,7 +116,7 @@ class Layout: for _, row in self._data[cols].drop_duplicates().iterrows(): lst_job = row["job"].split("-") dut = lst_job[1] - tbed = "-".join(lst_job[-2:]) + tbed = get_topo_arch(lst_job) lst_test = row["test_id"].split(".") if dut == "dpdk": area = "dpdk" @@ -303,7 +304,7 @@ class Layout: :returns: Control panel. :rtype: list """ - return [ + test_selection = [ dbc.Row( dbc.InputGroup( [ @@ -459,37 +460,43 @@ class Layout: class_name="g-0 p-1" ), dbc.Row( - dbc.InputGroup( - [ - dbc.InputGroupText(show_tooltip( - self._tooltips, - "help-normalize", - "Normalization" - )), - dbc.Col(dbc.Checklist( - id="normalize", - options=[{ - "value": "normalize", - "label": "Normalize to CPU frequency 2GHz" - }], - value=[], - inline=True, - class_name="ms-2" - )) - ], - style={"align-items": "center"}, - size="sm" - ), - class_name="g-0 p-1" - ), - dbc.Row( dbc.Button( id={"type": "ctrl-btn", "index": "add-test"}, children="Add Selected", - color="info" + color="info", + class_name="p-1" ), class_name="g-0 p-1" - ), + ) + ] + processing = [ + dbc.Row( + class_name="g-0 p-1", + children=[ + dbc.Checklist( + id="normalize", + options=[{ + "value": "normalize", + "label": "Normalize to 2GHz CPU frequency" + }], + value=[], + inline=True, + class_name="ms-2" + ), + dbc.Checklist( + id="show-trials", + options=[{ + "value": "trials", + "label": "Show MRR Trials" + }], + value=[], + inline=True, + class_name="ms-2" + ) + ] + ) + ] + test_list = [ dbc.Row( dbc.ListGroup( class_name="overflow-auto p-0", @@ -498,39 +505,43 @@ class Layout: style={"max-height": "20em"}, flush=True ), - id="row-card-sel-tests", - class_name="g-0 p-1", - style=C.STYLE_DISABLED, + class_name="g-0 p-1" ), dbc.Row( - dbc.ButtonGroup([ - dbc.Button( - "Remove Selected", - id={"type": "ctrl-btn", "index": "rm-test"}, - class_name="w-100", - color="info", - disabled=False - ), - dbc.Button( - "Remove All", - id={"type": "ctrl-btn", "index": "rm-test-all"}, - class_name="w-100", - color="info", - disabled=False - ) - ]), - id="row-btns-sel-tests", - class_name="g-0 p-1", - style=C.STYLE_DISABLED, + dbc.ButtonGroup( + children=[ + dbc.Button( + "Remove Selected", + id={"type": "ctrl-btn", "index": "rm-test"}, + class_name="w-100 p-1", + color="info", + disabled=False + ), + dbc.Button( + "Remove All", + id={"type": "ctrl-btn", "index": "rm-test-all"}, + class_name="w-100 p-1", + color="info", + disabled=False + ) + ] + ), + class_name="g-0 p-1" ), dbc.Stack( [ dbc.Button( "Add Telemetry Panel", id={"type": "telemetry-btn", "index": "open"}, - color="info" + color="info", + class_name="p-1" + ), + dbc.Button( + "Show URL", + id="plot-btn-url", + color="info", + class_name="p-1" ), - dbc.Button("Show URL", id="plot-btn-url", color="info"), dbc.Modal( [ dbc.ModalHeader(dbc.ModalTitle("URL")), @@ -542,13 +553,64 @@ class Layout: scrollable=True ) ], - id="row-btns-add-tm", class_name="g-0 p-1", - style=C.STYLE_DISABLED, gap=2 ) ] + return [ + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Test Selection") + ), + dbc.CardBody( + children=test_selection, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + class_name="g-0 p-1" + ), + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Data Manipulations") + ), + dbc.CardBody( + children=processing, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + class_name="g-0 p-1" + ), + dbc.Row( + dbc.Card( + [ + dbc.CardHeader( + html.H5("Selected Tests") + ), + dbc.CardBody( + children=test_list, + class_name="g-0 p-0" + ) + ], + color="secondary", + outline=True + ), + id = "row-selected-tests", + class_name="g-0 p-1", + style=C.STYLE_DISABLED, + ) + ] + def _add_plotting_col(self) -> dbc.Col: """Add column with plots. It is placed on the right side. @@ -919,9 +981,7 @@ class Layout: Output("plotting-area-trending", "children"), Output("plotting-area-telemetry", "children"), Output("col-plotting-area", "style"), - Output("row-card-sel-tests", "style"), - Output("row-btns-sel-tests", "style"), - Output("row-btns-add-tm", "style"), + Output("row-selected-tests", "style"), Output("lg-selected", "children"), Output({"type": "telemetry-search-out", "index": ALL}, "children"), Output({"type": "plot-mod-telemetry", "index": ALL}, "is_open"), @@ -952,6 +1012,7 @@ class Layout: Output({"type": "ctrl-cl", "index": "tsttype-all"}, "options"), Output({"type": "ctrl-btn", "index": "add-test"}, "disabled"), Output("normalize", "value"), + Output("show-trials", "value"), State("store", "data"), State({"type": "sel-cl", "index": ALL}, "value"), @@ -968,6 +1029,7 @@ class Layout: Input({"type": "tm-dd", "index": ALL}, "value"), Input("normalize", "value"), + Input("show-trials", "value"), Input({"type": "telemetry-search-in", "index": ALL}, "value"), Input({"type": "telemetry-btn", "index": ALL}, "n_clicks"), Input({"type": "tm-btn-remove", "index": ALL}, "n_clicks"), @@ -1054,9 +1116,12 @@ class Layout: trigger = Trigger(callback_context.triggered) if trigger.type == "url" and url_params: telemetry = None + normalize = list() + show_trials = list() try: store_sel = literal_eval(url_params["store_sel"][0]) normalize = literal_eval(url_params["norm"][0]) + show_trials = literal_eval(url_params["show-trials"][0]) telemetry = literal_eval(url_params["telemetry"][0]) url_p = url_params.get("all-in-one", ["[[None]]"]) tm_all_in_one = literal_eval(url_p[0]) @@ -1103,6 +1168,7 @@ class Layout: "cl-tsttype-all-val": list(), "cl-tsttype-all-opt": C.CL_ALL_ENABLED, "cl-normalize-val": normalize, + "cl-show-trials": show_trials, "btn-add-dis": False }) store["trending-graphs"] = None @@ -1119,6 +1185,10 @@ class Layout: ctrl_panel.set({"cl-normalize-val": trigger.value}) store["trending-graphs"] = None on_draw[0] = True + elif trigger.type == "show-trials": + ctrl_panel.set({"cl-show-trials": trigger.value}) + store["trending-graphs"] = None + on_draw[0] = True elif trigger.type == "ctrl-dd": if trigger.idx == "dut": try: @@ -1414,7 +1484,8 @@ class Layout: new_url_params = { "store_sel": store_sel, - "norm": ctrl_panel.get("cl-normalize-val") + "norm": ctrl_panel.get("cl-normalize-val"), + "show-trials": ctrl_panel.get("cl-show-trials") } if tm_panels: new_url_params["telemetry"] = tm_panels @@ -1431,7 +1502,8 @@ class Layout: self._data, store_sel, self._graph_layout, - bool(ctrl_panel.get("cl-normalize-val")) + bool(ctrl_panel.get("cl-normalize-val")), + bool(ctrl_panel.get("cl-show-trials")) ) if graphs and graphs[0]: store["trending-graphs"] = graphs @@ -1462,16 +1534,12 @@ class Layout: store["telemetry-graphs"] ) col_plotting_area = C.STYLE_ENABLED - row_card_sel_tests = C.STYLE_ENABLED - row_btns_sel_tests = C.STYLE_ENABLED - row_btns_add_tm = C.STYLE_ENABLED + row_selected_tests = C.STYLE_ENABLED else: plotting_area_trending = no_update plotting_area_telemetry = C.PLACEHOLDER col_plotting_area = C.STYLE_DISABLED - row_card_sel_tests = C.STYLE_DISABLED - row_btns_sel_tests = C.STYLE_DISABLED - row_btns_add_tm = C.STYLE_DISABLED + row_selected_tests = C.STYLE_DISABLED lg_selected = no_update store_sel = list() tm_panels = list() @@ -1481,9 +1549,7 @@ class Layout: else: plotting_area_trending = no_update col_plotting_area = no_update - row_card_sel_tests = no_update - row_btns_sel_tests = no_update - row_btns_add_tm = no_update + row_selected_tests = no_update lg_selected = no_update store["url"] = gen_new_url(parsed_url, new_url_params) @@ -1499,9 +1565,7 @@ class Layout: plotting_area_trending, plotting_area_telemetry, col_plotting_area, - row_card_sel_tests, - row_btns_sel_tests, - row_btns_add_tm, + row_selected_tests, lg_selected, search_out, is_open, diff --git a/csit.infra.dash/app/cdash/trending/layout.yaml b/csit.infra.dash/app/cdash/trending/layout.yaml index e4fcd29260..948ca9372b 100644 --- a/csit.infra.dash/app/cdash/trending/layout.yaml +++ b/csit.infra.dash/app/cdash/trending/layout.yaml @@ -16,7 +16,7 @@ plot-trending-tput: xaxis: title: 'Date [MMDD]' type: "date" - autorange: True + autorange: False fixedrange: False showgrid: True gridcolor: "rgb(238, 238, 238)" @@ -56,7 +56,7 @@ plot-trending-bandwidth: xaxis: title: 'Date [MMDD]' type: "date" - autorange: True + autorange: False fixedrange: False showgrid: True gridcolor: "rgb(238, 238, 238)" @@ -96,7 +96,7 @@ plot-trending-lat: xaxis: title: 'Date [MMDD]' type: "date" - autorange: True + autorange: False fixedrange: False showgrid: True gridcolor: "rgb(238, 238, 238)" diff --git a/csit.infra.dash/app/cdash/utils/constants.py b/csit.infra.dash/app/cdash/utils/constants.py index bafa7b7f42..444ccd3981 100644 --- a/csit.infra.dash/app/cdash/utils/constants.py +++ b/csit.infra.dash/app/cdash/utils/constants.py @@ -118,15 +118,18 @@ class Constants: # External stylesheets. EXTERNAL_STYLESHEETS = ["/static/dist/css/bootstrap.css", ] - # URL to Jenkins + # CICD type. + CICD_TYPE = get_str_from_env("CICD_TYPE", "jenkins") + + # URL to CICD. URL_CICD = get_str_from_env("URL_CICD", "https://jenkins.fd.io/job/") - # URL to logs + # URL to logs. URL_LOGS = get_str_from_env( "URL_LOGS", "https://logs.fd.io/vex-yul-rot-jenkins-1/" ) - # URL to the documentation + # URL to the documentation. URL_DOC = get_str_from_env("URL_DOC", "https://csit.fd.io/cdocs/") URL_DOC_TRENDING = URL_DOC + "methodology/trending/analysis/" URL_DOC_REL_NOTES = URL_DOC + "release_notes/current/" @@ -328,7 +331,7 @@ class Constants: } VALUE_ITER = { - "mrr": "result_receive_rate_rate_values", + "mrr": "result_receive_rate_rate_avg", "ndr": "result_ndr_lower_rate_value", "pdr": "result_pdr_lower_rate_value", "mrr-bandwidth": "result_receive_rate_bandwidth_avg", @@ -490,9 +493,6 @@ class Constants: # Layout of plot.ly graphs. STATS_GRAPH_LAYOUT_FILE = "cdash/stats/layout.yaml" - # The default job displayed when the page is loaded first time. - STATS_DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx" - # Default name of downloaded file with selected data. STATS_DOWNLOAD_FILE_NAME = "stats.csv" diff --git a/csit.infra.dash/app/cdash/utils/telemetry_data.py b/csit.infra.dash/app/cdash/utils/telemetry_data.py index 9975874d96..d3a114c596 100644 --- a/csit.infra.dash/app/cdash/utils/telemetry_data.py +++ b/csit.infra.dash/app/cdash/utils/telemetry_data.py @@ -64,7 +64,7 @@ class TelemetryData: df = pd.concat(lst_items, ignore_index=True, copy=False) # Use only neccessary data: - df = df[[ + df = df[df.columns.intersection([ "job", "build", "dut_type", @@ -81,7 +81,8 @@ class TelemetryData: "result_ndr_lower_rate_value", "result_ndr_lower_rate_unit", "telemetry" - ]] + ])] + # Transform metrics from strings to dataframes: lst_telemetry = list() for _, row in df.iterrows(): @@ -91,7 +92,7 @@ class TelemetryData: "value": list(), "timestamp": list() } - + # If there is no telemetry data, use empty dictionary if row["telemetry"] is None or isinstance(row["telemetry"], float): lst_telemetry.append(pd.DataFrame(data=d_telemetry)) @@ -282,8 +283,11 @@ class TelemetryData: for _, row in self._unique_metrics_labels.iterrows(): if _is_selected(row["labels"], selection): lst_items.append(row.to_frame().T) - self._selected_metrics_labels = \ - pd.concat(lst_items, ignore_index=True, axis=0, copy=False) + if len(lst_items) == 1: + self._selected_metrics_labels = lst_items[0] + elif len(lst_items) > 1: + self._selected_metrics_labels = \ + pd.concat(lst_items, ignore_index=True, axis=0, copy=False) return self._selected_metrics_labels def select_tm_trending_data( diff --git a/csit.infra.dash/app/cdash/utils/utils.py b/csit.infra.dash/app/cdash/utils/utils.py index e203dfbccd..8171c905c3 100644 --- a/csit.infra.dash/app/cdash/utils/utils.py +++ b/csit.infra.dash/app/cdash/utils/utils.py @@ -286,12 +286,13 @@ def set_job_params(df: pd.DataFrame, job: str) -> dict: """ l_job = job.split("-") + idx = -3 if "-x-" in job else -2 return { "job": job, "dut": l_job[1], "ttype": l_job[3], "cadence": l_job[4], - "tbed": "-".join(l_job[-2:]), + "tbed": "-".join(l_job[idx:]), "duts": generate_options(get_duts(df)), "ttypes": generate_options(get_ttypes(df, l_job[1])), "cadences": generate_options(get_cadences(df, l_job[1], l_job[3])), @@ -720,7 +721,7 @@ def show_trending_graph_data( dbc.Badge(lst_itm[0]), html.A( lst_itm[1], - href=f"{C.URL_LOGS}{lst_itm[1]}", + href=get_url_logs(lst_itm[1]), target="_blank" ) ]) @@ -852,7 +853,7 @@ def show_iterative_graph_data( continue list_group_item = dbc.ListGroupItem([ dbc.Badge(k), - html.A(v, href=f"{C.URL_LOGS}{v}", target="_blank") + html.A(v, href=get_url_logs(v), target="_blank") ]) else: list_group_item = dbc.ListGroupItem([dbc.Badge(k), v]) @@ -903,3 +904,67 @@ def show_iterative_graph_data( ] return metadata, graph, True + + +def get_url_job(job: str) -> str: + """Generates a URL to CI/CD job. + + :param job: The name of job. + :type job: str + :raises KeyError: If the job name is not a valid job name. + :returns: The URL to CI/CD job. + """ + + if C.CICD_TYPE == "jenkins": + return f"{C.URL_CICD}{job}" + elif C.CICD_TYPE == "github": + l_j = job.split("-") + try: + return f"{C.URL_CICD}{l_j[0]}-{l_j[1]}-{l_j[2]}-{l_j[4]}.yml" + except KeyError: + return str() + else: + return str() + + +def get_url_logs(job_build: str) -> str: + """Generates a URL to CI/CD job and its build. + + :param job_build: The name of job and number of build. Its structure is: + "<job name>/<build number>". + :type job: str + :raises KeyError: If the job name is not a valid job name. + :returns: The URL to CI/CD build. + """ + + if C.CICD_TYPE == "jenkins": + return f"{C.URL_LOGS}{job_build}" + elif C.CICD_TYPE == "github": + try: + return f"{C.URL_LOGS}{job_build.split('/')[1]}" + except KeyError: + return str() + else: + return str() + + +def get_topo_arch(lst_job: list) -> str: + """Get the topology and architecture string from the job name. + + :param lst_job: The job name split into substrings. + :type lst_job: list + :returns: String with information about topology and architecture. + :rtype: str + """ + + if len(lst_job) < 2: + return str() + + if "x" in lst_job[1:-1]: + # External testbeds. + # The structure of the name: + # <to be removed>-x-<topo>-<arch>-<other parts separated by dashes> + return "-".join(lst_job[(lst_job.index("x") + 1):]) + else: + # Topology and architecture are the last two substrings. + return "-".join(lst_job[-2:]) diff --git a/csit.infra.dash/app/requirements.txt b/csit.infra.dash/app/requirements.txt index edea01075d..7dfd7c8ccf 100644 --- a/csit.infra.dash/app/requirements.txt +++ b/csit.infra.dash/app/requirements.txt @@ -1,58 +1,60 @@ # AWS integration -awswrangler==3.2.1 -pip==23.2.1 +awswrangler==3.9.0 +pip==24.1.2 # Dash integration -dash==2.11.1 -dash-bootstrap-components==1.4.2 +dash==2.17.1 +dash-bootstrap-components==1.6.0 dash-core-components==2.0.0 dash-html-components==2.0.0 dash-renderer==1.9.1 dash-table==5.0.0 -numpy==1.25.2 -pandas==2.0.3 -plotly==5.15.0 -numexpr==2.8.4 -Bottleneck==1.3.7 +numpy==1.26.4 # awswrangler 3.9.0 depends on numpy<2.0 and >=1.18 +pandas==2.2.2 +plotly==5.23.0 +numexpr==2.10.1 +Bottleneck==1.4.0 # Web Application Integration -Flask==2.2.5 -Flask-Assets==2.0 -Flask-Compress==1.13 -Jinja2==3.1.2 -libsass==0.22.0 -uWSGI==2.0.22 -uwsgitop==0.11 +Flask==3.0.3 +Flask-Assets==2.1.0 +Flask-Compress==1.15 +Jinja2==3.1.4 +libsass==0.23.0 +uWSGI==2.0.26 +uwsgitop==0.12 webassets==2.0 # Web Application Dependencies -hdrhistogram==0.10.2 -python-dateutil==2.8.2 +hdrhistogram==0.10.3 +python-dateutil==2.9.0 PyYAML==6.0.1 # PIP freeze -ansi2html==1.8.0 -boto3==1.28.17 -botocore==1.31.17 -Brotli==1.0.9 -certifi==2023.7.22 -charset-normalizer==3.2.0 -click==8.1.6 -idna==3.4 -itsdangerous==2.1.2 +blinker==1.8.2 +boto3==1.34.149 +Brotli==1.1.0 +certifi==2024.7.4 +charset-normalizer==3.3.2 +click==8.1.7 +idna==3.7 +importlib_metadata==8.2.0 +itsdangerous==2.2.0 jmespath==1.0.1 -MarkupSafe==2.1.3 -nest-asyncio==1.5.7 -packaging==23.1 -pbr==5.11.1 -pyarrow==12.0.1 -pytz==2023.3 -requests==2.31.0 +MarkupSafe==2.1.5 +nest-asyncio==1.6.0 +packaging==24.1 +pbr==6.0.0 +pyarrow==17.0.0 +pytz==2024.1 +requests==2.32.3 retrying==1.3.4 -s3transfer==0.6.1 +s3transfer==0.10.2 six==1.16.0 -tenacity==8.2.2 -typing_extensions==4.7.1 -tzdata==2023.3 -urllib3==1.26.16 -Werkzeug==2.2.3
\ No newline at end of file +tenacity==8.5.0 +typing_extensions==4.12.2 +tzdata==2024.1 +urllib3==2.2.2 +Werkzeug==3.0.3 +zipp==3.19.2 +zstandard==0.23.0 |