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

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: Nits 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
« no previous file with comments | « tools/run-tests.py ('k') | tools/testrunner/local/statusfile_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
32 from utils import Freeze
29 33
30 # These outcomes can occur in a TestCase's outcomes list: 34 # These outcomes can occur in a TestCase's outcomes list:
31 SKIP = "SKIP" 35 SKIP = "SKIP"
32 FAIL = "FAIL" 36 FAIL = "FAIL"
33 PASS = "PASS" 37 PASS = "PASS"
34 OKAY = "OKAY" 38 OKAY = "OKAY"
35 TIMEOUT = "TIMEOUT" 39 TIMEOUT = "TIMEOUT"
36 CRASH = "CRASH" 40 CRASH = "CRASH"
37 SLOW = "SLOW" 41 SLOW = "SLOW"
38 FAST_VARIANTS = "FAST_VARIANTS" 42 FAST_VARIANTS = "FAST_VARIANTS"
(...skipping 17 matching lines...) Expand all
56 60
57 # Support arches, modes to be written as keywords instead of strings. 61 # Support arches, modes to be written as keywords instead of strings.
58 VARIABLES = {ALWAYS: True} 62 VARIABLES = {ALWAYS: True}
59 for var in ["debug", "release", "big", "little", 63 for var in ["debug", "release", "big", "little",
60 "android_arm", "android_arm64", "android_ia32", "android_x87", 64 "android_arm", "android_arm64", "android_ia32", "android_x87",
61 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64", 65 "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64",
62 "mips64el", "x64", "x87", "ppc", "ppc64", "s390", "s390x", "macos", 66 "mips64el", "x64", "x87", "ppc", "ppc64", "s390", "s390x", "macos",
63 "windows", "linux", "aix"]: 67 "windows", "linux", "aix"]:
64 VARIABLES[var] = var 68 VARIABLES[var] = var
65 69
70 # Allow using variants as keywords.
71 for var in ALL_VARIANTS:
72 VARIABLES[var] = var
73
66 74
67 def DoSkip(outcomes): 75 def DoSkip(outcomes):
68 return SKIP in outcomes 76 return SKIP in outcomes
69 77
70 78
71 def IsSlow(outcomes): 79 def IsSlow(outcomes):
72 return SLOW in outcomes 80 return SLOW in outcomes
73 81
74 82
75 def NoIgnitionVariant(outcomes): 83 def NoIgnitionVariant(outcomes):
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 def _JoinsPassAndFail(outcomes1, outcomes2): 117 def _JoinsPassAndFail(outcomes1, outcomes2):
110 """Indicates if we join PASS and FAIL from two different outcome sets and 118 """Indicates if we join PASS and FAIL from two different outcome sets and
111 the first doesn't already contain both. 119 the first doesn't already contain both.
112 """ 120 """
113 return ( 121 return (
114 PASS in outcomes1 and 122 PASS in outcomes1 and
115 not FAIL in outcomes1 and 123 not FAIL in outcomes1 and
116 FAIL in outcomes2 124 FAIL in outcomes2
117 ) 125 )
118 126
127 VARIANT_EXPRESSION = object()
128
129 def _EvalExpression(exp, variables):
130 try:
131 return eval(exp, variables)
132 except NameError as e:
133 identifier = re.match("name '(.*)' is not defined", e.message).group(1)
134 assert identifier == "variant", "Unknown identifier: %s" % identifier
135 return VARIANT_EXPRESSION
136
137
138 def _EvalVariantExpression(section, rules, wildcards, variant, variables):
139 variables_with_variant = {}
140 variables_with_variant.update(variables)
141 variables_with_variant["variant"] = variant
142 result = _EvalExpression(section[0], variables_with_variant)
143 assert result != VARIANT_EXPRESSION
144 if result is True:
145 _ReadSection(
146 section[1],
147 rules[variant],
148 wildcards[variant],
149 variables_with_variant,
150 )
151 else:
152 assert result is False, "Make sure expressions evaluate to boolean values"
153
154
119 def _ParseOutcomeList(rule, outcomes, target_dict, variables): 155 def _ParseOutcomeList(rule, outcomes, target_dict, variables):
120 result = set([]) 156 result = set([])
121 if type(outcomes) == str: 157 if type(outcomes) == str:
122 outcomes = [outcomes] 158 outcomes = [outcomes]
123 for item in outcomes: 159 for item in outcomes:
124 if type(item) == str: 160 if type(item) == str:
125 _AddOutcome(result, item) 161 _AddOutcome(result, item)
126 elif type(item) == list: 162 elif type(item) == list:
127 if not eval(item[0], variables): continue 163 exp = _EvalExpression(item[0], variables)
164 assert exp != VARIANT_EXPRESSION, (
165 "Nested variant expressions are not supported")
166 if exp is False:
167 continue
168
169 # Ensure nobody uses an identifier by mistake, like "default",
170 # which would evaluate to true here otherwise.
171 assert exp is True, "Make sure expressions evaluate to boolean values"
172
128 for outcome in item[1:]: 173 for outcome in item[1:]:
129 assert type(outcome) == str 174 assert type(outcome) == str
130 _AddOutcome(result, outcome) 175 _AddOutcome(result, outcome)
131 else: 176 else:
132 assert False 177 assert False
133 if len(result) == 0: return 178 if len(result) == 0: return
134 if rule in target_dict: 179 if rule in target_dict:
135 # A FAIL without PASS in one rule has always precedence over a single 180 # A FAIL without PASS in one rule has always precedence over a single
136 # PASS (without FAIL) in another. Otherwise the default PASS expectation 181 # 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 182 # 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 183 # from another rule (which intended to mark a test as FAIL and not as
139 # PASS and FAIL). 184 # PASS and FAIL).
140 if _JoinsPassAndFail(target_dict[rule], result): 185 if _JoinsPassAndFail(target_dict[rule], result):
141 target_dict[rule] -= set([PASS]) 186 target_dict[rule] -= set([PASS])
142 if _JoinsPassAndFail(result, target_dict[rule]): 187 if _JoinsPassAndFail(result, target_dict[rule]):
143 result -= set([PASS]) 188 result -= set([PASS])
144 target_dict[rule] |= result 189 target_dict[rule] |= result
145 else: 190 else:
146 target_dict[rule] = result 191 target_dict[rule] = result
147 192
148 193
149 def ReadContent(path): 194 def ReadContent(content):
150 with open(path) as f: 195 global KEYWORDS
151 global KEYWORDS 196 return eval(content, KEYWORDS)
152 return eval(f.read(), KEYWORDS)
153 197
154 198
155 def ReadStatusFile(path, variables): 199 def ReadStatusFile(content, variables):
156 contents = ReadContent(path) 200 # Empty defaults for rules and wildcards. Variant-independent
201 # rules are mapped by "", others by the variant name.
202 rules = {variant: {} for variant in ALL_VARIANTS}
203 rules[""] = {}
204 wildcards = {variant: {} for variant in ALL_VARIANTS}
205 wildcards[""] = {}
157 206
158 rules = {}
159 wildcards = {}
160 variables.update(VARIABLES) 207 variables.update(VARIABLES)
161 for section in contents: 208 for section in ReadContent(content):
162 assert type(section) == list 209 assert type(section) == list
163 assert len(section) == 2 210 assert len(section) == 2
164 if not eval(section[0], variables): continue 211 exp = _EvalExpression(section[0], variables)
165 section = section[1] 212 if exp is False:
166 assert type(section) == dict 213 # The expression is variant-independent and evaluates to False.
167 for rule in section: 214 continue
168 assert type(rule) == str 215 elif exp == VARIANT_EXPRESSION:
169 if rule[-1] == '*': 216 # If the expression contains one or more "variant" keywords, we evaluate
170 _ParseOutcomeList(rule, section[rule], wildcards, variables) 217 # it for all possible variants and create rules for those that apply.
171 else: 218 for variant in ALL_VARIANTS:
172 _ParseOutcomeList(rule, section[rule], rules, variables) 219 _EvalVariantExpression(section, rules, wildcards, variant, variables)
173 return rules, wildcards 220 else:
221 # The expression is variant-independent and evaluates to True.
222 assert exp is True, "Make sure expressions evaluate to boolean values"
223 _ReadSection(
224 section[1],
225 rules[""],
226 wildcards[""],
227 variables,
228 )
229 return Freeze(rules), Freeze(wildcards)
230
231
232 def _ReadSection(section, rules, wildcards, variables):
233 assert type(section) == dict
234 for rule in section:
235 assert type(rule) == str
236 if rule[-1] == '*':
237 _ParseOutcomeList(rule, section[rule], wildcards, variables)
238 else:
239 _ParseOutcomeList(rule, section[rule], rules, variables)
174 240
175 241
176 def PresubmitCheck(path): 242 def PresubmitCheck(path):
177 contents = ReadContent(path) 243 with open(path) as f:
244 contents = ReadContent(f.read())
178 root_prefix = os.path.basename(os.path.dirname(path)) + "/" 245 root_prefix = os.path.basename(os.path.dirname(path)) + "/"
179 status = {"success": True} 246 status = {"success": True}
180 def _assert(check, message): # Like "assert", but doesn't throw. 247 def _assert(check, message): # Like "assert", but doesn't throw.
181 if not check: 248 if not check:
182 print("%s: Error: %s" % (path, message)) 249 print("%s: Error: %s" % (path, message))
183 status["success"] = False 250 status["success"] = False
184 try: 251 try:
185 for section in contents: 252 for section in contents:
186 _assert(type(section) == list, "Section must be a list") 253 _assert(type(section) == list, "Section must be a list")
187 _assert(len(section) == 2, "Section list must have exactly 2 entries") 254 _assert(len(section) == 2, "Section list must have exactly 2 entries")
188 section = section[1] 255 section = section[1]
189 _assert(type(section) == dict, 256 _assert(type(section) == dict,
190 "Second entry of section must be a dictionary") 257 "Second entry of section must be a dictionary")
191 for rule in section: 258 for rule in section:
192 _assert(type(rule) == str, "Rule key must be a string") 259 _assert(type(rule) == str, "Rule key must be a string")
193 _assert(not rule.startswith(root_prefix), 260 _assert(not rule.startswith(root_prefix),
194 "Suite name prefix must not be used in rule keys") 261 "Suite name prefix must not be used in rule keys")
195 _assert(not rule.endswith('.js'), 262 _assert(not rule.endswith('.js'),
196 ".js extension must not be used in rule keys.") 263 ".js extension must not be used in rule keys.")
197 return status["success"] 264 return status["success"]
198 except Exception as e: 265 except Exception as e:
199 print e 266 print e
200 return False 267 return False
OLDNEW
« no previous file with comments | « tools/run-tests.py ('k') | tools/testrunner/local/statusfile_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698