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  }