Return not ready for connection reason

Currently, we use ReadyForConnections in server tests to wait for the
server to be ready. However, when this fails we don't get a clue about
why it failed.

This change adds a new unexported method called readyForConnections that
returns an error describing which check failed. The exported
ReadyForConnections version works exactly as before. The unexported
version gets used in internal tests only.
This commit is contained in:
Jaime Piña
2021-04-19 12:01:26 -07:00
parent 8f07929530
commit de105a0a4e
6 changed files with 55 additions and 33 deletions

View File

@@ -214,8 +214,8 @@ func TestAccountIsolationExportImport(t *testing.T) {
s := opTrustBasicSetup()
defer s.Shutdown()
go s.Start()
if !s.ReadyForConnections(5 * time.Second) {
t.Fatal("failed to be ready for connections")
if err := s.readyForConnections(5 * time.Second); err != nil {
t.Fatal(err)
}
buildMemAccResolver(s)
@@ -1689,8 +1689,8 @@ func TestAccountRequestReplyTrackLatency(t *testing.T) {
// Run server in Go routine. We need this one running for internal sending of msgs.
go s.Start()
// Wait for accept loop(s) to be started
if !s.ReadyForConnections(10 * time.Second) {
panic("Unable to start NATS Server in Go Routine")
if err := s.readyForConnections(10 * time.Second); err != nil {
t.Fatal(err)
}
cfoo, crFoo, _ := newClientForServer(s)

View File

@@ -216,8 +216,8 @@ func testMQTTRunServer(t testing.TB, o *Options) *Server {
l := &DummyLogger{}
s.SetLogger(l, true, true)
go s.Start()
if !s.ReadyForConnections(3 * time.Second) {
t.Fatal("Unable to start server")
if err := s.readyForConnections(3 * time.Second); err != nil {
t.Fatal(err)
}
return s
}

View File

@@ -1342,8 +1342,8 @@ func TestRouteIPResolutionAndRouteToSelf(t *testing.T) {
go func() {
s.Start()
}()
if !s.ReadyForConnections(time.Second) {
t.Fatalf("Failed to start server")
if err := s.readyForConnections(time.Second); err != nil {
t.Fatal(err)
}
select {

View File

@@ -2682,28 +2682,51 @@ func (s *Server) ProfilerAddr() *net.TCPAddr {
return s.profiler.Addr().(*net.TCPAddr)
}
func (s *Server) readyForConnections(d time.Duration) error {
// Snapshot server options.
opts := s.getOpts()
chk := make(map[string]bool)
end := time.Now().Add(d)
for time.Now().Before(end) {
s.mu.Lock()
chk["server"] = s.listener != nil
chk["route"] = (opts.Cluster.Port == 0 || s.routeListener != nil)
chk["gateway"] = (opts.Gateway.Name == "" || s.gatewayListener != nil)
chk["leafNode"] = (opts.LeafNode.Port == 0 || s.leafNodeListener != nil)
chk["websocket"] = (opts.Websocket.Port == 0 || s.websocket.listener != nil)
s.mu.Unlock()
var numOK int
for _, ok := range chk {
if ok {
numOK++
}
}
if numOK == len(chk) {
return nil
}
time.Sleep(25 * time.Millisecond)
}
failed := make([]string, 0, len(chk))
for name, ok := range chk {
if !ok {
failed = append(failed, name)
}
}
return fmt.Errorf(
"failed to be ready for connections after %s: %s",
d, strings.Join(failed, ", "),
)
}
// ReadyForConnections returns `true` if the server is ready to accept clients
// and, if routing is enabled, route connections. If after the duration
// `dur` the server is still not ready, returns `false`.
func (s *Server) ReadyForConnections(dur time.Duration) bool {
// Snapshot server options.
opts := s.getOpts()
end := time.Now().Add(dur)
for time.Now().Before(end) {
s.mu.Lock()
ok := s.listener != nil &&
(opts.Cluster.Port == 0 || s.routeListener != nil) &&
(opts.Gateway.Name == "" || s.gatewayListener != nil) &&
(opts.LeafNode.Port == 0 || s.leafNodeListener != nil) &&
(opts.Websocket.Port == 0 || s.websocket.listener != nil)
s.mu.Unlock()
if ok {
return true
}
time.Sleep(25 * time.Millisecond)
}
return false
return s.readyForConnections(dur) == nil
}
// Quick utility to function to tell if the server supports headers.

View File

@@ -84,8 +84,8 @@ func RunServer(opts *Options) *Server {
go s.Start()
// Wait for accept loop(s) to be started
if !s.ReadyForConnections(10 * time.Second) {
panic("Unable to start NATS Server in Go Routine")
if err := s.readyForConnections(10 * time.Second); err != nil {
panic(err)
}
return s
}
@@ -1481,8 +1481,8 @@ func TestInsecureSkipVerifyWarning(t *testing.T) {
s.Start()
wg.Done()
}()
if !s.ReadyForConnections(time.Second) {
t.Fatal("Unable to start the server")
if err := s.readyForConnections(time.Second); err != nil {
t.Fatal(err)
}
select {
case w := <-l.warn:

View File

@@ -16,7 +16,6 @@
package server
import (
"errors"
"testing"
"time"
)
@@ -31,8 +30,8 @@ func TestRun(t *testing.T) {
errC <- Run(s)
}()
go func() {
if !s.ReadyForConnections(time.Second) {
started <- errors.New("failed to start in time")
if err := s.readyForConnections(time.Second); err != nil {
started <- err
return
}
s.Shutdown()