Changeset 129051 in webkit
- Timestamp:
- Sep 19, 2012 3:29:45 PM (12 years ago)
- Location:
- trunk/Tools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r129047 r129051 1 2012-09-19 Dirk Pranke <dpranke@chromium.org> 2 3 implement first part of support for the new TestExpectations syntax 4 https://bugs.webkit.org/show_bug.cgi?id=96569 5 6 Reviewed by Ryosuke Niwa. 7 8 This patch implements support for parsing a line of the new 9 format for the TestExpectations file and converting it back into 10 the old format for compatibility. This routine is not yet used 11 by anything. 12 13 The new format is documented at: 14 http://trac.webkit.org/wiki/TestExpectations 15 16 but, in short: 17 18 [bugs] [ "[" modifiers "]" ] test_name [ "[" expectations "]" ] 19 20 - Comments are indicated with "#" instead of "//" 21 - If no expectations are specified we default to Skip for 22 compatibility with the Skipped files (these two changes make 23 Skipped files a subset of TestExpectations files) 24 25 - All of the tokens are now CamelCase instead of ALLCAPS. 26 - FAIL -> Failure 27 - IMAGE -> ImageOnlyFailure 28 - WONTFIX -> WontFix 29 - modifiers refer to just the platforms and configurations 30 (release/debug) that the line applies to. 31 - WontFix, Rebaseline, Slow, and Skip move to the right-hand side as 32 expectations 33 - expectations will typically be written out in lexicographic order 34 - We use webkit.org/b/12345, crbug.com/12345, and Bug(dpranke) 35 instead of BUGWK12345, BUGCR12345, and BUGDPRANKE. 36 37 * Scripts/webkitpy/layout_tests/models/test_expectations.py: 38 (TestExpectationParser): 39 (TestExpectationParser._tokenize_line_using_new_format): 40 * Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py: 41 (NewExpectationSyntaxTests): 42 (NewExpectationSyntaxTests.assert_exp): 43 (NewExpectationSyntaxTests.test_bare_name): 44 (NewExpectationSyntaxTests.test_bare_name_and_bugs): 45 (NewExpectationSyntaxTests.test_comments): 46 (NewExpectationSyntaxTests.test_config_modifiers): 47 (NewExpectationSyntaxTests.test_unknown_config): 48 (NewExpectationSyntaxTests.test_unknown_expectation): 49 (NewExpectationSyntaxTests.test_skip): 50 (NewExpectationSyntaxTests.test_slow): 51 (NewExpectationSyntaxTests.test_wontfix): 52 (NewExpectationSyntaxTests.test_blank_line): 53 (NewExpectationSyntaxTests.test_warnings): 54 1 55 2012-09-19 Dirk Pranke <dpranke@chromium.org> 2 56 -
trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
r129047 r129051 255 255 return expectation_line 256 256 257 # FIXME: Update the original modifiers and remove this once the old syntax is gone. 258 _configuration_tokens_list = [ 259 'Mac', 'SnowLeopard', 'Lion', 'MountainLion', 260 'Win', 'XP', 'Vista', 'Win7', 261 'Linux', 262 'Android', 263 'Release', 264 'Debug', 265 ] 266 267 _configuration_tokens = dict((token, token.upper()) for token in _configuration_tokens_list) 268 269 # Note: we can't distinguish audio failures or image+text failures from text-only failures. 270 # FIXME: Update the original modifiers list and remove this once the old syntax is gone. 271 _expectation_tokens = { 272 'WontFix': 'WONTFIX', 273 'Pass': 'PASS', 274 'Failure': 'FAIL', 275 'ImageOnlyFailure': 'IMAGE', 276 'Crash': 'CRASH', 277 'Timeout': 'TIMEOUT', 278 'Slow': 'SLOW', 279 } 280 257 281 @classmethod 258 282 def _tokenize_line_using_new_format(cls, filename, expectation_string, line_number): 259 # FIXME: implement :). 260 raise NotImplementedError 283 """Tokenizes a line from TestExpectations and returns an unparsed TestExpectationLine instance using the old format. 284 285 The new format for a test expectation line is: 286 287 [[bugs] [ "[" <configuration modifiers> "]" <name> [ "[" <expectations> "]" ["#" <comment>] 288 289 Any errant whitespace is not preserved. 290 291 """ 292 expectation_line = TestExpectationLine() 293 expectation_line.filename = filename 294 expectation_line.line_number = line_number 295 296 comment_index = expectation_string.find("#") 297 if comment_index == -1: 298 comment_index = len(expectation_string) 299 else: 300 expectation_line.comment = expectation_string[comment_index + 1:] 301 302 remaining_string = re.sub(r"\s+", " ", expectation_string[:comment_index].strip()) 303 if len(remaining_string) == 0: 304 return expectation_line 305 306 # special-case parsing this so that we fail immediately instead of treating this as a test name 307 if remaining_string.startswith('//'): 308 expectation_line.warnings = ['use "#" instead of "//" for comments'] 309 return expectation_line 310 311 bugs = [] 312 modifiers = [] 313 name = None 314 expectations = [] 315 warnings = [] 316 317 WEBKIT_BUG_PREFIX = 'webkit.org/b/' 318 CHROMIUM_BUG_PREFIX = 'crbug.com/' 319 V8_BUG_PREFIX = 'code.google.com/p/v8/issues/detail?id=' 320 321 tokens = remaining_string.split() 322 state = 'start' 323 for token in tokens: 324 if (token.startswith(WEBKIT_BUG_PREFIX) or 325 token.startswith(CHROMIUM_BUG_PREFIX) or 326 token.startswith(V8_BUG_PREFIX) or 327 token.startswith('Bug(')): 328 if state != 'start': 329 warnings.append('"%s" is not at the start of the line.' % token) 330 break 331 if token.startswith(WEBKIT_BUG_PREFIX): 332 bugs.append(token.replace(WEBKIT_BUG_PREFIX, 'BUGWK')) 333 elif token.startswith(CHROMIUM_BUG_PREFIX): 334 bugs.append(token.replace(CHROMIUM_BUG_PREFIX, 'BUGCR')) 335 elif token.startswith(V8_BUG_PREFIX): 336 bugs.append(token.replace(V8_BUG_PREFIX, 'BUGV8_')) 337 else: 338 match = re.match('Bug\((\w+)\)$', token) 339 if not match: 340 warnings.append('unrecognized bug identifier "%s"' % token) 341 break 342 else: 343 bugs.append('BUG' + match.group(1).upper()) 344 elif token.startswith('BUG'): 345 warnings.append('unrecognized old-style bug identifier "%s"' % token) 346 break 347 elif token == '[': 348 if state == 'start': 349 state = 'configuration' 350 elif state == 'name_found': 351 state = 'expectations' 352 else: 353 warnings.append('unexpected "["') 354 break 355 elif token == ']': 356 if state == 'configuration': 357 state = 'name' 358 elif state == 'expectations': 359 state = 'done' 360 else: 361 warnings.append('unexpected "]"') 362 break 363 elif token in ('//', ':', '='): 364 warnings.append('"%s" is not legal in the new TestExpectations syntax.' % token) 365 break 366 elif state == 'configuration': 367 modifiers.append(cls._configuration_tokens.get(token, token)) 368 elif state == 'expectations': 369 if token in ('Rebaseline', 'Skip', 'Slow', 'WontFix'): 370 modifiers.append(token.upper()) 371 else: 372 expectations.append(cls._expectation_tokens.get(token, token)) 373 elif state == 'name_found': 374 warnings.append('expecting "[", "#", or end of line instead of "%s"' % token) 375 break 376 else: 377 name = token 378 state = 'name_found' 379 380 if not warnings: 381 if not name: 382 warnings.append('Did not find a test name.') 383 elif state not in ('name_found', 'done'): 384 warnings.append('Missing a "]"') 385 386 if not expectations: 387 if 'SKIP' not in modifiers and 'REBASELINE' not in modifiers and 'SLOW' not in modifiers: 388 modifiers.append('SKIP') 389 expectations = ['PASS'] 390 391 # FIXME: expectation line should just store bugs and modifiers separately. 392 expectation_line.modifiers = bugs + modifiers 393 expectation_line.expectations = expectations 394 expectation_line.name = name 395 expectation_line.warnings = warnings 396 return expectation_line 261 397 262 398 @classmethod -
trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py
r129047 r129051 341 341 342 342 343 class NewExpectationSyntaxTests(unittest.TestCase): 344 def assert_exp(self, line, bugs=None, modifiers=None, expectations=None, warnings=None, comment=None, name='foo.html'): 345 bugs = bugs or [] 346 modifiers = modifiers or [] 347 expectations = expectations or [] 348 warnings = warnings or [] 349 filename = 'TestExpectations' 350 line_number = 1 351 expectation_line = TestExpectationParser._tokenize_line_using_new_format(filename, line, line_number) 352 self.assertEquals(expectation_line.warnings, warnings) 353 self.assertEquals(expectation_line.name, name) 354 self.assertEquals(expectation_line.filename, filename) 355 self.assertEquals(expectation_line.line_number, line_number) 356 if not warnings: 357 self.assertEquals(expectation_line.modifiers, modifiers) 358 self.assertEquals(expectation_line.expectations, expectations) 359 360 def test_bare_name(self): 361 self.assert_exp('foo.html', modifiers=['SKIP'], expectations=['PASS']) 362 363 def test_bare_name_and_bugs(self): 364 self.assert_exp('webkit.org/b/12345 foo.html', modifiers=['BUGWK12345', 'SKIP'], expectations=['PASS']) 365 self.assert_exp('crbug.com/12345 foo.html', modifiers=['BUGCR12345', 'SKIP'], expectations=['PASS']) 366 self.assert_exp('Bug(dpranke) foo.html', modifiers=['BUGDPRANKE', 'SKIP'], expectations=['PASS']) 367 self.assert_exp('crbug.com/12345 crbug.com/34567 foo.html', modifiers=['BUGCR12345', 'BUGCR34567', 'SKIP'], expectations=['PASS']) 368 369 def test_comments(self): 370 self.assert_exp("# comment", name=None, comment="# comment") 371 self.assert_exp("foo.html # comment", comment="# comment", expectations=['PASS'], modifiers=['SKIP']) 372 373 def test_config_modifiers(self): 374 self.assert_exp('[ Mac ] foo.html', modifiers=['MAC', 'SKIP'], expectations=['PASS']) 375 self.assert_exp('[ Mac Vista ] foo.html', modifiers=['MAC', 'VISTA', 'SKIP'], expectations=['PASS']) 376 self.assert_exp('[ Mac ] foo.html [ Failure ] ', modifiers=['MAC'], expectations=['FAIL']) 377 378 def test_unknown_config(self): 379 self.assert_exp('[ Foo ] foo.html ', modifiers=['Foo', 'SKIP'], expectations=['PASS']) 380 381 def test_unknown_expectation(self): 382 self.assert_exp('foo.html [ Audio ]', expectations=['Audio']) 383 384 def test_skip(self): 385 self.assert_exp('foo.html [ Skip ]', modifiers=['SKIP'], expectations=['PASS']) 386 387 def test_slow(self): 388 self.assert_exp('foo.html [ Slow ]', modifiers=['SLOW'], expectations=['PASS']) 389 390 def test_wontfix(self): 391 self.assert_exp('foo.html [ WontFix ]', modifiers=['WONTFIX', 'SKIP'], expectations=['PASS']) 392 393 def test_blank_line(self): 394 self.assert_exp('', name=None) 395 396 def test_warnings(self): 397 self.assert_exp('[ Mac ]', warnings=['Did not find a test name.'], name=None) 398 399 self.assert_exp('[ [', warnings=['unexpected "["'], name=None) 400 self.assert_exp('crbug.com/12345 ]', warnings=['unexpected "]"'], name=None) 401 402 self.assert_exp('foo.html crbug.com/12345 ]', warnings=['"crbug.com/12345" is not at the start of the line.']) 403 404 343 405 class SemanticTests(Base): 344 406 def test_bug_format(self):
Note: See TracChangeset
for help on using the changeset viewer.