mirror of
https://github.com/chatmail/relay.git
synced 2026-08-29 19:43:14 +00:00
tests: start the journalctl tail before it is needed
iter_output() waited until its caller's first next() call to spawn the journalctl tail, which could lead to log traffic being missed, hanging next() forever: start the tail right away instead.
This commit is contained in:
@@ -13,7 +13,8 @@ from cmdeploy.cmdeploy import get_sshexec
|
||||
|
||||
class TestSSHExecutor:
|
||||
@pytest.fixture(scope="class")
|
||||
def sshexec(self, sshdomain):
|
||||
@classmethod
|
||||
def sshexec(cls, sshdomain):
|
||||
return get_sshexec(sshdomain)
|
||||
|
||||
def test_ls(self, sshexec):
|
||||
|
||||
@@ -411,6 +411,7 @@ class Remote:
|
||||
self._procs = []
|
||||
|
||||
def iter_output(self, logcmd="", ready=None):
|
||||
# run popen run here so the tail is live before caller triggers
|
||||
getjournal = "journalctl -f" if not logcmd else logcmd
|
||||
print(self.sshdomain)
|
||||
if self.sshdomain in ("@local", "localhost"):
|
||||
@@ -425,6 +426,10 @@ class Remote:
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
self._procs.append(popen)
|
||||
return self._read_lines(popen, ready)
|
||||
|
||||
@staticmethod
|
||||
def _read_lines(popen, ready):
|
||||
try:
|
||||
while 1:
|
||||
line = popen.stdout.readline()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
from cmdeploy.tests.plugin import Remote
|
||||
|
||||
|
||||
def _script(tmp_path, name, body):
|
||||
# iter_output splits its command string on whitespace, so any command
|
||||
# with embedded spaces has to live in a file, not an inline string.
|
||||
path = tmp_path / name
|
||||
path.write_text(f"#!/bin/sh\n{body}\n")
|
||||
path.chmod(0o755)
|
||||
return str(path)
|
||||
|
||||
|
||||
def test_iter_output_spawns_before_first_next(tmp_path):
|
||||
"""The tail process must be live before the caller triggers or fast-moving logs can be missed"""
|
||||
script = _script(tmp_path, "late.sh", "sleep 0.2\necho late-line")
|
||||
remote = Remote("@local")
|
||||
lineproducer = remote.iter_output(script)
|
||||
assert remote._procs, "Popen must run on iter_output() itself, not on first next()"
|
||||
assert remote._procs[0].poll() is None
|
||||
assert next(lineproducer) == "late-line"
|
||||
remote.close()
|
||||
|
||||
|
||||
def test_iter_output_ready_fires_after_first_line(tmp_path):
|
||||
"""ready() must wait for the first real line, not fire at spawn time"""
|
||||
script = _script(tmp_path, "trigger.sh", "echo backlog\nsleep 0.2\necho trigger-fired")
|
||||
remote = Remote("@local")
|
||||
calls = []
|
||||
lineproducer = remote.iter_output(script, ready=lambda: calls.append(1))
|
||||
assert calls == []
|
||||
assert next(lineproducer) == "backlog"
|
||||
assert calls == [1]
|
||||
assert next(lineproducer) == "trigger-fired"
|
||||
remote.close()
|
||||
Reference in New Issue
Block a user