userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
shell.py
1
import
contextlib
2
import
logging
3
import
subprocess
4
import
threading
5
6
from
testsuite.utils
import
traceback
7
8
logger = logging.getLogger(__name__)
9
10
11
class
BaseError
(Exception):
12
pass
13
14
15
class
SubprocessFailed
(
BaseError
):
16
pass
17
18
19
__tracebackhide__ = traceback.hide(BaseError)
20
21
22
def
execute(args, *, env=None, verbose: int, command_alias: str) ->
None
:
23
buffer: list[str] = []
24
lock_process_completion = threading.Lock()
25
process_completed =
False
26
27
def
_capture_output(stream):
28
for
line
in
stream:
29
try
:
30
decoded = line.decode(
'utf-8'
)
31
except
UnicodeDecodeError
as
err:
32
logger.error(
33
'Failed to decode subprocess output'
,
34
exc_info=err,
35
)
36
continue
37
decoded = decoded.rstrip(
'\r\n'
)
38
with
lock_process_completion:
39
if
process_completed:
40
# Treat postmortem output from pipe as error.
41
# For example pg_ctl does not close pipe on exit so we may
42
# get output later from a started process.
43
logger.warning(
'%s: %s'
, ident, decoded)
44
else
:
45
if
verbose > 1:
46
logger.info(
'%s: %s'
, ident, decoded)
47
else
:
48
buffer.append(decoded)
49
50
def
_do_capture_output(stream):
51
with
contextlib.closing(stream):
52
_capture_output(stream)
53
54
process = subprocess.Popen(
55
args,
56
env=env,
57
stdout=subprocess.PIPE,
58
stderr=subprocess.STDOUT,
59
)
60
ident = f
'{command_alias}[{process.pid}]'
61
62
thread = threading.Thread(target=_do_capture_output, args=(process.stdout,))
63
thread.daemon =
True
64
thread.start()
65
exit_code = process.wait()
66
with
lock_process_completion:
67
process_completed =
True
68
if
exit_code != 0:
69
for
msg
in
buffer:
70
logger.error(
'%s: %s'
, ident, msg)
71
logger.error(
72
'%s: subprocess %s exited with code %d'
,
73
ident,
74
process.args,
75
exit_code,
76
)
77
78
if
exit_code != 0:
79
raise
SubprocessFailed(
80
f
'Subprocess {ident} exited with code {exit_code}\n'
81
f
'... args={process.args!r}'
82
)
en
testsuite
environment
shell.py
Generated on
for userver by
Doxygen
1.17.0