[llvm] r374194 - [lit] Refactor ProgressDisplay

Julian Lettner via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 9 11:23:31 PDT 2019


Author: yln
Date: Wed Oct  9 11:23:30 2019
New Revision: 374194

URL: http://llvm.org/viewvc/llvm-project?rev=374194&view=rev
Log:
[lit] Refactor ProgressDisplay

Move progress display to separate file.  Simplify some code paths.
Decouple from other components via progress callback.  Remove unused
`_Display` class.

Reviewed By: serge-sans-paille

Differential Revision: https://reviews.llvm.org/D68525

Added:
    llvm/trunk/utils/lit/lit/display.py
Modified:
    llvm/trunk/utils/lit/lit/ProgressBar.py
    llvm/trunk/utils/lit/lit/main.py
    llvm/trunk/utils/lit/lit/run.py
    llvm/trunk/utils/lit/tests/progress-bar.py

Modified: llvm/trunk/utils/lit/lit/ProgressBar.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/ProgressBar.py?rev=374194&r1=374193&r2=374194&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/ProgressBar.py (original)
+++ llvm/trunk/utils/lit/lit/ProgressBar.py Wed Oct  9 11:23:30 2019
@@ -172,7 +172,7 @@ class SimpleProgressBar:
     A simple progress bar which doesn't need any terminal support.
 
     This prints out a progress bar like:
