UTI: Move constatns to a separate file 16/36716/3
authorTibor Frank <tifrank@cisco.com>
Wed, 20 Jul 2022 13:51:21 +0000 (15:51 +0200)
committerTibor Frank <tifrank@cisco.com>
Thu, 21 Jul 2022 07:45:39 +0000 (07:45 +0000)
Change-Id: If3796b71d02bcf5a92612585dfa8867e5039f037
Signed-off-by: Tibor Frank <tifrank@cisco.com>
19 files changed:
resources/tools/dash/app/pal/__init__.py
resources/tools/dash/app/pal/data/data.py
resources/tools/dash/app/pal/news/layout.py
resources/tools/dash/app/pal/news/news.py
resources/tools/dash/app/pal/news/tables.py
resources/tools/dash/app/pal/report/graphs.py
resources/tools/dash/app/pal/report/layout.py
resources/tools/dash/app/pal/report/report.py
resources/tools/dash/app/pal/routes.py
resources/tools/dash/app/pal/stats/layout.py
resources/tools/dash/app/pal/stats/stats.py
resources/tools/dash/app/pal/trending/graphs.py
resources/tools/dash/app/pal/trending/layout.py
resources/tools/dash/app/pal/trending/trending.py
resources/tools/dash/app/pal/utils/__init__.py [new file with mode: 0644]
resources/tools/dash/app/pal/utils/constants.py [new file with mode: 0644]
resources/tools/dash/app/pal/utils/tooltips.yaml [moved from resources/tools/dash/app/pal/data/tooltips.yaml with 100% similarity]
resources/tools/dash/app/pal/utils/url_processing.py [moved from resources/tools/dash/app/pal/data/url_processing.py with 100% similarity]
resources/tools/dash/app/pal/utils/utils.py [moved from resources/tools/dash/app/pal/data/utils.py with 100% similarity]

index 9f80c5f..0eb2a4e 100644 (file)
@@ -19,21 +19,8 @@ import logging
 from flask import Flask
 from flask_assets import Environment
 
 from flask import Flask
 from flask_assets import Environment
 
+from .utils.constants import Constants as C
 
 
-# Maximal value of TIME_PERIOD for Trending in days.
-# Do not change without a good reason.
-MAX_TIME_PERIOD = 180
-
-# It defines the time period for Trending in days from now back to the past from
-# which data is read to dataframes.
-# TIME_PERIOD = None means all data (max MAX_TIME_PERIOD days) is read.
-# TIME_PERIOD = MAX_TIME_PERIOD is the default value
-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=["csit2206", "csit2202", ]
 
 def init_app():
     """Construct core Flask application with embedded Dash app.
 
 def init_app():
     """Construct core Flask application with embedded Dash app.
@@ -58,10 +45,10 @@ def init_app():
         assets.init_app(app)
 
         # Set the time period for Trending
         assets.init_app(app)
 
         # Set the time period for Trending
-        if TIME_PERIOD is None or TIME_PERIOD > MAX_TIME_PERIOD:
-            time_period = MAX_TIME_PERIOD
+        if C.TIME_PERIOD is None or C.TIME_PERIOD > C.MAX_TIME_PERIOD:
+            time_period = C.MAX_TIME_PERIOD
         else:
         else:
-            time_period = TIME_PERIOD
+            time_period = C.TIME_PERIOD
 
         # Import Dash applications.
         from .news.news import init_news
 
         # Import Dash applications.
         from .news.news import init_news
@@ -74,7 +61,7 @@ def init_app():
         app = init_trending(app, time_period=time_period)
 
         from .report.report import init_report
         app = init_trending(app, time_period=time_period)
 
         from .report.report import init_report
-        app = init_report(app, releases=RELEASES)
+        app = init_report(app, releases=C.RELEASES)
 
     return app
 
 
     return app
 
index 296db02..0956333 100644 (file)
 """
 
 import logging
 """
 
 import logging
+import awswrangler as wr
 
 from yaml import load, FullLoader, YAMLError
 from datetime import datetime, timedelta
 from time import time
 from pytz import UTC
 from pandas import DataFrame
 
 from yaml import load, FullLoader, YAMLError
 from datetime import datetime, timedelta
 from time import time
 from pytz import UTC
 from pandas import DataFrame
-
-import awswrangler as wr
-
 from awswrangler.exceptions import EmptyDataFrame, NoFilesFound
 
 
 from awswrangler.exceptions import EmptyDataFrame, NoFilesFound
 
 
index 2f66ce5..c9f2808 100644 (file)
@@ -27,7 +27,9 @@ from yaml import load, FullLoader, YAMLError
 from copy import deepcopy
 
 from ..data.data import Data
 from copy import deepcopy
 
 from ..data.data import Data
-from ..data.utils import classify_anomalies
+from ..utils.constants import Constants as C
+from ..utils.utils import classify_anomalies
+from ..data.data import Data
 from .tables import table_news
 
 
 from .tables import table_news
 
 
@@ -35,12 +37,6 @@ class Layout:
     """The layout of the dash app and the callbacks.
     """
 
     """The layout of the dash app and the callbacks.
     """
 
-    # The default job displayed when the page is loaded first time.
-    DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx"
-
-    # Time period for regressions and progressions.
-    TIME_PERIOD = 21  # [days]
-
     def __init__(self, app: Flask, html_layout_file: str, data_spec_file: str,
         tooltip_file: str) -> None:
         """Initialization:
     def __init__(self, app: Flask, html_layout_file: str, data_spec_file: str,
         tooltip_file: str) -> None:
         """Initialization:
@@ -73,7 +69,7 @@ class Layout:
         data_stats, data_mrr, data_ndrpdr = Data(
             data_spec_file=self._data_spec_file,
             debug=True
         data_stats, data_mrr, data_ndrpdr = Data(
             data_spec_file=self._data_spec_file,
             debug=True
-        ).read_stats(days=self.TIME_PERIOD)
+        ).read_stats(days=C.NEWS_TIME_PERIOD)
 
         df_tst_info = pd.concat([data_mrr, data_ndrpdr], ignore_index=True)
 
 
         df_tst_info = pd.concat([data_mrr, data_ndrpdr], ignore_index=True)
 
@@ -95,7 +91,7 @@ class Layout:
             job_info["tbed"].append("-".join(lst_job[-2:]))
         self.df_job_info = pd.DataFrame.from_dict(job_info)
 
             job_info["tbed"].append("-".join(lst_job[-2:]))
         self.df_job_info = pd.DataFrame.from_dict(job_info)
 
-        self._default = self._set_job_params(self.DEFAULT_JOB)
+        self._default = self._set_job_params(C.NEWS_DEFAULT_JOB)
 
         # Pre-process the data:
 
 
         # Pre-process the data:
 
index deb00c1..5e65b62 100644 (file)
@@ -14,8 +14,8 @@
 """Instantiate the Statistics Dash applocation.
 """
 import dash
 """Instantiate the Statistics Dash applocation.
 """
 import dash
-import dash_bootstrap_components as dbc
 
 
+from ..utils.constants import Constants as C
 from .layout import Layout
 
 
 from .layout import Layout
 
 
@@ -30,15 +30,15 @@ def init_news(server):
 
     dash_app = dash.Dash(
         server=server,
 
     dash_app = dash.Dash(
         server=server,
-        routes_pathname_prefix=u"/news/",
-        external_stylesheets=[dbc.themes.LUX],
+        routes_pathname_prefix=C.NEWS_ROUTES_PATHNAME_PREFIX,
+        external_stylesheets=C.EXTERNAL_STYLESHEETS
     )
 
     layout = Layout(
         app=dash_app,
     )
 
     layout = Layout(
         app=dash_app,
-        html_layout_file="pal/templates/news_layout.jinja2",
-        data_spec_file="pal/data/data.yaml",
-        tooltip_file="pal/data/tooltips.yaml",
+        html_layout_file=C.NEWS_HTML_LAYOUT_FILE,
+        data_spec_file=C.DATA_SPEC_FILE,
+        tooltip_file=C.TOOLTIP_FILE,
     )
     dash_app.index_string = layout.html_layout
     dash_app.layout = layout.add_content()
     )
     dash_app.index_string = layout.html_layout
     dash_app.layout = layout.add_content()
index 53b2460..6272814 100644 (file)
@@ -17,9 +17,7 @@
 import pandas as pd
 import dash_bootstrap_components as dbc
 
 import pandas as pd
 import dash_bootstrap_components as dbc
 
-
-# Time period for regressions and progressions.
-TIME_PERIOD = 21  # [days]
+from ..utils.constants import Constants as C
 
 
 def table_news(data: pd.DataFrame, job: str) -> list:
 
 
 def table_news(data: pd.DataFrame, job: str) -> list:
@@ -57,7 +55,7 @@ def table_news(data: pd.DataFrame, job: str) -> list:
             class_name="p-0",
             size="lg",
             children=(
             class_name="p-0",
             size="lg",
             children=(
-                f"Regressions during the last {TIME_PERIOD} days "
+                f"Regressions during the last {C.NEWS_TIME_PERIOD} days "
                 f"({len(regressions['Test Name'])})"
             )
         ),
                 f"({len(regressions['Test Name'])})"
             )
         ),
@@ -68,7 +66,7 @@ def table_news(data: pd.DataFrame, job: str) -> list:
             class_name="p-0",
             size="lg",
             children=(
             class_name="p-0",
             size="lg",
             children=(
-                f"Progressions during the last {TIME_PERIOD} days "
+                f"Progressions during the last {C.NEWS_TIME_PERIOD} days "
                 f"({len(progressions['Test Name'])})"
             )
         ),
                 f"({len(progressions['Test Name'])})"
             )
         ),
index 76aa8b7..c5d8f8f 100644 (file)
@@ -20,75 +20,13 @@ import pandas as pd
 
 from copy import deepcopy
 
 
 from copy import deepcopy
 
