grpctest

package
v0.0.0-...-2597ab7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2023 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package grpctest provides helpers for testing gRPC service implementations over the full gRPC client-server stack.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewClientConn

func NewClientConn[S any](register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) (*grpc.ClientConn, func(), error)

NewClientConn is a convenience wrapper for registering a single service with a Tester, and returning the ClientConn obtained from Dial(). The returned cleanup function blocks until the underlying grpc.Server stops, and does not need to be called if NewClientConn returns an error.

See Tester.RegisterService() for a description of the arguments.

Example
// This variable declaration is purely demonstrative of the fact that
// echo{} implements the interface.
var svc pb.EchoServiceServer = &echo{}
conn, cleanup, err := NewClientConn(pb.RegisterEchoServiceServer, svc)
if err != nil {
	fmt.Printf("NewClientConn() got err %v; want nil err", err)
	return
}
defer cleanup()

c := pb.NewEchoServiceClient(conn)
resp, err := c.Echo(context.Background(), &pb.Request{Msg: "foobar"})
if err != nil {
	fmt.Printf("EchoService.Echo() got err %v; want nil err", err)
}
fmt.Println(resp.Msg)
Output:

foobar

func NewClientConnTB

func NewClientConnTB[S any](tb testing.TB, register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) *grpc.ClientConn

NewClientConnTB is equivalent to NewClientConn() except that all errors are reported on tb.Fatal() and cleanup is handled by tb.Cleanup().

func RegisterService

func RegisterService[S any](t *Tester, register func(*grpc.Server, S), impl S)

RegisterService registers a service implementation with the Tester's underlying grpc.Server. The register argument must be a RegisterXServer() function from a proto file, where X is the name of some service.

If only one service needs to be registered, rather use NewClientConn().

This is a top-level function instead of a method on Tester as method's can't be generic.

Types

type Tester

type Tester struct {
	// contains filtered or unexported fields
}

A Tester wraps a grpc.Server, with connections made over a bufconn.Listener.

Example
st := New()
defer st.Close()

// Register as many services as necessary. If only one is needed, rather use
// NewClientConn() which handles all of the additional steps, and accepts
// identical arguments to RegisterService().

// This variable declaration is purely demonstrative of the fact that
// echo{} implements the interface.
var svc pb.EchoServiceServer = &echo{}
if err := st.RegisterService(pb.RegisterEchoServiceServer, svc); err != nil {
	fmt.Printf("RegisterService() got err %v", err)
	return
}

done := make(chan struct{})
go func() {
	defer close(done)
	st.Serve()
}()

conn, err := st.Dial()
if err != nil {
	fmt.Printf("%T.Dial() got err %v", st, err)
	return
}

c := pb.NewEchoServiceClient(conn)
resp, err := c.Echo(context.Background(), &pb.Request{Msg: "hello world"})
if err != nil {
	fmt.Printf("EchoService.Echo() got err %v", err)
	return
}
fmt.Println(resp.Msg)

st.Close()
// Not entirely necessary; but demonstrates that the Server has stopped.
<-done
Output:

hello world

func New

func New(opts ...grpc.ServerOption) *Tester

New returns a new Tester. Close() must be called to clean up, even if Serve() is never called.

func NewWithRegistered

func NewWithRegistered[S any](register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) (*Tester, func())

NewWithRegistered is a convenience wrapper for registering a single service with a Tester, which is then returned. The returned cleanup function blocks until the underlying grpc.Server stops.

See Tester.RegisterService() for a description of the arguments.

func NewWithRegisteredTB

func NewWithRegisteredTB[S any](tb testing.TB, register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) *Tester

NewWithRegisteredTB is equivalent to NewWithRegistered() except that cleanup is handled by tb.Cleanup().

func (*Tester) Close

func (t *Tester) Close() error

Close gracefully stops the grpc.Server if Serve was called, and closes the Listener. It must be called even if Serve() was not.

func (*Tester) Dial

func (t *Tester) Dial(opts ...grpc.DialOption) (*grpc.ClientConn, error)

Dial calls grpc.Dial() with a dialer that will connect to the underlying bufconn.Listener with the provided options, which must not include a dialer themselves. All connections use a grpc.WithInsecure() option.

func (*Tester) DialOpts

func (t *Tester) DialOpts(user ...grpc.DialOption) []grpc.DialOption

DialOpts extends the provided options with those necessary to connect to the Tester's grpc.Server.

func (*Tester) RegisterService deprecated

func (t *Tester) RegisterService(registerFunc, implementation interface{}) (err error)

RegisterService registers a service implementation with the underlying grpc.Server. The registerFunc argument must be a RegisterXServer() function from a proto file, where X is the name of some service. The implementation argument must implement the respective XServer interface.

If only one service needs to be registered, rather use NewClientConn().

Deprecated: use the top-level function RegisterService() as it provides static type safety through generics. Methods can't be parameterised, so this uses reflection as it pre-dates the introduction of generics.

func (*Tester) Serve

func (t *Tester) Serve()

Serve is equivalent to grpc.Server.Serve() but without the need for a Listener.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL