testutil

package
v0.0.0-...-c7154f0 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2023 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (
	// DefaultBufconnSize is an arbitrary default.
	DefaultBufconnSize = 1024 * 1024
)

Variables

View Source
var (
	Wrap      = testing.Wrap
	Parallel  = testing.Parallel
	SkipRegex = testing.SkipRegex
)
View Source
var (
	ClientConnFactories = map[string]ClientConnFactory{
		`bufconn`: BufconnClientConnFactory,
		`grpchan`: GrpchanClientConnFactory,
		`netpipe`: NetpipeClientConnFactory,
	}
)

Functions

func CallOn

func CallOn[T any](v T, f func(v T)) T

func CheckNumGoroutines

func CheckNumGoroutines(t TB, start int, increase bool, wait time.Duration)

func CleanupCheckNumGoroutines

func CleanupCheckNumGoroutines(t TB, start int, increase bool, wait time.Duration)

func Closers

func Closers(closers ...io.Closer) io.Closer

Closers combines a set of closers, always calling them in order, and using the last as the result.

Note this is a copy of stream.Closers.

func DumpGoroutineStacktrace

func DumpGoroutineStacktrace() string

func TestConn

func TestConn[
	T1 TG,
	T2 interface {
		TG
		Run(name string, f func(t T1)) bool
	},
	T3 ~func() (c1, c2 net.Conn, stop func(), err error)](
	t T2,
	test func(t T1, mp T3),
	closeConns bool,
	init func(t T1) T3,
)

TestConn runs (an implementation of) nettest.TestConn multiple times, testing different permutations of conn order (swapping the roles of c1 and c2), and if closeConns is true, also the order of close (better at catching close-related deadlocks). If closeConns is false, then the caller must close the two conns as part of the stop closure. Any stop closure will be run before any auto-generated (closeConns) stop.

If the nested t, provided by t.Run, is *testing.T, then the number of goroutines will be validated, to test for leaks. Other types (presumably testutil.T or equivalent) should be capable of implementing the same functionality via wrappers / other custom behavior.

func WaitNumGoroutines

func WaitNumGoroutines(wait time.Duration, fn func(n int) bool) (n int)

Types

type ClientConnCloser

type ClientConnCloser interface {
	grpc.ClientConnInterface
	io.Closer
}

func BufconnClientConnFactory

func BufconnClientConnFactory(fn func(h GRPCServer)) ClientConnCloser

func GrpchanClientConnFactory

func GrpchanClientConnFactory(fn func(h GRPCServer)) ClientConnCloser

func NetpipeClientConnFactory

func NetpipeClientConnFactory(fn func(h GRPCServer)) ClientConnCloser

type ClientConnFactory

type ClientConnFactory func(fn func(h GRPCServer)) ClientConnCloser

type Closer

type Closer func() error

Closer implements io.Closer, also supporting wrapping to be idempotent/cached, via the Once method.

Note this is a copy of stream.Closer.

func (Closer) Close

func (x Closer) Close() error

Close passes through to the receiver.

func (Closer) Comparable

func (x Closer) Comparable() io.Closer

Comparable wraps the receiver so that it is comparable.

func (Closer) Once

func (x Closer) Once() Closer

Once wraps the receiver in a closure guarded by sync.Once, which will record and return any error for subsequent close attempts. See also ErrPanic.

type DepthLimiter

type DepthLimiter = testing.DepthLimiter

type GRPCServer

type GRPCServer = reflection.GRPCServer

type GoroutineChecker

type GoroutineChecker struct {
	T
	Increase bool
	Wait     time.Duration
}

func (GoroutineChecker) Run

func (x GoroutineChecker) Run(name string, f func(t T)) bool

func (GoroutineChecker) Unwrap

func (x GoroutineChecker) Unwrap() T

type Hook

type Hook = testing.Hook

type ListenerDialer

type ListenerDialer interface {
	net.Listener
	DialContext(ctx context.Context) (net.Conn, error)
}

type PipeClient

type PipeClient struct {
	*grpc.ClientConn
	Listener ListenerDialer
	Server   *grpc.Server
	// contains filtered or unexported fields
}

func NewBufconnClient

func NewBufconnClient(size int, init func(lis *bufconn.Listener, srv *grpc.Server), options ...PipeClientOption) *PipeClient

NewBufconnClient initialises a new gRPC client for testing, using google.golang.org/grpc/test/bufconn. Size will default to DefaultBufconnSize if <= 0. The init func will be called prior to serving on the listener, which does not need to be implemented by the caller.

Example
defer CheckNumGoroutines(nil, runtime.NumGoroutine(), false, 0)

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

conn := NewBufconnClient(0, func(lis *bufconn.Listener, srv *grpc.Server) {
	if lis == nil || srv == nil {
		panic(`unexpected args`)
	}
	reflection.Register(srv)
})
defer conn.Close()

stream, err := refl.NewServerReflectionClient(conn).ServerReflectionInfo(ctx)
if err != nil {
	panic(err)
}

//lint:ignore SA1019 v1 isnt completely released yet
if err := stream.Send(&refl.ServerReflectionRequest{MessageRequest: &refl.ServerReflectionRequest_ListServices{}}); err != nil {
	panic(err)
}

if msg, err := stream.Recv(); err != nil {
	panic(err)
} else {
	//lint:ignore SA1019 v1 isnt completely released yet
	services := make([]string, 0, len(msg.GetListServicesResponse().GetService()))
	//lint:ignore SA1019 v1 isnt completely released yet
	for _, v := range msg.GetListServicesResponse().GetService() {
		//lint:ignore SA1019 v1 isnt completely released yet
		services = append(services, v.GetName())
	}
	fmt.Printf("there are %d available services: %q\n", len(services), services)
}

if err := conn.Close(); err != nil {
	panic(err)
}
Output:

there are 2 available services: ["grpc.reflection.v1.ServerReflection" "grpc.reflection.v1alpha.ServerReflection"]

func NewNetpipeClient

func NewNetpipeClient(factory func() (c1, c2 net.Conn), init func(lis *pipelistener.PipeListener, srv *grpc.Server), options ...PipeClientOption) *PipeClient

func NewPipeClient

func NewPipeClient(factory pipelistener.PipeFactory, init func(lis *pipelistener.PipeListener, srv *grpc.Server), options ...PipeClientOption) *PipeClient

NewPipeClient initialises a new gRPC client for testing, using a net.Pipe style implementation. Size will default to DefaultBufconnSize if <= 0. The init func will be called prior to serving on the listener, which does not need to be implemented by the caller.

func (*PipeClient) Close

func (x *PipeClient) Close() error

type PipeClientOption

type PipeClientOption func(c *pipeClientConfig)

func WithDialOptions

func WithDialOptions(options ...grpc.DialOption) PipeClientOption

func WithServerOptions

func WithServerOptions(options ...grpc.ServerOption) PipeClientOption

type T

type T = testing.T

type TB

type TB = testing.TB

type TG

type TG = testing.TG

type TestingT

type TestingT = testing.TestingT

type Unwrapper

type Unwrapper = testing.Unwrapper

Jump to

Keyboard shortcuts

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