]> arthur.barton.de Git - bup.git/blobdiff - buptest.py
lib/xstat: use // not / for int division for py3
[bup.git] / buptest.py
index 135713e104c2f845961fd77eb6f19177f4f657d7..dd145eed2d467b0170396849f04f062cebf7b180 100644 (file)
@@ -1,11 +1,12 @@
 
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function
+from collections import namedtuple
 from contextlib import contextmanager
 from os.path import basename, dirname, realpath
 from pipes import quote
 from contextlib import contextmanager
 from os.path import basename, dirname, realpath
 from pipes import quote
-from subprocess import PIPE, Popen, check_call
+from subprocess import PIPE, Popen
 from traceback import extract_stack
 from traceback import extract_stack
-import subprocess, sys, tempfile
+import errno, os, subprocess, sys, tempfile
 
 from wvtest import WVPASSEQ, wvfailure_count
 
 
 from wvtest import WVPASSEQ, wvfailure_count
 
@@ -33,7 +34,11 @@ def no_lingering_errors():
 
 # Assumes (of course) this file is at the top-level of the source tree
 _bup_tmp = realpath(dirname(__file__) + '/t/tmp')
 
 # Assumes (of course) this file is at the top-level of the source tree
 _bup_tmp = realpath(dirname(__file__) + '/t/tmp')
-helpers.mkdirp(_bup_tmp)
+try:
+    os.makedirs(_bup_tmp)
+except OSError as e:
+    if e.errno != errno.EEXIST:
+        raise
 
 
 @contextmanager
 
 
 @contextmanager
@@ -46,25 +51,49 @@ def test_tempdir(prefix):
         subprocess.call(['rm', '-rf', tmpdir])
 
 
         subprocess.call(['rm', '-rf', tmpdir])
 
 
+ex_res = namedtuple('SubprocResult', ['out', 'err', 'proc', 'rc'])
+
+def run(cmd, check=True, input=None, **kwargs):
+    """Run a subprocess as per subprocess.Popen(cmd, **kwargs) followed by
+    communicate(input=input).  If check is true, then throw an
+    exception if the subprocess exits with non-zero status.  Return a
+    SubprocResult tuple.
+
+    """
+    if input:
+        assert 'stdin' not in kwargs
+        kwargs['stdin'] = PIPE
+    p = Popen(cmd, **kwargs)
+    out, err = p.communicate(input=input)
+    if check and p.returncode != 0:
+        raise Exception('subprocess %r failed with status %d%s'
+                        % (' '.join(map(quote, cmd)), p.returncode,
+                           (', stderr: %r' % err) if err else ''))
+    return ex_res(out=out, err=err, proc=p, rc=p.returncode)
+
 def logcmd(cmd):
     if isinstance(cmd, basestring):
         print(cmd, file=sys.stderr)
     else:
         print(' '.join(map(quote, cmd)), file=sys.stderr)
 
 def logcmd(cmd):
     if isinstance(cmd, basestring):
         print(cmd, file=sys.stderr)
     else:
         print(' '.join(map(quote, cmd)), file=sys.stderr)
 
-def exc(cmd, shell=False):
+def ex(cmd, **kwargs):
+    """Print cmd to stderr and then run it as per ex(...).
+    Print the subprocess stderr to stderr if stderr=PIPE and there's
+    any data.
+    """
     logcmd(cmd)
     logcmd(cmd)
-    check_call(cmd, shell=shell)
+    result = run(cmd, **kwargs)
+    if result.err:
+        sys.stderr.write(result.err)
+    return result
 
 
-def exo(cmd, stdin=None, stdout=True, stderr=False, shell=False, check=True):
-    logcmd(cmd)
-    p = Popen(cmd,
-              stdin=None,
-              stdout=(PIPE if stdout else None),
-              stderr=PIPE,
-              shell=shell)
-    out, err = p.communicate()
-    if check and p.returncode != 0:
-        raise Exception('subprocess %r failed with status %d, stderr: %r'
-                        % (' '.join(map(quote, cmd)), p.returncode, err))
-    return out, err, p
+def exo(cmd, **kwargs):
+    """Print cmd to stderr and then run it as per ex(..., stdout=PIPE).
+    Print the subprocess stderr to stderr if stderr=PIPE and there's
+    any data.
+
+    """
+    assert 'stdout' not in kwargs
+    kwargs['stdout'] = PIPE
+    return ex(cmd, **kwargs)