@@ -777,8 +777,8 @@ def test_error_on_stdio_flush_2(self):
777777 finally :
778778 setattr (sys , stream_name , old_stream )
779779
780- @classmethod
781- def _sleep_and_set_event (self , evt , delay = 0.0 ):
780+ @staticmethod
781+ def _sleep_and_set_event (evt , delay = 0.0 ):
782782 time .sleep (delay )
783783 evt .set ()
784784
@@ -829,6 +829,68 @@ def test_forkserver_sigkill(self):
829829 if os .name != 'nt' :
830830 self .check_forkserver_death (signal .SIGKILL )
831831
832+ @staticmethod
833+ def _exit_process ():
834+ sys .exit (0 )
835+
836+ def test_forkserver_auth_is_enabled (self ):
837+ if self .TYPE == "threads" :
838+ self .skipTest (f"test not appropriate for { self .TYPE } " )
839+ if multiprocessing .get_start_method () != "forkserver" :
840+ self .skipTest ("forkserver start method specific" )
841+
842+ forkserver = multiprocessing .forkserver ._forkserver
843+ forkserver .ensure_running ()
844+ self .assertTrue (forkserver ._forkserver_pid )
845+ authkey = forkserver ._forkserver_authkey
846+ self .assertTrue (authkey )
847+ self .assertGreater (len (authkey ), 15 )
848+ addr = forkserver ._forkserver_address
849+ self .assertTrue (addr )
850+
851+ # First, demonstrate that a raw auth handshake as Client makes
852+ # does not raise an error.
853+ client = multiprocessing .connection .Client (addr , authkey = authkey )
854+ client .close ()
855+
856+ # That worked, now launch a quick process.
857+ proc = self .Process (target = self ._exit_process )
858+ proc .start ()
859+ proc .join ()
860+ self .assertEqual (proc .exitcode , 0 )
861+
862+ def test_forkserver_without_auth_fails (self ):
863+ if self .TYPE == "threads" :
864+ self .skipTest (f"test not appropriate for { self .TYPE } " )
865+ if multiprocessing .get_start_method () != "forkserver" :
866+ self .skipTest ("forkserver start method specific" )
867+
868+ forkserver = multiprocessing .forkserver ._forkserver
869+ forkserver .ensure_running ()
870+ self .assertTrue (forkserver ._forkserver_pid )
871+ authkey_len = len (forkserver ._forkserver_authkey )
872+ with unittest .mock .patch .object (
873+ forkserver , '_forkserver_authkey' , None ):
874+ # With no auth handshake, the connection this makes to the
875+ # forkserver will fail to do the file descriptor transfer
876+ # over the pipe as the forkserver is expecting auth.
877+ proc = self .Process (target = self ._exit_process )
878+ with self .assertRaisesRegex (RuntimeError , 'not receive ack' ):
879+ proc .start ()
880+ del proc
881+
882+ # With an incorrect authkey we should get an auth rejection
883+ # rather than the above protocol error.
884+ forkserver ._forkserver_authkey = b'T' * authkey_len
885+ proc = self .Process (target = self ._exit_process )
886+ with self .assertRaises (multiprocessing .AuthenticationError ):
887+ proc .start ()
888+ del proc
889+
890+ # authkey restored, launching processes should work again.
891+ proc = self .Process (target = self ._exit_process )
892+ proc .start ()
893+ proc .join ()
832894
833895#
834896#
0 commit comments