feat(topology): Enable 2 QATs
[csit.git] / csit.infra.dash / app / cdash / utils / constants.py
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:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
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.
13
14 """Constants used in CDash.
15
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.
18 """
19
20 import os
21 import logging
22
23 from dash import html
24
25
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.
28
29     The environment variable must start with perfix  "CSIT_".
30
31     If environment variable exists, but is empty (and default is not),
32     empty string is returned.
33
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.
39     :rtype: str
40     """
41     prefix = "CSIT_"
42     env_str = os.environ.get(prefix + env_var_name, None)
43     if env_str is not None:
44         return env_str
45     return default_value
46
47
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.
50
51     The environment variable must start with perfix  "CSIT_".
52
53     String value is read, default is returned also if conversion fails.
54
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.
60     :rtype: int
61     """
62     try:
63         return int(get_str_from_env(env_var_name, str()))
64     except ValueError:
65         return default_value
66
67
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.
70
71     The environment variable must start with perfix  "CSIT_".
72
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.
78     :rtype: bool
79     """
80     env_str = get_str_from_env(env_var_name, str()).lower()
81     if env_str in ("true", "yes", "y", "1"):
82         return True
83     elif env_str in ("false", "no", "n", "0"):
84         return False
85     else:
86         return default_value
87
88
89 class Constants:
90     """Constants used in CDash.
91     """
92
93     ############################################################################
94     # General, application wide constants.
95
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)
105
106     # Logging settings.
107     LOG_LEVEL = logging.INFO
108     LOG_FORMAT = "%(asctime)s: %(levelname)s: %(message)s"
109     LOG_DATE_FORMAT = "%Y/%m/%d %H:%M:%S"
110
111     # The application title.
112     TITLE = get_str_from_env("TITLE", "FD.io CSIT")
113     BRAND = get_str_from_env("BRAND", "CSIT-Dash")
114
115     # The application description.
116     DESCRIPTION = "Performance Dashboard"
117
118     # External stylesheets.
119     EXTERNAL_STYLESHEETS = ["/static/dist/css/bootstrap.css", ]
120
121     # URL to Jenkins
122     URL_CICD = get_str_from_env("URL_CICD", "https://jenkins.fd.io/job/")
123
124     # URL to logs
125     URL_LOGS = get_str_from_env(
126         "URL_LOGS", "https://logs.fd.io/vex-yul-rot-jenkins-1/"
127     )
128
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/"
133
134     # Path and name of the file specifying the HTML layout of the dash
135     # application.
136     MAIN_HTML_LAYOUT_FILE = "base_layout.jinja2"
137
138     # Path and name of the file specifying the HTML layout of the dash
139     # application.
140     HTML_LAYOUT_FILE = "cdash/templates/dash_layout.jinja2"
141
142     # Application root.
143     APPLICATIN_ROOT = "/"
144
145     # Data to be downloaded from the parquets specification file.
146     DATA_SPEC_FILE = "cdash/data/data.yaml"
147
148     # Path to schemas to use when reading data from the parquet.
149     PATH_TO_SCHEMAS = "cdash/data/_metadata/"
150
151     # The file with tooltips.
152     TOOLTIP_FILE = "cdash/utils/tooltips.yaml"
153
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
157
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]
163
164     ############################################################################
165     # General, application wide, layout affecting constants.
166
167     # Add a time delay (in ms) to the spinner being shown
168     SPINNER_DELAY = 500
169
170     # If True, clear all inputs in control panel when button "ADD SELECTED" is
171     # pressed.
172     CLEAR_ALL_INPUTS = False
173
174     # The element is disabled.
175     STYLE_DISABLED = {"visibility": "hidden"}
176
177     # The element is enabled and visible.
178     STYLE_ENABLED = {"visibility": "visible"}
179
180     # The element is not displayed.
181     STYLE_DONT_DISPLAY = {"display": "none"}
182
183     # The element is displaed.
184     STYLE_DISPLAY = {"display": "flex"}
185
186     # Checklist "All" is disabled.
187     CL_ALL_DISABLED = [
188         {
189             "label": "All",
190             "value": "all",
191             "disabled": True
192         }
193     ]
194
195     # Checklist "All" is enabled, visible and unchecked.
196     CL_ALL_ENABLED = [
197         {
198             "label": "All",
199             "value": "all",
200             "disabled": False
201         }
202     ]
203
204     # Placeholder for any element in the layout.
205     PLACEHOLDER = html.Nobr("")
206
207     # List of drivers used in CSIT.
208     DRIVERS = ("avf", "af-xdp", "rdma", "dpdk", "mlx5")
209
210     # Labels for input elements (dropdowns, ...).
211     LABELS = {
212         "dpdk": "DPDK",
213         "container_memif": "LXC/DRC Container Memif",
214         "crypto": "IPSec IPv4 Routing",
215         "gso": "GSO",
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",
230         "flow": "Flow",
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"
241     }
242
243     # URL style.
244     URL_STYLE = {
245         "background-color": "#d2ebf5",
246         "border-color": "#bce1f1",
247         "color": "#135d7c"
248     }
249
250     ############################################################################
251     # General, normalization constants.
252
253     NORM_FREQUENCY = 2.0  # [GHz]
254     FREQUENCY = {  # [GHz]
255         "1n-aws": 3.400,
256         "2n-aws": 3.400,
257         "2n-c6in": 3.500,
258         "2n-clx": 2.300,
259         "2n-icx": 2.600,
260         "2n-spr": 2.800,
261         "2n-tx2": 2.500,
262         "2n-zn2": 2.900,
263         "3n-alt": 3.000,
264         "3n-icx": 2.600,
265         "3n-icxd": 2.000,
266         "3n-snr": 2.200,
267         "3n-tsh": 2.200,
268         "3na-spr": 2.800,
269         "3nb-spr": 2.800
270     }
271
272     ############################################################################
273     # General, plots and tables constants.
274
275     PLOT_COLORS = (
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"
280     )
281
282     # Trending, anomalies.
283     ANOMALY_COLOR = {
284         "regression": 0.0,
285         "normal": 0.5,
286         "progression": 1.0
287     }
288
289     COLORSCALE_TPUT = [
290         [0.00, "red"],
291         [0.33, "red"],
292         [0.33, "white"],
293         [0.66, "white"],
294         [0.66, "green"],
295         [1.00, "green"]
296     ]
297
298     TICK_TEXT_TPUT = ["Regression", "Normal", "Progression"]
299
300     COLORSCALE_LAT = [
301         [0.00, "green"],
302         [0.33, "green"],
303         [0.33, "white"],
304         [0.66, "white"],
305         [0.66, "red"],
306         [1.00, "red"]
307     ]
308
309     TICK_TEXT_LAT = ["Progression", "Normal", "Regression"]
310
311     # Access to the results.
312     VALUE = {
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"
328     }
329
330     VALUE_ITER = {
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"
346     }
347
348     UNIT = {
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"
364     }
365
366     TESTS_WITH_BANDWIDTH = (
367         "ndr",
368         "pdr",
369         "mrr",
370         "hoststack-cps",
371         "hoststack-rps",
372         "soak"
373     )
374     TESTS_WITH_LATENCY = (
375         "pdr",
376         "hoststack-cps",
377         "hoststack-rps"
378     )
379
380     # Latencies.
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",
390     )
391
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
395
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."
405     }
406
407     # Operators used to filter data in comparison tables.
408     OPERATORS = (
409         ("contains ", ),
410         ("lt ", "<"),
411         ("gt ", ">"),
412         ("eq ", "="),
413         ("ge ", ">="),
414         ("le ", "<="),
415         ("ne ", "!="),
416         ("datestartswith ", )
417     )
418
419     ############################################################################
420     # News.
421
422     # The title.
423     NEWS_TITLE = "Failures and Anomalies"
424
425     # The pathname prefix for the application.
426     NEWS_ROUTES_PATHNAME_PREFIX = "/news/"
427
428     # Time period for regressions and progressions.
429     NEWS_TIME_PERIOD = TIME_PERIOD  # [days]
430
431     # Time periods for summary tables.
432     NEWS_LAST = 1  # [days]
433     NEWS_SHORT = 7  # [days]
434     NEWS_LONG = NEWS_TIME_PERIOD  # [days]
435
436     ############################################################################
437     # Report.
438
439     # The title.
440     REPORT_TITLE = "Per Release Performance"
441
442     # The pathname prefix for the application.
443     REPORT_ROUTES_PATHNAME_PREFIX = "/report/"
444
445     # Layout of plot.ly graphs.
446     REPORT_GRAPH_LAYOUT_FILE = "cdash/report/layout.yaml"
447
448     # Default name of downloaded file with selected data.
449     REPORT_DOWNLOAD_FILE_NAME = "iterative_data.csv"
450
451     ############################################################################
452     # Comparisons.
453
454     # The title.
455     COMP_TITLE = "Per Release Performance Comparisons"
456
457     # The pathname prefix for the application.
458     COMP_ROUTES_PATHNAME_PREFIX = "/comparisons/"
459
460     # Default name of downloaded file with selected data.
461     COMP_DOWNLOAD_FILE_NAME = "comparison_data.csv"
462
463     # This parameter specifies the method to use for estimating the percentile.
464     # Possible values:
465     # - inverted_cdf
466     # - averaged_inverted_cdf
467     # - closest_observation
468     # - interpolated_inverted_cdf
469     # - hazen
470     # - weibull
471     # - linear (default)
472     # - median_unbiased
473     # - normal_unbiased
474     COMP_PERCENTILE_METHOD = "linear"
475
476     # Extreme or mild outlier?
477     OUTLIER_EXTREME = 3
478     OUTLIER_MILD = 1.5
479     COMP_OUTLIER_TYPE = OUTLIER_EXTREME
480
481     ############################################################################
482     # Statistics.
483
484     # The title.
485     STATS_TITLE = "Test Job Statistics"
486
487     # The pathname prefix for the application.
488     STATS_ROUTES_PATHNAME_PREFIX = "/stats/"
489
490     # Layout of plot.ly graphs.
491     STATS_GRAPH_LAYOUT_FILE = "cdash/stats/layout.yaml"
492
493     # The default job displayed when the page is loaded first time.
494     STATS_DEFAULT_JOB = "csit-vpp-perf-mrr-daily-master-2n-icx"
495
496     # Default name of downloaded file with selected data.
497     STATS_DOWNLOAD_FILE_NAME = "stats.csv"
498
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
502
503     ############################################################################
504     # Trending.
505
506     # The title.
507     TREND_TITLE = "Performance Trending"
508
509     # The pathname prefix for the application.
510     TREND_ROUTES_PATHNAME_PREFIX = "/trending/"
511
512     # Layout of plot.ly graphs.
513     TREND_GRAPH_LAYOUT_FILE = "cdash/trending/layout.yaml"
514
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"
518
519     ############################################################################
520     # Coverage data.
521
522     # The title.
523     COVERAGE_TITLE = "Per Release Coverage Data"
524
525     # The pathname prefix for the application.
526     COVERAGE_ROUTES_PATHNAME_PREFIX = "/coverage/"
527
528     # Default name of downloaded file with selected data.
529     COVERAGE_DOWNLOAD_FILE_NAME = "coverage_data.csv"
530
531     ############################################################################
532     # Search tests.
533
534     # The title.
535     SEARCH_TITLE = "Search Tests"
536
537     # The pathname prefix for the application.
538     SEARCH_ROUTES_PATHNAME_PREFIX = "/search/"
539
540     # Layout of plot.ly graphs.
541     SEARCH_GRAPH_LAYOUT_FILE = "cdash/search/layout.yaml"
542
543     # Default name of downloaded file with selected data.
544     SEARCH_DOWNLOAD_FILE_NAME = "search_data.csv"
545
546     ############################################################################
547     # Documentation.
548
549     # The title.
550     DOC_TITLE = "Documentation"
551
552     ############################################################################