Chromium Code Reviews| 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 """A script to modify TestExpectations lines based layout test failures in try j obs. | 5 """A script to modify TestExpectations lines based layout test failures in try j obs. |
| 6 | 6 |
| 7 This script outputs a list of test expectation lines to add to a 'TestExpectatio ns' file | 7 This script outputs a list of test expectation lines to add to a 'TestExpectatio ns' file |
| 8 by retrieving the try job results for the current CL. | 8 by retrieving the try job results for the current CL. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import logging | 11 import logging |
| 12 | 12 |
| 13 from webkitpy.common.net import rietveld | |
| 13 from webkitpy.common.net.buildbot import BuildBot | 14 from webkitpy.common.net.buildbot import BuildBot |
| 14 from webkitpy.common.net import rietveld | 15 from webkitpy.common.webkit_finder import WebKitFinder |
| 15 | 16 from webkitpy.w3c.test_parser import TestParser |
| 16 | 17 |
| 17 _log = logging.getLogger(__name__) | 18 _log = logging.getLogger(__name__) |
| 18 | 19 |
| 19 | 20 |
| 20 def main(host, port): | 21 def main(host, port): |
| 21 expectations_file = port.path_to_generic_test_expectations_file() | 22 expectations_file = port.path_to_generic_test_expectations_file() |
| 22 expectations_line_adder = W3CExpectationsLineAdder(host) | 23 expectations_line_adder = W3CExpectationsLineAdder(host) |
| 23 issue_number = expectations_line_adder.get_issue_number() | 24 issue_number = expectations_line_adder.get_issue_number() |
| 24 try_bots = expectations_line_adder.get_try_bots() | 25 try_bots = expectations_line_adder.get_try_bots() |
| 25 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots, host.web) | 26 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots, host.web) |
| 26 test_expectations = {} | 27 test_expectations = {} |
| 27 if not try_jobs: | 28 if not try_jobs: |
| 28 print 'No Try Job information was collected.' | 29 print 'No Try Job information was collected.' |
| 29 return 1 | 30 return 1 |
| 30 for job in try_jobs: | 31 for job in try_jobs: |
| 31 platform_results = expectations_line_adder.get_failing_results_dict(Buil dBot(), job.builder_name, job.build_number) | 32 platform_results = expectations_line_adder.get_failing_results_dict(Buil dBot(), job.builder_name, job.build_number) |
| 32 test_expectations = expectations_line_adder.merge_dicts(test_expectation s, platform_results) | 33 test_expectations = expectations_line_adder.merge_dicts(test_expectation s, platform_results) |
| 33 for test_name, platform_result in test_expectations.iteritems(): | 34 for test_name, platform_result in test_expectations.iteritems(): |
| 34 test_expectations[test_name] = expectations_line_adder.merge_same_valued _keys(platform_result) | 35 test_expectations[test_name] = expectations_line_adder.merge_same_valued _keys(platform_result) |
| 36 test_expectations = expectations_line_adder.get_expected_txt_files(test_expe ctations) | |
| 35 test_expectation_lines = expectations_line_adder.create_line_list(test_expec tations) | 37 test_expectation_lines = expectations_line_adder.create_line_list(test_expec tations) |
| 36 expectations_line_adder.write_to_test_expectations(host, expectations_file, test_expectation_lines) | 38 expectations_line_adder.write_to_test_expectations(host, expectations_file, test_expectation_lines) |
| 37 | 39 |
| 38 | 40 |
| 39 class W3CExpectationsLineAdder(object): | 41 class W3CExpectationsLineAdder(object): |
| 40 | 42 |
| 41 def __init__(self, host): | 43 def __init__(self, host): |
| 42 self._host = host | 44 self._host = host |
| 43 self.filesystem = host.filesystem | 45 self.filesystem = host.filesystem |
| 44 | 46 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 all_lines += str(line) + '\n' | 263 all_lines += str(line) + '\n' |
| 262 all_lines = all_lines[:-1] | 264 all_lines = all_lines[:-1] |
| 263 if w3c_comment_line_index == -1: | 265 if w3c_comment_line_index == -1: |
| 264 file_contents += '\n%s\n' % comment_line | 266 file_contents += '\n%s\n' % comment_line |
| 265 file_contents += all_lines | 267 file_contents += all_lines |
| 266 else: | 268 else: |
| 267 end_of_comment_line = (file_contents[w3c_comment_line_index:].find(' \n')) + w3c_comment_line_index | 269 end_of_comment_line = (file_contents[w3c_comment_line_index:].find(' \n')) + w3c_comment_line_index |
| 268 new_data = file_contents[: end_of_comment_line + 1] + all_lines + fi le_contents[end_of_comment_line:] | 270 new_data = file_contents[: end_of_comment_line + 1] + all_lines + fi le_contents[end_of_comment_line:] |
| 269 file_contents = new_data | 271 file_contents = new_data |
| 270 host.filesystem.write_text_file(path, file_contents) | 272 host.filesystem.write_text_file(path, file_contents) |
| 273 | |
| 274 def get_expected_txt_files(self, tests_results): | |
| 275 """Gets -expected.txt files. | |
| 276 | |
| 277 Invokes webkit-patch rebaseline-from-try-jobs in order | |
| 278 to download new -expected.txt files for testharness.js | |
| 279 tests that did not Crash or Timeout. Then the platform- | |
| 280 specific test is removed from the overall failure test dictionary. | |
| 281 | |
| 282 Args: | |
| 283 tests_results: A dictionary that maps test name to platforms to | |
| 284 test results. | |
| 285 | |
| 286 Returns: | |
| 287 An updated tests_results dictionary without the platform-specific te st- | |
| 288 harness.js tests that required new baselines to be downloaded from | |
| 289 webkit-patch rebaseline-from-try-jobs. | |
| 290 """ | |
| 291 finder = WebKitFinder(self._host.filesystem) | |
| 292 layout_tests_relative_path = self._host.filesystem.relpath(finder.layout _tests_dir(), finder.chromium_base()) | |
| 293 tests_to_rebaseline = [] | |
| 294 tests = self._host.executive.run_command(['git', 'diff', 'master', '--na me-only']) | |
| 295 for test_dir in tests.splitlines(): | |
| 296 js_test = self.is_js_test(finder, test_dir) | |
|
qyearsley
2016/08/01 18:33:19
`test_dir` is generally not a directory, right? It
dcampb
2016/08/02 17:56:57
correct. The name 'test_dir' is a bit confusing.
| |
| 297 if js_test: | |
|
qyearsley
2016/08/01 18:33:19
To simplify the above two lines and avoid adding a
dcampb
2016/08/02 17:56:57
done
| |
| 298 test_path = self._host.filesystem.relpath(test_dir, layout_tests _relative_path) | |
| 299 for platform in tests_results[test_path]: | |
| 300 if tests_results[test_path][platform]['actual'] not in ['CRA SH', 'TIMEOUT']: | |
| 301 del tests_results[test_path][platform] | |
| 302 tests_to_rebaseline.append(test_path) | |
|
qyearsley
2016/08/01 18:33:19
It seems like you may be able to extract a helper
| |
| 303 if tests_to_rebaseline: | |
| 304 webkit_patch = self._host.filesystem.join(finder.chromium_base(), fi nder.webkit_base(), | |
| 305 finder.path_to_script('web kit-patch')) | |
| 306 self._host.executive.run_command(['python', webkit_patch, | |
| 307 'rebaseline-from-try-jobs', '-v', | |
| 308 ' '.join(tests_to_rebaseline)]) | |
| 309 return tests_results | |
|
qyearsley
2016/08/01 18:33:19
If we were to write a unit test for this function,
dcampb
2016/08/02 17:56:57
I have extracted helper functions and am currently
| |
| 310 | |
| 311 def is_js_test(self, webkit_finder, test_path): | |
|
qyearsley
2016/08/01 18:33:18
1. Is test_path relative to the LayoutTests direct
dcampb
2016/08/02 17:56:57
It is relative to layoutTests.
| |
| 312 absolute_path = self._host.filesystem.join(webkit_finder.chromium_base() , test_path) | |
| 313 test_parser = TestParser(None, absolute_path) | |
| 314 return test_parser.is_jstest() | |
| OLD | NEW |