-      'Header: 0 .. 10.. 20.. ...'
+      'Header:  0.. 10.. 20.. ...'
     """
 
     def __init__(self, header):
@@ -191,7 +191,7 @@ class SimpleProgressBar:
         for i in range(self.atIndex, next):
             idx = i % 5
             if idx == 0:
-                sys.stdout.write('%-2d' % (i*2))
+                sys.stdout.write('%2d' % (i*2))
             elif idx == 1:
                 pass # Skip second char
             elif idx < 4:

Added: llvm/trunk/utils/lit/lit/display.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/display.py?rev=374194&view=auto
==============================================================================
--- llvm/trunk/utils/lit/lit/display.py (added)
+++ llvm/trunk/utils/lit/lit/display.py Wed Oct  9 11:23:30 2019
@@ -0,0 +1,98 @@
+import sys
+
+import lit.ProgressBar
+
+def create_display(opts, tests, total_tests, workers):
+    if opts.quiet:
+        return NopProgressDisplay()
+
+    of_total = (' of %d' % total_tests) if (tests != total_tests) else ''
+    header = '-- Testing: %d%s tests, %d workers --' % (tests, of_total, workers)
+
+    progress_bar = None
+    if opts.succinct and opts.useProgressBar:
+        try:
+            tc = lit.ProgressBar.TerminalController()
+            progress_bar = lit.ProgressBar.ProgressBar(tc, header)
+        except ValueError:
+            print(header)
+            progress_bar = lit.ProgressBar.SimpleProgressBar('Testing: ')
+    else:
+        print(header)
+
+    if progress_bar:
+        progress_bar.update(0, '')
+
+    return ProgressDisplay(opts, tests, progress_bar)
+
+class NopProgressDisplay(object):
+    def update(self, test): pass
+    def finish(self): pass
+
+class ProgressDisplay(object):
+    def __init__(self, opts, numTests, progressBar):
+        self.opts = opts
+        self.numTests = numTests
+        self.progressBar = progressBar
+        self.completed = 0
+
+    def finish(self):
+        if self.progressBar:
+            self.progressBar.clear()
+        elif self.opts.succinct:
+            sys.stdout.write('\n')
+
+    def update(self, test):
+        self.completed += 1
+
+        show_result = test.result.code.isFailure or \
+                self.opts.showAllOutput or \
+                (not self.opts.quiet and not self.opts.succinct)
+        if show_result:
+            self.print_result(test)
+
+        if self.progressBar:
+            percent = float(self.completed) / self.numTests
+            self.progressBar.update(percent, test.getFullName())
+
+    def print_result(self, test):
+        if self.progressBar:
+            self.progressBar.clear()
+
+        # Show the test result line.
+        test_name = test.getFullName()
+        print('%s: %s (%d of %d)' % (test.result.code.name, test_name,
+                                     self.completed, self.numTests))
+
+        # Show the test failure output, if requested.
+        if (test.result.code.isFailure and self.opts.showOutput) or \
+           self.opts.showAllOutput:
+            if test.result.code.isFailure:
+                print("%s TEST '%s' FAILED %s" % ('*'*20, test.getFullName(),
+                                                  '*'*20))
+            print(test.result.output)
+            print("*" * 20)
+
+        # Report test metrics, if present.
+        if test.result.metrics:
+            print("%s TEST '%s' RESULTS %s" % ('*'*10, test.getFullName(),
+                                               '*'*10))
+            items = sorted(test.result.metrics.items())
+            for metric_name, value in items:
+                print('%s: %s ' % (metric_name, value.format()))
+            print("*" * 10)
+
+        # Report micro-tests, if present
+        if test.result.microResults:
+            items = sorted(test.result.microResults.items())
+            for micro_test_name, micro_test in items:
+                print("%s MICRO-TEST: %s" %
+                         ('*'*3, micro_test_name))
+
+                if micro_test.metrics:
+                    sorted_metrics = sorted(micro_test.metrics.items())
+                    for metric_name, value in sorted_metrics:
+                        print('    %s:  %s ' % (metric_name, value.format()))
+
+        # Ensure the output is flushed.
+        sys.stdout.flush()

Modified: llvm/trunk/utils/lit/lit/main.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/main.py?rev=374194&r1=374193&r2=374194&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/main.py (original)
+++ llvm/trunk/utils/lit/lit/main.py Wed Oct  9 11:23:30 2019
@@ -19,84 +19,12 @@ import tempfile
 import shutil
 from xml.sax.saxutils import quoteattr
 
-import lit.ProgressBar
+import lit.discovery
+import lit.display
 import lit.LitConfig
-import lit.Test
 import lit.run
+import lit.Test
 import lit.util
-import lit.discovery
-
-class TestingProgressDisplay(object):
-    def __init__(self, opts, numTests, progressBar=None):
-        self.opts = opts
-        self.numTests = numTests
-        self.progressBar = progressBar
-        self.completed = 0
-
-    def finish(self):
-        if self.progressBar:
-            self.progressBar.clear()
-        elif self.opts.quiet:
-            pass
-        elif self.opts.succinct:
-            sys.stdout.write('\n')
-
-    def update(self, test):
-        self.completed += 1
-
-        if self.opts.incremental:
-            update_incremental_cache(test)
-
-        if self.progressBar:
-            self.progressBar.update(float(self.completed)/self.numTests,
-                                    test.getFullName())
-
-        shouldShow = test.result.code.isFailure or \
-            self.opts.showAllOutput or \
-            (not self.opts.quiet and not self.opts.succinct)
-        if not shouldShow:
-            return
-
-        if self.progressBar:
-            self.progressBar.clear()
-
-        # Show the test result line.
-        test_name = test.getFullName()
-        print('%s: %s (%d of %d)' % (test.result.code.name, test_name,
-                                     self.completed, self.numTests))
-
-        # Show the test failure output, if requested.
-        if (test.result.code.isFailure and self.opts.showOutput) or \
-           self.opts.showAllOutput:
-            if test.result.code.isFailure:
-                print("%s TEST '%s' FAILED %s" % ('*'*20, test.getFullName(),
-                                                  '*'*20))
-            print(test.result.output)
-            print("*" * 20)
-
-        # Report test metrics, if present.
-        if test.result.metrics:
-            print("%s TEST '%s' RESULTS %s" % ('*'*10, test.getFullName(),
-                                               '*'*10))
-            items = sorted(test.result.metrics.items())
-            for metric_name, value in items:
-                print('%s: %s ' % (metric_name, value.format()))
-            print("*" * 10)
-
-        # Report micro-tests, if present
-        if test.result.microResults:
-            items = sorted(test.result.microResults.items())
-            for micro_test_name, micro_test in items:
-                print("%s MICRO-TEST: %s" %
-                         ('*'*3, micro_test_name))
-   
-                if micro_test.metrics:
-                    sorted_metrics = sorted(micro_test.metrics.items())
-                    for metric_name, value in sorted_metrics:
-                        print('    %s:  %s ' % (metric_name, value.format()))
-
-        # Ensure the output is flushed.
-        sys.stdout.flush()
 
 def write_test_results(run, lit_config, testing_time, output_path):
     try:
@@ -505,29 +433,22 @@ def main_with_tmp(builtinParameters):
     except:
         pass
 
-    extra = (' of %d' % numTotalTests) if (len(run.tests) != numTotalTests) else ''
-    header = '-- Testing: %d%s tests, %d workers --' % (len(run.tests), extra, opts.numWorkers)
-    progressBar = None
-    if not opts.quiet:
-        if opts.succinct and opts.useProgressBar:
-            try:
-                tc = lit.ProgressBar.TerminalController()
-                progressBar = lit.ProgressBar.ProgressBar(tc, header)
-            except ValueError:
-                print(header)
-                progressBar = lit.ProgressBar.SimpleProgressBar('Testing: ')
-        else:
-            print(header)
+    display = lit.display.create_display(opts, len(run.tests),
+                                         numTotalTests, opts.numWorkers)
+    def progress_callback(test):
+        display.update(test)
+        if opts.incremental:
+            update_incremental_cache(test)
 
     startTime = time.time()
-    display = TestingProgressDisplay(opts, len(run.tests), progressBar)
     try:
-        run.execute_tests(display, opts.numWorkers, opts.maxTime)
+        run.execute_tests(progress_callback, opts.numWorkers, opts.maxTime)
     except KeyboardInterrupt:
         sys.exit(2)
+    testing_time = time.time() - startTime
+
     display.finish()
 
-    testing_time = time.time() - startTime
     if not opts.quiet:
         print('Testing Time: %.2fs' % (testing_time,))
 

Modified: llvm/trunk/utils/lit/lit/run.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/run.py?rev=374194&r1=374193&r2=374194&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/run.py (original)
+++ llvm/trunk/utils/lit/lit/run.py Wed Oct  9 11:23:30 2019
@@ -5,18 +5,6 @@ import lit.Test
 import lit.util
 import lit.worker
 
-class _Display(object):
-    def __init__(self, display, provider, maxFailures):
-        self.display = display
-        self.provider = provider
-        self.maxFailures = maxFailures or object()
-        self.failedCount = 0
-    def update(self, test):
-        self.display.update(test)
-        self.failedCount += (test.result.code == lit.Test.FAIL)
-        if self.failedCount == self.maxFailures:
-            self.provider.cancel()
-
 # No-operation semaphore for supporting `None` for parallelism_groups.
 #   lit_config.parallelism_groups['my_group'] = None
 class NopSemaphore(object):
@@ -93,21 +81,20 @@ class Run(object):
         finally:
             pool.join()
 
-    def execute_tests(self, display, workers, max_time=None):
+    def execute_tests(self, progress_callback, workers, max_time):
         """
