Skip to content

Commit fb98a23

Browse files
authored
Merge pull request #79 from DataKitchen/fix-init-db-hang
fix: Testgen install was hanging on database init
2 parents d44ebd4 + 0df5940 commit fb98a23

File tree

4 files changed

+51
-20
lines changed

4 files changed

+51
-20
lines changed

dk-installer.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,14 +723,14 @@ def start_cmd(self, *cmd, raise_on_non_zero=True, env=None, **popen_args):
723723
]
724724

725725
try:
726-
with (
727-
stream_iterator(proc, "stdout", stdout_path) as stdout_iter,
728-
stream_iterator(proc, "stderr", stderr_path) as stderr_iter,
729-
):
730-
try:
726+
try:
727+
with (
728+
stream_iterator(proc, "stdout", stdout_path) as stdout_iter,
729+
stream_iterator(proc, "stderr", stderr_path) as stderr_iter,
730+
):
731731
yield proc, stdout_iter, stderr_iter
732-
finally:
733-
proc.wait()
732+
finally:
733+
proc.wait()
734734
if raise_on_non_zero and proc.returncode != 0:
735735
raise CommandFailed
736736
# We capture and raise CommandFailed to allow the client code to raise an empty CommandFailed exception

tests/conftest.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@
1010
from tests.installer import CONSOLE, Action, TESTGEN_DEFAULT_IMAGE
1111

1212

13-
@pytest.fixture
14-
def proc_mock():
15-
proc = Mock()
16-
proc.returncode = 0
17-
proc.wait.return_value = None
18-
proc.poll.return_value = 0
19-
return proc
20-
21-
2213
@pytest.fixture
2314
def stdout_mock():
2415
return Mock(return_value=[])
@@ -29,6 +20,16 @@ def stderr_mock():
2920
return Mock(return_value=[])
3021

3122

23+
@pytest.fixture
24+
def proc_mock(stdout_mock, stderr_mock):
25+
proc = Mock()
26+
proc.returncode = 0
27+
proc.wait.return_value = None
28+
proc.poll.return_value = 0
29+
proc.communicate.return_value = ["\n".join(stdout_mock()).encode(), "\n".join(stderr_mock()).encode()]
30+
return proc
31+
32+
3233
@pytest.fixture
3334
def console_msg_mock():
3435
with patch.object(CONSOLE, "msg") as mock:

tests/test_action.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,26 @@ def test_start_cmd_wait_on_exception(action, popen_mock, stream_iter_mock):
215215

216216
assert proc_mock.wait.call_count == 1
217217
assert exc_info.value.args == ("something went wrong",)
218+
219+
220+
@pytest.mark.unit
221+
@pytest.mark.parametrize("raise_", (True, False))
222+
def test_start_cmd_calls_wait_after_streams_consumed(raise_, action, popen_mock):
223+
try:
224+
with action.start_cmd("cmd", "arg") as (proc_mock, _, _):
225+
proc_mock.returncode = 0
226+
if raise_:
227+
raise RuntimeError()
228+
except RuntimeError:
229+
did_raise = True
230+
else:
231+
did_raise = False
232+
233+
assert did_raise == raise_
234+
proc_mock.assert_has_calls(
235+
[
236+
call.communicate(timeout=1.0),
237+
call.communicate(timeout=1.0),
238+
call.wait(),
239+
]
240+
)

tests/test_stream_iterator.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,28 @@
1111
def popen_stdout_buffer(popen_mock):
1212
buffer = "\n".join(["🔷🔶🔺🔻"[i % 4] + " xxxx" * 20 for i in range(100)]).encode()
1313
popen_mock.communicate.side_effect = [
14-
*[subprocess.TimeoutExpired("cmd", 1, output=buffer[:idx]) for idx in range(0, len(buffer), 38)],
14+
*[subprocess.TimeoutExpired("cmd", 1, output=buffer[:idx], stderr=b"") for idx in range(0, len(buffer), 38)],
15+
(buffer, b""),
1516
(buffer, b""),
1617
]
1718
return buffer
1819

1920

2021
@pytest.mark.unit
2122
def test_stream_iterator(popen_mock, popen_stdout_buffer, tmp_logs_folder):
22-
cmd_log_path = pathlib.Path(tmp_logs_folder) / "cmd-log.txt"
23+
cmd_log_stdout_path = pathlib.Path(tmp_logs_folder) / "cmd-log-out.txt"
24+
cmd_log_stderr_path = pathlib.Path(tmp_logs_folder) / "cmd-log-err.txt"
2325

24-
with stream_iterator(popen_mock, "stdout", cmd_log_path) as stdout_iter:
26+
with (
27+
stream_iterator(popen_mock, "stdout", cmd_log_stdout_path) as stdout_iter,
28+
stream_iterator(popen_mock, "stderr", cmd_log_stderr_path) as stderr_iter,
29+
):
2530
for stdout_line, buffer_line in itertools.zip_longest(stdout_iter, popen_stdout_buffer.splitlines()):
2631
assert stdout_line == buffer_line.decode()
32+
assert list(stderr_iter) == []
2733

28-
assert cmd_log_path.read_bytes() == popen_stdout_buffer
34+
assert cmd_log_stdout_path.read_bytes() == popen_stdout_buffer
35+
assert not cmd_log_stderr_path.exists()
2936

3037

3138
@pytest.mark.unit

0 commit comments

Comments
 (0)