-import hdrh.histogram
-import hdrh.codec
-
-
-_NORM_FREQUENCY = 2.0  # [GHz]
-_FREQURENCY = {  # [GHz]
-    "2n-aws": 1.000,
-    "2n-dnv": 2.000,
-    "2n-clx": 2.300,
-    "2n-icx": 2.600,
-    "2n-skx": 2.500,
-    "2n-tx2": 2.500,
-    "2n-zn2": 2.900,
-    "3n-alt": 3.000,
-    "3n-aws": 1.000,
-    "3n-dnv": 2.000,
-    "3n-icx": 2.600,
-    "3n-skx": 2.500,
-    "3n-tsh": 2.200
-}
-
-_VALUE = {
-    "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"
-}
-_UNIT = {
-    "mrr": "result_receive_rate_rate_unit",
-    "ndr": "result_ndr_lower_rate_unit",
-    "pdr": "result_pdr_lower_rate_unit",
-    "pdr-lat": "result_latency_forward_pdr_50_unit"
-}
-_LAT_HDRH = (  # Do not change the order
-    "result_latency_forward_pdr_0_hdrh",
-    "result_latency_reverse_pdr_0_hdrh",
-    "result_latency_forward_pdr_10_hdrh",
-    "result_latency_reverse_pdr_10_hdrh",
-    "result_latency_forward_pdr_50_hdrh",
-    "result_latency_reverse_pdr_50_hdrh",
-    "result_latency_forward_pdr_90_hdrh",
-    "result_latency_reverse_pdr_90_hdrh",
-)
-# This value depends on latency stream rate (9001 pps) and duration (5s).
-# Keep it slightly higher to ensure rounding errors to not remove tick mark.
-PERCENTILE_MAX = 99.999501
-
-_GRAPH_LAT_HDRH_DESC = {
-    "result_latency_forward_pdr_0_hdrh": "No-load.",
-    "result_latency_reverse_pdr_0_hdrh": "No-load.",
-    "result_latency_forward_pdr_10_hdrh": "Low-load, 10% PDR.",
-    "result_latency_reverse_pdr_10_hdrh": "Low-load, 10% PDR.",
-    "result_latency_forward_pdr_50_hdrh": "Mid-load, 50% PDR.",
-    "result_latency_reverse_pdr_50_hdrh": "Mid-load, 50% PDR.",
-    "result_latency_forward_pdr_90_hdrh": "High-load, 90% PDR.",
-    "result_latency_reverse_pdr_90_hdrh": "High-load, 90% PDR."
-}
+from ..utils.constants import Constants as C
 
 
 def _get_color(idx: int) -> str:
     """
     """
 
 
 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)]
+    return C.PLOT_COLORS[idx % len(C.PLOT_COLORS)]
 
 
 def get_short_version(version: str, dut_type: str="vpp") -> str:
 
 
 def get_short_version(version: str, dut_type: str="vpp") -> str:
@@ -182,16 +120,16 @@ def graph_iterative(data: pd.DataFrame, sel:dict, layout: dict,
             continue
         phy = itm["phy"].split("-")
         topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str()
             continue
         phy = itm["phy"].split("-")
         topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str()
-        norm_factor = (_NORM_FREQUENCY / _FREQURENCY[topo_arch]) \
+        norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY[topo_arch]) \
             if normalize else 1.0
         if itm["testtype"] == "mrr":
             if normalize else 1.0
         if itm["testtype"] == "mrr":
-            y_data_raw = itm_data[_VALUE[itm["testtype"]]].to_list()[0]
+            y_data_raw = itm_data[C.VALUE_ITER[itm["testtype"]]].to_list()[0]
             y_data = [(y * norm_factor) for y in y_data_raw]
             if len(y_data) > 0:
                 y_tput_max = \
                     max(y_data) if max(y_data) > y_tput_max else y_tput_max
         else:
             y_data = [(y * norm_factor) for y in y_data_raw]
             if len(y_data) > 0:
                 y_tput_max = \
                     max(y_data) if max(y_data) > y_tput_max else y_tput_max
         else:
-            y_data_raw = itm_data[_VALUE[itm["testtype"]]].to_list()
+            y_data_raw = itm_data[C.VALUE_ITER[itm["testtype"]]].to_list()
             y_data = [(y * norm_factor) for y in y_data_raw]
             if y_data:
                 y_tput_max = \
             y_data = [(y * norm_factor) for y in y_data_raw]
             if y_data:
                 y_tput_max = \
@@ -214,7 +152,7 @@ def graph_iterative(data: pd.DataFrame, sel:dict, layout: dict,
         show_tput = True
 
         if itm["testtype"] == "pdr":
         show_tput = True
 
         if itm["testtype"] == "pdr":
-            y_lat_row = itm_data[_VALUE["pdr-lat"]].to_list()
+            y_lat_row = itm_data[C.VALUE_ITER["pdr-lat"]].to_list()
             y_lat = [(y / norm_factor) for y in y_lat_row]
             if y_lat:
                 y_lat_max = max(y_lat) if max(y_lat) > y_lat_max else y_lat_max
             y_lat = [(y / norm_factor) for y in y_lat_row]
             if y_lat:
                 y_lat_max = max(y_lat) if max(y_lat) > y_lat_max else y_lat_max
@@ -302,73 +240,3 @@ def table_comparison(data: pd.DataFrame, sel:dict,
     )
 
     return pd.DataFrame()  #table
     )
 
     return pd.DataFrame()  #table
-
-
-def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
-    """
-    """
-
-    fig = None
-
-    traces = list()
-    for idx, (lat_name, lat_hdrh) in enumerate(data.items()):
-        try:
-            decoded = hdrh.histogram.HdrHistogram.decode(lat_hdrh)
-        except (hdrh.codec.HdrLengthException, TypeError) as err:
-            continue
-        previous_x = 0.0
-        prev_perc = 0.0
-        xaxis = list()
-        yaxis = list()
-        hovertext = list()
-        for item in decoded.get_recorded_iterator():
-            # The real value is "percentile".
-            # For 100%, we cut that down to "x_perc" to avoid
-            # infinity.
-            percentile = item.percentile_level_iterated_to
-            x_perc = min(percentile, PERCENTILE_MAX)
-            xaxis.append(previous_x)
-            yaxis.append(item.value_iterated_to)
-            hovertext.append(
-                f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
-                f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
-                f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
-                f"Latency: {item.value_iterated_to}uSec"
-            )
-            next_x = 100.0 / (100.0 - x_perc)
-            xaxis.append(next_x)
-            yaxis.append(item.value_iterated_to)
-            hovertext.append(
-                f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
-                f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
-                f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
-                f"Latency: {item.value_iterated_to}uSec"
-            )
-            previous_x = next_x
-            prev_perc = percentile
-
-        traces.append(
-            go.Scatter(
-                x=xaxis,
-                y=yaxis,
-                name=_GRAPH_LAT_HDRH_DESC[lat_name],
-                mode="lines",
-                legendgroup=_GRAPH_LAT_HDRH_DESC[lat_name],
-                showlegend=bool(idx % 2),
-                line=dict(
-                    color=_get_color(int(idx/2)),
-                    dash="solid",
-                    width=1 if idx % 2 else 2
-                ),
-                hovertext=hovertext,
-                hoverinfo="text"
-            )
-        )
-    if traces:
-        fig = go.Figure()
-        fig.add_traces(traces)
-        layout_hdrh = layout.get("plot-hdrh-latency", None)
-        if lat_hdrh:
-            fig.update_layout(layout_hdrh)
-
-    return fig
index e7c8db4..164f2d4 100644 (file)
@@ -27,8 +27,9 @@ from yaml import load, FullLoader, YAMLError
 from copy import deepcopy
 from ast import literal_eval
 
 from copy import deepcopy
 from ast import literal_eval
 
+from ..utils.constants import Constants as C
+from ..utils.url_processing import url_decode, url_encode
 from ..data.data import Data
 from ..data.data import Data
-from ..data.url_processing import url_decode, url_encode
 from .graphs import graph_iterative, table_comparison, get_short_version
 
 
 from .graphs import graph_iterative, table_comparison, get_short_version
 
 
@@ -36,51 +37,6 @@ class Layout:
     """
     """
 
     """
     """
 
-    # If True, clear all inputs in control panel when button "ADD SELECTED" is
-    # pressed.
-    CLEAR_ALL_INPUTS = False
-
-    STYLE_DISABLED = {"display": "none"}
-    STYLE_ENABLED = {"display": "inherit"}
-
-    CL_ALL_DISABLED = [{
-        "label": "All",
-        "value": "all",
-        "disabled": True
-    }]
-    CL_ALL_ENABLED = [{
-        "label": "All",
-        "value": "all",
-        "disabled": False
-    }]
-
-    PLACEHOLDER = html.Nobr("")
-
-    DRIVERS = ("avf", "af-xdp", "rdma", "dpdk")
-
-    LABELS = {
-        "dpdk": "DPDK",
-        "container_memif": "LXC/DRC Container Memif",
-        "crypto": "IPSec IPv4 Routing",
-        "ip4": "IPv4 Routing",
-        "ip6": "IPv6 Routing",
-        "ip4_tunnels": "IPv4 Tunnels",
-        "l2": "L2 Ethernet Switching",
-        "srv6": "SRv6 Routing",
-        "vm_vhost": "VMs vhost-user",
-        "nfv_density-dcr_memif-chain_ipsec": "CNF Service Chains Routing IPSec",
-        "nfv_density-vm_vhost-chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
-        "nfv_density-vm_vhost-chain": "VNF Service Chains Routing",
-        "nfv_density-dcr_memif-pipeline": "CNF Service Pipelines Routing",
-        "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
-    }
-
-    URL_STYLE = {
-        "background-color": "#d2ebf5",
-        "border-color": "#bce1f1",
-        "color": "#135d7c"
-    }
-
     def __init__(self, app: Flask, releases: list, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str) -> None:
         """
     def __init__(self, app: Flask, releases: list, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str) -> None:
         """
@@ -125,7 +81,7 @@ class Layout:
                 replace("2n-", "")
             test = lst_test_id[-1]
             nic = suite.split("-")[0]
                 replace("2n-", "")
             test = lst_test_id[-1]
             nic = suite.split("-")[0]
-            for drv in self.DRIVERS:
+            for drv in C.DRIVERS:
                 if drv in test:
                     driver = drv.replace("-", "_")
                     test = test.replace(f"{drv}-", "")
                 if drv in test:
                     driver = drv.replace("-", "_")
                     test = test.replace(f"{drv}-", "")
@@ -234,7 +190,7 @@ class Layout:
         return self._graph_layout
 
     def label(self, key: str) -> str:
         return self._graph_layout
 
     def label(self, key: str) -> str:
