diff options
-rw-r--r-- | test/conftest.py | 28 | ||||
-rw-r--r-- | test/lib/process.py | 84 |
2 files changed, 41 insertions, 71 deletions
diff --git a/test/conftest.py b/test/conftest.py index a3c8e6a..b96f08f 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -9,7 +9,7 @@ import random from pytest import fixture -from .lib.process import CmdLine, CmdLineRunner, Runner +from .lib.process import CmdLine from .lib.test_repo import TestRepo @@ -98,12 +98,12 @@ def paths(pytestconfig): @fixture(scope='session') -def process_runner(pytestconfig): - runner = Runner() +def base_cmd_line(pytestconfig): + cmd_line = CmdLine.unbuffered() valgrind = pytestconfig.getoption(PARAM_VALGRIND.codename) if valgrind is not None: - runner.add_wrapper(CmdLine(valgrind)) - return runner + cmd_line = CmdLine.wrap(CmdLine(valgrind), cmd_line) + return cmd_line @fixture(scope='session') @@ -132,20 +132,20 @@ class CmdLineWorker(CmdLine): @fixture -def server(process_runner, paths, server_port, sqlite_path): +def server(base_cmd_line, paths, server_port, sqlite_path): args = ['--port', server_port, '--sqlite', sqlite_path] - cmd_line = CmdLineServer(paths.server_binary, *args) - with process_runner.run_async(cmd_line) as server: + cmd_line = CmdLineServer.wrap(base_cmd_line, CmdLine(paths.server_binary, *args)) + with cmd_line.run_async() as server: yield server assert server.returncode == 0 @fixture -def workers(process_runner, paths, server_port): +def workers(base_cmd_line, paths, server_port): args = ['--host', '127.0.0.1', '--port', server_port] - cmd_line = CmdLineWorker(paths.worker_binary, *args) - with process_runner.run_async(cmd_line) as worker1, \ - process_runner.run_async(cmd_line) as worker2: + cmd_line = CmdLineWorker.wrap(base_cmd_line, CmdLine(paths.worker_binary, *args)) + with cmd_line.run_async() as worker1, \ + cmd_line.run_async() as worker2: yield [worker1, worker2] assert worker1.returncode == 0 assert worker2.returncode == 0 @@ -157,9 +157,9 @@ def server_and_workers(server, workers): @fixture -def client(process_runner, paths, server_port): +def client(base_cmd_line, paths, server_port): args = ['--host', '127.0.0.1', '--port', server_port] - cmd_line = CmdLineRunner(process_runner, paths.client_binary, *args) + cmd_line = CmdLine.wrap(base_cmd_line, CmdLine(paths.client_binary, *args)) return cmd_line diff --git a/test/lib/process.py b/test/lib/process.py index b9b24fb..b32d093 100644 --- a/test/lib/process.py +++ b/test/lib/process.py @@ -64,6 +64,10 @@ class CmdLine: raise RuntimeError("couldn't find a binary: " + binary) return path + @staticmethod + def unbuffered(): + return CmdLine('stdbuf', '-o0') + def __init__(self, binary, *args, name=None): binary = self.which(binary) argv = [binary] + list(args) @@ -82,11 +86,14 @@ class CmdLine: def wrap(cls, outer, inner): return cls(outer.argv[0], *outer.argv[1:], *inner.argv, name=inner.process_name) - def log_process_start(self): - if len(self.argv) > 1: - logging.info('Executing binary %s with arguments: %s', self.binary, ' '.join(self.argv[1:])) - else: - logging.info('Executing binary %s', self.binary) + def run(self, *argv): + result = Process.run(*self.argv, *argv) + return result.returncode, result.stdout + + @contextmanager + def run_async(self, *argv): + with Process(self, *argv) as process: + yield process class LoggingEventProcessReady(LoggingEvent): @@ -111,18 +118,30 @@ class Process(subprocess.Popen): } @staticmethod + def _log_process_start(argv): + if len(argv) > 1: + logging.info('Executing binary %s with arguments: %s', argv[0], ' '.join(argv[1:])) + else: + logging.info('Executing binary %s', argv[0]) + + @staticmethod def run(*args, **kwargs): + argv = list(args) + Process._log_process_start(argv) try: - return subprocess.run(list(args), check=True, **Process._COMMON_ARGS, **kwargs) + return subprocess.run(argv, check=True, **Process._COMMON_ARGS, **kwargs) except subprocess.CalledProcessError as e: logging.error('Command %s exited with code %s', e.cmd, e.returncode) logging.error('Output:\n%s', e.output) raise - def __init__(self, cmd_line): + def __init__(self, cmd_line, *args): self.cmd_line = cmd_line - super().__init__(cmd_line.argv, **Process._COMMON_ARGS) + argv = cmd_line.argv + list(args) + self._log_process_start(argv) + + super().__init__(argv, **Process._COMMON_ARGS) logging.info('Process %s has started', self.log_id) ready_event = LoggingEventProcessReady(self) @@ -159,52 +178,3 @@ class Process(subprocess.Popen): logging.info('Process %s failed to terminate in time, killing it', self.log_id) self.kill() self.wait(timeout=Process.SHUT_DOWN_TIMEOUT_SEC) - - -class Runner: - @staticmethod - def unbuffered(): - return CmdLine('stdbuf', '-o0') - - def __init__(self): - self.wrappers = [] - self.add_wrapper(self.unbuffered()) - - def add_wrapper(self, cmd_line): - self.wrappers.append(cmd_line) - - def _wrap(self, cmd_line): - for wrapper in self.wrappers: - cmd_line = cmd_line.wrap(wrapper, cmd_line) - return cmd_line - - def run(self, cmd_line): - cmd_line = self._wrap(cmd_line) - cmd_line.log_process_start() - - result = Process.run(*cmd_line.argv) - return result.returncode, result.stdout - - @contextmanager - def run_async(self, cmd_line): - cmd_line = self._wrap(cmd_line) - cmd_line.log_process_start() - - with Process(cmd_line) as process: - yield process - - -class CmdLineRunner: - def __init__(self, runner, binary, *args): - self.runner = runner - self.binary = binary - self.args = list(args) - - def _build(self, *args): - return CmdLine(self.binary, *self.args, *args) - - def run(self, *args): - return self.runner.run(self._build(*args)) - - def run_async(self, *args): - return self.runner.run_async(self._build(*args)) |