402 if os.path.exists(self._errpath): |
402 if os.path.exists(self._errpath): |
403 os.remove(self._errpath) |
403 os.remove(self._errpath) |
404 |
404 |
405 def run(self, result): |
405 def run(self, result): |
406 result.startTest(self) |
406 result.startTest(self) |
407 starttime = time.time() |
407 interrupted = False |
408 try: |
408 try: |
409 try: |
409 try: |
410 self.setUp() |
410 self.setUp() |
411 except (KeyboardInterrupt, SystemExit): |
411 except (KeyboardInterrupt, SystemExit): |
|
412 interrupted = True |
412 raise |
413 raise |
413 except Exception: |
414 except Exception: |
414 result.addError(self, sys.exc_info()) |
415 result.addError(self, sys.exc_info()) |
415 return |
416 return |
416 |
417 |
417 success = False |
418 success = False |
418 try: |
419 try: |
419 self.runTest() |
420 self.runTest() |
420 except KeyboardInterrupt: |
421 except KeyboardInterrupt: |
421 duration = time.time() - starttime |
422 interrupted = True |
422 log('INTERRUPTED: %s (after %d seconds)' % (self.name, |
|
423 duration)) |
|
424 self._runner.times.append((self.name, duration)) |
|
425 raise |
423 raise |
426 except SkipTest, e: |
424 except SkipTest, e: |
427 result.addSkip(self, str(e)) |
425 result.addSkip(self, str(e)) |
428 except IgnoreTest, e: |
426 except IgnoreTest, e: |
429 result.addIgnore(self, str(e)) |
427 result.addIgnore(self, str(e)) |
438 except Exception: |
436 except Exception: |
439 result.addError(self, sys.exc_info()) |
437 result.addError(self, sys.exc_info()) |
440 else: |
438 else: |
441 success = True |
439 success = True |
442 |
440 |
443 self._runner.times.append((self.name, time.time() - starttime)) |
|
444 |
|
445 try: |
441 try: |
446 self.tearDown() |
442 self.tearDown() |
447 except (KeyboardInterrupt, SystemExit): |
443 except (KeyboardInterrupt, SystemExit): |
|
444 interrupted = True |
448 raise |
445 raise |
449 except Exception: |
446 except Exception: |
450 result.addError(self, sys.exc_info()) |
447 result.addError(self, sys.exc_info()) |
451 success = False |
448 success = False |
452 |
449 |
453 if success: |
450 if success: |
454 result.addSuccess(self) |
451 result.addSuccess(self) |
455 finally: |
452 finally: |
456 result.stopTest(self) |
453 result.stopTest(self, interrupted=interrupted) |
457 |
454 |
458 def runTest(self): |
455 def runTest(self): |
459 """Run this test instance. |
456 """Run this test instance. |
460 |
457 |
461 This will return a tuple describing the result of the test. |
458 This will return a tuple describing the result of the test. |
1069 # We have a custom "warned" result that isn't present in any Python |
1066 # We have a custom "warned" result that isn't present in any Python |
1070 # unittest implementation. It is very similar to failed. It may make |
1067 # unittest implementation. It is very similar to failed. It may make |
1071 # sense to map it into fail some day. |
1068 # sense to map it into fail some day. |
1072 self.warned = [] |
1069 self.warned = [] |
1073 |
1070 |
|
1071 self.times = [] |
|
1072 self._started = {} |
|
1073 |
1074 def addFailure(self, test, reason): |
1074 def addFailure(self, test, reason): |
1075 self.failures.append((test, reason)) |
1075 self.failures.append((test, reason)) |
1076 |
1076 |
1077 if self._options.first: |
1077 if self._options.first: |
1078 self.stop() |
1078 self.stop() |
1111 if self.showAll: |
1111 if self.showAll: |
1112 self.stream.writeln('warned %s' % reason) |
1112 self.stream.writeln('warned %s' % reason) |
1113 else: |
1113 else: |
1114 self.stream.write('~') |
1114 self.stream.write('~') |
1115 self.stream.flush() |
1115 self.stream.flush() |
|
1116 |
|
1117 def startTest(self, test): |
|
1118 super(TestResult, self).startTest(test) |
|
1119 |
|
1120 self._started[test.name] = time.time() |
|
1121 |
|
1122 def stopTest(self, test, interrupted=False): |
|
1123 super(TestResult, self).stopTest(test) |
|
1124 |
|
1125 self.times.append((test.name, time.time() - self._started[test.name])) |
|
1126 del self._started[test.name] |
|
1127 |
|
1128 if interrupted: |
|
1129 self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % ( |
|
1130 test.name, self.times[-1][1])) |
1116 |
1131 |
1117 class TestSuite(unittest.TestSuite): |
1132 class TestSuite(unittest.TestSuite): |
1118 """Custom unitest TestSuite that knows how to execute concurrently.""" |
1133 """Custom unitest TestSuite that knows how to execute concurrently.""" |
1119 |
1134 |
1120 def __init__(self, runner, *args, **kwargs): |
1135 def __init__(self, runner, *args, **kwargs): |
1167 skipped + ignored, warned, failed)) |
1182 skipped + ignored, warned, failed)) |
1168 if failed: |
1183 if failed: |
1169 self.stream.writeln('python hash seed: %s' % |
1184 self.stream.writeln('python hash seed: %s' % |
1170 os.environ['PYTHONHASHSEED']) |
1185 os.environ['PYTHONHASHSEED']) |
1171 if self._runner.options.time: |
1186 if self._runner.options.time: |
1172 self.printtimes() |
1187 self.printtimes(result.times) |
1173 |
1188 |
1174 def printtimes(self): |
1189 def printtimes(self, times): |
1175 self.stream.writeln('# Producing time report') |
1190 self.stream.writeln('# Producing time report') |
1176 self._runner.times.sort(key=lambda t: (t[1], t[0]), reverse=True) |
1191 times.sort(key=lambda t: (t[1], t[0]), reverse=True) |
1177 cols = '%7.3f %s' |
1192 cols = '%7.3f %s' |
1178 self.stream.writeln('%-7s %s' % ('Time', 'Test')) |
1193 self.stream.writeln('%-7s %s' % ('Time', 'Test')) |
1179 for test, timetaken in self._runner.times: |
1194 for test, timetaken in times: |
1180 self.stream.writeln(cols % (timetaken, test)) |
1195 self.stream.writeln(cols % (timetaken, test)) |
1181 |
1196 |
1182 class TestRunner(object): |
1197 class TestRunner(object): |
1183 """Holds context for executing tests. |
1198 """Holds context for executing tests. |
1184 |
1199 |
1207 self.inst = None |
1222 self.inst = None |
1208 self.bindir = None |
1223 self.bindir = None |
1209 self.tmpbinddir = None |
1224 self.tmpbinddir = None |
1210 self.pythondir = None |
1225 self.pythondir = None |
1211 self.coveragefile = None |
1226 self.coveragefile = None |
1212 self.times = [] # Holds execution times of tests. |
|
1213 self.abort = [False] |
1227 self.abort = [False] |
1214 self._createdfiles = [] |
1228 self._createdfiles = [] |
1215 self._hgpath = None |
1229 self._hgpath = None |
1216 |
1230 |
1217 def run(self, args, parser=None): |
1231 def run(self, args, parser=None): |