OLD | NEW |
1 # Copyright (C) 2012 Google, Inc. | 1 # Copyright (C) 2012 Google, Inc. |
2 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) | 2 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) |
3 # | 3 # |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions | 5 # modification, are permitted provided that the following conditions |
6 # are met: | 6 # are met: |
7 # 1. Redistributions of source code must retain the above copyright | 7 # 1. Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # 2. Redistributions in binary form must reproduce the above copyright | 9 # 2. Redistributions in binary form must reproduce the above copyright |
10 # notice, this list of conditions and the following disclaimer in the | 10 # notice, this list of conditions and the following disclaimer in the |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 87 |
88 def skip(self, names, reason, bugid): | 88 def skip(self, names, reason, bugid): |
89 self.finder.skip(names, reason, bugid) | 89 self.finder.skip(names, reason, bugid) |
90 | 90 |
91 def _parse_args(self, argv): | 91 def _parse_args(self, argv): |
92 parser = optparse.OptionParser(usage='usage: %prog [options] [args...]') | 92 parser = optparse.OptionParser(usage='usage: %prog [options] [args...]') |
93 parser.add_option('-a', '--all', action='store_true', default=False, | 93 parser.add_option('-a', '--all', action='store_true', default=False, |
94 help='run all the tests') | 94 help='run all the tests') |
95 parser.add_option('-c', '--coverage', action='store_true', default=False
, | 95 parser.add_option('-c', '--coverage', action='store_true', default=False
, |
96 help='generate code coverage info') | 96 help='generate code coverage info') |
97 parser.add_option('-i', '--integration-tests', action='store_true', defa
ult=False, | |
98 help='run integration tests as well as unit tests'), | |
99 parser.add_option('-j', '--child-processes', action='store', type='int',
default=(1 if sys.platform == 'win32' else multiprocessing.cpu_count()), | 97 parser.add_option('-j', '--child-processes', action='store', type='int',
default=(1 if sys.platform == 'win32' else multiprocessing.cpu_count()), |
100 help='number of tests to run in parallel (default=%def
ault)') | 98 help='number of tests to run in parallel (default=%def
ault)') |
101 parser.add_option('-p', '--pass-through', action='store_true', default=F
alse, | 99 parser.add_option('-p', '--pass-through', action='store_true', default=F
alse, |
102 help='be debugger friendly by passing captured output
through to the system') | 100 help='be debugger friendly by passing captured output
through to the system') |
103 parser.add_option('-q', '--quiet', action='store_true', default=False, | 101 parser.add_option('-q', '--quiet', action='store_true', default=False, |
104 help='run quietly (errors, warnings, and progress only
)') | 102 help='run quietly (errors, warnings, and progress only
)') |
105 parser.add_option('-t', '--timing', action='store_true', default=False, | 103 parser.add_option('-t', '--timing', action='store_true', default=False, |
106 help='display per-test execution time (implies --verbo
se)') | 104 help='display per-test execution time (implies --verbo
se)') |
107 parser.add_option('-v', '--verbose', action='count', default=0, | 105 parser.add_option('-v', '--verbose', action='count', default=0, |
108 help='verbose output (specify once for individual test
results, twice for debug messages)') | 106 help='verbose output (specify once for individual test
results, twice for debug messages)') |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if not exit_code: | 157 if not exit_code: |
160 exit_code = self.executive.call(prefix_cmd + ['report', '--omit', 'w
ebkitpy/thirdparty/*,/usr/*,/Library/*'], cwd=script_dir, env=env) | 158 exit_code = self.executive.call(prefix_cmd + ['report', '--omit', 'w
ebkitpy/thirdparty/*,/usr/*,/Library/*'], cwd=script_dir, env=env) |
161 return (exit_code == 0) | 159 return (exit_code == 0) |
162 | 160 |
163 def _run_tests(self, names): | 161 def _run_tests(self, names): |
164 self.printer.write_update("Checking imports ...") | 162 self.printer.write_update("Checking imports ...") |
165 if not self._check_imports(names): | 163 if not self._check_imports(names): |
166 return False | 164 return False |
167 | 165 |
168 self.printer.write_update("Finding the individual test methods ...") | 166 self.printer.write_update("Finding the individual test methods ...") |
169 loader = _Loader() | 167 loader = unittest.TestLoader() |
170 parallel_tests = self._test_names(loader, names) | 168 tests = self._test_names(loader, names) |
171 | 169 |
172 self.printer.write_update("Running the tests ...") | 170 self.printer.write_update("Running the tests ...") |
173 self.printer.num_tests = len(parallel_tests) | 171 self.printer.num_tests = len(tests) |
174 start = time.time() | 172 start = time.time() |
175 test_runner = Runner(self.printer, loader, self.webkit_finder) | 173 test_runner = Runner(self.printer, loader, self.webkit_finder) |
176 test_runner.run(parallel_tests, self._options.child_processes) | 174 test_runner.run(tests, self._options.child_processes) |
177 | 175 |
178 self.printer.print_result(time.time() - start) | 176 self.printer.print_result(time.time() - start) |
179 | 177 |
180 return not self.printer.num_errors and not self.printer.num_failures | 178 return not self.printer.num_errors and not self.printer.num_failures |
181 | 179 |
182 def _check_imports(self, names): | 180 def _check_imports(self, names): |
183 for name in names: | 181 for name in names: |
184 if self.finder.is_module(name): | 182 if self.finder.is_module(name): |
185 # if we failed to load a name and it looks like a module, | 183 # if we failed to load a name and it looks like a module, |
186 # try importing it directly, because loadTestsFromName() | 184 # try importing it directly, because loadTestsFromName() |
187 # produces lousy error messages for bad modules. | 185 # produces lousy error messages for bad modules. |
188 try: | 186 try: |
189 __import__(name) | 187 __import__(name) |
190 except ImportError: | 188 except ImportError: |
191 _log.fatal('Failed to import %s:' % name) | 189 _log.fatal('Failed to import %s:' % name) |
192 self._log_exception() | 190 self._log_exception() |
193 return False | 191 return False |
194 return True | 192 return True |
195 | 193 |
196 def _test_names(self, loader, names): | 194 def _test_names(self, loader, names): |
197 parallel_test_method_prefixes = ['test_'] | 195 tests = [] |
198 if self._options.integration_tests: | |
199 parallel_test_method_prefixes.append('integration_test_') | |
200 | |
201 parallel_tests = [] | |
202 loader.test_method_prefixes = parallel_test_method_prefixes | |
203 for name in names: | 196 for name in names: |
204 parallel_tests.extend(self._all_test_names(loader.loadTestsFromName(
name, None))) | 197 tests.extend(self._all_test_names(loader.loadTestsFromName(name, Non
e))) |
205 | 198 return tests |
206 return parallel_tests | |
207 | 199 |
208 def _all_test_names(self, suite): | 200 def _all_test_names(self, suite): |
209 names = [] | 201 names = [] |
210 if hasattr(suite, '_tests'): | 202 if hasattr(suite, '_tests'): |
211 for t in suite._tests: | 203 for t in suite._tests: |
212 names.extend(self._all_test_names(t)) | 204 names.extend(self._all_test_names(t)) |
213 else: | 205 else: |
214 names.append(unit_test_name(suite)) | 206 names.append(unit_test_name(suite)) |
215 return names | 207 return names |
216 | 208 |
217 def _log_exception(self): | 209 def _log_exception(self): |
218 s = StringIO.StringIO() | 210 s = StringIO.StringIO() |
219 traceback.print_exc(file=s) | 211 traceback.print_exc(file=s) |
220 for l in s.buflist: | 212 for l in s.buflist: |
221 _log.error(' ' + l.rstrip()) | 213 _log.error(' ' + l.rstrip()) |
222 | 214 |
223 | 215 |
224 class _Loader(unittest.TestLoader): | |
225 test_method_prefixes = [] | |
226 | |
227 def getTestCaseNames(self, testCaseClass): | |
228 def isTestMethod(attrname, testCaseClass=testCaseClass): | |
229 if not hasattr(getattr(testCaseClass, attrname), '__call__'): | |
230 return False | |
231 return (any(attrname.startswith(prefix) for prefix in self.test_meth
od_prefixes)) | |
232 testFnNames = filter(isTestMethod, dir(testCaseClass)) | |
233 testFnNames.sort() | |
234 return testFnNames | |
235 | |
236 | 216 |
237 if __name__ == '__main__': | 217 if __name__ == '__main__': |
238 sys.exit(main()) | 218 sys.exit(main()) |
OLD | NEW |