github.com/renbou/grpcbridge@v0.0.2-0.20240416012907-bcbd8b12648a/internal/bridgetest/server.go (about) 1 package bridgetest 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "net" 8 "testing" 9 10 "github.com/renbou/grpcbridge/grpcadapter" 11 "google.golang.org/grpc" 12 "google.golang.org/grpc/credentials/insecure" 13 "google.golang.org/grpc/test/bufconn" 14 ) 15 16 const ( 17 TestTargetName = "bridgetest" 18 TestDialTarget = "passthrough:///bridgetest" 19 ) 20 21 func mustRawServer(tb testing.TB, opts []grpc.ServerOption, prepareFuncs []func(*grpc.Server)) (*bufconn.Listener, *grpc.Server) { 22 // Relatively big buffer to allow all test goroutines to communicate without blocking. 23 listener := bufconn.Listen(1 << 20) 24 server := grpc.NewServer(opts...) 25 26 for _, prepare := range prepareFuncs { 27 prepare(server) 28 } 29 30 go func() { 31 if err := server.Serve(listener); err != nil && !errors.Is(err, grpc.ErrServerStopped) { 32 panic(fmt.Sprintf("failed to serve test gRPC server: %s", err)) 33 } 34 }() 35 36 tb.Cleanup(func() { 37 if err := listener.Close(); err != nil { 38 tb.Errorf("unexpected error while closing bufconn.Listener: %s", err) 39 } 40 }) 41 42 return listener, server 43 } 44 45 func MustGRPCServer(tb testing.TB, prepareFuncs ...func(*grpc.Server)) (*grpc.Server, *grpcadapter.AdaptedClientPool, grpcadapter.ClientConn) { 46 listener, server := mustRawServer(tb, nil, prepareFuncs) 47 48 pool := grpcadapter.NewAdaptedClientPool(grpcadapter.AdaptedClientPoolOpts{ 49 DefaultOpts: []grpc.DialOption{ 50 grpc.WithTransportCredentials(insecure.NewCredentials()), 51 grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) { 52 return listener.Dial() 53 }), 54 }, 55 }) 56 57 controller, _ := pool.New(TestTargetName, TestDialTarget) 58 tb.Cleanup(controller.Close) // intentionally added after listener.Close cleanup for the connection to be closed before the listener 59 60 conn, _ := pool.Get(TestTargetName) 61 62 return server, pool, conn 63 }