aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTibor Frank <tifrank@cisco.com>2023-04-24 12:07:53 +0200
committerTibor Frank <tifrank@cisco.com>2023-04-24 14:01:13 +0200
commitf578663642305f144f76ddadf0370701147f18ff (patch)
treeef9170c422b16cb598e0647e6e0d662fd3805558
parent0e39caf5ffa1d2bca04811895ba57fde147cfdcb (diff)
C-Dash: Latency in coverage tables
- Display latency on demand Signed-off-by: Tibor Frank <tifrank@cisco.com> Change-Id: I5152d1f6c843f6b1ffac5818e1de76a701c7ccf1
-rw-r--r--csit.infra.dash/app/cdash/comparisons/layout.py2
-rw-r--r--csit.infra.dash/app/cdash/coverage/layout.py69
-rw-r--r--csit.infra.dash/app/cdash/coverage/tables.py100
-rw-r--r--csit.infra.dash/app/cdash/report/layout.py2
-rw-r--r--csit.infra.dash/app/cdash/trending/layout.py2
5 files changed, 88 insertions, 87 deletions
diff --git a/csit.infra.dash/app/cdash/comparisons/layout.py b/csit.infra.dash/app/cdash/comparisons/layout.py
index 452afad1af..d78123b187 100644
--- a/csit.infra.dash/app/cdash/comparisons/layout.py
+++ b/csit.infra.dash/app/cdash/comparisons/layout.py
@@ -737,7 +737,7 @@ class Layout:
(selected["reference"]["set"] == True) and
(c_sel["set"] == True)
)
- except (KeyError, IndexError):
+ except (KeyError, IndexError, AttributeError):
pass
if process_url:
ctrl_panel.set({
diff --git a/csit.infra.dash/app/cdash/coverage/layout.py b/csit.infra.dash/app/cdash/coverage/layout.py
index f519f5a8ac..a5e095f0c0 100644
--- a/csit.infra.dash/app/cdash/coverage/layout.py
+++ b/csit.infra.dash/app/cdash/coverage/layout.py
@@ -48,7 +48,8 @@ CP_PARAMS = {
"phy-val": str(),
"area-opt": list(),
"area-dis": True,
- "area-val": str()
+ "area-val": str(),
+ "show-latency": ["show_latency", ]
}
@@ -342,16 +343,45 @@ class Layout:
size="sm"
)
]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText("Latency"),
+ dbc.Checklist(
+ id="show-latency",
+ options=[{
+ "value": "show_latency",
+ "label": "Show Latency"
+ }],
+ value=["show_latency"],
+ inline=True,
+ class_name="ms-2"
+ )
+ ],
+ style={"align-items": "center"},
+ size="sm"
+ )
+ ]
)
]
- def _get_plotting_area(self, selected: dict, url: str) -> list:
+ def _get_plotting_area(
+ self,
+ selected: dict,
+ url: str,
+ show_latency: bool
+ ) -> list:
"""Generate the plotting area with all its content.
:param selected: Selected parameters of tests.
:param url: URL to be displayed in the modal window.
+ :param show_latency: If True, latency is displayed in the tables.
:type selected: dict
:type url: str
+ :type show_latency: bool
:returns: List of rows with elements to be displayed in the plotting
area.
:rtype: list
@@ -361,7 +391,7 @@ class Layout:
return [
dbc.Row(
- children=coverage_tables(self._data, selected),
+ children=coverage_tables(self._data, selected, show_latency),
class_name="g-0 p-0",
),
dbc.Row(
@@ -441,6 +471,7 @@ class Layout:
Output({"type": "ctrl-dd", "index": "area"}, "options"),
Output({"type": "ctrl-dd", "index": "area"}, "disabled"),
Output({"type": "ctrl-dd", "index": "area"}, "value"),
+ Output("show-latency", "value"),
],
[
State("store-control-panel", "data"),
@@ -448,6 +479,7 @@ class Layout:
],
[
Input("url", "href"),
+ Input("show-latency", "value"),
Input({"type": "ctrl-dd", "index": ALL}, "value")
]
)
@@ -455,6 +487,7 @@ class Layout:
control_panel: dict,
selected: dict,
href: str,
+ show_latency: list,
*_
) -> tuple:
"""Update the application when the event is detected.
@@ -477,8 +510,9 @@ class Layout:
if trigger.type == "url" and url_params:
try:
+ show_latency = literal_eval(url_params["show_latency"][0])
selected = literal_eval(url_params["selection"][0])
- except (KeyError, IndexError):
+ except (KeyError, IndexError, AttributeError):
pass
if selected:
ctrl_panel.set({
@@ -508,9 +542,13 @@ class Layout:
[selected["phy"]]
)
],
- "area-dis": False
+ "area-dis": False,
+ "show-latency": show_latency
})
on_draw = True
+ elif trigger.type == "show-latency":
+ ctrl_panel.set({"show-latency": show_latency})
+ on_draw = True
elif trigger.type == "ctrl-dd":
if trigger.idx == "rls":
try:
@@ -610,7 +648,14 @@ class Layout:
if selected:
plotting_area = self._get_plotting_area(
selected,
- gen_new_url(parsed_url, {"selection": selected})
+ gen_new_url(
+ parsed_url,
+ {
+ "selection": selected,
+ "show_latency": show_latency
+ }
+ ),
+ show_latency=bool(show_latency)
)
else:
plotting_area = C.PLACEHOLDER
@@ -639,15 +684,18 @@ class Layout:
@app.callback(
Output("download-iterative-data", "data"),
State("store-selected-tests", "data"),
+ State("show-latency", "value"),
Input("plot-btn-download", "n_clicks"),
prevent_initial_call=True
)
- def _download_coverage_data(selection, _):
+ def _download_coverage_data(selection, show_latency, _):
"""Download the data
:param selection: List of tests selected by user stored in the
browser.
+ :param show_latency: If True, latency is displayed in the tables.
:type selection: dict
+ :type show_latency: bool
:returns: dict of data frame content (base64 encoded) and meta data
used by the Download component.
:rtype: dict
@@ -656,6 +704,11 @@ class Layout:
if not selection:
raise PreventUpdate
- df = select_coverage_data(self._data, selection, csv=True)
+ df = select_coverage_data(
+ self._data,
+ selection,
+ csv=True,
+ show_latency=bool(show_latency)
+ )
return dcc.send_data_frame(df.to_csv, C.COVERAGE_DOWNLOAD_FILE_NAME)
diff --git a/csit.infra.dash/app/cdash/coverage/tables.py b/csit.infra.dash/app/cdash/coverage/tables.py
index a34b80f024..6cc2956637 100644
--- a/csit.infra.dash/app/cdash/coverage/tables.py
+++ b/csit.infra.dash/app/cdash/coverage/tables.py
@@ -28,7 +28,8 @@ from ..utils.constants import Constants as C
def select_coverage_data(
data: pd.DataFrame,
selected: dict,
- csv: bool=False
+ csv: bool=False,
+ show_latency: bool=True
) -> list:
"""Select coverage data for the tables and generate tables as pandas data
frames.
@@ -37,9 +38,11 @@ def select_coverage_data(
:param selected: Dictionary with user selection.
:param csv: If True, pandas data frame with selected coverage data is
returned for "Download Data" feature.
+ :param show_latency: If True, latency is displayed in the tables.
:type data: pandas.DataFrame
:type selected: dict
:type csv: bool
+ :type show_latency: bool
:returns: List of tuples with suite name (str) and data (pandas dataframe)
or pandas dataframe if csv is True.
:rtype: list[tuple[str, pandas.DataFrame], ] or pandas.DataFrame
@@ -78,7 +81,7 @@ def select_coverage_data(
ttype = df["test_type"].to_list()[0]
# Prepare the coverage data
- def _laten(hdrh_string: str, percentile: float) -> int:
+ def _latency(hdrh_string: str, percentile: float) -> int:
"""Get latency from HDRH string for given percentile.
:param hdrh_string: Encoded HDRH string.
@@ -126,78 +129,16 @@ def select_coverage_data(
cov["Throughput_PDR_Mbps"] = df.apply(
lambda row: row["result_pdr_lower_bandwidth_value"] /1e9, axis=1
)
- cov["Latency Forward [us]_10% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_10% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_10% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P50"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P90"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P99"] = df.apply(
- lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 99.0),
- axis=1
- )
+ if show_latency:
+ for way in ("Forward", "Reverse"):
+ for pdr in (10, 50, 90):
+ for perc in (50, 90, 99):
+ latency = f"result_latency_{way.lower()}_pdr_{pdr}_hdrh"
+ cov[f"Latency {way} [us]_{pdr}% PDR_P{perc}"] = \
+ df.apply(
+ lambda row: _latency(row[latency], perc),
+ axis=1
+ )
if csv:
return cov
@@ -222,19 +163,26 @@ def select_coverage_data(
return l_data
-def coverage_tables(data: pd.DataFrame, selected: dict) -> list:
+def coverage_tables(
+ data: pd.DataFrame,
+ selected: dict,
+ show_latency: bool=True
+ ) -> list:
"""Generate an accordion with coverage tables.
:param data: Coverage data.
:param selected: Dictionary with user selection.
+ :param show_latency: If True, latency is displayed in the tables.
:type data: pandas.DataFrame
:type selected: dict
+ :type show_latency: bool
:returns: Accordion with suite names (titles) and tables.
:rtype: dash_bootstrap_components.Accordion
"""
accordion_items = list()
- for suite, cov_data in select_coverage_data(data, selected):
+ sel_data = select_coverage_data(data, selected, show_latency=show_latency)
+ for suite, cov_data in sel_data:
if len(cov_data.columns) == 3: # VPP Device
cols = [
{
diff --git a/csit.infra.dash/app/cdash/report/layout.py b/csit.infra.dash/app/cdash/report/layout.py
index 1e79b68b5e..ec17dec7e8 100644
--- a/csit.infra.dash/app/cdash/report/layout.py
+++ b/csit.infra.dash/app/cdash/report/layout.py
@@ -919,7 +919,7 @@ class Layout:
try:
store_sel = literal_eval(url_params["store_sel"][0])
normalize = literal_eval(url_params["norm"][0])
- except (KeyError, IndexError):
+ except (KeyError, IndexError, AttributeError):
pass
if store_sel:
row_card_sel_tests = C.STYLE_ENABLED
diff --git a/csit.infra.dash/app/cdash/trending/layout.py b/csit.infra.dash/app/cdash/trending/layout.py
index 005d1dc141..87d11626d4 100644
--- a/csit.infra.dash/app/cdash/trending/layout.py
+++ b/csit.infra.dash/app/cdash/trending/layout.py
@@ -1087,7 +1087,7 @@ class Layout:
try:
store_sel = literal_eval(url_params["store_sel"][0])
normalize = literal_eval(url_params["norm"][0])
- except (KeyError, IndexError):
+ except (KeyError, IndexError, AttributeError):
pass
if store_sel:
last_test = store_sel[-1]