-        return self.LABELS.get(key, key)
+        return C.LABELS.get(key, key)
 
     def _show_tooltip(self, id: str, title: str,
             clipboard_id: str=None) -> list:
 
     def _show_tooltip(self, id: str, title: str,
             clipboard_id: str=None) -> list:
@@ -359,9 +315,7 @@ class Layout:
                                     dbc.Row(  # Throughput
                                         id="row-graph-tput",
                                         class_name="g-0 p-2",
                                     dbc.Row(  # Throughput
                                         id="row-graph-tput",
                                         class_name="g-0 p-2",
-                                        children=[
-                                            self.PLACEHOLDER
-                                        ]
+                                        children=[C.PLACEHOLDER, ]
                                     ),
                                     width=6
                                 ),
                                     ),
                                     width=6
                                 ),
@@ -369,9 +323,7 @@ class Layout:
                                     dbc.Row(  # Latency
                                         id="row-graph-lat",
                                         class_name="g-0 p-2",
                                     dbc.Row(  # Latency
                                         id="row-graph-lat",
                                         class_name="g-0 p-2",
-                                        children=[
-                                            self.PLACEHOLDER
-                                        ]
+                                        children=[C.PLACEHOLDER, ]
                                     ),
                                     width=6
                                 )
                                     ),
                                     width=6
                                 )
@@ -380,16 +332,12 @@ class Layout:
                         dbc.Row(  # Tables
                             id="row-table",
                             class_name="g-0 p-2",
                         dbc.Row(  # Tables
                             id="row-table",
                             class_name="g-0 p-2",
-                            children=[
-                                self.PLACEHOLDER
-                            ]
+                            children=[C.PLACEHOLDER, ]
                         ),
                         dbc.Row(  # Download
                             id="row-btn-download",
                             class_name="g-0 p-2",
                         ),
                         dbc.Row(  # Download
                             id="row-btn-download",
                             class_name="g-0 p-2",
-                            children=[
-                                self.PLACEHOLDER
-                            ]
+                            children=[C.PLACEHOLDER, ]
                         )
                     ]
                 )
                         )
                     ]
                 )
@@ -548,7 +496,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-framesize-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-framesize-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=True,
                                     switch=False
                                 ),
                                     inline=True,
                                     switch=False
                                 ),
@@ -579,7 +527,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-core-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-core-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=False,
                                     switch=False
                                 )
                                     inline=False,
                                     switch=False
                                 )
@@ -610,7 +558,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-testtype-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-testtype-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=True,
                                     switch=False
                                 ),
                                     inline=True,
                                     switch=False
                                 ),
@@ -675,7 +623,7 @@ class Layout:
                 dbc.Row(
                     id="row-card-sel-tests",
                     class_name="gy-1",
                 dbc.Row(
                     id="row-card-sel-tests",
                     class_name="gy-1",
-                    style=self.STYLE_DISABLED,
+                    style=C.STYLE_DISABLED,
                     children=[
                         dbc.Label(
                             "Selected tests",
                     children=[
                         dbc.Label(
                             "Selected tests",
@@ -692,7 +640,7 @@ class Layout:
                 ),
                 dbc.Row(
                     id="row-btns-sel-tests",
                 ),
                 dbc.Row(
                     id="row-btns-sel-tests",
-                    style=self.STYLE_DISABLED,
+                    style=C.STYLE_DISABLED,
                     children=[
                         dbc.ButtonGroup(
                             class_name="gy-2",
                     children=[
                         dbc.ButtonGroup(
                             class_name="gy-2",
@@ -722,12 +670,6 @@ class Layout:
     class ControlPanel:
         def __init__(self, panel: dict) -> None:
 
     class ControlPanel:
         def __init__(self, panel: dict) -> None:
 
-            CL_ALL_DISABLED = [{
-                "label": "All",
-                "value": "all",
-                "disabled": True
-            }]
-
             # Defines also the order of keys
             self._defaults = {
                 "dd-rls-value": str(),
             # Defines also the order of keys
             self._defaults = {
                 "dd-rls-value": str(),
@@ -749,15 +691,15 @@ class Layout:
                 "cl-core-options": list(),
                 "cl-core-value": list(),
                 "cl-core-all-value": list(),
                 "cl-core-options": list(),
                 "cl-core-value": list(),
                 "cl-core-all-value": list(),
-                "cl-core-all-options": CL_ALL_DISABLED,
+                "cl-core-all-options": C.CL_ALL_DISABLED,
                 "cl-framesize-options": list(),
                 "cl-framesize-value": list(),
                 "cl-framesize-all-value": list(),
                 "cl-framesize-options": list(),
                 "cl-framesize-value": list(),
                 "cl-framesize-all-value": list(),
-                "cl-framesize-all-options": CL_ALL_DISABLED,
+                "cl-framesize-all-options": C.CL_ALL_DISABLED,
                 "cl-testtype-options": list(),
                 "cl-testtype-value": list(),
                 "cl-testtype-all-value": list(),
                 "cl-testtype-options": list(),
                 "cl-testtype-value": list(),
                 "cl-testtype-all-value": list(),
-                "cl-testtype-all-options": CL_ALL_DISABLED,
+                "cl-testtype-all-options": C.CL_ALL_DISABLED,
                 "btn-add-disabled": True,
                 "cl-normalize-value": list(),
                 "cl-selected-options": list()
                 "btn-add-disabled": True,
                 "cl-normalize-value": list(),
                 "cl-selected-options": list()
@@ -818,10 +760,10 @@ class Layout:
 
             (fig_tput, fig_lat) = figs
 
 
             (fig_tput, fig_lat) = figs
 
-            row_fig_tput = self.PLACEHOLDER
-            row_fig_lat = self.PLACEHOLDER
-            row_table = self.PLACEHOLDER
-            row_btn_dwnld = self.PLACEHOLDER
+            row_fig_tput = C.PLACEHOLDER
+            row_fig_lat = C.PLACEHOLDER
+            row_table = C.PLACEHOLDER
+            row_btn_dwnld = C.PLACEHOLDER
 
             if fig_tput:
                 row_fig_tput = [
 
             if fig_tput:
                 row_fig_tput = [
@@ -853,7 +795,7 @@ class Layout:
                                 class_name="me-1",
                                 children=[
                                     dbc.InputGroupText(
                                 class_name="me-1",
                                 children=[
                                     dbc.InputGroupText(
-                                        style=self.URL_STYLE,
+                                        style=C.URL_STYLE,
                                         children=self._show_tooltip(
                                             "help-url", "URL", "input-url")
                                     ),
                                         children=self._show_tooltip(
                                             "help-url", "URL", "input-url")
                                     ),
@@ -861,7 +803,7 @@ class Layout:
                                         id="input-url",
                                         readonly=True,
                                         type="url",
                                         id="input-url",
                                         readonly=True,
                                         type="url",
-                                        style=self.URL_STYLE,
+                                        style=C.URL_STYLE,
                                         value=url
                                     )
                                 ]
                                         value=url
                                     )
                                 ]
@@ -1019,15 +961,15 @@ class Layout:
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
-                    "cl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
-                    "cl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
-                    "cl-testtype-all-options": self.CL_ALL_DISABLED
+                    "cl-testtype-all-options": C.CL_ALL_DISABLED
                 })
             elif trigger_id == "dd-ctrl-dut":
                 try:
                 })
             elif trigger_id == "dd-ctrl-dut":
                 try:
@@ -1058,15 +1000,15 @@ class Layout:
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
-                    "cl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
-                    "cl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
-                    "cl-testtype-all-options": self.CL_ALL_DISABLED
+                    "cl-testtype-all-options": C.CL_ALL_DISABLED
                 })
             elif trigger_id == "dd-ctrl-dutver":
                 try:
                 })
             elif trigger_id == "dd-ctrl-dutver":
                 try:
@@ -1095,15 +1037,15 @@ class Layout:
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
-                    "cl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
-                    "cl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
-                    "cl-testtype-all-options": self.CL_ALL_DISABLED
+                    "cl-testtype-all-options": C.CL_ALL_DISABLED
                 })
             elif trigger_id == "dd-ctrl-phy":
                 try:
                 })
             elif trigger_id == "dd-ctrl-phy":
                 try:
@@ -1131,15 +1073,15 @@ class Layout:
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
-                    "cl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
-                    "cl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
-                    "cl-testtype-all-options": self.CL_ALL_DISABLED
+                    "cl-testtype-all-options": C.CL_ALL_DISABLED
                 })
             elif trigger_id == "dd-ctrl-area":
                 try:
                 })
             elif trigger_id == "dd-ctrl-area":
                 try:
@@ -1164,15 +1106,15 @@ class Layout:
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
                     "cl-core-options": list(),
                     "cl-core-value": list(),
                     "cl-core-all-value": list(),
-                    "cl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
                     "cl-framesize-options": list(),
                     "cl-framesize-value": list(),
                     "cl-framesize-all-value": list(),
-                    "cl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
                     "cl-testtype-options": list(),
                     "cl-testtype-value": list(),
                     "cl-testtype-all-value": list(),
-                    "cl-testtype-all-options": self.CL_ALL_DISABLED
+                    "cl-testtype-all-options": C.CL_ALL_DISABLED
                 })
             elif trigger_id == "dd-ctrl-test":
                 rls = ctrl_panel.get("dd-rls-value")
                 })
             elif trigger_id == "dd-ctrl-test":
                 rls = ctrl_panel.get("dd-rls-value")
@@ -1188,17 +1130,17 @@ class Layout:
                             for v in sorted(test["core"])],
                         "cl-core-value": list(),
                         "cl-core-all-value": list(),
                             for v in sorted(test["core"])],
                         "cl-core-value": list(),
                         "cl-core-all-value": list(),
-                        "cl-core-all-options": self.CL_ALL_ENABLED,
+                        "cl-core-all-options": C.CL_ALL_ENABLED,
                         "cl-framesize-options": [{"label": v, "value": v}
                             for v in sorted(test["frame-size"])],
                         "cl-framesize-value": list(),
                         "cl-framesize-all-value": list(),
                         "cl-framesize-options": [{"label": v, "value": v}
                             for v in sorted(test["frame-size"])],
                         "cl-framesize-value": list(),
                         "cl-framesize-all-value": list(),
