From 64e598c2b4feead066fa51ff836c32e247590b7a Mon Sep 17 00:00:00 2001 From: shadeofblue Date: Thu, 13 Jan 2022 15:57:03 +0100 Subject: [PATCH] + test, fix --- goth/runner/process.py | 8 ++- .../runner/probe/test_run_command_on_host.py | 51 ++++++++++++------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/goth/runner/process.py b/goth/runner/process.py index 01c76e2f..2b7b265c 100644 --- a/goth/runner/process.py +++ b/goth/runner/process.py @@ -14,14 +14,18 @@ class ProcessMonitor: + """Monitor enabling acquisition of the process object of a running command.""" + _process: Optional[asyncio.subprocess.Process] = None async def get_process(self) -> asyncio.subprocess.Process: + """Wait for and return the `Process` object.""" while not self._process: await asyncio.sleep(0.1) return self._process def set_process(self, process: asyncio.subprocess.Process): + """Set the process object.""" self._process = process @@ -47,8 +51,8 @@ async def run_command( :param log_prefix: prefix for log lines with command output; ignored if `cmd_logger` is specified. Default: name of the command :param timeout: timeout for the command, in seconds. Default: 15 minutes - :param process_monitor: and optional `ProcessMonitor` to which the spawned process will be - reported, so that it can be communicated with from the calling code + :param process_monitor: and optional `ProcessMonitor` to which the spawned process + will be reported, so that it can be communicated with from the calling code """ logger.info("Running local command: %s", " ".join(args)) diff --git a/test/unit/runner/probe/test_run_command_on_host.py b/test/unit/runner/probe/test_run_command_on_host.py index 5485d2aa..27965f7b 100644 --- a/test/unit/runner/probe/test_run_command_on_host.py +++ b/test/unit/runner/probe/test_run_command_on_host.py @@ -1,4 +1,5 @@ """Tests for the method Probe.run_command_on_host.""" +import asyncio import os import pytest from unittest.mock import MagicMock @@ -7,16 +8,28 @@ import goth.runner.container.yagna from goth.runner.probe import RequestorProbe +CONTAINER_REST_PORT = 6006 -@pytest.mark.asyncio -async def test_run_command_on_host(monkeypatch): - """Test if the method `run_command_on_host` works as expected.""" + +async def env_lines_to_dict(lines): + """Convert the lines received from the `env` command into a dictionary.""" + # The monitor should guarantee that we don't skip any events + assert len(lines.past_events) == 0, lines.past_events + env = {} + async for line in lines: + tokens = line.split("=", 1) + if len(tokens) == 2: + env[tokens[0]] = tokens[1] + return env + + +def mock_probe(monkeypatch): + """Get a mocked `RequestorProbe`.""" runner = MagicMock() docker_client = MagicMock() container_config = MagicMock(use_proxy=False) log_config = MagicMock() - container_rest_port = 6006 monkeypatch.setattr(goth.runner.probe, "YagnaContainer", MagicMock(spec="ports")) monkeypatch.setattr(goth.runner.probe, "Cli", MagicMock(spec="yagna")) @@ -28,29 +41,31 @@ async def test_run_command_on_host(monkeypatch): config=container_config, log_config=log_config, ) - probe.container.ports = {YAGNA_REST_PORT: container_rest_port} - - async def func(lines): - # The monitor should guarantee that we don't skip any events - assert len(lines.past_events) == 0, lines.past_events - env = {} - async for line in lines: - tokens = line.split("=", 1) - if len(tokens) == 2: - env[tokens[0]] = tokens[1] - return env + probe.container.ports = {YAGNA_REST_PORT: CONTAINER_REST_PORT} + return probe + + +@pytest.mark.asyncio +async def test_run_command_on_host(monkeypatch): + """Test if the method `run_command_on_host` works as expected.""" + + probe = mock_probe(monkeypatch) async with probe.run_command_on_host( "/usr/bin/env", env=os.environ, - ) as (_task, monitor): - assertion = monitor.add_assertion(func) + get_process_monitor=True, + ) as (_task, monitor, process_monitor): + assertion = monitor.add_assertion(env_lines_to_dict) + proc: asyncio.subprocess.Process = await process_monitor.get_process() + + assert await proc.wait() == 0 result = await assertion.wait_for_result(timeout=1) assert result["YAGNA_APPKEY"] == probe.app_key assert result["YAGNA_API_URL"] == YAGNA_REST_URL.substitute( - host="127.0.0.1", port=container_rest_port + host="127.0.0.1", port=CONTAINER_REST_PORT ) assert result["GSB_URL"] == YAGNA_BUS_URL.substitute(host=None)