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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations.py

Issue 2902523002: Print a suggested commit description after removing flaky lines. (Closed)
Patch Set: add test, sort bugs Created 3 years, 7 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/layout_tests/update_test_expectations_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 TestExpectations based on results in builder bots. 5 """Updates TestExpectations based on results in builder bots.
6 6
7 Scans the TestExpectations file and uses results from actual builder bots runs 7 Scans the TestExpectations file and uses results from actual builder bots runs
8 to remove tests that are marked as flaky but don't fail in the specified way. 8 to remove tests that are marked as flaky but don't fail in the specified way.
9 9
10 E.g. If a test has this expectation: 10 E.g. If a test has this expectation:
11 bug(test) fast/test.html [ Failure Pass ] 11 bug(test) fast/test.html [ Failure Pass ]
12 12
13 And all the runs on builders have passed the line will be removed. 13 And all the runs on builders have passed the line will be removed.
14 14
15 Additionally, the runs don't all have to be Passing to remove the line; 15 Additionally, the runs don't all have to be Passing to remove the line;
16 as long as the non-Passing results are of a type not specified in the 16 as long as the non-Passing results are of a type not specified in the
17 expectation this line will be removed. For example, if this is the 17 expectation this line will be removed. For example, if this is the
18 expectation: 18 expectation:
19 19
20 bug(test) fast/test.html [ Crash Pass ] 20 bug(test) fast/test.html [ Crash Pass ]
21 21
22 But the results on the builders show only Passes and Timeouts, the line 22 But the results on the builders show only Passes and Timeouts, the line
23 will be removed since there's no Crash results. 23 will be removed since there's no Crash results.
24 """ 24 """
25 25
26 import argparse 26 import argparse
27 import logging 27 import logging
28 import webbrowser 28 import webbrowser
29 29
30 from webkitpy.layout_tests.models.test_expectations import CHROMIUM_BUG_PREFIX
30 from webkitpy.layout_tests.models.test_expectations import TestExpectations 31 from webkitpy.layout_tests.models.test_expectations import TestExpectations
31 from webkitpy.tool.commands.flaky_tests import FlakyTests 32 from webkitpy.tool.commands.flaky_tests import FlakyTests
32 33
33 _log = logging.getLogger(__name__) 34 _log = logging.getLogger(__name__)
34 35
35 36
36 def main(host, bot_test_expectations_factory, argv): 37 def main(host, bot_test_expectations_factory, argv):
37 parser = argparse.ArgumentParser(epilog=__doc__, formatter_class=argparse.Ra wTextHelpFormatter) 38 parser = argparse.ArgumentParser(epilog=__doc__, formatter_class=argparse.Ra wTextHelpFormatter)
38 parser.add_argument('--verbose', '-v', action='store_true', default=False, h elp='enable more verbose logging') 39 parser.add_argument('--verbose', '-v', action='store_true', default=False, h elp='enable more verbose logging')
39 parser.add_argument('--show-results', 40 parser.add_argument('--show-results',
40 '-s', 41 '-s',
41 action='store_true', 42 action='store_true',
42 default=False, 43 default=False,
43 help='Open results dashboard for all removed lines') 44 help='Open results dashboard for all removed lines')
44 args = parser.parse_args(argv) 45 args = parser.parse_args(argv)
45 46
46 logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO, f ormat='%(levelname)s: %(message)s') 47 logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO, f ormat='%(levelname)s: %(message)s')
47 48
48 port = host.port_factory.get() 49 port = host.port_factory.get()
49 expectations_file = port.path_to_generic_test_expectations_file() 50 expectations_file = port.path_to_generic_test_expectations_file()
50 if not host.filesystem.isfile(expectations_file): 51 if not host.filesystem.isfile(expectations_file):
51 _log.warning("Didn't find generic expectations file at: " + expectations _file) 52 _log.warning("Didn't find generic expectations file at: " + expectations _file)
52 return 1 53 return 1
53 54
54 remove_flakes_o_matic = RemoveFlakesOMatic(host, 55 remove_flakes_o_matic = RemoveFlakesOMatic(
55 port, 56 host, port, bot_test_expectations_factory, webbrowser)
56 bot_test_expectations_factory,
57 webbrowser)
58 57
59 test_expectations = remove_flakes_o_matic.get_updated_test_expectations() 58 test_expectations = remove_flakes_o_matic.get_updated_test_expectations()
60 59
61 if args.show_results: 60 if args.show_results:
62 remove_flakes_o_matic.show_removed_results() 61 remove_flakes_o_matic.show_removed_results()
63 62
64 remove_flakes_o_matic.write_test_expectations(test_expectations, 63 remove_flakes_o_matic.write_test_expectations(test_expectations, expectation s_file)
65 expectations_file) 64 remove_flakes_o_matic.print_suggested_commit_description()
66 return 0 65 return 0
67 66
68 67
69 class RemoveFlakesOMatic(object): 68 class RemoveFlakesOMatic(object):
70 69
71 def __init__(self, host, port, bot_test_expectations_factory, browser): 70 def __init__(self, host, port, bot_test_expectations_factory, browser):
72 self._host = host 71 self._host = host
73 self._port = port 72 self._port = port
74 self._expectations_factory = bot_test_expectations_factory 73 self._expectations_factory = bot_test_expectations_factory
75 self._builder_results_by_path = {} 74 self._builder_results_by_path = {}
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 test_expectations.remove(expectation) 311 test_expectations.remove(expectation)
313 312
314 # Remove associated comments and whitespace if we've removed the las t expectation under 313 # Remove associated comments and whitespace if we've removed the las t expectation under
315 # a comment block. Only remove a comment block if it's not separated from the test 314 # a comment block. Only remove a comment block if it's not separated from the test
316 # expectation line by whitespace. 315 # expectation line by whitespace.
317 self._remove_associated_comments_and_whitespace(test_expectations, i ndex) 316 self._remove_associated_comments_and_whitespace(test_expectations, i ndex)
318 317
319 return test_expectations 318 return test_expectations
320 319
321 def show_removed_results(self): 320 def show_removed_results(self):
322 """Opens removed lines in the results dashboard. 321 """Opens a browser showing the removed lines in the results dashboard.
323 322
324 Opens the results dashboard in the browser, showing all the tests for li nes that the script 323 Opens the results dashboard in the browser, showing all the tests for
325 removed from the TestExpectations file and allowing the user to manually confirm the 324 lines removed from the TestExpectations file, allowing the user to
326 results. 325 manually confirm the results.
327 """ 326 """
328 removed_test_names = ','.join(x.name for x in self._expectations_to_remo ve()) 327 url = self._flakiness_dashboard_url()
329 url = FlakyTests.FLAKINESS_DASHBOARD_URL % removed_test_names
330
331 _log.info('Opening results dashboard: ' + url) 328 _log.info('Opening results dashboard: ' + url)
332 self._browser.open(url) 329 self._browser.open(url)
333 330
334 def write_test_expectations(self, test_expectations, test_expectations_file) : 331 def write_test_expectations(self, test_expectations, test_expectations_file) :
335 """Writes the given TestExpectations object to the filesystem. 332 """Writes the given TestExpectations object to the filesystem.
336 333
337 Args: 334 Args:
338 test_expectations: The TestExpectations object to write. 335 test_expectations: The TestExpectations object to write.
339 test_expectations_file: The full file path of the Blink 336 test_expectations_file: The full file path of the Blink
340 TestExpectations file. This file will be overwritten. 337 TestExpectations file. This file will be overwritten.
341 """ 338 """
342 self._host.filesystem.write_text_file( 339 self._host.filesystem.write_text_file(
343 test_expectations_file, 340 test_expectations_file,
344 TestExpectations.list_to_string(test_expectations, reconstitute_only _these=[])) 341 TestExpectations.list_to_string(test_expectations, reconstitute_only _these=[]))
342
343 def print_suggested_commit_description(self):
344 """Prints the body of a suggested CL description after removing some lin es."""
345 dashboard_url = self._flakiness_dashboard_url()
346 bugs = ','.join(self._bug_numbers())
347 message = ('Remove flaky TestExpectations for tests which appear non-fla ky recently.\n\n'
348 'This change was made by the update-test-expectations script. \n\n'
349 'Recent test results history:\n%s\n\n'
350 'BUG=%s') % (dashboard_url, bugs)
351 _log.info('Suggested commit description:\n' + message)
352
353 def _flakiness_dashboard_url(self):
354 removed_test_names = ','.join(x.name for x in self._expectations_to_remo ve())
355 return FlakyTests.FLAKINESS_DASHBOARD_URL % removed_test_names
356
357 def _bug_numbers(self):
358 """Returns the list of all bug numbers affected by this change."""
359 numbers = []
360 for line in self._expectations_to_remove():
361 for bug in line.bugs:
362 if bug.startswith(CHROMIUM_BUG_PREFIX):
363 numbers.append(bug[len(CHROMIUM_BUG_PREFIX):])
364 return sorted(numbers)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698