@@ -956,6 +956,78 @@ func TestFlightAuthSessionStoreReconnectRefreshesDurableSessionMetadata(t *testi
956956 }
957957}
958958
959+ func TestFlightAuthSessionStoreReconnectFailureUpdatesDurableSessionState (t * testing.T ) {
960+ tests := []struct {
961+ name string
962+ reconnectErr error
963+ wantState DurableSessionState
964+ wantReconnectCall int
965+ }{
966+ {
967+ name : "terminal stale ownership closes durable session" ,
968+ reconnectErr : MarkDurableReconnectTerminal (errors .New ("stale owner" )),
969+ wantState : DurableSessionStateClosed ,
970+ wantReconnectCall : 1 ,
971+ },
972+ {
973+ name : "transient reconnect failure leaves durable session active" ,
974+ reconnectErr : context .DeadlineExceeded ,
975+ wantState : DurableSessionStateActive ,
976+ wantReconnectCall : 2 ,
977+ },
978+ }
979+
980+ for _ , tt := range tests {
981+ t .Run (tt .name , func (t * testing.T ) {
982+ durable := & captureDurableSessionStore {
983+ records : map [string ]DurableSessionRecord {
984+ "durable-token" : {
985+ SessionToken : "durable-token" ,
986+ Username : "postgres" ,
987+ OrgID : "analytics" ,
988+ WorkerID : 17 ,
989+ OwnerEpoch : 4 ,
990+ CPInstanceID : "cp-old:boot-a" ,
991+ State : DurableSessionStateActive ,
992+ ExpiresAt : time .Now ().Add (time .Hour ),
993+ LastSeenAt : time .Now ().Add (- time .Minute ),
994+ },
995+ },
996+ }
997+ reconnectCalls := 0
998+ provider := & testDurableSessionProvider {
999+ durableStore : durable ,
1000+ reconnectSessionFn : func (ctx context.Context , record DurableSessionRecord ) (int32 , * server.FlightExecutor , error ) {
1001+ reconnectCalls ++
1002+ return 0 , nil , tt .reconnectErr
1003+ },
1004+ }
1005+ store := newFlightAuthSessionStore (provider , time .Minute , time .Hour , time .Minute , time .Hour , 0 , Options {})
1006+
1007+ if session , ok := store .GetByTokenContext (context .Background (), "durable-token" ); ok || session != nil {
1008+ t .Fatal ("expected durable token reconnect to fail" )
1009+ }
1010+ record , err := durable .GetSession ("durable-token" )
1011+ if err != nil {
1012+ t .Fatalf ("GetSession: %v" , err )
1013+ }
1014+ if record == nil {
1015+ t .Fatal ("expected durable session record to remain present" )
1016+ }
1017+ if record .State != tt .wantState {
1018+ t .Fatalf ("expected durable session state %q, got %q" , tt .wantState , record .State )
1019+ }
1020+
1021+ if session , ok := store .GetByTokenContext (context .Background (), "durable-token" ); ok || session != nil {
1022+ t .Fatal ("expected second durable token lookup to fail" )
1023+ }
1024+ if reconnectCalls != tt .wantReconnectCall {
1025+ t .Fatalf ("expected %d reconnect attempts, got %d" , tt .wantReconnectCall , reconnectCalls )
1026+ }
1027+ })
1028+ }
1029+ }
1030+
9591031func TestFlightAuthSessionStoreRejectsNewSessionsWhileDraining (t * testing.T ) {
9601032 provider := & testDurableSessionProvider {
9611033 createSessionFn : func (ctx context.Context , username string , pid int32 , memoryLimit string , threads int ) (int32 , * server.FlightExecutor , error ) {
0 commit comments