From 8e00d5acbc9caafe1c514437869c7e8567ab5ed7 Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Thu, 17 Oct 2019 00:29:59 +0000 Subject: [PATCH] [lit] Improve lit.Run class * Push timing of overall test time into run module * Make lit.Run a proper class * Add a few TODO comments git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375065 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lit/lit/main.py | 21 ++++++++++--------- utils/lit/lit/run.py | 47 ++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/utils/lit/lit/main.py b/utils/lit/lit/main.py index 4430e1689a1..f2bc38bfa04 100755 --- a/utils/lit/lit/main.py +++ b/utils/lit/lit/main.py @@ -9,7 +9,6 @@ See lit.pod for more information. import os import platform import sys -import time import lit.cl_arguments import lit.discovery @@ -209,8 +208,6 @@ def increase_process_limit(litConfig, opts): def run_tests(tests, litConfig, opts, numTotalTests): increase_process_limit(litConfig, opts) - run = lit.run.Run(litConfig, tests) - display = lit.display.create_display(opts, len(tests), numTotalTests, opts.numWorkers) def progress_callback(test): @@ -218,18 +215,22 @@ def run_tests(tests, litConfig, opts, numTotalTests): if opts.incremental: update_incremental_cache(test) - run_callback = lambda: run.execute_tests(progress_callback, opts.numWorkers, - opts.maxTime) + run = lit.run.Run(tests, litConfig, progress_callback, opts.maxTime, + opts.numWorkers) - startTime = time.time() try: - run_tests_in_tmp_dir(run_callback, litConfig) + elapsed = run_tests_in_tmp_dir(run.execute_tests, litConfig) except KeyboardInterrupt: + #TODO(yln): should we attempt to cleanup the progress bar here? sys.exit(2) - testing_time = time.time() - startTime + # TODO(yln): display.finish_interrupted(), which shows the most recently started test + # TODO(yln): change display to update when test starts, not when test completes + # Ensure everything still works with SimpleProgressBar as well + # finally: + # display.finish() display.finish() - return testing_time + return elapsed def run_tests_in_tmp_dir(run_callback, litConfig): # Create a temp directory inside the normal temp directory so that we can @@ -252,7 +253,7 @@ def run_tests_in_tmp_dir(run_callback, litConfig): # scanning for stale temp directories, and deleting temp directories whose # lit process has died. try: - run_callback() + return run_callback() finally: if tmp_dir: try: diff --git a/utils/lit/lit/run.py b/utils/lit/lit/run.py index 6d1cc7c9207..08bb379f387 100644 --- a/utils/lit/lit/run.py +++ b/utils/lit/lit/run.py @@ -12,18 +12,17 @@ class NopSemaphore(object): def release(self): pass class Run(object): - """ - This class represents a concrete, configured testing run. - """ + """A concrete, configured testing run.""" - def __init__(self, lit_config, tests): - self.lit_config = lit_config + def __init__(self, tests, lit_config, progress_callback, max_time, workers): self.tests = tests + self.lit_config = lit_config + self.progress_callback = progress_callback + self.max_time = max_time + self.workers = workers - def execute_tests(self, progress_callback, workers, max_time): + def execute_tests(self): """ - execute_tests(progress_callback, workers, max_time) - Execute the tests in the run using up to the specified number of parallel tasks, and inform the caller of each individual result. The provided tests should be a subset of the tests available in this run @@ -34,42 +33,48 @@ class Run(object): If max_time is non-None, it should be a time in seconds after which to stop executing tests. + Returns the elapsed testing time. + Upon completion, each test in the run will have its result computed. Tests which were not actually executed (for any reason) will be given an UNRESOLVED result. """ - # Don't do anything if we aren't going to run any tests. if not self.tests: - return - - self.progress_callback = progress_callback + return 0.0 self.failure_count = 0 self.hit_max_failures = False - if workers == 1: - self._execute_in_serial(max_time) + + start = time.time() + + if self.workers == 1: + self._execute_in_serial() else: - self._execute_in_parallel(workers, max_time) + self._execute_in_parallel() + + end = time.time() # Mark any tests that weren't run as UNRESOLVED. for test in self.tests: if test.result is None: test.setResult(lit.Test.Result(lit.Test.UNRESOLVED, '', 0.0)) - def _execute_in_serial(self, max_time): + return end - start + + def _execute_in_serial(self): + # TODO(yln): ignores max_time for test_index, test in enumerate(self.tests): lit.worker._execute_test(test, self.lit_config) self._consume_test_result((test_index, test)) if self.hit_max_failures: break - def _execute_in_parallel(self, workers, max_time): - assert workers > 1 + def _execute_in_parallel(self): # We need to issue many wait calls, so compute the final deadline and # subtract time.time() from that as we go along. deadline = None - if max_time: - deadline = time.time() + max_time + if self.max_time: + deadline = time.time() + self.max_time semaphores = { k: NopSemaphore() if v is None else @@ -81,7 +86,7 @@ class Run(object): # interrupts the workers before we make it into our task callback, they # will each raise a KeyboardInterrupt exception and print to stderr at # the same time. - pool = multiprocessing.Pool(workers, lit.worker.initializer, + pool = multiprocessing.Pool(self.workers, lit.worker.initializer, (self.lit_config, semaphores)) # Install a console-control signal handler on Windows. -- 2.40.0