@@ -571,3 +571,41 @@ def test_generate_is_repeatable_with_same_mock(self, mock_randrange):
571571 second_run = list (itertools .islice (gen .generate (0 , 2 ), 5 ))
572572
573573 assert first_run == second_run
574+
575+
576+ class FactoryCloseRaceTest (unittest .TestCase ):
577+ """Tests for Connection.factory() handling connections closed during setup."""
578+
579+ def _make_fake_connection_class (self , is_closed = False , is_defunct = False , last_error = None ):
580+ """Create a fake connection class whose __init__ sets up minimal state
581+ needed by factory() without actually connecting to anything."""
582+ from threading import Event
583+
584+ class FakeConnection (Connection ):
585+ def __init__ (self , endpoint , * args , ** kwargs ): # noqa - intentionally skips super().__init__
586+ self .connected_event = Event ()
587+ self .connected_event .set ()
588+ self .is_closed = is_closed
589+ self .is_defunct = is_defunct
590+ self .is_unsupported_proto_version = False
591+ self .last_error = last_error
592+ self .endpoint = endpoint
593+
594+ return FakeConnection
595+
596+ def test_factory_raises_on_closed_during_setup (self ):
597+ FakeConn = self ._make_fake_connection_class (is_closed = True )
598+ with pytest .raises (ConnectionShutdown , match = "closed during setup" ):
599+ FakeConn .factory (DefaultEndPoint ('1.2.3.4' ), timeout = 5 )
600+
601+ def test_factory_raises_on_defunct_during_setup (self ):
602+ FakeConn = self ._make_fake_connection_class (is_defunct = True )
603+ with pytest .raises (ConnectionShutdown , match = "closed during setup" ):
604+ FakeConn .factory (DefaultEndPoint ('1.2.3.4' ), timeout = 5 )
605+
606+ def test_factory_returns_conn_when_connected_normally (self ):
607+ FakeConn = self ._make_fake_connection_class (is_closed = False , is_defunct = False )
608+ result = FakeConn .factory (DefaultEndPoint ('1.2.3.4' ), timeout = 5 )
609+ assert result is not None
610+ assert not result .is_closed
611+ assert not result .is_defunct
0 commit comments