[lit] Attempt to print test summary on CTRL+C
authorJulian Lettner <julian.lettner@gmail.com>
Tue, 26 Feb 2019 05:25:29 +0000 (21:25 -0800)
committerJulian Lettner <julian.lettner@apple.com>
Fri, 22 Nov 2019 18:57:33 +0000 (10:57 -0800)
llvm/utils/lit/lit/ProgressBar.py
llvm/utils/lit/lit/display.py
llvm/utils/lit/lit/main.py

index cefde67..4f8bd3c 100644 (file)
@@ -201,8 +201,8 @@ class SimpleProgressBar:
         sys.stdout.flush()
         self.atIndex = next
 
-    def clear(self):
-        if self.atIndex is not None:
+    def clear(self, interrupted):
+        if self.atIndex is not None and not interrupted:
             sys.stdout.write('\n')
             sys.stdout.flush()
             self.atIndex = None
@@ -275,11 +275,14 @@ class ProgressBar:
         if not self.term.XN:
             sys.stdout.flush()
 
-    def clear(self):
+    def clear(self, interrupted):
         if not self.cleared:
             sys.stdout.write(self.BOL + self.term.CLEAR_EOL +
                              self.term.UP + self.term.CLEAR_EOL +
                              self.term.UP + self.term.CLEAR_EOL)
+            if interrupted:  # ^C creates extra line. Gobble it up!
+                sys.stdout.write(self.term.UP + self.term.CLEAR_EOL)
+                sys.stdout.write('^C')
             sys.stdout.flush()
             self.cleared = 1
 
index 05b752a..c986b34 100644 (file)
@@ -24,7 +24,7 @@ def create_display(opts, tests, total_tests, workers):
 class NopDisplay(object):
     def print_header(self): pass
     def update(self, test): pass
-    def clear(self): pass
+    def clear(self, interrupted): pass
 
 
 class Display(object):
@@ -49,7 +49,7 @@ class Display(object):
                 (not self.opts.quiet and not self.opts.succinct)
         if show_result:
             if self.progress_bar:
-                self.progress_bar.clear()
+                self.progress_bar.clear(interrupted=False)
             self.print_result(test)
 
         if self.progress_bar:
@@ -58,10 +58,9 @@ class Display(object):
             percent = float(self.completed) / self.tests
             self.progress_bar.update(percent, test.getFullName())
 
-    def clear(self):
+    def clear(self, interrupted):
         if self.progress_bar:
-            self.progress_bar.clear()
-        sys.stdout.write('\n')
+            self.progress_bar.clear(interrupted)
 
     def print_result(self, test):
         # Show the test result line.
index 0eb95b9..e8d539a 100755 (executable)
@@ -97,7 +97,9 @@ def main(builtin_params = {}):
     run_tests(tests, litConfig, opts, numTotalTests)
     elapsed = time.time() - start
 
-    print_summary(tests, elapsed, opts)
+    executed_tests = [t for t in tests if t.result]
+
+    print_summary(executed_tests, elapsed, opts)
 
     if opts.output_path:
         write_test_results(tests, litConfig, elapsed, opts.output_path)
@@ -111,7 +113,7 @@ def main(builtin_params = {}):
     if litConfig.numWarnings:
         sys.stderr.write('\n%d warning(s) in tests.\n' % litConfig.numWarnings)
 
-    has_failure = any(t.isFailure() for t in tests)
+    has_failure = any(t.isFailure() for t in executed_tests)
     if has_failure:
         sys.exit(1)
 
@@ -203,16 +205,10 @@ def run_tests(tests, litConfig, opts, numTotalTests):
     display.print_header()
     try:
         execute_in_tmp_dir(run, litConfig)
+        display.clear(interrupted=False)
     except KeyboardInterrupt:
-        #TODO(yln): should we attempt to cleanup the progress bar here?
-        sys.exit(2)
-    # 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.clear()
-
-    display.clear()
+        display.clear(interrupted=True)
+        print(' [interrupted by user]')
 
 def execute_in_tmp_dir(run, litConfig):
     # Create a temp directory inside the normal temp directory so that we can
@@ -247,7 +243,7 @@ def execute_in_tmp_dir(run, litConfig):
 
 def print_summary(tests, elapsed, opts):
     if not opts.quiet:
-        print('Testing Time: %.2fs' % elapsed)
+        print('\nTesting Time: %.2fs' % elapsed)
 
     byCode = {}
     for test in tests:
@@ -296,6 +292,7 @@ def print_summary(tests, elapsed, opts):
             print('  %s: %d' % (name,N))
 
 def write_test_results(tests, lit_config, elapsed, output_path):
+    # TODO(yln): audit: unexecuted tests
     # Construct the data we will write.
     data = {}
     # Encode the current lit version as a schema version.
@@ -350,6 +347,7 @@ def write_test_results(tests, lit_config, elapsed, output_path):
         f.close()
 
 def write_test_results_xunit(tests, opts):
+    # TODO(yln): audit: unexecuted tests
     from xml.sax.saxutils import quoteattr
     # Collect the tests, indexed by test suite
     by_suite = {}