-                        "cl-framesize-all-options": self.CL_ALL_ENABLED,
+                        "cl-framesize-all-options": C.CL_ALL_ENABLED,
                         "cl-testtype-options": [{"label": v, "value": v}
                             for v in sorted(test["test-type"])],
                         "cl-testtype-value": list(),
                         "cl-testtype-all-value": list(),
                         "cl-testtype-options": [{"label": v, "value": v}
                             for v in sorted(test["test-type"])],
                         "cl-testtype-value": list(),
                         "cl-testtype-all-value": list(),
-                        "cl-testtype-all-options": self.CL_ALL_ENABLED,
+                        "cl-testtype-all-options": C.CL_ALL_ENABLED,
                     })
             elif trigger_id == "cl-ctrl-core":
                 val_sel, val_all = self._sync_checklists(
                     })
             elif trigger_id == "cl-ctrl-core":
                 val_sel, val_all = self._sync_checklists(
@@ -1305,21 +1247,21 @@ class Layout:
                                         "testtype": ttype.lower()
                                     })
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
                                         "testtype": ttype.lower()
                                     })
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
-                    row_card_sel_tests = self.STYLE_ENABLED
-                    row_btns_sel_tests = self.STYLE_ENABLED
-                    if self.CLEAR_ALL_INPUTS:
+                    row_card_sel_tests = C.STYLE_ENABLED
+                    row_btns_sel_tests = C.STYLE_ENABLED
+                    if C.CLEAR_ALL_INPUTS:
                         ctrl_panel.set(ctrl_panel.defaults)
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                     })
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
                         ctrl_panel.set(ctrl_panel.defaults)
                     ctrl_panel.set({
                         "cl-selected-options": self._list_tests(store_sel)
                     })
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
-                row_fig_tput = self.PLACEHOLDER
-                row_fig_lat = self.PLACEHOLDER
-                row_table = self.PLACEHOLDER
-                row_btn_dwnld = self.PLACEHOLDER
-                row_card_sel_tests = self.STYLE_DISABLED
-                row_btns_sel_tests = self.STYLE_DISABLED
+                row_fig_tput = C.PLACEHOLDER
+                row_fig_lat = C.PLACEHOLDER
+                row_table = C.PLACEHOLDER
+                row_btn_dwnld = C.PLACEHOLDER
+                row_card_sel_tests = C.STYLE_DISABLED
+                row_btns_sel_tests = C.STYLE_DISABLED
                 store_sel = list()
                 ctrl_panel.set({"cl-selected-options": list()})
             elif trigger_id == "btn-sel-remove":
                 store_sel = list()
                 ctrl_panel.set({"cl-selected-options": list()})
             elif trigger_id == "btn-sel-remove":
@@ -1337,8 +1279,8 @@ class Layout:
                     store_sel = literal_eval(
                         url_params.get("store_sel", list())[0])
                     if store_sel:
                     store_sel = literal_eval(
                         url_params.get("store_sel", list())[0])
                     if store_sel:
-                        row_card_sel_tests = self.STYLE_ENABLED
-                        row_btns_sel_tests = self.STYLE_ENABLED
+                        row_card_sel_tests = C.STYLE_ENABLED
+                        row_btns_sel_tests = C.STYLE_ENABLED
 
             if trigger_id in ("btn-ctrl-add", "url", "btn-sel-remove",
                     "cl-ctrl-normalize"):
 
             if trigger_id in ("btn-ctrl-add", "url", "btn-sel-remove",
                     "cl-ctrl-normalize"):
@@ -1358,12 +1300,12 @@ class Layout:
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                 else:
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                 else:
-                    row_fig_tput = self.PLACEHOLDER
-                    row_fig_lat = self.PLACEHOLDER
-                    row_table = self.PLACEHOLDER
-                    row_btn_dwnld = self.PLACEHOLDER
-                    row_card_sel_tests = self.STYLE_DISABLED
-                    row_btns_sel_tests = self.STYLE_DISABLED
+                    row_fig_tput = C.PLACEHOLDER
+                    row_fig_lat = C.PLACEHOLDER
+                    row_table = C.PLACEHOLDER
+                    row_btn_dwnld = C.PLACEHOLDER
+                    row_card_sel_tests = C.STYLE_DISABLED
+                    row_btns_sel_tests = C.STYLE_DISABLED
                     store_sel = list()
                     ctrl_panel.set({"cl-selected-options": list()})
 
                     store_sel = list()
                     ctrl_panel.set({"cl-selected-options": list()})
 
index c02b409..c6008ca 100644 (file)
@@ -14,8 +14,8 @@
 """Instantiate the Report Dash applocation.
 """
 import dash
 """Instantiate the Report Dash applocation.
 """
 import dash
-import dash_bootstrap_components as dbc
 
 
+from ..utils.constants import Constants as C
 from .layout import Layout
 
 
 from .layout import Layout
 
 
@@ -30,17 +30,17 @@ def init_report(server, releases):
 
     dash_app = dash.Dash(
         server=server,
 
     dash_app = dash.Dash(
         server=server,
-        routes_pathname_prefix=u"/report/",
-        external_stylesheets=[dbc.themes.LUX],
+        routes_pathname_prefix=C.REPORT_ROUTES_PATHNAME_PREFIX,
+        external_stylesheets=C.EXTERNAL_STYLESHEETS
     )
 
     layout = Layout(
         app=dash_app,
         releases=releases,
     )
 
     layout = Layout(
         app=dash_app,
         releases=releases,
-        html_layout_file="pal/templates/report_layout.jinja2",
-        graph_layout_file="pal/report/layout.yaml",
-        data_spec_file="pal/data/data.yaml",
-        tooltip_file="pal/data/tooltips.yaml"
+        html_layout_file=C.REPORT_HTML_LAYOUT_FILE,
+        graph_layout_file=C.REPORT_GRAPH_LAYOUT_FILE,
+        data_spec_file=C.DATA_SPEC_FILE,
+        tooltip_file=C.TOOLTIP_FILE,
     )
     dash_app.index_string = layout.html_layout
     dash_app.layout = layout.add_content()
     )
     dash_app.index_string = layout.html_layout
     dash_app.layout = layout.add_content()
index d4cd88f..59af748 100644 (file)
 from flask import current_app as app
 from flask import render_template
 
 from flask import current_app as app
 from flask import render_template
 
+from .utils.constants import Constants as C
 
 
-@app.route("/")
+
+@app.route(C.APPLICATIN_ROOT)
 def home():
     """Landing page.
     """
     return render_template(
 def home():
     """Landing page.
     """
     return render_template(
-        "index_layout.jinja2",
-        title="FD.io CSIT",
-        description="Performance Dashboard",
-        template="d-flex h-100 text-center text-white bg-dark"
+        C.MAIN_HTML_LAYOUT_FILE,
+        title=C.TITLE,
+        description=C.DESCRIPTION,
+        template=C.TEMPLATE
     )
     )
index 5c3758b..03707c0 100644 (file)
@@ -28,8 +28,9 @@ from yaml import load, FullLoader, YAMLError
 from datetime import datetime, timedelta
 from copy import deepcopy
 
 from datetime import datetime, timedelta
 from copy import deepcopy
 
+from ..utils.constants import Constants as C
+from ..utils.url_processing import url_decode, url_encode
 from ..data.data import Data
 from ..data.data import Data
-from ..data.url_processing import url_decode, url_encode
 from .graphs import graph_statistics, select_data
 
 
 from .graphs import graph_statistics, select_data
 
 
@@ -37,14 +38,6 @@ class Layout:
     """
     """
 
     """
     """
 
-    DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx"
-
-    URL_STYLE = {
-        "background-color": "#d2ebf5",
-        "border-color": "#bce1f1",
-        "color": "#135d7c"
-    }
-
     def __init__(self, app: Flask, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str,
         time_period: int=None) -> None:
     def __init__(self, app: Flask, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str,
         time_period: int=None) -> None:
@@ -95,7 +88,7 @@ class Layout:
             job_info["tbed"].append("-".join(lst_job[-2:]))
         self.df_job_info = pd.DataFrame.from_dict(job_info)
 
             job_info["tbed"].append("-".join(lst_job[-2:]))
         self.df_job_info = pd.DataFrame.from_dict(job_info)
 
-        self._default = self._set_job_params(self.DEFAULT_JOB)
+        self._default = self._set_job_params(C.STATS_DEFAULT_JOB)
 
         tst_info = {
             "job": list(),
 
         tst_info = {
             "job": list(),
@@ -431,7 +424,7 @@ class Layout:
                                     class_name="me-1",
                                     children=[
                                         dbc.InputGroupText(
                                     class_name="me-1",
                                     children=[
                                         dbc.InputGroupText(
-                                            style=self.URL_STYLE,
+                                            style=C.URL_STYLE,
                                             children=self._show_tooltip(
                                                 "help-url", "URL", "input-url")
                                         ),
                                             children=self._show_tooltip(
                                                 "help-url", "URL", "input-url")
                                         ),
@@ -439,7 +432,7 @@ class Layout:
                                             id="input-url",
                                             readonly=True,
                                             type="url",
                                             id="input-url",
                                             readonly=True,
                                             type="url",
-                                            style=self.URL_STYLE,
+                                            style=C.URL_STYLE,
                                             value=""
                                         )
                                     ]
                                             value=""
                                         )
                                     ]
index 3da742d..560ec53 100644 (file)
@@ -14,8 +14,8 @@
 """Instantiate the Statistics Dash applocation.
 """
 import dash
 """Instantiate the Statistics Dash applocation.
 """
 import dash
-import dash_bootstrap_components as dbc
 
 
+from ..utils.constants import Constants as C
 from .layout import Layout
 
 
 from .layout import Layout
 
 
@@ -30,16 +30,16 @@ def init_stats(server, time_period=None):
 
     dash_app = dash.Dash(
         server=server,
 
     dash_app = dash.Dash(
         server=server,
-        routes_pathname_prefix=u"/stats/",
-        external_stylesheets=[dbc.themes.LUX],
+        routes_pathname_prefix=C.STATS_ROUTES_PATHNAME_PREFIX,
+        external_stylesheets=C.EXTERNAL_STYLESHEETS
     )
 
     layout = Layout(
         app=dash_app,
     )
 
     layout = Layout(
         app=dash_app,
-        html_layout_file="pal/templates/stats_layout.jinja2",
-        graph_layout_file="pal/stats/layout.yaml",
-        data_spec_file="pal/data/data.yaml",
-        tooltip_file="pal/data/tooltips.yaml",
+        html_layout_file=C.STATS_HTML_LAYOUT_FILE,
+        graph_layout_file=C.STATS_GRAPH_LAYOUT_FILE,
+        data_spec_file=C.DATA_SPEC_FILE,
+        tooltip_file=C.TOOLTIP_FILE,
         time_period=time_period
     )
     dash_app.index_string = layout.html_layout
         time_period=time_period
     )
     dash_app.index_string = layout.html_layout
