[PATCH 2 of 2] run-tests: add --debug mode: don't capture child output, just show it

Greg Ward greg-hg at gerg.ca
Sat Oct 31 12:50:57 CDT 2009


# HG changeset patch
# User Greg Ward <greg-hg at gerg.ca>
# Date 1257011338 14400
# Node ID 41e60e23e66cd34ecae542b6e31632cffdf14419
# Parent  d1e60d343f8484b61a9c7959d51e2dfbea8aca0f
run-tests: add --debug mode: don't capture child output, just show it.

In debug mode, we:
- disallow --interactive
- don't try to parse hghave output, since we don't have the output
- don't try to save output to .err file

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -97,6 +97,10 @@
     parser.add_option("--tmpdir", type="string",
         help="run tests in the given temporary directory"
              " (implies --keep-tmpdir)")
+    # XXX --debug does not disable timeouts!
+    parser.add_option("-d", "--debug", action="store_true",
+        help="debug mode: write output of test scripts to console"
+             " rather than capturing and diff'ing it (disables timeout)")
     parser.add_option("-R", "--restart", action="store_true",
         help="restart at last error")
     parser.add_option("-p", "--port", type="int",
@@ -168,6 +172,7 @@
             for m in msg:
                 print m,
             print
+            sys.stdout.flush()
     else:
         vlog = lambda *msg: None
 
@@ -179,6 +184,8 @@
     if options.interactive and options.jobs > 1:
         print '(--interactive overrides --jobs)'
         options.jobs = 1
+    if options.interactive and options.debug:
+        parser.error("-i/--interactive and -d/--debug are incompatible")
     if options.py3k_warnings:
         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
             parser.error('--py3k-warnings can only be used on Python 2.6+')
@@ -374,8 +381,19 @@
 
 def run(cmd, options):
     """Run command in a sub-process, capturing the output (stdout and stderr).
-    Return the exist code, and output."""
+    Return a tuple (exitcode, output).  output is None in debug mode."""
     # TODO: Use subprocess.Popen if we're running on Python 2.4
+    if options.debug:
+        try:
+            proc = subprocess.Popen(cmd, shell=True)
+            ret = proc.wait()
+        except Timeout:
+            # Weird: when we get a timeout in debug mode, it appears
+            # that HGTMP is removed while the child is still running,
+            # which causes havoc.
+            ret = handletimeout(proc)
+        return (ret, None)
+
     if os.name == 'nt' or sys.platform.startswith('java'):
         tochild, fromchild = os.popen4(cmd)
         tochild.close()
@@ -393,15 +411,19 @@
             if os.WIFEXITED(ret):
                 ret = os.WEXITSTATUS(ret)
         except Timeout:
-            vlog('# Process %d timed out - killing it' % proc.pid)
-            os.kill(proc.pid, signal.SIGTERM)
-            ret = proc.wait()
-            if ret == 0:
-                ret = signal.SIGTERM << 8
+            ret = handletimeout(proc)
             output += ("\n### Abort: timeout after %d seconds.\n"
                        % options.timeout)
     return ret, splitnewlines(output)
 
+def handletimeout(proc):
+    vlog('# Process %d timed out - killing it' % proc.pid)
+    os.kill(proc.pid, signal.SIGTERM)
+    ret = proc.wait()
+    if ret == 0:
+        ret = signal.SIGTERM << 8
+    return ret
+
 def runone(options, test, skips, fails):
     '''tristate output:
     None -> skipped
@@ -487,16 +509,24 @@
     mark = '.'
 
     skipped = (ret == SKIPPED_STATUS)
-    # If reference output file exists, check test output against it
-    if os.path.exists(ref):
+    # If we're not in --debug mode and reference output file exists,
+    # check test output against it.
+    if options.debug:
+        refout = None                   # to match out == None
+    elif os.path.exists(ref):
         f = open(ref, "r")
         refout = splitnewlines(f.read())
         f.close()
     else:
         refout = []
+
     if skipped:
         mark = 's'
-        missing, failed = parsehghaveoutput(out)
+        if out is None:                 # debug mode: nothing to parse
+            missing = ['unknown']
+            failed = None
+        else:
+            missing, failed = parsehghaveoutput(out)
         if not missing:
             missing = ['irrelevant']
         if failed:
@@ -521,7 +551,7 @@
         sys.stdout.write(mark)
         sys.stdout.flush()
 
-    if ret != 0 and not skipped:
+    if ret != 0 and not skipped and not options.debug:
         # Save errors to a file for diagnosis
         f = open(err, "wb")
         for line in out:


More information about the Mercurial-devel mailing list