]> arthur.ath.cx Git - bup.git/blob - test/lib/buptest/__init__.py
e2b5284da6eca9aacd04fc4a53b40e7d59ee568d
[bup.git] / test / lib / buptest / __init__.py
1
2 from __future__ import absolute_import, print_function
3 from collections import namedtuple
4 from contextlib import contextmanager
5 from os.path import abspath, basename, dirname, realpath
6 from pipes import quote
7 from subprocess import PIPE, Popen
8 from traceback import extract_stack
9 import errno, os, subprocess, sys, tempfile
10
11 from bup import helpers
12 from bup.compat import fsencode
13 from bup.io import byte_stream
14
15
16 ex_res = namedtuple('SubprocResult', ['out', 'err', 'proc', 'rc'])
17
18 def run(cmd, check=True, input=None, **kwargs):
19     """Run a subprocess as per subprocess.Popen(cmd, **kwargs) followed by
20     communicate(input=input).  If check is true, then throw an
21     exception if the subprocess exits with non-zero status.  Return a
22     SubprocResult tuple.
23
24     """
25     if input:
26         assert 'stdin' not in kwargs
27         kwargs['stdin'] = PIPE
28     p = Popen(cmd, **kwargs)
29     out, err = p.communicate(input=input)
30     if check and p.returncode != 0:
31         raise Exception('subprocess %r failed with status %d%s'
32                         % (cmd, p.returncode,
33                            (', stderr: %r' % err) if err else ''))
34     return ex_res(out=out, err=err, proc=p, rc=p.returncode)
35
36 def logcmd(cmd):
37     s = helpers.shstr(cmd)
38     if isinstance(cmd, str):
39         print(s, file=sys.stderr)
40     else:
41         # bytes - for now just escape it
42         print(s.decode(errors='backslashreplace'), file=sys.stderr)
43
44 def ex(cmd, **kwargs):
45     """Print cmd to stderr and then run it as per ex(...).
46     Print the subprocess stderr to stderr if stderr=PIPE and there's
47     any data.
48     """
49     logcmd(cmd)
50     result = run(cmd, **kwargs)
51     if result.err:
52         sys.stderr.flush()
53         byte_stream(sys.stderr).write(result.err)
54     return result
55
56 def exo(cmd, **kwargs):
57     """Print cmd to stderr and then run it as per ex(..., stdout=PIPE).
58     Print the subprocess stderr to stderr if stderr=PIPE and there's
59     any data.
60
61     """
62     assert 'stdout' not in kwargs
63     kwargs['stdout'] = PIPE
64     return ex(cmd, **kwargs)