index a63bebb..0b49680 100644 (file)
@@ -22,96 +22,14 @@ import hdrh.codec
 
 from datetime import datetime
 
 
 from datetime import datetime
 
-from ..data.utils import classify_anomalies
-
-_NORM_FREQUENCY = 2.0  # [GHz]
-_FREQURENCY = {  # [GHz]
-    "2n-aws": 1.000,
-    "2n-dnv": 2.000,
-    "2n-clx": 2.300,
-    "2n-icx": 2.600,
-    "2n-skx": 2.500,
-    "2n-tx2": 2.500,
-    "2n-zn2": 2.900,
-    "3n-alt": 3.000,
-    "3n-aws": 1.000,
-    "3n-dnv": 2.000,
-    "3n-icx": 2.600,
-    "3n-skx": 2.500,
-    "3n-tsh": 2.200
-}
-
-_ANOMALY_COLOR = {
-    "regression": 0.0,
-    "normal": 0.5,
-    "progression": 1.0
-}
-_COLORSCALE_TPUT = [
-    [0.00, "red"],
-    [0.33, "red"],
-    [0.33, "white"],
-    [0.66, "white"],
-    [0.66, "green"],
-    [1.00, "green"]
-]
-_TICK_TEXT_TPUT = ["Regression", "Normal", "Progression"]
-_COLORSCALE_LAT = [
-    [0.00, "green"],
-    [0.33, "green"],
-    [0.33, "white"],
-    [0.66, "white"],
-    [0.66, "red"],
-    [1.00, "red"]
-]
-_TICK_TEXT_LAT = ["Progression", "Normal", "Regression"]
-_VALUE = {
-    "mrr": "result_receive_rate_rate_avg",
-    "ndr": "result_ndr_lower_rate_value",
-    "pdr": "result_pdr_lower_rate_value",
-    "pdr-lat": "result_latency_forward_pdr_50_avg"
-}
-_UNIT = {
-    "mrr": "result_receive_rate_rate_unit",
-    "ndr": "result_ndr_lower_rate_unit",
-    "pdr": "result_pdr_lower_rate_unit",
-    "pdr-lat": "result_latency_forward_pdr_50_unit"
-}
-_LAT_HDRH = (  # Do not change the order
-    "result_latency_forward_pdr_0_hdrh",
-    "result_latency_reverse_pdr_0_hdrh",
-    "result_latency_forward_pdr_10_hdrh",
-    "result_latency_reverse_pdr_10_hdrh",
-    "result_latency_forward_pdr_50_hdrh",
-    "result_latency_reverse_pdr_50_hdrh",
-    "result_latency_forward_pdr_90_hdrh",
-    "result_latency_reverse_pdr_90_hdrh",
-)
-# This value depends on latency stream rate (9001 pps) and duration (5s).
-# Keep it slightly higher to ensure rounding errors to not remove tick mark.
-PERCENTILE_MAX = 99.999501
-
-_GRAPH_LAT_HDRH_DESC = {
-    "result_latency_forward_pdr_0_hdrh": "No-load.",
-    "result_latency_reverse_pdr_0_hdrh": "No-load.",
-    "result_latency_forward_pdr_10_hdrh": "Low-load, 10% PDR.",
-    "result_latency_reverse_pdr_10_hdrh": "Low-load, 10% PDR.",
-    "result_latency_forward_pdr_50_hdrh": "Mid-load, 50% PDR.",
-    "result_latency_reverse_pdr_50_hdrh": "Mid-load, 50% PDR.",
-    "result_latency_forward_pdr_90_hdrh": "High-load, 90% PDR.",
-    "result_latency_reverse_pdr_90_hdrh": "High-load, 90% PDR."
-}
+from ..utils.constants import Constants as C
+from ..utils.utils import classify_anomalies
 
 
 def _get_color(idx: int) -> str:
     """
     """
 
 
 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)]
+    return C.PLOT_COLORS[idx % len(C.PLOT_COLORS)]
 
 
 def _get_hdrh_latencies(row: pd.Series, name: str) -> dict:
 
 
 def _get_hdrh_latencies(row: pd.Series, name: str) -> dict:
@@ -119,7 +37,7 @@ def _get_hdrh_latencies(row: pd.Series, name: str) -> dict:
     """
 
     latencies = {"name": name}
     """
 
     latencies = {"name": name}
-    for key in _LAT_HDRH:
+    for key in C.LAT_HDRH:
         try:
             latencies[key] = row[key]
         except KeyError:
         try:
             latencies[key] = row[key]
         except KeyError:
@@ -176,7 +94,7 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
     """
     """
 
     """
     """
 
-    df = df.dropna(subset=[_VALUE[ttype], ])
+    df = df.dropna(subset=[C.VALUE[ttype], ])
     if df.empty:
         return list()
     df = df.loc[((df["start_time"] >= start) & (df["start_time"] <= end))]
     if df.empty:
         return list()
     df = df.loc[((df["start_time"] >= start) & (df["start_time"] <= end))]
@@ -185,9 +103,9 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
 
     x_axis = df["start_time"].tolist()
     if ttype == "pdr-lat":
 
     x_axis = df["start_time"].tolist()
     if ttype == "pdr-lat":
-        y_data = [(itm / norm_factor) for itm in df[_VALUE[ttype]].tolist()]
+        y_data = [(itm / norm_factor) for itm in df[C.VALUE[ttype]].tolist()]
     else:
     else:
