aboutsummaryrefslogtreecommitdiffstats
path: root/resources/tools/dash/app/pal/report
diff options
context:
space:
mode:
authorTibor Frank <tifrank@cisco.com>2022-08-03 15:00:51 +0200
committerTibor Frank <tifrank@cisco.com>2022-08-03 13:57:50 +0000
commit808797d2d913eac7581a4e4cba3fb826ddbff775 (patch)
tree450d088ff8231635b2f498adc682aa07372a9e64 /resources/tools/dash/app/pal/report
parent1f0d4ffc8d3fabe2bd7452760425e005c2970ff6 (diff)
UTI: Add Download for iterative data.
Change-Id: I79bcfc2449310d4d186146ce79b2143a33ed2d1f Signed-off-by: Tibor Frank <tifrank@cisco.com>
Diffstat (limited to 'resources/tools/dash/app/pal/report')
-rw-r--r--resources/tools/dash/app/pal/report/graphs.py122
-rw-r--r--resources/tools/dash/app/pal/report/layout.py38
2 files changed, 117 insertions, 43 deletions
diff --git a/resources/tools/dash/app/pal/report/graphs.py b/resources/tools/dash/app/pal/report/graphs.py
index 4cd9287f0f..36f28d09e8 100644
--- a/resources/tools/dash/app/pal/report/graphs.py
+++ b/resources/tools/dash/app/pal/report/graphs.py
@@ -25,7 +25,14 @@ from ..utils.utils import get_color
def get_short_version(version: str, dut_type: str="vpp") -> str:
- """
+ """Returns the short version of DUT without build number.
+
+ :param version: Original version string.
+ :param dut_type: DUT type.
+ :type version: str
+ :type dut_type: str
+ :returns: Short verion string.
+ :rtype: str
"""
if dut_type in ("trex", "dpdk"):
@@ -48,7 +55,15 @@ def get_short_version(version: str, dut_type: str="vpp") -> str:
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.
+ :param itm: Item (in this case job name) which data will be selected from
+ the input data frame.
+ :type data: pandas.DataFrame
+ :type itm: str
+ :returns: A data frame with selected data.
+ :rtype: pandas.DataFrame
"""
phy = itm["phy"].split("-")
@@ -96,7 +111,20 @@ def select_iterative_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame:
def graph_iterative(data: pd.DataFrame, sel:dict, layout: dict,
normalize: bool) -> tuple:
- """
+ """Generate the statistical box graph with iterative data (MRR, NDR and PDR,
+ for PDR also Latencies).
+
+ :param data: Data frame with iterative data.
+ :param sel: Selected tests.
+ :param layout: Layout of plot.ly graph.
+ :param normalize: If True, the data is normalized to CPU frquency
+ Constants.NORM_FREQUENCY.
+ :param data: pandas.DataFrame
+ :param sel: dict
+ :param layout: dict
+ :param normalize: bool
+ :returns: Tuple of graphs - throughput and latency.
+ :rtype: tuple(plotly.graph_objects.Figure, plotly.graph_objects.Figure)
"""
fig_tput = None
@@ -192,46 +220,56 @@ def graph_iterative(data: pd.DataFrame, sel:dict, layout: dict,
def table_comparison(data: pd.DataFrame, sel:dict,
normalize: bool) -> pd.DataFrame:
- """
+ """Generate the comparison table with selected tests.
+
+ :param data: Data frame with iterative data.
+ :param sel: Selected tests.
+ :param normalize: If True, the data is normalized to CPU frquency
+ Constants.NORM_FREQUENCY.
+ :param data: pandas.DataFrame
+ :param sel: dict
+ :param normalize: bool
+ :returns: Comparison table.
+ :rtype: pandas.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 pd.DataFrame() #table
+ return table
diff --git a/resources/tools/dash/app/pal/report/layout.py b/resources/tools/dash/app/pal/report/layout.py
index 0e8f32405c..978ab0de6c 100644
--- a/resources/tools/dash/app/pal/report/layout.py
+++ b/resources/tools/dash/app/pal/report/layout.py
@@ -23,6 +23,7 @@ from dash import dcc
from dash import html
from dash import callback_context, no_update, ALL
from dash import Input, Output, State
+from dash.exceptions import PreventUpdate
from yaml import load, FullLoader, YAMLError
from copy import deepcopy
from ast import literal_eval
@@ -32,7 +33,8 @@ from ..utils.utils import show_tooltip, label, sync_checklists, list_tests, \
gen_new_url
from ..utils.url_processing import url_decode
from ..data.data import Data
-from .graphs import graph_iterative, table_comparison, get_short_version
+from .graphs import graph_iterative, table_comparison, get_short_version, \
+ select_iterative_data
class Layout:
@@ -1408,3 +1410,37 @@ class Layout:
]
ret_val.extend(ctrl_panel.values())
return ret_val
+
+ @app.callback(
+ Output("download-data", "data"),
+ State("selected-tests", "data"),
+ Input("btn-download-data", "n_clicks"),
+ prevent_initial_call=True
+ )
+ def _download_data(store_sel, n_clicks):
+ """Download the data
+
+ :param store_sel: List of tests selected by user stored in the
+ browser.
+ :param n_clicks: Number of clicks on the button "Download".
+ :type store_sel: list
+ :type n_clicks: int
+ :returns: dict of data frame content (base64 encoded) and meta data
+ used by the Download component.
+ :rtype: dict
+ """
+
+ if not n_clicks:
+ raise PreventUpdate
+
+ if not store_sel:
+ raise PreventUpdate
+
+ df = pd.DataFrame()
+ for itm in store_sel:
+ sel_data = select_iterative_data(self.data, itm)
+ if sel_data is None:
+ continue
+ df = pd.concat([df, sel_data], ignore_index=True)
+
+ return dcc.send_data_frame(df.to_csv, C.REPORT_DOWNLOAD_FILE_NAME)