-        execute_tests(display, workers, [max_time])
+        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 display of each individual result. The
+        parallel tasks, and inform the caller of each individual result. The
         provided tests should be a subset of the tests available in this run
         object.
 
+        The progress_callback will be invoked for each completed test.
+
         If max_time is non-None, it should be a time in seconds after which to
         stop executing tests.
 
-        The display object will have its update method called for each completed
-        test.
-
         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.
@@ -116,9 +103,7 @@ class Run(object):
         if not self.tests:
             return
 
-        # Save the display object on the runner so that we can update it from
-        # our task completion callback.
-        self.display = display
+        self.progress_callback = progress_callback
 
         self.failure_count = 0
         self.hit_max_failures = False
@@ -156,7 +141,7 @@ class Run(object):
         assert self.tests[test_index].file_path == test_with_result.file_path, \
                 "parent and child disagree on test path"
         self.tests[test_index] = test_with_result
-        self.display.update(test_with_result)
+        self.progress_callback(test_with_result)
 
         # If we've finished all the tests or too many tests have failed, notify
         # the main thread that we've stopped testing.

Modified: llvm/trunk/utils/lit/tests/progress-bar.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/tests/progress-bar.py?rev=374194&r1=374193&r2=374194&view=diff
==============================================================================
--- llvm/trunk/utils/lit/tests/progress-bar.py (original)
+++ llvm/trunk/utils/lit/tests/progress-bar.py Wed Oct  9 11:23:30 2019
@@ -3,11 +3,12 @@
 # RUN: not %{lit} -j 1 -s %{inputs}/progress-bar > %t.out
 # RUN: FileCheck < %t.out %s
 #
-# CHECK: Testing: 0 .. 10.. 20
+# CHECK: Testing:
 # CHECK: FAIL: progress-bar :: test-1.txt (1 of 4)
-# CHECK: Testing: 0 .. 10.. 20.. 30.. 40.. 
+# CHECK: Testing:  0.. 10.. 20
 # CHECK: FAIL: progress-bar :: test-2.txt (2 of 4)
-# CHECK: Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70
+# CHECK: Testing:  0.. 10.. 20.. 30.. 40..
 # CHECK: FAIL: progress-bar :: test-3.txt (3 of 4)
-# CHECK: Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
+# CHECK: Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70
 # CHECK: FAIL: progress-bar :: test-4.txt (4 of 4)
+# CHECK: Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..




More information about the llvm-commits mailing list