github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/server_test.go (about)

     1  // Copyright 2012-2020 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bufio"
    18  	"bytes"
    19  	"context"
    20  	"crypto/tls"
    21  	"encoding/json"
    22  	"errors"
    23  	"flag"
    24  	"fmt"
    25  	"io"
    26  	"net"
    27  	"net/url"
    28  	"os"
    29  	"reflect"
    30  	"runtime"
    31  	"sort"
    32  	"strings"
    33  	"sync"
    34  	"sync/atomic"
    35  	"testing"
    36  	"time"
    37  
    38  	"github.com/nats-io/nats.go"
    39  )
    40  
    41  func checkForErr(totalWait, sleepDur time.Duration, f func() error) error {
    42  	timeout := time.Now().Add(totalWait)
    43  	var err error
    44  	for time.Now().Before(timeout) {
    45  		err = f()
    46  		if err == nil {
    47  			return nil
    48  		}
    49  		time.Sleep(sleepDur)
    50  	}
    51  	return err
    52  }
    53  
    54  func checkFor(t testing.TB, totalWait, sleepDur time.Duration, f func() error) {
    55  	t.Helper()
    56  	err := checkForErr(totalWait, sleepDur, f)
    57  	if err != nil {
    58  		t.Fatal(err.Error())
    59  	}
    60  }
    61  
    62  func DefaultOptions() *Options {
    63  	return &Options{
    64  		Host:     "127.0.0.1",
    65  		Port:     -1,
    66  		HTTPPort: -1,
    67  		Cluster:  ClusterOpts{Port: -1, Name: "abc"},
    68  		NoLog:    true,
    69  		NoSigs:   true,
    70  		Debug:    true,
    71  		Trace:    true,
    72  	}
    73  }
    74  
    75  // New Go Routine based server
    76  func RunServer(opts *Options) *Server {
    77  	if opts == nil {
    78  		opts = DefaultOptions()
    79  	}
    80  	s, err := NewServer(opts)
    81  	if err != nil || s == nil {
    82  		panic(fmt.Sprintf("No NATS Server object returned: %v", err))
    83  	}
    84  
    85  	if !opts.NoLog {
    86  		s.ConfigureLogger()
    87  	}
    88  
    89  	// Run server in Go routine.
    90  	s.Start()
    91  
    92  	// Wait for accept loop(s) to be started
    93  	if err := s.readyForConnections(10 * time.Second); err != nil {
    94  		panic(err)
    95  	}
    96  	return s
    97  }
    98  
    99  // LoadConfig loads a configuration from a filename
   100  func LoadConfig(configFile string) (opts *Options) {
   101  	opts, err := ProcessConfigFile(configFile)
   102  	if err != nil {
   103  		panic(fmt.Sprintf("Error processing configuration file: %v", err))
   104  	}
   105  	opts.NoSigs, opts.NoLog = true, opts.LogFile == _EMPTY_
   106  	return
   107  }
   108  
   109  // RunServerWithConfig starts a new Go routine based server with a configuration file.
   110  func RunServerWithConfig(configFile string) (srv *Server, opts *Options) {
   111  	opts = LoadConfig(configFile)
   112  	srv = RunServer(opts)
   113  	return
   114  }
   115  
   116  func TestSemanticVersion(t *testing.T) {
   117  	if !semVerRe.MatchString(VERSION) {
   118  		t.Fatalf("Version (%s) is not a valid SemVer string", VERSION)
   119  	}
   120  }
   121  
   122  func TestVersionMatchesTag(t *testing.T) {
   123  	tag := os.Getenv("TRAVIS_TAG")
   124  	// Travis started to return '' when no tag is set. Support both now.
   125  	if tag == "" || tag == "''" {
   126  		t.SkipNow()
   127  	}
   128  	// We expect a tag of the form vX.Y.Z. If that's not the case,
   129  	// we need someone to have a look. So fail if first letter is not
   130  	// a `v`
   131  	if tag[0] != 'v' {
   132  		t.Fatalf("Expect tag to start with `v`, tag is: %s", tag)
   133  	}
   134  	// Strip the `v` from the tag for the version comparison.
   135  	if VERSION != tag[1:] {
   136  		t.Fatalf("Version (%s) does not match tag (%s)", VERSION, tag[1:])
   137  	}
   138  }
   139  
   140  func TestStartProfiler(t *testing.T) {
   141  	s := New(DefaultOptions())
   142  	s.StartProfiler()
   143  	s.mu.Lock()
   144  	s.profiler.Close()
   145  	s.mu.Unlock()
   146  }
   147  
   148  func TestStartupAndShutdown(t *testing.T) {
   149  	opts := DefaultOptions()
   150  	opts.NoSystemAccount = true
   151  
   152  	s := RunServer(opts)
   153  	defer s.Shutdown()
   154  
   155  	if !s.isRunning() {
   156  		t.Fatal("Could not run server")
   157  	}
   158  
   159  	// Debug stuff.
   160  	numRoutes := s.NumRoutes()
   161  	if numRoutes != 0 {
   162  		t.Fatalf("Expected numRoutes to be 0 vs %d\n", numRoutes)
   163  	}
   164  
   165  	numRemotes := s.NumRemotes()
   166  	if numRemotes != 0 {
   167  		t.Fatalf("Expected numRemotes to be 0 vs %d\n", numRemotes)
   168  	}
   169  
   170  	numClients := s.NumClients()
   171  	if numClients != 0 && numClients != 1 {
   172  		t.Fatalf("Expected numClients to be 1 or 0 vs %d\n", numClients)
   173  	}
   174  
   175  	numSubscriptions := s.NumSubscriptions()
   176  	if numSubscriptions != 0 {
   177  		t.Fatalf("Expected numSubscriptions to be 0 vs %d\n", numSubscriptions)
   178  	}
   179  }
   180  
   181  func TestTLSVersions(t *testing.T) {
   182  	for _, test := range []struct {
   183  		name     string
   184  		value    uint16
   185  		expected string
   186  	}{
   187  		{"1.0", tls.VersionTLS10, "1.0"},
   188  		{"1.1", tls.VersionTLS11, "1.1"},
   189  		{"1.2", tls.VersionTLS12, "1.2"},
   190  		{"1.3", tls.VersionTLS13, "1.3"},
   191  		{"unknown", 0x999, "Unknown [0x999]"},
   192  	} {
   193  		t.Run(test.name, func(t *testing.T) {
   194  			if v := tlsVersion(test.value); v != test.expected {
   195  				t.Fatalf("Expected value 0x%x to be %q, got %q", test.value, test.expected, v)
   196  			}
   197  		})
   198  	}
   199  }
   200  
   201  func TestTlsCipher(t *testing.T) {
   202  	if strings.Compare(tlsCipher(0x0005), "TLS_RSA_WITH_RC4_128_SHA") != 0 {
   203  		t.Fatalf("Invalid tls cipher")
   204  	}
   205  	if strings.Compare(tlsCipher(0x000a), "TLS_RSA_WITH_3DES_EDE_CBC_SHA") != 0 {
   206  		t.Fatalf("Invalid tls cipher")
   207  	}
   208  	if strings.Compare(tlsCipher(0x002f), "TLS_RSA_WITH_AES_128_CBC_SHA") != 0 {
   209  		t.Fatalf("Invalid tls cipher")
   210  	}
   211  	if strings.Compare(tlsCipher(0x0035), "TLS_RSA_WITH_AES_256_CBC_SHA") != 0 {
   212  		t.Fatalf("Invalid tls cipher")
   213  	}
   214  	if strings.Compare(tlsCipher(0xc007), "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA") != 0 {
   215  		t.Fatalf("Invalid tls cipher")
   216  	}
   217  	if strings.Compare(tlsCipher(0xc009), "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA") != 0 {
   218  		t.Fatalf("Invalid tls cipher")
   219  	}
   220  	if strings.Compare(tlsCipher(0xc00a), "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA") != 0 {
   221  		t.Fatalf("Invalid tls cipher")
   222  	}
   223  	if strings.Compare(tlsCipher(0xc011), "TLS_ECDHE_RSA_WITH_RC4_128_SHA") != 0 {
   224  		t.Fatalf("Invalid tls cipher")
   225  	}
   226  	if strings.Compare(tlsCipher(0xc012), "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA") != 0 {
   227  		t.Fatalf("Invalid tls cipher")
   228  	}
   229  	if strings.Compare(tlsCipher(0xc013), "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA") != 0 {
   230  		t.Fatalf("Invalid tls cipher")
   231  	}
   232  	if strings.Compare(tlsCipher(0xc014), "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA") != 0 {
   233  		t.Fatalf("IUnknownnvalid tls cipher")
   234  	}
   235  	if strings.Compare(tlsCipher(0xc02f), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") != 0 {
   236  		t.Fatalf("Invalid tls cipher")
   237  	}
   238  	if strings.Compare(tlsCipher(0xc02b), "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") != 0 {
   239  		t.Fatalf("Invalid tls cipher")
   240  	}
   241  	if strings.Compare(tlsCipher(0xc030), "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") != 0 {
   242  		t.Fatalf("Invalid tls cipher")
   243  	}
   244  	if strings.Compare(tlsCipher(0xc02c), "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") != 0 {
   245  		t.Fatalf("Invalid tls cipher")
   246  	}
   247  	if strings.Compare(tlsCipher(0x1301), "TLS_AES_128_GCM_SHA256") != 0 {
   248  		t.Fatalf("Invalid tls cipher")
   249  	}
   250  	if strings.Compare(tlsCipher(0x1302), "TLS_AES_256_GCM_SHA384") != 0 {
   251  		t.Fatalf("Invalid tls cipher")
   252  	}
   253  	if strings.Compare(tlsCipher(0x1303), "TLS_CHACHA20_POLY1305_SHA256") != 0 {
   254  		t.Fatalf("Invalid tls cipher")
   255  	}
   256  	if strings.Compare(tlsCipher(0x9999), "Unknown [0x9999]") != 0 {
   257  		t.Fatalf("Expected an unknown cipher")
   258  	}
   259  }
   260  
   261  func TestGetConnectURLs(t *testing.T) {
   262  	opts := DefaultOptions()
   263  	opts.Port = 4222
   264  
   265  	var globalIP net.IP
   266  
   267  	checkGlobalConnectURLs := func() {
   268  		s := New(opts)
   269  		defer s.Shutdown()
   270  
   271  		s.mu.Lock()
   272  		urls := s.getClientConnectURLs()
   273  		s.mu.Unlock()
   274  		if len(urls) == 0 {
   275  			t.Fatalf("Expected to get a list of urls, got none for listen addr: %v", opts.Host)
   276  		}
   277  		for _, u := range urls {
   278  			tcpaddr, err := net.ResolveTCPAddr("tcp", u)
   279  			if err != nil {
   280  				t.Fatalf("Error resolving: %v", err)
   281  			}
   282  			ip := tcpaddr.IP
   283  			if !ip.IsGlobalUnicast() {
   284  				t.Fatalf("IP %v is not global", ip.String())
   285  			}
   286  			if ip.IsUnspecified() {
   287  				t.Fatalf("IP %v is unspecified", ip.String())
   288  			}
   289  			addr := strings.TrimSuffix(u, ":4222")
   290  			if addr == opts.Host {
   291  				t.Fatalf("Returned url is not right: %v", u)
   292  			}
   293  			if globalIP == nil {
   294  				globalIP = ip
   295  			}
   296  		}
   297  	}
   298  
   299  	listenAddrs := []string{"0.0.0.0", "::"}
   300  	for _, listenAddr := range listenAddrs {
   301  		opts.Host = listenAddr
   302  		checkGlobalConnectURLs()
   303  	}
   304  
   305  	checkConnectURLsHasOnlyOne := func() {
   306  		s := New(opts)
   307  		defer s.Shutdown()
   308  
   309  		s.mu.Lock()
   310  		urls := s.getClientConnectURLs()
   311  		s.mu.Unlock()
   312  		if len(urls) != 1 {
   313  			t.Fatalf("Expected one URL, got %v", urls)
   314  		}
   315  		tcpaddr, err := net.ResolveTCPAddr("tcp", urls[0])
   316  		if err != nil {
   317  			t.Fatalf("Error resolving: %v", err)
   318  		}
   319  		ip := tcpaddr.IP
   320  		if ip.String() != opts.Host {
   321  			t.Fatalf("Expected connect URL to be %v, got %v", opts.Host, ip.String())
   322  		}
   323  	}
   324  
   325  	singleConnectReturned := []string{"127.0.0.1", "::1"}
   326  	if globalIP != nil {
   327  		singleConnectReturned = append(singleConnectReturned, globalIP.String())
   328  	}
   329  	for _, listenAddr := range singleConnectReturned {
   330  		opts.Host = listenAddr
   331  		checkConnectURLsHasOnlyOne()
   332  	}
   333  }
   334  
   335  func TestInfoServerNameDefaultsToPK(t *testing.T) {
   336  	opts := DefaultOptions()
   337  	opts.Port = 4222
   338  	opts.ClientAdvertise = "nats.example.com"
   339  	s := New(opts)
   340  	defer s.Shutdown()
   341  
   342  	if s.info.Name != s.info.ID {
   343  		t.Fatalf("server info hostname is incorrect, got: '%v' expected: '%v'", s.info.Name, s.info.ID)
   344  	}
   345  }
   346  
   347  func TestInfoServerNameIsSettable(t *testing.T) {
   348  	opts := DefaultOptions()
   349  	opts.Port = 4222
   350  	opts.ClientAdvertise = "nats.example.com"
   351  	opts.ServerName = "test_server_name"
   352  	s := New(opts)
   353  	defer s.Shutdown()
   354  
   355  	if s.info.Name != "test_server_name" {
   356  		t.Fatalf("server info hostname is incorrect, got: '%v' expected: 'test_server_name'", s.info.Name)
   357  	}
   358  }
   359  
   360  func TestClientAdvertiseConnectURL(t *testing.T) {
   361  	opts := DefaultOptions()
   362  	opts.Port = 4222
   363  	opts.ClientAdvertise = "nats.example.com"
   364  	s := New(opts)
   365  	defer s.Shutdown()
   366  
   367  	s.mu.Lock()
   368  	urls := s.getClientConnectURLs()
   369  	s.mu.Unlock()
   370  	if len(urls) != 1 {
   371  		t.Fatalf("Expected to get one url, got none: %v with ClientAdvertise %v",
   372  			opts.Host, opts.ClientAdvertise)
   373  	}
   374  	if urls[0] != "nats.example.com:4222" {
   375  		t.Fatalf("Expected to get '%s', got: '%v'", "nats.example.com:4222", urls[0])
   376  	}
   377  	s.Shutdown()
   378  
   379  	opts.ClientAdvertise = "nats.example.com:7777"
   380  	s = New(opts)
   381  	s.mu.Lock()
   382  	urls = s.getClientConnectURLs()
   383  	s.mu.Unlock()
   384  	if len(urls) != 1 {
   385  		t.Fatalf("Expected to get one url, got none: %v with ClientAdvertise %v",
   386  			opts.Host, opts.ClientAdvertise)
   387  	}
   388  	if urls[0] != "nats.example.com:7777" {
   389  		t.Fatalf("Expected 'nats.example.com:7777', got: '%v'", urls[0])
   390  	}
   391  	if s.info.Host != "nats.example.com" {
   392  		t.Fatalf("Expected host to be set to nats.example.com")
   393  	}
   394  	if s.info.Port != 7777 {
   395  		t.Fatalf("Expected port to be set to 7777")
   396  	}
   397  	s.Shutdown()
   398  
   399  	opts = DefaultOptions()
   400  	opts.Port = 0
   401  	opts.ClientAdvertise = "nats.example.com:7777"
   402  	s = New(opts)
   403  	if s.info.Host != "nats.example.com" && s.info.Port != 7777 {
   404  		t.Fatalf("Expected Client Advertise Host:Port to be nats.example.com:7777, got: %s:%d",
   405  			s.info.Host, s.info.Port)
   406  	}
   407  	s.Shutdown()
   408  }
   409  
   410  func TestClientAdvertiseInCluster(t *testing.T) {
   411  	optsA := DefaultOptions()
   412  	optsA.ClientAdvertise = "srvA:4222"
   413  	srvA := RunServer(optsA)
   414  	defer srvA.Shutdown()
   415  
   416  	nc := natsConnect(t, srvA.ClientURL())
   417  	defer nc.Close()
   418  
   419  	optsB := DefaultOptions()
   420  	optsB.ClientAdvertise = "srvBC:4222"
   421  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Cluster.Port))
   422  	srvB := RunServer(optsB)
   423  	defer srvB.Shutdown()
   424  
   425  	checkClusterFormed(t, srvA, srvB)
   426  
   427  	checkURLs := func(expected string) {
   428  		t.Helper()
   429  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
   430  			srvs := nc.DiscoveredServers()
   431  			for _, u := range srvs {
   432  				if u == expected {
   433  					return nil
   434  				}
   435  			}
   436  			return fmt.Errorf("Url %q not found in %q", expected, srvs)
   437  		})
   438  	}
   439  	checkURLs("nats://srvBC:4222")
   440  
   441  	optsC := DefaultOptions()
   442  	optsC.ClientAdvertise = "srvBC:4222"
   443  	optsC.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Cluster.Port))
   444  	srvC := RunServer(optsC)
   445  	defer srvC.Shutdown()
   446  
   447  	checkClusterFormed(t, srvA, srvB, srvC)
   448  	checkURLs("nats://srvBC:4222")
   449  
   450  	srvB.Shutdown()
   451  	checkNumRoutes(t, srvA, DEFAULT_ROUTE_POOL_SIZE+1)
   452  	checkURLs("nats://srvBC:4222")
   453  }
   454  
   455  func TestClientAdvertiseErrorOnStartup(t *testing.T) {
   456  	opts := DefaultOptions()
   457  	// Set invalid address
   458  	opts.ClientAdvertise = "addr:::123"
   459  	testFatalErrorOnStart(t, opts, "ClientAdvertise")
   460  }
   461  
   462  func TestNoDeadlockOnStartFailure(t *testing.T) {
   463  	opts := DefaultOptions()
   464  	opts.Host = "x.x.x.x" // bad host
   465  	opts.Port = 4222
   466  	opts.HTTPHost = opts.Host
   467  	opts.Cluster.Host = "127.0.0.1"
   468  	opts.Cluster.Port = -1
   469  	opts.ProfPort = -1
   470  	s := New(opts)
   471  
   472  	// This should return since it should fail to start a listener
   473  	// on x.x.x.x:4222
   474  	ch := make(chan struct{})
   475  	go func() {
   476  		s.Start()
   477  		close(ch)
   478  	}()
   479  	select {
   480  	case <-ch:
   481  	case <-time.After(time.Second):
   482  		t.Fatalf("Start() should have returned due to failure to start listener")
   483  	}
   484  
   485  	// We should be able to shutdown
   486  	s.Shutdown()
   487  }
   488  
   489  func TestMaxConnections(t *testing.T) {
   490  	opts := DefaultOptions()
   491  	opts.MaxConn = 1
   492  	s := RunServer(opts)
   493  	defer s.Shutdown()
   494  
   495  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   496  	nc, err := nats.Connect(addr)
   497  	if err != nil {
   498  		t.Fatalf("Error creating client: %v\n", err)
   499  	}
   500  	defer nc.Close()
   501  
   502  	nc2, err := nats.Connect(addr)
   503  	if err == nil {
   504  		nc2.Close()
   505  		t.Fatal("Expected connection to fail")
   506  	}
   507  }
   508  
   509  func TestMaxSubscriptions(t *testing.T) {
   510  	opts := DefaultOptions()
   511  	opts.MaxSubs = 10
   512  	s := RunServer(opts)
   513  	defer s.Shutdown()
   514  
   515  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   516  	nc, err := nats.Connect(addr)
   517  	if err != nil {
   518  		t.Fatalf("Error creating client: %v\n", err)
   519  	}
   520  	defer nc.Close()
   521  
   522  	for i := 0; i < 10; i++ {
   523  		_, err := nc.Subscribe(fmt.Sprintf("foo.%d", i), func(*nats.Msg) {})
   524  		if err != nil {
   525  			t.Fatalf("Error subscribing: %v\n", err)
   526  		}
   527  	}
   528  	// This should cause the error.
   529  	nc.Subscribe("foo.22", func(*nats.Msg) {})
   530  	nc.Flush()
   531  	if err := nc.LastError(); err == nil {
   532  		t.Fatal("Expected an error but got none\n")
   533  	}
   534  }
   535  
   536  func TestProcessCommandLineArgs(t *testing.T) {
   537  	var host string
   538  	var port int
   539  	cmd := flag.NewFlagSet("nats-server", flag.ExitOnError)
   540  	cmd.StringVar(&host, "a", "0.0.0.0", "Host.")
   541  	cmd.IntVar(&port, "p", 4222, "Port.")
   542  
   543  	cmd.Parse([]string{"-a", "127.0.0.1", "-p", "9090"})
   544  	showVersion, showHelp, err := ProcessCommandLineArgs(cmd)
   545  	if err != nil {
   546  		t.Errorf("Expected no errors, got: %s", err)
   547  	}
   548  	if showVersion || showHelp {
   549  		t.Errorf("Expected not having to handle subcommands")
   550  	}
   551  
   552  	cmd.Parse([]string{"version"})
   553  	showVersion, showHelp, err = ProcessCommandLineArgs(cmd)
   554  	if err != nil {
   555  		t.Errorf("Expected no errors, got: %s", err)
   556  	}
   557  	if !showVersion {
   558  		t.Errorf("Expected having to handle version command")
   559  	}
   560  	if showHelp {
   561  		t.Errorf("Expected not having to handle help command")
   562  	}
   563  
   564  	cmd.Parse([]string{"help"})
   565  	showVersion, showHelp, err = ProcessCommandLineArgs(cmd)
   566  	if err != nil {
   567  		t.Errorf("Expected no errors, got: %s", err)
   568  	}
   569  	if showVersion {
   570  		t.Errorf("Expected not having to handle version command")
   571  	}
   572  	if !showHelp {
   573  		t.Errorf("Expected having to handle help command")
   574  	}
   575  
   576  	cmd.Parse([]string{"foo", "-p", "9090"})
   577  	_, _, err = ProcessCommandLineArgs(cmd)
   578  	if err == nil {
   579  		t.Errorf("Expected an error handling the command arguments")
   580  	}
   581  }
   582  
   583  func TestRandomPorts(t *testing.T) {
   584  	opts := DefaultOptions()
   585  	opts.HTTPPort = -1
   586  	opts.Port = -1
   587  	s := RunServer(opts)
   588  
   589  	defer s.Shutdown()
   590  
   591  	if s.Addr() == nil || s.Addr().(*net.TCPAddr).Port <= 0 {
   592  		t.Fatal("Should have dynamically assigned server port.")
   593  	}
   594  
   595  	if s.Addr() == nil || s.Addr().(*net.TCPAddr).Port == 4222 {
   596  		t.Fatal("Should not have dynamically assigned default port: 4222.")
   597  	}
   598  
   599  	if s.MonitorAddr() == nil || s.MonitorAddr().Port <= 0 {
   600  		t.Fatal("Should have dynamically assigned monitoring port.")
   601  	}
   602  
   603  }
   604  
   605  func TestNilMonitoringPort(t *testing.T) {
   606  	opts := DefaultOptions()
   607  	opts.HTTPPort = 0
   608  	opts.HTTPSPort = 0
   609  	s := RunServer(opts)
   610  
   611  	defer s.Shutdown()
   612  
   613  	if s.MonitorAddr() != nil {
   614  		t.Fatal("HttpAddr should be nil.")
   615  	}
   616  }
   617  
   618  type DummyAuth struct {
   619  	t         *testing.T
   620  	needNonce bool
   621  	deadline  time.Time
   622  	register  bool
   623  }
   624  
   625  func (d *DummyAuth) Check(c ClientAuthentication) bool {
   626  	if d.needNonce && len(c.GetNonce()) == 0 {
   627  		d.t.Fatalf("Expected a nonce but received none")
   628  	} else if !d.needNonce && len(c.GetNonce()) > 0 {
   629  		d.t.Fatalf("Received a nonce when none was expected")
   630  	}
   631  
   632  	if c.GetOpts().Username != "valid" {
   633  		return false
   634  	}
   635  
   636  	if !d.register {
   637  		return true
   638  	}
   639  
   640  	u := &User{
   641  		Username:           c.GetOpts().Username,
   642  		ConnectionDeadline: d.deadline,
   643  	}
   644  	c.RegisterUser(u)
   645  
   646  	return true
   647  }
   648  
   649  func TestCustomClientAuthentication(t *testing.T) {
   650  	testAuth := func(t *testing.T, nonce bool) {
   651  		clientAuth := &DummyAuth{t: t, needNonce: nonce}
   652  
   653  		opts := DefaultOptions()
   654  		opts.CustomClientAuthentication = clientAuth
   655  		opts.AlwaysEnableNonce = nonce
   656  
   657  		s := RunServer(opts)
   658  		defer s.Shutdown()
   659  
   660  		addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   661  
   662  		nc, err := nats.Connect(addr, nats.UserInfo("valid", ""))
   663  		if err != nil {
   664  			t.Fatalf("Expected client to connect, got: %s", err)
   665  		}
   666  		nc.Close()
   667  		if _, err := nats.Connect(addr, nats.UserInfo("invalid", "")); err == nil {
   668  			t.Fatal("Expected client to fail to connect")
   669  		}
   670  	}
   671  
   672  	t.Run("with nonce", func(t *testing.T) { testAuth(t, true) })
   673  	t.Run("without nonce", func(t *testing.T) { testAuth(t, false) })
   674  }
   675  
   676  func TestCustomRouterAuthentication(t *testing.T) {
   677  	opts := DefaultOptions()
   678  	opts.CustomRouterAuthentication = &DummyAuth{}
   679  	opts.Cluster.Host = "127.0.0.1"
   680  	s := RunServer(opts)
   681  	defer s.Shutdown()
   682  	clusterPort := s.ClusterAddr().Port
   683  
   684  	opts2 := DefaultOptions()
   685  	opts2.Cluster.Host = "127.0.0.1"
   686  	opts2.Routes = RoutesFromStr(fmt.Sprintf("nats://invalid@127.0.0.1:%d", clusterPort))
   687  	s2 := RunServer(opts2)
   688  	defer s2.Shutdown()
   689  
   690  	// s2 will attempt to connect to s, which should reject.
   691  	// Keep in mind that s2 will try again...
   692  	time.Sleep(50 * time.Millisecond)
   693  	checkNumRoutes(t, s2, 0)
   694  
   695  	opts3 := DefaultOptions()
   696  	opts3.Cluster.Host = "127.0.0.1"
   697  	opts3.Routes = RoutesFromStr(fmt.Sprintf("nats://valid@127.0.0.1:%d", clusterPort))
   698  	s3 := RunServer(opts3)
   699  	defer s3.Shutdown()
   700  	checkClusterFormed(t, s, s3)
   701  	// Default pool size + 1 for system account
   702  	checkNumRoutes(t, s3, DEFAULT_ROUTE_POOL_SIZE+1)
   703  }
   704  
   705  func TestMonitoringNoTimeout(t *testing.T) {
   706  	s := runMonitorServer()
   707  	defer s.Shutdown()
   708  
   709  	s.mu.Lock()
   710  	srv := s.monitoringServer
   711  	s.mu.Unlock()
   712  
   713  	if srv == nil {
   714  		t.Fatalf("Monitoring server not set")
   715  	}
   716  	if srv.ReadTimeout != 0 {
   717  		t.Fatalf("ReadTimeout should not be set, was set to %v", srv.ReadTimeout)
   718  	}
   719  	if srv.WriteTimeout != 0 {
   720  		t.Fatalf("WriteTimeout should not be set, was set to %v", srv.WriteTimeout)
   721  	}
   722  }
   723  
   724  func TestProfilingNoTimeout(t *testing.T) {
   725  	opts := DefaultOptions()
   726  	opts.ProfPort = -1
   727  	s := RunServer(opts)
   728  	defer s.Shutdown()
   729  
   730  	paddr := s.ProfilerAddr()
   731  	if paddr == nil {
   732  		t.Fatalf("Profiler not started")
   733  	}
   734  	pport := paddr.Port
   735  	if pport <= 0 {
   736  		t.Fatalf("Expected profiler port to be set, got %v", pport)
   737  	}
   738  	s.mu.Lock()
   739  	srv := s.profilingServer
   740  	s.mu.Unlock()
   741  
   742  	if srv == nil {
   743  		t.Fatalf("Profiling server not set")
   744  	}
   745  	if srv.ReadTimeout != 0 {
   746  		t.Fatalf("ReadTimeout should not be set, was set to %v", srv.ReadTimeout)
   747  	}
   748  	if srv.WriteTimeout != 0 {
   749  		t.Fatalf("WriteTimeout should not be set, was set to %v", srv.WriteTimeout)
   750  	}
   751  }
   752  
   753  func TestLameDuckOptionsValidation(t *testing.T) {
   754  	o := DefaultOptions()
   755  	o.LameDuckDuration = 5 * time.Second
   756  	o.LameDuckGracePeriod = 10 * time.Second
   757  	s, err := NewServer(o)
   758  	if s != nil {
   759  		s.Shutdown()
   760  	}
   761  	if err == nil || !strings.Contains(err.Error(), "should be strictly lower") {
   762  		t.Fatalf("Expected error saying that ldm grace period should be lower than ldm duration, got %v", err)
   763  	}
   764  }
   765  
   766  func testSetLDMGracePeriod(o *Options, val time.Duration) {
   767  	// For tests, we set the grace period as a negative value
   768  	// so we can have a grace period bigger than the total duration.
   769  	// When validating options, we would not be able to run the
   770  	// server without this trick.
   771  	o.LameDuckGracePeriod = val * -1
   772  }
   773  
   774  func TestLameDuckMode(t *testing.T) {
   775  	optsA := DefaultOptions()
   776  	testSetLDMGracePeriod(optsA, time.Nanosecond)
   777  	optsA.Cluster.Host = "127.0.0.1"
   778  	srvA := RunServer(optsA)
   779  	defer srvA.Shutdown()
   780  
   781  	// Check that if there is no client, server is shutdown
   782  	srvA.lameDuckMode()
   783  	if !srvA.isShuttingDown() {
   784  		t.Fatalf("Server should have shutdown")
   785  	}
   786  
   787  	optsA.LameDuckDuration = 10 * time.Nanosecond
   788  	srvA = RunServer(optsA)
   789  	defer srvA.Shutdown()
   790  
   791  	optsB := DefaultOptions()
   792  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
   793  	srvB := RunServer(optsB)
   794  	defer srvB.Shutdown()
   795  
   796  	checkClusterFormed(t, srvA, srvB)
   797  
   798  	total := 50
   799  	connectClients := func() []*nats.Conn {
   800  		ncs := make([]*nats.Conn, 0, total)
   801  		for i := 0; i < total; i++ {
   802  			nc, err := nats.Connect(fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port),
   803  				nats.ReconnectWait(50*time.Millisecond))
   804  			if err != nil {
   805  				t.Fatalf("Error on connect: %v", err)
   806  			}
   807  			ncs = append(ncs, nc)
   808  		}
   809  		return ncs
   810  	}
   811  	stopClientsAndSrvB := func(ncs []*nats.Conn) {
   812  		for _, nc := range ncs {
   813  			nc.Close()
   814  		}
   815  		srvB.Shutdown()
   816  	}
   817  
   818  	ncs := connectClients()
   819  
   820  	checkClientsCount(t, srvA, total)
   821  	checkClientsCount(t, srvB, 0)
   822  
   823  	start := time.Now()
   824  	srvA.lameDuckMode()
   825  	// Make sure that nothing bad happens if called twice
   826  	srvA.lameDuckMode()
   827  	// Wait that shutdown completes
   828  	elapsed := time.Since(start)
   829  	// It should have taken more than the allotted time of 10ms since we had 50 clients.
   830  	if elapsed <= optsA.LameDuckDuration {
   831  		t.Fatalf("Expected to take more than %v, got %v", optsA.LameDuckDuration, elapsed)
   832  	}
   833  
   834  	checkClientsCount(t, srvA, 0)
   835  	checkClientsCount(t, srvB, total)
   836  
   837  	// Check closed status on server A
   838  	// Connections are saved in go routines, so although we have evaluated the number
   839  	// of connections in the server A to be 0, the polling of connection closed may
   840  	// need a bit more time.
   841  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
   842  		cz := pollConz(t, srvA, 1, "", &ConnzOptions{State: ConnClosed})
   843  		if n := len(cz.Conns); n != total {
   844  			return fmt.Errorf("expected %v closed connections, got %v", total, n)
   845  		}
   846  		return nil
   847  	})
   848  	cz := pollConz(t, srvA, 1, "", &ConnzOptions{State: ConnClosed})
   849  	if n := len(cz.Conns); n != total {
   850  		t.Fatalf("Expected %v closed connections, got %v", total, n)
   851  	}
   852  	for _, c := range cz.Conns {
   853  		checkReason(t, c.Reason, ServerShutdown)
   854  	}
   855  
   856  	stopClientsAndSrvB(ncs)
   857  
   858  	optsA.LameDuckDuration = time.Second
   859  	srvA = RunServer(optsA)
   860  	defer srvA.Shutdown()
   861  
   862  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
   863  	srvB = RunServer(optsB)
   864  	defer srvB.Shutdown()
   865  
   866  	checkClusterFormed(t, srvA, srvB)
   867  
   868  	ncs = connectClients()
   869  
   870  	checkClientsCount(t, srvA, total)
   871  	checkClientsCount(t, srvB, 0)
   872  
   873  	start = time.Now()
   874  	go srvA.lameDuckMode()
   875  	// Check that while in lameDuckMode, it is not possible to connect
   876  	// to the server. Wait to be in LD mode first
   877  	checkFor(t, 500*time.Millisecond, 15*time.Millisecond, func() error {
   878  		srvA.mu.Lock()
   879  		ldm := srvA.ldm
   880  		srvA.mu.Unlock()
   881  		if !ldm {
   882  			return fmt.Errorf("Did not reach lame duck mode")
   883  		}
   884  		return nil
   885  	})
   886  	if _, err := nats.Connect(fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)); err != nats.ErrNoServers {
   887  		t.Fatalf("Expected %v, got %v", nats.ErrNoServers, err)
   888  	}
   889  	srvA.grWG.Wait()
   890  	elapsed = time.Since(start)
   891  
   892  	checkClientsCount(t, srvA, 0)
   893  	checkClientsCount(t, srvB, total)
   894  
   895  	if elapsed > time.Duration(float64(optsA.LameDuckDuration)*1.1) {
   896  		t.Fatalf("Expected to not take more than %v, got %v", optsA.LameDuckDuration, elapsed)
   897  	}
   898  
   899  	stopClientsAndSrvB(ncs)
   900  
   901  	// Now check that we can shutdown server while in LD mode.
   902  	optsA.LameDuckDuration = 60 * time.Second
   903  	srvA = RunServer(optsA)
   904  	defer srvA.Shutdown()
   905  
   906  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
   907  	srvB = RunServer(optsB)
   908  	defer srvB.Shutdown()
   909  
   910  	checkClusterFormed(t, srvA, srvB)
   911  
   912  	ncs = connectClients()
   913  
   914  	checkClientsCount(t, srvA, total)
   915  	checkClientsCount(t, srvB, 0)
   916  
   917  	start = time.Now()
   918  	go srvA.lameDuckMode()
   919  	time.Sleep(100 * time.Millisecond)
   920  	srvA.Shutdown()
   921  	elapsed = time.Since(start)
   922  	// Make sure that it did not take that long
   923  	if elapsed > time.Second {
   924  		t.Fatalf("Took too long: %v", elapsed)
   925  	}
   926  	checkClientsCount(t, srvA, 0)
   927  	checkClientsCount(t, srvB, total)
   928  
   929  	stopClientsAndSrvB(ncs)
   930  
   931  	// Now test that we introduce delay before starting closing client connections.
   932  	// This allow to "signal" multiple servers and avoid their clients to reconnect
   933  	// to a server that is going to be going in LD mode.
   934  	testSetLDMGracePeriod(optsA, 100*time.Millisecond)
   935  	optsA.LameDuckDuration = 10 * time.Millisecond
   936  	srvA = RunServer(optsA)
   937  	defer srvA.Shutdown()
   938  
   939  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
   940  	testSetLDMGracePeriod(optsB, 100*time.Millisecond)
   941  	optsB.LameDuckDuration = 10 * time.Millisecond
   942  	srvB = RunServer(optsB)
   943  	defer srvB.Shutdown()
   944  
   945  	optsC := DefaultOptions()
   946  	optsC.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
   947  	testSetLDMGracePeriod(optsC, 100*time.Millisecond)
   948  	optsC.LameDuckGracePeriod = -100 * time.Millisecond
   949  	optsC.LameDuckDuration = 10 * time.Millisecond
   950  	srvC := RunServer(optsC)
   951  	defer srvC.Shutdown()
   952  
   953  	checkClusterFormed(t, srvA, srvB, srvC)
   954  
   955  	rt := int32(0)
   956  	nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Port),
   957  		nats.ReconnectWait(15*time.Millisecond),
   958  		nats.ReconnectHandler(func(*nats.Conn) {
   959  			atomic.AddInt32(&rt, 1)
   960  		}))
   961  	if err != nil {
   962  		t.Fatalf("Error on connect: %v", err)
   963  	}
   964  	defer nc.Close()
   965  
   966  	go srvA.lameDuckMode()
   967  	// Wait a bit, but less than lameDuckModeInitialDelay that we set in this
   968  	// test to 100ms.
   969  	time.Sleep(30 * time.Millisecond)
   970  	go srvB.lameDuckMode()
   971  
   972  	srvA.grWG.Wait()
   973  	srvB.grWG.Wait()
   974  	checkClientsCount(t, srvC, 1)
   975  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
   976  		if n := atomic.LoadInt32(&rt); n != 1 {
   977  			return fmt.Errorf("Expected client to reconnect only once, got %v", n)
   978  		}
   979  		return nil
   980  	})
   981  }
   982  
   983  func TestLameDuckModeInfo(t *testing.T) {
   984  	optsA := testWSOptions()
   985  	optsA.Cluster.Name = "abc"
   986  	optsA.Cluster.Host = "127.0.0.1"
   987  	optsA.Cluster.Port = -1
   988  	// Ensure that initial delay is set very high so that we can
   989  	// check that some events occur as expected before the client
   990  	// is disconnected.
   991  	testSetLDMGracePeriod(optsA, 5*time.Second)
   992  	optsA.LameDuckDuration = 50 * time.Millisecond
   993  	optsA.DisableShortFirstPing = true
   994  	srvA := RunServer(optsA)
   995  	defer srvA.Shutdown()
   996  
   997  	curla := fmt.Sprintf("127.0.0.1:%d", optsA.Port)
   998  	wscurla := fmt.Sprintf("127.0.0.1:%d", optsA.Websocket.Port)
   999  	c, err := net.Dial("tcp", curla)
  1000  	if err != nil {
  1001  		t.Fatalf("Error connecting: %v", err)
  1002  	}
  1003  	defer c.Close()
  1004  	client := bufio.NewReaderSize(c, maxBufSize)
  1005  
  1006  	wsconn, wsclient := testWSCreateClient(t, false, false, optsA.Websocket.Host, optsA.Websocket.Port)
  1007  	defer wsconn.Close()
  1008  
  1009  	getInfo := func(ws bool) *serverInfo {
  1010  		t.Helper()
  1011  		var l string
  1012  		var err error
  1013  		if ws {
  1014  			l = string(testWSReadFrame(t, wsclient))
  1015  		} else {
  1016  			l, err = client.ReadString('\n')
  1017  			if err != nil {
  1018  				t.Fatalf("Error receiving info from server: %v\n", err)
  1019  			}
  1020  		}
  1021  		var info serverInfo
  1022  		if err = json.Unmarshal([]byte(l[5:]), &info); err != nil {
  1023  			t.Fatalf("Could not parse INFO json: %v\n", err)
  1024  		}
  1025  		return &info
  1026  	}
  1027  
  1028  	getInfo(false)
  1029  	c.Write([]byte("CONNECT {\"protocol\":1,\"verbose\":false}\r\nPING\r\n"))
  1030  	client.ReadString('\n')
  1031  
  1032  	optsB := testWSOptions()
  1033  	optsB.Cluster.Name = "abc"
  1034  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
  1035  	srvB := RunServer(optsB)
  1036  	defer srvB.Shutdown()
  1037  
  1038  	checkClusterFormed(t, srvA, srvB)
  1039  
  1040  	checkConnectURLs := func(expected [][]string) *serverInfo {
  1041  		t.Helper()
  1042  		var si *serverInfo
  1043  		for i, ws := range []bool{false, true} {
  1044  			sort.Strings(expected[i])
  1045  			si = getInfo(ws)
  1046  			sort.Strings(si.ConnectURLs)
  1047  			if !reflect.DeepEqual(expected[i], si.ConnectURLs) {
  1048  				t.Fatalf("Expected %q, got %q", expected, si.ConnectURLs)
  1049  			}
  1050  		}
  1051  		return si
  1052  	}
  1053  
  1054  	curlb := fmt.Sprintf("127.0.0.1:%d", optsB.Port)
  1055  	wscurlb := fmt.Sprintf("127.0.0.1:%d", optsB.Websocket.Port)
  1056  	expected := [][]string{{curla, curlb}, {wscurla, wscurlb}}
  1057  	checkConnectURLs(expected)
  1058  
  1059  	optsC := testWSOptions()
  1060  	testSetLDMGracePeriod(optsA, 5*time.Second)
  1061  	optsC.Cluster.Name = "abc"
  1062  	optsC.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
  1063  	srvC := RunServer(optsC)
  1064  	defer srvC.Shutdown()
  1065  
  1066  	checkClusterFormed(t, srvA, srvB, srvC)
  1067  
  1068  	curlc := fmt.Sprintf("127.0.0.1:%d", optsC.Port)
  1069  	wscurlc := fmt.Sprintf("127.0.0.1:%d", optsC.Websocket.Port)
  1070  	expected = [][]string{{curla, curlb, curlc}, {wscurla, wscurlb, wscurlc}}
  1071  	checkConnectURLs(expected)
  1072  
  1073  	optsD := testWSOptions()
  1074  	optsD.Cluster.Name = "abc"
  1075  	optsD.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port))
  1076  	srvD := RunServer(optsD)
  1077  	defer srvD.Shutdown()
  1078  
  1079  	checkClusterFormed(t, srvA, srvB, srvC, srvD)
  1080  
  1081  	curld := fmt.Sprintf("127.0.0.1:%d", optsD.Port)
  1082  	wscurld := fmt.Sprintf("127.0.0.1:%d", optsD.Websocket.Port)
  1083  	expected = [][]string{{curla, curlb, curlc, curld}, {wscurla, wscurlb, wscurlc, wscurld}}
  1084  	checkConnectURLs(expected)
  1085  
  1086  	// Now lame duck server A and C. We should have client connected to A
  1087  	// receive info that A is in LDM without A's URL, but also receive
  1088  	// an update with C's URL gone.
  1089  	// But first we need to create a client to C because otherwise the
  1090  	// LDM signal will just shut it down because it would have no client.
  1091  	nc, err := nats.Connect(srvC.ClientURL())
  1092  	if err != nil {
  1093  		t.Fatalf("Failed to connect: %v", err)
  1094  	}
  1095  	defer nc.Close()
  1096  	nc.Flush()
  1097  
  1098  	start := time.Now()
  1099  	wg := sync.WaitGroup{}
  1100  	wg.Add(2)
  1101  	go func() {
  1102  		defer wg.Done()
  1103  		srvA.lameDuckMode()
  1104  	}()
  1105  
  1106  	expected = [][]string{{curlb, curlc, curld}, {wscurlb, wscurlc, wscurld}}
  1107  	si := checkConnectURLs(expected)
  1108  	if !si.LameDuckMode {
  1109  		t.Fatal("Expected LameDuckMode to be true, it was not")
  1110  	}
  1111  
  1112  	// Start LDM for server C. This should send an update to A
  1113  	// which in turn should remove C from the list of URLs and
  1114  	// update its client.
  1115  	go func() {
  1116  		defer wg.Done()
  1117  		srvC.lameDuckMode()
  1118  	}()
  1119  
  1120  	expected = [][]string{{curlb, curld}, {wscurlb, wscurld}}
  1121  	si = checkConnectURLs(expected)
  1122  	// This update should not say that it is LDM.
  1123  	if si.LameDuckMode {
  1124  		t.Fatal("Expected LameDuckMode to be false, it was true")
  1125  	}
  1126  
  1127  	// Now shutdown D, and we also should get an update.
  1128  	srvD.Shutdown()
  1129  
  1130  	expected = [][]string{{curlb}, {wscurlb}}
  1131  	si = checkConnectURLs(expected)
  1132  	// This update should not say that it is LDM.
  1133  	if si.LameDuckMode {
  1134  		t.Fatal("Expected LameDuckMode to be false, it was true")
  1135  	}
  1136  	if time.Since(start) > 2*time.Second {
  1137  		t.Fatalf("Did not get the expected events prior of server A and C shutting down")
  1138  	}
  1139  
  1140  	// Now explicitly shutdown srvA. When a server shutdown, it closes all its
  1141  	// connections. For routes, it means that it is going to remove the remote's
  1142  	// URL from its map. We want to make sure that in that case, server does not
  1143  	// actually send an updated INFO to its clients.
  1144  	srvA.Shutdown()
  1145  
  1146  	// Expect nothing to be received on the client connection.
  1147  	if l, err := client.ReadString('\n'); err == nil {
  1148  		t.Fatalf("Expected connection to fail, instead got %q", l)
  1149  	}
  1150  
  1151  	c.Close()
  1152  	nc.Close()
  1153  	// Don't need to wait for actual disconnect of clients.
  1154  	srvC.Shutdown()
  1155  	wg.Wait()
  1156  }
  1157  
  1158  func TestServerValidateGatewaysOptions(t *testing.T) {
  1159  	baseOpt := testDefaultOptionsForGateway("A")
  1160  	u, _ := url.Parse("host:5222")
  1161  	g := &RemoteGatewayOpts{
  1162  		URLs: []*url.URL{u},
  1163  	}
  1164  	baseOpt.Gateway.Gateways = append(baseOpt.Gateway.Gateways, g)
  1165  
  1166  	for _, test := range []struct {
  1167  		name        string
  1168  		opts        func() *Options
  1169  		expectedErr string
  1170  	}{
  1171  		{
  1172  			name: "gateway_has_no_name",
  1173  			opts: func() *Options {
  1174  				o := baseOpt.Clone()
  1175  				o.Gateway.Name = ""
  1176  				return o
  1177  			},
  1178  			expectedErr: "has no name",
  1179  		},
  1180  		{
  1181  			name: "gateway_has_no_port",
  1182  			opts: func() *Options {
  1183  				o := baseOpt.Clone()
  1184  				o.Gateway.Port = 0
  1185  				return o
  1186  			},
  1187  			expectedErr: "no port specified",
  1188  		},
  1189  		{
  1190  			name: "gateway_dst_has_no_name",
  1191  			opts: func() *Options {
  1192  				o := baseOpt.Clone()
  1193  				return o
  1194  			},
  1195  			expectedErr: "has no name",
  1196  		},
  1197  		{
  1198  			name: "gateway_dst_urls_is_nil",
  1199  			opts: func() *Options {
  1200  				o := baseOpt.Clone()
  1201  				o.Gateway.Gateways[0].Name = "B"
  1202  				o.Gateway.Gateways[0].URLs = nil
  1203  				return o
  1204  			},
  1205  			expectedErr: "has no URL",
  1206  		},
  1207  		{
  1208  			name: "gateway_dst_urls_is_empty",
  1209  			opts: func() *Options {
  1210  				o := baseOpt.Clone()
  1211  				o.Gateway.Gateways[0].Name = "B"
  1212  				o.Gateway.Gateways[0].URLs = []*url.URL{}
  1213  				return o
  1214  			},
  1215  			expectedErr: "has no URL",
  1216  		},
  1217  	} {
  1218  		t.Run(test.name, func(t *testing.T) {
  1219  			if err := validateOptions(test.opts()); err == nil || !strings.Contains(err.Error(), test.expectedErr) {
  1220  				t.Fatalf("Expected error about %q, got %v", test.expectedErr, err)
  1221  			}
  1222  		})
  1223  	}
  1224  }
  1225  
  1226  func TestAcceptError(t *testing.T) {
  1227  	o := DefaultOptions()
  1228  	s := New(o)
  1229  	s.running.Store(true)
  1230  	defer s.Shutdown()
  1231  	orgDelay := time.Hour
  1232  	delay := s.acceptError("Test", fmt.Errorf("any error"), orgDelay)
  1233  	if delay != orgDelay {
  1234  		t.Fatalf("With this type of error, delay should have stayed same, got %v", delay)
  1235  	}
  1236  
  1237  	// Create any net.Error and make it a temporary
  1238  	ne := &net.DNSError{IsTemporary: true}
  1239  	orgDelay = 10 * time.Millisecond
  1240  	delay = s.acceptError("Test", ne, orgDelay)
  1241  	if delay != 2*orgDelay {
  1242  		t.Fatalf("Expected delay to double, got %v", delay)
  1243  	}
  1244  	// Now check the max
  1245  	orgDelay = 60 * ACCEPT_MAX_SLEEP / 100
  1246  	delay = s.acceptError("Test", ne, orgDelay)
  1247  	if delay != ACCEPT_MAX_SLEEP {
  1248  		t.Fatalf("Expected delay to double, got %v", delay)
  1249  	}
  1250  	wg := sync.WaitGroup{}
  1251  	wg.Add(1)
  1252  	start := time.Now()
  1253  	go func() {
  1254  		s.acceptError("Test", ne, orgDelay)
  1255  		wg.Done()
  1256  	}()
  1257  	time.Sleep(100 * time.Millisecond)
  1258  	// This should kick out the sleep in acceptError
  1259  	s.Shutdown()
  1260  	if dur := time.Since(start); dur >= ACCEPT_MAX_SLEEP {
  1261  		t.Fatalf("Shutdown took too long: %v", dur)
  1262  	}
  1263  	wg.Wait()
  1264  	if d := s.acceptError("Test", ne, orgDelay); d >= 0 {
  1265  		t.Fatalf("Expected delay to be negative, got %v", d)
  1266  	}
  1267  }
  1268  
  1269  func TestServerShutdownDuringStart(t *testing.T) {
  1270  	o := DefaultOptions()
  1271  	o.ServerName = "server"
  1272  	o.DisableShortFirstPing = true
  1273  	o.Accounts = []*Account{NewAccount("$SYS")}
  1274  	o.SystemAccount = "$SYS"
  1275  	o.Cluster.Name = "abc"
  1276  	o.Cluster.Host = "127.0.0.1"
  1277  	o.Cluster.Port = -1
  1278  	o.Gateway.Name = "abc"
  1279  	o.Gateway.Host = "127.0.0.1"
  1280  	o.Gateway.Port = -1
  1281  	o.LeafNode.Host = "127.0.0.1"
  1282  	o.LeafNode.Port = -1
  1283  	o.Websocket.Host = "127.0.0.1"
  1284  	o.Websocket.Port = -1
  1285  	o.Websocket.HandshakeTimeout = 1
  1286  	o.Websocket.NoTLS = true
  1287  	o.MQTT.Host = "127.0.0.1"
  1288  	o.MQTT.Port = -1
  1289  
  1290  	// We are going to test that if the server is shutdown
  1291  	// while Start() runs (in this case, before), we don't
  1292  	// start the listeners and therefore leave accept loops
  1293  	// hanging.
  1294  	s, err := NewServer(o)
  1295  	if err != nil {
  1296  		t.Fatalf("Error creating server: %v", err)
  1297  	}
  1298  	s.Shutdown()
  1299  
  1300  	// Start() should not block, but just in case, start in
  1301  	// different go routine.
  1302  	ch := make(chan struct{}, 1)
  1303  	go func() {
  1304  		s.Start()
  1305  		close(ch)
  1306  	}()
  1307  	select {
  1308  	case <-ch:
  1309  	case <-time.After(time.Second):
  1310  		t.Fatal("Start appear to have blocked after server was shutdown")
  1311  	}
  1312  	// Now make sure that none of the listeners have been created
  1313  	listeners := []string{}
  1314  	s.mu.Lock()
  1315  	if s.listener != nil {
  1316  		listeners = append(listeners, "client")
  1317  	}
  1318  	if s.routeListener != nil {
  1319  		listeners = append(listeners, "route")
  1320  	}
  1321  	if s.gatewayListener != nil {
  1322  		listeners = append(listeners, "gateway")
  1323  	}
  1324  	if s.leafNodeListener != nil {
  1325  		listeners = append(listeners, "leafnode")
  1326  	}
  1327  	if s.websocket.listener != nil {
  1328  		listeners = append(listeners, "websocket")
  1329  	}
  1330  	if s.mqtt.listener != nil {
  1331  		listeners = append(listeners, "mqtt")
  1332  	}
  1333  	s.mu.Unlock()
  1334  	if len(listeners) > 0 {
  1335  		lst := ""
  1336  		for i, l := range listeners {
  1337  			if i > 0 {
  1338  				lst += ", "
  1339  			}
  1340  			lst += l
  1341  		}
  1342  		t.Fatalf("Following listeners have been created: %s", lst)
  1343  	}
  1344  }
  1345  
  1346  type myDummyDNSResolver struct {
  1347  	ips []string
  1348  	err error
  1349  }
  1350  
  1351  func (r *myDummyDNSResolver) LookupHost(ctx context.Context, host string) ([]string, error) {
  1352  	if r.err != nil {
  1353  		return nil, r.err
  1354  	}
  1355  	return r.ips, nil
  1356  }
  1357  
  1358  func TestGetRandomIP(t *testing.T) {
  1359  	s := &Server{}
  1360  	resolver := &myDummyDNSResolver{}
  1361  	// no port...
  1362  	if _, err := s.getRandomIP(resolver, "noport", nil); err == nil || !strings.Contains(err.Error(), "port") {
  1363  		t.Fatalf("Expected error about port missing, got %v", err)
  1364  	}
  1365  	resolver.err = fmt.Errorf("on purpose")
  1366  	if _, err := s.getRandomIP(resolver, "localhost:4222", nil); err == nil || !strings.Contains(err.Error(), "on purpose") {
  1367  		t.Fatalf("Expected error about no port, got %v", err)
  1368  	}
  1369  	resolver.err = nil
  1370  	a, err := s.getRandomIP(resolver, "localhost:4222", nil)
  1371  	if err != nil {
  1372  		t.Fatalf("Unexpected error: %v", err)
  1373  	}
  1374  	if a != "localhost:4222" {
  1375  		t.Fatalf("Expected address to be %q, got %q", "localhost:4222", a)
  1376  	}
  1377  	resolver.ips = []string{"1.2.3.4"}
  1378  	a, err = s.getRandomIP(resolver, "localhost:4222", nil)
  1379  	if err != nil {
  1380  		t.Fatalf("Unexpected error: %v", err)
  1381  	}
  1382  	if a != "1.2.3.4:4222" {
  1383  		t.Fatalf("Expected address to be %q, got %q", "1.2.3.4:4222", a)
  1384  	}
  1385  	// Check for randomness
  1386  	resolver.ips = []string{"1.2.3.4", "2.2.3.4", "3.2.3.4"}
  1387  	dist := [3]int{}
  1388  	for i := 0; i < 100; i++ {
  1389  		ip, err := s.getRandomIP(resolver, "localhost:4222", nil)
  1390  		if err != nil {
  1391  			t.Fatalf("Unexpected error: %v", err)
  1392  		}
  1393  		v := int(ip[0]-'0') - 1
  1394  		dist[v]++
  1395  	}
  1396  	low := 20
  1397  	high := 47
  1398  	for i, d := range dist {
  1399  		if d == 0 || d == 100 {
  1400  			t.Fatalf("Unexpected distribution for ip %v, got %v", i, d)
  1401  		} else if d < low || d > high {
  1402  			t.Logf("Warning: out of expected range [%v,%v] for ip %v, got %v", low, high, i, d)
  1403  		}
  1404  	}
  1405  
  1406  	// Check IP exclusions
  1407  	excludedIPs := map[string]struct{}{"1.2.3.4:4222": {}}
  1408  	for i := 0; i < 100; i++ {
  1409  		ip, err := s.getRandomIP(resolver, "localhost:4222", excludedIPs)
  1410  		if err != nil {
  1411  			t.Fatalf("Unexpected error: %v", err)
  1412  		}
  1413  		if ip[0] == '1' {
  1414  			t.Fatalf("Should not have returned this ip: %q", ip)
  1415  		}
  1416  	}
  1417  	excludedIPs["2.2.3.4:4222"] = struct{}{}
  1418  	for i := 0; i < 100; i++ {
  1419  		ip, err := s.getRandomIP(resolver, "localhost:4222", excludedIPs)
  1420  		if err != nil {
  1421  			t.Fatalf("Unexpected error: %v", err)
  1422  		}
  1423  		if ip[0] != '3' {
  1424  			t.Fatalf("Should only have returned '3.2.3.4', got returned %q", ip)
  1425  		}
  1426  	}
  1427  	excludedIPs["3.2.3.4:4222"] = struct{}{}
  1428  	for i := 0; i < 100; i++ {
  1429  		if _, err := s.getRandomIP(resolver, "localhost:4222", excludedIPs); err != errNoIPAvail {
  1430  			t.Fatalf("Unexpected error: %v", err)
  1431  		}
  1432  	}
  1433  
  1434  	// Now check that exclusion takes into account the port number.
  1435  	resolver.ips = []string{"127.0.0.1"}
  1436  	excludedIPs = map[string]struct{}{"127.0.0.1:4222": {}}
  1437  	for i := 0; i < 100; i++ {
  1438  		if _, err := s.getRandomIP(resolver, "localhost:4223", excludedIPs); err == errNoIPAvail {
  1439  			t.Fatal("Should not have failed")
  1440  		}
  1441  	}
  1442  }
  1443  
  1444  type shortWriteConn struct {
  1445  	net.Conn
  1446  }
  1447  
  1448  func (swc *shortWriteConn) Write(b []byte) (int, error) {
  1449  	// Limit the write to 10 bytes at a time.
  1450  	short := false
  1451  	max := len(b)
  1452  	if max > 10 {
  1453  		max = 10
  1454  		short = true
  1455  	}
  1456  	n, err := swc.Conn.Write(b[:max])
  1457  	if err == nil && short {
  1458  		return n, io.ErrShortWrite
  1459  	}
  1460  	return n, err
  1461  }
  1462  
  1463  func TestClientWriteLoopStall(t *testing.T) {
  1464  	opts := DefaultOptions()
  1465  	s := RunServer(opts)
  1466  	defer s.Shutdown()
  1467  
  1468  	errCh := make(chan error, 1)
  1469  
  1470  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1471  	nc, err := nats.Connect(url,
  1472  		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, e error) {
  1473  			select {
  1474  			case errCh <- e:
  1475  			default:
  1476  			}
  1477  		}))
  1478  	if err != nil {
  1479  		t.Fatalf("Error on connect: %v", err)
  1480  	}
  1481  	defer nc.Close()
  1482  	sub, err := nc.SubscribeSync("foo")
  1483  	if err != nil {
  1484  		t.Fatalf("Error on subscribe: %v", err)
  1485  	}
  1486  	nc.Flush()
  1487  	cid, _ := nc.GetClientID()
  1488  
  1489  	sender, err := nats.Connect(url)
  1490  	if err != nil {
  1491  		t.Fatalf("Error on connect: %v", err)
  1492  	}
  1493  	defer sender.Close()
  1494  
  1495  	c := s.getClient(cid)
  1496  	c.mu.Lock()
  1497  	c.nc = &shortWriteConn{Conn: c.nc}
  1498  	c.mu.Unlock()
  1499  
  1500  	sender.Publish("foo", make([]byte, 100))
  1501  
  1502  	if _, err := sub.NextMsg(3 * time.Second); err != nil {
  1503  		t.Fatalf("WriteLoop has stalled!")
  1504  	}
  1505  
  1506  	// Make sure that we did not get any async error
  1507  	select {
  1508  	case e := <-errCh:
  1509  		t.Fatalf("Got error: %v", e)
  1510  	case <-time.After(250 * time.Millisecond):
  1511  	}
  1512  }
  1513  
  1514  func TestInsecureSkipVerifyWarning(t *testing.T) {
  1515  	checkWarnReported := func(t *testing.T, o *Options, expectedWarn string) {
  1516  		t.Helper()
  1517  		s, err := NewServer(o)
  1518  		if err != nil {
  1519  			t.Fatalf("Error on new server: %v", err)
  1520  		}
  1521  		l := &captureWarnLogger{warn: make(chan string, 1)}
  1522  		s.SetLogger(l, false, false)
  1523  		wg := sync.WaitGroup{}
  1524  		wg.Add(1)
  1525  		go func() {
  1526  			s.Start()
  1527  			wg.Done()
  1528  		}()
  1529  		if err := s.readyForConnections(time.Second); err != nil {
  1530  			t.Fatal(err)
  1531  		}
  1532  		select {
  1533  		case w := <-l.warn:
  1534  			if !strings.Contains(w, expectedWarn) {
  1535  				t.Fatalf("Expected warning %q, got %q", expectedWarn, w)
  1536  			}
  1537  		case <-time.After(2 * time.Second):
  1538  			t.Fatalf("Did not get warning %q", expectedWarn)
  1539  		}
  1540  		s.Shutdown()
  1541  		wg.Wait()
  1542  	}
  1543  
  1544  	tc := &TLSConfigOpts{}
  1545  	tc.CertFile = "../test/configs/certs/server-cert.pem"
  1546  	tc.KeyFile = "../test/configs/certs/server-key.pem"
  1547  	tc.CaFile = "../test/configs/certs/ca.pem"
  1548  	tc.Insecure = true
  1549  	config, err := GenTLSConfig(tc)
  1550  	if err != nil {
  1551  		t.Fatalf("Error generating tls config: %v", err)
  1552  	}
  1553  
  1554  	o := DefaultOptions()
  1555  	o.Cluster.Name = "A"
  1556  	o.Cluster.Port = -1
  1557  	o.Cluster.TLSConfig = config.Clone()
  1558  	checkWarnReported(t, o, clusterTLSInsecureWarning)
  1559  
  1560  	// Remove the route setting
  1561  	o.Cluster.Port = 0
  1562  	o.Cluster.TLSConfig = nil
  1563  
  1564  	// Configure LeafNode with no TLS in the main block first, but only with remotes.
  1565  	o.LeafNode.Port = -1
  1566  	rurl, _ := url.Parse("nats://127.0.0.1:1234")
  1567  	o.LeafNode.Remotes = []*RemoteLeafOpts{
  1568  		{
  1569  			URLs:      []*url.URL{rurl},
  1570  			TLSConfig: config.Clone(),
  1571  		},
  1572  	}
  1573  	checkWarnReported(t, o, leafnodeTLSInsecureWarning)
  1574  
  1575  	// Now add to main block.
  1576  	o.LeafNode.TLSConfig = config.Clone()
  1577  	checkWarnReported(t, o, leafnodeTLSInsecureWarning)
  1578  
  1579  	// Now remove remote and check warning still reported
  1580  	o.LeafNode.Remotes = nil
  1581  	checkWarnReported(t, o, leafnodeTLSInsecureWarning)
  1582  
  1583  	// Remove the LN setting
  1584  	o.LeafNode.Port = 0
  1585  	o.LeafNode.TLSConfig = nil
  1586  
  1587  	// Configure GW with no TLS in main block first, but only with remotes
  1588  	o.Gateway.Name = "A"
  1589  	o.Gateway.Host = "127.0.0.1"
  1590  	o.Gateway.Port = -1
  1591  	o.Gateway.Gateways = []*RemoteGatewayOpts{
  1592  		{
  1593  			Name:      "B",
  1594  			URLs:      []*url.URL{rurl},
  1595  			TLSConfig: config.Clone(),
  1596  		},
  1597  	}
  1598  	checkWarnReported(t, o, gatewayTLSInsecureWarning)
  1599  
  1600  	// Now add to main block.
  1601  	o.Gateway.TLSConfig = config.Clone()
  1602  	checkWarnReported(t, o, gatewayTLSInsecureWarning)
  1603  
  1604  	// Now remove remote and check warning still reported
  1605  	o.Gateway.Gateways = nil
  1606  	checkWarnReported(t, o, gatewayTLSInsecureWarning)
  1607  }
  1608  
  1609  func TestConnectErrorReports(t *testing.T) {
  1610  	// On Windows, an attempt to connect to a port that has no listener will
  1611  	// take whatever timeout specified in DialTimeout() before failing.
  1612  	// So skip for now.
  1613  	if runtime.GOOS == "windows" {
  1614  		t.Skip()
  1615  	}
  1616  	// Check that default report attempts is as expected
  1617  	opts := DefaultOptions()
  1618  	s := RunServer(opts)
  1619  	defer s.Shutdown()
  1620  
  1621  	if ra := s.getOpts().ConnectErrorReports; ra != DEFAULT_CONNECT_ERROR_REPORTS {
  1622  		t.Fatalf("Expected default value to be %v, got %v", DEFAULT_CONNECT_ERROR_REPORTS, ra)
  1623  	}
  1624  
  1625  	tmpFile := createTempFile(t, "")
  1626  	log := tmpFile.Name()
  1627  	tmpFile.Close()
  1628  
  1629  	remoteURLs := RoutesFromStr("nats://127.0.0.1:1234")
  1630  
  1631  	opts = DefaultOptions()
  1632  	opts.ConnectErrorReports = 3
  1633  	opts.Cluster.Port = -1
  1634  	opts.Routes = remoteURLs
  1635  	opts.NoLog = false
  1636  	opts.LogFile = log
  1637  	opts.Logtime = true
  1638  	opts.Debug = true
  1639  	s = RunServer(opts)
  1640  	defer s.Shutdown()
  1641  
  1642  	checkContent := func(t *testing.T, txt string, attempt int, shouldBeThere bool) {
  1643  		t.Helper()
  1644  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  1645  			content, err := os.ReadFile(log)
  1646  			if err != nil {
  1647  				return fmt.Errorf("Error reading log file: %v", err)
  1648  			}
  1649  			present := bytes.Contains(content, []byte(fmt.Sprintf("%s (attempt %d)", txt, attempt)))
  1650  			if shouldBeThere && !present {
  1651  				return fmt.Errorf("Did not find expected log statement (%s) for attempt %d: %s", txt, attempt, content)
  1652  			} else if !shouldBeThere && present {
  1653  				return fmt.Errorf("Log statement (%s) for attempt %d should not be present: %s", txt, attempt, content)
  1654  			}
  1655  			return nil
  1656  		})
  1657  	}
  1658  
  1659  	type testConnect struct {
  1660  		name        string
  1661  		attempt     int
  1662  		errExpected bool
  1663  	}
  1664  	for _, test := range []testConnect{
  1665  		{"route_attempt_1", 1, true},
  1666  		{"route_attempt_2", 2, false},
  1667  		{"route_attempt_3", 3, true},
  1668  		{"route_attempt_4", 4, false},
  1669  		{"route_attempt_6", 6, true},
  1670  		{"route_attempt_7", 7, false},
  1671  	} {
  1672  		t.Run(test.name, func(t *testing.T) {
  1673  			debugExpected := !test.errExpected
  1674  			checkContent(t, "[DBG] Error trying to connect to route", test.attempt, debugExpected)
  1675  			checkContent(t, "[ERR] Error trying to connect to route", test.attempt, test.errExpected)
  1676  		})
  1677  	}
  1678  
  1679  	s.Shutdown()
  1680  	removeFile(t, log)
  1681  
  1682  	// Now try with leaf nodes
  1683  	opts.Cluster.Port = 0
  1684  	opts.Routes = nil
  1685  	opts.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{remoteURLs[0]}}}
  1686  	opts.LeafNode.ReconnectInterval = 15 * time.Millisecond
  1687  	s = RunServer(opts)
  1688  	defer s.Shutdown()
  1689  
  1690  	checkLeafContent := func(t *testing.T, txt, host string, attempt int, shouldBeThere bool) {
  1691  		t.Helper()
  1692  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  1693  			content, err := os.ReadFile(log)
  1694  			if err != nil {
  1695  				return fmt.Errorf("Error reading log file: %v", err)
  1696  			}
  1697  			present := bytes.Contains(content, []byte(fmt.Sprintf("%s %q (attempt %d)", txt, host, attempt)))
  1698  			if shouldBeThere && !present {
  1699  				return fmt.Errorf("Did not find expected log statement (%s %q) for attempt %d: %s", txt, host, attempt, content)
  1700  			} else if !shouldBeThere && present {
  1701  				return fmt.Errorf("Log statement (%s %q) for attempt %d should not be present: %s", txt, host, attempt, content)
  1702  			}
  1703  			return nil
  1704  		})
  1705  	}
  1706  
  1707  	for _, test := range []testConnect{
  1708  		{"leafnode_attempt_1", 1, true},
  1709  		{"leafnode_attempt_2", 2, false},
  1710  		{"leafnode_attempt_3", 3, true},
  1711  		{"leafnode_attempt_4", 4, false},
  1712  		{"leafnode_attempt_6", 6, true},
  1713  		{"leafnode_attempt_7", 7, false},
  1714  	} {
  1715  		t.Run(test.name, func(t *testing.T) {
  1716  			debugExpected := !test.errExpected
  1717  			checkLeafContent(t, "[DBG] Error trying to connect as leafnode to remote server", remoteURLs[0].Host, test.attempt, debugExpected)
  1718  			checkLeafContent(t, "[ERR] Error trying to connect as leafnode to remote server", remoteURLs[0].Host, test.attempt, test.errExpected)
  1719  		})
  1720  	}
  1721  
  1722  	s.Shutdown()
  1723  	removeFile(t, log)
  1724  
  1725  	// Now try with gateways
  1726  	opts.LeafNode.Remotes = nil
  1727  	opts.Cluster.Name = "A"
  1728  	opts.Gateway.Name = "A"
  1729  	opts.Gateway.Port = -1
  1730  	opts.Gateway.Gateways = []*RemoteGatewayOpts{
  1731  		{
  1732  			Name: "B",
  1733  			URLs: remoteURLs,
  1734  		},
  1735  	}
  1736  	opts.gatewaysSolicitDelay = 15 * time.Millisecond
  1737  	s = RunServer(opts)
  1738  	defer s.Shutdown()
  1739  
  1740  	for _, test := range []testConnect{
  1741  		{"gateway_attempt_1", 1, true},
  1742  		{"gateway_attempt_2", 2, false},
  1743  		{"gateway_attempt_3", 3, true},
  1744  		{"gateway_attempt_4", 4, false},
  1745  		{"gateway_attempt_6", 6, true},
  1746  		{"gateway_attempt_7", 7, false},
  1747  	} {
  1748  		t.Run(test.name, func(t *testing.T) {
  1749  			debugExpected := !test.errExpected
  1750  			infoExpected := test.errExpected
  1751  			// For gateways, we also check our notice that we attempt to connect
  1752  			checkContent(t, "[DBG] Connecting to explicit gateway \"B\" (127.0.0.1:1234) at 127.0.0.1:1234", test.attempt, debugExpected)
  1753  			checkContent(t, "[INF] Connecting to explicit gateway \"B\" (127.0.0.1:1234) at 127.0.0.1:1234", test.attempt, infoExpected)
  1754  			checkContent(t, "[DBG] Error connecting to explicit gateway \"B\" (127.0.0.1:1234) at 127.0.0.1:1234", test.attempt, debugExpected)
  1755  			checkContent(t, "[ERR] Error connecting to explicit gateway \"B\" (127.0.0.1:1234) at 127.0.0.1:1234", test.attempt, test.errExpected)
  1756  		})
  1757  	}
  1758  }
  1759  
  1760  func TestReconnectErrorReports(t *testing.T) {
  1761  	// On Windows, an attempt to connect to a port that has no listener will
  1762  	// take whatever timeout specified in DialTimeout() before failing.
  1763  	// So skip for now.
  1764  	if runtime.GOOS == "windows" {
  1765  		t.Skip()
  1766  	}
  1767  	// Check that default report attempts is as expected
  1768  	opts := DefaultOptions()
  1769  	s := RunServer(opts)
  1770  	defer s.Shutdown()
  1771  
  1772  	if ra := s.getOpts().ReconnectErrorReports; ra != DEFAULT_RECONNECT_ERROR_REPORTS {
  1773  		t.Fatalf("Expected default value to be %v, got %v", DEFAULT_RECONNECT_ERROR_REPORTS, ra)
  1774  	}
  1775  
  1776  	tmpFile := createTempFile(t, "")
  1777  	log := tmpFile.Name()
  1778  	tmpFile.Close()
  1779  
  1780  	csOpts := DefaultOptions()
  1781  	csOpts.Cluster.Port = -1
  1782  	cs := RunServer(csOpts)
  1783  	defer cs.Shutdown()
  1784  
  1785  	opts = DefaultOptions()
  1786  	opts.ReconnectErrorReports = 3
  1787  	opts.Cluster.Port = -1
  1788  	opts.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", cs.ClusterAddr().Port))
  1789  	opts.NoLog = false
  1790  	opts.LogFile = log
  1791  	opts.Logtime = true
  1792  	opts.Debug = true
  1793  	s = RunServer(opts)
  1794  	defer s.Shutdown()
  1795  
  1796  	// Wait for cluster to be formed
  1797  	checkClusterFormed(t, s, cs)
  1798  
  1799  	// Now shutdown the server s connected to.
  1800  	cs.Shutdown()
  1801  
  1802  	// Specifically for route test, wait at least reconnect interval before checking logs
  1803  	time.Sleep(DEFAULT_ROUTE_RECONNECT)
  1804  
  1805  	checkContent := func(t *testing.T, txt string, attempt int, shouldBeThere bool) {
  1806  		t.Helper()
  1807  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  1808  			content, err := os.ReadFile(log)
  1809  			if err != nil {
  1810  				return fmt.Errorf("Error reading log file: %v", err)
  1811  			}
  1812  			present := bytes.Contains(content, []byte(fmt.Sprintf("%s (attempt %d)", txt, attempt)))
  1813  			if shouldBeThere && !present {
  1814  				return fmt.Errorf("Did not find expected log statement (%s) for attempt %d: %s", txt, attempt, content)
  1815  			} else if !shouldBeThere && present {
  1816  				return fmt.Errorf("Log statement (%s) for attempt %d should not be present: %s", txt, attempt, content)
  1817  			}
  1818  			return nil
  1819  		})
  1820  	}
  1821  
  1822  	type testConnect struct {
  1823  		name        string
  1824  		attempt     int
  1825  		errExpected bool
  1826  	}
  1827  	for _, test := range []testConnect{
  1828  		{"route_attempt_1", 1, true},
  1829  		{"route_attempt_2", 2, false},
  1830  		{"route_attempt_3", 3, true},
  1831  		{"route_attempt_4", 4, false},
  1832  		{"route_attempt_6", 6, true},
  1833  		{"route_attempt_7", 7, false},
  1834  	} {
  1835  		t.Run(test.name, func(t *testing.T) {
  1836  			debugExpected := !test.errExpected
  1837  			checkContent(t, "[DBG] Error trying to connect to route", test.attempt, debugExpected)
  1838  			checkContent(t, "[ERR] Error trying to connect to route", test.attempt, test.errExpected)
  1839  		})
  1840  	}
  1841  
  1842  	s.Shutdown()
  1843  	removeFile(t, log)
  1844  
  1845  	// Now try with leaf nodes
  1846  	csOpts.Cluster.Port = 0
  1847  	csOpts.Cluster.Name = _EMPTY_
  1848  	csOpts.LeafNode.Host = "127.0.0.1"
  1849  	csOpts.LeafNode.Port = -1
  1850  
  1851  	cs = RunServer(csOpts)
  1852  	defer cs.Shutdown()
  1853  
  1854  	opts.Cluster.Port = 0
  1855  	opts.Cluster.Name = _EMPTY_
  1856  	opts.Routes = nil
  1857  	u, _ := url.Parse(fmt.Sprintf("nats://127.0.0.1:%d", csOpts.LeafNode.Port))
  1858  	opts.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{u}}}
  1859  	opts.LeafNode.ReconnectInterval = 15 * time.Millisecond
  1860  	s = RunServer(opts)
  1861  	defer s.Shutdown()
  1862  
  1863  	checkLeafNodeConnected(t, s)
  1864  
  1865  	// Now shutdown the server s is connected to
  1866  	cs.Shutdown()
  1867  
  1868  	checkLeafContent := func(t *testing.T, txt, host string, attempt int, shouldBeThere bool) {
  1869  		t.Helper()
  1870  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  1871  			content, err := os.ReadFile(log)
  1872  			if err != nil {
  1873  				return fmt.Errorf("Error reading log file: %v", err)
  1874  			}
  1875  			present := bytes.Contains(content, []byte(fmt.Sprintf("%s %q (attempt %d)", txt, host, attempt)))
  1876  			if shouldBeThere && !present {
  1877  				return fmt.Errorf("Did not find expected log statement (%s %q) for attempt %d: %s", txt, host, attempt, content)
  1878  			} else if !shouldBeThere && present {
  1879  				return fmt.Errorf("Log statement (%s %q) for attempt %d should not be present: %s", txt, host, attempt, content)
  1880  			}
  1881  			return nil
  1882  		})
  1883  	}
  1884  
  1885  	for _, test := range []testConnect{
  1886  		{"leafnode_attempt_1", 1, true},
  1887  		{"leafnode_attempt_2", 2, false},
  1888  		{"leafnode_attempt_3", 3, true},
  1889  		{"leafnode_attempt_4", 4, false},
  1890  		{"leafnode_attempt_6", 6, true},
  1891  		{"leafnode_attempt_7", 7, false},
  1892  	} {
  1893  		t.Run(test.name, func(t *testing.T) {
  1894  			debugExpected := !test.errExpected
  1895  			checkLeafContent(t, "[DBG] Error trying to connect as leafnode to remote server", u.Host, test.attempt, debugExpected)
  1896  			checkLeafContent(t, "[ERR] Error trying to connect as leafnode to remote server", u.Host, test.attempt, test.errExpected)
  1897  		})
  1898  	}
  1899  
  1900  	s.Shutdown()
  1901  	removeFile(t, log)
  1902  
  1903  	// Now try with gateways
  1904  	csOpts.LeafNode.Port = 0
  1905  	csOpts.Cluster.Name = "B"
  1906  	csOpts.Gateway.Name = "B"
  1907  	csOpts.Gateway.Port = -1
  1908  	cs = RunServer(csOpts)
  1909  
  1910  	opts.LeafNode.Remotes = nil
  1911  	opts.Cluster.Name = "A"
  1912  	opts.Gateway.Name = "A"
  1913  	opts.Gateway.Port = -1
  1914  	remoteGWPort := cs.GatewayAddr().Port
  1915  	u, _ = url.Parse(fmt.Sprintf("nats://127.0.0.1:%d", remoteGWPort))
  1916  	opts.Gateway.Gateways = []*RemoteGatewayOpts{
  1917  		{
  1918  			Name: "B",
  1919  			URLs: []*url.URL{u},
  1920  		},
  1921  	}
  1922  	opts.gatewaysSolicitDelay = 15 * time.Millisecond
  1923  	s = RunServer(opts)
  1924  	defer s.Shutdown()
  1925  
  1926  	waitForOutboundGateways(t, s, 1, 2*time.Second)
  1927  	waitForInboundGateways(t, s, 1, 2*time.Second)
  1928  
  1929  	// Now stop server s is connecting to
  1930  	cs.Shutdown()
  1931  
  1932  	connTxt := fmt.Sprintf("Connecting to explicit gateway \"B\" (127.0.0.1:%d) at 127.0.0.1:%d", remoteGWPort, remoteGWPort)
  1933  	dbgConnTxt := fmt.Sprintf("[DBG] %s", connTxt)
  1934  	infConnTxt := fmt.Sprintf("[INF] %s", connTxt)
  1935  
  1936  	errTxt := fmt.Sprintf("Error connecting to explicit gateway \"B\" (127.0.0.1:%d) at 127.0.0.1:%d", remoteGWPort, remoteGWPort)
  1937  	dbgErrTxt := fmt.Sprintf("[DBG] %s", errTxt)
  1938  	errErrTxt := fmt.Sprintf("[ERR] %s", errTxt)
  1939  
  1940  	for _, test := range []testConnect{
  1941  		{"gateway_attempt_1", 1, true},
  1942  		{"gateway_attempt_2", 2, false},
  1943  		{"gateway_attempt_3", 3, true},
  1944  		{"gateway_attempt_4", 4, false},
  1945  		{"gateway_attempt_6", 6, true},
  1946  		{"gateway_attempt_7", 7, false},
  1947  	} {
  1948  		t.Run(test.name, func(t *testing.T) {
  1949  			debugExpected := !test.errExpected
  1950  			infoExpected := test.errExpected
  1951  			// For gateways, we also check our notice that we attempt to connect
  1952  			checkContent(t, dbgConnTxt, test.attempt, debugExpected)
  1953  			checkContent(t, infConnTxt, test.attempt, infoExpected)
  1954  			checkContent(t, dbgErrTxt, test.attempt, debugExpected)
  1955  			checkContent(t, errErrTxt, test.attempt, test.errExpected)
  1956  		})
  1957  	}
  1958  }
  1959  
  1960  func TestServerLogsConfigurationFile(t *testing.T) {
  1961  	file := createTempFile(t, "nats_server_log_")
  1962  	file.Close()
  1963  
  1964  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  1965  	port: -1
  1966  	logfile: '%s'
  1967  	`, file.Name())))
  1968  
  1969  	o := LoadConfig(conf)
  1970  	o.ConfigFile = file.Name()
  1971  	o.NoLog = false
  1972  	s := RunServer(o)
  1973  	s.Shutdown()
  1974  
  1975  	log, err := os.ReadFile(file.Name())
  1976  	if err != nil {
  1977  		t.Fatalf("Error reading log file: %v", err)
  1978  	}
  1979  	if !bytes.Contains(log, []byte(fmt.Sprintf("Using configuration file: %s", file.Name()))) {
  1980  		t.Fatalf("Config file location was not reported in log: %s", log)
  1981  	}
  1982  }
  1983  
  1984  func TestServerRateLimitLogging(t *testing.T) {
  1985  	s := RunServer(DefaultOptions())
  1986  	defer s.Shutdown()
  1987  
  1988  	s.changeRateLimitLogInterval(100 * time.Millisecond)
  1989  
  1990  	l := &captureWarnLogger{warn: make(chan string, 100)}
  1991  	s.SetLogger(l, false, false)
  1992  
  1993  	s.RateLimitWarnf("Warning number 1")
  1994  	s.RateLimitWarnf("Warning number 2")
  1995  	s.RateLimitWarnf("Warning number 1")
  1996  	s.RateLimitWarnf("Warning number 2")
  1997  
  1998  	checkLog := func(c1, c2 *client) {
  1999  		t.Helper()
  2000  
  2001  		nb1 := "Warning number 1"
  2002  		nb2 := "Warning number 2"
  2003  		gotOne := 0
  2004  		gotTwo := 0
  2005  		for done := false; !done; {
  2006  			select {
  2007  			case w := <-l.warn:
  2008  				if strings.Contains(w, nb1) {
  2009  					gotOne++
  2010  				} else if strings.Contains(w, nb2) {
  2011  					gotTwo++
  2012  				}
  2013  			case <-time.After(150 * time.Millisecond):
  2014  				done = true
  2015  			}
  2016  		}
  2017  		if gotOne != 1 {
  2018  			t.Fatalf("Should have had only 1 warning for nb1, got %v", gotOne)
  2019  		}
  2020  		if gotTwo != 1 {
  2021  			t.Fatalf("Should have had only 1 warning for nb2, got %v", gotTwo)
  2022  		}
  2023  
  2024  		// Wait for more than the expiration interval
  2025  		time.Sleep(200 * time.Millisecond)
  2026  		if c1 == nil {
  2027  			s.RateLimitWarnf(nb1)
  2028  		} else {
  2029  			c1.RateLimitWarnf(nb1)
  2030  			c2.RateLimitWarnf(nb1)
  2031  		}
  2032  		gotOne = 0
  2033  		for {
  2034  			select {
  2035  			case w := <-l.warn:
  2036  				if strings.Contains(w, nb1) {
  2037  					gotOne++
  2038  				}
  2039  			case <-time.After(200 * time.Millisecond):
  2040  				if gotOne == 0 {
  2041  					t.Fatalf("Warning was still suppressed")
  2042  				} else if gotOne > 1 {
  2043  					t.Fatalf("Should have had only 1 warning for nb1, got %v", gotOne)
  2044  				} else {
  2045  					// OK! we are done
  2046  					return
  2047  				}
  2048  			}
  2049  		}
  2050  	}
  2051  
  2052  	checkLog(nil, nil)
  2053  
  2054  	nc1 := natsConnect(t, s.ClientURL(), nats.Name("c1"))
  2055  	defer nc1.Close()
  2056  	nc2 := natsConnect(t, s.ClientURL(), nats.Name("c2"))
  2057  	defer nc2.Close()
  2058  
  2059  	var c1 *client
  2060  	var c2 *client
  2061  	s.mu.Lock()
  2062  	for _, cli := range s.clients {
  2063  		cli.mu.Lock()
  2064  		switch cli.opts.Name {
  2065  		case "c1":
  2066  			c1 = cli
  2067  		case "c2":
  2068  			c2 = cli
  2069  		}
  2070  		cli.mu.Unlock()
  2071  		if c1 != nil && c2 != nil {
  2072  			break
  2073  		}
  2074  	}
  2075  	s.mu.Unlock()
  2076  	if c1 == nil || c2 == nil {
  2077  		t.Fatal("Did not find the clients")
  2078  	}
  2079  
  2080  	// Wait for more than the expiration interval
  2081  	time.Sleep(200 * time.Millisecond)
  2082  
  2083  	c1.RateLimitWarnf("Warning number 1")
  2084  	c1.RateLimitWarnf("Warning number 2")
  2085  	c2.RateLimitWarnf("Warning number 1")
  2086  	c2.RateLimitWarnf("Warning number 2")
  2087  
  2088  	checkLog(c1, c2)
  2089  }
  2090  
  2091  // https://github.com/nats-io/nats-server/discussions/4535
  2092  func TestServerAuthBlockAndSysAccounts(t *testing.T) {
  2093  	conf := createConfFile(t, []byte(`
  2094  		listen: 127.0.0.1:-1
  2095  		server_name: s-test
  2096  		authorization {
  2097  			users = [ { user: "u", password: "pass"} ]
  2098  		}
  2099  		accounts {
  2100  			$SYS: { users: [ { user: admin, password: pwd } ] }
  2101  		}
  2102  	`))
  2103  
  2104  	s, _ := RunServerWithConfig(conf)
  2105  	defer s.Shutdown()
  2106  
  2107  	// This should work of course.
  2108  	nc, err := nats.Connect(s.ClientURL(), nats.UserInfo("u", "pass"))
  2109  	require_NoError(t, err)
  2110  	defer nc.Close()
  2111  
  2112  	// This should not.
  2113  	_, err = nats.Connect(s.ClientURL())
  2114  	require_Error(t, err, nats.ErrAuthorization, errors.New("nats: Authorization Violation"))
  2115  }