Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: tools/testrunner/local/statusfile.py

Issue 2203013002: [test] Enable test status filtering by variant (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added tests Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2012 the V8 project authors. All rights reserved. 1 # Copyright 2012 the V8 project authors. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without 2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are 3 # modification, are permitted provided that the following conditions are
4 # met: 4 # met:
5 # 5 #
6 # * Redistributions of source code must retain the above copyright 6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer. 7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above 8 # * Redistributions in binary form must reproduce the above
9 # copyright notice, this list of conditions and the following 9 # copyright notice, this list of conditions and the following
10 # disclaimer in the documentation and/or other materials provided 10 # disclaimer in the documentation and/or other materials provided
11 # with the distribution. 11 # with the distribution.
12 # * Neither the name of Google Inc. nor the names of its 12 # * Neither the name of Google Inc. nor the names of its
13 # contributors may be used to endorse or promote products derived 13 # contributors may be used to endorse or promote products derived
14 # from this software without specific prior written permission. 14 # from this software without specific prior written permission.
15 # 15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 import os 28 import os
29 import re
30
31 from variants import ALL_VARIANTS
29 32
30 # These outcomes can occur in a TestCase's outcomes list: 33 # These outcomes can occur in a TestCase's outcomes list:
31 SKIP = "SKIP" 34 SKIP = "SKIP"
32 FAIL = "FAIL" 35 FAIL = "FAIL"
33 PASS = "PASS" 36 PASS = "PASS"
34 OKAY = "OKAY" 37 OKAY = "OKAY"
35 TIMEOUT = "TIMEOUT" 38 TIMEOUT = "TIMEOUT"
36 CRASH = "CRASH" 39 CRASH = "CRASH"
37 SLOW = "SLOW" 40 SLOW = "SLOW"
38 FAST_VARIANTS = "FAST_VARIANTS" 41 FAST_VARIANTS = "FAST_VARIANTS"
(...skipping 17 matching lines...) Expand all
56 59
57 # Support arches, modes to be written as keywords instead of strings. 60 # Support arches, modes to be written as keywords instead of strings.
58 VARIABLES = {ALWAYS: True} 61 VARIABLES = {ALWAYS: True}
59 for var in ["debug", "release", "big", "little", 62 for var in ["debug", "release", "big", "little",
60 "android_arm", "android_arm64", "android_ia32", "android_x87", 63 "android_arm", "android_arm64", "android_ia32", "android_x87",
61 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64", 64 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64",
62 "mips64el", "x64", "x87", "ppc", "ppc64", "s390", "s390x", "macos", 65 "mips64el", "x64", "x87", "ppc", "ppc64", "s390", "s390x", "macos",
63 "windows", "linux", "aix"]: 66 "windows", "linux", "aix"]:
64 VARIABLES[var] = var 67 VARIABLES[var] = var
65 68
69 # Allow using variants as keywords.
70 for var in ALL_VARIANTS:
71 VARIABLES[var] = var
72
66 73
67 def DoSkip(outcomes): 74 def DoSkip(outcomes):
68 return SKIP in outcomes 75 return SKIP in outcomes
69 76
70 77
71 def IsSlow(outcomes): 78 def IsSlow(outcomes):
72 return SLOW in outcomes 79 return SLOW in outcomes
73 80
74 81
75 def NoIgnitionVariant(outcomes): 82 def NoIgnitionVariant(outcomes):
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 def _JoinsPassAndFail(outcomes1, outcomes2): 116 def _JoinsPassAndFail(outcomes1, outcomes2):
110 """Indicates if we join PASS and FAIL from two different outcome sets and 117 """Indicates if we join PASS and FAIL from two different outcome sets and
111 the first doesn't already contain both. 118 the first doesn't already contain both.
112 """ 119 """
113 return ( 120 return (
114 PASS in outcomes1 and 121 PASS in outcomes1 and
115 not FAIL in outcomes1 and 122 not FAIL in outcomes1 and
116 FAIL in outcomes2 123 FAIL in outcomes2
117 ) 124 )
118 125
126 VARIANT_EXPRESSION = object()
127
128 def _EvalExpression(exp, variables):
129 try:
130 return eval(exp, variables)
131 except NameError as e:
132 identifier = re.match("name '(.*)' is not defined", e.message).group(1)
133 assert identifier == "variant", "Unknown identifier: %s" % identifier
134 return VARIANT_EXPRESSION
135
136
137 def _EvalVariantExpression(section, rules, wildcards, variant, variables):
138 variables_with_variant = {}
139 variables_with_variant.update(variables)
140 variables_with_variant["variant"] = variant
141 result = _EvalExpression(section[0], variables_with_variant)
142 assert result != VARIANT_EXPRESSION
143 if result is True:
144 _ReadSection(
145 section[1],
146 rules[variant],
147 wildcards[variant],
148 variables_with_variant,
149 )
150 else:
151 assert result is False, "Make sure expressions evaluate to boolean values"
152
153
119 def _ParseOutcomeList(rule, outcomes, target_dict, variables): 154 def _ParseOutcomeList(rule, outcomes, target_dict, variables):
120 result = set([]) 155 result = set([])
121 if type(outcomes) == str: 156 if type(outcomes) == str:
122 outcomes = [outcomes] 157 outcomes = [outcomes]
123 for item in outcomes: 158 for item in outcomes:
124 if type(item) == str: 159 if type(item) == str:
125 _AddOutcome(result, item) 160 _AddOutcome(result, item)
126 elif type(item) == list: 161 elif type(item) == list:
127 if not eval(item[0], variables): continue 162 exp = _EvalExpression(item[0], variables)
163 assert exp != VARIANT_EXPRESSION, (
164 "Nested variant expressions are not supported")
165 if exp is False:
166 continue
167
168 # Ensure nobody uses an identifier by mistake, like "default",
169 # which would evaluate to true here otherwise.
170 assert exp is True, "Make sure expressions evaluate to boolean values"
171
128 for outcome in item[1:]: 172 for outcome in item[1:]:
129 assert type(outcome) == str 173 assert type(outcome) == str
130 _AddOutcome(result, outcome) 174 _AddOutcome(result, outcome)
131 else: 175 else:
132 assert False 176 assert False
133 if len(result) == 0: return 177 if len(result) == 0: return
134 if rule in target_dict: 178 if rule in target_dict:
135 # A FAIL without PASS in one rule has always precedence over a single 179 # A FAIL without PASS in one rule has always precedence over a single
136 # PASS (without FAIL) in another. Otherwise the default PASS expectation 180 # PASS (without FAIL) in another. Otherwise the default PASS expectation
137 # in a rule with a modifier (e.g. PASS, SLOW) would be joined to a FAIL 181 # in a rule with a modifier (e.g. PASS, SLOW) would be joined to a FAIL
138 # from another rule (which intended to mark a test as FAIL and not as 182 # from another rule (which intended to mark a test as FAIL and not as
139 # PASS and FAIL). 183 # PASS and FAIL).
140 if _JoinsPassAndFail(target_dict[rule], result): 184 if _JoinsPassAndFail(target_dict[rule], result):
141 target_dict[rule] -= set([PASS]) 185 target_dict[rule] -= set([PASS])
142 if _JoinsPassAndFail(result, target_dict[rule]): 186 if _JoinsPassAndFail(result, target_dict[rule]):
143 result -= set([PASS]) 187 result -= set([PASS])
144 target_dict[rule] |= result 188 target_dict[rule] |= result
145 else: 189 else:
146 target_dict[rule] = result 190 target_dict[rule] = result
147 191
148 192
149 def ReadContent(path): 193 def ReadContent(content):
150 with open(path) as f: 194 global KEYWORDS
151 global KEYWORDS 195 return eval(content, KEYWORDS)
152 return eval(f.read(), KEYWORDS)
153 196
154 197
155 def ReadStatusFile(path, variables): 198 def ReadStatusFile(content, variables):
156 contents = ReadContent(path) 199 # Empty defaults for rules and wildcards. Variant-independent
200 # rules are mapped by "", others by the variant name.
201 rules = {variant: {} for variant in ALL_VARIANTS}
202 rules[""] = {}
203 wildcards = {variant: {} for variant in ALL_VARIANTS}
204 wildcards[""] = {}
157 205
158 rules = {}
159 wildcards = {}
160 variables.update(VARIABLES) 206 variables.update(VARIABLES)
161 for section in contents: 207 for section in ReadContent(content):
162 assert type(section) == list 208 assert type(section) == list
163 assert len(section) == 2 209 assert len(section) == 2
164 if not eval(section[0], variables): continue 210 exp = _EvalExpression(section[0], variables)
165 section = section[1] 211 if exp is False:
166 assert type(section) == dict 212 # The expression is variant-independent and evaluates to False.
167 for rule in section: 213 continue
168 assert type(rule) == str 214 elif exp == VARIANT_EXPRESSION:
169 if rule[-1] == '*': 215 # If the expression contains one or more "variant" keywords, we evaluate
170 _ParseOutcomeList(rule, section[rule], wildcards, variables) 216 # it for all possible variants and create rules for those that apply.
171 else: 217 for variant in ALL_VARIANTS:
172 _ParseOutcomeList(rule, section[rule], rules, variables) 218 _EvalVariantExpression(section, rules, wildcards, variant, variables)
219 else:
220 # The expression is variant-independent and evaluates to True.
221 assert exp is True, "Make sure expressions evaluate to boolean values"
222 _ReadSection(
223 section[1],
224 rules[""],
225 wildcards[""],
226 variables,
227 )
173 return rules, wildcards 228 return rules, wildcards
174 229
175 230
231 def _ReadSection(section, rules, wildcards, variables):
232 assert type(section) == dict
233 for rule in section:
234 assert type(rule) == str
235 if rule[-1] == '*':
236 _ParseOutcomeList(rule, section[rule], wildcards, variables)
237 else:
238 _ParseOutcomeList(rule, section[rule], rules, variables)
239
240
176 def PresubmitCheck(path): 241 def PresubmitCheck(path):
177 contents = ReadContent(path) 242 with open(path) as f:
243 contents = ReadContent(f.read())
178 root_prefix = os.path.basename(os.path.dirname(path)) + "/" 244 root_prefix = os.path.basename(os.path.dirname(path)) + "/"
179 status = {"success": True} 245 status = {"success": True}
180 def _assert(check, message): # Like "assert", but doesn't throw. 246 def _assert(check, message): # Like "assert", but doesn't throw.
181 if not check: 247 if not check:
182 print("%s: Error: %s" % (path, message)) 248 print("%s: Error: %s" % (path, message))
183 status["success"] = False 249 status["success"] = False
184 try: 250 try:
185 for section in contents: 251 for section in contents:
186 _assert(type(section) == list, "Section must be a list") 252 _assert(type(section) == list, "Section must be a list")
187 _assert(len(section) == 2, "Section list must have exactly 2 entries") 253 _assert(len(section) == 2, "Section list must have exactly 2 entries")
188 section = section[1] 254 section = section[1]
189 _assert(type(section) == dict, 255 _assert(type(section) == dict,
190 "Second entry of section must be a dictionary") 256 "Second entry of section must be a dictionary")
191 for rule in section: 257 for rule in section:
192 _assert(type(rule) == str, "Rule key must be a string") 258 _assert(type(rule) == str, "Rule key must be a string")
193 _assert(not rule.startswith(root_prefix), 259 _assert(not rule.startswith(root_prefix),
194 "Suite name prefix must not be used in rule keys") 260 "Suite name prefix must not be used in rule keys")
195 _assert(not rule.endswith('.js'), 261 _assert(not rule.endswith('.js'),
196 ".js extension must not be used in rule keys.") 262 ".js extension must not be used in rule keys.")
197 return status["success"] 263 return status["success"]
198 except Exception as e: 264 except Exception as e:
199 print e 265 print e
200 return False 266 return False
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698