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

Side by Side Diff: tools/flakiness/is_flaky_test.py

Issue 563243002: Implemented a flaky test runner for auto-bisect bot. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review Created 6 years, 3 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Runs a test repeatedly to measure its flakiness. The return code is non-zero
7 if the failure rate is higher than the specified threshold, but is not 100%."""
8
9 import argparse
10 import subprocess
11 import sys
12 import time
13
14 def load_options():
15 parser = argparse.ArgumentParser(description=__doc__)
16 parser.add_argument('--retries', default=1000, type=int,
17 help='Number of test retries to measure flakiness.')
18 parser.add_argument('--threshold', default=0.05, type=float,
19 help='Minimum flakiness level at which test is '
20 'considered flaky.')
21 parser.add_argument('--jobs', '-j', type=int, default=1,
22 help='Number of parallel jobs to run tests.')
23 parser.add_argument('command', nargs='+', help='Command to run test.')
24 return parser.parse_args()
25
26
27 def process_finished(running, num_passed, num_failed):
28 finished = [p for p in running if p.poll() is not None]
29 running[:] = [p for p in running if p.poll() is None]
qyearsley 2014/09/15 16:02:28 What's the difference between using slice assignme
Sergiy Byelozyorov 2014/09/15 16:27:29 This is to modify the value outside of the functio
30 num_passed += len([p for p in finished if p.returncode == 0])
31 num_failed += len([p for p in finished if p.returncode != 0])
32 print '%d processed finished. Total passed: %d. Total failed: %d' % (
33 len(finished), num_passed, num_failed)
34 return num_passed, num_failed
35
36
37 def main():
38 options = load_options()
39 num_passed = num_failed = 0
40 running = []
41
42 # Start all retries, while limiting total number of running processes.
43 for attempt in range(options.retries):
44 print 'Starting retry %d out of %d\n' % (attempt + 1, options.retries)
45 running.append(subprocess.Popen(options.command, stdout=subprocess.PIPE,
46 stderr=subprocess.STDOUT))
47 while len(running) >= options.jobs:
48 print 'Waiting for previous retries to finish before starting new ones...'
49 time.sleep(0.1)
50 num_passed, num_failed = process_finished(running, num_passed, num_failed)
51
52
53 # Wait for the remaining retries to finish.
54 print 'Waiting for the remaining retries to finish...'
55 for process in running:
56 process.wait()
57
58 num_passed, num_failed = process_finished(running, num_passed, num_failed)
59 if num_passed == 0 or num_failed == 0:
60 flakiness = 0
61 else:
62 flakiness = num_failed / (options.retries * 1.0)
qyearsley 2014/09/15 16:02:28 Equivalently, float(options.retries) would do the
Sergiy Byelozyorov 2014/09/15 16:27:29 Done.
63
64 print 'Flakiness is %.2f' % flakiness
65 if flakiness > options.threshold:
66 return 1
67 else:
68 return 0
69
70
71 if __name__ == '__main__':
72 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698