107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbarimport os 207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbarimport threading 38c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbarimport time 48c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbarimport traceback 54ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbartry: 64ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar import Queue as queue 74ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbarexcept ImportError: 84ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar import queue 98c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar 1007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbartry: 1107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar import win32api 1207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbarexcept ImportError: 1307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar win32api = None 1407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 154ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbartry: 164ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar import multiprocessing 174ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbarexcept ImportError: 184ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar multiprocessing = None 194ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 208c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbarimport lit.Test 218c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar 2207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar### 2307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar# Test Execution Implementation 2407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 254ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbarclass LockedValue(object): 264ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def __init__(self, value): 2707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock = threading.Lock() 284ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self._value = value 2907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 304ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def _get_value(self): 3107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock.acquire() 324ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar try: 334ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar return self._value 344ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar finally: 354ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.lock.release() 3607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 374ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def _set_value(self, value): 3807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock.acquire() 394ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar try: 404ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self._value = value 414ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar finally: 424ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.lock.release() 434ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 444ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar value = property(_get_value, _set_value) 454ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 464ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbarclass TestProvider(object): 474ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def __init__(self, tests, num_jobs, queue_impl, canceled_flag): 484ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.canceled_flag = canceled_flag 494ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 504ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Create a shared queue to provide the test indices. 514ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue = queue_impl() 524ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar for i in range(len(tests)): 534ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue.put(i) 544ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar for i in range(num_jobs): 554ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue.put(None) 564ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 574ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def cancel(self): 584ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.canceled_flag.value = 1 594ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 604ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def get(self): 614ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Check if we are canceled. 624ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar if self.canceled_flag.value: 6307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar return None 64df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar 65df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar # Otherwise take the next test. 664ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar return self.queue.get() 6707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 6807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbarclass Tester(object): 6907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def __init__(self, run_instance, provider, consumer): 7007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.run_instance = run_instance 7107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.provider = provider 7207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.consumer = consumer 7307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 7407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def run(self): 754ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar while True: 7607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar item = self.provider.get() 7707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar if item is None: 7807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar break 7907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.run_test(item) 8007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.consumer.task_finished() 8107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 8207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def run_test(self, test_index): 8307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar test = self.run_instance.tests[test_index] 8407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar try: 8507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.run_instance.execute_test(test) 8607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar except KeyboardInterrupt: 8707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # This is a sad hack. Unfortunately subprocess goes 8807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # bonkers with ctrl-c and we start forking merrily. 8907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar print('\nCtrl-C detected, goodbye.') 9007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar os.kill(0,9) 9107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.consumer.update(test_index, test) 9207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 9307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbarclass ThreadResultsConsumer(object): 9407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def __init__(self, display): 9507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.display = display 9607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock = threading.Lock() 9707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 9807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def update(self, test_index, test): 9907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock.acquire() 10007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar try: 10107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.display.update(test) 10207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar finally: 10307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar self.lock.release() 10407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 10507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def task_finished(self): 10607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar pass 10707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 10807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def handle_results(self): 10907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar pass 11007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 1114ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbarclass MultiprocessResultsConsumer(object): 1124ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def __init__(self, run, display, num_jobs): 1134ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.run = run 1144ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.display = display 1154ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.num_jobs = num_jobs 1164ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue = multiprocessing.Queue() 1174ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 1184ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def update(self, test_index, test): 1194ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # This method is called in the child processes, and communicates the 1204ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # results to the actual display implementation via an output queue. 1214ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue.put((test_index, test.result)) 1224ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 1234ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def task_finished(self): 1244ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # This method is called in the child processes, and communicates that 1254ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # individual tasks are complete. 1264ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.queue.put(None) 1274ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 1284ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def handle_results(self): 1294ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # This method is called in the parent, and consumes the results from the 1304ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # output queue and dispatches to the actual display. The method will 1314ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # complete after each of num_jobs tasks has signalled completion. 1324ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar completed = 0 1334ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar while completed != self.num_jobs: 1344ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Wait for a result item. 1354ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar item = self.queue.get() 1364ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar if item is None: 1374ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar completed += 1 1384ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar continue 1394ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 1404ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Update the test result in the parent process. 1414ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar index,result = item 1424ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar test = self.run.tests[index] 1434ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar test.result = result 1444ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 1454ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self.display.update(test) 1464ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 14707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbardef run_one_tester(run, provider, display): 14807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar tester = Tester(run, provider, display) 14907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar tester.run() 15007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 15107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar### 15207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 1535b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbarclass Run(object): 1545b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar """ 1555b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar This class represents a concrete, configured testing run. 1565b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar """ 1575b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar 1585b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar def __init__(self, lit_config, tests): 1595b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar self.lit_config = lit_config 1605b2efc28fd193701d2d05780c7b8d8ee5bf75c31Daniel Dunbar self.tests = tests 1618c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar 1628c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar def execute_test(self, test): 1638c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar result = None 16407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar start_time = time.time() 1658c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar try: 1668c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar result = test.config.test_format.execute(test, self.lit_config) 1678c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar 1688c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar # Support deprecated result from execute() which returned the result 1698c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar # code and additional output as a tuple. 1708c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar if isinstance(result, tuple): 1718c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar code, output = result 1728c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar result = lit.Test.Result(code, output) 1738c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar elif not isinstance(result, lit.Test.Result): 1748c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar raise ValueError("unexpected result from test execution") 1758c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar except KeyboardInterrupt: 1768c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar raise 1778c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar except: 1788c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar if self.lit_config.debug: 1798c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar raise 1808c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar output = 'Exception during script execution:\n' 1818c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar output += traceback.format_exc() 1828c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar output += '\n' 1838c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar result = lit.Test.Result(lit.Test.UNRESOLVED, output) 18407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar result.elapsed = time.time() - start_time 1858c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar 1868c59003cc382e4b2fb15b267aa2d356e869a89ccDaniel Dunbar test.setResult(result) 18707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 1884ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def execute_tests(self, display, jobs, max_time=None, 1894ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar use_processes=False): 19007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar """ 19107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar execute_tests(display, jobs, [max_time]) 19207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 19307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar Execute each of the tests in the run, using up to jobs number of 19407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar parallel tasks, and inform the display of each individual result. The 19507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar provided tests should be a subset of the tests available in this run 19607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar object. 19707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 19807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar If max_time is non-None, it should be a time in seconds after which to 19907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar stop executing tests. 20007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 20107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar The display object will have its update method called with each test as 20207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar it is completed. The calls are guaranteed to be locked with respect to 20307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar one another, but are *not* guaranteed to be called on the same thread as 20407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar this method was invoked on. 20507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 20607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar Upon completion, each test in the run will have its result 20707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar computed. Tests which were not actually executed (for any reason) will 20807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar be given an UNRESOLVED result. 20907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar """ 21007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 2114ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Choose the appropriate parallel execution implementation. 2128d93aa0de330e24fe1cec7a915bdf1354da377faAlp Toker consumer = None 213a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker if jobs != 1 and use_processes and multiprocessing: 214a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker try: 215a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker task_impl = multiprocessing.Process 216a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker queue_impl = multiprocessing.Queue 217a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker canceled_flag = multiprocessing.Value('i', 0) 218a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker consumer = MultiprocessResultsConsumer(self, display, jobs) 219188545867dbcd0a6870b19c6b06d49610e7cda93Alp Toker except: 220bbe8f3b0e19f9bcca6e739fd92cbae6d570cab93Alp Toker # multiprocessing fails to initialize with certain OpenBSD and 221bbe8f3b0e19f9bcca6e739fd92cbae6d570cab93Alp Toker # FreeBSD Python versions: http://bugs.python.org/issue3770 222188545867dbcd0a6870b19c6b06d49610e7cda93Alp Toker # Unfortunately the error raised also varies by platform. 223a685c139182519ed29c3cddd848649f533070004Alp Toker self.lit_config.note('failed to initialize multiprocessing') 224a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker consumer = None 225a4e71dea487750cd13a5a5821df3acee32988bf4Alp Toker if not consumer: 2264ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar task_impl = threading.Thread 2274ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar queue_impl = queue.Queue 2284ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar canceled_flag = LockedValue(0) 2294ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar consumer = ThreadResultsConsumer(display) 2304ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar 2314ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Create the test provider. 2324ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar provider = TestProvider(self.tests, jobs, queue_impl, canceled_flag) 23307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 23407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # Install a console-control signal handler on Windows. 23507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar if win32api is not None: 23607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar def console_ctrl_handler(type): 23707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar provider.cancel() 23807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar return True 23907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar win32api.SetConsoleCtrlHandler(console_ctrl_handler, True) 24007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 241df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar # Install a timeout handler, if requested. 242df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar if max_time is not None: 243df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar def timeout_handler(): 244df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar provider.cancel() 245df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar timeout_timer = threading.Timer(max_time, timeout_handler) 246df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar timeout_timer.start() 247df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar 2484ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # If not using multiple tasks, just run the tests directly. 2494ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar if jobs == 1: 2504ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar run_one_tester(self, provider, consumer) 2514ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar else: 2524ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar # Otherwise, execute the tests in parallel 2534ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar self._execute_tests_in_parallel(task_impl, provider, consumer, jobs) 25407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 255df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar # Cancel the timeout handler. 256df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar if max_time is not None: 257df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar timeout_timer.cancel() 258df44de6d918255eb51f3d042681e006f33948f80Daniel Dunbar 25907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # Update results for any tests which weren't run. 26007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar for test in self.tests: 26107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar if test.result is None: 26207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar test.setResult(lit.Test.Result(lit.Test.UNRESOLVED, '', 0.0)) 26307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 2644ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar def _execute_tests_in_parallel(self, task_impl, provider, consumer, jobs): 26507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # Start all of the tasks. 2664ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar tasks = [task_impl(target=run_one_tester, 2674ac723b53f2eb69e604891853ca87d1e2b3ee788Daniel Dunbar args=(self, provider, consumer)) 26807f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar for i in range(jobs)] 26907f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar for t in tasks: 27007f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar t.start() 27107f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 27207f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # Allow the consumer to handle results, if necessary. 27307f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar consumer.handle_results() 27407f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar 27507f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar # Wait for all the tasks to complete. 27607f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar for t in tasks: 27707f0f16bfd58c3e44babae65ccd88b9621d15f48Daniel Dunbar t.join() 278