351 |
351 |
352 abort is a flag that turns to True if test execution should be aborted. |
352 abort is a flag that turns to True if test execution should be aborted. |
353 It is consulted periodically during the execution of tests. |
353 It is consulted periodically during the execution of tests. |
354 """ |
354 """ |
355 |
355 |
356 self._path = path |
356 self.path = path |
357 self.name = os.path.basename(path) |
357 self.name = os.path.basename(path) |
358 self._testdir = os.path.dirname(path) |
358 self._testdir = os.path.dirname(path) |
359 self._errpath = os.path.join(self._testdir, '%s.err' % self.name) |
359 self.errpath = os.path.join(self._testdir, '%s.err' % self.name) |
360 |
360 |
361 self._options = options |
361 self._options = options |
362 self._count = count |
362 self._count = count |
363 self._threadtmp = tmpdir |
363 self._threadtmp = tmpdir |
364 self._abort = abort |
364 self._abort = abort |
399 except OSError, e: |
399 except OSError, e: |
400 if e.errno != errno.EEXIST: |
400 if e.errno != errno.EEXIST: |
401 raise |
401 raise |
402 |
402 |
403 self._testtmp = os.path.join(self._threadtmp, |
403 self._testtmp = os.path.join(self._threadtmp, |
404 os.path.basename(self._path)) |
404 os.path.basename(self.path)) |
405 os.mkdir(self._testtmp) |
405 os.mkdir(self._testtmp) |
406 |
406 |
407 # Remove any previous output files. |
407 # Remove any previous output files. |
408 if os.path.exists(self._errpath): |
408 if os.path.exists(self.errpath): |
409 os.remove(self._errpath) |
409 os.remove(self.errpath) |
410 |
410 |
411 def run(self, result): |
411 def run(self, result): |
412 result.startTest(self) |
412 result.startTest(self) |
413 interrupted = False |
413 interrupted = False |
414 try: |
414 try: |
461 def runTest(self): |
461 def runTest(self): |
462 """Run this test instance. |
462 """Run this test instance. |
463 |
463 |
464 This will return a tuple describing the result of the test. |
464 This will return a tuple describing the result of the test. |
465 """ |
465 """ |
466 if not os.path.exists(self._path): |
|
467 raise SkipTest("Doesn't exist") |
|
468 |
|
469 options = self._options |
466 options = self._options |
470 if not (options.whitelisted and self.name in options.whitelisted): |
|
471 if options.blacklist and self.name in options.blacklist: |
|
472 raise SkipTest('blacklisted') |
|
473 |
|
474 if options.retest and not os.path.exists('%s.err' % self.name): |
|
475 raise IgnoreTest('not retesting') |
|
476 |
|
477 if options.keywords: |
|
478 f = open(self.name) |
|
479 t = f.read().lower() + self.name.lower() |
|
480 f.close() |
|
481 for k in options.keywords.lower().split(): |
|
482 if k in t: |
|
483 break |
|
484 else: |
|
485 raise IgnoreTest("doesn't match keyword") |
|
486 |
|
487 if not os.path.basename(self.name.lower()).startswith('test-'): |
|
488 raise SkipTest('not a test file') |
|
489 |
467 |
490 replacements, port = self._getreplacements() |
468 replacements, port = self._getreplacements() |
491 env = self._getenv(port) |
469 env = self._getenv(port) |
492 self._daemonpids.append(env['DAEMON_PIDS']) |
470 self._daemonpids.append(env['DAEMON_PIDS']) |
493 self._createhgrc(env['HGRCPATH']) |
471 self._createhgrc(env['HGRCPATH']) |
527 info = {} |
505 info = {} |
528 if not options.nodiff: |
506 if not options.nodiff: |
529 iolock.acquire() |
507 iolock.acquire() |
530 if options.view: |
508 if options.view: |
531 os.system("%s %s %s" % (options.view, self._refpath, |
509 os.system("%s %s %s" % (options.view, self._refpath, |
532 self._errpath)) |
510 self.errpath)) |
533 else: |
511 else: |
534 info = showdiff(self._refout, out, self._refpath, |
512 info = showdiff(self._refout, out, self._refpath, |
535 self._errpath) |
513 self.errpath) |
536 iolock.release() |
514 iolock.release() |
537 msg = '' |
515 msg = '' |
538 if info.get('servefail'): |
516 if info.get('servefail'): |
539 msg += 'serve failed and ' |
517 msg += 'serve failed and ' |
540 if ret: |
518 if ret: |
563 shutil.rmtree(self._testtmp, True) |
541 shutil.rmtree(self._testtmp, True) |
564 shutil.rmtree(self._threadtmp, True) |
542 shutil.rmtree(self._threadtmp, True) |
565 |
543 |
566 if (self._ret != 0 or self._out != self._refout) and not self._skipped \ |
544 if (self._ret != 0 or self._out != self._refout) and not self._skipped \ |
567 and not self._options.debug and self._out: |
545 and not self._options.debug and self._out: |
568 f = open(self._errpath, 'wb') |
546 f = open(self.errpath, 'wb') |
569 for line in self._out: |
547 for line in self._out: |
570 f.write(line) |
548 f.write(line) |
571 f.close() |
549 f.close() |
572 |
550 |
573 vlog("# Ret was:", self._ret) |
551 vlog("# Ret was:", self._ret) |
652 warned = ret is False |
630 warned = ret is False |
653 if not self._options.nodiff: |
631 if not self._options.nodiff: |
654 log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name, |
632 log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name, |
655 msg)) |
633 msg)) |
656 if (not ret and self._options.interactive and |
634 if (not ret and self._options.interactive and |
657 os.path.exists(self._errpath)): |
635 os.path.exists(self.errpath)): |
658 iolock.acquire() |
636 iolock.acquire() |
659 print 'Accept this change? [n] ', |
637 print 'Accept this change? [n] ', |
660 answer = sys.stdin.readline().strip() |
638 answer = sys.stdin.readline().strip() |
661 iolock.release() |
639 iolock.release() |
662 if answer.lower() in ('y', 'yes'): |
640 if answer.lower() in ('y', 'yes'): |
663 if self.name.endswith('.t'): |
641 if self.name.endswith('.t'): |
664 rename(self._errpath, self._path) |
642 rename(self.errpath, self.path) |
665 else: |
643 else: |
666 rename(self._errpath, '%s.out' % self._path) |
644 rename(self.errpath, '%s.out' % self.path) |
667 |
645 |
668 return '.', self.name, '' |
646 return '.', self.name, '' |
669 |
647 |
670 if warned: |
648 if warned: |
671 raise WarnTest(msg) |
649 raise WarnTest(msg) |
681 def _refpath(self): |
659 def _refpath(self): |
682 return os.path.join(self._testdir, '%s.out' % self.name) |
660 return os.path.join(self._testdir, '%s.out' % self.name) |
683 |
661 |
684 def _run(self, replacements, env): |
662 def _run(self, replacements, env): |
685 py3kswitch = self._options.py3k_warnings and ' -3' or '' |
663 py3kswitch = self._options.py3k_warnings and ' -3' or '' |
686 cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self._path) |
664 cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self.path) |
687 vlog("# Running", cmd) |
665 vlog("# Running", cmd) |
688 if os.name == 'nt': |
666 if os.name == 'nt': |
689 replacements.append((r'\r\n', '\n')) |
667 replacements.append((r'\r\n', '\n')) |
690 return run(cmd, self._testtmp, replacements, env, self._abort, |
668 return run(cmd, self._testtmp, replacements, env, self._abort, |
691 debug=self._options.debug, timeout=self._options.timeout) |
669 debug=self._options.debug, timeout=self._options.timeout) |
704 @property |
682 @property |
705 def _refpath(self): |
683 def _refpath(self): |
706 return os.path.join(self._testdir, self.name) |
684 return os.path.join(self._testdir, self.name) |
707 |
685 |
708 def _run(self, replacements, env): |
686 def _run(self, replacements, env): |
709 f = open(self._path) |
687 f = open(self.path) |
710 lines = f.readlines() |
688 lines = f.readlines() |
711 f.close() |
689 f.close() |
712 |
690 |
713 salt, script, after, expected = self._parsetest(lines) |
691 salt, script, after, expected = self._parsetest(lines) |
714 |
692 |
1147 super(TestSuite, self).__init__(*args, **kwargs) |
1125 super(TestSuite, self).__init__(*args, **kwargs) |
1148 |
1126 |
1149 self._runner = runner |
1127 self._runner = runner |
1150 |
1128 |
1151 def run(self, result): |
1129 def run(self, result): |
1152 # We modify the list, so copy so callers aren't confused. |
1130 options = self._runner.options |
1153 tests = list(self._tests) |
1131 |
|
1132 # We have a number of filters that need to be applied. We do this |
|
1133 # here instead of inside Test because it makes the running logic for |
|
1134 # Test simpler. |
|
1135 tests = [] |
|
1136 for test in self._tests: |
|
1137 if not os.path.exists(test.path): |
|
1138 result.addSkip(test, "Doesn't exist") |
|
1139 continue |
|
1140 |
|
1141 if not (options.whitelisted and test.name in options.whitelisted): |
|
1142 if options.blacklist and test.name in options.blacklist: |
|
1143 result.addSkip(test, 'blacklisted') |
|
1144 continue |
|
1145 |
|
1146 if options.retest and not os.path.exists(test.errpath): |
|
1147 result.addIgnore(test, 'not retesting') |
|
1148 continue |
|
1149 |
|
1150 if options.keywords: |
|
1151 f = open(test.path) |
|
1152 t = f.read().lower() + test.name.lower() |
|
1153 f.close() |
|
1154 ignored = False |
|
1155 for k in options.keywords.lower().split(): |
|
1156 if k not in t: |
|
1157 result.addIgnore(test, "doesn't match keyword") |
|
1158 ignored = True |
|
1159 break |
|
1160 |
|
1161 if ignored: |
|
1162 continue |
|
1163 |
|
1164 if not test.name.lower().startswith('test-'): |
|
1165 result.addSkip(test, 'not a test file') |
|
1166 continue |
|
1167 |
|
1168 tests.append(test) |
1154 |
1169 |
1155 jobs = self._runner.options.jobs |
1170 jobs = self._runner.options.jobs |
1156 done = queue.Queue() |
1171 done = queue.Queue() |
1157 running = 0 |
1172 running = 0 |
1158 |
1173 |