1 # Copyright (c) 2022 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Plotly Dash HTML layout override.
19 import dash_bootstrap_components as dbc
21 from flask import Flask
24 from dash import callback_context, no_update, ALL
25 from dash import Input, Output, State
26 from yaml import load, FullLoader, YAMLError
27 from copy import deepcopy
28 from ast import literal_eval
30 from ..utils.constants import Constants as C
31 from ..utils.url_processing import url_decode, url_encode
32 from ..data.data import Data
33 from .graphs import graph_iterative, table_comparison, get_short_version
40 def __init__(self, app: Flask, releases: list, html_layout_file: str,
41 graph_layout_file: str, data_spec_file: str, tooltip_file: str) -> None:
47 self.releases = releases
48 self._html_layout_file = html_layout_file
49 self._graph_layout_file = graph_layout_file
50 self._data_spec_file = data_spec_file
51 self._tooltip_file = tooltip_file
54 self._data = pd.DataFrame()
56 data_mrr = Data(self._data_spec_file, True).\
57 read_iterative_mrr(release=rls.replace("csit", "rls"))
58 data_mrr["release"] = rls
59 data_ndrpdr = Data(self._data_spec_file, True).\
60 read_iterative_ndrpdr(release=rls.replace("csit", "rls"))
61 data_ndrpdr["release"] = rls
62 self._data = pd.concat(
63 [self._data, data_mrr, data_ndrpdr], ignore_index=True)
65 # Get structure of tests:
67 cols = ["job", "test_id", "test_type", "dut_version", "release"]
68 for _, row in self._data[cols].drop_duplicates().iterrows():
70 ttype = row["test_type"]
71 lst_job = row["job"].split("-")
73 d_ver = get_short_version(row["dut_version"], dut)
74 tbed = "-".join(lst_job[-2:])
75 lst_test_id = row["test_id"].split(".")
79 area = "-".join(lst_test_id[3:-2])
80 suite = lst_test_id[-2].replace("2n1l-", "").replace("1n1l-", "").\
82 test = lst_test_id[-1]
83 nic = suite.split("-")[0]
86 driver = drv.replace("-", "_")
87 test = test.replace(f"{drv}-", "")
91 infra = "-".join((tbed, nic, driver))
92 lst_test = test.split("-")
93 framesize = lst_test[0]
94 core = lst_test[1] if lst_test[1] else "8C"
95 test = "-".join(lst_test[2: -1])
97 if tbs.get(rls, None) is None:
99 if tbs[rls].get(dut, None) is None:
100 tbs[rls][dut] = dict()
101 if tbs[rls][dut].get(d_ver, None) is None:
102 tbs[rls][dut][d_ver] = dict()
103 if tbs[rls][dut][d_ver].get(infra, None) is None:
104 tbs[rls][dut][d_ver][infra] = dict()
105 if tbs[rls][dut][d_ver][infra].get(area, None) is None:
106 tbs[rls][dut][d_ver][infra][area] = dict()
107 if tbs[rls][dut][d_ver][infra][area].get(test, None) is None:
108 tbs[rls][dut][d_ver][infra][area][test] = dict()
109 tbs[rls][dut][d_ver][infra][area][test]["core"] = list()
110 tbs[rls][dut][d_ver][infra][area][test]["frame-size"] = list()
111 tbs[rls][dut][d_ver][infra][area][test]["test-type"] = list()
112 if core.upper() not in \
113 tbs[rls][dut][d_ver][infra][area][test]["core"]:
114 tbs[rls][dut][d_ver][infra][area][test]["core"].append(
116 if framesize.upper() not in \
117 tbs[rls][dut][d_ver][infra][area][test]["frame-size"]:
118 tbs[rls][dut][d_ver][infra][area][test]["frame-size"].append(
122 tbs[rls][dut][d_ver][infra][area][test]["test-type"]:
123 tbs[rls][dut][d_ver][infra][area][test]["test-type"].append(
125 elif ttype == "ndrpdr":
127 tbs[rls][dut][d_ver][infra][area][test]["test-type"]:
128 tbs[rls][dut][d_ver][infra][area][test]["test-type"].extend(
133 self._html_layout = ""
134 self._graph_layout = None
135 self._tooltips = dict()
138 with open(self._html_layout_file, "r") as file_read:
139 self._html_layout = file_read.read()
140 except IOError as err:
142 f"Not possible to open the file {self._html_layout_file}\n{err}"
146 with open(self._graph_layout_file, "r") as file_read:
147 self._graph_layout = load(file_read, Loader=FullLoader)
148 except IOError as err:
150 f"Not possible to open the file {self._graph_layout_file}\n"
153 except YAMLError as err:
155 f"An error occurred while parsing the specification file "
156 f"{self._graph_layout_file}\n{err}"
160 with open(self._tooltip_file, "r") as file_read:
161 self._tooltips = load(file_read, Loader=FullLoader)
162 except IOError as err:
164 f"Not possible to open the file {self._tooltip_file}\n{err}"
166 except YAMLError as err:
168 f"An error occurred while parsing the specification file "
169 f"{self._tooltip_file}\n{err}"
173 if self._app is not None and hasattr(self, 'callbacks'):
174 self.callbacks(self._app)
177 def html_layout(self):
178 return self._html_layout
182 return self._spec_tbs
190 return self._graph_layout
192 def label(self, key: str) -> str:
193 return C.LABELS.get(key, key)
195 def _show_tooltip(self, id: str, title: str,
196 clipboard_id: str=None) -> list:
200 dcc.Clipboard(target_id=clipboard_id, title="Copy URL") \
201 if clipboard_id else str(),
209 class_name="border ms-1",
212 children=self._tooltips.get(id, str()),
218 def add_content(self):
221 if self.html_layout and self.spec_tbs:
235 id="offcanvas-metadata",
236 title="Throughput And Latency",
240 dbc.Row(id="metadata-tput-lat"),
241 dbc.Row(id="metadata-hdrh-graph"),
249 dcc.Store(id="selected-tests"),
250 dcc.Store(id="control-panel"),
251 dcc.Location(id="url", refresh=False),
252 self._add_ctrl_col(),
253 self._add_plotting_col(),
271 def _add_navbar(self):
272 """Add nav element with navigation panel. It is placed on the top.
274 return dbc.NavbarSimple(
275 id="navbarsimple-main",
279 "Iterative Test Runs",
288 brand_external_link=True,
293 def _add_ctrl_col(self) -> dbc.Col:
294 """Add column with controls. It is placed on the left side.
299 self._add_ctrl_panel(),
303 def _add_plotting_col(self) -> dbc.Col:
304 """Add column with plots and tables. It is placed on the right side.
307 id="col-plotting-area",
312 class_name="g-0 p-2",
315 dbc.Row( # Throughput
317 class_name="g-0 p-2",
318 children=[C.PLACEHOLDER, ]
325 class_name="g-0 p-2",
326 children=[C.PLACEHOLDER, ]
334 class_name="g-0 p-2",
335 children=[C.PLACEHOLDER, ]
338 id="row-btn-download",
339 class_name="g-0 p-2",
340 children=[C.PLACEHOLDER, ]
348 def _add_ctrl_panel(self) -> dbc.Row:
353 class_name="g-0 p-2",
361 children=self._show_tooltip(
362 "help-release", "CSIT Release")
366 placeholder=("Select a Release..."),
369 {"label": k, "value": k} \
370 for k in self.spec_tbs.keys()
372 key=lambda d: d["label"]
387 children=self._show_tooltip(
393 "Select a Device under Test..."
408 children=self._show_tooltip(
409 "help-dut-ver", "DUT Version")
414 "Select a Version of "
415 "Device under Test..."
430 children=self._show_tooltip(
431 "help-infra", "Infra")
436 "Select a Physical Test Bed "
452 children=self._show_tooltip(
457 placeholder="Select an Area...",
472 children=self._show_tooltip(
477 placeholder="Select a Test...",
487 id="row-ctrl-framesize",
491 children=self._show_tooltip(
492 "help-framesize", "Frame Size"),
498 id="cl-ctrl-framesize-all",
499 options=C.CL_ALL_DISABLED,
509 id="cl-ctrl-framesize",
522 children=self._show_tooltip(
523 "help-cores", "Number of Cores"),
529 id="cl-ctrl-core-all",
530 options=C.CL_ALL_DISABLED,
549 id="row-ctrl-testtype",
553 children=self._show_tooltip(
554 "help-ttype", "Test Type"),
560 id="cl-ctrl-testtype-all",
561 options=C.CL_ALL_DISABLED,
571 id="cl-ctrl-testtype",
580 id="row-ctrl-normalize",
584 children=self._show_tooltip(
585 "help-normalize", "Normalize"),
591 id="cl-ctrl-normalize",
593 "value": "normalize",
595 "Normalize results to CPU"
608 class_name="gy-1 p-0",
614 children="Add Selected",
624 id="row-card-sel-tests",
626 style=C.STYLE_DISABLED,
633 class_name="overflow-auto",
637 style={"max-height": "20em"},
642 id="row-btns-sel-tests",
643 style=C.STYLE_DISABLED,
650 children="Remove Selected",
651 class_name="w-100 me-1",
656 id="btn-sel-remove-all",
657 children="Remove All",
658 class_name="w-100 me-1",
671 def __init__(self, panel: dict) -> None:
673 # Defines also the order of keys
675 "dd-rls-value": str(),
676 "dd-dut-options": list(),
677 "dd-dut-disabled": True,
678 "dd-dut-value": str(),
679 "dd-dutver-options": list(),
680 "dd-dutver-disabled": True,
681 "dd-dutver-value": str(),
682 "dd-phy-options": list(),
683 "dd-phy-disabled": True,
684 "dd-phy-value": str(),
685 "dd-area-options": list(),
686 "dd-area-disabled": True,
687 "dd-area-value": str(),
688 "dd-test-options": list(),
689 "dd-test-disabled": True,
690 "dd-test-value": str(),
691 "cl-core-options": list(),
692 "cl-core-value": list(),
693 "cl-core-all-value": list(),
694 "cl-core-all-options": C.CL_ALL_DISABLED,
695 "cl-framesize-options": list(),
696 "cl-framesize-value": list(),
697 "cl-framesize-all-value": list(),
698 "cl-framesize-all-options": C.CL_ALL_DISABLED,
699 "cl-testtype-options": list(),
700 "cl-testtype-value": list(),
701 "cl-testtype-all-value": list(),
702 "cl-testtype-all-options": C.CL_ALL_DISABLED,
703 "btn-add-disabled": True,
704 "cl-normalize-value": list(),
705 "cl-selected-options": list()
708 self._panel = deepcopy(self._defaults)
710 for key in self._defaults:
711 self._panel[key] = panel[key]
714 def defaults(self) -> dict:
715 return self._defaults
718 def panel(self) -> dict:
721 def set(self, kwargs: dict) -> None:
722 for key, val in kwargs.items():
723 if key in self._panel:
724 self._panel[key] = val
726 raise KeyError(f"The key {key} is not defined.")
728 def get(self, key: str) -> any:
729 return self._panel[key]
731 def values(self) -> tuple:
732 return tuple(self._panel.values())
735 def _sync_checklists(opt: list, sel: list, all: list, id: str) -> tuple:
738 options = {v["value"] for v in opt}
740 sel = list(options) if all else list()
742 all = ["all", ] if set(sel) == options else list()
746 def _list_tests(selection: dict) -> list:
747 """Display selected tests with checkboxes
750 return [{"label": v["id"], "value": v["id"]} for v in selection]
754 def callbacks(self, app):
756 def _generate_plotting_area(figs: tuple, table: pd.DataFrame,
761 (fig_tput, fig_lat) = figs
763 row_fig_tput = C.PLACEHOLDER
764 row_fig_lat = C.PLACEHOLDER
765 row_table = C.PLACEHOLDER
766 row_btn_dwnld = C.PLACEHOLDER
771 id={"type": "graph", "index": "tput"},
779 dcc.Loading(children=[
781 id="btn-download-data",
782 children=self._show_tooltip(
783 "help-download", "Download Data"),
787 dcc.Download(id="download-data")
799 children=self._show_tooltip(
800 "help-url", "URL", "input-url")
817 id={"type": "graph", "index": "lat"},
823 dbc.Table.from_dataframe(
825 id={"type": "table", "index": "compare"},
832 return row_fig_tput, row_fig_lat, row_table, row_btn_dwnld
835 Output("control-panel", "data"), # Store
836 Output("selected-tests", "data"), # Store
837 Output("row-graph-tput", "children"),
838 Output("row-graph-lat", "children"),
839 Output("row-table", "children"),
840 Output("row-btn-download", "children"),
841 Output("row-card-sel-tests", "style"),
842 Output("row-btns-sel-tests", "style"),
843 Output("dd-ctrl-rls", "value"),
844 Output("dd-ctrl-dut", "options"),
845 Output("dd-ctrl-dut", "disabled"),
846 Output("dd-ctrl-dut", "value"),
847 Output("dd-ctrl-dutver", "options"),
848 Output("dd-ctrl-dutver", "disabled"),
849 Output("dd-ctrl-dutver", "value"),
850 Output("dd-ctrl-phy", "options"),
851 Output("dd-ctrl-phy", "disabled"),
852 Output("dd-ctrl-phy", "value"),
853 Output("dd-ctrl-area", "options"),
854 Output("dd-ctrl-area", "disabled"),
855 Output("dd-ctrl-area", "value"),
856 Output("dd-ctrl-test", "options"),
857 Output("dd-ctrl-test", "disabled"),
858 Output("dd-ctrl-test", "value"),
859 Output("cl-ctrl-core", "options"),
860 Output("cl-ctrl-core", "value"),
861 Output("cl-ctrl-core-all", "value"),
862 Output("cl-ctrl-core-all", "options"),
863 Output("cl-ctrl-framesize", "options"),
864 Output("cl-ctrl-framesize", "value"),
865 Output("cl-ctrl-framesize-all", "value"),
866 Output("cl-ctrl-framesize-all", "options"),
867 Output("cl-ctrl-testtype", "options"),
868 Output("cl-ctrl-testtype", "value"),
869 Output("cl-ctrl-testtype-all", "value"),
870 Output("cl-ctrl-testtype-all", "options"),
871 Output("btn-ctrl-add", "disabled"),
872 Output("cl-ctrl-normalize", "value"),
873 Output("cl-selected", "options"), # User selection
874 State("control-panel", "data"), # Store
875 State("selected-tests", "data"), # Store
876 State("cl-selected", "value"), # User selection
877 Input("dd-ctrl-rls", "value"),
878 Input("dd-ctrl-dut", "value"),
879 Input("dd-ctrl-dutver", "value"),
880 Input("dd-ctrl-phy", "value"),
881 Input("dd-ctrl-area", "value"),
882 Input("dd-ctrl-test", "value"),
883 Input("cl-ctrl-core", "value"),
884 Input("cl-ctrl-core-all", "value"),
885 Input("cl-ctrl-framesize", "value"),
886 Input("cl-ctrl-framesize-all", "value"),
887 Input("cl-ctrl-testtype", "value"),
888 Input("cl-ctrl-testtype-all", "value"),
889 Input("cl-ctrl-normalize", "value"),
890 Input("btn-ctrl-add", "n_clicks"),
891 Input("btn-sel-remove", "n_clicks"),
892 Input("btn-sel-remove-all", "n_clicks"),
895 def _update_ctrl_panel(cp_data: dict, store_sel: list, list_sel: list,
896 dd_rls: str, dd_dut: str, dd_dutver: str, dd_phy: str, dd_area: str,
897 dd_test: str, cl_core: list, cl_core_all: list, cl_framesize: list,
898 cl_framesize_all: list, cl_testtype: list, cl_testtype_all: list,
899 cl_normalize: list, btn_add: int, btn_remove: int,
900 btn_remove_all: int, href: str) -> tuple:
904 def _gen_new_url(parsed_url: dict, store_sel: list) -> str:
907 new_url = url_encode({
908 "scheme": parsed_url["scheme"],
909 "netloc": parsed_url["netloc"],
910 "path": parsed_url["path"],
912 "store_sel": store_sel,
919 ctrl_panel = self.ControlPanel(cp_data)
922 parsed_url = url_decode(href)
924 row_fig_tput = no_update
925 row_fig_lat = no_update
926 row_table = no_update
927 row_btn_dwnld = no_update
928 row_card_sel_tests = no_update
929 row_btns_sel_tests = no_update
931 trigger_id = callback_context.triggered[0]["prop_id"].split(".")[0]
933 if trigger_id == "dd-ctrl-rls":
935 rls = self.spec_tbs[dd_rls]
937 [{"label": v, "value": v} for v in rls.keys()],
938 key=lambda d: d["label"]
945 "dd-rls-value": dd_rls,
946 "dd-dut-value": str(),
947 "dd-dut-options": options,
948 "dd-dut-disabled": disabled,
949 "dd-dutver-value": str(),
950 "dd-dutver-options": list(),
951 "dd-dutver-disabled": True,
952 "dd-phy-value": str(),
953 "dd-phy-options": list(),
954 "dd-phy-disabled": True,
955 "dd-area-value": str(),
956 "dd-area-options": list(),
957 "dd-area-disabled": True,
958 "dd-test-value": str(),
959 "dd-test-options": list(),
960 "dd-test-disabled": True,
961 "cl-core-options": list(),
962 "cl-core-value": list(),
963 "cl-core-all-value": list(),
964 "cl-core-all-options": C.CL_ALL_DISABLED,
965 "cl-framesize-options": list(),
966 "cl-framesize-value": list(),
967 "cl-framesize-all-value": list(),
968 "cl-framesize-all-options": C.CL_ALL_DISABLED,
969 "cl-testtype-options": list(),
970 "cl-testtype-value": list(),
971 "cl-testtype-all-value": list(),
972 "cl-testtype-all-options": C.CL_ALL_DISABLED
974 elif trigger_id == "dd-ctrl-dut":
976 rls = ctrl_panel.get("dd-rls-value")
977 dut = self.spec_tbs[rls][dd_dut]
979 [{"label": v, "value": v} for v in dut.keys()],
980 key=lambda d: d["label"]
987 "dd-dut-value": dd_dut,
988 "dd-dutver-value": str(),
989 "dd-dutver-options": options,
990 "dd-dutver-disabled": disabled,
991 "dd-phy-value": str(),
992 "dd-phy-options": list(),
993 "dd-phy-disabled": True,
994 "dd-area-value": str(),
995 "dd-area-options": list(),
996 "dd-area-disabled": True,
997 "dd-test-value": str(),
998 "dd-test-options": list(),
999 "dd-test-disabled": True,
1000 "cl-core-options": list(),
1001 "cl-core-value": list(),
1002 "cl-core-all-value": list(),
1003 "cl-core-all-options": C.CL_ALL_DISABLED,
1004 "cl-framesize-options": list(),
1005 "cl-framesize-value": list(),
1006 "cl-framesize-all-value": list(),
1007 "cl-framesize-all-options": C.CL_ALL_DISABLED,
1008 "cl-testtype-options": list(),
1009 "cl-testtype-value": list(),
1010 "cl-testtype-all-value": list(),
1011 "cl-testtype-all-options": C.CL_ALL_DISABLED
1013 elif trigger_id == "dd-ctrl-dutver":
1015 rls = ctrl_panel.get("dd-rls-value")
1016 dut = ctrl_panel.get("dd-dut-value")
1017 dutver = self.spec_tbs[rls][dut][dd_dutver]
1019 [{"label": v, "value": v} for v in dutver.keys()],
1020 key=lambda d: d["label"]
1027 "dd-dutver-value": dd_dutver,
1028 "dd-phy-value": str(),
1029 "dd-phy-options": options,
1030 "dd-phy-disabled": disabled,
1031 "dd-area-value": str(),
1032 "dd-area-options": list(),
1033 "dd-area-disabled": True,
1034 "dd-test-value": str(),
1035 "dd-test-options": list(),
1036 "dd-test-disabled": True,
1037 "cl-core-options": list(),
1038 "cl-core-value": list(),
1039 "cl-core-all-value": list(),
1040 "cl-core-all-options": C.CL_ALL_DISABLED,
1041 "cl-framesize-options": list(),
1042 "cl-framesize-value": list(),
1043 "cl-framesize-all-value": list(),
1044 "cl-framesize-all-options": C.CL_ALL_DISABLED,
1045 "cl-testtype-options": list(),
1046 "cl-testtype-value": list(),
1047 "cl-testtype-all-value": list(),
1048 "cl-testtype-all-options": C.CL_ALL_DISABLED
1050 elif trigger_id == "dd-ctrl-phy":
1052 rls = ctrl_panel.get("dd-rls-value")
1053 dut = ctrl_panel.get("dd-dut-value")
1054 dutver = ctrl_panel.get("dd-dutver-value")
1055 phy = self.spec_tbs[rls][dut][dutver][dd_phy]
1057 [{"label": self.label(v), "value": v}
1058 for v in phy.keys()],
1059 key=lambda d: d["label"]
1066 "dd-phy-value": dd_phy,
1067 "dd-area-value": str(),
1068 "dd-area-options": options,
1069 "dd-area-disabled": disabled,
1070 "dd-test-value": str(),
1071 "dd-test-options": list(),
1072 "dd-test-disabled": True,
1073 "cl-core-options": list(),
1074 "cl-core-value": list(),
1075 "cl-core-all-value": list(),
1076 "cl-core-all-options": C.CL_ALL_DISABLED,
1077 "cl-framesize-options": list(),
1078 "cl-framesize-value": list(),
1079 "cl-framesize-all-value": list(),
1080 "cl-framesize-all-options": C.CL_ALL_DISABLED,
1081 "cl-testtype-options": list(),
1082 "cl-testtype-value": list(),
1083 "cl-testtype-all-value": list(),
1084 "cl-testtype-all-options": C.CL_ALL_DISABLED
1086 elif trigger_id == "dd-ctrl-area":
1088 rls = ctrl_panel.get("dd-rls-value")
1089 dut = ctrl_panel.get("dd-dut-value")
1090 dutver = ctrl_panel.get("dd-dutver-value")
1091 phy = ctrl_panel.get("dd-phy-value")
1092 area = self.spec_tbs[rls][dut][dutver][phy][dd_area]
1094 [{"label": v, "value": v} for v in area.keys()],
1095 key=lambda d: d["label"]
1102 "dd-area-value": dd_area,
1103 "dd-test-value": str(),
1104 "dd-test-options": options,
1105 "dd-test-disabled": disabled,
1106 "cl-core-options": list(),
1107 "cl-core-value": list(),
1108 "cl-core-all-value": list(),
1109 "cl-core-all-options": C.CL_ALL_DISABLED,
1110 "cl-framesize-options": list(),
1111 "cl-framesize-value": list(),
1112 "cl-framesize-all-value": list(),
1113 "cl-framesize-all-options": C.CL_ALL_DISABLED,
1114 "cl-testtype-options": list(),
1115 "cl-testtype-value": list(),
1116 "cl-testtype-all-value": list(),
1117 "cl-testtype-all-options": C.CL_ALL_DISABLED
1119 elif trigger_id == "dd-ctrl-test":
1120 rls = ctrl_panel.get("dd-rls-value")
1121 dut = ctrl_panel.get("dd-dut-value")
1122 dutver = ctrl_panel.get("dd-dutver-value")
1123 phy = ctrl_panel.get("dd-phy-value")
1124 area = ctrl_panel.get("dd-area-value")
1125 test = self.spec_tbs[rls][dut][dutver][phy][area][dd_test]
1126 if dut and phy and area and dd_test:
1128 "dd-test-value": dd_test,
1129 "cl-core-options": [{"label": v, "value": v}
1130 for v in sorted(test["core"])],
1131 "cl-core-value": list(),
1132 "cl-core-all-value": list(),
1133 "cl-core-all-options": C.CL_ALL_ENABLED,
1134 "cl-framesize-options": [{"label": v, "value": v}
1135 for v in sorted(test["frame-size"])],
1136 "cl-framesize-value": list(),
1137 "cl-framesize-all-value": list(),
1138 "cl-framesize-all-options": C.CL_ALL_ENABLED,
1139 "cl-testtype-options": [{"label": v, "value": v}
1140 for v in sorted(test["test-type"])],
1141 "cl-testtype-value": list(),
1142 "cl-testtype-all-value": list(),
1143 "cl-testtype-all-options": C.CL_ALL_ENABLED,
1145 elif trigger_id == "cl-ctrl-core":
1146 val_sel, val_all = self._sync_checklists(
1147 opt=ctrl_panel.get("cl-core-options"),
1153 "cl-core-value": val_sel,
1154 "cl-core-all-value": val_all,
1156 elif trigger_id == "cl-ctrl-core-all":
1157 val_sel, val_all = self._sync_checklists(
1158 opt = ctrl_panel.get("cl-core-options"),
1164 "cl-core-value": val_sel,
1165 "cl-core-all-value": val_all,
1167 elif trigger_id == "cl-ctrl-framesize":
1168 val_sel, val_all = self._sync_checklists(
1169 opt = ctrl_panel.get("cl-framesize-options"),
1175 "cl-framesize-value": val_sel,
1176 "cl-framesize-all-value": val_all,
1178 elif trigger_id == "cl-ctrl-framesize-all":
1179 val_sel, val_all = self._sync_checklists(
1180 opt = ctrl_panel.get("cl-framesize-options"),
1182 all=cl_framesize_all,
1186 "cl-framesize-value": val_sel,
1187 "cl-framesize-all-value": val_all,
1189 elif trigger_id == "cl-ctrl-testtype":
1190 val_sel, val_all = self._sync_checklists(
1191 opt = ctrl_panel.get("cl-testtype-options"),
1197 "cl-testtype-value": val_sel,
1198 "cl-testtype-all-value": val_all,
1200 elif trigger_id == "cl-ctrl-testtype-all":
1201 val_sel, val_all = self._sync_checklists(
1202 opt = ctrl_panel.get("cl-testtype-options"),
1204 all=cl_testtype_all,
1208 "cl-testtype-value": val_sel,
1209 "cl-testtype-all-value": val_all,
1211 elif trigger_id == "btn-ctrl-add":
1213 rls = ctrl_panel.get("dd-rls-value")
1214 dut = ctrl_panel.get("dd-dut-value")
1215 dutver = ctrl_panel.get("dd-dutver-value")
1216 phy = ctrl_panel.get("dd-phy-value")
1217 area = ctrl_panel.get("dd-area-value")
1218 test = ctrl_panel.get("dd-test-value")
1219 cores = ctrl_panel.get("cl-core-value")
1220 framesizes = ctrl_panel.get("cl-framesize-value")
1221 testtypes = ctrl_panel.get("cl-testtype-value")
1222 # Add selected test to the list of tests in store:
1223 if all((rls, dut, dutver, phy, area, test, cores, framesizes,
1225 if store_sel is None:
1228 for framesize in framesizes:
1229 for ttype in testtypes:
1232 tid = "-".join((rls, dut, dutver,
1233 phy.replace('af_xdp', 'af-xdp'), area,
1234 framesize.lower(), core.lower(), test,
1236 if tid not in [itm["id"] for itm in store_sel]:
1245 "framesize": framesize.lower(),
1246 "core": core.lower(),
1247 "testtype": ttype.lower()
1249 store_sel = sorted(store_sel, key=lambda d: d["id"])
1250 row_card_sel_tests = C.STYLE_ENABLED
1251 row_btns_sel_tests = C.STYLE_ENABLED
1252 if C.CLEAR_ALL_INPUTS:
1253 ctrl_panel.set(ctrl_panel.defaults)
1255 "cl-selected-options": self._list_tests(store_sel)
1257 elif trigger_id == "btn-sel-remove-all":
1259 row_fig_tput = C.PLACEHOLDER
1260 row_fig_lat = C.PLACEHOLDER
1261 row_table = C.PLACEHOLDER
1262 row_btn_dwnld = C.PLACEHOLDER
1263 row_card_sel_tests = C.STYLE_DISABLED
1264 row_btns_sel_tests = C.STYLE_DISABLED
1266 ctrl_panel.set({"cl-selected-options": list()})
1267 elif trigger_id == "btn-sel-remove":
1270 new_store_sel = list()
1271 for item in store_sel:
1272 if item["id"] not in list_sel:
1273 new_store_sel.append(item)
1274 store_sel = new_store_sel
1275 elif trigger_id == "url":
1276 # TODO: Add verification
1277 url_params = parsed_url["params"]
1279 store_sel = literal_eval(
1280 url_params.get("store_sel", list())[0])
1282 row_card_sel_tests = C.STYLE_ENABLED
1283 row_btns_sel_tests = C.STYLE_ENABLED
1285 if trigger_id in ("btn-ctrl-add", "url", "btn-sel-remove",
1286 "cl-ctrl-normalize"):
1288 row_fig_tput, row_fig_lat, row_table, row_btn_dwnld = \
1289 _generate_plotting_area(
1291 self.data, store_sel, self.layout,
1295 self.data, store_sel, bool(cl_normalize)
1297 _gen_new_url(parsed_url, store_sel)
1300 "cl-selected-options": self._list_tests(store_sel)
1303 row_fig_tput = C.PLACEHOLDER
1304 row_fig_lat = C.PLACEHOLDER
1305 row_table = C.PLACEHOLDER
1306 row_btn_dwnld = C.PLACEHOLDER
1307 row_card_sel_tests = C.STYLE_DISABLED
1308 row_btns_sel_tests = C.STYLE_DISABLED
1310 ctrl_panel.set({"cl-selected-options": list()})
1312 if ctrl_panel.get("cl-core-value") and \
1313 ctrl_panel.get("cl-framesize-value") and \
1314 ctrl_panel.get("cl-testtype-value"):
1319 "btn-add-disabled": disabled,
1320 "cl-normalize-value": cl_normalize
1324 ctrl_panel.panel, store_sel,
1325 row_fig_tput, row_fig_lat, row_table, row_btn_dwnld,
1326 row_card_sel_tests, row_btns_sel_tests
1328 ret_val.extend(ctrl_panel.values())
1332 # Output("download-data", "data"),
1333 # State("selected-tests", "data"),
1334 # Input("btn-download-data", "n_clicks"),
1335 # prevent_initial_call=True
1337 # def _download_data(store_sel, n_clicks):
1342 # raise PreventUpdate
1345 # raise PreventUpdate
1347 # df = pd.DataFrame()
1348 # for itm in store_sel:
1349 # sel_data = select_trending_data(self.data, itm)
1350 # if sel_data is None:
1352 # df = pd.concat([df, sel_data], ignore_index=True)
1354 # return dcc.send_data_frame(df.to_csv, "trending_data.csv")