1 # Copyright (c) 2024 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 """Constants used in CDash.
16 "Constant" means a value that keeps its value since initialization. The value
17 does not need to be hard coded here, but can be read from environment variables.
26 def get_str_from_env(env_var_name: str, default_value: str) -> str:
27 """Attempt to read string from environment variable, return that or default.
29 The environment variable must start with perfix "CSIT_".
31 If environment variable exists, but is empty (and default is not),
32 empty string is returned.
34 :param env_var_name: Base name of environment variable to attempt to read.
35 :param default_value: Value to return if the env var does not exist.
36 :type env_var_names: str
37 :type default_value: str
38 :returns: The value read, or default value.
42 env_str = os.environ.get(prefix + env_var_name, None)
43 if env_str is not None:
48 def get_int_from_env(env_var_name: str, default_value: int) -> int:
49 """Attempt to read int from environment variable, return that or default.
51 The environment variable must start with perfix "CSIT_".
53 String value is read, default is returned also if conversion fails.
55 :param env_var_name: Base name of environment variable to attempt to read.
56 :param default_value: Value to return if read or conversion fails.
57 :type env_var_names: str
58 :type default_value: int
59 :returns: The value read, or default value.
63 return int(get_str_from_env(env_var_name, str()))
68 def get_bool_from_env(env_var_name: str, default_value: bool) -> bool:
69 """Attempt to read bool from environment variable, return that or default.
71 The environment variable must start with perfix "CSIT_".
73 :param env_var_name: Base name of environment variable to attempt to read.
74 :param default_value: Value to return if read or conversion fails.
75 :type env_var_names: str
76 :type default_value: bool
77 :returns: The value read, or default value.
80 env_str = get_str_from_env(env_var_name, str()).lower()
81 if env_str in ("true", "yes", "y", "1"):
83 elif env_str in ("false", "no", "n", "0"):
90 """Constants used in CDash.
93 ############################################################################
94 # General, application wide constants.
96 # Select applications to start.
97 START_TRENDING = get_bool_from_env("START_TRENDING", True)
98 START_REPORT = get_bool_from_env("START_REPORT", True)
99 START_COMPARISONS = get_bool_from_env("START_COMPARISONS", True)
100 START_COVERAGE = get_bool_from_env("START_COVERAGE", True)
101 START_STATISTICS = get_bool_from_env("START_STATISTICS", True)
102 START_FAILURES = get_bool_from_env("START_FAILURES", True)
103 START_SEARCH = get_bool_from_env("START_SEARCH", True)
104 START_DOC = get_bool_from_env("START_DOC", True)
107 LOG_LEVEL = logging.INFO
108 LOG_FORMAT = "%(asctime)s: %(levelname)s: %(message)s"
109 LOG_DATE_FORMAT = "%Y/%m/%d %H:%M:%S"
111 # The application title.
112 TITLE = get_str_from_env("TITLE", "FD.io CSIT")
113 BRAND = get_str_from_env("BRAND", "CSIT-Dash")
115 # The application description.
116 DESCRIPTION = "Performance Dashboard"
118 # External stylesheets.
119 EXTERNAL_STYLESHEETS = ["/static/dist/css/bootstrap.css", ]
122 URL_CICD = get_str_from_env("URL_CICD", "https://jenkins.fd.io/job/")
125 URL_LOGS = get_str_from_env(
126 "URL_LOGS", "https://logs.fd.io/vex-yul-rot-jenkins-1/"
129 # URL to the documentation
130 URL_DOC = get_str_from_env("URL_DOC", "https://csit.fd.io/cdocs/")
131 URL_DOC_TRENDING = URL_DOC + "methodology/trending/analysis/"
132 URL_DOC_REL_NOTES = URL_DOC + "release_notes/current/"
134 # Path and name of the file specifying the HTML layout of the dash
136 MAIN_HTML_LAYOUT_FILE = "base_layout.jinja2"
138 # Path and name of the file specifying the HTML layout of the dash
140 HTML_LAYOUT_FILE = "cdash/templates/dash_layout.jinja2"
143 APPLICATIN_ROOT = "/"
145 # Data to be downloaded from the parquets specification file.
146 DATA_SPEC_FILE = "cdash/data/data.yaml"
148 # Path to schemas to use when reading data from the parquet.
149 PATH_TO_SCHEMAS = "cdash/data/_metadata/"
151 # The file with tooltips.
152 TOOLTIP_FILE = "cdash/utils/tooltips.yaml"
154 # Maximal value of TIME_PERIOD for data read from the parquets in days.
155 # Do not change without a good reason.
156 MAX_TIME_PERIOD = 250
158 # It defines the time period for data read from the parquets in days from
159 # now back to the past.
160 # TIME_PERIOD = None - means all data (max MAX_TIME_PERIOD days) is read.
161 # TIME_PERIOD = MAX_TIME_PERIOD - is the default value
162 TIME_PERIOD = get_int_from_env("TIME_PERIOD", MAX_TIME_PERIOD) # [days]
164 ############################################################################
165 # General, application wide, layout affecting constants.
167 # Add a time delay (in ms) to the spinner being shown
170 # If True, clear all inputs in control panel when button "ADD SELECTED" is
172 CLEAR_ALL_INPUTS = False
174 # The element is disabled.
175 STYLE_DISABLED = {"visibility": "hidden"}
177 # The element is enabled and visible.
178 STYLE_ENABLED = {"visibility": "visible"}
180 # The element is not displayed.
181 STYLE_DONT_DISPLAY = {"display": "none"}
183 # The element is displaed.
184 STYLE_DISPLAY = {"display": "flex"}
186 # Checklist "All" is disabled.
195 # Checklist "All" is enabled, visible and unchecked.
204 # Placeholder for any element in the layout.
205 PLACEHOLDER = html.Nobr("")
207 # List of drivers used in CSIT.
208 DRIVERS = ("avf", "af-xdp", "rdma", "dpdk", "mlx5")
210 # Labels for input elements (dropdowns, ...).
213 "container_memif": "LXC/DRC Container Memif",
214 "crypto": "IPSec IPv4 Routing",
216 "ip4": "IPv4 Routing",
217 "ip4_tunnels": "IPv4 Tunnels",
218 "ip6": "IPv6 Routing",
219 "ip6_tunnels": "IPv6 Tunnels",
220 "l2": "L2 Ethernet Switching",
221 "lb": "Load Balancer",
222 "srv6": "SRv6 Routing",
223 "vm_vhost": "VMs vhost-user",
224 "nfv_density.dcr_memif.chain_ipsec": "CNF Service Chains Routing IPSec",
225 "nfv_density.vm_vhost.chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
226 "nfv_density.vm_vhost.chain": "VNF Service Chains Routing",
227 "nfv_density.dcr_memif.pipeline": "CNF Service Pipelines Routing",
228 "nfv_density.dcr_memif.chain": "CNF Service Chains Routing",
229 "hoststack": "Hoststack",
231 "l2bd": "L2 Bridge Domain",
232 "crypto.ethip4": "IPSec IPv4 Routing",
233 "crypto.ethip6": "IPSec IPv6 Routing",
234 "interfaces": "Interfaces",
235 "ip4_tunnels.lisp": "IPv4 Tunnels LISP",
236 "ip6_tunnels.lisp": "IPv6 Tunnels LISP",
237 "l2patch": "L2 Patch",
238 "l2xc": "L2 Cross Connect",
239 "vm_vhost.ethip4": "VMs vhost-user IPv4 Routing",
240 "vm_vhost.ethip6": "VMs vhost-user IPv6 Routing"
245 "background-color": "#d2ebf5",
246 "border-color": "#bce1f1",
250 ############################################################################
251 # General, normalization constants.
253 NORM_FREQUENCY = 2.0 # [GHz]
254 FREQUENCY = { # [GHz]
272 ############################################################################
273 # General, plots and tables constants.
276 "#1A1110", "#DA2647", "#214FC6", "#01786F", "#BD8260", "#FFD12A",
277 "#A6E7FF", "#738276", "#C95A49", "#FC5A8D", "#CEC8EF", "#391285",
278 "#6F2DA8", "#FF878D", "#45A27D", "#FFD0B9", "#FD5240", "#DB91EF",
279 "#44D7A8", "#4F86F7", "#84DE02", "#FFCFF1", "#614051"
282 # Trending, anomalies.
298 TICK_TEXT_TPUT = ["Regression", "Normal", "Progression"]
309 TICK_TEXT_LAT = ["Progression", "Normal", "Regression"]
311 # Access to the results.
313 "mrr": "result_receive_rate_rate_avg",
314 "ndr": "result_ndr_lower_rate_value",
315 "pdr": "result_pdr_lower_rate_value",
316 "mrr-bandwidth": "result_receive_rate_bandwidth_avg",
317 "ndr-bandwidth": "result_ndr_lower_bandwidth_value",
318 "pdr-bandwidth": "result_pdr_lower_bandwidth_value",
319 "latency": "result_latency_forward_pdr_50_avg",
320 "hoststack-cps": "result_rate_value",
321 "hoststack-rps": "result_rate_value",
322 "hoststack-cps-bandwidth": "result_bandwidth_value",
323 "hoststack-rps-bandwidth": "result_bandwidth_value",
324 "hoststack-bps": "result_bandwidth_value",
325 "hoststack-latency": "result_latency_value",
326 "soak": "result_critical_rate_lower_rate_value",
327 "soak-bandwidth": "result_critical_rate_lower_bandwidth_value"
331 "mrr": "result_receive_rate_rate_values",
332 "ndr": "result_ndr_lower_rate_value",
333 "pdr": "result_pdr_lower_rate_value",
334 "mrr-bandwidth": "result_receive_rate_bandwidth_avg",
335 "ndr-bandwidth": "result_ndr_lower_bandwidth_value",
336 "pdr-bandwidth": "result_pdr_lower_bandwidth_value",
337 "latency": "result_latency_forward_pdr_50_avg",
338 "hoststack-cps": "result_rate_value",
339 "hoststack-rps": "result_rate_value",
340 "hoststack-cps-bandwidth": "result_bandwidth_value",
341 "hoststack-rps-bandwidth": "result_bandwidth_value",
342 "hoststack-bps": "result_bandwidth_value",
343 "hoststack-latency": "result_latency_value",
344 "soak": "result_critical_rate_lower_rate_value",
345 "soak-bandwidth": "result_critical_rate_lower_bandwidth_value"
349 "mrr": "result_receive_rate_rate_unit",
350 "ndr": "result_ndr_lower_rate_unit",
351 "pdr": "result_pdr_lower_rate_unit",
352 "mrr-bandwidth": "result_receive_rate_bandwidth_unit",
353 "ndr-bandwidth": "result_ndr_lower_bandwidth_unit",
354 "pdr-bandwidth": "result_pdr_lower_bandwidth_unit",
355 "latency": "result_latency_forward_pdr_50_unit",
356 "hoststack-cps": "result_rate_unit",
357 "hoststack-rps": "result_rate_unit",
358 "hoststack-cps-bandwidth": "result_bandwidth_unit",
359 "hoststack-rps-bandwidth": "result_bandwidth_unit",
360 "hoststack-bps": "result_bandwidth_unit",
361 "hoststack-latency": "result_latency_unit",
362 "soak": "result_critical_rate_lower_rate_unit",
363 "soak-bandwidth": "result_critical_rate_lower_bandwidth_unit"
366 TESTS_WITH_BANDWIDTH = (
374 TESTS_WITH_LATENCY = (
381 LAT_HDRH = ( # Do not change the order
382 "result_latency_forward_pdr_0_hdrh",
383 "result_latency_reverse_pdr_0_hdrh",
384 "result_latency_forward_pdr_10_hdrh",
385 "result_latency_reverse_pdr_10_hdrh",
386 "result_latency_forward_pdr_50_hdrh",
387 "result_latency_reverse_pdr_50_hdrh",
388 "result_latency_forward_pdr_90_hdrh",
389 "result_latency_reverse_pdr_90_hdrh",
392 # This value depends on latency stream rate (9001 pps) and duration (5s).
393 # Keep it slightly higher to ensure rounding errors to not remove tick mark.
394 PERCENTILE_MAX = 99.999501
396 GRAPH_LAT_HDRH_DESC = {
397 "result_latency_forward_pdr_0_hdrh": "No-load.",
398 "result_latency_reverse_pdr_0_hdrh": "No-load.",
399 "result_latency_forward_pdr_10_hdrh": "Low-load, 10% PDR.",
400 "result_latency_reverse_pdr_10_hdrh": "Low-load, 10% PDR.",
401 "result_latency_forward_pdr_50_hdrh": "Mid-load, 50% PDR.",
402 "result_latency_reverse_pdr_50_hdrh": "Mid-load, 50% PDR.",
403 "result_latency_forward_pdr_90_hdrh": "High-load, 90% PDR.",
404 "result_latency_reverse_pdr_90_hdrh": "High-load, 90% PDR."
407 # Operators used to filter data in comparison tables.
416 ("datestartswith ", )
419 ############################################################################
423 NEWS_TITLE = "Failures and Anomalies"
425 # The pathname prefix for the application.
426 NEWS_ROUTES_PATHNAME_PREFIX = "/news/"
428 # Time period for regressions and progressions.
429 NEWS_TIME_PERIOD = TIME_PERIOD # [days]
431 # Time periods for summary tables.
432 NEWS_LAST = 1 # [days]
433 NEWS_SHORT = 7 # [days]
434 NEWS_LONG = NEWS_TIME_PERIOD # [days]
436 ############################################################################
440 REPORT_TITLE = "Per Release Performance"
442 # The pathname prefix for the application.
443 REPORT_ROUTES_PATHNAME_PREFIX = "/report/"
445 # Layout of plot.ly graphs.
446 REPORT_GRAPH_LAYOUT_FILE = "cdash/report/layout.yaml"
448 # Default name of downloaded file with selected data.
449 REPORT_DOWNLOAD_FILE_NAME = "iterative_data.csv"
451 ############################################################################
455 COMP_TITLE = "Per Release Performance Comparisons"
457 # The pathname prefix for the application.
458 COMP_ROUTES_PATHNAME_PREFIX = "/comparisons/"
460 # Default name of downloaded file with selected data.
461 COMP_DOWNLOAD_FILE_NAME = "comparison_data.csv"
463 # This parameter specifies the method to use for estimating the percentile.
466 # - averaged_inverted_cdf
467 # - closest_observation
468 # - interpolated_inverted_cdf
474 COMP_PERCENTILE_METHOD = "linear"
476 # Extreme or mild outlier?
479 COMP_OUTLIER_TYPE = OUTLIER_EXTREME
481 ############################################################################
485 STATS_TITLE = "Test Job Statistics"
487 # The pathname prefix for the application.
488 STATS_ROUTES_PATHNAME_PREFIX = "/stats/"
490 # Layout of plot.ly graphs.
491 STATS_GRAPH_LAYOUT_FILE = "cdash/stats/layout.yaml"
493 # The default job displayed when the page is loaded first time.
494 STATS_DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx"
496 # Default name of downloaded file with selected data.
497 STATS_DOWNLOAD_FILE_NAME = "stats.csv"
499 # The width of the bar in the graph in miliseconds.
500 STATS_BAR_WIDTH_DAILY = 1000 * 3600 * 15
501 STATS_BAR_WIDTH_WEEKLY = 1000 * 3600 * 24
503 ############################################################################
507 TREND_TITLE = "Performance Trending"
509 # The pathname prefix for the application.
510 TREND_ROUTES_PATHNAME_PREFIX = "/trending/"
512 # Layout of plot.ly graphs.
513 TREND_GRAPH_LAYOUT_FILE = "cdash/trending/layout.yaml"
515 # Default name of downloaded file with selected data.
516 TREND_DOWNLOAD_FILE_NAME = "trending_data.csv"
517 TELEMETRY_DOWNLOAD_FILE_NAME = "telemetry_data.csv"
519 ############################################################################
523 COVERAGE_TITLE = "Per Release Coverage Data"
525 # The pathname prefix for the application.
526 COVERAGE_ROUTES_PATHNAME_PREFIX = "/coverage/"
528 # Default name of downloaded file with selected data.
529 COVERAGE_DOWNLOAD_FILE_NAME = "coverage_data.csv"
531 ############################################################################
535 SEARCH_TITLE = "Search Tests"
537 # The pathname prefix for the application.
538 SEARCH_ROUTES_PATHNAME_PREFIX = "/search/"
540 # Layout of plot.ly graphs.
541 SEARCH_GRAPH_LAYOUT_FILE = "cdash/search/layout.yaml"
543 # Default name of downloaded file with selected data.
544 SEARCH_DOWNLOAD_FILE_NAME = "search_data.csv"
546 ############################################################################
550 DOC_TITLE = "Documentation"
552 ############################################################################