579 killdaemons(entry) |
579 killdaemons(entry) |
580 |
580 |
581 if self._threadtmp and not self._options.keep_tmpdir: |
581 if self._threadtmp and not self._options.keep_tmpdir: |
582 shutil.rmtree(self._threadtmp, True) |
582 shutil.rmtree(self._threadtmp, True) |
583 |
583 |
584 def run(self, result): |
584 def run(self): |
585 if not os.path.exists(self._path): |
585 if not os.path.exists(self._path): |
586 result.skipped = True |
|
587 return self.skip("Doesn't exist") |
586 return self.skip("Doesn't exist") |
588 |
587 |
589 options = self._options |
588 options = self._options |
590 if not (options.whitelisted and self._test in options.whitelisted): |
589 if not (options.whitelisted and self._test in options.whitelisted): |
591 if options.blacklist and self._test in options.blacklist: |
590 if options.blacklist and self._test in options.blacklist: |
592 result.skipped = True |
|
593 return self.skip('blacklisted') |
591 return self.skip('blacklisted') |
594 |
592 |
595 if options.retest and not os.path.exists('%s.err' % self._test): |
593 if options.retest and not os.path.exists('%s.err' % self._test): |
596 return self.ignore('not retesting') |
594 return self.ignore('not retesting') |
597 |
595 |
618 env = self._getenv(testtmp, port) |
616 env = self._getenv(testtmp, port) |
619 self._daemonpids.append(env['DAEMON_PIDS']) |
617 self._daemonpids.append(env['DAEMON_PIDS']) |
620 createhgrc(env['HGRCPATH'], options) |
618 createhgrc(env['HGRCPATH'], options) |
621 |
619 |
622 starttime = time.time() |
620 starttime = time.time() |
623 |
|
624 def updateduration(): |
|
625 result.duration = time.time() - starttime |
|
626 |
|
627 try: |
621 try: |
628 ret, out = self._run(testtmp, replacements, env) |
622 ret, out = self._run(testtmp, replacements, env) |
629 updateduration() |
623 duration = time.time() - starttime |
630 except KeyboardInterrupt: |
624 except KeyboardInterrupt: |
631 updateduration() |
625 duration = time.time() - starttime |
632 log('INTERRUPTED: %s (after %d seconds)' % (self._test, |
626 log('INTERRUPTED: %s (after %d seconds)' % (self._test, duration)) |
633 result.duration)) |
|
634 raise |
627 raise |
635 except Exception, e: |
628 except Exception, e: |
636 updateduration() |
|
637 return self.fail('Exception during execution: %s' % e, 255) |
629 return self.fail('Exception during execution: %s' % e, 255) |
638 |
630 |
639 killdaemons(env['DAEMON_PIDS']) |
631 killdaemons(env['DAEMON_PIDS']) |
640 |
632 |
641 if not options.keep_tmpdir: |
633 if not options.keep_tmpdir: |
643 |
635 |
644 def describe(ret): |
636 def describe(ret): |
645 if ret < 0: |
637 if ret < 0: |
646 return 'killed by signal: %d' % -ret |
638 return 'killed by signal: %d' % -ret |
647 return 'returned error code %d' % ret |
639 return 'returned error code %d' % ret |
|
640 |
|
641 skipped = False |
648 |
642 |
649 if ret == SKIPPED_STATUS: |
643 if ret == SKIPPED_STATUS: |
650 if out is None: # Debug mode, nothing to parse. |
644 if out is None: # Debug mode, nothing to parse. |
651 missing = ['unknown'] |
645 missing = ['unknown'] |
652 failed = None |
646 failed = None |
658 |
652 |
659 if failed: |
653 if failed: |
660 res = self.fail('hg have failed checking for %s' % failed[-1], |
654 res = self.fail('hg have failed checking for %s' % failed[-1], |
661 ret) |
655 ret) |
662 else: |
656 else: |
663 result.skipped = True |
657 skipped = True |
664 res = self.skip(missing[-1]) |
658 res = self.skip(missing[-1]) |
665 elif ret == 'timeout': |
659 elif ret == 'timeout': |
666 res = self.fail('timed out', ret) |
660 res = self.fail('timed out', ret) |
667 elif out != self._refout: |
661 elif out != self._refout: |
668 info = {} |
662 info = {} |
687 elif ret: |
681 elif ret: |
688 res = self.fail(describe(ret), ret) |
682 res = self.fail(describe(ret), ret) |
689 else: |
683 else: |
690 res = self.success() |
684 res = self.success() |
691 |
685 |
692 if (ret != 0 or out != self._refout) and not result.skipped \ |
686 if (ret != 0 or out != self._refout) and not skipped \ |
693 and not options.debug: |
687 and not options.debug: |
694 f = open(self._errpath, 'wb') |
688 f = open(self._errpath, 'wb') |
695 for line in out: |
689 for line in out: |
696 f.write(line) |
690 f.write(line) |
697 f.close() |
691 f.close() |
701 if not options.verbose: |
695 if not options.verbose: |
702 iolock.acquire() |
696 iolock.acquire() |
703 sys.stdout.write(res[0]) |
697 sys.stdout.write(res[0]) |
704 sys.stdout.flush() |
698 sys.stdout.flush() |
705 iolock.release() |
699 iolock.release() |
|
700 |
|
701 times.append((self._test, duration)) |
706 |
702 |
707 return res |
703 return res |
708 |
704 |
709 def _run(self, testtmp, replacements, env): |
705 def _run(self, testtmp, replacements, env): |
710 raise NotImplemented('Subclasses must implement Test.run()') |
706 raise NotImplemented('Subclasses must implement Test.run()') |
792 |
788 |
793 return 's', self._test, msg |
789 return 's', self._test, msg |
794 |
790 |
795 def ignore(self, msg): |
791 def ignore(self, msg): |
796 return 'i', self._test, msg |
792 return 'i', self._test, msg |
797 |
|
798 class TestResult(object): |
|
799 """Holds the result of a test execution.""" |
|
800 |
|
801 def __init__(self): |
|
802 self.duration = None |
|
803 self.skipped = False |
|
804 |
793 |
805 class PythonTest(Test): |
794 class PythonTest(Test): |
806 """A Python-based test.""" |
795 """A Python-based test.""" |
807 def _run(self, testtmp, replacements, env): |
796 def _run(self, testtmp, replacements, env): |
808 py3kswitch = self._options.py3k_warnings and ' -3' or '' |
797 py3kswitch = self._options.py3k_warnings and ' -3' or '' |
1156 return skip("unknown test type") |
1145 return skip("unknown test type") |
1157 |
1146 |
1158 vlog("# Test", test) |
1147 vlog("# Test", test) |
1159 |
1148 |
1160 t = runner(test, testpath, options, count, ref, err) |
1149 t = runner(test, testpath, options, count, ref, err) |
1161 res = TestResult() |
1150 result = t.run() |
1162 result = t.run(res) |
|
1163 |
|
1164 times.append((test, res.duration)) |
|
1165 |
1151 |
1166 t.cleanup() |
1152 t.cleanup() |
1167 |
1153 |
1168 return result |
1154 return result |
1169 |
1155 |