OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Scripts to run a test, grab the failures and trace them.""" | 6 """Scripts to run a test, grab the failures and trace them.""" |
7 | 7 |
| 8 import json |
8 import os | 9 import os |
9 import subprocess | 10 import subprocess |
10 import sys | 11 import sys |
| 12 import tempfile |
11 | 13 |
12 import run_test_cases | 14 import run_test_cases |
13 | 15 |
14 | 16 |
15 if sys.platform == 'win32': | 17 if sys.platform == 'win32': |
16 import msvcrt # pylint: disable=F0401 | 18 import msvcrt # pylint: disable=F0401 |
17 | 19 |
18 def get_keyboard(): | 20 def get_keyboard(): |
19 """Returns a letter from the keyboard if any. | 21 """Returns a letter from the keyboard if any. |
20 | 22 |
(...skipping 20 matching lines...) Expand all Loading... |
41 """Traces a single test case and merges the result back into .isolate.""" | 43 """Traces a single test case and merges the result back into .isolate.""" |
42 subprocess.call( | 44 subprocess.call( |
43 [ | 45 [ |
44 sys.executable, 'isolate.py', 'trace', '-r', result, | 46 sys.executable, 'isolate.py', 'trace', '-r', result, |
45 '--', '--gtest_filter=' + test, | 47 '--', '--gtest_filter=' + test, |
46 ]) | 48 ]) |
47 return not subprocess.call( | 49 return not subprocess.call( |
48 [sys.executable, 'isolate.py', 'merge', '-r', result]) | 50 [sys.executable, 'isolate.py', 'merge', '-r', result]) |
49 | 51 |
50 | 52 |
| 53 def run_all(result): |
| 54 """Runs all the tests. Returns the tests that failed or None on failure. |
| 55 |
| 56 Assumes run_test_cases.py is implicitly called. |
| 57 """ |
| 58 handle, result_file = tempfile.mkstemp(prefix='run_test_cases') |
| 59 os.close(handle) |
| 60 env = os.environ.copy() |
| 61 env['RUN_TEST_CASES_RESULT_FILE'] = result_file |
| 62 subprocess.call( |
| 63 [sys.executable, 'isolate.py', 'run', '-r', result], env=env) |
| 64 if not os.path.isfile(result_file): |
| 65 print >> sys.stderr, 'Failed to find %s' % result_file |
| 66 return None |
| 67 with open(result_file) as f: |
| 68 data = json.load(f) |
| 69 os.remove(result_file) |
| 70 return [ |
| 71 test for test, runs in data.iteritems() |
| 72 if not any(not run['returncode'] for run in runs) |
| 73 ] |
| 74 |
| 75 |
51 def run(result, test): | 76 def run(result, test): |
52 """Runs a single test case in an isolated environment. | 77 """Runs a single test case in an isolated environment. |
53 | 78 |
54 Returns True if the test passed. | 79 Returns True if the test passed. |
55 """ | 80 """ |
56 return not subprocess.call([ | 81 return not subprocess.call([ |
57 sys.executable, 'isolate.py', 'run', '-r', result, | 82 sys.executable, 'isolate.py', 'run', '-r', result, |
58 '--', '--gtest_filter=' + test | 83 '--', '--gtest_filter=' + test, |
59 ]) | 84 ]) |
60 | 85 |
61 | 86 |
62 def diff_and_commit(test): | 87 def diff_and_commit(test): |
63 """Prints the diff and commit.""" | 88 """Prints the diff and commit.""" |
64 subprocess.call(['git', 'diff']) | 89 subprocess.call(['git', 'diff']) |
65 subprocess.call(['git', 'commit', '-a', '-m', test]) | 90 subprocess.call(['git', 'commit', '-a', '-m', test]) |
66 | 91 |
67 | 92 |
68 def trace_and_verify(result, test): | 93 def trace_and_verify(result, test): |
69 """Traces a test case, updates .isolate and makes sure it passes afterward. | 94 """Traces a test case, updates .isolate and makes sure it passes afterward. |
70 | 95 |
71 Return None if the test was already passing, True on success. | 96 Return None if the test was already passing, True on success. |
72 """ | 97 """ |
73 trace_and_merge(result, test) | 98 trace_and_merge(result, test) |
74 diff_and_commit(test) | 99 diff_and_commit(test) |
75 return run(result, test) | 100 return run(result, test) |
76 | 101 |
77 | 102 |
78 def run_all(result, executable): | 103 def fix_all(result): |
79 """Runs all the test cases in a gtest executable and trace the failing tests. | 104 """Runs all the test cases in a gtest executable and trace the failing tests. |
80 | 105 |
81 Then make sure the test passes afterward. | 106 Returns True on success. |
| 107 |
| 108 Makes sure the test passes afterward. |
82 """ | 109 """ |
83 test_cases = run_test_cases.list_test_cases( | 110 # These could have adverse side-effects. |
84 executable, 0, 0, False, False, False) | 111 # TODO(maruel): Be more intelligent about it, for now be safe. |
85 print 'Found %d test cases.' % len(test_cases) | 112 for i in run_test_cases.KNOWN_GTEST_ENV_VARS: |
| 113 if i in os.environ: |
| 114 print >> 'Please unset %s' % i |
| 115 return False |
| 116 |
| 117 test_cases = run_all(result) |
| 118 if test_cases is None: |
| 119 return False |
| 120 |
| 121 print '\nFound %d broken test cases.' % len(test_cases) |
| 122 if not test_cases: |
| 123 return True |
| 124 |
86 failures = [] | 125 failures = [] |
87 fixed_tests = [] | 126 fixed_tests = [] |
88 try: | 127 try: |
89 for index, test_case in enumerate(test_cases): | 128 for index, test_case in enumerate(test_cases): |
90 if get_keyboard(): | 129 if get_keyboard(): |
91 # Return early. | 130 # Return early. |
92 return True | 131 return True |
93 | 132 |
94 try: | 133 try: |
95 if run(result, test_case): | 134 if run(result, test_case): |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 executable += '.exe' | 167 executable += '.exe' |
129 if not os.path.isfile(executable): | 168 if not os.path.isfile(executable): |
130 print >> sys.stderr, ( | 169 print >> sys.stderr, ( |
131 '%s doesn\'t exist, please build %s_run' % (executable, basename)) | 170 '%s doesn\'t exist, please build %s_run' % (executable, basename)) |
132 return 1 | 171 return 1 |
133 if not os.path.isfile(result): | 172 if not os.path.isfile(result): |
134 print >> sys.stderr, ( | 173 print >> sys.stderr, ( |
135 '%s doesn\'t exist, please build %s_run' % (result, basename)) | 174 '%s doesn\'t exist, please build %s_run' % (result, basename)) |
136 return 1 | 175 return 1 |
137 | 176 |
138 return not run_all(result, executable) | 177 return not fix_all(result) |
139 | 178 |
140 | 179 |
141 if __name__ == '__main__': | 180 if __name__ == '__main__': |
142 sys.exit(main()) | 181 sys.exit(main()) |
OLD | NEW |