diff options
-rw-r--r-- | resources/tools/dash/app/pal/data/tooltips.yaml | 30 | ||||
-rw-r--r-- | resources/tools/dash/app/pal/stats/layout.py | 120 | ||||
-rw-r--r-- | resources/tools/dash/app/pal/stats/stats.py | 1 | ||||
-rw-r--r-- | resources/tools/dash/app/pal/templates/index_layout.jinja2 | 4 | ||||
-rw-r--r-- | resources/tools/dash/app/pal/trending/layout.py | 102 | ||||
-rw-r--r-- | resources/tools/dash/app/pal/trending/trending.py | 1 |
6 files changed, 196 insertions, 62 deletions
diff --git a/resources/tools/dash/app/pal/data/tooltips.yaml b/resources/tools/dash/app/pal/data/tooltips.yaml new file mode 100644 index 0000000000..1b61ab6c63 --- /dev/null +++ b/resources/tools/dash/app/pal/data/tooltips.yaml @@ -0,0 +1,30 @@ +help-area: + The area defines a VPP packet path and lookup type. +help-cadence: + The cadence of the Jenkins job which runs the tests. +help-cores: + Number of cores the DUT uses during the test. +help-download: + Download the selected data as a csv file. +help-dut: + Device Under Test (DUT) - In software networking, “device” denotes a specific + piece of software tasked with packet processing. Such device is surrounded + with other software components (such as operating system kernel). +help-framesize: + Frame size - size of an Ethernet Layer-2 frame on the wire, including any VLAN + tags (dot1q, dot1ad) and Ethernet FCS, but excluding Ethernet preamble and + inter-frame gap. Measured in Bytes. +help-infra: + Infrastructure is defined by the toplology (number of nodes), processor + architecture, NIC and driver. +help-tbed: + The test bed is defined by toplology (number of nodes) and processor + architecture. +help-test: + The test specification consists of packet encapsulation, VPP packet processing + (packet forwarding mode and packet processing function(s)) and packet + forwarding path. +help-time-period: + Choose a time period for selected tests. +help-ttype: + Main measured variable. diff --git a/resources/tools/dash/app/pal/stats/layout.py b/resources/tools/dash/app/pal/stats/layout.py index dedb265684..7ac379ae01 100644 --- a/resources/tools/dash/app/pal/stats/layout.py +++ b/resources/tools/dash/app/pal/stats/layout.py @@ -14,6 +14,7 @@ """Plotly Dash HTML layout override. """ +import logging import pandas as pd import dash_bootstrap_components as dbc @@ -38,7 +39,7 @@ class Layout: DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx" def __init__(self, app: Flask, html_layout_file: str, spec_file: str, - graph_layout_file: str, data_spec_file: str, + graph_layout_file: str, data_spec_file: str, tooltip_file: str, time_period: int=None) -> None: """ """ @@ -49,6 +50,7 @@ class Layout: self._spec_file = spec_file self._graph_layout_file = graph_layout_file self._data_spec_file = data_spec_file + self._tooltip_file = tooltip_file self._time_period = time_period # Read the data: @@ -138,6 +140,7 @@ class Layout: # Read from files: self._html_layout = "" self._graph_layout = None + self._tooltips = dict() try: with open(self._html_layout_file, "r") as file_read: @@ -158,10 +161,23 @@ class Layout: except YAMLError as err: raise RuntimeError( f"An error occurred while parsing the specification file " - f"{self._graph_layout_file}\n" - f"{err}" + f"{self._graph_layout_file}\n{err}" + ) + + try: + with open(self._tooltip_file, "r") as file_read: + self._tooltips = load(file_read, Loader=FullLoader) + except IOError as err: + logging.warning( + f"Not possible to open the file {self._tooltip_file}\n{err}" + ) + except YAMLError as err: + logging.warning( + f"An error occurred while parsing the specification file " + f"{self._tooltip_file}\n{err}" ) + self._default_fig_passed, self._default_fig_duration = graph_statistics( self.data, self._default["job"], self.layout ) @@ -231,6 +247,25 @@ class Layout: (self.df_job_info["tbed"] == testbed) )]["job"].item() + def _show_tooltip(self, id: str, title: str) -> list: + """ + """ + return [ + f"{title} ", + dbc.Badge( + id=id, + children="?", + pill=True, + color="white", + text_color="info", + class_name="border ms-1", + ), + dbc.Tooltip( + children=self._tooltips.get(id, str()), + target=id, + placement="auto" + ) + ] def add_content(self): """ @@ -353,7 +388,8 @@ class Layout: dcc.Loading(children=[ dbc.Button( id="btn-download-data", - children=["Download Data"], + children=self._show_tooltip( + "help-download", "Download"), class_name="me-1", color="info" ), @@ -379,14 +415,17 @@ class Layout: class_name="gy-1", children=[ dbc.Label( - "Device under Test", - class_name="p-0" + class_name="p-0", + children=self._show_tooltip( + "help-dut", "Device under Test") ), - dbc.RadioItems( - id="ri-duts", - inline=True, - value=self.default["dut"], - options=self.default["duts"] + dbc.Row( + dbc.RadioItems( + id="ri-duts", + inline=True, + value=self.default["dut"], + options=self.default["duts"] + ) ) ] ), @@ -394,8 +433,9 @@ class Layout: class_name="gy-1", children=[ dbc.Label( - "Test Type", - class_name="p-0" + class_name="p-0", + children=self._show_tooltip( + "help-ttype", "Test Type"), ), dbc.RadioItems( id="ri-ttypes", @@ -409,8 +449,9 @@ class Layout: class_name="gy-1", children=[ dbc.Label( - "Cadence", - class_name="p-0" + class_name="p-0", + children=self._show_tooltip( + "help-cadence", "Cadence"), ), dbc.RadioItems( id="ri-cadences", @@ -424,8 +465,9 @@ class Layout: class_name="gy-1", children=[ dbc.Label( - "Test Bed", - class_name="p-0" + class_name="p-0", + children=self._show_tooltip( + "help-tbed", "Test Bed"), ), dbc.Select( id="dd-tbeds", @@ -444,29 +486,33 @@ class Layout: children=self.default["job"] ) ] + ), + dbc.Row( + class_name="g-0 p-2", + children=[ + dbc.Label( + class_name="gy-1", + children=self._show_tooltip( + "help-time-period", "Time Period"), + ), + dcc.DatePickerRange( + id="dpr-period", + className="d-flex justify-content-center", + min_date_allowed=\ + datetime.utcnow() - timedelta( + days=self.time_period), + max_date_allowed=datetime.utcnow(), + initial_visible_month=datetime.utcnow(), + start_date=\ + datetime.utcnow() - timedelta( + days=self.time_period), + end_date=datetime.utcnow(), + display_format="D MMM YY" + ) + ] ) ] ), - dbc.Row( - class_name="g-0 p-2", - children=[ - dbc.Label("Choose the Time Period"), - dcc.DatePickerRange( - id="dpr-period", - className="d-flex justify-content-center", - min_date_allowed=\ - datetime.utcnow() - timedelta( - days=self.time_period), - max_date_allowed=datetime.utcnow(), - initial_visible_month=datetime.utcnow(), - start_date=\ - datetime.utcnow() - timedelta( - days=self.time_period), - end_date=datetime.utcnow(), - display_format="D MMMM YY" - ) - ] - ) ] ) diff --git a/resources/tools/dash/app/pal/stats/stats.py b/resources/tools/dash/app/pal/stats/stats.py index d733e0ca81..56fe27f4f7 100644 --- a/resources/tools/dash/app/pal/stats/stats.py +++ b/resources/tools/dash/app/pal/stats/stats.py @@ -41,6 +41,7 @@ def init_stats(server, time_period=None): spec_file="pal/stats/spec_job_selection.yaml", graph_layout_file="pal/stats/layout.yaml", data_spec_file="pal/data/data.yaml", + tooltip_file="pal/data/tooltips.yaml", time_period=time_period ) dash_app.index_string = layout.html_layout diff --git a/resources/tools/dash/app/pal/templates/index_layout.jinja2 b/resources/tools/dash/app/pal/templates/index_layout.jinja2 index 5fd3d40b25..47abac1a43 100644 --- a/resources/tools/dash/app/pal/templates/index_layout.jinja2 +++ b/resources/tools/dash/app/pal/templates/index_layout.jinja2 @@ -14,10 +14,10 @@ <h1 class="text-white">{{ title }}</h1> <p class="lead">{{ description }}</p> <p class="lead"> - <a href="/trending/" class="btn btn-primary fw-bold">Trending</a> + <a href="/trending/" class="btn btn-primary fw-bold">Performance Trending</a> </p> <p class="lead"> - <a href="/stats/" class="btn btn-primary fw-bold">Statistics</a> + <a href="/stats/" class="btn btn-primary fw-bold">Job Statistics</a> </p> </main> diff --git a/resources/tools/dash/app/pal/trending/layout.py b/resources/tools/dash/app/pal/trending/layout.py index b5286a0424..43a3786008 100644 --- a/resources/tools/dash/app/pal/trending/layout.py +++ b/resources/tools/dash/app/pal/trending/layout.py @@ -14,6 +14,7 @@ """Plotly Dash HTML layout override. """ +import logging import pandas as pd import dash_bootstrap_components as dbc @@ -73,7 +74,7 @@ class Layout: } def __init__(self, app: Flask, html_layout_file: str, spec_file: str, - graph_layout_file: str, data_spec_file: str, + graph_layout_file: str, data_spec_file: str, tooltip_file: str, time_period: str=None) -> None: """ """ @@ -84,6 +85,7 @@ class Layout: self._spec_file = spec_file self._graph_layout_file = graph_layout_file self._data_spec_file = data_spec_file + self._tooltip_file = tooltip_file self._time_period = time_period # Read the data: @@ -135,7 +137,7 @@ class Layout: infra = "-".join((tbed, nic, driver)) lst_test = test.split("-") framesize = lst_test[0] - core = lst_test[1] if lst_test[1] else "1C" + core = lst_test[1] if lst_test[1] else "8C" test = "-".join(lst_test[2: -1]) if tbs.get(dut, None) is None: @@ -167,6 +169,7 @@ class Layout: # Read from files: self._html_layout = "" self._graph_layout = None + self._tooltips = dict() try: with open(self._html_layout_file, "r") as file_read: @@ -187,8 +190,20 @@ class Layout: except YAMLError as err: raise RuntimeError( f"An error occurred while parsing the specification file " - f"{self._graph_layout_file}\n" - f"{err}" + f"{self._graph_layout_file}\n{err}" + ) + + try: + with open(self._tooltip_file, "r") as file_read: + self._tooltips = load(file_read, Loader=FullLoader) + except IOError as err: + logging.warning( + f"Not possible to open the file {self._tooltip_file}\n{err}" + ) + except YAMLError as err: + logging.warning( + f"An error occurred while parsing the specification file " + f"{self._tooltip_file}\n{err}" ) # Callbacks: @@ -218,6 +233,26 @@ class Layout: def label(self, key: str) -> str: return self.LABELS.get(key, key) + def _show_tooltip(self, id: str, title: str) -> list: + """ + """ + return [ + f"{title} ", + dbc.Badge( + id=id, + children="?", + pill=True, + color="white", + text_color="info", + class_name="border ms-1", + ), + dbc.Tooltip( + children=self._tooltips.get(id, str()), + target=id, + placement="auto" + ) + ] + def add_content(self): """ """ @@ -353,7 +388,10 @@ class Layout: children=[ dbc.InputGroup( [ - dbc.InputGroupText("DUT"), + dbc.InputGroupText( + children=self._show_tooltip( + "help-dut", "DUT") + ), dbc.Select( id="dd-ctrl-dut", placeholder=( @@ -378,7 +416,10 @@ class Layout: children=[ dbc.InputGroup( [ - dbc.InputGroupText("Infra"), + dbc.InputGroupText( + children=self._show_tooltip( + "help-infra", "Infra") + ), dbc.Select( id="dd-ctrl-phy", placeholder=( @@ -397,7 +438,10 @@ class Layout: children=[ dbc.InputGroup( [ - dbc.InputGroupText("Area"), + dbc.InputGroupText( + children=self._show_tooltip( + "help-area", "Area") + ), dbc.Select( id="dd-ctrl-area", placeholder="Select an Area...", @@ -414,7 +458,10 @@ class Layout: children=[ dbc.InputGroup( [ - dbc.InputGroupText("Test"), + dbc.InputGroupText( + children=self._show_tooltip( + "help-test", "Test") + ), dbc.Select( id="dd-ctrl-test", placeholder="Select a Test...", @@ -427,28 +474,29 @@ class Layout: ] ), dbc.Row( - id="row-ctrl-core", + id="row-ctrl-framesize", class_name="gy-1", children=[ dbc.Label( - "Number of Cores", + children=self._show_tooltip( + "help-framesize", "Frame Size"), class_name="p-0" ), dbc.Col( children=[ dbc.Checklist( - id="cl-ctrl-core-all", + id="cl-ctrl-framesize-all", options=self.CL_ALL_DISABLED, - inline=False, + inline=True, switch=False - ) + ), ], width=3 ), dbc.Col( children=[ dbc.Checklist( - id="cl-ctrl-core", + id="cl-ctrl-framesize", inline=True, switch=False ) @@ -457,28 +505,29 @@ class Layout: ] ), dbc.Row( - id="row-ctrl-framesize", + id="row-ctrl-core", class_name="gy-1", children=[ dbc.Label( - "Frame Size", + children=self._show_tooltip( + "help-cores", "Number of Cores"), class_name="p-0" ), dbc.Col( children=[ dbc.Checklist( - id="cl-ctrl-framesize-all", + id="cl-ctrl-core-all", options=self.CL_ALL_DISABLED, - inline=True, + inline=False, switch=False - ), + ) ], width=3 ), dbc.Col( children=[ dbc.Checklist( - id="cl-ctrl-framesize", + id="cl-ctrl-core", inline=True, switch=False ) @@ -491,7 +540,8 @@ class Layout: class_name="gy-1", children=[ dbc.Label( - "Test Type", + children=self._show_tooltip( + "help-ttype", "Test Type"), class_name="p-0" ), dbc.Col( @@ -535,6 +585,11 @@ class Layout: dbc.Row( class_name="gy-1", children=[ + dbc.Label( + class_name="gy-1", + children=self._show_tooltip( + "help-time-period", "Time Period"), + ), dcc.DatePickerRange( id="dpr-period", className="d-flex justify-content-center", @@ -547,7 +602,7 @@ class Layout: datetime.utcnow() - timedelta( days=self.time_period), end_date=datetime.utcnow(), - display_format="D MMMM YY" + display_format="D MMM YY" ) ] ), @@ -704,7 +759,8 @@ class Layout: dcc.Loading(children=[ dbc.Button( id="btn-download-data", - children=["Download Data"], + children=self._show_tooltip( + "help-download", "Download"), class_name="me-1", color="info" ), diff --git a/resources/tools/dash/app/pal/trending/trending.py b/resources/tools/dash/app/pal/trending/trending.py index 8cd52b5c3f..68dc420556 100644 --- a/resources/tools/dash/app/pal/trending/trending.py +++ b/resources/tools/dash/app/pal/trending/trending.py @@ -41,6 +41,7 @@ def init_trending(server, time_period=None): spec_file="pal/trending/spec_test_selection.yaml", graph_layout_file="pal/trending/layout.yaml", data_spec_file="pal/data/data.yaml", + tooltip_file="pal/data/tooltips.yaml", time_period=time_period ) dash_app.index_string = layout.html_layout |