Skip to content

Commit ea59e4d

Browse files
committed
tests: Add first_stage_test that checks that the stage handles an too early EOF
Add first_stage_test that checks that the first stage handles an too early EOF. Without the next commit, this hangs forever in a loop causing a Python process taking up to 100% usage of a core. Signed-off-by: Marc Hartmayer <[email protected]>
1 parent 7be79d0 commit ea59e4d

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

tests/first_stage_test.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,35 @@ def test_valid_syntax(self):
5050
)
5151
finally:
5252
fp.close()
53+
54+
def test_eof_too_early(self):
55+
options = mitogen.parent.Options(max_message_size=123)
56+
conn = mitogen.parent.Connection(options, self.router)
57+
conn.context = mitogen.core.Context(None, 123)
58+
args = conn.get_boot_command()
59+
60+
# The boot command should write an ECO marker to stdout, read the
61+
# preamble from stdin, then execute it.
62+
63+
# This test attaches closes stdin to create a specific failure
64+
# 1. Fork child tries to read from STDIN, but fails as it is closed
65+
# 2. Fork child raises TimeoutError
66+
# 3. Fork child's file descriptors (write pipes) are closed by the OS
67+
# 4. Fork parent does `dup(<read pipe>, <stdin>)` and `exec(<python>)`
68+
# 5. Python reads `b''` (i.e. EOF) from stdin (a closed pipe)
69+
# 6. Python runs `''` (a valid script) and exits with success
70+
71+
proc = mitogen.parent.popen(args=args,
72+
stdout=subprocess.PIPE,
73+
stderr=subprocess.PIPE,
74+
stdin=subprocess.PIPE,
75+
)
76+
stdout, stderr = proc.communicate(input=b'not enough data')
77+
78+
self.assertEqual(0, proc.returncode)
79+
self.assertEqual(stdout,
80+
mitogen.parent.BootstrapProtocol.EC0_MARKER+b('\n'))
81+
self.assertIn(
82+
b("Error -3 while decompressing data"), # Unknown compression method
83+
stderr,
84+
)

0 commit comments

Comments
 (0)