@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/stretchr/testify/require"
1212 "google.golang.org/grpc"
13+ "google.golang.org/grpc/connectivity"
1314
1415 "github.com/ydb-platform/ydb-go-sdk/v3/internal/conn/state"
1516 "github.com/ydb-platform/ydb-go-sdk/v3/internal/endpoint"
@@ -999,3 +1000,99 @@ func TestPool_EndpointsToConnectionsNilMap(t *testing.T) {
9991000 e := endpoint .New ("closed:2135" )
10001001 require .Empty (t , endpointsToConnections (pool , []endpoint.Endpoint {e }))
10011002}
1003+
1004+ func TestPool_AddRefReturnsErrorWhenClosed (t * testing.T ) {
1005+ ctx := context .Background ()
1006+ pool := NewPool (ctx , & mockConfig {})
1007+ require .NoError (t , pool .RemoveRef (ctx ))
1008+
1009+ err := pool .AddRef (ctx )
1010+ require .ErrorIs (t , err , ErrClosedPool )
1011+ }
1012+
1013+ func TestPool_RemoveRefReturnsCloseErrors (t * testing.T ) {
1014+ ctx := context .Background ()
1015+ pool := NewPool (ctx , & mockConfig {})
1016+
1017+ e := endpoint .New ("close-error:2135" )
1018+ cc := newConn (e , pool )
1019+ cc .mtx .Lock ()
1020+ cc .grpcConn = & mockGrpcConn {closeErr : errors .New ("grpc close failed" )}
1021+ cc .mtx .Unlock ()
1022+
1023+ pool .mu .Lock ()
1024+ pool .conns [e .Key ()] = & connValue {cc : cc }
1025+ pool .mu .Unlock ()
1026+
1027+ err := pool .RemoveRef (ctx )
1028+ require .Error (t , err )
1029+ require .Contains (t , err .Error (), "connection pool close failed" )
1030+ }
1031+
1032+ func TestPool_OnResolveCallback (t * testing.T ) {
1033+ ctx := context .Background ()
1034+ pool := NewPool (ctx , & mockConfig {})
1035+ defer func () {
1036+ _ = pool .RemoveRef (ctx )
1037+ }()
1038+
1039+ target := "localhost:2135"
1040+ e := endpoint .New (target )
1041+ _ = pool .Get (e )
1042+
1043+ done := pool .onResolveCallback (ctx , trace.DriverResolveStartInfo {
1044+ Target : target ,
1045+ Resolved : []string {target },
1046+ })
1047+ done (trace.DriverResolveDoneInfo {Error : errors .New ("resolve failed" )})
1048+
1049+ require .True (t , testPoolHasConn (pool , e .Key ()))
1050+ }
1051+
1052+ func TestPool_CloseConnsForFailedResolveSkipsAlreadyClosed (t * testing.T ) {
1053+ ctx := context .Background ()
1054+ pool := NewPool (ctx , & mockConfig {})
1055+ defer func () {
1056+ _ = pool .RemoveRef (ctx )
1057+ }()
1058+
1059+ target := "localhost:2135"
1060+ e := endpoint .New (target )
1061+ cc := newConn (e , pool )
1062+ cc .mtx .Lock ()
1063+ cc .closed = true
1064+ cc .mtx .Unlock ()
1065+
1066+ pool .mu .Lock ()
1067+ pool .conns [e .Key ()] = & connValue {cc : cc }
1068+ pool .mu .Unlock ()
1069+
1070+ require .NotPanics (t , func () {
1071+ pool .closeConnsForFailedResolve (ctx , target )
1072+ })
1073+ }
1074+
1075+ type mockGrpcConn struct {
1076+ closeErr error
1077+ }
1078+
1079+ func (m * mockGrpcConn ) Invoke (context.Context , string , any , any , ... grpc.CallOption ) error {
1080+ return nil
1081+ }
1082+
1083+ func (m * mockGrpcConn ) NewStream (
1084+ context.Context ,
1085+ * grpc.StreamDesc ,
1086+ string ,
1087+ ... grpc.CallOption ,
1088+ ) (grpc.ClientStream , error ) {
1089+ return nil , errors .New ("not implemented" )
1090+ }
1091+
1092+ func (m * mockGrpcConn ) Close () error {
1093+ return m .closeErr
1094+ }
1095+
1096+ func (m * mockGrpcConn ) GetState () connectivity.State {
1097+ return connectivity .Ready
1098+ }
0 commit comments