-        y_data = [(itm * norm_factor) for itm in df[_VALUE[ttype]].tolist()]
+        y_data = [(itm * norm_factor) for itm in df[C.VALUE[ttype]].tolist()]
 
     anomalies, trend_avg, trend_stdev = classify_anomalies(
         {k: v for k, v in zip(x_axis, y_data)}
 
     anomalies, trend_avg, trend_stdev = classify_anomalies(
         {k: v for k, v in zip(x_axis, y_data)}
@@ -199,7 +117,7 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
         d_type = "trex" if row["dut_type"] == "none" else row["dut_type"]
         hover_itm = (
             f"date: {row['start_time'].strftime('%Y-%m-%d %H:%M:%S')}<br>"
         d_type = "trex" if row["dut_type"] == "none" else row["dut_type"]
         hover_itm = (
             f"date: {row['start_time'].strftime('%Y-%m-%d %H:%M:%S')}<br>"
-            f"<prop> [{row[_UNIT[ttype]]}]: {y_data[idx]:,.0f}<br>"
+            f"<prop> [{row[C.UNIT[ttype]]}]: {y_data[idx]:,.0f}<br>"
             f"<stdev>"
             f"{d_type}-ref: {row['dut_version']}<br>"
             f"csit-ref: {row['job']}/{row['build']}<br>"
             f"<stdev>"
             f"{d_type}-ref: {row['dut_version']}<br>"
             f"csit-ref: {row['job']}/{row['build']}<br>"
@@ -277,7 +195,7 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
             if anomaly in ("regression", "progression"):
                 anomaly_x.append(x_axis[idx])
                 anomaly_y.append(trend_avg[idx])
             if anomaly in ("regression", "progression"):
                 anomaly_x.append(x_axis[idx])
                 anomaly_y.append(trend_avg[idx])
-                anomaly_color.append(_ANOMALY_COLOR[anomaly])
+                anomaly_color.append(C.ANOMALY_COLOR[anomaly])
                 hover_itm = (
                     f"date: {x_axis[idx].strftime('%Y-%m-%d %H:%M:%S')}<br>"
                     f"trend [pps]: {trend_avg[idx]:,.0f}<br>"
                 hover_itm = (
                     f"date: {x_axis[idx].strftime('%Y-%m-%d %H:%M:%S')}<br>"
                     f"trend [pps]: {trend_avg[idx]:,.0f}<br>"
@@ -301,8 +219,8 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
                     "size": 15,
                     "symbol": "circle-open",
                     "color": anomaly_color,
                     "size": 15,
                     "symbol": "circle-open",
                     "color": anomaly_color,
-                    "colorscale": _COLORSCALE_LAT \
-                        if ttype == "pdr-lat" else _COLORSCALE_TPUT,
+                    "colorscale": C.COLORSCALE_LAT \
+                        if ttype == "pdr-lat" else C.COLORSCALE_TPUT,
                     "showscale": True,
                     "line": {
                         "width": 2
                     "showscale": True,
                     "line": {
                         "width": 2
@@ -314,8 +232,8 @@ def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame,
                         "titleside": "right",
                         "tickmode": "array",
                         "tickvals": [0.167, 0.500, 0.833],
                         "titleside": "right",
                         "tickmode": "array",
                         "tickvals": [0.167, 0.500, 0.833],
-                        "ticktext": _TICK_TEXT_LAT \
-                            if ttype == "pdr-lat" else _TICK_TEXT_TPUT,
+                        "ticktext": C.TICK_TEXT_LAT \
+                            if ttype == "pdr-lat" else C.TICK_TEXT_TPUT,
                         "ticks": "",
                         "ticklen": 0,
                         "tickangle": -90,
                         "ticks": "",
                         "ticklen": 0,
                         "tickangle": -90,
@@ -349,7 +267,7 @@ def graph_trending(data: pd.DataFrame, sel:dict, layout: dict,
         if normalize:
             phy = itm["phy"].split("-")
             topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str()
         if normalize:
             phy = itm["phy"].split("-")
             topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str()
-            norm_factor = (_NORM_FREQUENCY / _FREQURENCY[topo_arch]) \
+            norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY[topo_arch]) \
                 if topo_arch else 1.0
         else:
             norm_factor = 1.0
                 if topo_arch else 1.0
         else:
             norm_factor = 1.0
@@ -400,11 +318,11 @@ def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
             # For 100%, we cut that down to "x_perc" to avoid
             # infinity.
             percentile = item.percentile_level_iterated_to
             # For 100%, we cut that down to "x_perc" to avoid
             # infinity.
             percentile = item.percentile_level_iterated_to
-            x_perc = min(percentile, PERCENTILE_MAX)
+            x_perc = min(percentile, C.PERCENTILE_MAX)
             xaxis.append(previous_x)
             yaxis.append(item.value_iterated_to)
             hovertext.append(
             xaxis.append(previous_x)
             yaxis.append(item.value_iterated_to)
             hovertext.append(
-                f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
+                f"<b>{C.GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
                 f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
                 f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
                 f"Latency: {item.value_iterated_to}uSec"
                 f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
                 f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
                 f"Latency: {item.value_iterated_to}uSec"
@@ -413,7 +331,7 @@ def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
             xaxis.append(next_x)
             yaxis.append(item.value_iterated_to)
             hovertext.append(
             xaxis.append(next_x)
             yaxis.append(item.value_iterated_to)
             hovertext.append(
-                f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
+                f"<b>{C.GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
                 f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
                 f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
                 f"Latency: {item.value_iterated_to}uSec"
                 f"Direction: {('W-E', 'E-W')[idx % 2]}<br>"
                 f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
                 f"Latency: {item.value_iterated_to}uSec"
@@ -425,9 +343,9 @@ def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
             go.Scatter(
                 x=xaxis,
                 y=yaxis,
             go.Scatter(
                 x=xaxis,
                 y=yaxis,
-                name=_GRAPH_LAT_HDRH_DESC[lat_name],
+                name=C.GRAPH_LAT_HDRH_DESC[lat_name],
                 mode="lines",
                 mode="lines",
-                legendgroup=_GRAPH_LAT_HDRH_DESC[lat_name],
+                legendgroup=C.GRAPH_LAT_HDRH_DESC[lat_name],
                 showlegend=bool(idx % 2),
                 line=dict(
                     color=_get_color(int(idx/2)),
                 showlegend=bool(idx % 2),
                 line=dict(
                     color=_get_color(int(idx/2)),
index d632820..48a8e54 100644 (file)
@@ -30,8 +30,9 @@ from copy import deepcopy
 from json import loads, JSONDecodeError
 from ast import literal_eval
 
 from json import loads, JSONDecodeError
 from ast import literal_eval
 
+from ..utils.constants import Constants as C
+from ..utils.url_processing import url_decode, url_encode
 from ..data.data import Data
 from ..data.data import Data
-from ..data.url_processing import url_decode, url_encode
 from .graphs import graph_trending, graph_hdrh_latency, \
     select_trending_data
 
 from .graphs import graph_trending, graph_hdrh_latency, \
     select_trending_data
 
@@ -40,51 +41,6 @@ class Layout:
     """
     """
 
     """
     """
 
-    # If True, clear all inputs in control panel when button "ADD SELECTED" is
-    # pressed.
-    CLEAR_ALL_INPUTS = False
-
-    STYLE_DISABLED = {"display": "none"}
-    STYLE_ENABLED = {"display": "inherit"}
-
-    CL_ALL_DISABLED = [{
-        "label": "All",
-        "value": "all",
-        "disabled": True
-    }]
-    CL_ALL_ENABLED = [{
-        "label": "All",
-        "value": "all",
-        "disabled": False
-    }]
-
-    PLACEHOLDER = html.Nobr("")
-
-    DRIVERS = ("avf", "af-xdp", "rdma", "dpdk")
-
-    LABELS = {
-        "dpdk": "DPDK",
-        "container_memif": "LXC/DRC Container Memif",
-        "crypto": "IPSec IPv4 Routing",
-        "ip4": "IPv4 Routing",
-        "ip6": "IPv6 Routing",
-        "ip4_tunnels": "IPv4 Tunnels",
-        "l2": "L2 Ethernet Switching",
-        "srv6": "SRv6 Routing",
-        "vm_vhost": "VMs vhost-user",
-        "nfv_density-dcr_memif-chain_ipsec": "CNF Service Chains Routing IPSec",
-        "nfv_density-vm_vhost-chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
-        "nfv_density-vm_vhost-chain": "VNF Service Chains Routing",
-        "nfv_density-dcr_memif-pipeline": "CNF Service Pipelines Routing",
-        "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
-    }
-
-    URL_STYLE = {
-        "background-color": "#d2ebf5",
-        "border-color": "#bce1f1",
-        "color": "#135d7c"
-    }
-
     def __init__(self, app: Flask, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str,
         time_period: str=None) -> None:
     def __init__(self, app: Flask, html_layout_file: str,
         graph_layout_file: str, data_spec_file: str, tooltip_file: str,
         time_period: str=None) -> None:
@@ -135,7 +91,7 @@ class Layout:
                 replace("2n-", "")
             test = lst_test[-1]
             nic = suite.split("-")[0]
                 replace("2n-", "")
             test = lst_test[-1]
             nic = suite.split("-")[0]
-            for drv in self.DRIVERS:
+            for drv in C.DRIVERS:
                 if drv in test:
                     if drv == "af-xdp":
                         driver = "af_xdp"
                 if drv in test:
                     if drv == "af-xdp":
                         driver = "af_xdp"
@@ -242,7 +198,7 @@ class Layout:
         return self._time_period
 
     def label(self, key: str) -> str:
         return self._time_period
 
     def label(self, key: str) -> str:
-        return self.LABELS.get(key, key)
+        return C.LABELS.get(key, key)
 
     def _show_tooltip(self, id: str, title: str,
             clipboard_id: str=None) -> list:
 
     def _show_tooltip(self, id: str, title: str,
             clipboard_id: str=None) -> list:
@@ -364,21 +320,21 @@ class Layout:
                             id="row-graph-tput",
                             class_name="g-0 p-2",
                             children=[
                             id="row-graph-tput",
                             class_name="g-0 p-2",
                             children=[
-                                self.PLACEHOLDER
+                                C.PLACEHOLDER
                             ]
                         ),
                         dbc.Row(  # Latency
                             id="row-graph-lat",
                             class_name="g-0 p-2",
                             children=[
                             ]
                         ),
                         dbc.Row(  # Latency
                             id="row-graph-lat",
                             class_name="g-0 p-2",
                             children=[
-                                self.PLACEHOLDER
+                                C.PLACEHOLDER
                             ]
                         ),
                         dbc.Row(  # Download
                             id="row-btn-download",
                             class_name="g-0 p-2",
                             children=[
                             ]
                         ),
                         dbc.Row(  # Download
                             id="row-btn-download",
                             class_name="g-0 p-2",
                             children=[
-                                self.PLACEHOLDER
+                                C.PLACEHOLDER
                             ]
                         )
                     ]
                             ]
                         )
                     ]
@@ -497,7 +453,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-framesize-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-framesize-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=True,
                                     switch=False
                                 ),
                                     inline=True,
                                     switch=False
                                 ),
@@ -528,7 +484,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-core-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-core-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=False,
                                     switch=False
                                 )
                                     inline=False,
                                     switch=False
                                 )
@@ -559,7 +515,7 @@ class Layout:
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-testtype-all",
                             children=[
                                 dbc.Checklist(
                                     id="cl-ctrl-testtype-all",
-                                    options=self.CL_ALL_DISABLED,
+                                    options=C.CL_ALL_DISABLED,
                                     inline=True,
                                     switch=False
                                 ),
                                     inline=True,
                                     switch=False
                                 ),
@@ -648,7 +604,7 @@ class Layout:
                 dbc.Row(
                     id="row-card-sel-tests",
                     class_name="gy-1",
                 dbc.Row(
                     id="row-card-sel-tests",
                     class_name="gy-1",
-                    style=self.STYLE_DISABLED,
+                    style=C.STYLE_DISABLED,
                     children=[
                         dbc.Label(
                             "Selected tests",
                     children=[
                         dbc.Label(
                             "Selected tests",
@@ -665,7 +621,7 @@ class Layout:
                 ),
                 dbc.Row(
                     id="row-btns-sel-tests",
                 ),
                 dbc.Row(
                     id="row-btns-sel-tests",
-                    style=self.STYLE_DISABLED,
+                    style=C.STYLE_DISABLED,
                     children=[
                         dbc.ButtonGroup(
                             class_name="gy-2",
                     children=[
                         dbc.ButtonGroup(
                             class_name="gy-2",
@@ -695,12 +651,6 @@ class Layout:
     class ControlPanel:
         def __init__(self, panel: dict) -> None:
 
     class ControlPanel:
         def __init__(self, panel: dict) -> None:
 
-            CL_ALL_DISABLED = [{
-                "label": "All",
-                "value": "all",
-                "disabled": True
-            }]
-
             # Defines also the order of keys
             self._defaults = {
                 "dd-ctrl-dut-value": str(),
             # Defines also the order of keys
             self._defaults = {
                 "dd-ctrl-dut-value": str(),
@@ -716,15 +666,15 @@ class Layout:
                 "cl-ctrl-core-options": list(),
                 "cl-ctrl-core-value": list(),
                 "cl-ctrl-core-all-value": list(),
                 "cl-ctrl-core-options": list(),
                 "cl-ctrl-core-value": list(),
                 "cl-ctrl-core-all-value": list(),
-                "cl-ctrl-core-all-options": CL_ALL_DISABLED,
+                "cl-ctrl-core-all-options": C.CL_ALL_DISABLED,
                 "cl-ctrl-framesize-options": list(),
                 "cl-ctrl-framesize-value": list(),
                 "cl-ctrl-framesize-all-value": list(),
                 "cl-ctrl-framesize-options": list(),
                 "cl-ctrl-framesize-value": list(),
                 "cl-ctrl-framesize-all-value": list(),
-                "cl-ctrl-framesize-all-options": CL_ALL_DISABLED,
+                "cl-ctrl-framesize-all-options": C.CL_ALL_DISABLED,
                 "cl-ctrl-testtype-options": list(),
                 "cl-ctrl-testtype-value": list(),
                 "cl-ctrl-testtype-all-value": list(),
                 "cl-ctrl-testtype-options": list(),
                 "cl-ctrl-testtype-value": list(),
                 "cl-ctrl-testtype-all-value": list(),
-                "cl-ctrl-testtype-all-options": CL_ALL_DISABLED,
+                "cl-ctrl-testtype-all-options": C.CL_ALL_DISABLED,
                 "btn-ctrl-add-disabled": True,
                 "cl-normalize-value": list(),
                 "cl-selected-options": list(),
                 "btn-ctrl-add-disabled": True,
                 "cl-normalize-value": list(),
                 "cl-selected-options": list(),
@@ -788,9 +738,9 @@ class Layout:
 
             (fig_tput, fig_lat) = figs
 
 
             (fig_tput, fig_lat) = figs
 
-            row_fig_tput = self.PLACEHOLDER
-            row_fig_lat = self.PLACEHOLDER
-            row_btn_dwnld = self.PLACEHOLDER
+            row_fig_tput = C.PLACEHOLDER
+            row_fig_lat = C.PLACEHOLDER
+            row_btn_dwnld = C.PLACEHOLDER
 
             if fig_tput:
                 row_fig_tput = [
 
             if fig_tput:
                 row_fig_tput = [
@@ -822,7 +772,7 @@ class Layout:
                                 class_name="me-1",
                                 children=[
                                     dbc.InputGroupText(
                                 class_name="me-1",
                                 children=[
                                     dbc.InputGroupText(
-                                        style=self.URL_STYLE,
+                                        style=C.URL_STYLE,
                                         children=self._show_tooltip(
                                             "help-url", "URL", "input-url")
                                     ),
                                         children=self._show_tooltip(
                                             "help-url", "URL", "input-url")
                                     ),
@@ -830,7 +780,7 @@ class Layout:
                                         id="input-url",
                                         readonly=True,
                                         type="url",
                                         id="input-url",
                                         readonly=True,
                                         type="url",
-                                        style=self.URL_STYLE,
+                                        style=C.URL_STYLE,
                                         value=url
                                     )
                                 ]
                                         value=url
                                     )
                                 ]
@@ -971,15 +921,15 @@ class Layout:
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
-                    "cl-ctrl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
-                    "cl-ctrl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
-                    "cl-ctrl-testtype-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-testtype-all-options": C.CL_ALL_DISABLED,
                 })
             elif trigger_id == "dd-ctrl-phy":
                 try:
                 })
             elif trigger_id == "dd-ctrl-phy":
                 try:
@@ -1005,15 +955,15 @@ class Layout:
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
-                    "cl-ctrl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
-                    "cl-ctrl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
-                    "cl-ctrl-testtype-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-testtype-all-options": C.CL_ALL_DISABLED,
                 })
             elif trigger_id == "dd-ctrl-area":
                 try:
                 })
             elif trigger_id == "dd-ctrl-area":
                 try:
@@ -1036,15 +986,15 @@ class Layout:
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
                     "cl-ctrl-core-options": list(),
                     "cl-ctrl-core-value": list(),
                     "cl-ctrl-core-all-value": list(),
-                    "cl-ctrl-core-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-core-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
                     "cl-ctrl-framesize-options": list(),
                     "cl-ctrl-framesize-value": list(),
                     "cl-ctrl-framesize-all-value": list(),
-                    "cl-ctrl-framesize-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-framesize-all-options": C.CL_ALL_DISABLED,
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
                     "cl-ctrl-testtype-options": list(),
                     "cl-ctrl-testtype-value": list(),
                     "cl-ctrl-testtype-all-value": list(),
-                    "cl-ctrl-testtype-all-options": self.CL_ALL_DISABLED,
+                    "cl-ctrl-testtype-all-options": C.CL_ALL_DISABLED,
                 })
             elif trigger_id == "dd-ctrl-test":
                 core_opts = list()
                 })
             elif trigger_id == "dd-ctrl-test":
                 core_opts = list()
@@ -1069,15 +1019,15 @@ class Layout:
                         "cl-ctrl-core-options": core_opts,
                         "cl-ctrl-core-value": list(),
                         "cl-ctrl-core-all-value": list(),
                         "cl-ctrl-core-options": core_opts,
                         "cl-ctrl-core-value": list(),
                         "cl-ctrl-core-all-value": list(),
-                        "cl-ctrl-core-all-options": self.CL_ALL_ENABLED,
+                        "cl-ctrl-core-all-options": C.CL_ALL_ENABLED,
                         "cl-ctrl-framesize-options": framesize_opts,
                         "cl-ctrl-framesize-value": list(),
                         "cl-ctrl-framesize-all-value": list(),
                         "cl-ctrl-framesize-options": framesize_opts,
                         "cl-ctrl-framesize-value": list(),
                         "cl-ctrl-framesize-all-value": list(),
-                        "cl-ctrl-framesize-all-options": self.CL_ALL_ENABLED,
+                        "cl-ctrl-framesize-all-options": C.CL_ALL_ENABLED,
                         "cl-ctrl-testtype-options": testtype_opts,
                         "cl-ctrl-testtype-value": list(),
                         "cl-ctrl-testtype-all-value": list(),
                         "cl-ctrl-testtype-options": testtype_opts,
                         "cl-ctrl-testtype-value": list(),
                         "cl-ctrl-testtype-all-value": list(),
-                        "cl-ctrl-testtype-all-options": self.CL_ALL_ENABLED,
+                        "cl-ctrl-testtype-all-options": C.CL_ALL_ENABLED,
                     })
             elif trigger_id == "cl-ctrl-core":
                 val_sel, val_all = self._sync_checklists(
                     })
             elif trigger_id == "cl-ctrl-core":
                 val_sel, val_all = self._sync_checklists(
@@ -1180,17 +1130,17 @@ class Layout:
                                         "testtype": ttype.lower()
                                     })
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
                                         "testtype": ttype.lower()
                                     })
                     store_sel = sorted(store_sel, key=lambda d: d["id"])
-                    row_card_sel_tests = self.STYLE_ENABLED
-                    row_btns_sel_tests = self.STYLE_ENABLED
-                    if self.CLEAR_ALL_INPUTS:
+                    row_card_sel_tests = C.STYLE_ENABLED
+                    row_btns_sel_tests = C.STYLE_ENABLED
+                    if C.CLEAR_ALL_INPUTS:
                         ctrl_panel.set(ctrl_panel.defaults)
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
                         ctrl_panel.set(ctrl_panel.defaults)
             elif trigger_id == "btn-sel-remove-all":
                 _ = btn_remove_all
-                row_fig_tput = self.PLACEHOLDER
-                row_fig_lat = self.PLACEHOLDER
-                row_btn_dwnld = self.PLACEHOLDER
-                row_card_sel_tests = self.STYLE_DISABLED
-                row_btns_sel_tests = self.STYLE_DISABLED
+                row_fig_tput = C.PLACEHOLDER
+                row_fig_lat = C.PLACEHOLDER
+                row_btn_dwnld = C.PLACEHOLDER
+                row_card_sel_tests = C.STYLE_DISABLED
+                row_btns_sel_tests = C.STYLE_DISABLED
                 store_sel = list()
                 ctrl_panel.set({"cl-selected-options": list()})
             elif trigger_id == "btn-sel-remove":
                 store_sel = list()
                 ctrl_panel.set({"cl-selected-options": list()})
             elif trigger_id == "btn-sel-remove":
@@ -1210,8 +1160,8 @@ class Layout:
                     d_start = self._get_date(url_params.get("start", list())[0])
                     d_end = self._get_date(url_params.get("end", list())[0])
                     if store_sel:
                     d_start = self._get_date(url_params.get("start", list())[0])
                     d_end = self._get_date(url_params.get("end", list())[0])
                     if store_sel:
-                        row_card_sel_tests = self.STYLE_ENABLED
-                        row_btns_sel_tests = self.STYLE_ENABLED
+                        row_card_sel_tests = C.STYLE_ENABLED
+                        row_btns_sel_tests = C.STYLE_ENABLED
 
             if trigger_id in ("btn-ctrl-add", "url", "dpr-period",
                     "btn-sel-remove", "cl-ctrl-normalize"):
 
             if trigger_id in ("btn-ctrl-add", "url", "dpr-period",
                     "btn-sel-remove", "cl-ctrl-normalize"):
@@ -1226,11 +1176,11 @@ class Layout:
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                 else:
                         "cl-selected-options": self._list_tests(store_sel)
                     })
                 else:
