Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2008 the V8 project authors. All rights reserved. | 3 # Copyright 2008 the V8 project authors. All rights reserved. |
| 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 are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 try: | 90 try: |
| 91 self.RunSingle() | 91 self.RunSingle() |
| 92 # Wait for the remaining threads | 92 # Wait for the remaining threads |
| 93 for thread in threads: | 93 for thread in threads: |
| 94 # Use a timeout so that signals (ctrl-c) will be processed. | 94 # Use a timeout so that signals (ctrl-c) will be processed. |
| 95 thread.join(timeout=10000000) | 95 thread.join(timeout=10000000) |
| 96 except Exception, e: | 96 except Exception, e: |
| 97 # If there's an exception we schedule an interruption for any | 97 # If there's an exception we schedule an interruption for any |
| 98 # remaining threads. | 98 # remaining threads. |
| 99 self.terminate = True | 99 self.terminate = True |
| 100 print e | 100 # ...and then reraise the exception to bail out |
| 101 return False | 101 raise |
| 102 self.Done() | 102 self.Done() |
| 103 return not self.failed | 103 return not self.failed |
| 104 | 104 |
| 105 def RunSingle(self): | 105 def RunSingle(self): |
| 106 while not self.terminate: | 106 while not self.terminate: |
| 107 try: | 107 try: |
| 108 test = self.queue.get_nowait() | 108 test = self.queue.get_nowait() |
| 109 except Empty: | 109 except Empty: |
| 110 return | 110 return |
| 111 case = test.case | 111 case = test.case |
| 112 self.lock.acquire() | 112 self.lock.acquire() |
| 113 self.AboutToRun(case) | 113 self.AboutToRun(case) |
| 114 self.lock.release() | 114 self.lock.release() |
| 115 try: | 115 try: |
| 116 start = time.time() | |
| 116 output = case.Run() | 117 output = case.Run() |
| 118 case.duration = (time.time() - start) | |
| 117 except IOError, e: | 119 except IOError, e: |
| 118 assert self.terminate | 120 assert self.terminate |
| 119 return | 121 return |
| 120 if self.terminate: | 122 if self.terminate: |
| 121 return | 123 return |
| 122 self.lock.acquire() | 124 self.lock.acquire() |
| 123 if output.UnexpectedOutput(): | 125 if output.UnexpectedOutput(): |
| 124 self.failed.append(output) | 126 self.failed.append(output) |
| 125 else: | 127 else: |
| 126 self.succeeded += 1 | 128 self.succeeded += 1 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 else: | 166 else: |
| 165 print | 167 print |
| 166 print "===" | 168 print "===" |
| 167 print "=== %i tests failed" % len(self.failed) | 169 print "=== %i tests failed" % len(self.failed) |
| 168 print "===" | 170 print "===" |
| 169 | 171 |
| 170 | 172 |
| 171 class VerboseProgressIndicator(SimpleProgressIndicator): | 173 class VerboseProgressIndicator(SimpleProgressIndicator): |
| 172 | 174 |
| 173 def AboutToRun(self, case): | 175 def AboutToRun(self, case): |
| 174 print '%s:' % case.GetLabel(), | 176 print 'Starting %s...' % case.GetLabel() |
| 175 sys.stdout.flush() | 177 sys.stdout.flush() |
| 176 | 178 |
| 177 def HasRun(self, output): | 179 def HasRun(self, output): |
| 178 if output.UnexpectedOutput(): | 180 if output.UnexpectedOutput(): |
| 179 print "FAIL" | 181 outcome = 'FAIL' |
| 180 else: | 182 else: |
| 181 print "pass" | 183 outcome = 'pass' |
| 184 print 'Done running %s: %s' % (output.test.GetLabel(), outcome) | |
| 182 | 185 |
| 183 | 186 |
| 184 class DotsProgressIndicator(SimpleProgressIndicator): | 187 class DotsProgressIndicator(SimpleProgressIndicator): |
| 185 | 188 |
| 186 def AboutToRun(self, case): | 189 def AboutToRun(self, case): |
| 187 pass | 190 pass |
| 188 | 191 |
| 189 def HasRun(self, output): | 192 def HasRun(self, output): |
| 190 total = self.succeeded + len(self.failed) | 193 total = self.succeeded + len(self.failed) |
| 191 if (total > 1) and (total % 50 == 1): | 194 if (total > 1) and (total % 50 == 1): |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 self.stdout = stdout | 303 self.stdout = stdout |
| 301 self.stderr = stderr | 304 self.stderr = stderr |
| 302 | 305 |
| 303 | 306 |
| 304 class TestCase(object): | 307 class TestCase(object): |
| 305 | 308 |
| 306 def __init__(self, context, path): | 309 def __init__(self, context, path): |
| 307 self.path = path | 310 self.path = path |
| 308 self.context = context | 311 self.context = context |
| 309 self.failed = None | 312 self.failed = None |
| 313 self.duration = None | |
| 310 | 314 |
| 311 def IsNegative(self): | 315 def IsNegative(self): |
| 312 return False | 316 return False |
| 313 | 317 |
| 318 def CompareTime(self, other): | |
|
Dean McNamee
2008/10/01 08:58:39
Can't you just use cmp() or something?
| |
| 319 diff = other.duration - self.duration | |
| 320 if diff == 0: return 0 | |
| 321 elif diff < 0: return -1 | |
| 322 else: return 1 | |
| 323 | |
| 314 def DidFail(self, output): | 324 def DidFail(self, output): |
| 315 if self.failed is None: | 325 if self.failed is None: |
| 316 self.failed = self.IsFailureOutput(output) | 326 self.failed = self.IsFailureOutput(output) |
| 317 return self.failed | 327 return self.failed |
| 318 | 328 |
| 319 def IsFailureOutput(self, output): | 329 def IsFailureOutput(self, output): |
| 320 return output.exit_code != 0 | 330 return output.exit_code != 0 |
| 321 | 331 |
| 322 def GetSource(self): | 332 def GetSource(self): |
| 323 return "(no source available)" | 333 return "(no source available)" |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1014 default='none') | 1024 default='none') |
| 1015 result.add_option("--simulator", help="Run tests with architecture simulator", | 1025 result.add_option("--simulator", help="Run tests with architecture simulator", |
| 1016 default='none') | 1026 default='none') |
| 1017 result.add_option("--special-command", default=None) | 1027 result.add_option("--special-command", default=None) |
| 1018 result.add_option("--cat", help="Print the source of the tests", | 1028 result.add_option("--cat", help="Print the source of the tests", |
| 1019 default=False, action="store_true") | 1029 default=False, action="store_true") |
| 1020 result.add_option("--warn-unused", help="Report unused rules", | 1030 result.add_option("--warn-unused", help="Report unused rules", |
| 1021 default=False, action="store_true") | 1031 default=False, action="store_true") |
| 1022 result.add_option("-j", help="The number of parallel tasks to run", | 1032 result.add_option("-j", help="The number of parallel tasks to run", |
| 1023 default=1, type="int") | 1033 default=1, type="int") |
| 1034 result.add_option("--time", help="Print timing information after running", | |
| 1035 default=False, action="store_true") | |
| 1024 return result | 1036 return result |
| 1025 | 1037 |
| 1026 | 1038 |
| 1027 def ProcessOptions(options): | 1039 def ProcessOptions(options): |
| 1028 global VERBOSE | 1040 global VERBOSE |
| 1029 VERBOSE = options.verbose | 1041 VERBOSE = options.verbose |
| 1030 options.mode = options.mode.split(',') | 1042 options.mode = options.mode.split(',') |
| 1031 for mode in options.mode: | 1043 for mode in options.mode: |
| 1032 if not mode in ['debug', 'release']: | 1044 if not mode in ['debug', 'release']: |
| 1033 print "Unknown mode %s" % mode | 1045 print "Unknown mode %s" % mode |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1112 | 1124 |
| 1113 BUILT_IN_TESTS = ['mjsunit', 'cctest', 'message'] | 1125 BUILT_IN_TESTS = ['mjsunit', 'cctest', 'message'] |
| 1114 | 1126 |
| 1115 | 1127 |
| 1116 def GetSuites(test_root): | 1128 def GetSuites(test_root): |
| 1117 def IsSuite(path): | 1129 def IsSuite(path): |
| 1118 return isdir(path) and exists(join(path, 'testcfg.py')) | 1130 return isdir(path) and exists(join(path, 'testcfg.py')) |
| 1119 return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ] | 1131 return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ] |
| 1120 | 1132 |
| 1121 | 1133 |
| 1134 def FormatTime(d): | |
| 1135 millis = round(d * 1000) % 1000 | |
| 1136 return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) | |
| 1137 | |
| 1138 | |
| 1122 def Main(): | 1139 def Main(): |
| 1123 parser = BuildOptions() | 1140 parser = BuildOptions() |
| 1124 (options, args) = parser.parse_args() | 1141 (options, args) = parser.parse_args() |
| 1125 if not ProcessOptions(options): | 1142 if not ProcessOptions(options): |
| 1126 parser.print_help() | 1143 parser.print_help() |
| 1127 return 1 | 1144 return 1 |
| 1128 | 1145 |
| 1129 workspace = abspath(join(dirname(sys.argv[0]), '..')) | 1146 workspace = abspath(join(dirname(sys.argv[0]), '..')) |
| 1130 suites = GetSuites(join(workspace, 'test')) | 1147 suites = GetSuites(join(workspace, 'test')) |
| 1131 repositories = [TestRepository(join(workspace, 'test', name)) for name in suit es] | 1148 repositories = [TestRepository(join(workspace, 'test', name)) for name in suit es] |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 print "--- end source: %s ---" % test.GetLabel() | 1215 print "--- end source: %s ---" % test.GetLabel() |
| 1199 return 0 | 1216 return 0 |
| 1200 | 1217 |
| 1201 if options.warn_unused: | 1218 if options.warn_unused: |
| 1202 for rule in globally_unused_rules: | 1219 for rule in globally_unused_rules: |
| 1203 print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path] ) | 1220 print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path] ) |
| 1204 | 1221 |
| 1205 if options.report: | 1222 if options.report: |
| 1206 PrintReport(all_cases) | 1223 PrintReport(all_cases) |
| 1207 | 1224 |
| 1225 result = None | |
| 1208 if len(all_cases) == 0: | 1226 if len(all_cases) == 0: |
| 1209 print "No tests to run." | 1227 print "No tests to run." |
| 1210 return 0 | 1228 return 0 |
| 1211 else: | 1229 else: |
| 1212 try: | 1230 try: |
| 1231 start = time.time() | |
| 1213 if RunTestCases(all_cases, options.progress, options.j): | 1232 if RunTestCases(all_cases, options.progress, options.j): |
| 1214 return 0 | 1233 result = 0 |
| 1215 else: | 1234 else: |
| 1216 return 1 | 1235 result = 1 |
| 1236 duration = time.time() - start | |
| 1217 except KeyboardInterrupt: | 1237 except KeyboardInterrupt: |
| 1218 print "Interrupted" | 1238 print "Interrupted" |
| 1219 return 1 | 1239 return 1 |
| 1220 | 1240 |
| 1241 if options.time: | |
| 1242 # Write the times to stderr to make it easy to separate from the | |
| 1243 # test output. | |
| 1244 print | |
| 1245 sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration)) | |
| 1246 timed_tests = [ t.case for t in all_cases if not t.case.duration is None ] | |
| 1247 timed_tests.sort(lambda a, b: a.CompareTime(b)) | |
| 1248 index = 1 | |
| 1249 for entry in timed_tests: | |
| 1250 t = FormatTime(entry.duration) | |
| 1251 sys.stderr.write("%3i (%s) %s\n" % (index, t, entry.GetLabel())) | |
| 1252 index += 1 | |
| 1253 | |
| 1254 return result | |
| 1255 | |
| 1221 | 1256 |
| 1222 if __name__ == '__main__': | 1257 if __name__ == '__main__': |
| 1223 sys.exit(Main()) | 1258 sys.exit(Main()) |
| OLD | NEW |