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