Add script invocation to ScriptQuestion
[quizzer.git] / quizzer / util.py
1 import subprocess as _subprocess
2
3 from . import error as _error
4
5
6 def invoke(args, stdin=None, universal_newlines=False, timeout=None,
7            expect=None, **kwargs):
8     if stdin:
9         stdin_pipe = _subprocess.PIPE
10     else:
11         stdin_pipe = None
12     try:
13         p = _subprocess.Popen(
14             args, stdin=stdin_pipe, stdout=_subprocess.PIPE,
15             stderr=_subprocess.PIPE, universal_newlines=universal_newlines,
16             **kwargs)
17     except FileNotFoundError as e:
18         raise _error.CommandError(arguments=args, stdin=stdin) from e
19     try:
20         stdout,stderr = p.communicate(input=stdin, timeout=timeout)
21     except _subprocess.TimeoutExpired as e:
22         p.kill()
23         stdout,stderr = p.communicate()
24         status = p.wait()
25         raise _error.CommandError(
26             msg='timeout ({}s) expired'.format(timeout),
27             arguments=args, stdin=stdin, stdout=stdout, stderr=stderr,
28             status=status) from e
29     status = p.wait()
30     if expect and status not in expect:
31         raise _error.CommandError(
32             msg='unexpected exit status ({} not in {})'.format(status, expect),
33             args=args, stdin=stdin, stdout=stdout, stderr=stderr,
34             status=status)
35     return (status, stdout, stderr)