| OLD | NEW |
| 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 """Functionality for adding TestExpectations lines and downloading baselines | 5 """Functionality for adding TestExpectations lines and downloading baselines |
| 6 based on layout test failures in try jobs. | 6 based on layout test failures in try jobs. |
| 7 | 7 |
| 8 This script is used as part of the w3c test auto-import process. | 8 This script is used as part of the w3c test auto-import process. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import logging |
| 12 |
| 11 from webkitpy.common.net.rietveld import Rietveld | 13 from webkitpy.common.net.rietveld import Rietveld |
| 12 from webkitpy.common.net.buildbot import BuildBot | 14 from webkitpy.common.net.buildbot import BuildBot, Build |
| 13 from webkitpy.common.net.git_cl import GitCL | 15 from webkitpy.common.net.git_cl import GitCL |
| 14 from webkitpy.common.webkit_finder import WebKitFinder | 16 from webkitpy.common.webkit_finder import WebKitFinder |
| 15 from webkitpy.w3c.test_parser import TestParser | 17 from webkitpy.w3c.test_parser import TestParser |
| 16 | 18 |
| 19 _log = logging.getLogger(__name__) |
| 20 |
| 17 | 21 |
| 18 def main(host): | 22 def main(host): |
| 23 # TODO(qyearsley): Add a "main" function to W3CExpectationsLineAdder |
| 24 # and move most or all of this logic in there. |
| 19 host.initialize_scm() | 25 host.initialize_scm() |
| 20 port = host.port_factory.get() | 26 port = host.port_factory.get() |
| 21 expectations_file = port.path_to_generic_test_expectations_file() | 27 expectations_file = port.path_to_generic_test_expectations_file() |
| 22 expectations_line_adder = W3CExpectationsLineAdder(host) | 28 expectations_line_adder = W3CExpectationsLineAdder(host) |
| 23 issue_number = expectations_line_adder.get_issue_number() | 29 issue_number = expectations_line_adder.get_issue_number() |
| 24 try_bots = expectations_line_adder.get_try_bots() | 30 try_bots = expectations_line_adder.get_try_bots() |
| 25 rietveld = Rietveld(host.web) | 31 rietveld = Rietveld(host.web) |
| 26 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots) | 32 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots) |
| 27 test_expectations = {} | 33 test_expectations = {} |
| 28 if not try_jobs: | 34 if not try_jobs: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 }} | 71 }} |
| 66 return test_dict | 72 return test_dict |
| 67 | 73 |
| 68 def get_failing_results_dict(self, buildbot, builder_name, build_number): | 74 def get_failing_results_dict(self, buildbot, builder_name, build_number): |
| 69 """Returns a nested dict of failing test results. | 75 """Returns a nested dict of failing test results. |
| 70 | 76 |
| 71 Retrieves a full list of layout test results from a builder result URL. | 77 Retrieves a full list of layout test results from a builder result URL. |
| 72 Collects the builder name, platform and a list of tests that did not | 78 Collects the builder name, platform and a list of tests that did not |
| 73 run as expected. | 79 run as expected. |
| 74 | 80 |
| 81 TODO(qyearsley): Rather than taking a BuildBot object, this should use |
| 82 the Host's BuildBot object. |
| 83 |
| 75 Args: | 84 Args: |
| 85 buildbot: A BuildBot object. |
| 76 builder: A Builder object. | 86 builder: A Builder object. |
| 77 build: A Build object. | 87 build: A Build object. |
| 78 | 88 |
| 79 Returns: | 89 Returns: |
| 80 A dictionary with the structure: { | 90 A dictionary with the structure: { |
| 81 'key': { | 91 'key': { |
| 82 'expected': 'TIMEOUT', | 92 'expected': 'TIMEOUT', |
| 83 'actual': 'CRASH', | 93 'actual': 'CRASH', |
| 84 'bug': 'crbug.com/11111' | 94 'bug': 'crbug.com/11111' |
| 85 } | 95 } |
| 86 } | 96 } |
| 97 If there are no failing results or no results could be fetched, |
| 98 this will return an empty dict. |
| 87 """ | 99 """ |
| 88 results_url = buildbot.results_url(builder_name, build_number) | 100 layout_test_results = buildbot.fetch_results(Build(builder_name, build_n
umber)) |
| 89 layout_test_results = buildbot.fetch_layout_test_results(results_url) | 101 if layout_test_results is None: |
| 102 _log.warning('No results for builder %s, build %s', builder_name, bu
ild_number) |
| 103 return {} |
| 90 platform = self._host.builders.port_name_for_builder_name(builder_name) | 104 platform = self._host.builders.port_name_for_builder_name(builder_name) |
| 91 result_list = layout_test_results.didnt_run_as_expected_results() | 105 result_list = layout_test_results.didnt_run_as_expected_results() |
| 92 failing_results_dict = self._generate_results_dict(platform, result_list
) | 106 failing_results_dict = self._generate_results_dict(platform, result_list
) |
| 93 return failing_results_dict | 107 return failing_results_dict |
| 94 | 108 |
| 95 def merge_dicts(self, target, source, path=None): | 109 def merge_dicts(self, target, source, path=None): |
| 96 """Recursively merges nested dictionaries. | 110 """Recursively merges nested dictionaries. |
| 97 | 111 |
| 98 Args: | 112 Args: |
| 99 target: First dictionary, which is updated based on source. | 113 target: First dictionary, which is updated based on source. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 for platform in tests_results[test_path].keys(): | 339 for platform in tests_results[test_path].keys(): |
| 326 if tests_results[test_path][platform]['actual'] not in ['CRA
SH', 'TIMEOUT']: | 340 if tests_results[test_path][platform]['actual'] not in ['CRA
SH', 'TIMEOUT']: |
| 327 del tests_results[test_path][platform] | 341 del tests_results[test_path][platform] |
| 328 tests_to_rebaseline.add(test_path) | 342 tests_to_rebaseline.add(test_path) |
| 329 return list(tests_to_rebaseline), tests_results | 343 return list(tests_to_rebaseline), tests_results |
| 330 | 344 |
| 331 def is_js_test(self, webkit_finder, test_path): | 345 def is_js_test(self, webkit_finder, test_path): |
| 332 absolute_path = self._host.filesystem.join(webkit_finder.chromium_base()
, test_path) | 346 absolute_path = self._host.filesystem.join(webkit_finder.chromium_base()
, test_path) |
| 333 test_parser = TestParser(absolute_path, self._host) | 347 test_parser = TestParser(absolute_path, self._host) |
| 334 return test_parser.is_jstest() | 348 return test_parser.is_jstest() |
| OLD | NEW |