-                    row_fig_tput = self.PLACEHOLDER
-                    row_fig_lat = self.PLACEHOLDER
-                    row_btn_dwnld = self.PLACEHOLDER
-                    row_card_sel_tests = self.STYLE_DISABLED
-                    row_btns_sel_tests = self.STYLE_DISABLED
+                    row_fig_tput = C.PLACEHOLDER
+                    row_fig_lat = C.PLACEHOLDER
+                    row_btn_dwnld = C.PLACEHOLDER
+                    row_card_sel_tests = C.STYLE_DISABLED
+                    row_btns_sel_tests = C.STYLE_DISABLED
                     store_sel = list()
                     ctrl_panel.set({"cl-selected-options": list()})
 
                     store_sel = list()
                     ctrl_panel.set({"cl-selected-options": list()})
 
index 1c64677..3697f71 100644 (file)
@@ -14,8 +14,8 @@
 """Instantiate the Trending Dash applocation.
 """
 import dash
 """Instantiate the Trending Dash applocation.
 """
 import dash
-import dash_bootstrap_components as dbc
 
 
+from ..utils.constants import Constants as C
 from .layout import Layout
 
 
 from .layout import Layout
 
 
@@ -30,16 +30,16 @@ def init_trending(server, time_period=None):
 
     dash_app = dash.Dash(
         server=server,
 
     dash_app = dash.Dash(
         server=server,
-        routes_pathname_prefix=u"/trending/",
-        external_stylesheets=[dbc.themes.LUX],
+        routes_pathname_prefix=C.TREND_ROUTES_PATHNAME_PREFIX,
+        external_stylesheets=C.EXTERNAL_STYLESHEETS
     )
 
     layout = Layout(
         app=dash_app,
     )
 
     layout = Layout(
         app=dash_app,
-        html_layout_file="pal/templates/trending_layout.jinja2",
-        graph_layout_file="pal/trending/layout.yaml",
-        data_spec_file="pal/data/data.yaml",
-        tooltip_file="pal/data/tooltips.yaml",
+        html_layout_file=C.TREND_HTML_LAYOUT_FILE,
+        graph_layout_file=C.TREND_GRAPH_LAYOUT_FILE,
+        data_spec_file=C.DATA_SPEC_FILE,
+        tooltip_file=C.TOOLTIP_FILE,
         time_period=time_period
     )
     dash_app.index_string = layout.html_layout
         time_period=time_period
     )
     dash_app.index_string = layout.html_layout
