@@ -464,6 +464,92 @@ def cancel_make_transport():
464
464
465
465
466
466
class Test_UV_Process (_TestProcess , tb .UVTestCase ):
467
+
468
+ def test_process_lated_stdio_init (self ):
469
+
470
+ class TestProto :
471
+ def __init__ (self ):
472
+ self .lost = 0
473
+ self .stages = []
474
+
475
+ def connection_made (self , transport ):
476
+ self .stages .append (('CM' , transport ))
477
+
478
+ def pipe_data_received (self , fd , data ):
479
+ if fd == 1 :
480
+ self .stages .append (('STDOUT' , data ))
481
+
482
+ def pipe_connection_lost (self , fd , exc ):
483
+ if fd == 1 :
484
+ self .stages .append (('STDOUT' , 'LOST' ))
485
+
486
+ def process_exited (self ):
487
+ self .stages .append ('PROC_EXIT' )
488
+
489
+ def connection_lost (self , exc ):
490
+ self .stages .append (('CL' , self .lost , exc ))
491
+ self .lost += 1
492
+
493
+ async def run (** kwargs ):
494
+ return await self .loop .subprocess_shell (
495
+ lambda : TestProto (),
496
+ 'echo 1' ,
497
+ ** kwargs )
498
+
499
+ with self .subTest ('paused, stdin pipe' ):
500
+ transport , proto = self .loop .run_until_complete (
501
+ run (stdin = subprocess .PIPE ,
502
+ stdout = subprocess .PIPE ,
503
+ stderr = subprocess .PIPE ,
504
+ __uvloop_sleep_after_fork = True ))
505
+ self .assertIsNot (transport , None )
506
+ self .assertEqual (transport .get_returncode (), 0 )
507
+ self .assertEqual (
508
+ set (proto .stages ),
509
+ {
510
+ ('CM' , transport ),
511
+ 'PROC_EXIT' ,
512
+ ('STDOUT' , b'1\n ' ),
513
+ ('STDOUT' , 'LOST' ),
514
+ ('CL' , 0 , None )
515
+ })
516
+
517
+ with self .subTest ('paused, no stdin' ):
518
+ transport , proto = self .loop .run_until_complete (
519
+ run (stdin = None ,
520
+ stdout = subprocess .PIPE ,
521
+ stderr = subprocess .PIPE ,
522
+ __uvloop_sleep_after_fork = True ))
523
+ self .assertIsNot (transport , None )
524
+ self .assertEqual (transport .get_returncode (), 0 )
525
+ self .assertEqual (
526
+ set (proto .stages ),
527
+ {
528
+ ('CM' , transport ),
529
+ 'PROC_EXIT' ,
530
+ ('STDOUT' , b'1\n ' ),
531
+ ('STDOUT' , 'LOST' ),
532
+ ('CL' , 0 , None )
533
+ })
534
+
535
+ with self .subTest ('no pause, no stdin' ):
536
+ transport , proto = self .loop .run_until_complete (
537
+ run (stdin = None ,
538
+ stdout = subprocess .PIPE ,
539
+ stderr = subprocess .PIPE ))
540
+ self .loop .run_until_complete (transport ._wait ())
541
+ self .assertEqual (transport .get_returncode (), 0 )
542
+ self .assertIsNot (transport , None )
543
+ self .assertEqual (
544
+ set (proto .stages ),
545
+ {
546
+ ('CM' , transport ),
547
+ 'PROC_EXIT' ,
548
+ ('STDOUT' , b'1\n ' ),
549
+ ('STDOUT' , 'LOST' ),
550
+ ('CL' , 0 , None )
551
+ })
552
+
467
553
def test_process_streams_redirect (self ):
468
554
# This won't work for asyncio implementation of subprocess
469
555
0 commit comments