1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 # This file contains utility functions shared by the scalars and the histogram generation
14 # This is a list of flags that determine which process a measurement is allowed
16 KNOWN_PROCESS_FLAGS
= {
18 "all_children": "AllChildren",
26 "all_childs": "AllChildren", # Supporting files from before bug 1363725
29 SUPPORTED_PRODUCTS
= {
32 "thunderbird": "Thunderbird",
33 # Historical, deprecated values:
34 # 'geckoview': 'Geckoview',
35 # "geckoview_streaming": "GeckoviewStreaming",
38 SUPPORTED_OPERATING_SYSTEMS
= [
47 # mozinfo identifies linux, BSD variants, Solaris and SunOS as unix
48 # Solaris and SunOS are identified as "unix" OS.
55 CANONICAL_OPERATING_SYSTEMS
= {
60 # for simplicity we treat all BSD and Solaris systems as unix
61 "gnu/kfreebsd": "unix",
69 PROCESS_ENUM_PREFIX
= "mozilla::Telemetry::Common::RecordedProcessType::"
70 PRODUCT_ENUM_PREFIX
= "mozilla::Telemetry::Common::SupportedProduct::"
73 class ParserError(Exception):
74 """Thrown by different probe parsers. Errors are partitioned into
75 'immediately fatal' and 'eventually fatal' so that the parser can print
76 multiple error messages at a time. See bug 1401612 ."""
80 def __init__(self
, *args
):
81 Exception.__init
__(self
, *args
)
83 def handle_later(self
):
84 ParserError
.eventual_errors
.append(self
)
87 ParserError
.print_eventuals()
88 print(str(self
), file=sys
.stderr
)
93 def print_eventuals(cls
):
94 while cls
.eventual_errors
:
95 print(str(cls
.eventual_errors
.pop(0)), file=sys
.stderr
)
99 if cls
.eventual_errors
:
100 cls("Some errors occurred").handle_now()
103 def is_valid_process_name(name
):
104 return name
in KNOWN_PROCESS_FLAGS
107 def process_name_to_enum(name
):
108 return PROCESS_ENUM_PREFIX
+ KNOWN_PROCESS_FLAGS
.get(name
)
111 def is_valid_product(name
):
112 return name
in SUPPORTED_PRODUCTS
115 def is_valid_os(name
):
116 return name
in SUPPORTED_OPERATING_SYSTEMS
119 def canonical_os(os
):
120 """Translate possible OS_TARGET names to their canonical value."""
122 return CANONICAL_OPERATING_SYSTEMS
.get(os
.lower()) or "unknown"
125 def product_name_to_enum(product
):
126 if not is_valid_product(product
):
127 raise ParserError("Invalid product {}".format(product
))
128 return PRODUCT_ENUM_PREFIX
+ SUPPORTED_PRODUCTS
.get(product
)
131 def static_assert(output
, expression
, message
):
132 """Writes a C++ compile-time assertion expression to a file.
133 :param output: the output stream.
134 :param expression: the expression to check.
135 :param message: the string literal that will appear if the expression evaluates to
138 print('static_assert(%s, "%s");' % (expression
, message
), file=output
)
141 def validate_expiration_version(expiration
):
142 """Makes sure the expiration version has the expected format.
144 Allowed examples: "10", "20", "60", "never"
145 Disallowed examples: "Never", "asd", "4000000", "60a1", "30.5a1"
147 :param expiration: the expiration version string.
148 :return: True if the expiration validates correctly, False otherwise.
150 if expiration
!= "never" and not re
.match(r
"^\d{1,3}$", expiration
):
156 def add_expiration_postfix(expiration
):
157 """Formats the expiration version and adds a version postfix if needed.
159 :param expiration: the expiration version string.
160 :return: the modified expiration string.
162 if re
.match(r
"^[1-9][0-9]*$", expiration
):
163 return expiration
+ ".0a1"
165 if re
.match(r
"^[1-9][0-9]*\.0$", expiration
):
166 return expiration
+ "a1"
171 def load_yaml_file(filename
):
172 """Load a YAML file from disk, throw a ParserError on failure."""
174 with
open(filename
, "r") as f
:
175 return yaml
.safe_load(f
)
177 raise ParserError("Error opening " + filename
+ ": " + str(e
))
178 except ValueError as e
:
179 raise ParserError("Error parsing processes in {}: {}".format(filename
, e
))