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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py

Issue 2805563002: Change wpt_expectations_updater to not depend on TestParser. (Closed)
Patch Set: Finish updating test and fix code Created 3 years, 8 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 | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_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 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Updates expectations and baselines when updating web-platform-tests. 5 """Updates expectations and baselines when updating web-platform-tests.
6 6
7 Specifically, this class fetches results from try bots for the current CL, then 7 Specifically, this class fetches results from try bots for the current CL, then
8 (1) downloads new baseline files for any tests that can be rebaselined, and 8 (1) downloads new baseline files for any tests that can be rebaselined, and
9 (2) updates the generic TestExpectations file for any other failing tests. 9 (2) updates the generic TestExpectations file for any other failing tests.
10 """ 10 """
11 11
12 import argparse 12 import argparse
13 import copy 13 import copy
14 import logging 14 import logging
15 15
16 from webkitpy.common.memoized import memoized 16 from webkitpy.common.memoized import memoized
17 from webkitpy.common.net.git_cl import GitCL 17 from webkitpy.common.net.git_cl import GitCL
18 from webkitpy.common.webkit_finder import WebKitFinder 18 from webkitpy.common.webkit_finder import WebKitFinder
19 from webkitpy.layout_tests.models.test_expectations import TestExpectationLine, TestExpectations 19 from webkitpy.layout_tests.models.test_expectations import TestExpectationLine, TestExpectations
20 from webkitpy.w3c.test_parser import TestParser 20 from webkitpy.w3c.wpt_manifest import WPTManifest
21 21
22 _log = logging.getLogger(__name__) 22 _log = logging.getLogger(__name__)
23 23
24 MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======' 24 MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======'
25 25
26 26
27 class WPTExpectationsUpdater(object): 27 class WPTExpectationsUpdater(object):
28 28
29 def __init__(self, host): 29 def __init__(self, host):
30 self.host = host 30 self.host = host
31 self.finder = WebKitFinder(self.host.filesystem) 31 self.finder = WebKitFinder(self.host.filesystem)
32 self.port = self.host.port_factory.get()
32 33
33 def run(self, args=None): 34 def run(self, args=None):
34 """Downloads text new baselines and adds test expectations lines.""" 35 """Downloads text new baselines and adds test expectations lines."""
35 parser = argparse.ArgumentParser(description=__doc__) 36 parser = argparse.ArgumentParser(description=__doc__)
36 parser.add_argument('-v', '--verbose', action='store_true', help='More v erbose logging.') 37 parser.add_argument('-v', '--verbose', action='store_true', help='More v erbose logging.')
37 args = parser.parse_args(args) 38 args = parser.parse_args(args)
38 39
39 log_level = logging.DEBUG if args.verbose else logging.INFO 40 log_level = logging.DEBUG if args.verbose else logging.INFO
40 logging.basicConfig(level=log_level, format='%(message)s') 41 logging.basicConfig(level=log_level, format='%(message)s')
41 42
42 issue_number = self.get_issue_number() 43 issue_number = self.get_issue_number()
43 if issue_number == 'None': 44 if issue_number == 'None':
44 _log.error('No issue on current branch.') 45 _log.error('No issue on current branch.')
45 return 1 46 return 1
46 47
47 builds = self.get_latest_try_jobs() 48 builds = self.get_latest_try_jobs()
48 _log.debug('Latest try jobs: %r', builds) 49 _log.debug('Latest try jobs: %r', builds)
49 if not builds: 50 if not builds:
50 _log.error('No try job information was collected.') 51 _log.error('No try job information was collected.')
51 return 1 52 return 1
52 53
54 # The manifest may be used below to do check which tests are reference t ests.
55 WPTManifest.ensure_manifest(self.host)
56
53 # Here we build up a dict of failing test results for all platforms. 57 # Here we build up a dict of failing test results for all platforms.
54 test_expectations = {} 58 test_expectations = {}
55 for build in builds: 59 for build in builds:
56 port_results = self.get_failing_results_dict(build) 60 port_results = self.get_failing_results_dict(build)
57 test_expectations = self.merge_dicts(test_expectations, port_results ) 61 test_expectations = self.merge_dicts(test_expectations, port_results )
58 62
59 # And then we merge results for different platforms that had the same re sults. 63 # And then we merge results for different platforms that had the same re sults.
60 for test_name, platform_result in test_expectations.iteritems(): 64 for test_name, platform_result in test_expectations.iteritems():
61 # platform_result is a dict mapping platforms to results. 65 # platform_result is a dict mapping platforms to results.
62 test_expectations[test_name] = self.merge_same_valued_keys(platform_ result) 66 test_expectations[test_name] = self.merge_same_valued_keys(platform_ result)
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 port_names: A list of full port names that the line should apply to. 283 port_names: A list of full port names that the line should apply to.
280 test_name: The test name for the expectation line. 284 test_name: The test name for the expectation line.
281 285
282 Returns: 286 Returns:
283 The specifier part of the new expectation line, e.g. "[ Mac ]". 287 The specifier part of the new expectation line, e.g. "[ Mac ]".
284 This will be an empty string if the line should apply to all platfor ms. 288 This will be an empty string if the line should apply to all platfor ms.
285 """ 289 """
286 specifiers = [] 290 specifiers = []
287 for name in sorted(port_names): 291 for name in sorted(port_names):
288 specifiers.append(self.host.builders.version_specifier_for_port_name (name)) 292 specifiers.append(self.host.builders.version_specifier_for_port_name (name))
289 port = self.host.port_factory.get() 293
290 specifiers.extend(self.skipped_specifiers(test_name)) 294 specifiers.extend(self.skipped_specifiers(test_name))
291 specifiers = self.simplify_specifiers(specifiers, port.configuration_spe cifier_macros()) 295 specifiers = self.simplify_specifiers(specifiers, self.port.configuratio n_specifier_macros())
292 if not specifiers: 296 if not specifiers:
293 return '' 297 return ''
294 return '[ %s ]' % ' '.join(specifiers) 298 return '[ %s ]' % ' '.join(specifiers)
295 299
296 @staticmethod 300 @staticmethod
297 def to_list(tuple_or_value): 301 def to_list(tuple_or_value):
298 """Converts a tuple to a list, and a string value to a one-item list.""" 302 """Converts a tuple to a list, and a string value to a one-item list."""
299 if isinstance(tuple_or_value, tuple): 303 if isinstance(tuple_or_value, tuple):
300 return list(tuple_or_value) 304 return list(tuple_or_value)
301 return [tuple_or_value] 305 return [tuple_or_value]
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 The place in the file where the new lines are inserted is after a 357 The place in the file where the new lines are inserted is after a
354 marker comment line. If this marker comment line is not found, it will 358 marker comment line. If this marker comment line is not found, it will
355 be added to the end of the file. 359 be added to the end of the file.
356 360
357 Args: 361 Args:
358 line_list: A list of lines to add to the TestExpectations file. 362 line_list: A list of lines to add to the TestExpectations file.
359 """ 363 """
360 _log.info('Lines to write to TestExpectations:') 364 _log.info('Lines to write to TestExpectations:')
361 for line in line_list: 365 for line in line_list:
362 _log.info(' %s', line) 366 _log.info(' %s', line)
363 port = self.host.port_factory.get() 367 expectations_file_path = self.port.path_to_generic_test_expectations_fil e()
364 expectations_file_path = port.path_to_generic_test_expectations_file()
365 file_contents = self.host.filesystem.read_text_file(expectations_file_pa th) 368 file_contents = self.host.filesystem.read_text_file(expectations_file_pa th)
366 marker_comment_index = file_contents.find(MARKER_COMMENT) 369 marker_comment_index = file_contents.find(MARKER_COMMENT)
367 line_list = [line for line in line_list if self._test_name_from_expectat ion_string(line) not in file_contents] 370 line_list = [line for line in line_list if self._test_name_from_expectat ion_string(line) not in file_contents]
368 if not line_list: 371 if not line_list:
369 return 372 return
370 if marker_comment_index == -1: 373 if marker_comment_index == -1:
371 file_contents += '\n%s\n' % MARKER_COMMENT 374 file_contents += '\n%s\n' % MARKER_COMMENT
372 file_contents += '\n'.join(line_list) 375 file_contents += '\n'.join(line_list)
373 else: 376 else:
374 end_of_marker_line = (file_contents[marker_comment_index:].find('\n' )) + marker_comment_index 377 end_of_marker_line = (file_contents[marker_comment_index:].find('\n' )) + marker_comment_index
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 new_test_results = copy.deepcopy(test_results) 433 new_test_results = copy.deepcopy(test_results)
431 tests_to_rebaseline = set() 434 tests_to_rebaseline = set()
432 for test_path in test_results: 435 for test_path in test_results:
433 for platform, result in test_results[test_path].iteritems(): 436 for platform, result in test_results[test_path].iteritems():
434 if self.can_rebaseline(test_path, result): 437 if self.can_rebaseline(test_path, result):
435 del new_test_results[test_path][platform] 438 del new_test_results[test_path][platform]
436 tests_to_rebaseline.add(test_path) 439 tests_to_rebaseline.add(test_path)
437 return sorted(tests_to_rebaseline), new_test_results 440 return sorted(tests_to_rebaseline), new_test_results
438 441
439 def can_rebaseline(self, test_path, result): 442 def can_rebaseline(self, test_path, result):
440 return (self.is_js_test(test_path) and 443 if self.is_reference_test(test_path):
441 result['actual'] not in ('CRASH', 'TIMEOUT')) 444 return False
445 if result['actual'] in ('CRASH', 'TIMEOUT', 'MISSING'):
446 return False
447 return True
442 448
443 def is_js_test(self, test_path): 449 def is_reference_test(self, test_path):
444 """Checks whether a given file is a testharness.js test. 450 """Checks whether a given file is a testharness.js test."""
445 451 return bool(self.port.reference_files(test_path))
446 TODO(qyearsley): This may not behave how we want it to for virtual tests .
447 TODO(qyearsley): Avoid using TestParser; maybe this should use
448 Port.test_type, or Port.reference_files to see whether it's not
449 a reference test?
450
451 Args:
452 test_path: A file path relative to the layout tests directory.
453 This might correspond to a deleted file or a non-test.
454 """
455 absolute_path = self.host.filesystem.join(self.finder.layout_tests_dir() , test_path)
456 test_parser = TestParser(absolute_path, self.host)
457 if not test_parser.test_doc:
458 return False
459 return test_parser.is_jstest()
460 452
461 def _get_try_bots(self): 453 def _get_try_bots(self):
462 return self.host.builders.all_try_builder_names() 454 return self.host.builders.all_try_builder_names()
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698