@@ -648,6 +648,60 @@ typealias TestPoolStateMachine = PoolStateMachine<
648648 #expect( stateMachine. connections. stats. active == 1 )
649649 }
650650
651+ @available ( macOS 13 . 0 , iOS 16 . 0 , tvOS 16 . 0 , watchOS 9 . 0 , * )
652+ @Test func testTwoConnectionsFailAndSucceed( ) throws {
653+ struct ConnectionFailed : Error , Equatable { }
654+ let clock = MockClock ( )
655+ var configuration = PoolConfiguration ( )
656+ configuration. minimumConnectionCount = 0
657+ configuration. maximumConnectionSoftLimit = 10
658+ configuration. maximumConnectionHardLimit = 10
659+ configuration. keepAliveDuration = . seconds( 2 )
660+ configuration. idleTimeoutDuration = . seconds( 4 )
661+ configuration. maximumConcurrentConnectionRequests = 3
662+
663+ var stateMachine = TestPoolStateMachine (
664+ configuration: configuration,
665+ generator: . init( ) ,
666+ timerCancellationTokenType: MockTimerCancellationToken . self,
667+ clock: clock
668+ )
669+
670+ // request two connections
671+ let mockRequest1 = MockRequest ( connectionType: MockConnection . self)
672+ let leaseAction1 = stateMachine. leaseConnection ( mockRequest1)
673+ guard case . makeConnection( let request1, _) = leaseAction1. connection else {
674+ Issue . record ( )
675+ return
676+ }
677+ let mockRequest2 = MockRequest ( connectionType: MockConnection . self)
678+ let leaseAction2 = stateMachine. leaseConnection ( mockRequest2)
679+ guard case . makeConnection = leaseAction2. connection else {
680+ Issue . record ( )
681+ return
682+ }
683+
684+ // fail connection 1
685+ let failedAction = stateMachine. connectionEstablishFailed ( ConnectionFailed ( ) , for: request1)
686+ #expect( failedAction. request == . none)
687+ guard case . scheduleTimers( let timers) = failedAction. connection else {
688+ Issue . record ( )
689+ return
690+ }
691+ #expect( timers. count == 1 )
692+ let timer = try #require( timers. first)
693+ #expect( timer. underlying. usecase == . backoff)
694+
695+ // make connection
696+ let connection = MockConnection ( id: 1 )
697+ let createdAction = stateMachine. connectionEstablished ( connection, maxStreams: 1 )
698+ #expect( createdAction. request == . leaseConnection( [ mockRequest1] , connection) )
699+
700+ // backoff timer from failed connection triggers
701+ let timerAction = stateMachine. timerTriggered ( timer)
702+ #expect( timerAction. connection == . makeConnection( request1, [ ] ) )
703+ }
704+
651705 /// Test that we limit concurrent connection requests and that when connections are established
652706 /// we request new connections
653707 @available ( macOS 13 . 0 , iOS 16 . 0 , tvOS 16 . 0 , watchOS 9 . 0 , * )
0 commit comments