@@ -222,3 +222,37 @@ def test_premature_eof(self):
222222 finally :
223223 proc .stdout .close ()
224224 proc .stderr .close ()
225+
226+ def test_timeout_error (self ):
227+ """ The boot command should write an ECO marker to stdout, try to read
228+ the preamble from stdin, then fail with an TimeoutError as nothing is
229+ written.
230+
231+ This test writes no data to STDIN to enforce a time out.
232+ 1. Fork child tries to read from STDIN, but runs into the timeout
233+ 2. Fork child raises TimeoutError
234+ 3. Fork child's file descriptors (write pipes) are closed by the OS
235+ 4. Fork parent does `dup(<read pipe>, <stdin>)` and `exec(<python>)`
236+ 5. Python reads `b''` (i.e. EOF) from stdin (a closed pipe)
237+ 6. Python runs `''` (a valid script) and exits with success
238+ """
239+
240+ proc = testlib .subprocess .Popen (
241+ args = self .args ,
242+ stdout = testlib .subprocess .PIPE ,
243+ stderr = testlib .subprocess .PIPE ,
244+ close_fds = True ,
245+ )
246+ try :
247+ returncode = proc .wait (timeout = 12 )
248+ except testlib .subprocess .TimeoutExpired :
249+ proc .kill ()
250+ self .fail ("Timeout situation was not recognized" )
251+ stdout = proc .stdout .read ()
252+ stderr = proc .stderr .read ()
253+ self .assertEqual (0 , returncode )
254+ self .assertEqual (stdout , mitogen .parent .BootstrapProtocol .EC0_MARKER + b ("\n " ))
255+ self .assertIn (
256+ b ("TimeoutError" ),
257+ stderr ,
258+ )
0 commit comments