blob: 86865263d3fe12dad384bd1832d4016429e46016 [file] [log] [blame]
package testutils
import (
"net"
"sync"
"github.com/stretchr/testify/mock"
assert "github.com/stretchr/testify/require"
"go.skia.org/infra/go/sktest"
traceservice "go.skia.org/infra/go/trace/service"
"google.golang.org/grpc"
)
// StartTestTraceDBServer starts up a traceDB server for testing. It stores its
// data at the given path and returns the address at which the server is
// listening as the second return value.
// Upon completion the calling test should call the Stop() function of the
// returned server object.
func StartTraceDBTestServer(t sktest.TestingT, traceDBFileName, shareDBDir string) (*grpc.Server, string) {
traceDBServer, err := traceservice.NewTraceServiceServer(traceDBFileName)
assert.NoError(t, err)
lis, err := net.Listen("tcp", "localhost:0")
assert.NoError(t, err)
server := grpc.NewServer()
traceservice.RegisterTraceServiceServer(server, traceDBServer)
go func() {
// We ignore the error, because calling the Stop() function always causes
// an error and we are primarily interested in using this to test other code.
_ = server.Serve(lis)
}()
return server, lis.Addr().String()
}
// These helpers assist in wrapping the Run calls in the wait group
// so we can be sure everything actually runs before the function
// terminates. Ideally, I would have liked to be able to chain multiple
// Run calls to the mock, but testify's mocks only allow one
// Run per Call. We have two helpers then, one if a mock does not already
// have a Run function and the other is for wrapping around a Run function
// that already exists.
// Note: do not call defer wg.Wait() because if any assert fails, it will
// panic, possibly before all the wg.Done() are called, causing a deadlock.
func AsyncHelpers() (*sync.WaitGroup, func(c *mock.Call) *mock.Call, func(f func(args mock.Arguments)) func(mock.Arguments)) {
wg := sync.WaitGroup{}
isAsync := func(c *mock.Call) *mock.Call {
wg.Add(1)
return c.Run(func(a mock.Arguments) {
wg.Done()
})
}
asyncWrapper := func(f func(args mock.Arguments)) func(mock.Arguments) {
wg.Add(1)
return func(args mock.Arguments) {
defer wg.Done()
f(args)
}
}
return &wg, isAsync, asyncWrapper
}