feat(uti): Add statistical graphs 72/36172/10
authorTibor Frank <tifrank@cisco.com>
Thu, 19 May 2022 12:24:15 +0000 (14:24 +0200)
committerTibor Frank <tifrank@cisco.com>
Thu, 9 Jun 2022 11:00:10 +0000 (11:00 +0000)
Change-Id: Ia2831cfbcb9e2333c5b49af5c6b0577867d99902
Signed-off-by: Tibor Frank <tifrank@cisco.com>
resources/tools/dash/app/pal/__init__.py
resources/tools/dash/app/pal/report/graphs.py
resources/tools/dash/app/pal/report/layout.py
resources/tools/dash/app/pal/report/layout.yaml
resources/tools/dash/app/pal/templates/index_layout.jinja2
resources/tools/dash/app/pal/trending/graphs.py

index bb110a2..cb12b7d 100644 (file)
@@ -33,7 +33,7 @@ TIME_PERIOD = MAX_TIME_PERIOD  # [days]
 # List of releases used for iterative data processing.
 # The releases MUST be in the order from the current (newest) to the last
 # (oldest).
-RELEASES=["rls2202", ]
+RELEASES=["rls2206", "rls2202", ]
 
 def init_app():
     """Construct core Flask application with embedded Dash app.
index 751eb34..42ae079 100644 (file)
 """
 """
 
+import re
 import plotly.graph_objects as go
 import pandas as pd
 
+from copy import deepcopy
+
 import hdrh.histogram
 import hdrh.codec
 
 
-_COLORS = (
-    u"#1A1110", u"#DA2647", u"#214FC6", u"#01786F", u"#BD8260", u"#FFD12A",
-    u"#A6E7FF", u"#738276", u"#C95A49", u"#FC5A8D", u"#CEC8EF", u"#391285",
-    u"#6F2DA8", u"#FF878D", u"#45A27D", u"#FFD0B9", u"#FD5240", u"#DB91EF",
-    u"#44D7A8", u"#4F86F7", u"#84DE02", u"#FFCFF1", u"#614051"
-)
 _VALUE = {
-    "mrr": "result_receive_rate_rate_avg",
+    "mrr": "result_receive_rate_rate_values",
     "ndr": "result_ndr_lower_rate_value",
     "pdr": "result_pdr_lower_rate_value",
     "pdr-lat": "result_latency_forward_pdr_50_avg"
@@ -63,6 +60,37 @@ _GRAPH_LAT_HDRH_DESC = {
     u"result_latency_forward_pdr_90_hdrh": u"High-load, 90% PDR.",
     u"result_latency_reverse_pdr_90_hdrh": u"High-load, 90% PDR."
 }
+REG_EX_VPP_VERSION = re.compile(r"^(\d{2}).(\d{2})-(rc0|rc1|rc2|release$)")
+
+
+def _get_color(idx: int) -> str:
+    """
+    """
+    _COLORS = (
+        "#1A1110", "#DA2647", "#214FC6", "#01786F", "#BD8260", "#FFD12A",
+        "#A6E7FF", "#738276", "#C95A49", "#FC5A8D", "#CEC8EF", "#391285",
+        "#6F2DA8", "#FF878D", "#45A27D", "#FFD0B9", "#FD5240", "#DB91EF",
+        "#44D7A8", "#4F86F7", "#84DE02", "#FFCFF1", "#614051"
+    )
+    return _COLORS[idx % len(_COLORS)]
+
+
+def get_short_version(version: str, dut_type: str="vpp") -> str:
+    """
+    """
+
+    if dut_type in ("trex", "dpdk"):
+        return version
+
+    s_version = str()
+    groups = re.search(pattern=REG_EX_VPP_VERSION, string=version)
+    if groups:
+        try:
+            s_version = f"{groups.group(1)}.{groups.group(2)}_{groups.group(3)}"
+        except IndexError:
+            pass
+
+    return s_version
 
 
 def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame:
@@ -82,18 +110,31 @@ def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame:
 
     core = str() if itm["dut"] == "trex" else f"{itm['core']}"
     ttype = "ndrpdr" if itm["testtype"] in ("ndr", "pdr") else itm["testtype"]
-    dut = "none" if itm["dut"] == "trex" else itm["dut"].upper()
+    dut_v100 = "none" if itm["dut"] == "trex" else itm["dut"]
+    dut_v101 = itm["dut"]
 
     df = data.loc[(
-        (data["dut_type"] == dut) &
+        (data["release"] == itm["rls"]) &
+        (
+            (
+                (data["version"] == "1.0.0") &
+                (data["dut_type"].str.lower() == dut_v100)
+            ) |
+            (
+                (data["version"] == "1.0.1") &
+                (data["dut_type"].str.lower() == dut_v101)
+            )
+        ) &
         (data["test_type"] == ttype) &
         (data["passed"] == True)
     )]
-    df = df[df.job.str.endswith(f"{topo}-{arch}")]
-    df = df[df.test_id.str.contains(
-        f"^.*[.|-]{nic}.*{itm['framesize']}-{core}-{drv}{itm['test']}-{ttype}$",
-        regex=True
-    )].sort_values(by="start_time", ignore_index=True)
+    regex_test = \
+        f"^.*[.|-]{nic}.*{itm['framesize']}-{core}-{drv}{itm['test']}-{ttype}$"
+    df = df[
+        (df.job.str.endswith(f"{topo}-{arch}")) &
+        (df.dut_version.str.contains(itm["dutver"].replace("_", "-"))) &
+        (df.test_id.str.contains(regex_test, regex=True))
+    ]
 
     return df
 
@@ -102,56 +143,129 @@ def graph_iterative(data: pd.DataFrame, sel:dict, layout: dict) -> tuple:
     """
     """
 
-    fig_tput = go.Figure()
-    fig_tsa = go.Figure()
+    fig_tput = None
+    fig_lat = None
+
+    tput_traces = list()
+    y_tput_max = 0
+    lat_traces = list()
+    y_lat_max = 0
+    x_lat = list()
+    for idx, itm in enumerate(sel):
+        itm_data = select_iterative_data(data, itm)
+        if itm["testtype"] == "mrr":
+            y_data = itm_data[_VALUE[itm["testtype"]]].to_list()[0]
+            if y_data.size > 0:
+                y_tput_max = \
+                    max(y_data) if max(y_data) > y_tput_max else y_tput_max
+        else:
+            y_data = itm_data[_VALUE[itm["testtype"]]].to_list()
+            if y_data:
+                y_tput_max = \
+                    max(y_data) if max(y_data) > y_tput_max else y_tput_max
+        nr_of_samples = len(y_data)
+        tput_kwargs = dict(
+            y=y_data,
+            name=(
+                f"{idx + 1}. "
+                f"({nr_of_samples:02d} "
+                f"run{u's' if nr_of_samples > 1 else u''}) "
+                f"{itm['id']}"
+            ),
+            hoverinfo=u"y+name",
+            boxpoints="all",
+            jitter=0.3,
+            marker=dict(color=_get_color(idx))
+        )
+        tput_traces.append(go.Box(**tput_kwargs))
+
+        show_latency = False
+        if itm["testtype"] == "pdr":
+            y_lat = itm_data[_VALUE["pdr-lat"]].to_list()
+            if y_lat:
+                y_lat_max = max(y_lat) if max(y_lat) > y_lat_max else y_lat_max
+            nr_of_samples = len(y_lat)
+            lat_kwargs = dict(
+                y=y_lat,
+                name=(
+                    f"{idx + 1}. "
+                    f"({nr_of_samples:02d} "
+                    f"run{u's' if nr_of_samples > 1 else u''}) "
+                    f"{itm['id']}"
+                ),
+                hoverinfo=u"y+name",
+                boxpoints="all",
+                jitter=0.3,
+                marker=dict(color=_get_color(idx))
+            )
+            x_lat.append(idx + 1)
+            lat_traces.append(go.Box(**lat_kwargs))
+            show_latency = True
+        else:
+            lat_traces.append(go.Box())
 
-    return fig_tput, fig_tsa
+    pl_tput = deepcopy(layout["plot-throughput"])
+    pl_tput[u"xaxis"][u"tickvals"] = [i for i in range(len(sel))]
+    pl_tput[u"xaxis"][u"ticktext"] = [str(i + 1) for i in range(len(sel))]
+    if y_tput_max:
+        pl_tput[u"yaxis"][u"range"] = [0, (int(y_tput_max / 1e6) + 1) * 1e6]
+    fig_tput = go.Figure(data=tput_traces, layout=pl_tput)
+
+    if show_latency:
+        pl_lat = deepcopy(layout["plot-latency"])
+        pl_lat[u"xaxis"][u"tickvals"] = [i for i in range(len(x_lat))]
+        pl_lat[u"xaxis"][u"ticktext"] = x_lat
+        if y_lat_max:
+            pl_lat[u"yaxis"][u"range"] = [0, (int(y_lat_max / 10) + 1) * 10]
+        fig_lat = go.Figure(data=lat_traces, layout=pl_lat)
+
+    return fig_tput, fig_lat
 
 
 def table_comparison(data: pd.DataFrame, sel:dict) -> pd.DataFrame:
     """
     """
     table = pd.DataFrame(
-    {
-        "Test Case": [
-            "64b-2t1c-avf-eth-l2xcbase-eth-2memif-1dcr",
-            "64b-2t1c-avf-eth-l2xcbase-eth-2vhostvr1024-1vm-vppl2xc",
-            "64b-2t1c-avf-ethip4udp-ip4base-iacl50sl-10kflows",
-            "78b-2t1c-avf-ethip6-ip6scale2m-rnd "],
-        "2106.0-8": [
-            "14.45 +- 0.08",
-            "9.63 +- 0.05",
-            "9.7 +- 0.02",
-            "8.95 +- 0.06"],
-        "2110.0-8": [
-            "14.45 +- 0.08",
-            "9.63 +- 0.05",
-            "9.7 +- 0.02",
-            "8.95 +- 0.06"],
-        "2110.0-9": [
-            "14.45 +- 0.08",
-            "9.63 +- 0.05",
-            "9.7 +- 0.02",
-            "8.95 +- 0.06"],
-        "2202.0-9": [
-            "14.45 +- 0.08",
-            "9.63 +- 0.05",
-            "9.7 +- 0.02",
-            "8.95 +- 0.06"],
-        "2110.0-9 vs 2110.0-8": [
-            "-0.23 +-  0.62",
-            "-1.37 +-   1.3",
-            "+0.08 +-   0.2",
-            "-2.16 +-  0.83"],
-        "2202.0-9 vs 2110.0-9": [
-            "+6.95 +-  0.72",
-            "+5.35 +-  1.26",
-            "+4.48 +-  1.48",
-            "+4.09 +-  0.95"]
-    }
-)
+        {
+            "Test Case": [
+                "64b-2t1c-avf-eth-l2xcbase-eth-2memif-1dcr",
+                "64b-2t1c-avf-eth-l2xcbase-eth-2vhostvr1024-1vm-vppl2xc",
+                "64b-2t1c-avf-ethip4udp-ip4base-iacl50sl-10kflows",
+                "78b-2t1c-avf-ethip6-ip6scale2m-rnd "],
+            "2106.0-8": [
+                "14.45 +- 0.08",
+                "9.63 +- 0.05",
+                "9.7 +- 0.02",
+                "8.95 +- 0.06"],
+            "2110.0-8": [
+                "14.45 +- 0.08",
+                "9.63 +- 0.05",
+                "9.7 +- 0.02",
+                "8.95 +- 0.06"],
+            "2110.0-9": [
+                "14.45 +- 0.08",
+                "9.63 +- 0.05",
+                "9.7 +- 0.02",
+                "8.95 +- 0.06"],
+            "2202.0-9": [
+                "14.45 +- 0.08",
+                "9.63 +- 0.05",
+                "9.7 +- 0.02",
+                "8.95 +- 0.06"],
+            "2110.0-9 vs 2110.0-8": [
+                "-0.23 +-  0.62",
+                "-1.37 +-   1.3",
+                "+0.08 +-   0.2",
+                "-2.16 +-  0.83"],
+            "2202.0-9 vs 2110.0-9": [
+                "+6.95 +-  0.72",
+                "+5.35 +-  1.26",
+                "+4.48 +-  1.48",
+                "+4.09 +-  0.95"]
+        }
+    )
 
-    return table
+    return pd.DataFrame()  #table
 
 
 def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
@@ -206,7 +320,7 @@ def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
                 legendgroup=_GRAPH_LAT_HDRH_DESC[lat_name],
                 showlegend=bool(idx % 2),
                 line=dict(
-                    color=_COLORS[int(idx/2)],
+                    color=_get_color(int(idx/2)),
                     dash=u"solid",
                     width=1 if idx % 2 else 2
                 ),
index 26b9a9f..ef98b7b 100644 (file)
@@ -33,7 +33,7 @@ from pprint import pformat
 
 from ..data.data import Data
 from ..data.url_processing import url_decode, url_encode
-from .graphs import graph_iterative, table_comparison
+from .graphs import graph_iterative, table_comparison, get_short_version
 
 
 class Layout:
@@ -116,9 +116,9 @@ class Layout:
         for _, row in self._data[cols].drop_duplicates().iterrows():
             rls = row["release"]
             ttype = row["test_type"]
-            d_ver = row["dut_version"]
             lst_job = row["job"].split("-")
             dut = lst_job[1]
+            d_ver = get_short_version(row["dut_version"], dut)
             tbed = "-".join(lst_job[-2:])
             lst_test_id = row["test_id"].split(".")
             if dut == "dpdk":
@@ -131,10 +131,7 @@ class Layout:
             nic = suite.split("-")[0]
             for drv in self.DRIVERS:
                 if drv in test:
-                    if drv == "af-xdp":
-                        driver = "af_xdp"
-                    else:
-                        driver = drv
+                    driver = drv.replace("-", "_")
                     test = test.replace(f"{drv}-", "")
                     break
             else:
@@ -157,20 +154,27 @@ class Layout:
                 tbs[rls][dut][d_ver][infra][area] = dict()
             if tbs[rls][dut][d_ver][infra][area].get(test, None) is None:
                 tbs[rls][dut][d_ver][infra][area][test] = dict()
-                tbs_test = tbs[rls][dut][d_ver][infra][area][test]
-                tbs_test["core"] = list()
-                tbs_test["frame-size"] = list()
-                tbs_test["test-type"] = list()
-            if core.upper() not in tbs_test["core"]:
-                tbs_test["core"].append(core.upper())
-            if framesize.upper() not in tbs_test["frame-size"]:
-                tbs_test["frame-size"].append(framesize.upper())
+                tbs[rls][dut][d_ver][infra][area][test]["core"] = list()
+                tbs[rls][dut][d_ver][infra][area][test]["frame-size"] = list()
+                tbs[rls][dut][d_ver][infra][area][test]["test-type"] = list()
+            if core.upper() not in \
+                    tbs[rls][dut][d_ver][infra][area][test]["core"]:
+                tbs[rls][dut][d_ver][infra][area][test]["core"].append(
+                    core.upper())
+            if framesize.upper() not in \
+                        tbs[rls][dut][d_ver][infra][area][test]["frame-size"]:
+                tbs[rls][dut][d_ver][infra][area][test]["frame-size"].append(
+                    framesize.upper())
             if ttype == "mrr":
-                if "MRR" not in tbs_test["test-type"]:
-                    tbs_test["test-type"].append("MRR")
+                if "MRR" not in \
+                        tbs[rls][dut][d_ver][infra][area][test]["test-type"]:
+                    tbs[rls][dut][d_ver][infra][area][test]["test-type"].append(
+                        "MRR")
             elif ttype == "ndrpdr":
-                if "NDR" not in tbs_test["test-type"]:
-                    tbs_test["test-type"].extend(("NDR", "PDR", ))
+                if "NDR" not in \
+                        tbs[rls][dut][d_ver][infra][area][test]["test-type"]:
+                    tbs[rls][dut][d_ver][infra][area][test]["test-type"].extend(
+                        ("NDR", "PDR", ))
         self._spec_tbs = tbs
 
         # Read from files:
@@ -366,8 +370,8 @@ class Layout:
                                     width=6
                                 ),
                                 dbc.Col(
-                                    dbc.Row(  # TSA
-                                        id="row-graph-tsa",
+                                    dbc.Row(  # Latency
+                                        id="row-graph-lat",
                                         class_name="g-0 p-2",
                                         children=[
                                             self.PLACEHOLDER
@@ -787,10 +791,10 @@ class Layout:
             """
             """
 
-            (fig_tput, fig_tsa) = figs
+            (fig_tput, fig_lat) = figs
 
             row_fig_tput = self.PLACEHOLDER
-            row_fig_tsa = self.PLACEHOLDER
+            row_fig_lat = self.PLACEHOLDER
             row_table = self.PLACEHOLDER
             row_btn_dwnld = self.PLACEHOLDER
 
@@ -840,11 +844,11 @@ class Layout:
                         ]
                     )
                 ]
-            if fig_tsa:
-                row_fig_tsa = [
+            if fig_lat:
+                row_fig_lat = [
                     dcc.Graph(
                         id={"type": "graph", "index": "lat"},
-                        figure=fig_tsa
+                        figure=fig_lat
                     )
                 ]
             if not table.empty:
@@ -858,13 +862,13 @@ class Layout:
                     )
                 ]
 
-            return row_fig_tput, row_fig_tsa, row_table, row_btn_dwnld
+            return row_fig_tput, row_fig_lat, row_table, row_btn_dwnld
 
         @app.callback(
             Output("control-panel", "data"),  # Store
             Output("selected-tests", "data"),  # Store
             Output("row-graph-tput", "children"),
-            Output("row-graph-tsa", "children"),
+            Output("row-graph-lat", "children"),
             Output("row-table", "children"),
             Output("row-btn-download", "children"),
             Output("row-card-sel-tests", "style"),
@@ -950,7 +954,7 @@ class Layout:
             parsed_url = url_decode(href)
 
             row_fig_tput = no_update
-            row_fig_tsa = no_update
+            row_fig_lat = no_update
             row_table = no_update
             row_btn_dwnld = no_update
             row_card_sel_tests = no_update
@@ -1282,7 +1286,7 @@ class Layout:
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                     })
-                    row_fig_tput, row_fig_tsa, row_table, row_btn_dwnld = \
+                    row_fig_tput, row_fig_lat, row_table, row_btn_dwnld = \
                         _generate_plotting_area(
                             graph_iterative(self.data, store_sel, self.layout),
                             table_comparison(self.data, store_sel),
@@ -1291,7 +1295,7 @@ class Layout:
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
                 row_fig_tput = self.PLACEHOLDER
-                row_fig_tsa = self.PLACEHOLDER
+                row_fig_lat = self.PLACEHOLDER
                 row_table = self.PLACEHOLDER
                 row_btn_dwnld = self.PLACEHOLDER
                 row_card_sel_tests = self.STYLE_DISABLED
@@ -1307,7 +1311,7 @@ class Layout:
                             new_store_sel.append(item)
                     store_sel = new_store_sel
                 if store_sel:
-                    row_fig_tput, row_fig_tsa, row_table, row_btn_dwnld = \
+                    row_fig_tput, row_fig_lat, row_table, row_btn_dwnld = \
                         _generate_plotting_area(
                             graph_iterative(self.data, store_sel, self.layout),
                             table_comparison(self.data, store_sel),
@@ -1318,7 +1322,7 @@ class Layout:
                     })
                 else:
                     row_fig_tput = self.PLACEHOLDER
-                    row_fig_tsa = self.PLACEHOLDER
+                    row_fig_lat = self.PLACEHOLDER
                     row_table = self.PLACEHOLDER
                     row_btn_dwnld = self.PLACEHOLDER
                     row_card_sel_tests = self.STYLE_DISABLED
@@ -1332,7 +1336,7 @@ class Layout:
                     store_sel = literal_eval(
                         url_params.get("store_sel", list())[0])
                     if store_sel:
-                        row_fig_tput, row_fig_tsa, row_table, row_btn_dwnld = \
+                        row_fig_tput, row_fig_lat, row_table, row_btn_dwnld = \
                             _generate_plotting_area(
                                 graph_iterative(self.data, store_sel,
                                     self.layout),
@@ -1346,7 +1350,7 @@ class Layout:
                         })
                     else:
                         row_fig_tput = self.PLACEHOLDER
-                        row_fig_tsa = self.PLACEHOLDER
+                        row_fig_lat = self.PLACEHOLDER
                         row_table = self.PLACEHOLDER
                         row_btn_dwnld = self.PLACEHOLDER
                         row_card_sel_tests = self.STYLE_DISABLED
@@ -1364,7 +1368,7 @@ class Layout:
 
             ret_val = [
                 ctrl_panel.panel, store_sel,
-                row_fig_tput, row_fig_tsa, row_table, row_btn_dwnld,
+                row_fig_tput, row_fig_lat, row_table, row_btn_dwnld,
                 row_card_sel_tests, row_btns_sel_tests
             ]
             ret_val.extend(ctrl_panel.values())
index 6fa91f3..e6ee788 100644 (file)
@@ -1,10 +1,6 @@
 plot-throughput:
-  titlefont:
-    size: 16
   xaxis:
     title: "<b>Test Cases [Index]</b>"
-    titlefont:
-      size: 14
     autorange: True
     fixedrange: False
     gridcolor: "rgb(230, 230, 230)"
@@ -15,24 +11,18 @@ plot-throughput:
     showticklabels: True
     tickcolor: "rgb(220, 220, 220)"
     tickmode: "array"
-    tickfont:
-      size: 14
     zeroline: False
   yaxis:
-    title: "<b>Packet Throughput [Mpps]</b>"
-    titlefont:
-      size: 14
+    title: "<b>Packet Throughput [pps]</b>"
     gridcolor: "rgb(230, 230, 230)"
-    hoverformat: ".4r"
-    tickformat: ".3r"
+    hoverformat: ".3s"
+    tickformat: ".3s"
     linecolor: "rgb(220, 220, 220)"
     linewidth: 1
     showgrid: True
     showline: True
     showticklabels: True
     tickcolor: "rgb(220, 220, 220)"
-    tickfont:
-      size: 14
     zeroline: False
     range: [0, 50]
   autosize: False
@@ -45,7 +35,52 @@ plot-throughput:
   legend:
     orientation: "h"
     font:
-      size: 14
+      size: 10
+  width: 700
+  height: 900
+  paper_bgcolor: "#fff"
+  plot_bgcolor: "#fff"
+  hoverlabel:
+    namelength: -1
+
+plot-latency:
+  xaxis:
+    title: "<b>Test Cases [Index]</b>"
+    autorange: True
+    fixedrange: False
+    gridcolor: "rgb(230, 230, 230)"
+    linecolor: "rgb(220, 220, 220)"
+    linewidth: 1
+    showgrid: True
+    showline: True
+    showticklabels: True
+    tickcolor: "rgb(220, 220, 220)"
+    tickmode: "array"
+    zeroline: False
+  yaxis:
+    title: "<b>Packet Latency [us]</b>"
+    gridcolor: "rgb(230, 230, 230)"
+    hoverformat: ".3s"
+    tickformat: ".3s"
+    linecolor: "rgb(220, 220, 220)"
+    linewidth: 1
+    showgrid: True
+    showline: True
+    showticklabels: True
+    tickcolor: "rgb(220, 220, 220)"
+    zeroline: False
+    range: [0, 50]
+  autosize: False
+  margin:
+    t: 50
+    b: 0
+    l: 80
+    r: 20
+  showlegend: True
+  legend:
+    orientation: "h"
+    font:
+      size: 10
   width: 700
   height: 900
   paper_bgcolor: "#fff"
@@ -53,6 +88,61 @@ plot-throughput:
   hoverlabel:
     namelength: -1
 
+plot-hdrh-latency:
+  # title:
+  #   text: "Latency by Percentile Distribution"
+  #   xanchor: "center"
+  #   x: 0.5
+    # font:
+    #   size: 10
+  showlegend: True
+  legend:
+    traceorder: "normal"
+    orientation: "h"
+    # font:
+    #   size: 16
+    xanchor: "left"
+    yanchor: "top"
+    x: 0
+    y: -0.25
+    bgcolor: "rgba(255, 255, 255, 0)"
+    bordercolor: "rgba(255, 255, 255, 0)"
+  xaxis:
+    type: "log"
+    title: "Percentile [%]"
+    # titlefont:
+    #   size: 14
+    autorange: False
+    fixedrange: True
+    gridcolor: "rgb(230, 230, 230)"
+    linecolor: "rgb(220, 220, 220)"
+    linewidth: 1
+    showgrid: True
+    showline: True
+    showticklabels: True
+    tickcolor: "rgb(220, 220, 220)"
+    tickvals: [1, 2, 1e1, 20, 1e2, 1e3, 1e4, 1e5, 1e6]
+    ticktext: [0, 50, 90, 95, 99, 99.9, 99.99, 99.999, 99.9999]
+    # tickfont:
+    #   size: 14
+  yaxis:
+    title: "One-Way Latency per Direction [us]"
+    # titlefont:
+    #   size: 14
+    gridcolor: "rgb(230, 230, 230)"
+    linecolor: "rgb(220, 220, 220)"
+    linewidth: 1
+    showgrid: True
+    showline: True
+    showticklabels: True
+    tickcolor: "rgb(220, 220, 220)"
+    # tickfont:
+    #   size: 14
+  autosize: True
+  #height: 400
+  paper_bgcolor: "white"
+  plot_bgcolor: "white"
+
 plot-throughput-speedup-analysis:
   titlefont:
     size: 16
index 47abac1..09b91a4 100644 (file)
@@ -16,6 +16,9 @@
     <p class="lead">
       <a href="/trending/" class="btn btn-primary fw-bold">Performance Trending</a>
     </p>
+    <p class="lead">
+      <a href="/report/" class="btn btn-primary fw-bold">Iterative Test Runs</a>
+    </p>
     <p class="lead">
       <a href="/stats/" class="btn btn-primary fw-bold">Job Statistics</a>
     </p>
index 36c1949..d3164a8 100644 (file)
@@ -26,12 +26,6 @@ from numpy import isnan
 from ..jumpavg import classify
 
 
-_COLORS = (
-    u"#1A1110", u"#DA2647", u"#214FC6", u"#01786F", u"#BD8260", u"#FFD12A",
-    u"#A6E7FF", u"#738276", u"#C95A49", u"#FC5A8D", u"#CEC8EF", u"#391285",
-    u"#6F2DA8", u"#FF878D", u"#45A27D", u"#FFD0B9", u"#FD5240", u"#DB91EF",
-    u"#44D7A8", u"#4F86F7", u"#84DE02", u"#FFCFF1", u"#614051"
-)
 _ANOMALY_COLOR = {
     u"regression": 0.0,
     u"normal": 0.5,
@@ -93,6 +87,18 @@ _GRAPH_LAT_HDRH_DESC = {
 }
 
 
+def _get_color(idx: int) -> str:
+    """
+    """
+    _COLORS = (
+        "#1A1110", "#DA2647", "#214FC6", "#01786F", "#BD8260", "#FFD12A",
+        "#A6E7FF", "#738276", "#C95A49", "#FC5A8D", "#CEC8EF", "#391285",
+        "#6F2DA8", "#FF878D", "#45A27D", "#FFD0B9", "#FD5240", "#DB91EF",
+        "#44D7A8", "#4F86F7", "#84DE02", "#FFCFF1", "#614051"
+    )
+    return _COLORS[idx % len(_COLORS)]
+
+
 def _get_hdrh_latencies(row: pd.Series, name: str) -> dict:
     """
     """
@@ -174,10 +180,20 @@ def select_trending_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame:
 
     core = str() if itm["dut"] == "trex" else f"{itm['core']}"
     ttype = "ndrpdr" if itm["testtype"] in ("ndr", "pdr") else itm["testtype"]
-    dut = "none" if itm["dut"] == "trex" else itm["dut"].upper()
+    dut_v100 = "none" if itm["dut"] == "trex" else itm["dut"]
+    dut_v101 = itm["dut"]
 
     df = data.loc[(
-        (data["dut_type"] == dut) &
+        (
+            (
+                (data["version"] == "1.0.0") &
+                (data["dut_type"].str.lower() == dut_v100)
+            ) |
+            (
+                (data["version"] == "1.0.1") &
+                (data["dut_type"].str.lower() == dut_v101)
+            )
+        ) &
         (data["test_type"] == ttype) &
         (data["passed"] == True)
     )]
@@ -362,7 +378,7 @@ def graph_trending(data: pd.DataFrame, sel:dict, layout: dict,
         name = "-".join((itm["dut"], itm["phy"], itm["framesize"], itm["core"],
             itm["test"], itm["testtype"], ))
         traces = _generate_trending_traces(
-            itm["testtype"], name, df, start, end, _COLORS[idx % len(_COLORS)]
+            itm["testtype"], name, df, start, end, _get_color(idx)
         )
         if traces:
             if not fig_tput:
@@ -371,7 +387,7 @@ def graph_trending(data: pd.DataFrame, sel:dict, layout: dict,
 
         if itm["testtype"] == "pdr":
             traces = _generate_trending_traces(
-                "pdr-lat", name, df, start, end, _COLORS[idx % len(_COLORS)]
+                "pdr-lat", name, df, start, end, _get_color(idx)
             )
             if traces:
                 if not fig_lat:
@@ -438,7 +454,7 @@ def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
                 legendgroup=_GRAPH_LAT_HDRH_DESC[lat_name],
                 showlegend=bool(idx % 2),
                 line=dict(
-                    color=_COLORS[int(idx/2)],
+                    color=_get_color(int(idx/2)),
                     dash=u"solid",
                     width=1 if idx % 2 else 2
                 ),