测试时"Unable to start NATS Server in Go Routine"



我正在尝试分离测试以使用不同的NATS服务器。(我还不确定是NATS,但我的测试相互影响。

在运行单个测试或测试单个包时,这样做效果很好。在我的所有软件包上运行go test ./...(如在 CI 中所做的那样(,我收到此错误(路径匿名(:

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

似乎 Go 启动了 goroutines 以在其中运行测试。在测试中使用TestMaininit并不能解决问题。

是否可以在每个测试中启动服务器而不会遇到goroutine错误?还是有一些轻量级但有效的内存替换?


这里有一些代码:

// +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
}

我的目标是每个测试都有一台服务器:

func TestSomeThing(t *testing.T) {
conn, shutdown := myNats.NewTestConn()
defer shutdown()
_ = conn
// test code here
}

我怀疑错误消息:

Unable to start NATS Server in Go Routine

具有误导性。关于 Go 例程的部分可能只是它如何尝试启动 NATS 服务器的实现细节。我怀疑服务器无法启动,因为您在选项中对端口进行了硬编码,并且因为多个测试包可能并行运行。只有一个测试包能够绑定到端口以启动 NATS 服务器,所有其他测试包都将失败。

go test旗上的文档说:

-parallel n
Allow parallel execution of test functions that call t.Parallel.
The value of this flag is the maximum number of tests to run
simultaneously; by default, it is set to the value of GOMAXPROCS.
Note that -parallel only applies within a single test binary.
The 'go test' command may run tests for different packages
in parallel as well, according to the setting of the -p flag
(see 'go help build').

除非你在给定的测试套件中有并行测试,我假设你没有,否则问题可能是并行运行的不同包。按照上面末尾的线索,让我们看一下构建标志:

-p n
the number of programs, such as build commands or
test binaries, that can be run in parallel.
The default is the number of CPUs available.

这是来自"编译包和依赖项"文档。请注意,您可以将构建标志测试标志传递给go test

$ go test -h
usage: go test [build/test flags] [packages] [build/test flags & test binary flags]
Run 'go help test' for details.

所以考虑运行go test -p 1 ./....或者,将选项传递给RunServer函数,以允许多个选项安全地并行发生。

它可能已经为每个测试启动了一个服务器。如果没有 goroutine,您就无法同时运行事情。该错误实际上没有任何意义 - Go 中的任何内容都必须能够在 goroutine 中运行,事实上一切都goroutine(甚至main中运行(,所以不清楚他们在这里真正想说什么(我绝对建议打开一个关于它的错误报告,因为该错误消息很糟糕(。同时,您可以防止go test-parallel 1同时运行(如go help testflag所示(,这可能会有所帮助。

就我而言,问题是我已经运行了 nats-server 的实例,因此测试失败了。通过停止服务器,测试成功通过。

我的解决方案是在go test命令之前添加GODEBUG=x509sha1=1

附言1.18.3

最新更新