@@ -179,3 +179,46 @@ def test_valid_syntax(self):
179179 )
180180 finally :
181181 fp .close ()
182+
183+ def test_premature_eof (self ):
184+ """The boot command should write an ECO marker to stdout, read the
185+ preamble from stdin, then execute it.
186+
187+ This test writes some data to STDIN and closes it then to create an
188+ EOF situation.
189+ 1. Fork child tries to read from STDIN, but stops as EOF is received.
190+ 2. Fork child crashes (trying to decompress the junk data)
191+ 3. Fork child's file descriptors (write pipes) are closed by the OS
192+ 4. Fork parent does `dup(<read pipe>, <stdin>)` and `exec(<python>)`
193+ 5. Python reads `b''` (i.e. EOF) from stdin (a closed pipe)
194+ 6. Python runs `''` (a valid script) and exits with success"""
195+
196+ proc = testlib .subprocess .Popen (
197+ args = self .args ,
198+ stdout = testlib .subprocess .PIPE ,
199+ stderr = testlib .subprocess .PIPE ,
200+ stdin = testlib .subprocess .PIPE ,
201+ )
202+
203+ # Do not send all of the data from the preamble
204+ proc .stdin .write (self .preamble [:- 128 ])
205+ proc .stdin .flush ()
206+ proc .stdin .close ()
207+ try :
208+ returncode = proc .wait (timeout = 10 )
209+ except testlib .subprocess .TimeoutExpired :
210+ proc .kill ()
211+ self .fail ("First stage did not handle EOF on STDIN" )
212+ try :
213+ self .assertEqual (0 , returncode )
214+ self .assertEqual (
215+ proc .stdout .read (),
216+ mitogen .parent .BootstrapProtocol .EC0_MARKER + b ("\n " ),
217+ )
218+ self .assertIn (
219+ b ("Error -5 while decompressing data" ),
220+ proc .stderr .read (),
221+ )
222+ finally :
223+ proc .stdout .close ()
224+ proc .stderr .close ()
0 commit comments