1136 super(TestSuite, self).__init__(*args, **kwargs) |
1136 super(TestSuite, self).__init__(*args, **kwargs) |
1137 |
1137 |
1138 self._runner = runner |
1138 self._runner = runner |
1139 |
1139 |
1140 def run(self, result): |
1140 def run(self, result): |
1141 self._runner._executetests(self._tests, result=result) |
1141 # We modify the list, so copy so callers aren't confused. |
|
1142 tests = list(self._tests) |
|
1143 |
|
1144 jobs = self._runner.options.jobs |
|
1145 done = queue.Queue() |
|
1146 running = 0 |
|
1147 |
|
1148 def job(test, result): |
|
1149 try: |
|
1150 test(result) |
|
1151 done.put(None) |
|
1152 except KeyboardInterrupt: |
|
1153 pass |
|
1154 except: # re-raises |
|
1155 done.put(('!', test, 'run-test raised an error, see traceback')) |
|
1156 raise |
|
1157 |
|
1158 try: |
|
1159 while tests or running: |
|
1160 if not done.empty() or running == jobs or not tests: |
|
1161 try: |
|
1162 done.get(True, 1) |
|
1163 if result and result.shouldStop: |
|
1164 break |
|
1165 except queue.Empty: |
|
1166 continue |
|
1167 running -= 1 |
|
1168 if tests and not running == jobs: |
|
1169 test = tests.pop(0) |
|
1170 if self._runner.options.loop: |
|
1171 tests.append(test) |
|
1172 t = threading.Thread(target=job, name=test.name, |
|
1173 args=(test, result)) |
|
1174 t.start() |
|
1175 running += 1 |
|
1176 except KeyboardInterrupt: |
|
1177 self._runner.abort[0] = True |
1142 |
1178 |
1143 return result |
1179 return result |
1144 |
1180 |
1145 class TextTestRunner(unittest.TextTestRunner): |
1181 class TextTestRunner(unittest.TextTestRunner): |
1146 """Custom unittest test runner that uses appropriate settings.""" |
1182 """Custom unittest test runner that uses appropriate settings.""" |
1607 adir = os.path.join(self.testdir, 'annotated') |
1643 adir = os.path.join(self.testdir, 'annotated') |
1608 if not os.path.isdir(adir): |
1644 if not os.path.isdir(adir): |
1609 os.mkdir(adir) |
1645 os.mkdir(adir) |
1610 covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit) |
1646 covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit) |
1611 |
1647 |
1612 def _executetests(self, tests, result): |
|
1613 # We modify the list, so copy so callers aren't confused. |
|
1614 tests = list(tests) |
|
1615 |
|
1616 jobs = self.options.jobs |
|
1617 done = queue.Queue() |
|
1618 running = 0 |
|
1619 |
|
1620 def job(test, result): |
|
1621 try: |
|
1622 test(result) |
|
1623 done.put(None) |
|
1624 except KeyboardInterrupt: |
|
1625 pass |
|
1626 except: # re-raises |
|
1627 done.put(('!', test, 'run-test raised an error, see traceback')) |
|
1628 raise |
|
1629 |
|
1630 try: |
|
1631 while tests or running: |
|
1632 if not done.empty() or running == jobs or not tests: |
|
1633 try: |
|
1634 done.get(True, 1) |
|
1635 if result and result.shouldStop: |
|
1636 break |
|
1637 except queue.Empty: |
|
1638 continue |
|
1639 running -= 1 |
|
1640 if tests and not running == jobs: |
|
1641 test = tests.pop(0) |
|
1642 if self.options.loop: |
|
1643 tests.append(test) |
|
1644 t = threading.Thread(target=job, name=test.name, |
|
1645 args=(test, result)) |
|
1646 t.start() |
|
1647 running += 1 |
|
1648 except KeyboardInterrupt: |
|
1649 self.abort[0] = True |
|
1650 |
|
1651 def _findprogram(self, program): |
1648 def _findprogram(self, program): |
1652 """Search PATH for a executable program""" |
1649 """Search PATH for a executable program""" |
1653 for p in os.environ.get('PATH', os.defpath).split(os.pathsep): |
1650 for p in os.environ.get('PATH', os.defpath).split(os.pathsep): |
1654 name = os.path.join(p, program) |
1651 name = os.path.join(p, program) |
1655 if os.name == 'nt' or os.access(name, os.X_OK): |
1652 if os.name == 'nt' or os.access(name, os.X_OK): |