diff --git a/resources/tools/dash/app/pal/utils/__init__.py b/resources/tools/dash/app/pal/utils/__init__.py
new file mode 100644 (file)
index 0000000..5692432
--- /dev/null
@@ -0,0 +1,12 @@
+# Copyright (c) 2022 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/resources/tools/dash/app/pal/utils/constants.py b/resources/tools/dash/app/pal/utils/constants.py
new file mode 100644 (file)
index 0000000..1c84ba1
--- /dev/null
@@ -0,0 +1,299 @@
+# Copyright (c) 2022 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Constants used in Dash PAL.
+
+"Constant" means a value that keeps its value since initialization. The value
+does not need to be hard coded here, but can be read from environment variables.
+"""
+
+
+import dash_bootstrap_components as dbc
+
+from dash import html
+
+
+class Constants:
+    """Constants used in Dash PAL.
+    """
+
+    ############################################################################
+    # General, application wide constants.
+
+    # The application title.
+    TITLE = "FD.io CSIT"
+
+    # The application description.
+    DESCRIPTION = "Performance Dashboard"
+
+    # External stylesheets.
+    EXTERNAL_STYLESHEETS = [dbc.themes.LUX, ]
+
+    # Top level template for all pages.
+    TEMPLATE = "d-flex h-100 text-center text-white bg-dark"
+
+    # Path and name of the file specifying the HTML layout of the dash
+    # application.
+    MAIN_HTML_LAYOUT_FILE = "index_layout.jinja2"
+
+    # Application root.
+    APPLICATIN_ROOT = "/"
+
+    # Data to be downloaded from the parquets specification file.
+    DATA_SPEC_FILE = "pal/data/data.yaml"
+
+    # The file with tooltips.
+    TOOLTIP_FILE = "pal/utils/tooltips.yaml"
+
+    # Maximal value of TIME_PERIOD for data read from the parquets in days.
+    # Do not change without a good reason.
+    MAX_TIME_PERIOD = 180
+
+    # It defines the time period for data read from the parquets in days from
+    # now back to the past.
+    # TIME_PERIOD = None - means all data (max MAX_TIME_PERIOD days) is read.
+    # TIME_PERIOD = MAX_TIME_PERIOD - is the default value
+    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 = ["csit2206", "csit2202", ]
+
+    ############################################################################
+    # General, application wide, layout affecting constants.
+
+    # If True, clear all inputs in control panel when button "ADD SELECTED" is
+    # pressed.
+    CLEAR_ALL_INPUTS = False
+
+    # The element is disabled.
+    STYLE_DISABLED = {"display": "none"}
+
+    # The element is enabled and visible.
+    STYLE_ENABLED = {"display": "inherit"}
+
+    # Checklist "All" is disabled.
+    CL_ALL_DISABLED = [
+        {
+            "label": "All",
+            "value": "all",
+            "disabled": True
+        }
+    ]
+
+    # Checklist "All" is enable, visible and unchecked.
+    CL_ALL_ENABLED = [
+        {
+            "label": "All",
+            "value": "all",
+            "disabled": False
+        }
+    ]
+
+    # Placeholder for any element in the layout.
+    PLACEHOLDER = html.Nobr("")
+
+    # List of drivers used in CSIT.
+    DRIVERS = ("avf", "af-xdp", "rdma", "dpdk")
+
+    # Labels for input elements (dropdowns, ...).
+    LABELS = {
+        "dpdk": "DPDK",
+        "container_memif": "LXC/DRC Container Memif",
+        "crypto": "IPSec IPv4 Routing",
+        "ip4": "IPv4 Routing",
+        "ip6": "IPv6 Routing",
+        "ip4_tunnels": "IPv4 Tunnels",
+        "l2": "L2 Ethernet Switching",
+        "srv6": "SRv6 Routing",
+        "vm_vhost": "VMs vhost-user",
+        "nfv_density-dcr_memif-chain_ipsec": "CNF Service Chains Routing IPSec",
+        "nfv_density-vm_vhost-chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
+        "nfv_density-vm_vhost-chain": "VNF Service Chains Routing",
+        "nfv_density-dcr_memif-pipeline": "CNF Service Pipelines Routing",
+        "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
+    }
+
+    # URL style.
+    URL_STYLE = {
+        "background-color": "#d2ebf5",
+        "border-color": "#bce1f1",
+        "color": "#135d7c"
+    }
+
+    ############################################################################
+    # General, normalization constants.
+
+    NORM_FREQUENCY = 2.0  # [GHz]
+    FREQUENCY = {  # [GHz]
+        "2n-aws": 1.000,
+        "2n-dnv": 2.000,
+        "2n-clx": 2.300,
+        "2n-icx": 2.600,
+        "2n-skx": 2.500,
+        "2n-tx2": 2.500,
+        "2n-zn2": 2.900,
+        "3n-alt": 3.000,
+        "3n-aws": 1.000,
+        "3n-dnv": 2.000,
+        "3n-icx": 2.600,
+        "3n-skx": 2.500,
+        "3n-tsh": 2.200
+    }
+
+    ############################################################################
+    # General, plots constants.
+
+    PLOT_COLORS = (
+        "#1A1110", "#DA2647", "#214FC6", "#01786F", "#BD8260", "#FFD12A",
+        "#A6E7FF", "#738276", "#C95A49", "#FC5A8D", "#CEC8EF", "#391285",
+        "#6F2DA8", "#FF878D", "#45A27D", "#FFD0B9", "#FD5240", "#DB91EF",
+        "#44D7A8", "#4F86F7", "#84DE02", "#FFCFF1", "#614051"
+    )
+
+    # Trending, anomalies.
+    ANOMALY_COLOR = {
+        "regression": 0.0,
+        "normal": 0.5,
+        "progression": 1.0
+    }
+
+    COLORSCALE_TPUT = [
+        [0.00, "red"],
+        [0.33, "red"],
+        [0.33, "white"],
+        [0.66, "white"],
+        [0.66, "green"],
+        [1.00, "green"]
+    ]
+
+    TICK_TEXT_TPUT = ["Regression", "Normal", "Progression"]
+
+    COLORSCALE_LAT = [
+        [0.00, "green"],
+        [0.33, "green"],
+        [0.33, "white"],
+        [0.66, "white"],
+        [0.66, "red"],
+        [1.00, "red"]
+    ]
+
+    TICK_TEXT_LAT = ["Progression", "Normal", "Regression"]
+
+    # Access to the results.
+    VALUE = {
+        "mrr": "result_receive_rate_rate_avg",
+        "ndr": "result_ndr_lower_rate_value",
+        "pdr": "result_pdr_lower_rate_value",
+        "pdr-lat": "result_latency_forward_pdr_50_avg"
+    }
+
+    VALUE_ITER = {
+        "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"
+    }
+
+    UNIT = {
+        "mrr": "result_receive_rate_rate_unit",
+        "ndr": "result_ndr_lower_rate_unit",
+        "pdr": "result_pdr_lower_rate_unit",
+        "pdr-lat": "result_latency_forward_pdr_50_unit"
+    }
+
+    # Latencies.
+    LAT_HDRH = (  # Do not change the order
+        "result_latency_forward_pdr_0_hdrh",
+        "result_latency_reverse_pdr_0_hdrh",
+        "result_latency_forward_pdr_10_hdrh",
+        "result_latency_reverse_pdr_10_hdrh",
+        "result_latency_forward_pdr_50_hdrh",
+        "result_latency_reverse_pdr_50_hdrh",
+        "result_latency_forward_pdr_90_hdrh",
+        "result_latency_reverse_pdr_90_hdrh",
+    )
+
+    # This value depends on latency stream rate (9001 pps) and duration (5s).
+    # Keep it slightly higher to ensure rounding errors to not remove tick mark.
+    PERCENTILE_MAX = 99.999501
+
+    GRAPH_LAT_HDRH_DESC = {
+        "result_latency_forward_pdr_0_hdrh": "No-load.",
+        "result_latency_reverse_pdr_0_hdrh": "No-load.",
+        "result_latency_forward_pdr_10_hdrh": "Low-load, 10% PDR.",
+        "result_latency_reverse_pdr_10_hdrh": "Low-load, 10% PDR.",
+        "result_latency_forward_pdr_50_hdrh": "Mid-load, 50% PDR.",
+        "result_latency_reverse_pdr_50_hdrh": "Mid-load, 50% PDR.",
+        "result_latency_forward_pdr_90_hdrh": "High-load, 90% PDR.",
+        "result_latency_reverse_pdr_90_hdrh": "High-load, 90% PDR."
+    }
+
+    ############################################################################
+    # News.
+
+    # The pathname prefix for the application.
+    NEWS_ROUTES_PATHNAME_PREFIX = "/news/"
+
+    # Path and name of the file specifying the HTML layout of the dash
+    # application.
+    NEWS_HTML_LAYOUT_FILE = "pal/templates/news_layout.jinja2"
+
+    # The default job displayed when the page is loaded first time.
+    NEWS_DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx"
+
+    # Time period for regressions and progressions.
+    NEWS_TIME_PERIOD = 21  # [days]
+
+    ############################################################################
+    # Report.
+
+    # The pathname prefix for the application.
+    REPORT_ROUTES_PATHNAME_PREFIX = "/report/"
+
+    # Path and name of the file specifying the HTML layout of the dash
+    # application.
+    REPORT_HTML_LAYOUT_FILE = "pal/templates/report_layout.jinja2"
+
+    # Layout of plot.ly graphs.
+    REPORT_GRAPH_LAYOUT_FILE = "pal/report/layout.yaml"
+
+    ############################################################################
+    # Statistics.
+
+    # The pathname prefix for the application.
+    STATS_ROUTES_PATHNAME_PREFIX = "/stats/"
+
+    # Path and name of the file specifying the HTML layout of the dash
+    # application.
+    STATS_HTML_LAYOUT_FILE = "pal/templates/stats_layout.jinja2"
+
+    # Layout of plot.ly graphs.
+    STATS_GRAPH_LAYOUT_FILE = "pal/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"
+
+    ############################################################################
+    # Trending.
+
+    # The pathname prefix for the application.
+    TREND_ROUTES_PATHNAME_PREFIX = "/trending/"
+
+    # Path and name of the file specifying the HTML layout of the dash
+    # application.
+    TREND_HTML_LAYOUT_FILE = "pal/templates/trending_layout.jinja2"
+
+    # Layout of plot.ly graphs.
+    TREND_GRAPH_LAYOUT_FILE = "pal/trending/layout.yaml"