Skip to content

Commit fa2f663

Browse files
committed
tests: Add first_stage_test with closed STDIN
Without the next commit, this hangs forever in the select call. Signed-off-by: Marc Hartmayer <[email protected]>
1 parent d2b0b42 commit fa2f663

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
@@ -1,4 +1,5 @@
11
import subprocess
2+
import sys
23

34
import mitogen.core
45
import mitogen.parent
@@ -82,3 +83,34 @@ def test_eof_too_early(self):
8283
b("Error -3 while decompressing data"), # Unknown compression method
8384
stderr,
8485
)
86+
87+
def test_timeout_error(self):
88+
options = mitogen.parent.Options(max_message_size=123)
89+
conn = mitogen.parent.Connection(options, self.router)
90+
conn.context = mitogen.core.Context(None, 123)
91+
args = conn.get_boot_command()
92+
93+
# The boot command should write an ECO marker to stdout, read the
94+
# preamble from stdin, then execute it.
95+
96+
# This test attaches closes stdin to create a specific failure
97+
# 1. Fork child tries to read from STDIN, but fails as it is closed
98+
# 2. Fork child raises TimeoutError
99+
# 3. Fork child's file descriptors (write pipes) are closed by the OS
100+
# 4. Fork parent does `dup(<read pipe>, <stdin>)` and `exec(<python>)`
101+
# 5. Python reads `b''` (i.e. EOF) from stdin (a closed pipe)
102+
# 6. Python runs `''` (a valid script) and exits with success
103+
104+
proc = mitogen.parent.popen(args=args,
105+
stdout=subprocess.PIPE,
106+
stderr=subprocess.PIPE,
107+
preexec_fn=sys.stdin.close
108+
)
109+
stdout, stderr = proc.communicate()
110+
self.assertEqual(0, proc.returncode)
111+
self.assertEqual(stdout,
112+
mitogen.parent.BootstrapProtocol.EC0_MARKER+b('\n'))
113+
self.assertIn(
114+
b("TimeoutError"),
115+
stderr,
116+
)

0 commit comments

Comments
 (0)