[lit] max_failures does not need to be stored in LitConfig
authorJulian Lettner <julian.lettner@gmail.com>
Tue, 26 Feb 2019 07:00:17 +0000 (23:00 -0800)
committerJulian Lettner <julian.lettner@apple.com>
Mon, 16 Dec 2019 18:08:57 +0000 (10:08 -0800)
llvm/utils/lit/lit/LitConfig.py
llvm/utils/lit/lit/cl_arguments.py
llvm/utils/lit/lit/main.py
llvm/utils/lit/lit/run.py

index 881d9fa..58011b5 100644 (file)
@@ -25,7 +25,6 @@ class LitConfig(object):
                  noExecute, debug, isWindows,
                  params, config_prefix = None,
                  maxIndividualTestTime = 0,
-                 maxFailures = None,
                  parallelism_groups = {},
                  echo_all_commands = False):
         # The name of the test runner.
@@ -65,7 +64,6 @@ class LitConfig(object):
             self.valgrindArgs.extend(self.valgrindUserArgs)
 
         self.maxIndividualTestTime = maxIndividualTestTime
-        self.maxFailures = maxFailures
         self.parallelism_groups = parallelism_groups
         self.echo_all_commands = echo_all_commands
 
index 1417e89..bac2be2 100644 (file)
@@ -106,7 +106,6 @@ def parse_args():
                  "0 means no time limit. [Default: 0]",
             type=_non_negative_int) # TODO(yln): --[no-]test-timeout, instead of 0 allowed
     execution_group.add_argument("--max-failures",
-            dest="maxFailures",
             help="Stop execution after the given number of failures.",
             type=_positive_int)
     execution_group.add_argument("--allow-empty-runs",
index 38a6f57..c58b06c 100755 (executable)
@@ -40,7 +40,6 @@ def main(builtin_params={}):
         isWindows=is_windows,
         params=params,
         config_prefix=opts.configPrefix,
-        maxFailures=opts.maxFailures, # TODO(yln): doesn't need to be in lit config
         echo_all_commands=opts.echoAllCommands)
 
     discovered_tests = lit.discovery.find_tests_for_inputs(lit_config, opts.test_paths)
@@ -195,6 +194,7 @@ def filter_by_shard(tests, run, shards, lit_config):
     lit_config.note(msg)
     return selected_tests
 
+
 def run_tests(tests, lit_config, opts, numTotalTests):
     display = lit.display.create_display(opts, len(tests), numTotalTests,
                                          opts.workers)
@@ -204,7 +204,7 @@ def run_tests(tests, lit_config, opts, numTotalTests):
             touch_file(test)
 
     run = lit.run.create_run(tests, lit_config, opts.workers, progress_callback,
-                             opts.timeout)
+                             opts.max_failures, opts.timeout)
 
     display.print_header()
     try:
@@ -214,6 +214,7 @@ def run_tests(tests, lit_config, opts, numTotalTests):
         display.clear(interrupted=True)
         print(' [interrupted by user]')
 
+
 def execute_in_tmp_dir(run, lit_config):
     # Create a temp directory inside the normal temp directory so that we can
     # try to avoid temporary test file leaks. The user can avoid this behavior
@@ -264,7 +265,7 @@ def print_summary(tests, elapsed, opts):
                        ('Timed Out Tests', lit.Test.TIMEOUT)):
         if (lit.Test.XFAIL == code and not opts.show_xfail) or \
            (lit.Test.UNSUPPORTED == code and not opts.show_unsupported) or \
-           (lit.Test.UNRESOLVED == code and (opts.maxFailures is not None)):
+           (lit.Test.UNRESOLVED == code and (opts.max_failures is not None)):
             continue
         elts = byCode.get(code)
         if not elts:
index f1004a4..65495ed 100644 (file)
@@ -6,25 +6,30 @@ import lit.Test
 import lit.util
 import lit.worker
 
+
 # No-operation semaphore for supporting `None` for parallelism_groups.
 #   lit_config.parallelism_groups['my_group'] = None
 class NopSemaphore(object):
     def acquire(self): pass
     def release(self): pass
 
-def create_run(tests, lit_config, workers, progress_callback, timeout=None):
+
+def create_run(tests, lit_config, workers, progress_callback, max_failures,
+               timeout):
     assert workers > 0
     if workers == 1:
-        return SerialRun(tests, lit_config, progress_callback, timeout)
-    return ParallelRun(tests, lit_config, progress_callback, timeout, workers)
+        return SerialRun(tests, lit_config, progress_callback, max_failures, timeout)
+    return ParallelRun(tests, lit_config, progress_callback, max_failures, timeout, workers)
+
 
 class Run(object):
     """A concrete, configured testing run."""
 
-    def __init__(self, tests, lit_config, progress_callback, timeout):
+    def __init__(self, tests, lit_config, progress_callback, max_failures, timeout):
         self.tests = tests
         self.lit_config = lit_config
         self.progress_callback = progress_callback
+        self.max_failures = max_failures
         self.timeout = timeout
 
     def execute(self):
@@ -69,22 +74,20 @@ class Run(object):
         if self.hit_max_failures:
             return
 
-        # Update the parent process copy of the test. This includes the result,
-        # XFAILS, REQUIRES, and UNSUPPORTED statuses.
         test.setResult(result)
 
+        # Use test.isFailure() for correct XFAIL and XPASS handling
+        if test.isFailure():
+            self.failure_count += 1
+            if self.failure_count == self.max_failures:
+                self.hit_max_failures = True
+
         self.progress_callback(test)
 
-        # If we've finished all the tests or too many tests have failed, notify
-        # the main thread that we've stopped testing.
-        self.failure_count += (result.code == lit.Test.FAIL)  # TODO(yln): this is buggy
-        if self.lit_config.maxFailures and \
-                self.failure_count == self.lit_config.maxFailures:
-            self.hit_max_failures = True
 
 class SerialRun(Run):
-    def __init__(self, tests, lit_config, progress_callback, timeout):
-        super(SerialRun, self).__init__(tests, lit_config, progress_callback, timeout)
+    def __init__(self, tests, lit_config, progress_callback, max_failures, timeout):
+        super(SerialRun, self).__init__(tests, lit_config, progress_callback, max_failures, timeout)
 
     def _execute(self, deadline):
         # TODO(yln): ignores deadline
@@ -94,9 +97,10 @@ class SerialRun(Run):
             if self.hit_max_failures:
                 break
 
+
 class ParallelRun(Run):
-    def __init__(self, tests, lit_config, progress_callback, timeout, workers):
-        super(ParallelRun, self).__init__(tests, lit_config, progress_callback, timeout)
+    def __init__(self, tests, lit_config, progress_callback, max_failures, timeout, workers):
+        super(ParallelRun, self).__init__(tests, lit_config, progress_callback, max_failures, timeout)
         self.workers = workers
 
     def _execute(self, deadline):