I'm trying to separate tests to use different NATS servers. (I'm not yet sure it is NATS, but my tests influence each other.)
Doing that works fine when running a single test or testing a single package. Running go test ./...
on all my packages (as done in CI) I get this error (paths anonymised):
panic: Unable to start NATS Server in Go Routine
goroutine 1 [running]:
github.com/nats-io/gnatsd/test.RunServer(0xc000163400, 0xc000163400)
./go/pkg/mod/github.com/nats-io/gnatsd@v1.4.1/test/test.go:66 +0xbd
./lib/msgQueue/nats.NewTestConn(0xc0002adf68, 0x1879e12)
./lib/msgQueue/nats/testconn.go:19 +0x80
It seems like Go starts goroutines to run tests in them. Both using TestMain
and init
in the tests does not solve the problem.
Is it possible to start a server per test without running into the goroutine
error? Or is there some lightweight, but functioning in-memory replacement?
Here some code:
// +build !build
package myNats
import (
"fmt"
"github.com/pkg/errors"
"github.com/nats-io/gnatsd/server"
"github.com/nats-io/gnatsd/test"
gonats "github.com/nats-io/go-nats"
)
type Conn struct {
db *gonats.Conn
}
func NewTestConn() (conn *Conn, shutdown func()) {
opts := server.Options{
Host: "localhost",
Port: 53347,
NoLog: true,
NoSigs: true,
}
gnatsd := test.RunServer(&opts)
if gnatsd == nil {
panic("could not start NATS test server")
}
url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
conn, err := open(url)
if err != nil {
panic(errors.Wrap(err, "could not connect to test NATS"))
}
return conn, func() {
conn.close()
gnatsd.Shutdown()
}
}
func open(addr string) (*Conn, error) {
// Connect to NATS
nc, err := gonats.Connect(addr)
if err != nil {
return nil, errors.Wrapf(err, "nats not reachable on %s", addr)
}
if !nc.IsConnected() {
errorMsg := fmt.Errorf("could not establish connection to nats-server at: %s", addr)
return nil, errorMsg
}
return &Conn{
db: nc,
}, nil
}
My goal would be to have a server per test:
func TestSomeThing(t *testing.T) {
conn, shutdown := myNats.NewTestConn()
defer shutdown()
_ = conn
// test code here
}