get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/reload_test.go (about)

     1  // Copyright 2017-2022 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  	"bytes"
    18  	"crypto/tls"
    19  	"encoding/base64"
    20  	"encoding/json"
    21  	"flag"
    22  	"fmt"
    23  	"io"
    24  	"log"
    25  	"net"
    26  	"net/http"
    27  	"net/http/httptest"
    28  	"net/url"
    29  	"os"
    30  	"path/filepath"
    31  	"reflect"
    32  	"runtime"
    33  	"strings"
    34  	"sync"
    35  	"testing"
    36  	"time"
    37  
    38  	"github.com/nats-io/jwt/v2"
    39  	"github.com/nats-io/nats.go"
    40  	"github.com/nats-io/nkeys"
    41  )
    42  
    43  func newServerWithConfig(t *testing.T, configFile string) (*Server, *Options, string) {
    44  	t.Helper()
    45  	content, err := os.ReadFile(configFile)
    46  	if err != nil {
    47  		t.Fatalf("Error loading file: %v", err)
    48  	}
    49  	return newServerWithContent(t, content)
    50  }
    51  
    52  func newServerWithContent(t *testing.T, content []byte) (*Server, *Options, string) {
    53  	t.Helper()
    54  	opts, tmpFile := newOptionsFromContent(t, content)
    55  	return New(opts), opts, tmpFile
    56  }
    57  
    58  func newOptionsFromContent(t *testing.T, content []byte) (*Options, string) {
    59  	t.Helper()
    60  	tmpFile := createConfFile(t, content)
    61  	opts, err := ProcessConfigFile(tmpFile)
    62  	if err != nil {
    63  		t.Fatalf("Error processing config file: %v", err)
    64  	}
    65  	opts.NoSigs = true
    66  	return opts, tmpFile
    67  }
    68  
    69  func createConfFile(t testing.TB, content []byte) string {
    70  	t.Helper()
    71  	conf := createTempFile(t, _EMPTY_)
    72  	fName := conf.Name()
    73  	conf.Close()
    74  	if err := os.WriteFile(fName, content, 0666); err != nil {
    75  		t.Fatalf("Error writing conf file: %v", err)
    76  	}
    77  	return fName
    78  }
    79  
    80  func runReloadServerWithConfig(t *testing.T, configFile string) (*Server, *Options, string) {
    81  	t.Helper()
    82  	content, err := os.ReadFile(configFile)
    83  	if err != nil {
    84  		t.Fatalf("Error loading file: %v", err)
    85  	}
    86  	return runReloadServerWithContent(t, content)
    87  }
    88  
    89  func runReloadServerWithContent(t *testing.T, content []byte) (*Server, *Options, string) {
    90  	t.Helper()
    91  	opts, tmpFile := newOptionsFromContent(t, content)
    92  	opts.NoLog = true
    93  	opts.NoSigs = true
    94  	s := RunServer(opts)
    95  	return s, opts, tmpFile
    96  }
    97  
    98  func changeCurrentConfigContent(t *testing.T, curConfig, newConfig string) {
    99  	t.Helper()
   100  	content, err := os.ReadFile(newConfig)
   101  	if err != nil {
   102  		t.Fatalf("Error loading file: %v", err)
   103  	}
   104  	changeCurrentConfigContentWithNewContent(t, curConfig, content)
   105  }
   106  
   107  func changeCurrentConfigContentWithNewContent(t *testing.T, curConfig string, content []byte) {
   108  	t.Helper()
   109  	if err := os.WriteFile(curConfig, content, 0666); err != nil {
   110  		t.Fatalf("Error writing config: %v", err)
   111  	}
   112  }
   113  
   114  // Ensure Reload returns an error when attempting to reload a server that did
   115  // not start with a config file.
   116  func TestConfigReloadNoConfigFile(t *testing.T) {
   117  	server := New(&Options{NoSigs: true})
   118  	loaded := server.ConfigTime()
   119  	if server.Reload() == nil {
   120  		t.Fatal("Expected Reload to return an error")
   121  	}
   122  	if reloaded := server.ConfigTime(); reloaded != loaded {
   123  		t.Fatalf("ConfigTime is incorrect.\nexpected: %s\ngot: %s", loaded, reloaded)
   124  	}
   125  }
   126  
   127  // Ensure Reload returns an error when attempting to change an option which
   128  // does not support reloading.
   129  func TestConfigReloadUnsupported(t *testing.T) {
   130  	server, _, config := newServerWithConfig(t, "./configs/reload/test.conf")
   131  	defer server.Shutdown()
   132  
   133  	loaded := server.ConfigTime()
   134  
   135  	golden := &Options{
   136  		ConfigFile:     config,
   137  		Host:           "0.0.0.0",
   138  		Port:           2233,
   139  		AuthTimeout:    float64(AUTH_TIMEOUT / time.Second),
   140  		Debug:          false,
   141  		Trace:          false,
   142  		Logtime:        false,
   143  		MaxControlLine: 4096,
   144  		MaxPayload:     1048576,
   145  		MaxConn:        65536,
   146  		PingInterval:   2 * time.Minute,
   147  		MaxPingsOut:    2,
   148  		WriteDeadline:  10 * time.Second,
   149  		Cluster: ClusterOpts{
   150  			Name: "abc",
   151  			Host: "127.0.0.1",
   152  			Port: -1,
   153  		},
   154  		NoSigs: true,
   155  	}
   156  	setBaselineOptions(golden)
   157  
   158  	checkOptionsEqual(t, golden, server.getOpts())
   159  
   160  	// Change config file to bad config.
   161  	changeCurrentConfigContent(t, config, "./configs/reload/reload_unsupported.conf")
   162  
   163  	// This should fail because `cluster` host cannot be changed.
   164  	if err := server.Reload(); err == nil {
   165  		t.Fatal("Expected Reload to return an error")
   166  	}
   167  
   168  	// Ensure config didn't change.
   169  	checkOptionsEqual(t, golden, server.getOpts())
   170  
   171  	if reloaded := server.ConfigTime(); reloaded != loaded {
   172  		t.Fatalf("ConfigTime is incorrect.\nexpected: %s\ngot: %s", loaded, reloaded)
   173  	}
   174  }
   175  
   176  // This checks that if we change an option that does not support hot-swapping
   177  // we get an error. Using `listen` for now (test may need to be updated if
   178  // server is changed to support change of listen spec).
   179  func TestConfigReloadUnsupportedHotSwapping(t *testing.T) {
   180  	server, _, config := newServerWithContent(t, []byte("listen: 127.0.0.1:-1"))
   181  	defer server.Shutdown()
   182  
   183  	loaded := server.ConfigTime()
   184  
   185  	time.Sleep(time.Millisecond)
   186  
   187  	// Change config file with unsupported option hot-swap
   188  	changeCurrentConfigContentWithNewContent(t, config, []byte("listen: 127.0.0.1:9999"))
   189  
   190  	// This should fail because `listen` host cannot be changed.
   191  	if err := server.Reload(); err == nil || !strings.Contains(err.Error(), "not supported") {
   192  		t.Fatalf("Expected Reload to return a not supported error, got %v", err)
   193  	}
   194  
   195  	if reloaded := server.ConfigTime(); reloaded != loaded {
   196  		t.Fatalf("ConfigTime is incorrect.\nexpected: %s\ngot: %s", loaded, reloaded)
   197  	}
   198  }
   199  
   200  // Ensure Reload returns an error when reloading from a bad config file.
   201  func TestConfigReloadInvalidConfig(t *testing.T) {
   202  	server, _, config := newServerWithConfig(t, "./configs/reload/test.conf")
   203  	defer server.Shutdown()
   204  
   205  	loaded := server.ConfigTime()
   206  
   207  	golden := &Options{
   208  		ConfigFile:     config,
   209  		Host:           "0.0.0.0",
   210  		Port:           2233,
   211  		AuthTimeout:    float64(AUTH_TIMEOUT / time.Second),
   212  		Debug:          false,
   213  		Trace:          false,
   214  		Logtime:        false,
   215  		MaxControlLine: 4096,
   216  		MaxPayload:     1048576,
   217  		MaxConn:        65536,
   218  		PingInterval:   2 * time.Minute,
   219  		MaxPingsOut:    2,
   220  		WriteDeadline:  10 * time.Second,
   221  		Cluster: ClusterOpts{
   222  			Name: "abc",
   223  			Host: "127.0.0.1",
   224  			Port: -1,
   225  		},
   226  		NoSigs: true,
   227  	}
   228  	setBaselineOptions(golden)
   229  
   230  	checkOptionsEqual(t, golden, server.getOpts())
   231  
   232  	// Change config file to bad config.
   233  	changeCurrentConfigContent(t, config, "./configs/reload/invalid.conf")
   234  
   235  	// This should fail because the new config should not parse.
   236  	if err := server.Reload(); err == nil {
   237  		t.Fatal("Expected Reload to return an error")
   238  	}
   239  
   240  	// Ensure config didn't change.
   241  	checkOptionsEqual(t, golden, server.getOpts())
   242  
   243  	if reloaded := server.ConfigTime(); reloaded != loaded {
   244  		t.Fatalf("ConfigTime is incorrect.\nexpected: %s\ngot: %s", loaded, reloaded)
   245  	}
   246  }
   247  
   248  // Ensure Reload returns nil and the config is changed on success.
   249  func TestConfigReload(t *testing.T) {
   250  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/test.conf")
   251  	defer removeFile(t, "nats-server.pid")
   252  	defer removeFile(t, "nats-server.log")
   253  	defer server.Shutdown()
   254  
   255  	var content []byte
   256  	if runtime.GOOS != "windows" {
   257  		content = []byte(`
   258  			remote_syslog: "udp://127.0.0.1:514" # change on reload
   259  			syslog:        true # enable on reload
   260  		`)
   261  	}
   262  	platformConf := filepath.Join(filepath.Dir(config), "platform.conf")
   263  	if err := os.WriteFile(platformConf, content, 0666); err != nil {
   264  		t.Fatalf("Unable to write config file: %v", err)
   265  	}
   266  
   267  	loaded := server.ConfigTime()
   268  
   269  	golden := &Options{
   270  		ConfigFile:     config,
   271  		Host:           "0.0.0.0",
   272  		Port:           2233,
   273  		AuthTimeout:    float64(AUTH_TIMEOUT / time.Second),
   274  		Debug:          false,
   275  		Trace:          false,
   276  		NoLog:          true,
   277  		Logtime:        false,
   278  		MaxControlLine: 4096,
   279  		MaxPayload:     1048576,
   280  		MaxConn:        65536,
   281  		PingInterval:   2 * time.Minute,
   282  		MaxPingsOut:    2,
   283  		WriteDeadline:  10 * time.Second,
   284  		Cluster: ClusterOpts{
   285  			Name: "abc",
   286  			Host: "127.0.0.1",
   287  			Port: server.ClusterAddr().Port,
   288  		},
   289  		NoSigs: true,
   290  	}
   291  	setBaselineOptions(golden)
   292  
   293  	checkOptionsEqual(t, golden, opts)
   294  
   295  	// Change config file to new config.
   296  	changeCurrentConfigContent(t, config, "./configs/reload/reload.conf")
   297  
   298  	if err := server.Reload(); err != nil {
   299  		t.Fatalf("Error reloading config: %v", err)
   300  	}
   301  
   302  	// Ensure config changed.
   303  	updated := server.getOpts()
   304  	if !updated.Trace {
   305  		t.Fatal("Expected Trace to be true")
   306  	}
   307  	if !updated.Debug {
   308  		t.Fatal("Expected Debug to be true")
   309  	}
   310  	if !updated.Logtime {
   311  		t.Fatal("Expected Logtime to be true")
   312  	}
   313  	if !updated.LogtimeUTC {
   314  		t.Fatal("Expected LogtimeUTC to be true")
   315  	}
   316  	if runtime.GOOS != "windows" {
   317  		if !updated.Syslog {
   318  			t.Fatal("Expected Syslog to be true")
   319  		}
   320  		if updated.RemoteSyslog != "udp://127.0.0.1:514" {
   321  			t.Fatalf("RemoteSyslog is incorrect.\nexpected: udp://127.0.0.1:514\ngot: %s", updated.RemoteSyslog)
   322  		}
   323  	}
   324  	if updated.LogFile != "nats-server.log" {
   325  		t.Fatalf("LogFile is incorrect.\nexpected: nats-server.log\ngot: %s", updated.LogFile)
   326  	}
   327  	if updated.TLSConfig == nil {
   328  		t.Fatal("Expected TLSConfig to be non-nil")
   329  	}
   330  	if !server.info.TLSRequired {
   331  		t.Fatal("Expected TLSRequired to be true")
   332  	}
   333  	if !server.info.TLSVerify {
   334  		t.Fatal("Expected TLSVerify to be true")
   335  	}
   336  	if updated.Username != "tyler" {
   337  		t.Fatalf("Username is incorrect.\nexpected: tyler\ngot: %s", updated.Username)
   338  	}
   339  	if updated.Password != "T0pS3cr3t" {
   340  		t.Fatalf("Password is incorrect.\nexpected: T0pS3cr3t\ngot: %s", updated.Password)
   341  	}
   342  	if updated.AuthTimeout != 2 {
   343  		t.Fatalf("AuthTimeout is incorrect.\nexpected: 2\ngot: %f", updated.AuthTimeout)
   344  	}
   345  	if !server.info.AuthRequired {
   346  		t.Fatal("Expected AuthRequired to be true")
   347  	}
   348  	if !updated.Cluster.NoAdvertise {
   349  		t.Fatal("Expected NoAdvertise to be true")
   350  	}
   351  	if updated.Cluster.PingInterval != 20*time.Second {
   352  		t.Fatalf("Cluster PingInterval is incorrect.\nexpected: 20s\ngot: %v", updated.Cluster.PingInterval)
   353  	}
   354  	if updated.Cluster.MaxPingsOut != 8 {
   355  		t.Fatalf("Cluster MaxPingsOut is incorrect.\nexpected: 6\ngot: %v", updated.Cluster.MaxPingsOut)
   356  	}
   357  	if updated.PidFile != "nats-server.pid" {
   358  		t.Fatalf("PidFile is incorrect.\nexpected: nats-server.pid\ngot: %s", updated.PidFile)
   359  	}
   360  	if updated.MaxControlLine != 512 {
   361  		t.Fatalf("MaxControlLine is incorrect.\nexpected: 512\ngot: %d", updated.MaxControlLine)
   362  	}
   363  	if updated.PingInterval != 5*time.Second {
   364  		t.Fatalf("PingInterval is incorrect.\nexpected 5s\ngot: %s", updated.PingInterval)
   365  	}
   366  	if updated.MaxPingsOut != 1 {
   367  		t.Fatalf("MaxPingsOut is incorrect.\nexpected 1\ngot: %d", updated.MaxPingsOut)
   368  	}
   369  	if updated.WriteDeadline != 3*time.Second {
   370  		t.Fatalf("WriteDeadline is incorrect.\nexpected 3s\ngot: %s", updated.WriteDeadline)
   371  	}
   372  	if updated.MaxPayload != 1024 {
   373  		t.Fatalf("MaxPayload is incorrect.\nexpected 1024\ngot: %d", updated.MaxPayload)
   374  	}
   375  
   376  	if reloaded := server.ConfigTime(); !reloaded.After(loaded) {
   377  		t.Fatalf("ConfigTime is incorrect.\nexpected greater than: %s\ngot: %s", loaded, reloaded)
   378  	}
   379  }
   380  
   381  // Ensure Reload supports TLS config changes. Test this by starting a server
   382  // with TLS enabled, connect to it to verify, reload config using a different
   383  // key pair and client verification enabled, ensure reconnect fails, then
   384  // ensure reconnect succeeds when the client provides a cert.
   385  func TestConfigReloadRotateTLS(t *testing.T) {
   386  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/tls_test.conf")
   387  	defer server.Shutdown()
   388  
   389  	// Ensure we can connect as a sanity check.
   390  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
   391  
   392  	nc, err := nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true}))
   393  	if err != nil {
   394  		t.Fatalf("Error creating client: %v", err)
   395  	}
   396  	defer nc.Close()
   397  	sub, err := nc.SubscribeSync("foo")
   398  	if err != nil {
   399  		t.Fatalf("Error subscribing: %v", err)
   400  	}
   401  	defer sub.Unsubscribe()
   402  
   403  	// Rotate cert and enable client verification.
   404  	changeCurrentConfigContent(t, config, "./configs/reload/tls_verify_test.conf")
   405  	if err := server.Reload(); err != nil {
   406  		t.Fatalf("Error reloading config: %v", err)
   407  	}
   408  
   409  	// Ensure connecting fails.
   410  	if _, err := nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true})); err == nil {
   411  		t.Fatal("Expected connect to fail")
   412  	}
   413  
   414  	// Ensure connecting succeeds when client presents cert.
   415  	cert := nats.ClientCert("./configs/certs/cert.new.pem", "./configs/certs/key.new.pem")
   416  	conn, err := nats.Connect(addr, cert, nats.RootCAs("./configs/certs/cert.new.pem"))
   417  	if err != nil {
   418  		t.Fatalf("Error creating client: %v", err)
   419  	}
   420  	conn.Close()
   421  
   422  	// Ensure the original connection can still publish/receive.
   423  	if err := nc.Publish("foo", []byte("hello")); err != nil {
   424  		t.Fatalf("Error publishing: %v", err)
   425  	}
   426  	nc.Flush()
   427  	msg, err := sub.NextMsg(2 * time.Second)
   428  	if err != nil {
   429  		t.Fatalf("Error receiving msg: %v", err)
   430  	}
   431  	if string(msg.Data) != "hello" {
   432  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
   433  	}
   434  }
   435  
   436  // Ensure Reload supports enabling TLS. Test this by starting a server without
   437  // TLS enabled, connect to it to verify, reload config with TLS enabled, ensure
   438  // reconnect fails, then ensure reconnect succeeds when using secure.
   439  func TestConfigReloadEnableTLS(t *testing.T) {
   440  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
   441  	defer server.Shutdown()
   442  
   443  	// Ensure we can connect as a sanity check.
   444  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
   445  	nc, err := nats.Connect(addr)
   446  	if err != nil {
   447  		t.Fatalf("Error creating client: %v", err)
   448  	}
   449  	nc.Close()
   450  
   451  	// Enable TLS.
   452  	changeCurrentConfigContent(t, config, "./configs/reload/tls_test.conf")
   453  	if err := server.Reload(); err != nil {
   454  		t.Fatalf("Error reloading config: %v", err)
   455  	}
   456  
   457  	// Ensure connecting is OK (we need to skip server cert verification since
   458  	// the library is not doing that by default now).
   459  	nc, err = nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true}))
   460  	if err != nil {
   461  		t.Fatalf("Error creating client: %v", err)
   462  	}
   463  	nc.Close()
   464  }
   465  
   466  // Ensure Reload supports disabling TLS. Test this by starting a server with
   467  // TLS enabled, connect to it to verify, reload config with TLS disabled,
   468  // ensure reconnect fails, then ensure reconnect succeeds when connecting
   469  // without secure.
   470  func TestConfigReloadDisableTLS(t *testing.T) {
   471  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/tls_test.conf")
   472  	defer server.Shutdown()
   473  
   474  	// Ensure we can connect as a sanity check.
   475  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
   476  	nc, err := nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true}))
   477  	if err != nil {
   478  		t.Fatalf("Error creating client: %v", err)
   479  	}
   480  	nc.Close()
   481  
   482  	// Disable TLS.
   483  	changeCurrentConfigContent(t, config, "./configs/reload/basic.conf")
   484  	if err := server.Reload(); err != nil {
   485  		t.Fatalf("Error reloading config: %v", err)
   486  	}
   487  
   488  	// Ensure connecting fails.
   489  	if _, err := nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true})); err == nil {
   490  		t.Fatal("Expected connect to fail")
   491  	}
   492  
   493  	// Ensure connecting succeeds when not using secure.
   494  	nc, err = nats.Connect(addr)
   495  	if err != nil {
   496  		t.Fatalf("Error creating client: %v", err)
   497  	}
   498  	nc.Close()
   499  }
   500  
   501  func TestConfigReloadRotateTLSMultiCert(t *testing.T) {
   502  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/tls_multi_cert_1.conf")
   503  	defer server.Shutdown()
   504  
   505  	// Ensure we can connect as a sanity check.
   506  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
   507  
   508  	rawCerts := make(chan []byte, 3)
   509  	nc, err := nats.Connect(addr, nats.Secure(&tls.Config{
   510  		VerifyConnection: func(s tls.ConnectionState) error {
   511  			rawCerts <- s.PeerCertificates[0].Raw
   512  			return nil
   513  		},
   514  		InsecureSkipVerify: true,
   515  	}))
   516  	if err != nil {
   517  		t.Fatalf("Error creating client: %v", err)
   518  	}
   519  	defer nc.Close()
   520  	sub, err := nc.SubscribeSync("foo")
   521  	if err != nil {
   522  		t.Fatalf("Error subscribing: %v", err)
   523  	}
   524  	defer sub.Unsubscribe()
   525  
   526  	// Rotate cert and enable client verification.
   527  	changeCurrentConfigContent(t, config, "./configs/reload/tls_multi_cert_2.conf")
   528  	if err := server.Reload(); err != nil {
   529  		t.Fatalf("Error reloading config: %v", err)
   530  	}
   531  
   532  	// Ensure connecting fails.
   533  	if _, err := nats.Connect(addr, nats.Secure(&tls.Config{InsecureSkipVerify: true})); err == nil {
   534  		t.Fatal("Expected connect to fail")
   535  	}
   536  
   537  	// Ensure connecting succeeds when client presents cert.
   538  	cert := nats.ClientCert("../test/configs/certs/client-cert.pem", "../test/configs/certs/client-key.pem")
   539  	conn, err := nats.Connect(addr, cert, nats.RootCAs("../test/configs/certs/ca.pem"), nats.Secure(&tls.Config{
   540  		VerifyConnection: func(s tls.ConnectionState) error {
   541  			rawCerts <- s.PeerCertificates[0].Raw
   542  			return nil
   543  		},
   544  	}))
   545  	if err != nil {
   546  		t.Fatalf("Error creating client: %v", err)
   547  	}
   548  	conn.Close()
   549  
   550  	// Ensure the original connection can still publish/receive.
   551  	if err := nc.Publish("foo", []byte("hello")); err != nil {
   552  		t.Fatalf("Error publishing: %v", err)
   553  	}
   554  	nc.Flush()
   555  	msg, err := sub.NextMsg(2 * time.Second)
   556  	if err != nil {
   557  		t.Fatalf("Error receiving msg: %v", err)
   558  	}
   559  	if string(msg.Data) != "hello" {
   560  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
   561  	}
   562  
   563  	// Rotate cert and disable client verification.
   564  	changeCurrentConfigContent(t, config, "./configs/reload/tls_multi_cert_3.conf")
   565  	if err := server.Reload(); err != nil {
   566  		t.Fatalf("Error reloading config: %v", err)
   567  	}
   568  
   569  	nc, err = nats.Connect(addr, nats.Secure(&tls.Config{
   570  		VerifyConnection: func(s tls.ConnectionState) error {
   571  			rawCerts <- s.PeerCertificates[0].Raw
   572  			return nil
   573  		},
   574  		InsecureSkipVerify: true,
   575  	}))
   576  	if err != nil {
   577  		t.Fatalf("Error creating client: %v", err)
   578  	}
   579  	defer nc.Close()
   580  	sub, err = nc.SubscribeSync("foo")
   581  	if err != nil {
   582  		t.Fatalf("Error subscribing: %v", err)
   583  	}
   584  	defer sub.Unsubscribe()
   585  
   586  	certA := <-rawCerts
   587  	certB := <-rawCerts
   588  	certC := <-rawCerts
   589  	if !bytes.Equal(certA, certB) {
   590  		t.Error("Expected the same cert")
   591  	}
   592  	if bytes.Equal(certB, certC) {
   593  		t.Error("Expected a different cert")
   594  	}
   595  }
   596  
   597  // Ensure Reload supports single user authentication config changes. Test this
   598  // by starting a server with authentication enabled, connect to it to verify,
   599  // reload config using a different username/password, ensure reconnect fails,
   600  // then ensure reconnect succeeds when using the correct credentials.
   601  func TestConfigReloadRotateUserAuthentication(t *testing.T) {
   602  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/single_user_authentication_1.conf")
   603  	defer server.Shutdown()
   604  
   605  	// Ensure we can connect as a sanity check.
   606  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   607  	nc, err := nats.Connect(addr, nats.UserInfo("tyler", "T0pS3cr3t"))
   608  	if err != nil {
   609  		t.Fatalf("Error creating client: %v", err)
   610  	}
   611  	defer nc.Close()
   612  	disconnected := make(chan struct{}, 1)
   613  	asyncErr := make(chan error, 1)
   614  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   615  		asyncErr <- err
   616  	})
   617  	nc.SetDisconnectHandler(func(*nats.Conn) {
   618  		disconnected <- struct{}{}
   619  	})
   620  
   621  	// Change user credentials.
   622  	changeCurrentConfigContent(t, config, "./configs/reload/single_user_authentication_2.conf")
   623  	if err := server.Reload(); err != nil {
   624  		t.Fatalf("Error reloading config: %v", err)
   625  	}
   626  
   627  	// Ensure connecting fails.
   628  	if _, err := nats.Connect(addr, nats.UserInfo("tyler", "T0pS3cr3t")); err == nil {
   629  		t.Fatal("Expected connect to fail")
   630  	}
   631  
   632  	// Ensure connecting succeeds when using new credentials.
   633  	conn, err := nats.Connect(addr, nats.UserInfo("derek", "passw0rd"))
   634  	if err != nil {
   635  		t.Fatalf("Error creating client: %v", err)
   636  	}
   637  	conn.Close()
   638  
   639  	// Ensure the previous connection received an authorization error.
   640  	// Note that it is possible that client gets EOF and not able to
   641  	// process async error, so don't fail if we don't get it.
   642  	select {
   643  	case err := <-asyncErr:
   644  		if err != nats.ErrAuthorization {
   645  			t.Fatalf("Expected ErrAuthorization, got %v", err)
   646  		}
   647  	case <-time.After(time.Second):
   648  		// Give it up to 1 sec.
   649  	}
   650  
   651  	// Ensure the previous connection was disconnected.
   652  	select {
   653  	case <-disconnected:
   654  	case <-time.After(2 * time.Second):
   655  		t.Fatal("Expected connection to be disconnected")
   656  	}
   657  }
   658  
   659  // Ensure Reload supports enabling single user authentication. Test this by
   660  // starting a server with authentication disabled, connect to it to verify,
   661  // reload config using with a username/password, ensure reconnect fails, then
   662  // ensure reconnect succeeds when using the correct credentials.
   663  func TestConfigReloadEnableUserAuthentication(t *testing.T) {
   664  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
   665  	defer server.Shutdown()
   666  
   667  	// Ensure we can connect as a sanity check.
   668  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   669  	nc, err := nats.Connect(addr)
   670  	if err != nil {
   671  		t.Fatalf("Error creating client: %v", err)
   672  	}
   673  	defer nc.Close()
   674  	disconnected := make(chan struct{}, 1)
   675  	asyncErr := make(chan error, 1)
   676  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   677  		asyncErr <- err
   678  	})
   679  	nc.SetDisconnectHandler(func(*nats.Conn) {
   680  		disconnected <- struct{}{}
   681  	})
   682  
   683  	// Enable authentication.
   684  	changeCurrentConfigContent(t, config, "./configs/reload/single_user_authentication_1.conf")
   685  	if err := server.Reload(); err != nil {
   686  		t.Fatalf("Error reloading config: %v", err)
   687  	}
   688  
   689  	// Ensure connecting fails.
   690  	if _, err := nats.Connect(addr); err == nil {
   691  		t.Fatal("Expected connect to fail")
   692  	}
   693  
   694  	// Ensure connecting succeeds when using new credentials.
   695  	conn, err := nats.Connect(addr, nats.UserInfo("tyler", "T0pS3cr3t"))
   696  	if err != nil {
   697  		t.Fatalf("Error creating client: %v", err)
   698  	}
   699  	conn.Close()
   700  
   701  	// Ensure the previous connection received an authorization error.
   702  	// Note that it is possible that client gets EOF and not able to
   703  	// process async error, so don't fail if we don't get it.
   704  	select {
   705  	case err := <-asyncErr:
   706  		if err != nats.ErrAuthorization {
   707  			t.Fatalf("Expected ErrAuthorization, got %v", err)
   708  		}
   709  	case <-time.After(time.Second):
   710  	}
   711  
   712  	// Ensure the previous connection was disconnected.
   713  	select {
   714  	case <-disconnected:
   715  	case <-time.After(2 * time.Second):
   716  		t.Fatal("Expected connection to be disconnected")
   717  	}
   718  }
   719  
   720  // Ensure Reload supports disabling single user authentication. Test this by
   721  // starting a server with authentication enabled, connect to it to verify,
   722  // reload config using with authentication disabled, then ensure connecting
   723  // with no credentials succeeds.
   724  func TestConfigReloadDisableUserAuthentication(t *testing.T) {
   725  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/single_user_authentication_1.conf")
   726  	defer server.Shutdown()
   727  
   728  	// Ensure we can connect as a sanity check.
   729  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   730  	nc, err := nats.Connect(addr, nats.UserInfo("tyler", "T0pS3cr3t"))
   731  	if err != nil {
   732  		t.Fatalf("Error creating client: %v", err)
   733  	}
   734  	defer nc.Close()
   735  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   736  		t.Fatalf("Client received an unexpected error: %v", err)
   737  	})
   738  
   739  	// Disable authentication.
   740  	changeCurrentConfigContent(t, config, "./configs/reload/basic.conf")
   741  	if err := server.Reload(); err != nil {
   742  		t.Fatalf("Error reloading config: %v", err)
   743  	}
   744  
   745  	// Ensure connecting succeeds with no credentials.
   746  	conn, err := nats.Connect(addr)
   747  	if err != nil {
   748  		t.Fatalf("Error creating client: %v", err)
   749  	}
   750  	conn.Close()
   751  }
   752  
   753  // Ensure Reload supports token authentication config changes. Test this by
   754  // starting a server with token authentication enabled, connect to it to
   755  // verify, reload config using a different token, ensure reconnect fails, then
   756  // ensure reconnect succeeds when using the correct token.
   757  func TestConfigReloadRotateTokenAuthentication(t *testing.T) {
   758  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/token_authentication_1.conf")
   759  	defer server.Shutdown()
   760  
   761  	disconnected := make(chan struct{})
   762  	asyncErr := make(chan error)
   763  	eh := func(nc *nats.Conn, sub *nats.Subscription, err error) { asyncErr <- err }
   764  	dh := func(*nats.Conn) { disconnected <- struct{}{} }
   765  
   766  	// Ensure we can connect as a sanity check.
   767  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   768  	nc, err := nats.Connect(addr, nats.Token("T0pS3cr3t"), nats.ErrorHandler(eh), nats.DisconnectHandler(dh))
   769  	if err != nil {
   770  		t.Fatalf("Error creating client: %v", err)
   771  	}
   772  	defer nc.Close()
   773  
   774  	// Change authentication token.
   775  	changeCurrentConfigContent(t, config, "./configs/reload/token_authentication_2.conf")
   776  	if err := server.Reload(); err != nil {
   777  		t.Fatalf("Error reloading config: %v", err)
   778  	}
   779  
   780  	// Ensure connecting fails.
   781  	if _, err := nats.Connect(addr, nats.Token("T0pS3cr3t")); err == nil {
   782  		t.Fatal("Expected connect to fail")
   783  	}
   784  
   785  	// Ensure connecting succeeds when using new credentials.
   786  	conn, err := nats.Connect(addr, nats.Token("passw0rd"))
   787  	if err != nil {
   788  		t.Fatalf("Error creating client: %v", err)
   789  	}
   790  	conn.Close()
   791  
   792  	// Ensure the previous connection received an authorization error.
   793  	select {
   794  	case err := <-asyncErr:
   795  		if err != nats.ErrAuthorization {
   796  			t.Fatalf("Expected ErrAuthorization, got %v", err)
   797  		}
   798  	case <-time.After(2 * time.Second):
   799  		t.Fatal("Expected authorization error")
   800  	}
   801  
   802  	// Ensure the previous connection was disconnected.
   803  	select {
   804  	case <-disconnected:
   805  	case <-time.After(2 * time.Second):
   806  		t.Fatal("Expected connection to be disconnected")
   807  	}
   808  }
   809  
   810  // Ensure Reload supports enabling token authentication. Test this by starting
   811  // a server with authentication disabled, connect to it to verify, reload
   812  // config using with a token, ensure reconnect fails, then ensure reconnect
   813  // succeeds when using the correct token.
   814  func TestConfigReloadEnableTokenAuthentication(t *testing.T) {
   815  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
   816  	defer server.Shutdown()
   817  
   818  	// Ensure we can connect as a sanity check.
   819  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   820  	nc, err := nats.Connect(addr)
   821  	if err != nil {
   822  		t.Fatalf("Error creating client: %v", err)
   823  	}
   824  	defer nc.Close()
   825  	disconnected := make(chan struct{}, 1)
   826  	asyncErr := make(chan error, 1)
   827  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   828  		asyncErr <- err
   829  	})
   830  	nc.SetDisconnectHandler(func(*nats.Conn) {
   831  		disconnected <- struct{}{}
   832  	})
   833  
   834  	// Enable authentication.
   835  	changeCurrentConfigContent(t, config, "./configs/reload/token_authentication_1.conf")
   836  	if err := server.Reload(); err != nil {
   837  		t.Fatalf("Error reloading config: %v", err)
   838  	}
   839  
   840  	// Ensure connecting fails.
   841  	if _, err := nats.Connect(addr); err == nil {
   842  		t.Fatal("Expected connect to fail")
   843  	}
   844  
   845  	// Ensure connecting succeeds when using new credentials.
   846  	conn, err := nats.Connect(addr, nats.Token("T0pS3cr3t"))
   847  	if err != nil {
   848  		t.Fatalf("Error creating client: %v", err)
   849  	}
   850  	conn.Close()
   851  
   852  	// Ensure the previous connection received an authorization error.
   853  	// Note that it is possible that client gets EOF and not able to
   854  	// process async error, so don't fail if we don't get it.
   855  	select {
   856  	case err := <-asyncErr:
   857  		if err != nats.ErrAuthorization {
   858  			t.Fatalf("Expected ErrAuthorization, got %v", err)
   859  		}
   860  	case <-time.After(time.Second):
   861  	}
   862  
   863  	// Ensure the previous connection was disconnected.
   864  	select {
   865  	case <-disconnected:
   866  	case <-time.After(2 * time.Second):
   867  		t.Fatal("Expected connection to be disconnected")
   868  	}
   869  }
   870  
   871  // Ensure Reload supports disabling single token authentication. Test this by
   872  // starting a server with authentication enabled, connect to it to verify,
   873  // reload config using with authentication disabled, then ensure connecting
   874  // with no token succeeds.
   875  func TestConfigReloadDisableTokenAuthentication(t *testing.T) {
   876  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/token_authentication_1.conf")
   877  	defer server.Shutdown()
   878  
   879  	// Ensure we can connect as a sanity check.
   880  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   881  	nc, err := nats.Connect(addr, nats.Token("T0pS3cr3t"))
   882  	if err != nil {
   883  		t.Fatalf("Error creating client: %v", err)
   884  	}
   885  	defer nc.Close()
   886  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   887  		t.Fatalf("Client received an unexpected error: %v", err)
   888  	})
   889  
   890  	// Disable authentication.
   891  	changeCurrentConfigContent(t, config, "./configs/reload/basic.conf")
   892  	if err := server.Reload(); err != nil {
   893  		t.Fatalf("Error reloading config: %v", err)
   894  	}
   895  
   896  	// Ensure connecting succeeds with no credentials.
   897  	conn, err := nats.Connect(addr)
   898  	if err != nil {
   899  		t.Fatalf("Error creating client: %v", err)
   900  	}
   901  	conn.Close()
   902  }
   903  
   904  // Ensure Reload supports users authentication config changes. Test this by
   905  // starting a server with users authentication enabled, connect to it to
   906  // verify, reload config using a different user, ensure reconnect fails, then
   907  // ensure reconnect succeeds when using the correct credentials.
   908  func TestConfigReloadRotateUsersAuthentication(t *testing.T) {
   909  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/multiple_users_1.conf")
   910  	defer server.Shutdown()
   911  
   912  	// Ensure we can connect as a sanity check.
   913  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   914  	nc, err := nats.Connect(addr, nats.UserInfo("alice", "foo"))
   915  	if err != nil {
   916  		t.Fatalf("Error creating client: %v", err)
   917  	}
   918  	defer nc.Close()
   919  	disconnected := make(chan struct{}, 1)
   920  	asyncErr := make(chan error, 1)
   921  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
   922  		asyncErr <- err
   923  	})
   924  	nc.SetDisconnectHandler(func(*nats.Conn) {
   925  		disconnected <- struct{}{}
   926  	})
   927  
   928  	// These credentials won't change.
   929  	nc2, err := nats.Connect(addr, nats.UserInfo("bob", "bar"))
   930  	if err != nil {
   931  		t.Fatalf("Error creating client: %v", err)
   932  	}
   933  	defer nc2.Close()
   934  	sub, err := nc2.SubscribeSync("foo")
   935  	if err != nil {
   936  		t.Fatalf("Error subscribing: %v", err)
   937  	}
   938  	defer sub.Unsubscribe()
   939  
   940  	// Change users credentials.
   941  	changeCurrentConfigContent(t, config, "./configs/reload/multiple_users_2.conf")
   942  	if err := server.Reload(); err != nil {
   943  		t.Fatalf("Error reloading config: %v", err)
   944  	}
   945  
   946  	// Ensure connecting fails.
   947  	if _, err := nats.Connect(addr, nats.UserInfo("alice", "foo")); err == nil {
   948  		t.Fatal("Expected connect to fail")
   949  	}
   950  
   951  	// Ensure connecting succeeds when using new credentials.
   952  	conn, err := nats.Connect(addr, nats.UserInfo("alice", "baz"))
   953  	if err != nil {
   954  		t.Fatalf("Error creating client: %v", err)
   955  	}
   956  	conn.Close()
   957  
   958  	// Ensure the previous connection received an authorization error.
   959  	// Note that it is possible that client gets EOF and not able to
   960  	// process async error, so don't fail if we don't get it.
   961  	select {
   962  	case err := <-asyncErr:
   963  		if err != nats.ErrAuthorization {
   964  			t.Fatalf("Expected ErrAuthorization, got %v", err)
   965  		}
   966  	case <-time.After(time.Second):
   967  	}
   968  
   969  	// Ensure the previous connection was disconnected.
   970  	select {
   971  	case <-disconnected:
   972  	case <-time.After(2 * time.Second):
   973  		t.Fatal("Expected connection to be disconnected")
   974  	}
   975  
   976  	// Ensure the connection using unchanged credentials can still
   977  	// publish/receive.
   978  	if err := nc2.Publish("foo", []byte("hello")); err != nil {
   979  		t.Fatalf("Error publishing: %v", err)
   980  	}
   981  	nc2.Flush()
   982  	msg, err := sub.NextMsg(2 * time.Second)
   983  	if err != nil {
   984  		t.Fatalf("Error receiving msg: %v", err)
   985  	}
   986  	if string(msg.Data) != "hello" {
   987  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
   988  	}
   989  }
   990  
   991  // Ensure Reload supports enabling users authentication. Test this by starting
   992  // a server with authentication disabled, connect to it to verify, reload
   993  // config using with users, ensure reconnect fails, then ensure reconnect
   994  // succeeds when using the correct credentials.
   995  func TestConfigReloadEnableUsersAuthentication(t *testing.T) {
   996  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
   997  	defer server.Shutdown()
   998  
   999  	// Ensure we can connect as a sanity check.
  1000  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1001  	nc, err := nats.Connect(addr)
  1002  	if err != nil {
  1003  		t.Fatalf("Error creating client: %v", err)
  1004  	}
  1005  	defer nc.Close()
  1006  	disconnected := make(chan struct{}, 1)
  1007  	asyncErr := make(chan error, 1)
  1008  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
  1009  		asyncErr <- err
  1010  	})
  1011  	nc.SetDisconnectHandler(func(*nats.Conn) {
  1012  		disconnected <- struct{}{}
  1013  	})
  1014  
  1015  	// Enable authentication.
  1016  	changeCurrentConfigContent(t, config, "./configs/reload/multiple_users_1.conf")
  1017  	if err := server.Reload(); err != nil {
  1018  		t.Fatalf("Error reloading config: %v", err)
  1019  	}
  1020  
  1021  	// Ensure connecting fails.
  1022  	if _, err := nats.Connect(addr); err == nil {
  1023  		t.Fatal("Expected connect to fail")
  1024  	}
  1025  
  1026  	// Ensure connecting succeeds when using new credentials.
  1027  	conn, err := nats.Connect(addr, nats.UserInfo("alice", "foo"))
  1028  	if err != nil {
  1029  		t.Fatalf("Error creating client: %v", err)
  1030  	}
  1031  	conn.Close()
  1032  
  1033  	// Ensure the previous connection received an authorization error.
  1034  	// Note that it is possible that client gets EOF and not able to
  1035  	// process async error, so don't fail if we don't get it.
  1036  	select {
  1037  	case err := <-asyncErr:
  1038  		if err != nats.ErrAuthorization {
  1039  			t.Fatalf("Expected ErrAuthorization, got %v", err)
  1040  		}
  1041  	case <-time.After(time.Second):
  1042  	}
  1043  
  1044  	// Ensure the previous connection was disconnected.
  1045  	select {
  1046  	case <-disconnected:
  1047  	case <-time.After(5 * time.Second):
  1048  		t.Fatal("Expected connection to be disconnected")
  1049  	}
  1050  }
  1051  
  1052  // Ensure Reload supports disabling users authentication. Test this by starting
  1053  // a server with authentication enabled, connect to it to verify,
  1054  // reload config using with authentication disabled, then ensure connecting
  1055  // with no credentials succeeds.
  1056  func TestConfigReloadDisableUsersAuthentication(t *testing.T) {
  1057  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/multiple_users_1.conf")
  1058  	defer server.Shutdown()
  1059  
  1060  	// Ensure we can connect as a sanity check.
  1061  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1062  	nc, err := nats.Connect(addr, nats.UserInfo("alice", "foo"))
  1063  	if err != nil {
  1064  		t.Fatalf("Error creating client: %v", err)
  1065  	}
  1066  	defer nc.Close()
  1067  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
  1068  		t.Fatalf("Client received an unexpected error: %v", err)
  1069  	})
  1070  
  1071  	// Disable authentication.
  1072  	changeCurrentConfigContent(t, config, "./configs/reload/basic.conf")
  1073  	if err := server.Reload(); err != nil {
  1074  		t.Fatalf("Error reloading config: %v", err)
  1075  	}
  1076  
  1077  	// Ensure connecting succeeds with no credentials.
  1078  	conn, err := nats.Connect(addr)
  1079  	if err != nil {
  1080  		t.Fatalf("Error creating client: %v", err)
  1081  	}
  1082  	conn.Close()
  1083  }
  1084  
  1085  // Ensure Reload supports changing permissions. Test this by starting a server
  1086  // with a user configured with certain permissions, test publish and subscribe,
  1087  // reload config with new permissions, ensure the previous subscription was
  1088  // closed and publishes fail, then ensure the new permissions succeed.
  1089  func TestConfigReloadChangePermissions(t *testing.T) {
  1090  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/authorization_1.conf")
  1091  	defer server.Shutdown()
  1092  
  1093  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1094  	nc, err := nats.Connect(addr, nats.UserInfo("bob", "bar"))
  1095  	if err != nil {
  1096  		t.Fatalf("Error creating client: %v", err)
  1097  	}
  1098  	defer nc.Close()
  1099  	asyncErr := make(chan error, 1)
  1100  	nc.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
  1101  		asyncErr <- err
  1102  	})
  1103  	// Ensure we can publish and receive messages as a sanity check.
  1104  	sub, err := nc.SubscribeSync("_INBOX.>")
  1105  	if err != nil {
  1106  		t.Fatalf("Error subscribing: %v", err)
  1107  	}
  1108  	nc.Flush()
  1109  
  1110  	conn, err := nats.Connect(addr, nats.UserInfo("alice", "foo"))
  1111  	if err != nil {
  1112  		t.Fatalf("Error creating client: %v", err)
  1113  	}
  1114  	defer conn.Close()
  1115  
  1116  	sub2, err := conn.SubscribeSync("req.foo")
  1117  	if err != nil {
  1118  		t.Fatalf("Error subscribing: %v", err)
  1119  	}
  1120  	if err := conn.Publish("_INBOX.foo", []byte("hello")); err != nil {
  1121  		t.Fatalf("Error publishing message: %v", err)
  1122  	}
  1123  	conn.Flush()
  1124  
  1125  	msg, err := sub.NextMsg(2 * time.Second)
  1126  	if err != nil {
  1127  		t.Fatalf("Error receiving msg: %v", err)
  1128  	}
  1129  	if string(msg.Data) != "hello" {
  1130  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
  1131  	}
  1132  
  1133  	if err := nc.Publish("req.foo", []byte("world")); err != nil {
  1134  		t.Fatalf("Error publishing message: %v", err)
  1135  	}
  1136  	nc.Flush()
  1137  
  1138  	msg, err = sub2.NextMsg(2 * time.Second)
  1139  	if err != nil {
  1140  		t.Fatalf("Error receiving msg: %v", err)
  1141  	}
  1142  	if string(msg.Data) != "world" {
  1143  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("world"), msg.Data)
  1144  	}
  1145  
  1146  	// Susan will subscribe to two subjects, both will succeed but a send to foo.bar should not succeed
  1147  	// however PUBLIC.foo should.
  1148  	sconn, err := nats.Connect(addr, nats.UserInfo("susan", "baz"))
  1149  	if err != nil {
  1150  		t.Fatalf("Error creating client: %v", err)
  1151  	}
  1152  	defer sconn.Close()
  1153  
  1154  	asyncErr2 := make(chan error, 1)
  1155  	sconn.SetErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
  1156  		asyncErr2 <- err
  1157  	})
  1158  
  1159  	fooSub, err := sconn.SubscribeSync("foo.*")
  1160  	if err != nil {
  1161  		t.Fatalf("Error subscribing: %v", err)
  1162  	}
  1163  	sconn.Flush()
  1164  
  1165  	// Publishing from bob on foo.bar should not come through.
  1166  	if err := conn.Publish("foo.bar", []byte("hello")); err != nil {
  1167  		t.Fatalf("Error publishing message: %v", err)
  1168  	}
  1169  	conn.Flush()
  1170  
  1171  	_, err = fooSub.NextMsg(100 * time.Millisecond)
  1172  	if err != nats.ErrTimeout {
  1173  		t.Fatalf("Received a message we shouldn't have")
  1174  	}
  1175  
  1176  	pubSub, err := sconn.SubscribeSync("PUBLIC.*")
  1177  	if err != nil {
  1178  		t.Fatalf("Error subscribing: %v", err)
  1179  	}
  1180  	sconn.Flush()
  1181  
  1182  	select {
  1183  	case err := <-asyncErr2:
  1184  		t.Fatalf("Received unexpected error for susan: %v", err)
  1185  	default:
  1186  	}
  1187  
  1188  	// This should work ok with original config.
  1189  	if err := conn.Publish("PUBLIC.foo", []byte("hello monkey")); err != nil {
  1190  		t.Fatalf("Error publishing message: %v", err)
  1191  	}
  1192  	conn.Flush()
  1193  
  1194  	msg, err = pubSub.NextMsg(2 * time.Second)
  1195  	if err != nil {
  1196  		t.Fatalf("Error receiving msg: %v", err)
  1197  	}
  1198  	if string(msg.Data) != "hello monkey" {
  1199  		t.Fatalf("Msg is incorrect.\nexpected: %q\ngot: %q", "hello monkey", msg.Data)
  1200  	}
  1201  
  1202  	///////////////////////////////////////////
  1203  	// Change permissions.
  1204  	///////////////////////////////////////////
  1205  
  1206  	changeCurrentConfigContent(t, config, "./configs/reload/authorization_2.conf")
  1207  	if err := server.Reload(); err != nil {
  1208  		t.Fatalf("Error reloading config: %v", err)
  1209  	}
  1210  
  1211  	// Ensure we receive an error for the subscription that is no longer authorized.
  1212  	// In this test, since connection is not closed by the server,
  1213  	// the client must receive an -ERR
  1214  	select {
  1215  	case err := <-asyncErr:
  1216  		if !strings.Contains(strings.ToLower(err.Error()), "permissions violation for subscription to \"_inbox.>\"") {
  1217  			t.Fatalf("Expected permissions violation error, got %v", err)
  1218  		}
  1219  	case <-time.After(5 * time.Second):
  1220  		t.Fatal("Expected permissions violation error")
  1221  	}
  1222  
  1223  	// Ensure we receive an error when publishing to req.foo and we no longer
  1224  	// receive messages on _INBOX.>.
  1225  	if err := nc.Publish("req.foo", []byte("hola")); err != nil {
  1226  		t.Fatalf("Error publishing message: %v", err)
  1227  	}
  1228  	nc.Flush()
  1229  	if err := conn.Publish("_INBOX.foo", []byte("mundo")); err != nil {
  1230  		t.Fatalf("Error publishing message: %v", err)
  1231  	}
  1232  	conn.Flush()
  1233  
  1234  	select {
  1235  	case err := <-asyncErr:
  1236  		if !strings.Contains(strings.ToLower(err.Error()), "permissions violation for publish to \"req.foo\"") {
  1237  			t.Fatalf("Expected permissions violation error, got %v", err)
  1238  		}
  1239  	case <-time.After(5 * time.Second):
  1240  		t.Fatal("Expected permissions violation error")
  1241  	}
  1242  
  1243  	queued, _, err := sub2.Pending()
  1244  	if err != nil {
  1245  		t.Fatalf("Failed to get pending messaged: %v", err)
  1246  	}
  1247  	if queued != 0 {
  1248  		t.Fatalf("Pending is incorrect.\nexpected: 0\ngot: %d", queued)
  1249  	}
  1250  
  1251  	queued, _, err = sub.Pending()
  1252  	if err != nil {
  1253  		t.Fatalf("Failed to get pending messaged: %v", err)
  1254  	}
  1255  	if queued != 0 {
  1256  		t.Fatalf("Pending is incorrect.\nexpected: 0\ngot: %d", queued)
  1257  	}
  1258  
  1259  	// Ensure we can publish to _INBOX.foo.bar and subscribe to _INBOX.foo.>.
  1260  	sub, err = nc.SubscribeSync("_INBOX.foo.>")
  1261  	if err != nil {
  1262  		t.Fatalf("Error subscribing: %v", err)
  1263  	}
  1264  	nc.Flush()
  1265  	if err := nc.Publish("_INBOX.foo.bar", []byte("testing")); err != nil {
  1266  		t.Fatalf("Error publishing message: %v", err)
  1267  	}
  1268  	nc.Flush()
  1269  	msg, err = sub.NextMsg(2 * time.Second)
  1270  	if err != nil {
  1271  		t.Fatalf("Error receiving msg: %v", err)
  1272  	}
  1273  	if string(msg.Data) != "testing" {
  1274  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("testing"), msg.Data)
  1275  	}
  1276  
  1277  	select {
  1278  	case err := <-asyncErr:
  1279  		t.Fatalf("Received unexpected error: %v", err)
  1280  	default:
  1281  	}
  1282  
  1283  	// Now check susan again.
  1284  	//
  1285  	// This worked ok with original config but should not deliver a message now.
  1286  	if err := conn.Publish("PUBLIC.foo", []byte("hello monkey")); err != nil {
  1287  		t.Fatalf("Error publishing message: %v", err)
  1288  	}
  1289  	conn.Flush()
  1290  
  1291  	_, err = pubSub.NextMsg(100 * time.Millisecond)
  1292  	if err != nats.ErrTimeout {
  1293  		t.Fatalf("Received a message we shouldn't have")
  1294  	}
  1295  
  1296  	// Now check foo.bar, which did not work before but should work now..
  1297  	if err := conn.Publish("foo.bar", []byte("hello?")); err != nil {
  1298  		t.Fatalf("Error publishing message: %v", err)
  1299  	}
  1300  	conn.Flush()
  1301  
  1302  	msg, err = fooSub.NextMsg(2 * time.Second)
  1303  	if err != nil {
  1304  		t.Fatalf("Error receiving msg: %v", err)
  1305  	}
  1306  	if string(msg.Data) != "hello?" {
  1307  		t.Fatalf("Msg is incorrect.\nexpected: %q\ngot: %q", "hello?", msg.Data)
  1308  	}
  1309  
  1310  	// Once last check for no errors.
  1311  	sconn.Flush()
  1312  
  1313  	select {
  1314  	case err := <-asyncErr2:
  1315  		t.Fatalf("Received unexpected error for susan: %v", err)
  1316  	default:
  1317  	}
  1318  }
  1319  
  1320  // Ensure Reload returns an error when attempting to change cluster address
  1321  // host.
  1322  func TestConfigReloadClusterHostUnsupported(t *testing.T) {
  1323  	server, _, config := runReloadServerWithConfig(t, "./configs/reload/srv_a_1.conf")
  1324  	defer server.Shutdown()
  1325  
  1326  	// Attempt to change cluster listen host.
  1327  	changeCurrentConfigContent(t, config, "./configs/reload/srv_c_1.conf")
  1328  
  1329  	// This should fail because cluster address cannot be changed.
  1330  	if err := server.Reload(); err == nil {
  1331  		t.Fatal("Expected Reload to return an error")
  1332  	}
  1333  }
  1334  
  1335  // Ensure Reload returns an error when attempting to change cluster address
  1336  // port.
  1337  func TestConfigReloadClusterPortUnsupported(t *testing.T) {
  1338  	server, _, config := runReloadServerWithConfig(t, "./configs/reload/srv_a_1.conf")
  1339  	defer server.Shutdown()
  1340  
  1341  	// Attempt to change cluster listen port.
  1342  	changeCurrentConfigContent(t, config, "./configs/reload/srv_b_1.conf")
  1343  
  1344  	// This should fail because cluster address cannot be changed.
  1345  	if err := server.Reload(); err == nil {
  1346  		t.Fatal("Expected Reload to return an error")
  1347  	}
  1348  }
  1349  
  1350  // Ensure Reload supports enabling route authorization. Test this by starting
  1351  // two servers in a cluster without authorization, ensuring messages flow
  1352  // between them, then reloading with authorization and ensuring messages no
  1353  // longer flow until reloading with the correct credentials.
  1354  func TestConfigReloadEnableClusterAuthorization(t *testing.T) {
  1355  	srvb, srvbOpts, srvbConfig := runReloadServerWithConfig(t, "./configs/reload/srv_b_1.conf")
  1356  	defer srvb.Shutdown()
  1357  
  1358  	srva, srvaOpts, srvaConfig := runReloadServerWithConfig(t, "./configs/reload/srv_a_1.conf")
  1359  	defer srva.Shutdown()
  1360  
  1361  	checkClusterFormed(t, srva, srvb)
  1362  
  1363  	srvaAddr := fmt.Sprintf("nats://%s:%d", srvaOpts.Host, srvaOpts.Port)
  1364  	srvaConn, err := nats.Connect(srvaAddr)
  1365  	if err != nil {
  1366  		t.Fatalf("Error creating client: %v", err)
  1367  	}
  1368  	defer srvaConn.Close()
  1369  	sub, err := srvaConn.SubscribeSync("foo")
  1370  	if err != nil {
  1371  		t.Fatalf("Error subscribing: %v", err)
  1372  	}
  1373  	defer sub.Unsubscribe()
  1374  	if err := srvaConn.Flush(); err != nil {
  1375  		t.Fatalf("Error flushing: %v", err)
  1376  	}
  1377  
  1378  	srvbAddr := fmt.Sprintf("nats://%s:%d", srvbOpts.Host, srvbOpts.Port)
  1379  	srvbConn, err := nats.Connect(srvbAddr)
  1380  	if err != nil {
  1381  		t.Fatalf("Error creating client: %v", err)
  1382  	}
  1383  	defer srvbConn.Close()
  1384  
  1385  	if numRoutes := srvb.NumRoutes(); numRoutes != DEFAULT_ROUTE_POOL_SIZE {
  1386  		t.Fatalf("Expected %d route, got %d", DEFAULT_ROUTE_POOL_SIZE, numRoutes)
  1387  	}
  1388  
  1389  	// Ensure messages flow through the cluster as a sanity check.
  1390  	if err := srvbConn.Publish("foo", []byte("hello")); err != nil {
  1391  		t.Fatalf("Error publishing: %v", err)
  1392  	}
  1393  	srvbConn.Flush()
  1394  	msg, err := sub.NextMsg(2 * time.Second)
  1395  	if err != nil {
  1396  		t.Fatalf("Error receiving message: %v", err)
  1397  	}
  1398  	if string(msg.Data) != "hello" {
  1399  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
  1400  	}
  1401  
  1402  	// Enable route authorization.
  1403  	changeCurrentConfigContent(t, srvbConfig, "./configs/reload/srv_b_2.conf")
  1404  	if err := srvb.Reload(); err != nil {
  1405  		t.Fatalf("Error reloading config: %v", err)
  1406  	}
  1407  
  1408  	checkNumRoutes(t, srvb, 0)
  1409  
  1410  	// Ensure messages no longer flow through the cluster.
  1411  	for i := 0; i < 5; i++ {
  1412  		if err := srvbConn.Publish("foo", []byte("world")); err != nil {
  1413  			t.Fatalf("Error publishing: %v", err)
  1414  		}
  1415  		srvbConn.Flush()
  1416  	}
  1417  	if _, err := sub.NextMsg(50 * time.Millisecond); err != nats.ErrTimeout {
  1418  		t.Fatalf("Expected ErrTimeout, got %v", err)
  1419  	}
  1420  
  1421  	// Reload Server A with correct route credentials.
  1422  	changeCurrentConfigContent(t, srvaConfig, "./configs/reload/srv_a_2.conf")
  1423  	if err := srva.Reload(); err != nil {
  1424  		t.Fatalf("Error reloading config: %v", err)
  1425  	}
  1426  	checkClusterFormed(t, srva, srvb)
  1427  
  1428  	if numRoutes := srvb.NumRoutes(); numRoutes != DEFAULT_ROUTE_POOL_SIZE {
  1429  		t.Fatalf("Expected %d route, got %d", DEFAULT_ROUTE_POOL_SIZE, numRoutes)
  1430  	}
  1431  
  1432  	// Ensure messages flow through the cluster now.
  1433  	if err := srvbConn.Publish("foo", []byte("hola")); err != nil {
  1434  		t.Fatalf("Error publishing: %v", err)
  1435  	}
  1436  	srvbConn.Flush()
  1437  	msg, err = sub.NextMsg(2 * time.Second)
  1438  	if err != nil {
  1439  		t.Fatalf("Error receiving message: %v", err)
  1440  	}
  1441  	if string(msg.Data) != "hola" {
  1442  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hola"), msg.Data)
  1443  	}
  1444  }
  1445  
  1446  // Ensure Reload supports disabling route authorization. Test this by starting
  1447  // two servers in a cluster with authorization, ensuring messages flow
  1448  // between them, then reloading without authorization and ensuring messages
  1449  // still flow.
  1450  func TestConfigReloadDisableClusterAuthorization(t *testing.T) {
  1451  	srvb, srvbOpts, srvbConfig := runReloadServerWithConfig(t, "./configs/reload/srv_b_2.conf")
  1452  	defer srvb.Shutdown()
  1453  
  1454  	srva, srvaOpts, _ := runReloadServerWithConfig(t, "./configs/reload/srv_a_2.conf")
  1455  	defer srva.Shutdown()
  1456  
  1457  	checkClusterFormed(t, srva, srvb)
  1458  
  1459  	srvaAddr := fmt.Sprintf("nats://%s:%d", srvaOpts.Host, srvaOpts.Port)
  1460  	srvaConn, err := nats.Connect(srvaAddr)
  1461  	if err != nil {
  1462  		t.Fatalf("Error creating client: %v", err)
  1463  	}
  1464  	defer srvaConn.Close()
  1465  
  1466  	sub, err := srvaConn.SubscribeSync("foo")
  1467  	if err != nil {
  1468  		t.Fatalf("Error subscribing: %v", err)
  1469  	}
  1470  	defer sub.Unsubscribe()
  1471  	if err := srvaConn.Flush(); err != nil {
  1472  		t.Fatalf("Error flushing: %v", err)
  1473  	}
  1474  
  1475  	srvbAddr := fmt.Sprintf("nats://%s:%d", srvbOpts.Host, srvbOpts.Port)
  1476  	srvbConn, err := nats.Connect(srvbAddr)
  1477  	if err != nil {
  1478  		t.Fatalf("Error creating client: %v", err)
  1479  	}
  1480  	defer srvbConn.Close()
  1481  
  1482  	if numRoutes := srvb.NumRoutes(); numRoutes != DEFAULT_ROUTE_POOL_SIZE {
  1483  		t.Fatalf("Expected %d route, got %d", DEFAULT_ROUTE_POOL_SIZE, numRoutes)
  1484  	}
  1485  
  1486  	// Ensure messages flow through the cluster as a sanity check.
  1487  	if err := srvbConn.Publish("foo", []byte("hello")); err != nil {
  1488  		t.Fatalf("Error publishing: %v", err)
  1489  	}
  1490  	srvbConn.Flush()
  1491  	msg, err := sub.NextMsg(2 * time.Second)
  1492  	if err != nil {
  1493  		t.Fatalf("Error receiving message: %v", err)
  1494  	}
  1495  	if string(msg.Data) != "hello" {
  1496  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
  1497  	}
  1498  
  1499  	// Disable route authorization.
  1500  	changeCurrentConfigContent(t, srvbConfig, "./configs/reload/srv_b_1.conf")
  1501  	if err := srvb.Reload(); err != nil {
  1502  		t.Fatalf("Error reloading config: %v", err)
  1503  	}
  1504  
  1505  	checkClusterFormed(t, srva, srvb)
  1506  
  1507  	if numRoutes := srvb.NumRoutes(); numRoutes != DEFAULT_ROUTE_POOL_SIZE {
  1508  		t.Fatalf("Expected %d route, got %d", DEFAULT_ROUTE_POOL_SIZE, numRoutes)
  1509  	}
  1510  
  1511  	// Ensure messages still flow through the cluster.
  1512  	if err := srvbConn.Publish("foo", []byte("hola")); err != nil {
  1513  		t.Fatalf("Error publishing: %v", err)
  1514  	}
  1515  	srvbConn.Flush()
  1516  	msg, err = sub.NextMsg(2 * time.Second)
  1517  	if err != nil {
  1518  		t.Fatalf("Error receiving message: %v", err)
  1519  	}
  1520  	if string(msg.Data) != "hola" {
  1521  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hola"), msg.Data)
  1522  	}
  1523  }
  1524  
  1525  // Ensure Reload supports changing cluster routes. Test this by starting
  1526  // two servers in a cluster, ensuring messages flow between them, then
  1527  // reloading with a different route and ensuring messages flow through the new
  1528  // cluster.
  1529  func TestConfigReloadClusterRoutes(t *testing.T) {
  1530  	srvb, srvbOpts, _ := runReloadServerWithConfig(t, "./configs/reload/srv_b_1.conf")
  1531  	defer srvb.Shutdown()
  1532  
  1533  	srva, srvaOpts, srvaConfig := runReloadServerWithConfig(t, "./configs/reload/srv_a_1.conf")
  1534  	defer srva.Shutdown()
  1535  
  1536  	checkClusterFormed(t, srva, srvb)
  1537  
  1538  	srvcOpts, err := ProcessConfigFile("./configs/reload/srv_c_1.conf")
  1539  	if err != nil {
  1540  		t.Fatalf("Error processing config file: %v", err)
  1541  	}
  1542  	srvcOpts.NoLog = true
  1543  	srvcOpts.NoSigs = true
  1544  
  1545  	srvc := RunServer(srvcOpts)
  1546  	defer srvc.Shutdown()
  1547  
  1548  	srvaAddr := fmt.Sprintf("nats://%s:%d", srvaOpts.Host, srvaOpts.Port)
  1549  	srvaConn, err := nats.Connect(srvaAddr)
  1550  	if err != nil {
  1551  		t.Fatalf("Error creating client: %v", err)
  1552  	}
  1553  	defer srvaConn.Close()
  1554  
  1555  	sub, err := srvaConn.SubscribeSync("foo")
  1556  	if err != nil {
  1557  		t.Fatalf("Error subscribing: %v", err)
  1558  	}
  1559  	defer sub.Unsubscribe()
  1560  	if err := srvaConn.Flush(); err != nil {
  1561  		t.Fatalf("Error flushing: %v", err)
  1562  	}
  1563  
  1564  	srvbAddr := fmt.Sprintf("nats://%s:%d", srvbOpts.Host, srvbOpts.Port)
  1565  	srvbConn, err := nats.Connect(srvbAddr)
  1566  	if err != nil {
  1567  		t.Fatalf("Error creating client: %v", err)
  1568  	}
  1569  	defer srvbConn.Close()
  1570  
  1571  	if numRoutes := srvb.NumRoutes(); numRoutes != DEFAULT_ROUTE_POOL_SIZE {
  1572  		t.Fatalf("Expected %d route, got %d", DEFAULT_ROUTE_POOL_SIZE, numRoutes)
  1573  	}
  1574  
  1575  	// Ensure consumer on srvA is propagated to srvB
  1576  	checkExpectedSubs(t, 1, srvb)
  1577  
  1578  	// Ensure messages flow through the cluster as a sanity check.
  1579  	if err := srvbConn.Publish("foo", []byte("hello")); err != nil {
  1580  		t.Fatalf("Error publishing: %v", err)
  1581  	}
  1582  	srvbConn.Flush()
  1583  	msg, err := sub.NextMsg(2 * time.Second)
  1584  	if err != nil {
  1585  		t.Fatalf("Error receiving message: %v", err)
  1586  	}
  1587  	if string(msg.Data) != "hello" {
  1588  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
  1589  	}
  1590  
  1591  	// Reload cluster routes.
  1592  	changeCurrentConfigContent(t, srvaConfig, "./configs/reload/srv_a_3.conf")
  1593  	if err := srva.Reload(); err != nil {
  1594  		t.Fatalf("Error reloading config: %v", err)
  1595  	}
  1596  
  1597  	// Kill old route server.
  1598  	srvbConn.Close()
  1599  	srvb.Shutdown()
  1600  
  1601  	checkClusterFormed(t, srva, srvc)
  1602  
  1603  	srvcAddr := fmt.Sprintf("nats://%s:%d", srvcOpts.Host, srvcOpts.Port)
  1604  	srvcConn, err := nats.Connect(srvcAddr)
  1605  	if err != nil {
  1606  		t.Fatalf("Error creating client: %v", err)
  1607  	}
  1608  	defer srvcConn.Close()
  1609  
  1610  	// Ensure messages flow through the new cluster.
  1611  	for i := 0; i < 5; i++ {
  1612  		if err := srvcConn.Publish("foo", []byte("hola")); err != nil {
  1613  			t.Fatalf("Error publishing: %v", err)
  1614  		}
  1615  		srvcConn.Flush()
  1616  	}
  1617  	msg, err = sub.NextMsg(2 * time.Second)
  1618  	if err != nil {
  1619  		t.Fatalf("Error receiving message: %v", err)
  1620  	}
  1621  	if string(msg.Data) != "hola" {
  1622  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hola"), msg.Data)
  1623  	}
  1624  }
  1625  
  1626  // Ensure Reload supports removing a solicited route. In this case from A->B
  1627  // Test this by starting two servers in a cluster, ensuring messages flow between them.
  1628  // Then stop server B, and have server A continue to try to connect. Reload A with a config
  1629  // that removes the route and make sure it does not connect to server B when its restarted.
  1630  func TestConfigReloadClusterRemoveSolicitedRoutes(t *testing.T) {
  1631  	srvb, srvbOpts := RunServerWithConfig("./configs/reload/srv_b_1.conf")
  1632  	defer srvb.Shutdown()
  1633  
  1634  	srva, srvaOpts, srvaConfig := runReloadServerWithConfig(t, "./configs/reload/srv_a_1.conf")
  1635  	defer srva.Shutdown()
  1636  
  1637  	checkClusterFormed(t, srva, srvb)
  1638  
  1639  	srvaAddr := fmt.Sprintf("nats://%s:%d", srvaOpts.Host, srvaOpts.Port)
  1640  	srvaConn, err := nats.Connect(srvaAddr)
  1641  	if err != nil {
  1642  		t.Fatalf("Error creating client: %v", err)
  1643  	}
  1644  	defer srvaConn.Close()
  1645  	sub, err := srvaConn.SubscribeSync("foo")
  1646  	if err != nil {
  1647  		t.Fatalf("Error subscribing: %v", err)
  1648  	}
  1649  	defer sub.Unsubscribe()
  1650  	if err := srvaConn.Flush(); err != nil {
  1651  		t.Fatalf("Error flushing: %v", err)
  1652  	}
  1653  	checkExpectedSubs(t, 1, srvb)
  1654  
  1655  	srvbAddr := fmt.Sprintf("nats://%s:%d", srvbOpts.Host, srvbOpts.Port)
  1656  	srvbConn, err := nats.Connect(srvbAddr)
  1657  	if err != nil {
  1658  		t.Fatalf("Error creating client: %v", err)
  1659  	}
  1660  	defer srvbConn.Close()
  1661  
  1662  	if err := srvbConn.Publish("foo", []byte("hello")); err != nil {
  1663  		t.Fatalf("Error publishing: %v", err)
  1664  	}
  1665  	srvbConn.Flush()
  1666  	msg, err := sub.NextMsg(5 * time.Second)
  1667  	if err != nil {
  1668  		t.Fatalf("Error receiving message: %v", err)
  1669  	}
  1670  	if string(msg.Data) != "hello" {
  1671  		t.Fatalf("Msg is incorrect.\nexpected: %+v\ngot: %+v", []byte("hello"), msg.Data)
  1672  	}
  1673  
  1674  	// Now stop server B.
  1675  	srvb.Shutdown()
  1676  
  1677  	// Wait til route is dropped.
  1678  	checkNumRoutes(t, srva, 0)
  1679  
  1680  	// Now change config for server A to not solicit a route to server B.
  1681  	changeCurrentConfigContent(t, srvaConfig, "./configs/reload/srv_a_4.conf")
  1682  	if err := srva.Reload(); err != nil {
  1683  		t.Fatalf("Error reloading config: %v", err)
  1684  	}
  1685  
  1686  	// Restart server B.
  1687  	srvb, _ = RunServerWithConfig("./configs/reload/srv_b_1.conf")
  1688  	defer srvb.Shutdown()
  1689  
  1690  	// We should not have a cluster formed here.
  1691  	numRoutes := 0
  1692  	deadline := time.Now().Add(2 * DEFAULT_ROUTE_RECONNECT)
  1693  	for time.Now().Before(deadline) {
  1694  		if numRoutes = srva.NumRoutes(); numRoutes != 0 {
  1695  			break
  1696  		} else {
  1697  			time.Sleep(100 * time.Millisecond)
  1698  		}
  1699  	}
  1700  	if numRoutes != 0 {
  1701  		t.Fatalf("Expected 0 routes for server A, got %d", numRoutes)
  1702  	}
  1703  }
  1704  
  1705  func reloadUpdateConfig(t *testing.T, s *Server, conf, content string) {
  1706  	t.Helper()
  1707  	if err := os.WriteFile(conf, []byte(content), 0666); err != nil {
  1708  		t.Fatalf("Error creating config file: %v", err)
  1709  	}
  1710  	if err := s.Reload(); err != nil {
  1711  		t.Fatalf("Error on reload: %v", err)
  1712  	}
  1713  }
  1714  
  1715  func TestConfigReloadClusterAdvertise(t *testing.T) {
  1716  	s, _, conf := runReloadServerWithContent(t, []byte(`
  1717  		listen: "0.0.0.0:-1"
  1718  		cluster: {
  1719  			listen: "0.0.0.0:-1"
  1720  		}
  1721  	`))
  1722  	defer s.Shutdown()
  1723  
  1724  	orgClusterPort := s.ClusterAddr().Port
  1725  
  1726  	verify := func(expectedHost string, expectedPort int, expectedIP string) {
  1727  		s.mu.Lock()
  1728  		routeInfo := s.routeInfo
  1729  		rij := generateInfoJSON(&routeInfo)
  1730  		s.mu.Unlock()
  1731  		if routeInfo.Host != expectedHost || routeInfo.Port != expectedPort || routeInfo.IP != expectedIP {
  1732  			t.Fatalf("Expected host/port/IP to be %s:%v, %q, got %s:%d, %q",
  1733  				expectedHost, expectedPort, expectedIP, routeInfo.Host, routeInfo.Port, routeInfo.IP)
  1734  		}
  1735  		routeInfoJSON := Info{}
  1736  		err := json.Unmarshal(rij[5:], &routeInfoJSON) // Skip "INFO "
  1737  		if err != nil {
  1738  			t.Fatalf("Error on Unmarshal: %v", err)
  1739  		}
  1740  		// Check that server routeInfoJSON was updated too
  1741  		if !reflect.DeepEqual(routeInfo, routeInfoJSON) {
  1742  			t.Fatalf("Expected routeInfoJSON to be %+v, got %+v", routeInfo, routeInfoJSON)
  1743  		}
  1744  	}
  1745  
  1746  	// Update config with cluster_advertise
  1747  	reloadUpdateConfig(t, s, conf, `
  1748  	listen: "0.0.0.0:-1"
  1749  	cluster: {
  1750  		listen: "0.0.0.0:-1"
  1751  		cluster_advertise: "me:1"
  1752  	}
  1753  	`)
  1754  	verify("me", 1, "nats-route://me:1/")
  1755  
  1756  	// Update config with cluster_advertise (no port specified)
  1757  	reloadUpdateConfig(t, s, conf, `
  1758  	listen: "0.0.0.0:-1"
  1759  	cluster: {
  1760  		listen: "0.0.0.0:-1"
  1761  		cluster_advertise: "me"
  1762  	}
  1763  	`)
  1764  	verify("me", orgClusterPort, fmt.Sprintf("nats-route://me:%d/", orgClusterPort))
  1765  
  1766  	// Update config with cluster_advertise (-1 port specified)
  1767  	reloadUpdateConfig(t, s, conf, `
  1768  	listen: "0.0.0.0:-1"
  1769  	cluster: {
  1770  		listen: "0.0.0.0:-1"
  1771  		cluster_advertise: "me:-1"
  1772  	}
  1773  	`)
  1774  	verify("me", orgClusterPort, fmt.Sprintf("nats-route://me:%d/", orgClusterPort))
  1775  
  1776  	// Update to remove cluster_advertise
  1777  	reloadUpdateConfig(t, s, conf, `
  1778  	listen: "0.0.0.0:-1"
  1779  	cluster: {
  1780  		listen: "0.0.0.0:-1"
  1781  	}
  1782  	`)
  1783  	verify("0.0.0.0", orgClusterPort, "")
  1784  }
  1785  
  1786  func TestConfigReloadClusterNoAdvertise(t *testing.T) {
  1787  	s, _, conf := runReloadServerWithContent(t, []byte(`
  1788  		listen: "0.0.0.0:-1"
  1789  		client_advertise: "me:1"
  1790  		cluster: {
  1791  			listen: "0.0.0.0:-1"
  1792  		}
  1793  	`))
  1794  	defer s.Shutdown()
  1795  
  1796  	s.mu.Lock()
  1797  	ccurls := s.routeInfo.ClientConnectURLs
  1798  	s.mu.Unlock()
  1799  	if len(ccurls) != 1 && ccurls[0] != "me:1" {
  1800  		t.Fatalf("Unexpected routeInfo.ClientConnectURLS: %v", ccurls)
  1801  	}
  1802  
  1803  	// Update config with no_advertise
  1804  	reloadUpdateConfig(t, s, conf, `
  1805  	listen: "0.0.0.0:-1"
  1806  	client_advertise: "me:1"
  1807  	cluster: {
  1808  		listen: "0.0.0.0:-1"
  1809  		no_advertise: true
  1810  	}
  1811  	`)
  1812  
  1813  	s.mu.Lock()
  1814  	ccurls = s.routeInfo.ClientConnectURLs
  1815  	s.mu.Unlock()
  1816  	if len(ccurls) != 0 {
  1817  		t.Fatalf("Unexpected routeInfo.ClientConnectURLS: %v", ccurls)
  1818  	}
  1819  
  1820  	// Update config with cluster_advertise (no port specified)
  1821  	reloadUpdateConfig(t, s, conf, `
  1822  	listen: "0.0.0.0:-1"
  1823  	client_advertise: "me:1"
  1824  	cluster: {
  1825  		listen: "0.0.0.0:-1"
  1826  	}
  1827  	`)
  1828  	s.mu.Lock()
  1829  	ccurls = s.routeInfo.ClientConnectURLs
  1830  	s.mu.Unlock()
  1831  	if len(ccurls) != 1 && ccurls[0] != "me:1" {
  1832  		t.Fatalf("Unexpected routeInfo.ClientConnectURLS: %v", ccurls)
  1833  	}
  1834  }
  1835  
  1836  func TestConfigReloadClusterName(t *testing.T) {
  1837  	s, _, conf := runReloadServerWithContent(t, []byte(`
  1838  		listen: "0.0.0.0:-1"
  1839  		cluster: {
  1840  			name: "abc"
  1841  			listen: "0.0.0.0:-1"
  1842  		}
  1843  	`))
  1844  	defer s.Shutdown()
  1845  
  1846  	// Update config with a new cluster name.
  1847  	reloadUpdateConfig(t, s, conf, `
  1848  	listen: "0.0.0.0:-1"
  1849  	cluster: {
  1850  		name: "xyz"
  1851  		listen: "0.0.0.0:-1"
  1852  	}
  1853  	`)
  1854  
  1855  	if s.ClusterName() != "xyz" {
  1856  		t.Fatalf("Expected update clustername of \"xyz\", got %q", s.ClusterName())
  1857  	}
  1858  }
  1859  
  1860  func TestConfigReloadMaxSubsUnsupported(t *testing.T) {
  1861  	s, _, conf := runReloadServerWithContent(t, []byte(`
  1862  		port: -1
  1863  		max_subs: 1
  1864  		`))
  1865  	defer s.Shutdown()
  1866  
  1867  	if err := os.WriteFile(conf, []byte(`max_subs: 10`), 0666); err != nil {
  1868  		t.Fatalf("Error writing config file: %v", err)
  1869  	}
  1870  	if err := s.Reload(); err == nil {
  1871  		t.Fatal("Expected Reload to return an error")
  1872  	}
  1873  }
  1874  
  1875  func TestConfigReloadClientAdvertise(t *testing.T) {
  1876  	s, _, conf := runReloadServerWithContent(t, []byte(`listen: "0.0.0.0:-1"`))
  1877  	defer s.Shutdown()
  1878  
  1879  	orgPort := s.Addr().(*net.TCPAddr).Port
  1880  
  1881  	verify := func(expectedHost string, expectedPort int) {
  1882  		s.mu.Lock()
  1883  		info := s.info
  1884  		s.mu.Unlock()
  1885  		if info.Host != expectedHost || info.Port != expectedPort {
  1886  			stackFatalf(t, "Expected host/port to be %s:%d, got %s:%d",
  1887  				expectedHost, expectedPort, info.Host, info.Port)
  1888  		}
  1889  	}
  1890  
  1891  	// Update config with ClientAdvertise (port specified)
  1892  	reloadUpdateConfig(t, s, conf, `
  1893  	listen: "0.0.0.0:-1"
  1894  	client_advertise: "me:1"
  1895  	`)
  1896  	verify("me", 1)
  1897  
  1898  	// Update config with ClientAdvertise (no port specified)
  1899  	reloadUpdateConfig(t, s, conf, `
  1900  	listen: "0.0.0.0:-1"
  1901  	client_advertise: "me"
  1902  	`)
  1903  	verify("me", orgPort)
  1904  
  1905  	// Update config with ClientAdvertise (-1 port specified)
  1906  	reloadUpdateConfig(t, s, conf, `
  1907  	listen: "0.0.0.0:-1"
  1908  	client_advertise: "me:-1"
  1909  	`)
  1910  	verify("me", orgPort)
  1911  
  1912  	// Now remove ClientAdvertise to check that original values
  1913  	// are restored.
  1914  	reloadUpdateConfig(t, s, conf, `listen: "0.0.0.0:-1"`)
  1915  	verify("0.0.0.0", orgPort)
  1916  }
  1917  
  1918  // Ensure Reload supports changing the max connections. Test this by starting a
  1919  // server with no max connections, connecting two clients, reloading with a
  1920  // max connections of one, and ensuring one client is disconnected.
  1921  func TestConfigReloadMaxConnections(t *testing.T) {
  1922  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
  1923  	defer server.Shutdown()
  1924  
  1925  	// Make two connections.
  1926  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
  1927  	nc1, err := nats.Connect(addr)
  1928  	if err != nil {
  1929  		t.Fatalf("Error creating client: %v", err)
  1930  	}
  1931  	defer nc1.Close()
  1932  	closed := make(chan struct{}, 1)
  1933  	nc1.SetDisconnectHandler(func(*nats.Conn) {
  1934  		closed <- struct{}{}
  1935  	})
  1936  	nc2, err := nats.Connect(addr)
  1937  	if err != nil {
  1938  		t.Fatalf("Error creating client: %v", err)
  1939  	}
  1940  	defer nc2.Close()
  1941  	nc2.SetDisconnectHandler(func(*nats.Conn) {
  1942  		closed <- struct{}{}
  1943  	})
  1944  
  1945  	if numClients := server.NumClients(); numClients != 2 {
  1946  		t.Fatalf("Expected 2 clients, got %d", numClients)
  1947  	}
  1948  
  1949  	// Set max connections to one.
  1950  	changeCurrentConfigContent(t, config, "./configs/reload/max_connections.conf")
  1951  	if err := server.Reload(); err != nil {
  1952  		t.Fatalf("Error reloading config: %v", err)
  1953  	}
  1954  
  1955  	// Ensure one connection was closed.
  1956  	select {
  1957  	case <-closed:
  1958  	case <-time.After(5 * time.Second):
  1959  		t.Fatal("Expected to be disconnected")
  1960  	}
  1961  
  1962  	checkClientsCount(t, server, 1)
  1963  
  1964  	// Ensure new connections fail.
  1965  	_, err = nats.Connect(addr)
  1966  	if err == nil {
  1967  		t.Fatal("Expected error on connect")
  1968  	}
  1969  }
  1970  
  1971  // Ensure reload supports changing the max payload size. Test this by starting
  1972  // a server with the default size limit, ensuring publishes work, reloading
  1973  // with a restrictive limit, and ensuring publishing an oversized message fails
  1974  // and disconnects the client.
  1975  func TestConfigReloadMaxPayload(t *testing.T) {
  1976  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
  1977  	defer server.Shutdown()
  1978  
  1979  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
  1980  	nc, err := nats.Connect(addr)
  1981  	if err != nil {
  1982  		t.Fatalf("Error creating client: %v", err)
  1983  	}
  1984  	defer nc.Close()
  1985  	closed := make(chan struct{})
  1986  	nc.SetDisconnectHandler(func(*nats.Conn) {
  1987  		closed <- struct{}{}
  1988  	})
  1989  
  1990  	conn, err := nats.Connect(addr)
  1991  	if err != nil {
  1992  		t.Fatalf("Error creating client: %v", err)
  1993  	}
  1994  	defer conn.Close()
  1995  	sub, err := conn.SubscribeSync("foo")
  1996  	if err != nil {
  1997  		t.Fatalf("Error subscribing: %v", err)
  1998  	}
  1999  	conn.Flush()
  2000  
  2001  	// Ensure we can publish as a sanity check.
  2002  	if err := nc.Publish("foo", []byte("hello")); err != nil {
  2003  		t.Fatalf("Error publishing: %v", err)
  2004  	}
  2005  	nc.Flush()
  2006  	_, err = sub.NextMsg(2 * time.Second)
  2007  	if err != nil {
  2008  		t.Fatalf("Error receiving message: %v", err)
  2009  	}
  2010  
  2011  	// Set max payload to one.
  2012  	changeCurrentConfigContent(t, config, "./configs/reload/max_payload.conf")
  2013  	if err := server.Reload(); err != nil {
  2014  		t.Fatalf("Error reloading config: %v", err)
  2015  	}
  2016  
  2017  	// Ensure oversized messages don't get delivered and the client is
  2018  	// disconnected.
  2019  	if err := nc.Publish("foo", []byte("hello")); err != nil {
  2020  		t.Fatalf("Error publishing: %v", err)
  2021  	}
  2022  	nc.Flush()
  2023  	_, err = sub.NextMsg(20 * time.Millisecond)
  2024  	if err != nats.ErrTimeout {
  2025  		t.Fatalf("Expected ErrTimeout, got: %v", err)
  2026  	}
  2027  
  2028  	select {
  2029  	case <-closed:
  2030  	case <-time.After(5 * time.Second):
  2031  		t.Fatal("Expected to be disconnected")
  2032  	}
  2033  }
  2034  
  2035  // Ensure reload supports rotating out files. Test this by starting
  2036  // a server with log and pid files, reloading new ones, then check that
  2037  // we can rename and delete the old log/pid files.
  2038  func TestConfigReloadRotateFiles(t *testing.T) {
  2039  	server, _, config := runReloadServerWithConfig(t, "./configs/reload/file_rotate.conf")
  2040  	defer func() {
  2041  		removeFile(t, "log1.txt")
  2042  		removeFile(t, "nats-server1.pid")
  2043  	}()
  2044  	defer server.Shutdown()
  2045  
  2046  	// Configure the logger to enable actual logging
  2047  	opts := server.getOpts()
  2048  	opts.NoLog = false
  2049  	server.ConfigureLogger()
  2050  
  2051  	// Load a config that renames the files.
  2052  	changeCurrentConfigContent(t, config, "./configs/reload/file_rotate1.conf")
  2053  	if err := server.Reload(); err != nil {
  2054  		t.Fatalf("Error reloading config: %v", err)
  2055  	}
  2056  
  2057  	// Make sure the new files exist.
  2058  	if _, err := os.Stat("log1.txt"); os.IsNotExist(err) {
  2059  		t.Fatalf("Error reloading config, no new file: %v", err)
  2060  	}
  2061  	if _, err := os.Stat("nats-server1.pid"); os.IsNotExist(err) {
  2062  		t.Fatalf("Error reloading config, no new file: %v", err)
  2063  	}
  2064  
  2065  	// Check that old file can be renamed.
  2066  	if err := os.Rename("log.txt", "log_old.txt"); err != nil {
  2067  		t.Fatalf("Error reloading config, cannot rename file: %v", err)
  2068  	}
  2069  	if err := os.Rename("nats-server.pid", "nats-server_old.pid"); err != nil {
  2070  		t.Fatalf("Error reloading config, cannot rename file: %v", err)
  2071  	}
  2072  
  2073  	// Check that the old files can be removed after rename.
  2074  	removeFile(t, "log_old.txt")
  2075  	removeFile(t, "nats-server_old.pid")
  2076  }
  2077  
  2078  func TestConfigReloadClusterWorks(t *testing.T) {
  2079  	confBTemplate := `
  2080  		listen: -1
  2081  		cluster: {
  2082  			listen: 127.0.0.1:7244
  2083  			authorization {
  2084  				user: ruser
  2085  				password: pwd
  2086  				timeout: %d
  2087  			}
  2088  			routes = [
  2089  				nats-route://ruser:pwd@127.0.0.1:7246
  2090  			]
  2091  		}`
  2092  	confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, 3)))
  2093  
  2094  	confATemplate := `
  2095  		listen: -1
  2096  		cluster: {
  2097  			listen: 127.0.0.1:7246
  2098  			authorization {
  2099  				user: ruser
  2100  				password: pwd
  2101  				timeout: %d
  2102  			}
  2103  			routes = [
  2104  				nats-route://ruser:pwd@127.0.0.1:7244
  2105  			]
  2106  		}`
  2107  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, 3)))
  2108  
  2109  	srvb, _ := RunServerWithConfig(confB)
  2110  	defer srvb.Shutdown()
  2111  
  2112  	srva, _ := RunServerWithConfig(confA)
  2113  	defer srva.Shutdown()
  2114  
  2115  	// Wait for the cluster to form and capture the connection IDs of each route
  2116  	checkClusterFormed(t, srva, srvb)
  2117  
  2118  	getCID := func(s *Server) uint64 {
  2119  		s.mu.Lock()
  2120  		defer s.mu.Unlock()
  2121  		if r := getFirstRoute(s); r != nil {
  2122  			return r.cid
  2123  		}
  2124  		return 0
  2125  	}
  2126  	acid := getCID(srva)
  2127  	bcid := getCID(srvb)
  2128  
  2129  	// Update auth timeout to force a check of the connected route auth
  2130  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, 5))
  2131  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, 5))
  2132  
  2133  	// Wait a little bit to ensure that there is no issue with connection
  2134  	// breaking at this point (this was an issue before).
  2135  	time.Sleep(100 * time.Millisecond)
  2136  
  2137  	// Cluster should still exist
  2138  	checkClusterFormed(t, srva, srvb)
  2139  
  2140  	// Check that routes were not re-created
  2141  	newacid := getCID(srva)
  2142  	newbcid := getCID(srvb)
  2143  
  2144  	if newacid != acid {
  2145  		t.Fatalf("Expected server A route ID to be %v, got %v", acid, newacid)
  2146  	}
  2147  	if newbcid != bcid {
  2148  		t.Fatalf("Expected server B route ID to be %v, got %v", bcid, newbcid)
  2149  	}
  2150  }
  2151  
  2152  func TestConfigReloadClusterPerms(t *testing.T) {
  2153  	confATemplate := `
  2154  		port: -1
  2155  		cluster {
  2156  			listen: 127.0.0.1:-1
  2157  			permissions {
  2158  				import {
  2159  					allow: %s
  2160  				}
  2161  				export {
  2162  					allow: %s
  2163  				}
  2164  			}
  2165  		}
  2166  		no_sys_acc: true
  2167  	`
  2168  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `"foo"`, `"foo"`)))
  2169  	srva, _ := RunServerWithConfig(confA)
  2170  	defer srva.Shutdown()
  2171  
  2172  	confBTemplate := `
  2173  		port: -1
  2174  		cluster {
  2175  			listen: 127.0.0.1:-1
  2176  			permissions {
  2177  				import {
  2178  					allow: %s
  2179  				}
  2180  				export {
  2181  					allow: %s
  2182  				}
  2183  			}
  2184  			routes = [
  2185  				"nats://127.0.0.1:%d"
  2186  			]
  2187  		}
  2188  		no_sys_acc: true
  2189  	`
  2190  	confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, `"foo"`, `"foo"`, srva.ClusterAddr().Port)))
  2191  	srvb, _ := RunServerWithConfig(confB)
  2192  	defer srvb.Shutdown()
  2193  
  2194  	checkClusterFormed(t, srva, srvb)
  2195  
  2196  	// Create a connection on A
  2197  	nca, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", srva.Addr().(*net.TCPAddr).Port))
  2198  	if err != nil {
  2199  		t.Fatalf("Error on connect: %v", err)
  2200  	}
  2201  	defer nca.Close()
  2202  	// Create a subscription on "foo" and "bar", only "foo" will be also on server B.
  2203  	subFooOnA, err := nca.SubscribeSync("foo")
  2204  	if err != nil {
  2205  		t.Fatalf("Error on subscribe: %v", err)
  2206  	}
  2207  	subBarOnA, err := nca.SubscribeSync("bar")
  2208  	if err != nil {
  2209  		t.Fatalf("Error on subscribe: %v", err)
  2210  	}
  2211  
  2212  	// Connect on B and do the same
  2213  	ncb, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", srvb.Addr().(*net.TCPAddr).Port))
  2214  	if err != nil {
  2215  		t.Fatalf("Error on connect: %v", err)
  2216  	}
  2217  	defer ncb.Close()
  2218  	// Create a subscription on "foo" and "bar", only "foo" will be also on server B.
  2219  	subFooOnB, err := ncb.SubscribeSync("foo")
  2220  	if err != nil {
  2221  		t.Fatalf("Error on subscribe: %v", err)
  2222  	}
  2223  	subBarOnB, err := ncb.SubscribeSync("bar")
  2224  	if err != nil {
  2225  		t.Fatalf("Error on subscribe: %v", err)
  2226  	}
  2227  
  2228  	// Check subscriptions on each server. There should be 3 on each server,
  2229  	// foo and bar locally and foo from remote server.
  2230  	checkExpectedSubs(t, 3, srva, srvb)
  2231  
  2232  	sendMsg := func(t *testing.T, subj string, nc *nats.Conn) {
  2233  		t.Helper()
  2234  		if err := nc.Publish(subj, []byte("msg")); err != nil {
  2235  			t.Fatalf("Error on publish: %v", err)
  2236  		}
  2237  	}
  2238  
  2239  	checkSub := func(t *testing.T, sub *nats.Subscription, shouldReceive bool) {
  2240  		t.Helper()
  2241  		_, err := sub.NextMsg(100 * time.Millisecond)
  2242  		if shouldReceive && err != nil {
  2243  			t.Fatalf("Expected message on %q, got %v", sub.Subject, err)
  2244  		} else if !shouldReceive && err == nil {
  2245  			t.Fatalf("Expected no message on %q, got one", sub.Subject)
  2246  		}
  2247  	}
  2248  
  2249  	// Produce from A and check received on both sides
  2250  	sendMsg(t, "foo", nca)
  2251  	checkSub(t, subFooOnA, true)
  2252  	checkSub(t, subFooOnB, true)
  2253  	// Now from B:
  2254  	sendMsg(t, "foo", ncb)
  2255  	checkSub(t, subFooOnA, true)
  2256  	checkSub(t, subFooOnB, true)
  2257  
  2258  	// Publish on bar from A and make sure only local sub receives
  2259  	sendMsg(t, "bar", nca)
  2260  	checkSub(t, subBarOnA, true)
  2261  	checkSub(t, subBarOnB, false)
  2262  
  2263  	// Publish on bar from B and make sure only local sub receives
  2264  	sendMsg(t, "bar", ncb)
  2265  	checkSub(t, subBarOnA, false)
  2266  	checkSub(t, subBarOnB, true)
  2267  
  2268  	// We will now both import/export foo and bar. Start with reloading A.
  2269  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`, `["foo", "bar"]`))
  2270  
  2271  	// Since B has not been updated yet, the state should remain the same,
  2272  	// that is 3 subs on each server.
  2273  	checkExpectedSubs(t, 3, srva, srvb)
  2274  
  2275  	// Now update and reload B. Add "baz" for another test down below
  2276  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, `["foo", "bar", "baz"]`, `["foo", "bar", "baz"]`, srva.ClusterAddr().Port))
  2277  
  2278  	// Now 4 on each server
  2279  	checkExpectedSubs(t, 4, srva, srvb)
  2280  
  2281  	// Make sure that we can receive all messages
  2282  	sendMsg(t, "foo", nca)
  2283  	checkSub(t, subFooOnA, true)
  2284  	checkSub(t, subFooOnB, true)
  2285  	sendMsg(t, "foo", ncb)
  2286  	checkSub(t, subFooOnA, true)
  2287  	checkSub(t, subFooOnB, true)
  2288  
  2289  	sendMsg(t, "bar", nca)
  2290  	checkSub(t, subBarOnA, true)
  2291  	checkSub(t, subBarOnB, true)
  2292  	sendMsg(t, "bar", ncb)
  2293  	checkSub(t, subBarOnA, true)
  2294  	checkSub(t, subBarOnB, true)
  2295  
  2296  	// Create subscription on baz on server B.
  2297  	subBazOnB, err := ncb.SubscribeSync("baz")
  2298  	if err != nil {
  2299  		t.Fatalf("Error on subscribe: %v", err)
  2300  	}
  2301  	// Check subscriptions count
  2302  	checkExpectedSubs(t, 5, srvb)
  2303  	checkExpectedSubs(t, 4, srva)
  2304  
  2305  	sendMsg(t, "baz", nca)
  2306  	checkSub(t, subBazOnB, false)
  2307  	sendMsg(t, "baz", ncb)
  2308  	checkSub(t, subBazOnB, true)
  2309  
  2310  	// Test UNSUB by denying something that was previously imported
  2311  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"foo"`, `["foo", "bar"]`))
  2312  	// Since A no longer imports "bar", we should have one less subscription
  2313  	// on B (B will have received an UNSUB for bar)
  2314  	checkExpectedSubs(t, 4, srvb)
  2315  	// A, however, should still have same number of subs.
  2316  	checkExpectedSubs(t, 4, srva)
  2317  
  2318  	// Remove all permissions from A.
  2319  	reloadUpdateConfig(t, srva, confA, `
  2320  		port: -1
  2321  		cluster {
  2322  			listen: 127.0.0.1:-1
  2323  		}
  2324  		no_sys_acc: true
  2325  	`)
  2326  	// Server A should now have baz sub
  2327  	checkExpectedSubs(t, 5, srvb)
  2328  	checkExpectedSubs(t, 5, srva)
  2329  
  2330  	sendMsg(t, "baz", nca)
  2331  	checkSub(t, subBazOnB, true)
  2332  	sendMsg(t, "baz", ncb)
  2333  	checkSub(t, subBazOnB, true)
  2334  
  2335  	// Finally, remove permissions from B
  2336  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(`
  2337  		port: -1
  2338  		cluster {
  2339  			listen: 127.0.0.1:-1
  2340  			routes = [
  2341  				"nats://127.0.0.1:%d"
  2342  			]
  2343  		}
  2344  		no_sys_acc: true
  2345  	`, srva.ClusterAddr().Port))
  2346  	// Check expected subscriptions count.
  2347  	checkExpectedSubs(t, 5, srvb)
  2348  	checkExpectedSubs(t, 5, srva)
  2349  }
  2350  
  2351  func TestConfigReloadClusterPermsImport(t *testing.T) {
  2352  	confATemplate := `
  2353  		port: -1
  2354  		cluster {
  2355  			listen: 127.0.0.1:-1
  2356  			permissions {
  2357  				import: {
  2358  					allow: %s
  2359  				}
  2360  			}
  2361  		}
  2362  		no_sys_acc: true
  2363  	`
  2364  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `["foo", "bar"]`)))
  2365  	srva, _ := RunServerWithConfig(confA)
  2366  	defer srva.Shutdown()
  2367  
  2368  	confBTemplate := `
  2369  		port: -1
  2370  		cluster {
  2371  			listen: 127.0.0.1:-1
  2372  			routes = [
  2373  				"nats://127.0.0.1:%d"
  2374  			]
  2375  		}
  2376  		no_sys_acc: true
  2377  	`
  2378  	confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, srva.ClusterAddr().Port)))
  2379  	srvb, _ := RunServerWithConfig(confB)
  2380  	defer srvb.Shutdown()
  2381  
  2382  	checkClusterFormed(t, srva, srvb)
  2383  
  2384  	// Create a connection on A
  2385  	nca, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", srva.Addr().(*net.TCPAddr).Port))
  2386  	if err != nil {
  2387  		t.Fatalf("Error on connect: %v", err)
  2388  	}
  2389  	defer nca.Close()
  2390  	// Create a subscription on "foo" and "bar"
  2391  	if _, err := nca.SubscribeSync("foo"); err != nil {
  2392  		t.Fatalf("Error on subscribe: %v", err)
  2393  	}
  2394  	if _, err := nca.SubscribeSync("bar"); err != nil {
  2395  		t.Fatalf("Error on subscribe: %v", err)
  2396  	}
  2397  
  2398  	checkExpectedSubs(t, 2, srva, srvb)
  2399  
  2400  	// Drop foo
  2401  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`))
  2402  	checkExpectedSubs(t, 2, srva)
  2403  	checkExpectedSubs(t, 1, srvb)
  2404  
  2405  	// Add it back
  2406  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`))
  2407  	checkExpectedSubs(t, 2, srva, srvb)
  2408  
  2409  	// Empty Import means implicit allow
  2410  	reloadUpdateConfig(t, srva, confA, `
  2411  		port: -1
  2412  		cluster {
  2413  			listen: 127.0.0.1:-1
  2414  			permissions {
  2415  				export: ">"
  2416  			}
  2417  		}
  2418  		no_sys_acc: true
  2419  	`)
  2420  	checkExpectedSubs(t, 2, srva, srvb)
  2421  
  2422  	confATemplate = `
  2423  		port: -1
  2424  		cluster {
  2425  			listen: 127.0.0.1:-1
  2426  			permissions {
  2427  				import: {
  2428  					allow: ["foo", "bar"]
  2429  					deny: %s
  2430  				}
  2431  			}
  2432  		}
  2433  		no_sys_acc: true
  2434  	`
  2435  	// Now deny all:
  2436  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`))
  2437  	checkExpectedSubs(t, 2, srva)
  2438  	checkExpectedSubs(t, 0, srvb)
  2439  
  2440  	// Drop foo from the deny list
  2441  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`))
  2442  	checkExpectedSubs(t, 2, srva)
  2443  	checkExpectedSubs(t, 1, srvb)
  2444  }
  2445  
  2446  func TestConfigReloadClusterPermsExport(t *testing.T) {
  2447  	confATemplate := `
  2448  		port: -1
  2449  		cluster {
  2450  			listen: 127.0.0.1:-1
  2451  			permissions {
  2452  				export: {
  2453  					allow: %s
  2454  				}
  2455  			}
  2456  		}
  2457  		no_sys_acc: true
  2458  	`
  2459  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `["foo", "bar"]`)))
  2460  	srva, _ := RunServerWithConfig(confA)
  2461  	defer srva.Shutdown()
  2462  
  2463  	confBTemplate := `
  2464  		port: -1
  2465  		cluster {
  2466  			listen: 127.0.0.1:-1
  2467  			routes = [
  2468  				"nats://127.0.0.1:%d"
  2469  			]
  2470  		}
  2471  		no_sys_acc: true
  2472  	`
  2473  	confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, srva.ClusterAddr().Port)))
  2474  	srvb, _ := RunServerWithConfig(confB)
  2475  	defer srvb.Shutdown()
  2476  
  2477  	checkClusterFormed(t, srva, srvb)
  2478  
  2479  	// Create a connection on B
  2480  	ncb, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", srvb.Addr().(*net.TCPAddr).Port))
  2481  	if err != nil {
  2482  		t.Fatalf("Error on connect: %v", err)
  2483  	}
  2484  	defer ncb.Close()
  2485  	// Create a subscription on "foo" and "bar"
  2486  	if _, err := ncb.SubscribeSync("foo"); err != nil {
  2487  		t.Fatalf("Error on subscribe: %v", err)
  2488  	}
  2489  	if _, err := ncb.SubscribeSync("bar"); err != nil {
  2490  		t.Fatalf("Error on subscribe: %v", err)
  2491  	}
  2492  
  2493  	checkExpectedSubs(t, 2, srva, srvb)
  2494  
  2495  	// Drop foo
  2496  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`))
  2497  	checkExpectedSubs(t, 2, srvb)
  2498  	checkExpectedSubs(t, 1, srva)
  2499  
  2500  	// Add it back
  2501  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`))
  2502  	checkExpectedSubs(t, 2, srva, srvb)
  2503  
  2504  	// Empty Export means implicit allow
  2505  	reloadUpdateConfig(t, srva, confA, `
  2506  		port: -1
  2507  		cluster {
  2508  			listen: 127.0.0.1:-1
  2509  			permissions {
  2510  				import: ">"
  2511  			}
  2512  		}
  2513  		no_sys_acc: true
  2514  	`)
  2515  	checkExpectedSubs(t, 2, srva, srvb)
  2516  
  2517  	confATemplate = `
  2518  		port: -1
  2519  		cluster {
  2520  			listen: 127.0.0.1:-1
  2521  			permissions {
  2522  				export: {
  2523  					allow: ["foo", "bar"]
  2524  					deny: %s
  2525  				}
  2526  			}
  2527  		}
  2528  		no_sys_acc: true
  2529  	`
  2530  	// Now deny all:
  2531  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`))
  2532  	checkExpectedSubs(t, 0, srva)
  2533  	checkExpectedSubs(t, 2, srvb)
  2534  
  2535  	// Drop foo from the deny list
  2536  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`))
  2537  	checkExpectedSubs(t, 1, srva)
  2538  	checkExpectedSubs(t, 2, srvb)
  2539  }
  2540  
  2541  func TestConfigReloadClusterPermsOldServer(t *testing.T) {
  2542  	confATemplate := `
  2543  		port: -1
  2544  		cluster {
  2545  			listen: 127.0.0.1:-1
  2546  			permissions {
  2547  				export: {
  2548  					allow: %s
  2549  				}
  2550  			}
  2551  		}
  2552  	`
  2553  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `["foo", "bar"]`)))
  2554  	srva, _ := RunServerWithConfig(confA)
  2555  	defer srva.Shutdown()
  2556  
  2557  	optsB := DefaultOptions()
  2558  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srva.ClusterAddr().Port))
  2559  	// Make server B behave like an old server
  2560  	optsB.overrideProto = setServerProtoForTest(RouteProtoZero)
  2561  	srvb := RunServer(optsB)
  2562  	defer srvb.Shutdown()
  2563  
  2564  	checkClusterFormed(t, srva, srvb)
  2565  
  2566  	// Get the route's connection ID
  2567  	getRouteRID := func() uint64 {
  2568  		rid := uint64(0)
  2569  		srvb.mu.Lock()
  2570  		if r := getFirstRoute(srvb); r != nil {
  2571  			r.mu.Lock()
  2572  			rid = r.cid
  2573  			r.mu.Unlock()
  2574  		}
  2575  		srvb.mu.Unlock()
  2576  		return rid
  2577  	}
  2578  	orgRID := getRouteRID()
  2579  
  2580  	// Cause a config reload on A
  2581  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`))
  2582  
  2583  	// Check that new route gets created
  2584  	check := func(t *testing.T) {
  2585  		t.Helper()
  2586  		checkFor(t, 3*time.Second, 15*time.Millisecond, func() error {
  2587  			if rid := getRouteRID(); rid == orgRID {
  2588  				return fmt.Errorf("Route does not seem to have been recreated")
  2589  			}
  2590  			return nil
  2591  		})
  2592  	}
  2593  	check(t)
  2594  
  2595  	// Save the current value
  2596  	orgRID = getRouteRID()
  2597  
  2598  	// Add another server that supports INFO updates
  2599  
  2600  	optsC := DefaultOptions()
  2601  	optsC.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srva.ClusterAddr().Port))
  2602  	srvc := RunServer(optsC)
  2603  	defer srvc.Shutdown()
  2604  
  2605  	checkClusterFormed(t, srva, srvb, srvc)
  2606  
  2607  	// Cause a config reload on A
  2608  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"foo"`))
  2609  	// Check that new route gets created
  2610  	check(t)
  2611  }
  2612  
  2613  func TestConfigReloadAccountUsers(t *testing.T) {
  2614  	conf := createConfFile(t, []byte(`
  2615  	listen: "127.0.0.1:-1"
  2616  	accounts {
  2617  		synadia {
  2618  			users = [
  2619  				{user: derek, password: derek}
  2620  				{user: foo, password: foo}
  2621  			]
  2622  		}
  2623  		nats.io {
  2624  			users = [
  2625  				{user: ivan, password: ivan}
  2626  				{user: bar, password: bar}
  2627  			]
  2628  		}
  2629  		acc_deleted_after_reload {
  2630  			users = [
  2631  				{user: gone, password: soon}
  2632  				{user: baz, password: baz}
  2633  				{user: bat, password: bat}
  2634  			]
  2635  		}
  2636  	}
  2637  	`))
  2638  	s, opts := RunServerWithConfig(conf)
  2639  	defer s.Shutdown()
  2640  
  2641  	// Connect as exisiting users, should work.
  2642  	nc, err := nats.Connect(fmt.Sprintf("nats://derek:derek@%s:%d", opts.Host, opts.Port))
  2643  	if err != nil {
  2644  		t.Fatalf("Error on connect: %v", err)
  2645  	}
  2646  	defer nc.Close()
  2647  	ch := make(chan bool, 2)
  2648  	cb := func(_ *nats.Conn) {
  2649  		ch <- true
  2650  	}
  2651  	nc2, err := nats.Connect(
  2652  		fmt.Sprintf("nats://ivan:ivan@%s:%d", opts.Host, opts.Port),
  2653  		nats.NoReconnect(),
  2654  		nats.ClosedHandler(cb))
  2655  	if err != nil {
  2656  		t.Fatalf("Error on connect: %v", err)
  2657  	}
  2658  	defer nc2.Close()
  2659  	nc3, err := nats.Connect(
  2660  		fmt.Sprintf("nats://gone:soon@%s:%d", opts.Host, opts.Port),
  2661  		nats.NoReconnect(),
  2662  		nats.ClosedHandler(cb))
  2663  	if err != nil {
  2664  		t.Fatalf("Error on connect: %v", err)
  2665  	}
  2666  	defer nc3.Close()
  2667  	// These users will be moved from an account to another (to a specific or to global account)
  2668  	// We will create subscriptions to ensure that they are moved to proper sublists too.
  2669  	rch := make(chan bool, 4)
  2670  	rcb := func(_ *nats.Conn) {
  2671  		rch <- true
  2672  	}
  2673  	nc4, err := nats.Connect(fmt.Sprintf("nats://foo:foo@%s:%d", opts.Host, opts.Port),
  2674  		nats.ReconnectWait(50*time.Millisecond), nats.ReconnectHandler(rcb))
  2675  	if err != nil {
  2676  		t.Fatalf("Error on connect: %v", err)
  2677  	}
  2678  	defer nc4.Close()
  2679  	if _, err := nc4.SubscribeSync("foo"); err != nil {
  2680  		t.Fatalf("Error on subscribe: %v", err)
  2681  	}
  2682  	nc5, err := nats.Connect(fmt.Sprintf("nats://bar:bar@%s:%d", opts.Host, opts.Port),
  2683  		nats.ReconnectWait(50*time.Millisecond), nats.ReconnectHandler(rcb))
  2684  	if err != nil {
  2685  		t.Fatalf("Error on connect: %v", err)
  2686  	}
  2687  	defer nc5.Close()
  2688  	if _, err := nc5.SubscribeSync("bar"); err != nil {
  2689  		t.Fatalf("Error on subscribe: %v", err)
  2690  	}
  2691  	nc6, err := nats.Connect(fmt.Sprintf("nats://baz:baz@%s:%d", opts.Host, opts.Port),
  2692  		nats.ReconnectWait(50*time.Millisecond), nats.ReconnectHandler(rcb))
  2693  	if err != nil {
  2694  		t.Fatalf("Error on connect: %v", err)
  2695  	}
  2696  	defer nc6.Close()
  2697  	if _, err := nc6.SubscribeSync("baz"); err != nil {
  2698  		t.Fatalf("Error on subscribe: %v", err)
  2699  	}
  2700  	nc7, err := nats.Connect(fmt.Sprintf("nats://bat:bat@%s:%d", opts.Host, opts.Port),
  2701  		nats.ReconnectWait(50*time.Millisecond), nats.ReconnectHandler(rcb))
  2702  	if err != nil {
  2703  		t.Fatalf("Error on connect: %v", err)
  2704  	}
  2705  	defer nc7.Close()
  2706  	if _, err := nc7.SubscribeSync("bat"); err != nil {
  2707  		t.Fatalf("Error on subscribe: %v", err)
  2708  	}
  2709  
  2710  	// confirm subscriptions before and after reload.
  2711  	var expectedSubs uint32 = 5
  2712  	sAcc, err := s.LookupAccount("synadia")
  2713  	require_NoError(t, err)
  2714  	sAcc.mu.RLock()
  2715  	n := sAcc.sl.Count()
  2716  	sAcc.mu.RUnlock()
  2717  	if n != expectedSubs {
  2718  		t.Errorf("Synadia account should have %d sub, got %v", expectedSubs, n)
  2719  	}
  2720  	nAcc, err := s.LookupAccount("nats.io")
  2721  	require_NoError(t, err)
  2722  	nAcc.mu.RLock()
  2723  	n = nAcc.sl.Count()
  2724  	nAcc.mu.RUnlock()
  2725  	if n != expectedSubs {
  2726  		t.Errorf("Nats.io account should have %d sub, got %v", expectedSubs, n)
  2727  	}
  2728  
  2729  	// Remove user from account and whole account
  2730  	reloadUpdateConfig(t, s, conf, `
  2731  	listen: "127.0.0.1:-1"
  2732  	authorization {
  2733  		users = [
  2734  			{user: foo, password: foo}
  2735  			{user: baz, password: baz}
  2736  		]
  2737  	}
  2738  	accounts {
  2739  		synadia {
  2740  			users = [
  2741  				{user: derek, password: derek}
  2742  				{user: bar, password: bar}
  2743  			]
  2744  		}
  2745  		nats.io {
  2746  			users = [
  2747  				{user: bat, password: bat}
  2748  			]
  2749  		}
  2750  	}
  2751  	`)
  2752  	// nc2 and nc3 should be closed
  2753  	if err := wait(ch); err != nil {
  2754  		t.Fatal("Did not get the closed callback")
  2755  	}
  2756  	if err := wait(ch); err != nil {
  2757  		t.Fatal("Did not get the closed callback")
  2758  	}
  2759  	// And first connection should still be connected
  2760  	if !nc.IsConnected() {
  2761  		t.Fatal("First connection should still be connected")
  2762  	}
  2763  
  2764  	// Old account should be gone
  2765  	if _, err := s.LookupAccount("acc_deleted_after_reload"); err == nil {
  2766  		t.Fatal("old account should be gone")
  2767  	}
  2768  
  2769  	// Check subscriptions. Since most of the users have been
  2770  	// moving accounts, make sure we account for the reconnect
  2771  	for i := 0; i < 4; i++ {
  2772  		if err := wait(rch); err != nil {
  2773  			t.Fatal("Did not get the reconnect cb")
  2774  		}
  2775  	}
  2776  	// Still need to do the tests in a checkFor() because clients
  2777  	// being reconnected does not mean that resent of subscriptions
  2778  	// has already been processed.
  2779  	checkFor(t, 2*time.Second, 100*time.Millisecond, func() error {
  2780  		gAcc, err := s.LookupAccount(globalAccountName)
  2781  		require_NoError(t, err)
  2782  		gAcc.mu.RLock()
  2783  		n := gAcc.sl.Count()
  2784  		fooMatch := gAcc.sl.Match("foo")
  2785  		bazMatch := gAcc.sl.Match("baz")
  2786  		gAcc.mu.RUnlock()
  2787  		// The number of subscriptions should be 4 ($SYS.REQ.USER.INFO,
  2788  		// $SYS.REQ.ACCOUNT.PING.CONNZ, $SYS.REQ.ACCOUNT.PING.STATZ,
  2789  		// $SYS.REQ.SERVER.PING.CONNZ) + 2 (foo and baz)
  2790  		if n != 6 {
  2791  			return fmt.Errorf("Global account should have 6 subs, got %v", n)
  2792  		}
  2793  		if len(fooMatch.psubs) != 1 {
  2794  			return fmt.Errorf("Global account should have foo sub")
  2795  		}
  2796  		if len(bazMatch.psubs) != 1 {
  2797  			return fmt.Errorf("Global account should have baz sub")
  2798  		}
  2799  
  2800  		sAcc, err := s.LookupAccount("synadia")
  2801  		require_NoError(t, err)
  2802  		sAcc.mu.RLock()
  2803  		n = sAcc.sl.Count()
  2804  		barMatch := sAcc.sl.Match("bar")
  2805  
  2806  		sAcc.mu.RUnlock()
  2807  		if n != expectedSubs {
  2808  			return fmt.Errorf("Synadia account should have %d sub, got %v", expectedSubs, n)
  2809  		}
  2810  		if len(barMatch.psubs) != 1 {
  2811  			return fmt.Errorf("Synadia account should have bar sub")
  2812  		}
  2813  
  2814  		nAcc, err := s.LookupAccount("nats.io")
  2815  		require_NoError(t, err)
  2816  		nAcc.mu.RLock()
  2817  		n = nAcc.sl.Count()
  2818  		batMatch := nAcc.sl.Match("bat")
  2819  		nAcc.mu.RUnlock()
  2820  		if n != expectedSubs {
  2821  			return fmt.Errorf("Nats.io account should have %d sub, got %v", expectedSubs, n)
  2822  		}
  2823  		if len(batMatch.psubs) != 1 {
  2824  			return fmt.Errorf("Synadia account should have bar sub")
  2825  		}
  2826  		return nil
  2827  	})
  2828  }
  2829  
  2830  func TestConfigReloadAccountWithNoChanges(t *testing.T) {
  2831  	conf := createConfFile(t, []byte(`
  2832  	listen: "127.0.0.1:-1"
  2833          system_account: sys
  2834  	accounts {
  2835  		A {
  2836  			users = [{ user: a }]
  2837  		}
  2838  		B {
  2839  			users = [{ user: b }]
  2840  		}
  2841  		C {
  2842  			users = [{ user: c }]
  2843  		}
  2844  		sys {
  2845  			users = [{ user: sys }]
  2846  		}
  2847  	}
  2848  	`))
  2849  	s, opts := RunServerWithConfig(conf)
  2850  	defer s.Shutdown()
  2851  
  2852  	ncA, err := nats.Connect(fmt.Sprintf("nats://a:@%s:%d", opts.Host, opts.Port))
  2853  	if err != nil {
  2854  		t.Fatalf("Error on connect: %v", err)
  2855  	}
  2856  	defer ncA.Close()
  2857  
  2858  	// Confirm default service imports are ok.
  2859  	checkSubs := func(t *testing.T) {
  2860  		resp, err := ncA.Request("$SYS.REQ.ACCOUNT.PING.CONNZ", nil, time.Second)
  2861  		if err != nil {
  2862  			t.Error(err)
  2863  		}
  2864  		if resp == nil || !strings.Contains(string(resp.Data), `"num_connections":1`) {
  2865  			t.Fatal("unexpected data in connz response")
  2866  		}
  2867  		resp, err = ncA.Request("$SYS.REQ.SERVER.PING.CONNZ", nil, time.Second)
  2868  		if err != nil {
  2869  			t.Error(err)
  2870  		}
  2871  		if resp == nil || !strings.Contains(string(resp.Data), `"num_connections":1`) {
  2872  			t.Fatal("unexpected data in connz response")
  2873  		}
  2874  		resp, err = ncA.Request("$SYS.REQ.ACCOUNT.PING.STATZ", nil, time.Second)
  2875  		if err != nil {
  2876  			t.Error(err)
  2877  		}
  2878  		if resp == nil || !strings.Contains(string(resp.Data), `"conns":1`) {
  2879  			t.Fatal("unexpected data in connz response")
  2880  		}
  2881  	}
  2882  	checkSubs(t)
  2883  	before := s.NumSubscriptions()
  2884  	s.Reload()
  2885  	after := s.NumSubscriptions()
  2886  	if before != after {
  2887  		t.Errorf("Number of subscriptions changed after reload: %d -> %d", before, after)
  2888  	}
  2889  
  2890  	// Confirm this still works after a reload...
  2891  	checkSubs(t)
  2892  	before = s.NumSubscriptions()
  2893  	s.Reload()
  2894  	after = s.NumSubscriptions()
  2895  	if before != after {
  2896  		t.Errorf("Number of subscriptions changed after reload: %d -> %d", before, after)
  2897  	}
  2898  
  2899  	// Do another extra reload just in case.
  2900  	checkSubs(t)
  2901  	before = s.NumSubscriptions()
  2902  	s.Reload()
  2903  	after = s.NumSubscriptions()
  2904  	if before != after {
  2905  		t.Errorf("Number of subscriptions changed after reload: %d -> %d", before, after)
  2906  	}
  2907  }
  2908  
  2909  func TestConfigReloadAccountNKeyUsers(t *testing.T) {
  2910  	conf := createConfFile(t, []byte(`
  2911  	listen: "127.0.0.1:-1"
  2912  	accounts {
  2913  		synadia {
  2914  			users = [
  2915  				# Derek
  2916  				{nkey : UCNGL4W5QX66CFX6A6DCBVDH5VOHMI7B2UZZU7TXAUQQSI2JPHULCKBR}
  2917  			]
  2918  		}
  2919  		nats.io {
  2920  			users = [
  2921  				# Ivan
  2922  				{nkey : UDPGQVFIWZ7Q5UH4I5E6DBCZULQS6VTVBG6CYBD7JV3G3N2GMQOMNAUH}
  2923  			]
  2924  		}
  2925  	}
  2926  	`))
  2927  	s, _ := RunServerWithConfig(conf)
  2928  	defer s.Shutdown()
  2929  
  2930  	synadia, _ := s.LookupAccount("synadia")
  2931  	nats, _ := s.LookupAccount("nats.io")
  2932  
  2933  	seed1 := []byte("SUAPM67TC4RHQLKBX55NIQXSMATZDOZK6FNEOSS36CAYA7F7TY66LP4BOM")
  2934  	seed2 := []byte("SUAIS5JPX4X4GJ7EIIJEQ56DH2GWPYJRPWN5XJEDENJOZHCBLI7SEPUQDE")
  2935  
  2936  	kp, _ := nkeys.FromSeed(seed1)
  2937  	pubKey, _ := kp.PublicKey()
  2938  
  2939  	c, cr, l := newClientForServer(s)
  2940  	defer c.close()
  2941  	// Check for Nonce
  2942  	var info nonceInfo
  2943  	if err := json.Unmarshal([]byte(l[5:]), &info); err != nil {
  2944  		t.Fatalf("Could not parse INFO json: %v\n", err)
  2945  	}
  2946  	if info.Nonce == "" {
  2947  		t.Fatalf("Expected a non-empty nonce with nkeys defined")
  2948  	}
  2949  	sigraw, err := kp.Sign([]byte(info.Nonce))
  2950  	if err != nil {
  2951  		t.Fatalf("Failed signing nonce: %v", err)
  2952  	}
  2953  	sig := base64.RawURLEncoding.EncodeToString(sigraw)
  2954  
  2955  	// PING needed to flush the +OK to us.
  2956  	cs := fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
  2957  	c.parseAsync(cs)
  2958  	l, _ = cr.ReadString('\n')
  2959  	if !strings.HasPrefix(l, "+OK") {
  2960  		t.Fatalf("Expected an OK, got: %v", l)
  2961  	}
  2962  	if c.acc != synadia {
  2963  		t.Fatalf("Expected the nkey client's account to match 'synadia', got %v", c.acc)
  2964  	}
  2965  
  2966  	// Now nats account nkey user.
  2967  	kp, _ = nkeys.FromSeed(seed2)
  2968  	pubKey, _ = kp.PublicKey()
  2969  
  2970  	c, cr, l = newClientForServer(s)
  2971  	defer c.close()
  2972  	// Check for Nonce
  2973  	err = json.Unmarshal([]byte(l[5:]), &info)
  2974  	if err != nil {
  2975  		t.Fatalf("Could not parse INFO json: %v\n", err)
  2976  	}
  2977  	if info.Nonce == "" {
  2978  		t.Fatalf("Expected a non-empty nonce with nkeys defined")
  2979  	}
  2980  	sigraw, err = kp.Sign([]byte(info.Nonce))
  2981  	if err != nil {
  2982  		t.Fatalf("Failed signing nonce: %v", err)
  2983  	}
  2984  	sig = base64.RawURLEncoding.EncodeToString(sigraw)
  2985  
  2986  	// PING needed to flush the +OK to us.
  2987  	cs = fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
  2988  	c.parseAsync(cs)
  2989  	l, _ = cr.ReadString('\n')
  2990  	if !strings.HasPrefix(l, "+OK") {
  2991  		t.Fatalf("Expected an OK, got: %v", l)
  2992  	}
  2993  	if c.acc != nats {
  2994  		t.Fatalf("Expected the nkey client's account to match 'nats', got %v", c.acc)
  2995  	}
  2996  
  2997  	// Remove user from account and whole account
  2998  	reloadUpdateConfig(t, s, conf, `
  2999  	listen: "127.0.0.1:-1"
  3000  	authorization {
  3001  		users = [
  3002  			# Ivan
  3003  			{nkey : UDPGQVFIWZ7Q5UH4I5E6DBCZULQS6VTVBG6CYBD7JV3G3N2GMQOMNAUH}
  3004  		]
  3005  	}
  3006  	accounts {
  3007  		nats.io {
  3008  			users = [
  3009  				# Derek
  3010  				{nkey : UCNGL4W5QX66CFX6A6DCBVDH5VOHMI7B2UZZU7TXAUQQSI2JPHULCKBR}
  3011  			]
  3012  		}
  3013  	}
  3014  	`)
  3015  
  3016  	s.mu.Lock()
  3017  	nkeys := s.nkeys
  3018  	globalAcc := s.gacc
  3019  	s.mu.Unlock()
  3020  
  3021  	if n := len(nkeys); n != 2 {
  3022  		t.Fatalf("NKeys map should have 2 users, got %v", n)
  3023  	}
  3024  	derek := nkeys["UCNGL4W5QX66CFX6A6DCBVDH5VOHMI7B2UZZU7TXAUQQSI2JPHULCKBR"]
  3025  	if derek == nil {
  3026  		t.Fatal("NKey for user Derek not found")
  3027  	}
  3028  	if derek.Account == nil || derek.Account.Name != "nats.io" {
  3029  		t.Fatalf("Invalid account for user Derek: %#v", derek.Account)
  3030  	}
  3031  	ivan := nkeys["UDPGQVFIWZ7Q5UH4I5E6DBCZULQS6VTVBG6CYBD7JV3G3N2GMQOMNAUH"]
  3032  	if ivan == nil {
  3033  		t.Fatal("NKey for user Ivan not found")
  3034  	}
  3035  	if ivan.Account != globalAcc {
  3036  		t.Fatalf("Invalid account for user Ivan: %#v", ivan.Account)
  3037  	}
  3038  	if _, err := s.LookupAccount("synadia"); err == nil {
  3039  		t.Fatal("Account Synadia should have been removed")
  3040  	}
  3041  }
  3042  
  3043  func TestConfigReloadAccountStreamsImportExport(t *testing.T) {
  3044  	template := `
  3045  	listen: "127.0.0.1:-1"
  3046  	accounts {
  3047  		synadia {
  3048  			users [{user: derek, password: foo}]
  3049  			exports = [
  3050  				{stream: "private.>", accounts: [nats.io]}
  3051  				{stream: %s}
  3052  			]
  3053  		}
  3054  		nats.io {
  3055  			users [
  3056  				{user: ivan, password: bar, permissions: {subscribe: {deny: %s}}}
  3057  			]
  3058  			imports = [
  3059  				{stream: {account: "synadia", subject: %s}}
  3060  				{stream: {account: "synadia", subject: "private.natsio.*"}, prefix: %s}
  3061  			]
  3062  		}
  3063  	}
  3064  	no_sys_acc: true
  3065  	`
  3066  	// synadia account exports "private.>" to nats.io
  3067  	// synadia account exports "foo.*"
  3068  	// user ivan denies subscription on "xxx"
  3069  	// nats.io account imports "foo.*" from synadia
  3070  	// nats.io account imports "private.natsio.*" from synadia with prefix "ivan"
  3071  	conf := createConfFile(t, []byte(fmt.Sprintf(template, `"foo.*"`, `"xxx"`, `"foo.*"`, `"ivan"`)))
  3072  	s, opts := RunServerWithConfig(conf)
  3073  	defer s.Shutdown()
  3074  
  3075  	derek, err := nats.Connect(fmt.Sprintf("nats://derek:foo@%s:%d", opts.Host, opts.Port))
  3076  	if err != nil {
  3077  		t.Fatalf("Error on connect: %v", err)
  3078  	}
  3079  	defer derek.Close()
  3080  	checkClientsCount(t, s, 1)
  3081  
  3082  	ch := make(chan bool, 1)
  3083  	ivan, err := nats.Connect(fmt.Sprintf("nats://ivan:bar@%s:%d", opts.Host, opts.Port),
  3084  		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  3085  			if strings.Contains(strings.ToLower(err.Error()), "permissions violation") {
  3086  				ch <- true
  3087  			}
  3088  		}))
  3089  	if err != nil {
  3090  		t.Fatalf("Error on connect: %v", err)
  3091  	}
  3092  	defer ivan.Close()
  3093  	checkClientsCount(t, s, 2)
  3094  
  3095  	subscribe := func(t *testing.T, nc *nats.Conn, subj string) *nats.Subscription {
  3096  		t.Helper()
  3097  		s, err := nc.SubscribeSync(subj)
  3098  		if err != nil {
  3099  			t.Fatalf("Error on subscribe: %v", err)
  3100  		}
  3101  		return s
  3102  	}
  3103  
  3104  	subFooBar := subscribe(t, ivan, "foo.bar")
  3105  	subFooBaz := subscribe(t, ivan, "foo.baz")
  3106  	subFooBat := subscribe(t, ivan, "foo.bat")
  3107  	subPriv := subscribe(t, ivan, "ivan.private.natsio.*")
  3108  	ivan.Flush()
  3109  
  3110  	publish := func(t *testing.T, nc *nats.Conn, subj string) {
  3111  		t.Helper()
  3112  		if err := nc.Publish(subj, []byte("hello")); err != nil {
  3113  			t.Fatalf("Error on publish: %v", err)
  3114  		}
  3115  	}
  3116  
  3117  	nextMsg := func(t *testing.T, sub *nats.Subscription, expected bool) {
  3118  		t.Helper()
  3119  		dur := 100 * time.Millisecond
  3120  		if expected {
  3121  			dur = time.Second
  3122  		}
  3123  		_, err := sub.NextMsg(dur)
  3124  		if expected && err != nil {
  3125  			t.Fatalf("Expected a message on %s, got %v", sub.Subject, err)
  3126  		} else if !expected && err != nats.ErrTimeout {
  3127  			t.Fatalf("Expected a timeout on %s, got %v", sub.Subject, err)
  3128  		}
  3129  	}
  3130  
  3131  	// Checks the derek's user sublist for presence of given subject
  3132  	// interest. Boolean says if interest is expected or not.
  3133  	checkSublist := func(t *testing.T, subject string, shouldBeThere bool) {
  3134  		t.Helper()
  3135  		dcli := s.getClient(1)
  3136  		dcli.mu.Lock()
  3137  		r := dcli.acc.sl.Match(subject)
  3138  		dcli.mu.Unlock()
  3139  		if shouldBeThere && len(r.psubs) != 1 {
  3140  			t.Fatalf("%s should have 1 match in derek's sublist, got %v", subject, len(r.psubs))
  3141  		} else if !shouldBeThere && len(r.psubs) > 0 {
  3142  			t.Fatalf("%s should not be in derek's sublist", subject)
  3143  		}
  3144  	}
  3145  
  3146  	// Publish on all subjects and the subs should receive and
  3147  	// subjects should be in sublist
  3148  	publish(t, derek, "foo.bar")
  3149  	nextMsg(t, subFooBar, true)
  3150  	checkSublist(t, "foo.bar", true)
  3151  
  3152  	publish(t, derek, "foo.baz")
  3153  	nextMsg(t, subFooBaz, true)
  3154  	checkSublist(t, "foo.baz", true)
  3155  
  3156  	publish(t, derek, "foo.bat")
  3157  	nextMsg(t, subFooBat, true)
  3158  	checkSublist(t, "foo.bat", true)
  3159  
  3160  	publish(t, derek, "private.natsio.foo")
  3161  	nextMsg(t, subPriv, true)
  3162  	checkSublist(t, "private.natsio.foo", true)
  3163  
  3164  	// Also make sure that intra-account subscription works OK
  3165  	ivanSub := subscribe(t, ivan, "ivan.sub")
  3166  	publish(t, ivan, "ivan.sub")
  3167  	nextMsg(t, ivanSub, true)
  3168  	derekSub := subscribe(t, derek, "derek.sub")
  3169  	publish(t, derek, "derek.sub")
  3170  	nextMsg(t, derekSub, true)
  3171  
  3172  	// synadia account exports "private.>" to nats.io
  3173  	// synadia account exports "foo.*"
  3174  	// user ivan denies subscription on "foo.bat"
  3175  	// nats.io account imports "foo.baz" from synadia
  3176  	// nats.io account imports "private.natsio.*" from synadia with prefix "yyyy"
  3177  	reloadUpdateConfig(t, s, conf, fmt.Sprintf(template, `"foo.*"`, `"foo.bat"`, `"foo.baz"`, `"yyyy"`))
  3178  
  3179  	// Sub on foo.bar should now fail to receive
  3180  	publish(t, derek, "foo.bar")
  3181  	nextMsg(t, subFooBar, false)
  3182  	checkSublist(t, "foo.bar", false)
  3183  	// But foo.baz should be received
  3184  	publish(t, derek, "foo.baz")
  3185  	nextMsg(t, subFooBaz, true)
  3186  	checkSublist(t, "foo.baz", true)
  3187  	// Due to permissions, foo.bat should not
  3188  	publish(t, derek, "foo.bat")
  3189  	nextMsg(t, subFooBat, false)
  3190  	checkSublist(t, "foo.bat", false)
  3191  	// Prefix changed, so should not be received
  3192  	publish(t, derek, "private.natsio.foo")
  3193  	nextMsg(t, subPriv, false)
  3194  	checkSublist(t, "private.natsio.foo", false)
  3195  
  3196  	// Wait for client notification of permissions error
  3197  	if err := wait(ch); err != nil {
  3198  		t.Fatal("Did not the permissions error")
  3199  	}
  3200  
  3201  	publish(t, ivan, "ivan.sub")
  3202  	nextMsg(t, ivanSub, true)
  3203  	publish(t, derek, "derek.sub")
  3204  	nextMsg(t, derekSub, true)
  3205  
  3206  	// Change export so that foo.* is no longer exported
  3207  	// synadia account exports "private.>" to nats.io
  3208  	// synadia account exports "xxx"
  3209  	// user ivan denies subscription on "foo.bat"
  3210  	// nats.io account imports "xxx" from synadia
  3211  	// nats.io account imports "private.natsio.*" from synadia with prefix "ivan"
  3212  	reloadUpdateConfig(t, s, conf, fmt.Sprintf(template, `"xxx"`, `"foo.bat"`, `"xxx"`, `"ivan"`))
  3213  
  3214  	publish(t, derek, "foo.bar")
  3215  	nextMsg(t, subFooBar, false)
  3216  	checkSublist(t, "foo.bar", false)
  3217  
  3218  	publish(t, derek, "foo.baz")
  3219  	nextMsg(t, subFooBaz, false)
  3220  	checkSublist(t, "foo.baz", false)
  3221  
  3222  	publish(t, derek, "foo.bat")
  3223  	nextMsg(t, subFooBat, false)
  3224  	checkSublist(t, "foo.bat", false)
  3225  
  3226  	// Prefix changed back, so should receive
  3227  	publish(t, derek, "private.natsio.foo")
  3228  	nextMsg(t, subPriv, true)
  3229  	checkSublist(t, "private.natsio.foo", true)
  3230  
  3231  	publish(t, ivan, "ivan.sub")
  3232  	nextMsg(t, ivanSub, true)
  3233  	publish(t, derek, "derek.sub")
  3234  	nextMsg(t, derekSub, true)
  3235  }
  3236  
  3237  func TestConfigReloadAccountServicesImportExport(t *testing.T) {
  3238  	conf := createConfFile(t, []byte(`
  3239  	listen: "127.0.0.1:-1"
  3240  	accounts {
  3241  		synadia {
  3242  			users [{user: derek, password: foo}]
  3243  			exports = [
  3244  				{service: "pub.request"}
  3245  				{service: "pub.special.request", accounts: [nats.io]}
  3246  			]
  3247  		}
  3248  		nats.io {
  3249  			users [{user: ivan, password: bar}]
  3250  			imports = [
  3251  				{service: {account: "synadia", subject: "pub.special.request"}, to: "foo"}
  3252  				{service: {account: "synadia", subject: "pub.request"}, to: "bar"}
  3253  			]
  3254  		}
  3255  	}
  3256  	cluster {
  3257  		name: "abc"
  3258  		port: -1
  3259  	}
  3260  	`))
  3261  	s, opts := RunServerWithConfig(conf)
  3262  	defer s.Shutdown()
  3263  
  3264  	opts2 := DefaultOptions()
  3265  	opts2.Cluster.Name = "abc"
  3266  	opts2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", opts.Cluster.Port))
  3267  	s2 := RunServer(opts2)
  3268  	defer s2.Shutdown()
  3269  
  3270  	checkClusterFormed(t, s, s2)
  3271  
  3272  	derek, err := nats.Connect(fmt.Sprintf("nats://derek:foo@%s:%d", opts.Host, opts.Port))
  3273  	if err != nil {
  3274  		t.Fatalf("Error on connect: %v", err)
  3275  	}
  3276  	defer derek.Close()
  3277  	checkClientsCount(t, s, 1)
  3278  
  3279  	ivan, err := nats.Connect(fmt.Sprintf("nats://ivan:bar@%s:%d", opts.Host, opts.Port))
  3280  	if err != nil {
  3281  		t.Fatalf("Error on connect: %v", err)
  3282  	}
  3283  	defer ivan.Close()
  3284  	checkClientsCount(t, s, 2)
  3285  
  3286  	if _, err := derek.Subscribe("pub.special.request", func(m *nats.Msg) {
  3287  		derek.Publish(m.Reply, []byte("reply1"))
  3288  	}); err != nil {
  3289  		t.Fatalf("Error on subscribe: %v", err)
  3290  	}
  3291  	if _, err := derek.Subscribe("pub.request", func(m *nats.Msg) {
  3292  		derek.Publish(m.Reply, []byte("reply2"))
  3293  	}); err != nil {
  3294  		t.Fatalf("Error on subscribe: %v", err)
  3295  	}
  3296  	if _, err := derek.Subscribe("pub.special.request.new", func(m *nats.Msg) {
  3297  		derek.Publish(m.Reply, []byte("reply3"))
  3298  	}); err != nil {
  3299  		t.Fatalf("Error on subscribe: %v", err)
  3300  	}
  3301  	// Also create one that will be used for intra-account communication
  3302  	if _, err := derek.Subscribe("derek.sub", func(m *nats.Msg) {
  3303  		derek.Publish(m.Reply, []byte("private"))
  3304  	}); err != nil {
  3305  		t.Fatalf("Error on subscribe: %v", err)
  3306  	}
  3307  	derek.Flush()
  3308  
  3309  	// Create an intra-account sub for ivan too
  3310  	if _, err := ivan.Subscribe("ivan.sub", func(m *nats.Msg) {
  3311  		ivan.Publish(m.Reply, []byte("private"))
  3312  	}); err != nil {
  3313  		t.Fatalf("Error on subscribe: %v", err)
  3314  	}
  3315  	// This subscription is just to make sure that we can update
  3316  	// route map without locking issues during reload.
  3317  	natsSubSync(t, ivan, "bar")
  3318  
  3319  	req := func(t *testing.T, nc *nats.Conn, subj string, reply string) {
  3320  		t.Helper()
  3321  		var timeout time.Duration
  3322  		if reply != "" {
  3323  			timeout = time.Second
  3324  		} else {
  3325  			timeout = 100 * time.Millisecond
  3326  		}
  3327  		msg, err := nc.Request(subj, []byte("request"), timeout)
  3328  		if reply != "" {
  3329  			if err != nil {
  3330  				t.Fatalf("Expected reply %s on subject %s, got %v", reply, subj, err)
  3331  			}
  3332  			if string(msg.Data) != reply {
  3333  				t.Fatalf("Expected reply %s on subject %s, got %s", reply, subj, msg.Data)
  3334  			}
  3335  		} else if err != nats.ErrTimeout && err != nats.ErrNoResponders {
  3336  			t.Fatalf("Expected timeout on subject %s, got %v", subj, err)
  3337  		}
  3338  	}
  3339  
  3340  	req(t, ivan, "foo", "reply1")
  3341  	req(t, ivan, "bar", "reply2")
  3342  	// This not exported/imported, so should timeout
  3343  	req(t, ivan, "baz", "")
  3344  
  3345  	// Check intra-account communication
  3346  	req(t, ivan, "ivan.sub", "private")
  3347  	req(t, derek, "derek.sub", "private")
  3348  
  3349  	reloadUpdateConfig(t, s, conf, `
  3350  	listen: "127.0.0.1:-1"
  3351  	accounts {
  3352  		synadia {
  3353  			users [{user: derek, password: foo}]
  3354  			exports = [
  3355  				{service: "pub.request"}
  3356  				{service: "pub.special.request", accounts: [nats.io]}
  3357  				{service: "pub.special.request.new", accounts: [nats.io]}
  3358  			]
  3359  		}
  3360  		nats.io {
  3361  			users [{user: ivan, password: bar}]
  3362  			imports = [
  3363  				{service: {account: "synadia", subject: "pub.special.request"}, to: "foo"}
  3364  				{service: {account: "synadia", subject: "pub.special.request.new"}, to: "baz"}
  3365  			]
  3366  		}
  3367  	}
  3368  	cluster {
  3369  		name: "abc"
  3370  		port: -1
  3371  	}
  3372  	`)
  3373  	// This still should work
  3374  	req(t, ivan, "foo", "reply1")
  3375  	// This should not
  3376  	req(t, ivan, "bar", "")
  3377  	// This now should work
  3378  	req(t, ivan, "baz", "reply3")
  3379  
  3380  	// Check intra-account communication
  3381  	req(t, ivan, "ivan.sub", "private")
  3382  	req(t, derek, "derek.sub", "private")
  3383  }
  3384  
  3385  // As of now, config reload does not support changes for gateways.
  3386  // However, ensure that if a gateway is defined, one can still
  3387  // do reload as long as we don't change the gateway spec.
  3388  func TestConfigReloadNotPreventedByGateways(t *testing.T) {
  3389  	confTemplate := `
  3390  		listen: "127.0.0.1:-1"
  3391  		%s
  3392  		gateway {
  3393  			name: "A"
  3394  			listen: "127.0.0.1:-1"
  3395  			tls {
  3396  				cert_file: "configs/certs/server.pem"
  3397  				key_file: "configs/certs/key.pem"
  3398  				timeout: %s
  3399  			}
  3400  			gateways [
  3401  				{
  3402  					name: "B"
  3403  					url: "nats://localhost:8888"
  3404  				}
  3405  			]
  3406  		}
  3407  		no_sys_acc: true
  3408  	`
  3409  	conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, "", "5")))
  3410  	s, _ := RunServerWithConfig(conf)
  3411  	defer s.Shutdown()
  3412  
  3413  	// Cause reload with adding a param that is supported
  3414  	reloadUpdateConfig(t, s, conf, fmt.Sprintf(confTemplate, "max_payload: 100000", "5"))
  3415  
  3416  	// Now update gateway, should fail to reload.
  3417  	changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(confTemplate, "max_payload: 100000", "3")))
  3418  	if err := s.Reload(); err == nil || !strings.Contains(err.Error(), "not supported for Gateway") {
  3419  		t.Fatalf("Expected Reload to return a not supported error, got %v", err)
  3420  	}
  3421  }
  3422  
  3423  func TestConfigReloadBoolFlags(t *testing.T) {
  3424  	defer func() { FlagSnapshot = nil }()
  3425  
  3426  	logfile := filepath.Join(t.TempDir(), "logtime.log")
  3427  	template := `
  3428  		listen: "127.0.0.1:-1"
  3429  		logfile: "%s"
  3430  		%s
  3431  	`
  3432  
  3433  	var opts *Options
  3434  	var err error
  3435  
  3436  	for _, test := range []struct {
  3437  		name     string
  3438  		content  string
  3439  		cmdLine  []string
  3440  		expected bool
  3441  		val      func() bool
  3442  	}{
  3443  		// Logtime
  3444  		{
  3445  			"logtime_not_in_config_no_override",
  3446  			"",
  3447  			nil,
  3448  			true,
  3449  			func() bool { return opts.Logtime },
  3450  		},
  3451  		{
  3452  			"logtime_not_in_config_override_short_true",
  3453  			"",
  3454  			[]string{"-T"},
  3455  			true,
  3456  			func() bool { return opts.Logtime },
  3457  		},
  3458  		{
  3459  			"logtime_not_in_config_override_true",
  3460  			"",
  3461  			[]string{"-logtime"},
  3462  			true,
  3463  			func() bool { return opts.Logtime },
  3464  		},
  3465  		{
  3466  			"logtime_false_in_config_no_override",
  3467  			"logtime: false",
  3468  			nil,
  3469  			false,
  3470  			func() bool { return opts.Logtime },
  3471  		},
  3472  		{
  3473  			"logtime_false_in_config_override_short_true",
  3474  			"logtime: false",
  3475  			[]string{"-T"},
  3476  			true,
  3477  			func() bool { return opts.Logtime },
  3478  		},
  3479  		{
  3480  			"logtime_false_in_config_override_true",
  3481  			"logtime: false",
  3482  			[]string{"-logtime"},
  3483  			true,
  3484  			func() bool { return opts.Logtime },
  3485  		},
  3486  		{
  3487  			"logtime_true_in_config_no_override",
  3488  			"logtime: true",
  3489  			nil,
  3490  			true,
  3491  			func() bool { return opts.Logtime },
  3492  		},
  3493  		{
  3494  			"logtime_true_in_config_override_short_false",
  3495  			"logtime: true",
  3496  			[]string{"-T=false"},
  3497  			false,
  3498  			func() bool { return opts.Logtime },
  3499  		},
  3500  		{
  3501  			"logtime_true_in_config_override_false",
  3502  			"logtime: true",
  3503  			[]string{"-logtime=false"},
  3504  			false,
  3505  			func() bool { return opts.Logtime },
  3506  		},
  3507  		// Debug
  3508  		{
  3509  			"debug_not_in_config_no_override",
  3510  			"",
  3511  			nil,
  3512  			false,
  3513  			func() bool { return opts.Debug },
  3514  		},
  3515  		{
  3516  			"debug_not_in_config_override_short_true",
  3517  			"",
  3518  			[]string{"-D"},
  3519  			true,
  3520  			func() bool { return opts.Debug },
  3521  		},
  3522  		{
  3523  			"debug_not_in_config_override_true",
  3524  			"",
  3525  			[]string{"-debug"},
  3526  			true,
  3527  			func() bool { return opts.Debug },
  3528  		},
  3529  		{
  3530  			"debug_false_in_config_no_override",
  3531  			"debug: false",
  3532  			nil,
  3533  			false,
  3534  			func() bool { return opts.Debug },
  3535  		},
  3536  		{
  3537  			"debug_false_in_config_override_short_true",
  3538  			"debug: false",
  3539  			[]string{"-D"},
  3540  			true,
  3541  			func() bool { return opts.Debug },
  3542  		},
  3543  		{
  3544  			"debug_false_in_config_override_true",
  3545  			"debug: false",
  3546  			[]string{"-debug"},
  3547  			true,
  3548  			func() bool { return opts.Debug },
  3549  		},
  3550  		{
  3551  			"debug_true_in_config_no_override",
  3552  			"debug: true",
  3553  			nil,
  3554  			true,
  3555  			func() bool { return opts.Debug },
  3556  		},
  3557  		{
  3558  			"debug_true_in_config_override_short_false",
  3559  			"debug: true",
  3560  			[]string{"-D=false"},
  3561  			false,
  3562  			func() bool { return opts.Debug },
  3563  		},
  3564  		{
  3565  			"debug_true_in_config_override_false",
  3566  			"debug: true",
  3567  			[]string{"-debug=false"},
  3568  			false,
  3569  			func() bool { return opts.Debug },
  3570  		},
  3571  		// Trace
  3572  		{
  3573  			"trace_not_in_config_no_override",
  3574  			"",
  3575  			nil,
  3576  			false,
  3577  			func() bool { return opts.Trace },
  3578  		},
  3579  		{
  3580  			"trace_not_in_config_override_short_true",
  3581  			"",
  3582  			[]string{"-V"},
  3583  			true,
  3584  			func() bool { return opts.Trace },
  3585  		},
  3586  		{
  3587  			"trace_not_in_config_override_true",
  3588  			"",
  3589  			[]string{"-trace"},
  3590  			true,
  3591  			func() bool { return opts.Trace },
  3592  		},
  3593  		{
  3594  			"trace_false_in_config_no_override",
  3595  			"trace: false",
  3596  			nil,
  3597  			false,
  3598  			func() bool { return opts.Trace },
  3599  		},
  3600  		{
  3601  			"trace_false_in_config_override_short_true",
  3602  			"trace: false",
  3603  			[]string{"-V"},
  3604  			true,
  3605  			func() bool { return opts.Trace },
  3606  		},
  3607  		{
  3608  			"trace_false_in_config_override_true",
  3609  			"trace: false",
  3610  			[]string{"-trace"},
  3611  			true,
  3612  			func() bool { return opts.Trace },
  3613  		},
  3614  		{
  3615  			"trace_true_in_config_no_override",
  3616  			"trace: true",
  3617  			nil,
  3618  			true,
  3619  			func() bool { return opts.Trace },
  3620  		},
  3621  		{
  3622  			"trace_true_in_config_override_short_false",
  3623  			"trace: true",
  3624  			[]string{"-V=false"},
  3625  			false,
  3626  			func() bool { return opts.Trace },
  3627  		},
  3628  		{
  3629  			"trace_true_in_config_override_false",
  3630  			"trace: true",
  3631  			[]string{"-trace=false"},
  3632  			false,
  3633  			func() bool { return opts.Trace },
  3634  		},
  3635  		// Syslog
  3636  		{
  3637  			"syslog_not_in_config_no_override",
  3638  			"",
  3639  			nil,
  3640  			false,
  3641  			func() bool { return opts.Syslog },
  3642  		},
  3643  		{
  3644  			"syslog_not_in_config_override_short_true",
  3645  			"",
  3646  			[]string{"-s"},
  3647  			true,
  3648  			func() bool { return opts.Syslog },
  3649  		},
  3650  		{
  3651  			"syslog_not_in_config_override_true",
  3652  			"",
  3653  			[]string{"-syslog"},
  3654  			true,
  3655  			func() bool { return opts.Syslog },
  3656  		},
  3657  		{
  3658  			"syslog_false_in_config_no_override",
  3659  			"syslog: false",
  3660  			nil,
  3661  			false,
  3662  			func() bool { return opts.Syslog },
  3663  		},
  3664  		{
  3665  			"syslog_false_in_config_override_short_true",
  3666  			"syslog: false",
  3667  			[]string{"-s"},
  3668  			true,
  3669  			func() bool { return opts.Syslog },
  3670  		},
  3671  		{
  3672  			"syslog_false_in_config_override_true",
  3673  			"syslog: false",
  3674  			[]string{"-syslog"},
  3675  			true,
  3676  			func() bool { return opts.Syslog },
  3677  		},
  3678  		{
  3679  			"syslog_true_in_config_no_override",
  3680  			"syslog: true",
  3681  			nil,
  3682  			true,
  3683  			func() bool { return opts.Syslog },
  3684  		},
  3685  		{
  3686  			"syslog_true_in_config_override_short_false",
  3687  			"syslog: true",
  3688  			[]string{"-s=false"},
  3689  			false,
  3690  			func() bool { return opts.Syslog },
  3691  		},
  3692  		{
  3693  			"syslog_true_in_config_override_false",
  3694  			"syslog: true",
  3695  			[]string{"-syslog=false"},
  3696  			false,
  3697  			func() bool { return opts.Syslog },
  3698  		},
  3699  		// Cluster.NoAdvertise
  3700  		{
  3701  			"cluster_no_advertise_not_in_config_no_override",
  3702  			`cluster {
  3703  				port: -1
  3704  			}`,
  3705  			nil,
  3706  			false,
  3707  			func() bool { return opts.Cluster.NoAdvertise },
  3708  		},
  3709  		{
  3710  			"cluster_no_advertise_not_in_config_override_true",
  3711  			`cluster {
  3712  				port: -1
  3713  			}`,
  3714  			[]string{"-no_advertise"},
  3715  			true,
  3716  			func() bool { return opts.Cluster.NoAdvertise },
  3717  		},
  3718  		{
  3719  			"cluster_no_advertise_false_in_config_no_override",
  3720  			`cluster {
  3721  				port: -1
  3722  				no_advertise: false
  3723  			}`,
  3724  			nil,
  3725  			false,
  3726  			func() bool { return opts.Cluster.NoAdvertise },
  3727  		},
  3728  		{
  3729  			"cluster_no_advertise_false_in_config_override_true",
  3730  			`cluster {
  3731  				port: -1
  3732  				no_advertise: false
  3733  			}`,
  3734  			[]string{"-no_advertise"},
  3735  			true,
  3736  			func() bool { return opts.Cluster.NoAdvertise },
  3737  		},
  3738  		{
  3739  			"cluster_no_advertise_true_in_config_no_override",
  3740  			`cluster {
  3741  				port: -1
  3742  				no_advertise: true
  3743  			}`,
  3744  			nil,
  3745  			true,
  3746  			func() bool { return opts.Cluster.NoAdvertise },
  3747  		},
  3748  		{
  3749  			"cluster_no_advertise_true_in_config_override_false",
  3750  			`cluster {
  3751  				port: -1
  3752  				no_advertise: true
  3753  			}`,
  3754  			[]string{"-no_advertise=false"},
  3755  			false,
  3756  			func() bool { return opts.Syslog },
  3757  		},
  3758  		// -DV override
  3759  		{
  3760  			"debug_trace_not_in_config_dv_override_true",
  3761  			"",
  3762  			[]string{"-DV"},
  3763  			true,
  3764  			func() bool { return opts.Debug && opts.Trace },
  3765  		},
  3766  		{
  3767  			"debug_trace_false_in_config_dv_override_true",
  3768  			`debug: false
  3769  		     trace: false
  3770  			`,
  3771  			[]string{"-DV"},
  3772  			true,
  3773  			func() bool { return opts.Debug && opts.Trace },
  3774  		},
  3775  		{
  3776  			"debug_trace_true_in_config_dv_override_false",
  3777  			`debug: true
  3778  		     trace: true
  3779  			`,
  3780  			[]string{"-DV=false"},
  3781  			false,
  3782  			func() bool { return opts.Debug && opts.Trace },
  3783  		},
  3784  		{
  3785  			"trace_verbose_true_in_config_override_true",
  3786  			`trace_verbose: true
  3787  			`,
  3788  			nil,
  3789  			true,
  3790  			func() bool { return opts.Trace && opts.TraceVerbose },
  3791  		},
  3792  		{
  3793  			"trace_verbose_true_in_config_override_false",
  3794  			`trace_verbose: true
  3795  			`,
  3796  			[]string{"--VV=false"},
  3797  			true,
  3798  			func() bool { return !opts.TraceVerbose },
  3799  		},
  3800  		{
  3801  			"trace_verbose_true_in_config_override_false",
  3802  			`trace_verbose: false
  3803  			`,
  3804  			[]string{"--VV=true"},
  3805  			true,
  3806  			func() bool { return opts.TraceVerbose },
  3807  		},
  3808  	} {
  3809  		t.Run(test.name, func(t *testing.T) {
  3810  			conf := createConfFile(t, []byte(fmt.Sprintf(template, logfile, test.content)))
  3811  
  3812  			fs := flag.NewFlagSet("test", flag.ContinueOnError)
  3813  			var args []string
  3814  			args = append(args, "-c", conf)
  3815  			if test.cmdLine != nil {
  3816  				args = append(args, test.cmdLine...)
  3817  			}
  3818  			opts, err = ConfigureOptions(fs, args, nil, nil, nil)
  3819  			if err != nil {
  3820  				t.Fatalf("Error processing config: %v", err)
  3821  			}
  3822  			opts.NoSigs = true
  3823  			s := RunServer(opts)
  3824  			defer s.Shutdown()
  3825  
  3826  			if test.val() != test.expected {
  3827  				t.Fatalf("Expected to be set to %v, got %v", test.expected, test.val())
  3828  			}
  3829  			if err := s.Reload(); err != nil {
  3830  				t.Fatalf("Error on reload: %v", err)
  3831  			}
  3832  			if test.val() != test.expected {
  3833  				t.Fatalf("Expected to be set to %v, got %v", test.expected, test.val())
  3834  			}
  3835  		})
  3836  	}
  3837  }
  3838  
  3839  func TestConfigReloadMaxControlLineWithClients(t *testing.T) {
  3840  	server, opts, config := runReloadServerWithConfig(t, "./configs/reload/basic.conf")
  3841  	defer server.Shutdown()
  3842  
  3843  	// Ensure we can connect as a sanity check.
  3844  	addr := fmt.Sprintf("nats://%s:%d", opts.Host, server.Addr().(*net.TCPAddr).Port)
  3845  	nc, err := nats.Connect(addr)
  3846  	if err != nil {
  3847  		t.Fatalf("Error creating client: %v", err)
  3848  	}
  3849  	defer nc.Close()
  3850  
  3851  	// Now grab server's internal client that matches.
  3852  	cid, _ := nc.GetClientID()
  3853  	c := server.getClient(cid)
  3854  	if c == nil {
  3855  		t.Fatalf("Could not look up internal client")
  3856  	}
  3857  
  3858  	// Check that we have the correct mcl snapshotted into the connected client.
  3859  	getMcl := func(c *client) int32 {
  3860  		c.mu.Lock()
  3861  		defer c.mu.Unlock()
  3862  		return c.mcl
  3863  	}
  3864  	if mcl := getMcl(c); mcl != opts.MaxControlLine {
  3865  		t.Fatalf("Expected snapshot in client for mcl to be same as opts.MaxControlLine, got %d vs %d",
  3866  			mcl, opts.MaxControlLine)
  3867  	}
  3868  
  3869  	changeCurrentConfigContentWithNewContent(t, config, []byte("listen: 127.0.0.1:-1; max_control_line: 222"))
  3870  	if err := server.Reload(); err != nil {
  3871  		t.Fatalf("Expected Reload to succeed, got %v", err)
  3872  	}
  3873  
  3874  	// Refresh properly.
  3875  	opts = server.getOpts()
  3876  
  3877  	if mcl := getMcl(c); mcl != opts.MaxControlLine {
  3878  		t.Fatalf("Expected snapshot in client for mcl to be same as new opts.MaxControlLine, got %d vs %d",
  3879  			mcl, opts.MaxControlLine)
  3880  	}
  3881  }
  3882  
  3883  type testCustomAuth struct{}
  3884  
  3885  func (ca *testCustomAuth) Check(c ClientAuthentication) bool { return true }
  3886  
  3887  func TestConfigReloadIgnoreCustomAuth(t *testing.T) {
  3888  	conf := createConfFile(t, []byte(`
  3889  		port: -1
  3890  	`))
  3891  	opts := LoadConfig(conf)
  3892  
  3893  	ca := &testCustomAuth{}
  3894  	opts.CustomClientAuthentication = ca
  3895  	opts.CustomRouterAuthentication = ca
  3896  
  3897  	s := RunServer(opts)
  3898  	defer s.Shutdown()
  3899  
  3900  	if err := s.Reload(); err != nil {
  3901  		t.Fatalf("Error during reload: %v", err)
  3902  	}
  3903  
  3904  	if s.getOpts().CustomClientAuthentication != ca || s.getOpts().CustomRouterAuthentication != ca {
  3905  		t.Fatalf("Custom auth missing")
  3906  	}
  3907  }
  3908  
  3909  func TestConfigReloadLeafNodeRandomPort(t *testing.T) {
  3910  	conf := createConfFile(t, []byte(`
  3911  		port: -1
  3912  		leafnodes {
  3913  			port: -1
  3914  		}
  3915  	`))
  3916  	s, _ := RunServerWithConfig(conf)
  3917  	defer s.Shutdown()
  3918  
  3919  	s.mu.Lock()
  3920  	lnPortBefore := s.leafNodeListener.Addr().(*net.TCPAddr).Port
  3921  	s.mu.Unlock()
  3922  
  3923  	if err := s.Reload(); err != nil {
  3924  		t.Fatalf("Error during reload: %v", err)
  3925  	}
  3926  
  3927  	s.mu.Lock()
  3928  	lnPortAfter := s.leafNodeListener.Addr().(*net.TCPAddr).Port
  3929  	s.mu.Unlock()
  3930  
  3931  	if lnPortBefore != lnPortAfter {
  3932  		t.Fatalf("Expected leafnodes listen port to be same, was %v is now %v", lnPortBefore, lnPortAfter)
  3933  	}
  3934  }
  3935  
  3936  func TestConfigReloadLeafNodeWithTLS(t *testing.T) {
  3937  	template := `
  3938  		port: -1
  3939  		%s
  3940  		leaf {
  3941  			listen: "127.0.0.1:-1"
  3942  			tls: {
  3943  				ca_file: "../test/configs/certs/tlsauth/ca.pem"
  3944  				cert_file: "../test/configs/certs/tlsauth/server.pem"
  3945  				key_file: "../test/configs/certs/tlsauth/server-key.pem"
  3946  				timeout: 3
  3947  			}
  3948  		}
  3949  	`
  3950  	conf1 := createConfFile(t, []byte(fmt.Sprintf(template, "")))
  3951  	s1, o1 := RunServerWithConfig(conf1)
  3952  	defer s1.Shutdown()
  3953  
  3954  	u, err := url.Parse(fmt.Sprintf("nats://localhost:%d", o1.LeafNode.Port))
  3955  	if err != nil {
  3956  		t.Fatalf("Error creating url: %v", err)
  3957  	}
  3958  	conf2 := createConfFile(t, []byte(fmt.Sprintf(`
  3959  		port: -1
  3960  		leaf {
  3961  			remotes [
  3962  				{
  3963  					url: "%s"
  3964  					tls {
  3965  						ca_file: "../test/configs/certs/tlsauth/ca.pem"
  3966  						cert_file: "../test/configs/certs/tlsauth/client.pem"
  3967  						key_file:  "../test/configs/certs/tlsauth/client-key.pem"
  3968  						timeout: 2
  3969  					}
  3970  				}
  3971  			]
  3972  		}
  3973  	`, u.String())))
  3974  	o2, err := ProcessConfigFile(conf2)
  3975  	if err != nil {
  3976  		t.Fatalf("Error processing config file: %v", err)
  3977  	}
  3978  	o2.NoLog, o2.NoSigs = true, true
  3979  	o2.LeafNode.resolver = &testLoopbackResolver{}
  3980  	s2 := RunServer(o2)
  3981  	defer s2.Shutdown()
  3982  
  3983  	checkFor(t, 3*time.Second, 15*time.Millisecond, func() error {
  3984  		if n := s1.NumLeafNodes(); n != 1 {
  3985  			return fmt.Errorf("Expected 1 leaf node, got %v", n)
  3986  		}
  3987  		return nil
  3988  	})
  3989  
  3990  	changeCurrentConfigContentWithNewContent(t, conf1, []byte(fmt.Sprintf(template, "debug: false")))
  3991  
  3992  	if err := s1.Reload(); err != nil {
  3993  		t.Fatalf("Error during reload: %v", err)
  3994  	}
  3995  }
  3996  
  3997  func TestConfigReloadLeafNodeWithRemotesNoChanges(t *testing.T) {
  3998  	template := `
  3999          port: -1
  4000          cluster {
  4001              port: -1
  4002              name: "%s"
  4003          }
  4004          leaf {
  4005              remotes [
  4006                  {
  4007                      urls: [
  4008                          "nats://127.0.0.1:1234",
  4009                          "nats://127.0.0.1:1235",
  4010                          "nats://127.0.0.1:1236",
  4011                          "nats://127.0.0.1:1237",
  4012                          "nats://127.0.0.1:1238",
  4013                          "nats://127.0.0.1:1239",
  4014                      ]
  4015                  }
  4016              ]
  4017          }
  4018  	`
  4019  	config := fmt.Sprintf(template, "A")
  4020  	conf := createConfFile(t, []byte(config))
  4021  	o, err := ProcessConfigFile(conf)
  4022  	if err != nil {
  4023  		t.Fatalf("Error processing config file: %v", err)
  4024  	}
  4025  	o.NoLog, o.NoSigs = true, false
  4026  	s := RunServer(o)
  4027  	defer s.Shutdown()
  4028  
  4029  	config = fmt.Sprintf(template, "B")
  4030  	changeCurrentConfigContentWithNewContent(t, conf, []byte(config))
  4031  
  4032  	if err := s.Reload(); err != nil {
  4033  		t.Fatalf("Error during reload: %v", err)
  4034  	}
  4035  }
  4036  
  4037  func TestConfigReloadAndVarz(t *testing.T) {
  4038  	template := `
  4039  		port: -1
  4040  		%s
  4041  	`
  4042  	conf := createConfFile(t, []byte(fmt.Sprintf(template, "")))
  4043  	s, _ := RunServerWithConfig(conf)
  4044  	defer s.Shutdown()
  4045  
  4046  	s.mu.Lock()
  4047  	initConfigTime := s.configTime
  4048  	s.mu.Unlock()
  4049  
  4050  	v, _ := s.Varz(nil)
  4051  	if !v.ConfigLoadTime.Equal(initConfigTime) {
  4052  		t.Fatalf("ConfigLoadTime should be %v, got %v", initConfigTime, v.ConfigLoadTime)
  4053  	}
  4054  	if v.MaxConn != DEFAULT_MAX_CONNECTIONS {
  4055  		t.Fatalf("MaxConn should be %v, got %v", DEFAULT_MAX_CONNECTIONS, v.MaxConn)
  4056  	}
  4057  
  4058  	changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(template, "max_connections: 10")))
  4059  
  4060  	// Make sure we wait a bit so config load time has a chance to change.
  4061  	time.Sleep(15 * time.Millisecond)
  4062  
  4063  	if err := s.Reload(); err != nil {
  4064  		t.Fatalf("Error during reload: %v", err)
  4065  	}
  4066  
  4067  	v, _ = s.Varz(nil)
  4068  	if v.ConfigLoadTime.Equal(initConfigTime) {
  4069  		t.Fatalf("ConfigLoadTime should be different from %v", initConfigTime)
  4070  	}
  4071  	if v.MaxConn != 10 {
  4072  		t.Fatalf("MaxConn should be 10, got %v", v.MaxConn)
  4073  	}
  4074  }
  4075  
  4076  func TestConfigReloadConnectErrReports(t *testing.T) {
  4077  	template := `
  4078  		port: -1
  4079  		%s
  4080  		%s
  4081  	`
  4082  	conf := createConfFile(t, []byte(fmt.Sprintf(template, "", "")))
  4083  	s, _ := RunServerWithConfig(conf)
  4084  	defer s.Shutdown()
  4085  
  4086  	opts := s.getOpts()
  4087  	if cer := opts.ConnectErrorReports; cer != DEFAULT_CONNECT_ERROR_REPORTS {
  4088  		t.Fatalf("Expected ConnectErrorReports to be %v, got %v", DEFAULT_CONNECT_ERROR_REPORTS, cer)
  4089  	}
  4090  	if rer := opts.ReconnectErrorReports; rer != DEFAULT_RECONNECT_ERROR_REPORTS {
  4091  		t.Fatalf("Expected ReconnectErrorReports to be %v, got %v", DEFAULT_RECONNECT_ERROR_REPORTS, rer)
  4092  	}
  4093  
  4094  	changeCurrentConfigContentWithNewContent(t, conf,
  4095  		[]byte(fmt.Sprintf(template, "connect_error_reports: 2", "reconnect_error_reports: 3")))
  4096  
  4097  	if err := s.Reload(); err != nil {
  4098  		t.Fatalf("Error during reload: %v", err)
  4099  	}
  4100  
  4101  	opts = s.getOpts()
  4102  	if cer := opts.ConnectErrorReports; cer != 2 {
  4103  		t.Fatalf("Expected ConnectErrorReports to be %v, got %v", 2, cer)
  4104  	}
  4105  	if rer := opts.ReconnectErrorReports; rer != 3 {
  4106  		t.Fatalf("Expected ReconnectErrorReports to be %v, got %v", 3, rer)
  4107  	}
  4108  }
  4109  
  4110  func TestConfigReloadAuthDoesNotBreakRouteInterest(t *testing.T) {
  4111  	s, opts := RunServerWithConfig("./configs/seed_tls.conf")
  4112  	defer s.Shutdown()
  4113  
  4114  	// Create client and sub interest on seed server.
  4115  	urlSeed := fmt.Sprintf("nats://%s:%d/", opts.Host, opts.Port)
  4116  	nc, err := nats.Connect(urlSeed)
  4117  	if err != nil {
  4118  		t.Fatalf("Error creating client: %v\n", err)
  4119  	}
  4120  	defer nc.Close()
  4121  
  4122  	ch := make(chan bool)
  4123  	nc.Subscribe("foo", func(m *nats.Msg) { ch <- true })
  4124  	nc.Flush()
  4125  
  4126  	// Use this to check for message.
  4127  	checkForMsg := func() {
  4128  		t.Helper()
  4129  		select {
  4130  		case <-ch:
  4131  		case <-time.After(2 * time.Second):
  4132  			t.Fatal("Timeout waiting for message across route")
  4133  		}
  4134  	}
  4135  
  4136  	// Create second server and form cluster. We will send from here.
  4137  	urlRoute := fmt.Sprintf("nats://%s:%d", opts.Cluster.Host, opts.Cluster.Port)
  4138  	optsA := nextServerOpts(opts)
  4139  	optsA.Routes = RoutesFromStr(urlRoute)
  4140  
  4141  	sa := RunServer(optsA)
  4142  	defer sa.Shutdown()
  4143  
  4144  	checkClusterFormed(t, s, sa)
  4145  	checkSubInterest(t, sa, globalAccountName, "foo", time.Second)
  4146  
  4147  	// Create second client and send message from this one. Interest should be here.
  4148  	urlA := fmt.Sprintf("nats://%s:%d/", optsA.Host, optsA.Port)
  4149  	nc2, err := nats.Connect(urlA)
  4150  	if err != nil {
  4151  		t.Fatalf("Error creating client: %v\n", err)
  4152  	}
  4153  	defer nc2.Close()
  4154  
  4155  	// Check that we can send messages.
  4156  	nc2.Publish("foo", nil)
  4157  	checkForMsg()
  4158  
  4159  	// Now shutdown nc2 and srvA.
  4160  	nc2.Close()
  4161  	sa.Shutdown()
  4162  
  4163  	// Now force reload on seed server of auth.
  4164  	s.reloadAuthorization()
  4165  
  4166  	// Restart both server A and client 2.
  4167  	sa = RunServer(optsA)
  4168  	defer sa.Shutdown()
  4169  
  4170  	checkClusterFormed(t, s, sa)
  4171  	checkSubInterest(t, sa, globalAccountName, "foo", time.Second)
  4172  
  4173  	nc2, err = nats.Connect(urlA)
  4174  	if err != nil {
  4175  		t.Fatalf("Error creating client: %v\n", err)
  4176  	}
  4177  	defer nc2.Close()
  4178  
  4179  	// Check that we can still send messages.
  4180  	nc2.Publish("foo", nil)
  4181  	checkForMsg()
  4182  }
  4183  
  4184  func TestConfigReloadAccountResolverTLSConfig(t *testing.T) {
  4185  	kp, _ := nkeys.FromSeed(oSeed)
  4186  	akp, _ := nkeys.CreateAccount()
  4187  	apub, _ := akp.PublicKey()
  4188  	nac := jwt.NewAccountClaims(apub)
  4189  	ajwt, err := nac.Encode(kp)
  4190  	if err != nil {
  4191  		t.Fatalf("Error generating account JWT: %v", err)
  4192  	}
  4193  	pub, _ := kp.PublicKey()
  4194  
  4195  	tc := &TLSConfigOpts{
  4196  		CertFile: "../test/configs/certs/server-cert.pem",
  4197  		KeyFile:  "../test/configs/certs/server-key.pem",
  4198  		CaFile:   "../test/configs/certs/ca.pem",
  4199  	}
  4200  	tlsConfig, err := GenTLSConfig(tc)
  4201  	if err != nil {
  4202  		t.Fatalf("Error generating tls config: %v", err)
  4203  	}
  4204  	ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  4205  		w.Write([]byte(ajwt))
  4206  	}))
  4207  	ts.TLS = tlsConfig
  4208  	ts.StartTLS()
  4209  	defer ts.Close()
  4210  	// Set a dummy logger to prevent tls bad certificate output to stderr.
  4211  	ts.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0)
  4212  
  4213  	confTemplate := `
  4214  				listen: -1
  4215  				trusted_keys: %s
  4216  				resolver: URL("%s/ngs/v1/accounts/jwt/")
  4217  				%s
  4218  	`
  4219  	conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, pub, ts.URL, `
  4220  		resolver_tls {
  4221  			cert_file: "../test/configs/certs/client-cert.pem"
  4222  			key_file: "../test/configs/certs/client-key.pem"
  4223  			ca_file: "../test/configs/certs/ca.pem"
  4224  		}
  4225  	`)))
  4226  
  4227  	s, _ := RunServerWithConfig(conf)
  4228  	defer s.Shutdown()
  4229  
  4230  	changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(confTemplate, pub, ts.URL, "")))
  4231  	if err := s.Reload(); err != nil {
  4232  		t.Fatalf("Error during reload: %v", err)
  4233  	}
  4234  
  4235  	if _, err := s.LookupAccount(apub); err == nil {
  4236  		t.Fatal("Expected error during lookup, did not get one")
  4237  	}
  4238  
  4239  	changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(confTemplate, pub, ts.URL, `
  4240  		resolver_tls {
  4241  			insecure: true
  4242  		}
  4243  	`)))
  4244  	if err := s.Reload(); err != nil {
  4245  		t.Fatalf("Error during reload: %v", err)
  4246  	}
  4247  
  4248  	acc, err := s.LookupAccount(apub)
  4249  	if err != nil {
  4250  		t.Fatalf("Error during lookup: %v", err)
  4251  	}
  4252  	if acc == nil {
  4253  		t.Fatalf("Expected to receive an account")
  4254  	}
  4255  	if acc.Name != apub {
  4256  		t.Fatalf("Account name did not match claim key")
  4257  	}
  4258  }
  4259  
  4260  func TestConfigReloadLogging(t *testing.T) {
  4261  	// This test basically starts a server and causes it's configuration to be reloaded 3 times.
  4262  	// Each time, a new log file is created and trace levels are turned, off - on - off.
  4263  
  4264  	// At the end of the test, all 3 log files are inspected for certain traces.
  4265  	countMatches := func(log []byte, stmts ...string) int {
  4266  		matchCnt := 0
  4267  		for _, stmt := range stmts {
  4268  			if strings.Contains(string(log), stmt) {
  4269  				matchCnt++
  4270  			}
  4271  		}
  4272  		return matchCnt
  4273  	}
  4274  
  4275  	traces := []string{"[TRC]", "[DBG]", "SYSTEM", "MSG_PAYLOAD", "$SYS.SERVER.ACCOUNT"}
  4276  
  4277  	didTrace := func(log []byte) bool {
  4278  		return countMatches(log, "[INF] Reloaded server configuration") == 1
  4279  	}
  4280  
  4281  	tracingAbsent := func(log []byte) bool {
  4282  		return countMatches(log, traces...) == 0 && didTrace(log)
  4283  	}
  4284  
  4285  	tracingPresent := func(log []byte) bool {
  4286  		return len(traces) == countMatches(log, traces...) && didTrace(log)
  4287  	}
  4288  
  4289  	check := func(filename string, valid func([]byte) bool) {
  4290  		t.Helper()
  4291  		log, err := os.ReadFile(filename)
  4292  		if err != nil {
  4293  			t.Fatalf("Error reading log file %s: %v\n", filename, err)
  4294  		}
  4295  		if !valid(log) {
  4296  			t.Fatalf("%s is not valid: %s", filename, log)
  4297  		}
  4298  		//t.Logf("%s contains: %s\n", filename, log)
  4299  	}
  4300  
  4301  	// common configuration setting up system accounts. trace_verbose needs this to cause traces
  4302  	commonCfg := `
  4303  		port: -1
  4304  		system_account: sys
  4305  		accounts {
  4306  		  sys { users = [ {user: sys, pass: "" } ] }
  4307  		  nats.io: { users = [ { user : bar, pass: "pwd" } ] }
  4308  		}
  4309  	`
  4310  
  4311  	conf := createConfFile(t, []byte(commonCfg))
  4312  
  4313  	defer removeFile(t, "off-pre.log")
  4314  	defer removeFile(t, "on.log")
  4315  	defer removeFile(t, "off-post.log")
  4316  
  4317  	s, opts := RunServerWithConfig(conf)
  4318  	defer s.Shutdown()
  4319  
  4320  	reload := func(change string) {
  4321  		t.Helper()
  4322  		changeCurrentConfigContentWithNewContent(t, conf, []byte(commonCfg+`
  4323  			`+change+`
  4324  		`))
  4325  
  4326  		if err := s.Reload(); err != nil {
  4327  			t.Fatalf("Error during reload: %v", err)
  4328  		}
  4329  	}
  4330  
  4331  	traffic := func(cnt int) {
  4332  		t.Helper()
  4333  		// Create client and sub interest on server and create traffic
  4334  		urlSeed := fmt.Sprintf("nats://bar:pwd@%s:%d/", opts.Host, opts.Port)
  4335  		nc, err := nats.Connect(urlSeed)
  4336  		if err != nil {
  4337  			t.Fatalf("Error creating client: %v\n", err)
  4338  		}
  4339  		defer nc.Close()
  4340  
  4341  		msgs := make(chan *nats.Msg, 1)
  4342  		defer close(msgs)
  4343  
  4344  		sub, err := nc.ChanSubscribe("foo", msgs)
  4345  		if err != nil {
  4346  			t.Fatalf("Error creating subscriber: %v\n", err)
  4347  		}
  4348  
  4349  		nc.Flush()
  4350  
  4351  		for i := 0; i < cnt; i++ {
  4352  			if err := nc.Publish("foo", []byte("bar")); err == nil {
  4353  				<-msgs
  4354  			}
  4355  		}
  4356  
  4357  		sub.Unsubscribe()
  4358  		nc.Close()
  4359  	}
  4360  
  4361  	reload("log_file: off-pre.log")
  4362  
  4363  	traffic(10) // generate NO trace/debug entries in off-pre.log
  4364  
  4365  	reload(`
  4366  		log_file: on.log
  4367  		debug: true
  4368  		trace_verbose: true
  4369  	`)
  4370  
  4371  	traffic(10) // generate trace/debug entries in on.log
  4372  
  4373  	reload(`
  4374  		log_file: off-post.log
  4375  		debug: false
  4376  		trace_verbose: false
  4377  	`)
  4378  
  4379  	traffic(10) // generate trace/debug entries in off-post.log
  4380  
  4381  	// check resulting log files for expected content
  4382  	check("off-pre.log", tracingAbsent)
  4383  	check("on.log", tracingPresent)
  4384  	check("off-post.log", tracingAbsent)
  4385  }
  4386  
  4387  func TestConfigReloadValidate(t *testing.T) {
  4388  	confFileName := createConfFile(t, []byte(`
  4389  		listen: "127.0.0.1:-1"
  4390  		no_auth_user: a
  4391  		authorization {
  4392  			users [
  4393  				{user: "a", password: "a"},
  4394  				{user: "b", password: "b"}
  4395  			]
  4396  		}
  4397  	`))
  4398  	srv, _ := RunServerWithConfig(confFileName)
  4399  	if srv == nil {
  4400  		t.Fatal("Server did not start")
  4401  	}
  4402  	// Induce error by removing the user no_auth_user points to
  4403  	changeCurrentConfigContentWithNewContent(t, confFileName, []byte(`
  4404  		listen: "127.0.0.1:-1"
  4405  		no_auth_user: a
  4406  		authorization {
  4407  			users [
  4408  				{user: "b", password: "b"}
  4409  			]
  4410  		}
  4411  	`))
  4412  	if err := srv.Reload(); err == nil {
  4413  		t.Fatal("Expected error on reload, got none")
  4414  	} else if strings.HasPrefix(err.Error(), " no_auth_user:") {
  4415  		t.Logf("Expected no_auth_user error, got different one %s", err)
  4416  	}
  4417  	srv.Shutdown()
  4418  }
  4419  
  4420  func TestConfigReloadAccounts(t *testing.T) {
  4421  	conf := createConfFile(t, []byte(`
  4422  	listen: "127.0.0.1:-1"
  4423  	system_account: SYS
  4424  	accounts {
  4425  		SYS {
  4426  			users = [
  4427  				{user: sys, password: pwd}
  4428  			]
  4429  		}
  4430  		ACC {
  4431  			users = [
  4432  				{user: usr, password: pwd}
  4433  			]
  4434  		}
  4435  		acc_deleted_after_reload_will_trigger_reload_of_all_accounts {
  4436  			users = [
  4437  				{user: notused, password: soon}
  4438  			]
  4439  		}
  4440  	}
  4441  	`))
  4442  	s, o := RunServerWithConfig(conf)
  4443  	defer s.Shutdown()
  4444  
  4445  	urlSys := fmt.Sprintf("nats://sys:pwd@%s:%d", o.Host, o.Port)
  4446  	urlUsr := fmt.Sprintf("nats://usr:pwd@%s:%d", o.Host, o.Port)
  4447  	oldAcci, ok := s.accounts.Load("SYS")
  4448  	if !ok {
  4449  		t.Fatal("No SYS account")
  4450  	}
  4451  	oldAcc := oldAcci.(*Account)
  4452  
  4453  	testSrvState := func(oldAcc *Account) {
  4454  		t.Helper()
  4455  		sysAcc := s.SystemAccount()
  4456  		s.mu.Lock()
  4457  		defer s.mu.Unlock()
  4458  		if s.sys == nil || sysAcc == nil {
  4459  			t.Fatal("Expected sys.account to be non-nil")
  4460  		}
  4461  		if sysAcc.Name != "SYS" {
  4462  			t.Fatal("Found wrong sys.account")
  4463  		}
  4464  		if s.opts.SystemAccount != "SYS" {
  4465  			t.Fatal("Found wrong sys.account")
  4466  		}
  4467  		ai, ok := s.accounts.Load(s.opts.SystemAccount)
  4468  		if !ok {
  4469  			t.Fatalf("System account %q not found in s.accounts map", s.opts.SystemAccount)
  4470  		}
  4471  		acc := ai.(*Account)
  4472  		if acc != oldAcc {
  4473  			t.Fatalf("System account pointer was changed during reload, was %p now %p", oldAcc, acc)
  4474  		}
  4475  		if s.sys.client == nil {
  4476  			t.Fatal("Expected sys.client to be non-nil")
  4477  		}
  4478  		s.sys.client.mu.Lock()
  4479  		defer s.sys.client.mu.Unlock()
  4480  		if s.sys.client.acc.Name != "SYS" {
  4481  			t.Fatal("Found wrong sys.account")
  4482  		}
  4483  		if s.sys.client.echo {
  4484  			t.Fatal("Internal clients should always have echo false")
  4485  		}
  4486  		s.sys.account.mu.Lock()
  4487  		if _, ok := s.sys.account.clients[s.sys.client]; !ok {
  4488  			s.sys.account.mu.Unlock()
  4489  			t.Fatal("internal client not present")
  4490  		}
  4491  		s.sys.account.mu.Unlock()
  4492  	}
  4493  
  4494  	// Below tests use connection names so that they can be checked for.
  4495  	// The test subscribes to ACC only. This avoids receiving own messages.
  4496  	subscribe := func(name string) (*nats.Conn, *nats.Subscription, *nats.Subscription) {
  4497  		t.Helper()
  4498  		c, err := nats.Connect(urlSys, nats.Name(name))
  4499  		if err != nil {
  4500  			t.Fatalf("Error on connect: %v", err)
  4501  		}
  4502  		subCon, err := c.SubscribeSync("$SYS.ACCOUNT.ACC.CONNECT")
  4503  		if err != nil {
  4504  			t.Fatalf("Error on subscribe CONNECT: %v", err)
  4505  		}
  4506  		subDis, err := c.SubscribeSync("$SYS.ACCOUNT.ACC.DISCONNECT")
  4507  		if err != nil {
  4508  			t.Fatalf("Error on subscribe DISCONNECT: %v", err)
  4509  		}
  4510  		c.Flush()
  4511  		return c, subCon, subDis
  4512  	}
  4513  	recv := func(name string, sub *nats.Subscription) {
  4514  		t.Helper()
  4515  		if msg, err := sub.NextMsg(1 * time.Second); err != nil {
  4516  			t.Fatalf("%s Error on next: %v", name, err)
  4517  		} else {
  4518  			cMsg := ConnectEventMsg{}
  4519  			json.Unmarshal(msg.Data, &cMsg)
  4520  			if cMsg.Client.Name != name {
  4521  				t.Fatalf("%s wrong message: %s", name, string(msg.Data))
  4522  			}
  4523  		}
  4524  	}
  4525  	triggerSysEvent := func(name string, subs []*nats.Subscription) {
  4526  		t.Helper()
  4527  		ncs1, err := nats.Connect(urlUsr, nats.Name(name))
  4528  		if err != nil {
  4529  			t.Fatalf("Error on connect: %v", err)
  4530  		}
  4531  		ncs1.Close()
  4532  		for _, sub := range subs {
  4533  			recv(name, sub)
  4534  			// Make sure they are empty.
  4535  			if pending, _, _ := sub.Pending(); pending != 0 {
  4536  				t.Fatalf("Expected no pending, got %d for %+v", pending, sub)
  4537  			}
  4538  		}
  4539  	}
  4540  
  4541  	testSrvState(oldAcc)
  4542  	c1, s1C, s1D := subscribe("SYS1")
  4543  	defer c1.Close()
  4544  	defer s1C.Unsubscribe()
  4545  	defer s1D.Unsubscribe()
  4546  	triggerSysEvent("BEFORE1", []*nats.Subscription{s1C, s1D})
  4547  	triggerSysEvent("BEFORE2", []*nats.Subscription{s1C, s1D})
  4548  
  4549  	// Remove account to trigger account reload
  4550  	reloadUpdateConfig(t, s, conf, `
  4551  	listen: "127.0.0.1:-1"
  4552  	system_account: SYS
  4553  	accounts {
  4554  		SYS {
  4555  			users = [
  4556  				{user: sys, password: pwd}
  4557  			]
  4558  		}
  4559  		ACC {
  4560  			users = [
  4561  				{user: usr, password: pwd}
  4562  			]
  4563  		}
  4564  	}
  4565  	`)
  4566  
  4567  	testSrvState(oldAcc)
  4568  	c2, s2C, s2D := subscribe("SYS2")
  4569  	defer c2.Close()
  4570  	defer s2C.Unsubscribe()
  4571  	defer s2D.Unsubscribe()
  4572  	// test new and existing subscriptions
  4573  	triggerSysEvent("AFTER1", []*nats.Subscription{s1C, s1D, s2C, s2D})
  4574  	triggerSysEvent("AFTER2", []*nats.Subscription{s1C, s1D, s2C, s2D})
  4575  }
  4576  
  4577  func TestConfigReloadDefaultSystemAccount(t *testing.T) {
  4578  	conf := createConfFile(t, []byte(`
  4579  	listen: "127.0.0.1:-1"
  4580  	accounts {
  4581  		ACC {
  4582  			users = [
  4583  				{user: usr, password: pwd}
  4584  			]
  4585  		}
  4586  	}
  4587  	`))
  4588  	s, _ := RunServerWithConfig(conf)
  4589  	defer s.Shutdown()
  4590  
  4591  	sysAcc := s.SystemAccount()
  4592  	if sysAcc == nil {
  4593  		t.Fatalf("Expected system account to be present")
  4594  	}
  4595  	numSubs := sysAcc.TotalSubs()
  4596  
  4597  	sname := sysAcc.GetName()
  4598  	testInAccounts := func() {
  4599  		t.Helper()
  4600  		var found bool
  4601  		s.accounts.Range(func(k, v interface{}) bool {
  4602  			acc := v.(*Account)
  4603  			if acc.GetName() == sname {
  4604  				found = true
  4605  				return false
  4606  			}
  4607  			return true
  4608  		})
  4609  		if !found {
  4610  			t.Fatalf("System account not found in accounts list")
  4611  		}
  4612  	}
  4613  	testInAccounts()
  4614  
  4615  	if err := s.Reload(); err != nil {
  4616  		t.Fatalf("Unexpected error reloading: %v", err)
  4617  	}
  4618  
  4619  	sysAcc = s.SystemAccount()
  4620  	if sysAcc == nil {
  4621  		t.Fatalf("Expected system account to still be present")
  4622  	}
  4623  	if sysAcc.TotalSubs() != numSubs {
  4624  		t.Fatalf("Expected %d subs, got %d", numSubs, sysAcc.TotalSubs())
  4625  	}
  4626  	testInAccounts()
  4627  }
  4628  
  4629  func TestConfigReloadAccountMappings(t *testing.T) {
  4630  	conf := createConfFile(t, []byte(`
  4631  	listen: "127.0.0.1:-1"
  4632  	accounts {
  4633  		ACC {
  4634  			users = [{user: usr, password: pwd}]
  4635  			mappings = { foo: bar }
  4636  		}
  4637  	}
  4638  	`))
  4639  	s, opts := RunServerWithConfig(conf)
  4640  	defer s.Shutdown()
  4641  
  4642  	reloadUpdateConfig(t, s, conf, `
  4643  	listen: "127.0.0.1:-1"
  4644  	accounts {
  4645  		ACC {
  4646  			users = [{user: usr, password: pwd}]
  4647  			mappings = { foo: baz }
  4648  		}
  4649  	}
  4650  	`)
  4651  
  4652  	nc := natsConnect(t, fmt.Sprintf("nats://usr:pwd@%s:%d", opts.Host, opts.Port))
  4653  	defer nc.Close()
  4654  
  4655  	fsub, _ := nc.SubscribeSync("foo")
  4656  	sub, _ := nc.SubscribeSync("baz")
  4657  	nc.Publish("foo", nil)
  4658  	nc.Flush()
  4659  
  4660  	checkPending := func(sub *nats.Subscription, expected int) {
  4661  		t.Helper()
  4662  		if n, _, _ := sub.Pending(); n != expected {
  4663  			t.Fatalf("Expected %d msgs for %q, but got %d", expected, sub.Subject, n)
  4664  		}
  4665  	}
  4666  	checkPending(fsub, 0)
  4667  	checkPending(sub, 1)
  4668  
  4669  	// Drain it off
  4670  	if _, err := sub.NextMsg(2 * time.Second); err != nil {
  4671  		t.Fatalf("Error receiving msg: %v", err)
  4672  	}
  4673  
  4674  	reloadUpdateConfig(t, s, conf, `
  4675  	listen: "127.0.0.1:-1"
  4676  	accounts {
  4677  		ACC {
  4678  			users = [{user: usr, password: pwd}]
  4679  		}
  4680  	}
  4681  	`)
  4682  
  4683  	nc.Publish("foo", nil)
  4684  	nc.Flush()
  4685  
  4686  	checkPending(fsub, 1)
  4687  	checkPending(sub, 0)
  4688  }
  4689  
  4690  func TestConfigReloadWithSysAccountOnly(t *testing.T) {
  4691  	conf := createConfFile(t, []byte(`
  4692  		listen: "127.0.0.1:-1"
  4693  		accounts {
  4694  			$SYS {
  4695  				users = [{user: "system",pass: "password"}, {user: "system2",pass: "password2"}]
  4696  			}
  4697  		}
  4698  	`))
  4699  	defer os.Remove(conf)
  4700  	s, _ := RunServerWithConfig(conf)
  4701  	defer s.Shutdown()
  4702  
  4703  	dch := make(chan struct{}, 1)
  4704  	nc := natsConnect(t,
  4705  		s.ClientURL(),
  4706  		nats.DisconnectErrHandler(func(_ *nats.Conn, _ error) {
  4707  			dch <- struct{}{}
  4708  		}),
  4709  		nats.NoCallbacksAfterClientClose())
  4710  	defer nc.Close()
  4711  
  4712  	// Just reload...
  4713  	if err := s.Reload(); err != nil {
  4714  		t.Fatalf("Error on reload: %v", err)
  4715  	}
  4716  
  4717  	// Make sure we did not get disconnected
  4718  	select {
  4719  	case <-dch:
  4720  		t.Fatal("Got disconnected!")
  4721  	case <-time.After(500 * time.Millisecond):
  4722  		// ok
  4723  	}
  4724  }
  4725  
  4726  func TestConfigReloadRouteImportPermissionsWithAccounts(t *testing.T) {
  4727  	for _, test := range []struct {
  4728  		name     string
  4729  		poolSize string
  4730  		accounts string
  4731  	}{
  4732  		{"regular", "pool_size: -1", _EMPTY_},
  4733  		{"pooling", "pool_size: 5", _EMPTY_},
  4734  		{"per-account", _EMPTY_, "accounts: [\"A\"]"},
  4735  		{"pool and per-account", "pool_size: 3", "accounts: [\"A\"]"},
  4736  	} {
  4737  		t.Run("import "+test.name, func(t *testing.T) {
  4738  			confATemplate := `
  4739  				server_name: "A"
  4740  				port: -1
  4741  				accounts {
  4742  					A { users: [{user: "user1", password: "pwd"}] }
  4743  					B { users: [{user: "user2", password: "pwd"}] }
  4744  					C { users: [{user: "user3", password: "pwd"}] }
  4745  					D { users: [{user: "user4", password: "pwd"}] }
  4746  				}
  4747  				cluster {
  4748  					name: "local"
  4749  					listen: 127.0.0.1:-1
  4750  					permissions {
  4751  						import {
  4752  							allow: %s
  4753  						}
  4754  						export {
  4755  							allow: ">"
  4756  						}
  4757  					}
  4758  					%s
  4759  					%s
  4760  				}
  4761  			`
  4762  			confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `"foo"`, test.poolSize, test.accounts)))
  4763  			srva, optsA := RunServerWithConfig(confA)
  4764  			defer srva.Shutdown()
  4765  
  4766  			confBTemplate := `
  4767  				server_name: "B"
  4768  				port: -1
  4769  				accounts {
  4770  					A { users: [{user: "user1", password: "pwd"}] }
  4771  					B { users: [{user: "user2", password: "pwd"}] }
  4772  					C { users: [{user: "user3", password: "pwd"}] }
  4773  					D { users: [{user: "user4", password: "pwd"}] }
  4774  				}
  4775  				cluster {
  4776  					listen: 127.0.0.1:-1
  4777  					name: "local"
  4778  					permissions {
  4779  						import {
  4780  							allow: %s
  4781  						}
  4782  						export {
  4783  							allow: ">"
  4784  						}
  4785  					}
  4786  					routes = [
  4787  						"nats://127.0.0.1:%d"
  4788  					]
  4789  					%s
  4790  					%s
  4791  				}
  4792  			`
  4793  			confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, `"foo"`, optsA.Cluster.Port, test.poolSize, test.accounts)))
  4794  			srvb, _ := RunServerWithConfig(confB)
  4795  			defer srvb.Shutdown()
  4796  
  4797  			checkClusterFormed(t, srva, srvb)
  4798  
  4799  			ncA := natsConnect(t, srva.ClientURL(), nats.UserInfo("user1", "pwd"))
  4800  			defer ncA.Close()
  4801  
  4802  			sub1Foo := natsSubSync(t, ncA, "foo")
  4803  			sub2Foo := natsSubSync(t, ncA, "foo")
  4804  
  4805  			sub1Bar := natsSubSync(t, ncA, "bar")
  4806  			sub2Bar := natsSubSync(t, ncA, "bar")
  4807  
  4808  			natsFlush(t, ncA)
  4809  
  4810  			checkSubInterest(t, srvb, "A", "foo", 2*time.Second)
  4811  			checkSubNoInterest(t, srvb, "A", "bar", 2*time.Second)
  4812  
  4813  			ncB := natsConnect(t, srvb.ClientURL(), nats.UserInfo("user1", "pwd"))
  4814  			defer ncB.Close()
  4815  
  4816  			check := func(sub *nats.Subscription, expected bool) {
  4817  				t.Helper()
  4818  				if expected {
  4819  					natsNexMsg(t, sub, time.Second)
  4820  				} else {
  4821  					if msg, err := sub.NextMsg(50 * time.Millisecond); err == nil {
  4822  						t.Fatalf("Should not have gotten the message, got %s/%s", msg.Subject, msg.Data)
  4823  					}
  4824  				}
  4825  			}
  4826  
  4827  			// Should receive on "foo"
  4828  			natsPub(t, ncB, "foo", []byte("foo1"))
  4829  			check(sub1Foo, true)
  4830  			check(sub2Foo, true)
  4831  
  4832  			// But not on "bar"
  4833  			natsPub(t, ncB, "bar", []byte("bar1"))
  4834  			check(sub1Bar, false)
  4835  			check(sub2Bar, false)
  4836  
  4837  			reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"bar"`, test.poolSize, test.accounts))
  4838  			reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, `"bar"`, optsA.Cluster.Port, test.poolSize, test.accounts))
  4839  
  4840  			checkClusterFormed(t, srva, srvb)
  4841  
  4842  			checkSubNoInterest(t, srvb, "A", "foo", 2*time.Second)
  4843  			checkSubInterest(t, srvb, "A", "bar", 2*time.Second)
  4844  
  4845  			// Should not receive on foo
  4846  			natsPub(t, ncB, "foo", []byte("foo2"))
  4847  			check(sub1Foo, false)
  4848  			check(sub2Foo, false)
  4849  
  4850  			// Should be able to receive on bar
  4851  			natsPub(t, ncB, "bar", []byte("bar2"))
  4852  			check(sub1Bar, true)
  4853  			check(sub2Bar, true)
  4854  
  4855  			// Restore "foo"
  4856  			reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"foo"`, test.poolSize, test.accounts))
  4857  			reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, `"foo"`, optsA.Cluster.Port, test.poolSize, test.accounts))
  4858  
  4859  			checkClusterFormed(t, srva, srvb)
  4860  
  4861  			checkSubInterest(t, srvb, "A", "foo", 2*time.Second)
  4862  			checkSubNoInterest(t, srvb, "A", "bar", 2*time.Second)
  4863  
  4864  			// Should receive on "foo"
  4865  			natsPub(t, ncB, "foo", []byte("foo3"))
  4866  			check(sub1Foo, true)
  4867  			check(sub2Foo, true)
  4868  			// But make sure there are no more than what we expect
  4869  			check(sub1Foo, false)
  4870  			check(sub2Foo, false)
  4871  
  4872  			// And now "bar" should fail
  4873  			natsPub(t, ncB, "bar", []byte("bar3"))
  4874  			check(sub1Bar, false)
  4875  			check(sub2Bar, false)
  4876  		})
  4877  	}
  4878  	// Check export now
  4879  	for _, test := range []struct {
  4880  		name     string
  4881  		poolSize string
  4882  		accounts string
  4883  	}{
  4884  		{"regular", "pool_size: -1", _EMPTY_},
  4885  		{"pooling", "pool_size: 5", _EMPTY_},
  4886  		{"per-account", _EMPTY_, "accounts: [\"A\"]"},
  4887  		{"pool and per-account", "pool_size: 3", "accounts: [\"A\"]"},
  4888  	} {
  4889  		t.Run("export "+test.name, func(t *testing.T) {
  4890  			confATemplate := `
  4891  				server_name: "A"
  4892  				port: -1
  4893  				accounts {
  4894  					A { users: [{user: "user1", password: "pwd"}] }
  4895  					B { users: [{user: "user2", password: "pwd"}] }
  4896  					C { users: [{user: "user3", password: "pwd"}] }
  4897  					D { users: [{user: "user4", password: "pwd"}] }
  4898  				}
  4899  				cluster {
  4900  					name: "local"
  4901  					listen: 127.0.0.1:-1
  4902  					permissions {
  4903  						import {
  4904  							allow: ">"
  4905  						}
  4906  						export {
  4907  							allow: %s
  4908  						}
  4909  					}
  4910  					%s
  4911  					%s
  4912  				}
  4913  			`
  4914  			confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, `"foo"`, test.poolSize, test.accounts)))
  4915  			srva, optsA := RunServerWithConfig(confA)
  4916  			defer srva.Shutdown()
  4917  
  4918  			confBTemplate := `
  4919  				server_name: "B"
  4920  				port: -1
  4921  				accounts {
  4922  					A { users: [{user: "user1", password: "pwd"}] }
  4923  					B { users: [{user: "user2", password: "pwd"}] }
  4924  					C { users: [{user: "user3", password: "pwd"}] }
  4925  					D { users: [{user: "user4", password: "pwd"}] }
  4926  				}
  4927  				cluster {
  4928  					listen: 127.0.0.1:-1
  4929  					name: "local"
  4930  					permissions {
  4931  						import {
  4932  							allow: ">"
  4933  						}
  4934  						export {
  4935  							allow: %s
  4936  						}
  4937  					}
  4938  					routes = [
  4939  						"nats://127.0.0.1:%d"
  4940  					]
  4941  					%s
  4942  					%s
  4943  				}
  4944  			`
  4945  			confB := createConfFile(t, []byte(fmt.Sprintf(confBTemplate, `"foo"`, optsA.Cluster.Port, test.poolSize, test.accounts)))
  4946  			srvb, _ := RunServerWithConfig(confB)
  4947  			defer srvb.Shutdown()
  4948  
  4949  			checkClusterFormed(t, srva, srvb)
  4950  
  4951  			ncA := natsConnect(t, srva.ClientURL(), nats.UserInfo("user1", "pwd"))
  4952  			defer ncA.Close()
  4953  
  4954  			sub1Foo := natsSubSync(t, ncA, "foo")
  4955  			sub2Foo := natsSubSync(t, ncA, "foo")
  4956  
  4957  			sub1Bar := natsSubSync(t, ncA, "bar")
  4958  			sub2Bar := natsSubSync(t, ncA, "bar")
  4959  
  4960  			natsFlush(t, ncA)
  4961  
  4962  			checkSubInterest(t, srvb, "A", "foo", 2*time.Second)
  4963  			checkSubNoInterest(t, srvb, "A", "bar", 2*time.Second)
  4964  
  4965  			ncB := natsConnect(t, srvb.ClientURL(), nats.UserInfo("user1", "pwd"))
  4966  			defer ncB.Close()
  4967  
  4968  			check := func(sub *nats.Subscription, expected bool) {
  4969  				t.Helper()
  4970  				if expected {
  4971  					natsNexMsg(t, sub, time.Second)
  4972  				} else {
  4973  					if msg, err := sub.NextMsg(50 * time.Millisecond); err == nil {
  4974  						t.Fatalf("Should not have gotten the message, got %s/%s", msg.Subject, msg.Data)
  4975  					}
  4976  				}
  4977  			}
  4978  
  4979  			// Should receive on "foo"
  4980  			natsPub(t, ncB, "foo", []byte("foo1"))
  4981  			check(sub1Foo, true)
  4982  			check(sub2Foo, true)
  4983  
  4984  			// But not on "bar"
  4985  			natsPub(t, ncB, "bar", []byte("bar1"))
  4986  			check(sub1Bar, false)
  4987  			check(sub2Bar, false)
  4988  
  4989  			reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `["foo", "bar"]`, test.poolSize, test.accounts))
  4990  			reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, `["foo", "bar"]`, optsA.Cluster.Port, test.poolSize, test.accounts))
  4991  
  4992  			checkClusterFormed(t, srva, srvb)
  4993  
  4994  			checkSubInterest(t, srvb, "A", "foo", 2*time.Second)
  4995  			checkSubInterest(t, srvb, "A", "bar", 2*time.Second)
  4996  
  4997  			// Should receive on foo and bar
  4998  			natsPub(t, ncB, "foo", []byte("foo2"))
  4999  			check(sub1Foo, true)
  5000  			check(sub2Foo, true)
  5001  
  5002  			natsPub(t, ncB, "bar", []byte("bar2"))
  5003  			check(sub1Bar, true)
  5004  			check(sub2Bar, true)
  5005  
  5006  			// Remove "bar"
  5007  			reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, `"foo"`, test.poolSize, test.accounts))
  5008  			reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBTemplate, `"foo"`, optsA.Cluster.Port, test.poolSize, test.accounts))
  5009  
  5010  			checkClusterFormed(t, srva, srvb)
  5011  
  5012  			checkSubInterest(t, srvb, "A", "foo", 2*time.Second)
  5013  			checkSubNoInterest(t, srvb, "A", "bar", 2*time.Second)
  5014  
  5015  			// Should receive on "foo"
  5016  			natsPub(t, ncB, "foo", []byte("foo3"))
  5017  			check(sub1Foo, true)
  5018  			check(sub2Foo, true)
  5019  			// But make sure there are no more than what we expect
  5020  			check(sub1Foo, false)
  5021  			check(sub2Foo, false)
  5022  
  5023  			// And now "bar" should fail
  5024  			natsPub(t, ncB, "bar", []byte("bar3"))
  5025  			check(sub1Bar, false)
  5026  			check(sub2Bar, false)
  5027  		})
  5028  	}
  5029  }
  5030  
  5031  func TestConfigReloadRoutePoolAndPerAccount(t *testing.T) {
  5032  	confATemplate := `
  5033  		port: -1
  5034  		server_name: "A"
  5035  		accounts {
  5036  				A { users: [{user: "user1", password: "pwd"}] }
  5037  				B { users: [{user: "user2", password: "pwd"}] }
  5038  				C { users: [{user: "user3", password: "pwd"}] }
  5039  				D { users: [{user: "user4", password: "pwd"}] }
  5040  		}
  5041  		cluster {
  5042  				name: "local"
  5043  				listen: 127.0.0.1:-1
  5044  				%s
  5045  				%s
  5046  		}
  5047  	`
  5048  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, "pool_size: 3", "accounts: [\"A\"]")))
  5049  	srva, optsA := RunServerWithConfig(confA)
  5050  	defer srva.Shutdown()
  5051  
  5052  	confBCTemplate := `
  5053  		port: -1
  5054  		server_name: "%s"
  5055  		accounts {
  5056  				A { users: [{user: "user1", password: "pwd"}] }
  5057  				B { users: [{user: "user2", password: "pwd"}] }
  5058  				C { users: [{user: "user3", password: "pwd"}] }
  5059  				D { users: [{user: "user4", password: "pwd"}] }
  5060  		}
  5061  		cluster {
  5062  				listen: 127.0.0.1:-1
  5063  				name: "local"
  5064  				routes = [
  5065  						"nats://127.0.0.1:%d"
  5066  				]
  5067  				%s
  5068  				%s
  5069  		}
  5070  	`
  5071  	confB := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\"]")))
  5072  	srvb, _ := RunServerWithConfig(confB)
  5073  	defer srvb.Shutdown()
  5074  	confC := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\"]")))
  5075  	srvc, _ := RunServerWithConfig(confC)
  5076  	defer srvc.Shutdown()
  5077  
  5078  	checkClusterFormed(t, srva, srvb, srvc)
  5079  
  5080  	// We will also create subscriptions for accounts A, B and C on all sides
  5081  	// just to make sure that interest is properly propagated after a reload.
  5082  	// The conns slices will contain connections for accounts A on srva, srvb,
  5083  	// srvc, then B on srva, srvb, etc.. and the subs slices will contain
  5084  	// subscriptions for account A on foo on srva, bar on srvb, baz on srvc,
  5085  	// then for account B on foo on srva, etc...
  5086  	var conns []*nats.Conn
  5087  	var subs []*nats.Subscription
  5088  	for _, user := range []string{"user1", "user2", "user3"} {
  5089  		nc := natsConnect(t, srva.ClientURL(), nats.UserInfo(user, "pwd"))
  5090  		defer nc.Close()
  5091  		conns = append(conns, nc)
  5092  		sub := natsSubSync(t, nc, "foo")
  5093  		subs = append(subs, sub)
  5094  		nc = natsConnect(t, srvb.ClientURL(), nats.UserInfo(user, "pwd"))
  5095  		defer nc.Close()
  5096  		conns = append(conns, nc)
  5097  		sub = natsSubSync(t, nc, "bar")
  5098  		subs = append(subs, sub)
  5099  		nc = natsConnect(t, srvc.ClientURL(), nats.UserInfo(user, "pwd"))
  5100  		defer nc.Close()
  5101  		conns = append(conns, nc)
  5102  		sub = natsSubSync(t, nc, "baz")
  5103  		subs = append(subs, sub)
  5104  	}
  5105  
  5106  	checkCluster := func() {
  5107  		t.Helper()
  5108  		checkClusterFormed(t, srva, srvb, srvc)
  5109  
  5110  		for _, acc := range []string{"A", "B", "C"} {
  5111  			// On server A, there should be interest for bar/baz
  5112  			checkSubInterest(t, srva, acc, "bar", 2*time.Second)
  5113  			checkSubInterest(t, srva, acc, "baz", 2*time.Second)
  5114  			// On serer B, there should be interest on foo/baz
  5115  			checkSubInterest(t, srvb, acc, "foo", 2*time.Second)
  5116  			checkSubInterest(t, srvb, acc, "baz", 2*time.Second)
  5117  			// And on server C, interest on foo/bar
  5118  			checkSubInterest(t, srvc, acc, "foo", 2*time.Second)
  5119  			checkSubInterest(t, srvc, acc, "bar", 2*time.Second)
  5120  		}
  5121  	}
  5122  	checkCluster()
  5123  
  5124  	getAccRouteID := func(acc string) uint64 {
  5125  		s := srva
  5126  		var id uint64
  5127  		srvbId := srvb.ID()
  5128  		s.mu.RLock()
  5129  		if remotes, ok := s.accRoutes[acc]; ok {
  5130  			// For this test, we will take a single remote, say srvb
  5131  			if r := remotes[srvbId]; r != nil {
  5132  				r.mu.Lock()
  5133  				if string(r.route.accName) == acc {
  5134  					id = r.cid
  5135  				}
  5136  				r.mu.Unlock()
  5137  			}
  5138  		}
  5139  		s.mu.RUnlock()
  5140  		return id
  5141  	}
  5142  	// Capture the route for account "A"
  5143  	raid := getAccRouteID("A")
  5144  	if raid == 0 {
  5145  		t.Fatal("Did not find route for account A")
  5146  	}
  5147  
  5148  	getRouteIDForAcc := func(acc string) uint64 {
  5149  		s := srva
  5150  		a, _ := s.LookupAccount(acc)
  5151  		if a == nil {
  5152  			return 0
  5153  		}
  5154  		a.mu.RLock()
  5155  		pidx := a.routePoolIdx
  5156  		a.mu.RUnlock()
  5157  		var id uint64
  5158  		s.mu.RLock()
  5159  		// For this test, we will take a single remote, say srvb
  5160  		srvbId := srvb.ID()
  5161  		if conns, ok := s.routes[srvbId]; ok {
  5162  			if r := conns[pidx]; r != nil {
  5163  				r.mu.Lock()
  5164  				id = r.cid
  5165  				r.mu.Unlock()
  5166  			}
  5167  		}
  5168  		s.mu.RUnlock()
  5169  		return id
  5170  	}
  5171  	rbid := getRouteIDForAcc("B")
  5172  	if rbid == 0 {
  5173  		t.Fatal("Did not find route for account B")
  5174  	}
  5175  	rcid := getRouteIDForAcc("C")
  5176  	if rcid == 0 {
  5177  		t.Fatal("Did not find route for account C")
  5178  	}
  5179  	rdid := getRouteIDForAcc("D")
  5180  	if rdid == 0 {
  5181  		t.Fatal("Did not find route for account D")
  5182  	}
  5183  
  5184  	sendAndRecv := func(msg string) {
  5185  		t.Helper()
  5186  		for accIdx := 0; accIdx < 9; accIdx += 3 {
  5187  			natsPub(t, conns[accIdx], "bar", []byte(msg))
  5188  			m := natsNexMsg(t, subs[accIdx+1], time.Second)
  5189  			checkMsg := func(m *nats.Msg, subj string) {
  5190  				t.Helper()
  5191  				if string(m.Data) != msg {
  5192  					t.Fatalf("For accIdx=%v, subject %q, expected message %q, got %q", accIdx, subj, msg, m.Data)
  5193  				}
  5194  			}
  5195  			checkMsg(m, "bar")
  5196  			natsPub(t, conns[accIdx+1], "baz", []byte(msg))
  5197  			m = natsNexMsg(t, subs[accIdx+2], time.Second)
  5198  			checkMsg(m, "baz")
  5199  			natsPub(t, conns[accIdx+2], "foo", []byte(msg))
  5200  			m = natsNexMsg(t, subs[accIdx], time.Second)
  5201  			checkMsg(m, "foo")
  5202  		}
  5203  	}
  5204  	sendAndRecv("0")
  5205  
  5206  	// Now add accounts "B" and "D" and do a config reload.
  5207  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 3", "accounts: [\"A\",\"B\",\"D\"]"))
  5208  
  5209  	// Even before reloading srvb and srvc, we should already have per-account
  5210  	// routes for accounts B and D being established. The accounts routePoolIdx
  5211  	// should be marked as transitioning.
  5212  	checkAccPoolIdx := func(s *Server, acc string, expected int) {
  5213  		t.Helper()
  5214  		checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  5215  			s.mu.RLock()
  5216  			defer s.mu.RUnlock()
  5217  			if a, ok := s.accounts.Load(acc); ok {
  5218  				acc := a.(*Account)
  5219  				acc.mu.RLock()
  5220  				rpi := acc.routePoolIdx
  5221  				acc.mu.RUnlock()
  5222  				if rpi != expected {
  5223  					return fmt.Errorf("Server %q - Account %q routePoolIdx should be %v, but is %v", s, acc, expected, rpi)
  5224  				}
  5225  				return nil
  5226  			}
  5227  			return fmt.Errorf("Server %q - Account %q not found", s, acc)
  5228  		})
  5229  	}
  5230  	checkRoutePerAccAlreadyEstablished := func(s *Server, acc string) {
  5231  		t.Helper()
  5232  		checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  5233  			s.mu.RLock()
  5234  			defer s.mu.RUnlock()
  5235  			if _, ok := s.accRoutes[acc]; !ok {
  5236  				return fmt.Errorf("Route for account %q still not established", acc)
  5237  			}
  5238  			return nil
  5239  		})
  5240  		checkAccPoolIdx(s, acc, accTransitioningToDedicatedRoute)
  5241  	}
  5242  	// Check srvb and srvc for both accounts.
  5243  	for _, s := range []*Server{srvb, srvc} {
  5244  		for _, acc := range []string{"B", "D"} {
  5245  			checkRoutePerAccAlreadyEstablished(s, acc)
  5246  		}
  5247  	}
  5248  	// On srva, the accounts should already have their routePoolIdx set to
  5249  	// the accDedicatedRoute value.
  5250  	for _, acc := range []string{"B", "D"} {
  5251  		checkAccPoolIdx(srva, acc, accDedicatedRoute)
  5252  	}
  5253  	// Now reload the other servers
  5254  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\",\"B\",\"D\"]"))
  5255  	reloadUpdateConfig(t, srvc, confC, fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\",\"B\",\"D\"]"))
  5256  
  5257  	checkCluster()
  5258  	// Now check that the accounts B and D are no longer transitioning
  5259  	for _, s := range []*Server{srva, srvb, srvc} {
  5260  		for _, acc := range []string{"B", "D"} {
  5261  			checkAccPoolIdx(s, acc, accDedicatedRoute)
  5262  		}
  5263  	}
  5264  
  5265  	checkRouteForADidNotChange := func() {
  5266  		t.Helper()
  5267  		if id := getAccRouteID("A"); id != raid {
  5268  			t.Fatalf("Route id for account 'A' was %d, is now %d", raid, id)
  5269  		}
  5270  	}
  5271  	// Verify that the route for account "A" did not change.
  5272  	checkRouteForADidNotChange()
  5273  
  5274  	// Verify that account "B" has now its own route
  5275  	if id := getAccRouteID("B"); id == 0 {
  5276  		t.Fatal("Did not find route for account B")
  5277  	}
  5278  	// Same for "D".
  5279  	if id := getAccRouteID("D"); id == 0 {
  5280  		t.Fatal("Did not find route for account D")
  5281  	}
  5282  
  5283  	checkRouteStillPresent := func(id uint64) {
  5284  		t.Helper()
  5285  		srva.mu.RLock()
  5286  		defer srva.mu.RUnlock()
  5287  		srvbId := srvb.ID()
  5288  		for _, r := range srva.routes[srvbId] {
  5289  			if r != nil {
  5290  				r.mu.Lock()
  5291  				found := r.cid == id
  5292  				r.mu.Unlock()
  5293  				if found {
  5294  					return
  5295  				}
  5296  			}
  5297  		}
  5298  		t.Fatalf("Route id %v has been disconnected", id)
  5299  	}
  5300  	// Verify that routes that were dealing with "B", and "D" were not disconnected.
  5301  	// Of course, since "C" was not involved, that route should still be present too.
  5302  	checkRouteStillPresent(rbid)
  5303  	checkRouteStillPresent(rcid)
  5304  	checkRouteStillPresent(rdid)
  5305  
  5306  	sendAndRecv("1")
  5307  
  5308  	// Now remove "B" and "D" and verify that route for "A" did not change.
  5309  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 3", "accounts: [\"A\"]"))
  5310  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\"]"))
  5311  	reloadUpdateConfig(t, srvc, confC, fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\"]"))
  5312  
  5313  	checkCluster()
  5314  
  5315  	// Verify that the route for account "A" did not change.
  5316  	checkRouteForADidNotChange()
  5317  
  5318  	// Verify that there is no dedicated route for account "B"
  5319  	if id := getAccRouteID("B"); id != 0 {
  5320  		t.Fatal("Should not have found a route for account B")
  5321  	}
  5322  	// It should instead be in one of the pooled route, and same
  5323  	// than it was before.
  5324  	if id := getRouteIDForAcc("B"); id != rbid {
  5325  		t.Fatalf("Account B's route was %d, it is now %d", rbid, id)
  5326  	}
  5327  	// Same for "D"
  5328  	if id := getAccRouteID("D"); id != 0 {
  5329  		t.Fatal("Should not have found a route for account D")
  5330  	}
  5331  	if id := getRouteIDForAcc("D"); id != rdid {
  5332  		t.Fatalf("Account D's route was %d, it is now %d", rdid, id)
  5333  	}
  5334  
  5335  	sendAndRecv("2")
  5336  
  5337  	// Finally, change pool size and make sure that routes handling B, C and D
  5338  	// were disconnected/reconnected, and that A did not change.
  5339  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 5", "accounts: [\"A\"]"))
  5340  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 5", "accounts: [\"A\"]"))
  5341  	reloadUpdateConfig(t, srvc, confC, fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "pool_size: 5", "accounts: [\"A\"]"))
  5342  
  5343  	checkCluster()
  5344  
  5345  	checkRouteForADidNotChange()
  5346  
  5347  	checkRouteDisconnected := func(acc string, oldID uint64) {
  5348  		t.Helper()
  5349  		if id := getRouteIDForAcc(acc); id == oldID {
  5350  			t.Fatalf("Route that was handling account %q did not change", acc)
  5351  		}
  5352  	}
  5353  	checkRouteDisconnected("B", rbid)
  5354  	checkRouteDisconnected("C", rcid)
  5355  	checkRouteDisconnected("D", rdid)
  5356  
  5357  	sendAndRecv("3")
  5358  
  5359  	// Now check that there were no duplicates and that all subs have 0 pending messages.
  5360  	for i, sub := range subs {
  5361  		if n, _, _ := sub.Pending(); n != 0 {
  5362  			t.Fatalf("Expected 0 pending messages, got %v for accIdx=%d sub=%q", n, i, sub.Subject)
  5363  		}
  5364  	}
  5365  }
  5366  
  5367  func TestConfigReloadRoutePoolCannotBeDisabledIfAccountsPresent(t *testing.T) {
  5368  	tmpl := `
  5369  		port: -1
  5370  		server_name: "%s"
  5371  		accounts {
  5372  			A { users: [{user: "user1", password: "pwd"}] }
  5373  			B { users: [{user: "user2", password: "pwd"}] }
  5374  		}
  5375  		cluster {
  5376  				name: "local"
  5377  				listen: 127.0.0.1:-1
  5378  				%s
  5379  				%s
  5380  				%s
  5381  		}
  5382  	`
  5383  	conf1 := createConfFile(t, []byte(fmt.Sprintf(tmpl, "A", "accounts: [\"A\"]", _EMPTY_, _EMPTY_)))
  5384  	s1, o1 := RunServerWithConfig(conf1)
  5385  	defer s1.Shutdown()
  5386  
  5387  	conf2 := createConfFile(t, []byte(fmt.Sprintf(tmpl, "B", "accounts: [\"A\"]", _EMPTY_,
  5388  		fmt.Sprintf("routes: [\"nats://127.0.0.1:%d\"]", o1.Cluster.Port))))
  5389  	s2, _ := RunServerWithConfig(conf2)
  5390  	defer s2.Shutdown()
  5391  
  5392  	checkClusterFormed(t, s1, s2)
  5393  
  5394  	err := os.WriteFile(conf1, []byte(fmt.Sprintf(tmpl, "A", "accounts: [\"A\"]", "pool_size: -1", _EMPTY_)), 0666)
  5395  	require_NoError(t, err)
  5396  	if err := s1.Reload(); err == nil || !strings.Contains(err.Error(), "accounts") {
  5397  		t.Fatalf("Expected error regarding presence of accounts, got %v", err)
  5398  	}
  5399  
  5400  	// Now remove the accounts too and reload, this should work
  5401  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "pool_size: -1", _EMPTY_))
  5402  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", _EMPTY_, "pool_size: -1", fmt.Sprintf("routes: [\"nats://127.0.0.1:%d\"]", o1.Cluster.Port)))
  5403  	checkClusterFormed(t, s1, s2)
  5404  
  5405  	ncs2 := natsConnect(t, s2.ClientURL(), nats.UserInfo("user1", "pwd"))
  5406  	defer ncs2.Close()
  5407  	sub := natsSubSync(t, ncs2, "foo")
  5408  	checkSubInterest(t, s1, "A", "foo", time.Second)
  5409  
  5410  	ncs1 := natsConnect(t, s1.ClientURL(), nats.UserInfo("user1", "pwd"))
  5411  	defer ncs1.Close()
  5412  	natsPub(t, ncs1, "foo", []byte("hello"))
  5413  	natsNexMsg(t, sub, time.Second)
  5414  
  5415  	// Wait a bit and make sure there are no duplicates
  5416  	time.Sleep(50 * time.Millisecond)
  5417  	if n, _, _ := sub.Pending(); n != 0 {
  5418  		t.Fatalf("Expected no pending messages, got %v", n)
  5419  	}
  5420  
  5421  	// Finally, verify that the system account is no longer bound to
  5422  	// a dedicated route. For that matter, s.accRoutes should be nil.
  5423  	for _, s := range []*Server{s1, s2} {
  5424  		sys := s.SystemAccount()
  5425  		if sys == nil {
  5426  			t.Fatal("No system account found")
  5427  		}
  5428  		sys.mu.RLock()
  5429  		rpi := sys.routePoolIdx
  5430  		sys.mu.RUnlock()
  5431  		if rpi != 0 {
  5432  			t.Fatalf("Server %q - expected account's routePoolIdx to be 0, got %v", s, rpi)
  5433  		}
  5434  		s.mu.RLock()
  5435  		arNil := s.accRoutes == nil
  5436  		s.mu.RUnlock()
  5437  		if !arNil {
  5438  			t.Fatalf("Server %q - accRoutes expected to be nil, it was not", s)
  5439  		}
  5440  	}
  5441  }
  5442  
  5443  func TestConfigReloadRoutePoolAndPerAccountWithOlderServer(t *testing.T) {
  5444  	confATemplate := `
  5445  		port: -1
  5446  		server_name: "A"
  5447  		accounts {
  5448  				A { users: [{user: "user1", password: "pwd"}] }
  5449  		}
  5450  		cluster {
  5451  				name: "local"
  5452  				listen: 127.0.0.1:-1
  5453  				%s
  5454  				%s
  5455  		}
  5456  	`
  5457  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, "pool_size: 3", _EMPTY_)))
  5458  	srva, optsA := RunServerWithConfig(confA)
  5459  	defer srva.Shutdown()
  5460  
  5461  	confBCTemplate := `
  5462  		port: -1
  5463  		server_name: "%s"
  5464  		accounts {
  5465  				A { users: [{user: "user1", password: "pwd"}] }
  5466  		}
  5467  		cluster {
  5468  				listen: 127.0.0.1:-1
  5469  				name: "local"
  5470  				routes = [
  5471  						"nats://127.0.0.1:%d"
  5472  				]
  5473  				%s
  5474  				%s
  5475  		}
  5476  	`
  5477  	confB := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", _EMPTY_)))
  5478  	srvb, _ := RunServerWithConfig(confB)
  5479  	defer srvb.Shutdown()
  5480  	confC := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "pool_size: -1", _EMPTY_)))
  5481  	srvc, _ := RunServerWithConfig(confC)
  5482  	defer srvc.Shutdown()
  5483  
  5484  	checkClusterFormed(t, srva, srvb, srvc)
  5485  
  5486  	// Create a connection and sub on B and C
  5487  	ncB := natsConnect(t, srvb.ClientURL(), nats.UserInfo("user1", "pwd"))
  5488  	defer ncB.Close()
  5489  	subB := natsSubSync(t, ncB, "foo")
  5490  
  5491  	ncC := natsConnect(t, srvc.ClientURL(), nats.UserInfo("user1", "pwd"))
  5492  	defer ncC.Close()
  5493  	subC := natsSubSync(t, ncC, "bar")
  5494  
  5495  	// Check that on server B, there is interest on "bar" for account A
  5496  	// (coming from server C), and on server C, there is interest on "foo"
  5497  	// for account A (coming from server B).
  5498  	checkCluster := func() {
  5499  		t.Helper()
  5500  		checkClusterFormed(t, srva, srvb, srvc)
  5501  		checkSubInterest(t, srvb, "A", "bar", 2*time.Second)
  5502  		checkSubInterest(t, srvc, "A", "foo", 2*time.Second)
  5503  	}
  5504  	checkCluster()
  5505  
  5506  	sendAndRecv := func(msg string) {
  5507  		t.Helper()
  5508  		natsPub(t, ncB, "bar", []byte(msg))
  5509  		if m := natsNexMsg(t, subC, time.Second); string(m.Data) != msg {
  5510  			t.Fatalf("Expected message %q on %q, got %q", msg, "bar", m.Data)
  5511  		}
  5512  		natsPub(t, ncC, "foo", []byte(msg))
  5513  		if m := natsNexMsg(t, subB, time.Second); string(m.Data) != msg {
  5514  			t.Fatalf("Expected message %q on %q, got %q", msg, "foo", m.Data)
  5515  		}
  5516  	}
  5517  	sendAndRecv("0")
  5518  
  5519  	// Now add account "A" and do a config reload. We do this only on
  5520  	// server srva and srb since server C really does not change.
  5521  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 3", "accounts: [\"A\"]"))
  5522  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", "accounts: [\"A\"]"))
  5523  	checkCluster()
  5524  	sendAndRecv("1")
  5525  
  5526  	// Remove "A" from the accounts list
  5527  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 3", _EMPTY_))
  5528  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", _EMPTY_))
  5529  	checkCluster()
  5530  	sendAndRecv("2")
  5531  
  5532  	// Change the pool size
  5533  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 5", _EMPTY_))
  5534  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 5", _EMPTY_))
  5535  	checkCluster()
  5536  	sendAndRecv("3")
  5537  
  5538  	// Add account "A" and change the pool size
  5539  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 4", "accounts: [\"A\"]"))
  5540  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 4", "accounts: [\"A\"]"))
  5541  	checkCluster()
  5542  	sendAndRecv("4")
  5543  
  5544  	// Remove account "A" and change the pool size
  5545  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "pool_size: 3", _EMPTY_))
  5546  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "pool_size: 3", _EMPTY_))
  5547  	checkCluster()
  5548  	sendAndRecv("5")
  5549  }
  5550  
  5551  func TestConfigReloadRoutePoolAndPerAccountNoDuplicateSub(t *testing.T) {
  5552  	confATemplate := `
  5553  		port: -1
  5554  		server_name: "A"
  5555  		accounts {
  5556  				A { users: [{user: "user1", password: "pwd"}] }
  5557  		}
  5558  		cluster {
  5559  				name: "local"
  5560  				listen: 127.0.0.1:-1
  5561  				pool_size: 3
  5562  				%s
  5563  		}
  5564  	`
  5565  	confA := createConfFile(t, []byte(fmt.Sprintf(confATemplate, _EMPTY_)))
  5566  	srva, optsA := RunServerWithConfig(confA)
  5567  	defer srva.Shutdown()
  5568  
  5569  	confBCTemplate := `
  5570  		port: -1
  5571  		server_name: "%s"
  5572  		accounts {
  5573  				A { users: [{user: "user1", password: "pwd"}] }
  5574  		}
  5575  		cluster {
  5576  				listen: 127.0.0.1:-1
  5577  				name: "local"
  5578  				routes = [
  5579  						"nats://127.0.0.1:%d"
  5580  				]
  5581  				pool_size: 3
  5582  				%s
  5583  		}
  5584  	`
  5585  	confB := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, _EMPTY_)))
  5586  	srvb, _ := RunServerWithConfig(confB)
  5587  	defer srvb.Shutdown()
  5588  	confC := createConfFile(t, []byte(fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, _EMPTY_)))
  5589  	srvc, _ := RunServerWithConfig(confC)
  5590  	defer srvc.Shutdown()
  5591  
  5592  	checkClusterFormed(t, srva, srvb, srvc)
  5593  
  5594  	ncC := natsConnect(t, srvc.ClientURL(), nats.UserInfo("user1", "pwd"))
  5595  	defer ncC.Close()
  5596  
  5597  	ch := make(chan struct{})
  5598  	wg := sync.WaitGroup{}
  5599  	wg.Add(1)
  5600  	var subs []*nats.Subscription
  5601  	go func() {
  5602  		defer wg.Done()
  5603  		// Limit the number of subscriptions. From experimentation, the issue would
  5604  		// arise around subscriptions ~700.
  5605  		for i := 0; i < 1000; i++ {
  5606  			if sub, err := ncC.SubscribeSync(fmt.Sprintf("foo.%d", i)); err == nil {
  5607  				subs = append(subs, sub)
  5608  			}
  5609  			select {
  5610  			case <-ch:
  5611  				return
  5612  			default:
  5613  				if i%100 == 0 {
  5614  					time.Sleep(5 * time.Millisecond)
  5615  				}
  5616  			}
  5617  		}
  5618  	}()
  5619  
  5620  	// Wait a tiny bit before doing the configuration reload.
  5621  	time.Sleep(100 * time.Millisecond)
  5622  
  5623  	reloadUpdateConfig(t, srva, confA, fmt.Sprintf(confATemplate, "accounts: [\"A\"]"))
  5624  	reloadUpdateConfig(t, srvb, confB, fmt.Sprintf(confBCTemplate, "B", optsA.Cluster.Port, "accounts: [\"A\"]"))
  5625  	reloadUpdateConfig(t, srvc, confC, fmt.Sprintf(confBCTemplate, "C", optsA.Cluster.Port, "accounts: [\"A\"]"))
  5626  
  5627  	checkClusterFormed(t, srva, srvb, srvc)
  5628  
  5629  	close(ch)
  5630  	wg.Wait()
  5631  
  5632  	for _, sub := range subs {
  5633  		checkSubInterest(t, srvb, "A", sub.Subject, 500*time.Millisecond)
  5634  	}
  5635  
  5636  	ncB := natsConnect(t, srvb.ClientURL(), nats.UserInfo("user1", "pwd"))
  5637  	defer ncB.Close()
  5638  
  5639  	for _, sub := range subs {
  5640  		natsPub(t, ncB, sub.Subject, []byte("hello"))
  5641  	}
  5642  
  5643  	// Now make sure that there is only 1 pending message for each sub.
  5644  	// Wait a bit to give a chance to duplicate messages to arrive if
  5645  	// there was a bug that would lead to a sub on each route (the pooled
  5646  	// and the per-account)
  5647  	time.Sleep(250 * time.Millisecond)
  5648  	for _, sub := range subs {
  5649  		if n, _, _ := sub.Pending(); n != 1 {
  5650  			t.Fatalf("Expected only 1 message for subscription on %q, got %v", sub.Subject, n)
  5651  		}
  5652  	}
  5653  }
  5654  
  5655  func TestConfigReloadGlobalAccountWithMappingAndJetStream(t *testing.T) {
  5656  	tmpl := `
  5657  		listen: 127.0.0.1:-1
  5658  		server_name: %s
  5659  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5660  
  5661  		mappings {
  5662  			subj.orig: subj.mapped.before.reload
  5663  		}
  5664  
  5665  		leaf {
  5666  			listen: 127.0.0.1:-1
  5667  		}
  5668  
  5669  		cluster {
  5670  			name: %s
  5671  			listen: 127.0.0.1:%d
  5672  			routes = [%s]
  5673  		}
  5674  
  5675  		# For access to system account.
  5676  		accounts { $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } }
  5677  	`
  5678  	c := createJetStreamClusterWithTemplate(t, tmpl, "R3S", 3)
  5679  	defer c.shutdown()
  5680  
  5681  	nc, js := jsClientConnect(t, c.randomServer())
  5682  	defer nc.Close()
  5683  
  5684  	// Verify that mapping works
  5685  	checkMapping := func(expectedSubj string) {
  5686  		t.Helper()
  5687  		sub := natsSubSync(t, nc, "subj.>")
  5688  		defer sub.Unsubscribe()
  5689  		natsPub(t, nc, "subj.orig", nil)
  5690  		msg := natsNexMsg(t, sub, time.Second)
  5691  		if msg.Subject != expectedSubj {
  5692  			t.Fatalf("Expected subject to have been mapped to %q, got %q", expectedSubj, msg.Subject)
  5693  		}
  5694  	}
  5695  	checkMapping("subj.mapped.before.reload")
  5696  
  5697  	// Create a stream and check that we can get the INFO
  5698  	_, err := js.AddStream(&nats.StreamConfig{
  5699  		Name:      "TEST",
  5700  		Replicas:  3,
  5701  		Subjects:  []string{"foo"},
  5702  		Retention: nats.InterestPolicy,
  5703  	})
  5704  	require_NoError(t, err)
  5705  	c.waitOnStreamLeader(globalAccountName, "TEST")
  5706  
  5707  	_, err = js.StreamInfo("TEST")
  5708  	require_NoError(t, err)
  5709  
  5710  	// Change mapping on all servers and issue reload
  5711  	for i, s := range c.servers {
  5712  		opts := c.opts[i]
  5713  		content, err := os.ReadFile(opts.ConfigFile)
  5714  		require_NoError(t, err)
  5715  		reloadUpdateConfig(t, s, opts.ConfigFile, strings.Replace(string(content), "subj.mapped.before.reload", "subj.mapped.after.reload", 1))
  5716  	}
  5717  	// Make sure the cluster is still formed
  5718  	checkClusterFormed(t, c.servers...)
  5719  	// Now repeat the test for the subject mapping and stream info
  5720  	checkMapping("subj.mapped.after.reload")
  5721  	_, err = js.StreamInfo("TEST")
  5722  	require_NoError(t, err)
  5723  }
  5724  
  5725  func TestConfigReloadRouteCompression(t *testing.T) {
  5726  	org := testDefaultClusterCompression
  5727  	testDefaultClusterCompression = _EMPTY_
  5728  	defer func() { testDefaultClusterCompression = org }()
  5729  
  5730  	tmpl := `
  5731  		port: -1
  5732  		server_name: "%s"
  5733  		cluster {
  5734  			port: -1
  5735  			name: "local"
  5736  			%s
  5737  			%s
  5738  		}
  5739  	`
  5740  	conf1 := createConfFile(t, []byte(fmt.Sprintf(tmpl, "A", _EMPTY_, _EMPTY_)))
  5741  	s1, o1 := RunServerWithConfig(conf1)
  5742  	defer s1.Shutdown()
  5743  
  5744  	routes := fmt.Sprintf("routes: [\"nats://127.0.0.1:%d\"]", o1.Cluster.Port)
  5745  	conf2 := createConfFile(t, []byte(fmt.Sprintf(tmpl, "B", routes, _EMPTY_)))
  5746  	s2, _ := RunServerWithConfig(conf2)
  5747  	defer s2.Shutdown()
  5748  
  5749  	// Run a 3rd server but make it as if it was an old server. We want to
  5750  	// make sure that reload of s1 and s2 will not affect routes from s3 to
  5751  	// s1/s2 because these do not support compression.
  5752  	conf3 := createConfFile(t, []byte(fmt.Sprintf(tmpl, "C", routes, "compression: \"not supported\"")))
  5753  	s3, _ := RunServerWithConfig(conf3)
  5754  	defer s3.Shutdown()
  5755  
  5756  	checkClusterFormed(t, s1, s2, s3)
  5757  
  5758  	// Collect routes' cid from servers so we can check if routes are
  5759  	// recreated when they should and are not when they should not.
  5760  	collect := func(s *Server) map[uint64]struct{} {
  5761  		m := make(map[uint64]struct{})
  5762  		s.mu.RLock()
  5763  		defer s.mu.RUnlock()
  5764  		s.forEachRoute(func(r *client) {
  5765  			r.mu.Lock()
  5766  			m[r.cid] = struct{}{}
  5767  			r.mu.Unlock()
  5768  		})
  5769  		return m
  5770  	}
  5771  	s1RouteIDs := collect(s1)
  5772  	s2RouteIDs := collect(s2)
  5773  	s3ID := s3.ID()
  5774  
  5775  	servers := []*Server{s1, s2}
  5776  	checkCompMode := func(s1Expected, s2Expected string, shouldBeNew bool) {
  5777  		t.Helper()
  5778  		// We wait a bit to make sure that we have routes closed before
  5779  		// checking that the cluster has (re)formed.
  5780  		time.Sleep(100 * time.Millisecond)
  5781  		// First, make sure that the cluster is formed
  5782  		checkClusterFormed(t, s1, s2, s3)
  5783  		// Then check that all routes are with the expected mode. We need to
  5784  		// possibly wait a bit since there is negotiation going on.
  5785  		checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  5786  			for _, s := range servers {
  5787  				var err error
  5788  				s.mu.RLock()
  5789  				s.forEachRoute(func(r *client) {
  5790  					if err != nil {
  5791  						return
  5792  					}
  5793  					r.mu.Lock()
  5794  					var exp string
  5795  					var m map[uint64]struct{}
  5796  					if r.route.remoteID == s3ID {
  5797  						exp = CompressionNotSupported
  5798  					} else if s == s1 {
  5799  						exp = s1Expected
  5800  					} else {
  5801  						exp = s2Expected
  5802  					}
  5803  					if s == s1 {
  5804  						m = s1RouteIDs
  5805  					} else {
  5806  						m = s2RouteIDs
  5807  					}
  5808  					_, present := m[r.cid]
  5809  					cm := r.route.compression
  5810  					r.mu.Unlock()
  5811  					if cm != exp {
  5812  						err = fmt.Errorf("Expected route %v for server %s to have compression mode %q, got %q", r, s, exp, cm)
  5813  					}
  5814  					sbn := shouldBeNew
  5815  					if exp == CompressionNotSupported {
  5816  						// Override for routes to s3
  5817  						sbn = false
  5818  					}
  5819  					if sbn && present {
  5820  						err = fmt.Errorf("Expected route %v for server %s to be a new route, but it was already present", r, s)
  5821  					} else if !sbn && !present {
  5822  						err = fmt.Errorf("Expected route %v for server %s to not be new", r, s)
  5823  					}
  5824  				})
  5825  				s.mu.RUnlock()
  5826  				if err != nil {
  5827  					return err
  5828  				}
  5829  			}
  5830  			s1RouteIDs = collect(s1)
  5831  			s2RouteIDs = collect(s2)
  5832  			return nil
  5833  		})
  5834  	}
  5835  	// Since both started without any compression setting, we default to
  5836  	// "accept" which means that a server can accept/switch to compression
  5837  	// but not initiate compression, so they should both be "off"
  5838  	checkCompMode(CompressionOff, CompressionOff, false)
  5839  
  5840  	// Now reload s1 with "on" (s2_fast), since s2 is *configured* with "accept",
  5841  	// they should both be CompressionS2Fast, even before we reload s2.
  5842  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: on"))
  5843  	checkCompMode(CompressionS2Fast, CompressionS2Fast, true)
  5844  	// Now reload s2
  5845  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, "compression: on"))
  5846  	checkCompMode(CompressionS2Fast, CompressionS2Fast, false)
  5847  
  5848  	// Move on with "better"
  5849  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: s2_better"))
  5850  	// s1 should be at "better", but s2 still at "fast"
  5851  	checkCompMode(CompressionS2Better, CompressionS2Fast, false)
  5852  	// Now reload s2
  5853  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, "compression: s2_better"))
  5854  	checkCompMode(CompressionS2Better, CompressionS2Better, false)
  5855  
  5856  	// Move to "best"
  5857  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: s2_best"))
  5858  	checkCompMode(CompressionS2Best, CompressionS2Better, false)
  5859  	// Now reload s2
  5860  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, "compression: s2_best"))
  5861  	checkCompMode(CompressionS2Best, CompressionS2Best, false)
  5862  
  5863  	// Now turn off
  5864  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: off"))
  5865  	checkCompMode(CompressionOff, CompressionOff, true)
  5866  	// Now reload s2
  5867  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, "compression: off"))
  5868  	checkCompMode(CompressionOff, CompressionOff, false)
  5869  
  5870  	// When "off" (and not "accept"), enabling 1 is not enough, the reload
  5871  	// has to be done on both to take effect.
  5872  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: s2_better"))
  5873  	checkCompMode(CompressionOff, CompressionOff, true)
  5874  	// Now reload s2
  5875  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, "compression: s2_better"))
  5876  	checkCompMode(CompressionS2Better, CompressionS2Better, true)
  5877  
  5878  	// Try now to have different ones
  5879  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, "compression: s2_best"))
  5880  	// S1 should be "best" but S2 should have stayed at "better"
  5881  	checkCompMode(CompressionS2Best, CompressionS2Better, false)
  5882  
  5883  	// If we remove the compression setting, it defaults to "accept", which
  5884  	// in that case we want to have a negotiation and use the remote's compression
  5885  	// level. So connections should be re-created.
  5886  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl, "A", _EMPTY_, _EMPTY_))
  5887  	checkCompMode(CompressionS2Better, CompressionS2Better, true)
  5888  
  5889  	// To avoid flapping, add a little sleep here to make sure we have things
  5890  	// settled before reloading s2.
  5891  	time.Sleep(100 * time.Millisecond)
  5892  	// And if we do the same with s2, then we will end-up with no compression.
  5893  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl, "B", routes, _EMPTY_))
  5894  	checkCompMode(CompressionOff, CompressionOff, true)
  5895  }
  5896  
  5897  func TestConfigReloadRouteCompressionS2Auto(t *testing.T) {
  5898  	// This test checks s2_auto specific behavior. It makes sure that we update
  5899  	// only if the rtt_thresholds and current RTT value warrants a change and
  5900  	// also that we actually save in c.route.compression the actual compression
  5901  	// level (not s2_auto).
  5902  	tmpl1 := `
  5903  		port: -1
  5904  		server_name: "A"
  5905  		cluster {
  5906  			port: -1
  5907  			name: "local"
  5908  			pool_size: -1
  5909  			compression: {mode: s2_auto, rtt_thresholds: [%s]}
  5910  		}
  5911  	`
  5912  	conf1 := createConfFile(t, []byte(fmt.Sprintf(tmpl1, "50ms, 100ms, 150ms")))
  5913  	s1, o1 := RunServerWithConfig(conf1)
  5914  	defer s1.Shutdown()
  5915  
  5916  	conf2 := createConfFile(t, []byte(fmt.Sprintf(`
  5917  		port: -1
  5918  		server_name: "B"
  5919  		cluster {
  5920  			port: -1
  5921  			name: "local"
  5922  			pool_size: -1
  5923  			compression: s2_fast
  5924  			routes: ["nats://127.0.0.1:%d"]
  5925  		}
  5926  	`, o1.Cluster.Port)))
  5927  	s2, _ := RunServerWithConfig(conf2)
  5928  	defer s2.Shutdown()
  5929  
  5930  	checkClusterFormed(t, s1, s2)
  5931  
  5932  	getCompInfo := func() (string, io.Writer) {
  5933  		var cm string
  5934  		var cw io.Writer
  5935  		s1.mu.RLock()
  5936  		// There should be only 1 route...
  5937  		s1.forEachRemote(func(r *client) {
  5938  			r.mu.Lock()
  5939  			cm = r.route.compression
  5940  			cw = r.out.cw
  5941  			r.mu.Unlock()
  5942  		})
  5943  		s1.mu.RUnlock()
  5944  		return cm, cw
  5945  	}
  5946  	// Capture the s2 writer from s1 to s2
  5947  	cm, cw := getCompInfo()
  5948  
  5949  	// We do a reload but really the mode is still s2_auto (even if the current
  5950  	// compression level may be "uncompressed", "better", etc.. so we don't
  5951  	// expect the writer to have changed.
  5952  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "100ms, 200ms, 300ms"))
  5953  	if ncm, ncw := getCompInfo(); ncm != cm || ncw != cw {
  5954  		t.Fatalf("Expected compression info to have stayed the same, was %q - %p, got %q - %p", cm, cw, ncm, ncw)
  5955  	}
  5956  }
  5957  
  5958  func TestConfigReloadLeafNodeCompression(t *testing.T) {
  5959  	org := testDefaultLeafNodeCompression
  5960  	testDefaultLeafNodeCompression = _EMPTY_
  5961  	defer func() { testDefaultLeafNodeCompression = org }()
  5962  
  5963  	tmpl1 := `
  5964  		port: -1
  5965  		server_name: "A"
  5966  		leafnodes {
  5967  			port: -1
  5968  			%s
  5969  		}
  5970  	`
  5971  	conf1 := createConfFile(t, []byte(fmt.Sprintf(tmpl1, "compression: accept")))
  5972  	s1, o1 := RunServerWithConfig(conf1)
  5973  	defer s1.Shutdown()
  5974  
  5975  	port := o1.LeafNode.Port
  5976  
  5977  	tmpl2 := `
  5978  		port: -1
  5979  		server_name: "%s"
  5980  		leafnodes {
  5981  			remotes [
  5982  				{
  5983  					url: "nats://127.0.0.1:%d"
  5984  					%s
  5985  				}
  5986  			]
  5987  		}
  5988  	`
  5989  	conf2 := createConfFile(t, []byte(fmt.Sprintf(tmpl2, "B", port, "compression: accept")))
  5990  	s2, _ := RunServerWithConfig(conf2)
  5991  	defer s2.Shutdown()
  5992  
  5993  	// Run a 3rd server but make it as if it was an old server. We want to
  5994  	// make sure that reload of s1 and s2 will not affect leafnodes from s3 to
  5995  	// s1/s2 because these do not support compression.
  5996  	conf3 := createConfFile(t, []byte(fmt.Sprintf(tmpl2, "C", port, "compression: \"not supported\"")))
  5997  	s3, _ := RunServerWithConfig(conf3)
  5998  	defer s3.Shutdown()
  5999  
  6000  	checkLeafNodeConnected(t, s2)
  6001  	checkLeafNodeConnected(t, s3)
  6002  	checkLeafNodeConnectedCount(t, s1, 2)
  6003  
  6004  	// Collect leafnodes' cid from servers so we can check if connections are
  6005  	// recreated when they should and are not when they should not.
  6006  	collect := func(s *Server) map[uint64]struct{} {
  6007  		m := make(map[uint64]struct{})
  6008  		s.mu.RLock()
  6009  		defer s.mu.RUnlock()
  6010  		for _, l := range s.leafs {
  6011  			l.mu.Lock()
  6012  			m[l.cid] = struct{}{}
  6013  			l.mu.Unlock()
  6014  		}
  6015  		return m
  6016  	}
  6017  	s1LeafNodeIDs := collect(s1)
  6018  	s2LeafNodeIDs := collect(s2)
  6019  
  6020  	servers := []*Server{s1, s2}
  6021  	checkCompMode := func(s1Expected, s2Expected string, shouldBeNew bool) {
  6022  		t.Helper()
  6023  		// We wait a bit to make sure that we have leaf connections closed
  6024  		// before checking that they are properly reconnected.
  6025  		time.Sleep(100 * time.Millisecond)
  6026  		checkLeafNodeConnected(t, s2)
  6027  		checkLeafNodeConnected(t, s3)
  6028  		checkLeafNodeConnectedCount(t, s1, 2)
  6029  		// Check that all leafnodes are with the expected mode. We need to
  6030  		// possibly wait a bit since there is negotiation going on.
  6031  		checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  6032  			for _, s := range servers {
  6033  				var err error
  6034  				s.mu.RLock()
  6035  				for _, l := range s.leafs {
  6036  					l.mu.Lock()
  6037  					var exp string
  6038  					var m map[uint64]struct{}
  6039  					if l.leaf.remoteServer == "C" {
  6040  						exp = CompressionNotSupported
  6041  					} else if s == s1 {
  6042  						exp = s1Expected
  6043  					} else {
  6044  						exp = s2Expected
  6045  					}
  6046  					if s == s1 {
  6047  						m = s1LeafNodeIDs
  6048  					} else {
  6049  						m = s2LeafNodeIDs
  6050  					}
  6051  					_, present := m[l.cid]
  6052  					cm := l.leaf.compression
  6053  					l.mu.Unlock()
  6054  					if cm != exp {
  6055  						err = fmt.Errorf("Expected leaf %v for server %s to have compression mode %q, got %q", l, s, exp, cm)
  6056  					}
  6057  					sbn := shouldBeNew
  6058  					if exp == CompressionNotSupported {
  6059  						// Override for routes to s3
  6060  						sbn = false
  6061  					}
  6062  					if sbn && present {
  6063  						err = fmt.Errorf("Expected leaf %v for server %s to be a new leaf, but it was already present", l, s)
  6064  					} else if !sbn && !present {
  6065  						err = fmt.Errorf("Expected leaf %v for server %s to not be new", l, s)
  6066  					}
  6067  					if err != nil {
  6068  						break
  6069  					}
  6070  				}
  6071  				s.mu.RUnlock()
  6072  				if err != nil {
  6073  					return err
  6074  				}
  6075  			}
  6076  			s1LeafNodeIDs = collect(s1)
  6077  			s2LeafNodeIDs = collect(s2)
  6078  			return nil
  6079  		})
  6080  	}
  6081  	// Since both started with compression "accept", they should both be set to "off"
  6082  	checkCompMode(CompressionOff, CompressionOff, false)
  6083  
  6084  	// Now reload s1 with "on" (s2_auto), since s2 is *configured* with "accept",
  6085  	// s1 should be "uncompressed" (due to low RTT), and s2 is in that case set
  6086  	// to s2_fast.
  6087  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: on"))
  6088  	checkCompMode(CompressionS2Uncompressed, CompressionS2Fast, true)
  6089  	// Now reload s2
  6090  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: on"))
  6091  	checkCompMode(CompressionS2Uncompressed, CompressionS2Uncompressed, false)
  6092  
  6093  	// Move on with "better"
  6094  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: s2_better"))
  6095  	// s1 should be at "better", but s2 still at "uncompressed"
  6096  	checkCompMode(CompressionS2Better, CompressionS2Uncompressed, false)
  6097  	// Now reload s2
  6098  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: s2_better"))
  6099  	checkCompMode(CompressionS2Better, CompressionS2Better, false)
  6100  
  6101  	// Move to "best"
  6102  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: s2_best"))
  6103  	checkCompMode(CompressionS2Best, CompressionS2Better, false)
  6104  	// Now reload s2
  6105  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: s2_best"))
  6106  	checkCompMode(CompressionS2Best, CompressionS2Best, false)
  6107  
  6108  	// Now turn off
  6109  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: off"))
  6110  	checkCompMode(CompressionOff, CompressionOff, true)
  6111  	// Now reload s2
  6112  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: off"))
  6113  	checkCompMode(CompressionOff, CompressionOff, false)
  6114  
  6115  	// When "off" (and not "accept"), enabling 1 is not enough, the reload
  6116  	// has to be done on both to take effect.
  6117  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: s2_better"))
  6118  	checkCompMode(CompressionOff, CompressionOff, true)
  6119  	// Now reload s2
  6120  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: s2_better"))
  6121  	checkCompMode(CompressionS2Better, CompressionS2Better, true)
  6122  
  6123  	// Try now to have different ones
  6124  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: s2_best"))
  6125  	// S1 should be "best" but S2 should have stayed at "better"
  6126  	checkCompMode(CompressionS2Best, CompressionS2Better, false)
  6127  
  6128  	// Change the setting to "accept", which in that case we want to have a
  6129  	// negotiation and use the remote's compression level. So connections
  6130  	// should be re-created.
  6131  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "compression: accept"))
  6132  	checkCompMode(CompressionS2Better, CompressionS2Better, true)
  6133  
  6134  	// To avoid flapping, add a little sleep here to make sure we have things
  6135  	// settled before reloading s2.
  6136  	time.Sleep(100 * time.Millisecond)
  6137  	// And if we do the same with s2, then we will end-up with no compression.
  6138  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, "compression: accept"))
  6139  	checkCompMode(CompressionOff, CompressionOff, true)
  6140  
  6141  	// Now remove completely and we should default to s2_auto, which means that
  6142  	// s1 should be at "uncompressed" and s2 to "fast".
  6143  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, _EMPTY_))
  6144  	checkCompMode(CompressionS2Uncompressed, CompressionS2Fast, true)
  6145  
  6146  	// Now with s2, both will be "uncompressed"
  6147  	reloadUpdateConfig(t, s2, conf2, fmt.Sprintf(tmpl2, "B", port, _EMPTY_))
  6148  	checkCompMode(CompressionS2Uncompressed, CompressionS2Uncompressed, false)
  6149  }
  6150  
  6151  func TestConfigReloadLeafNodeCompressionS2Auto(t *testing.T) {
  6152  	// This test checks s2_auto specific behavior. It makes sure that we update
  6153  	// only if the rtt_thresholds and current RTT value warrants a change and
  6154  	// also that we actually save in c.leaf.compression the actual compression
  6155  	// level (not s2_auto).
  6156  	tmpl1 := `
  6157  		port: -1
  6158  		server_name: "A"
  6159  		leafnodes {
  6160  			port: -1
  6161  			compression: {mode: s2_auto, rtt_thresholds: [%s]}
  6162  		}
  6163  	`
  6164  	conf1 := createConfFile(t, []byte(fmt.Sprintf(tmpl1, "50ms, 100ms, 150ms")))
  6165  	s1, o1 := RunServerWithConfig(conf1)
  6166  	defer s1.Shutdown()
  6167  
  6168  	conf2 := createConfFile(t, []byte(fmt.Sprintf(`
  6169  		port: -1
  6170  		server_name: "B"
  6171  		leafnodes {
  6172  			remotes [{ url: "nats://127.0.0.1:%d", compression: s2_fast}]
  6173  		}
  6174  	`, o1.LeafNode.Port)))
  6175  	s2, _ := RunServerWithConfig(conf2)
  6176  	defer s2.Shutdown()
  6177  
  6178  	checkLeafNodeConnected(t, s2)
  6179  
  6180  	getCompInfo := func() (string, io.Writer) {
  6181  		var cm string
  6182  		var cw io.Writer
  6183  		s1.mu.RLock()
  6184  		// There should be only 1 leaf...
  6185  		for _, l := range s1.leafs {
  6186  			l.mu.Lock()
  6187  			cm = l.leaf.compression
  6188  			cw = l.out.cw
  6189  			l.mu.Unlock()
  6190  		}
  6191  		s1.mu.RUnlock()
  6192  		return cm, cw
  6193  	}
  6194  	// Capture the s2 writer from s1 to s2
  6195  	cm, cw := getCompInfo()
  6196  
  6197  	// We do a reload but really the mode is still s2_auto (even if the current
  6198  	// compression level may be "uncompressed", "better", etc.. so we don't
  6199  	// expect the writer to have changed.
  6200  	reloadUpdateConfig(t, s1, conf1, fmt.Sprintf(tmpl1, "100ms, 200ms, 300ms"))
  6201  	if ncm, ncw := getCompInfo(); ncm != cm || ncw != cw {
  6202  		t.Fatalf("Expected compression info to have stayed the same, was %q - %p, got %q - %p", cm, cw, ncm, ncw)
  6203  	}
  6204  }
  6205  
  6206  func TestConfigReloadNoPanicOnShutdown(t *testing.T) {
  6207  	tmpl := `
  6208  		port: -1
  6209  		jetstream: true
  6210  		accounts {
  6211  			A {
  6212  				users: [{user: A, password: pwd}]
  6213  				%s
  6214  			}
  6215  			B {
  6216  				users: [{user: B, password: pwd}]
  6217  			}
  6218  		}
  6219  	`
  6220  	for i := 0; i < 50; i++ {
  6221  		conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, _EMPTY_)))
  6222  		s, _ := RunServerWithConfig(conf)
  6223  		// Don't use a defer s.Shutdown() here since it would prevent the panic
  6224  		// to be reported (but the test would still fail because of a runtime timeout).
  6225  
  6226  		err := os.WriteFile(conf, []byte(fmt.Sprintf(tmpl, "jetstream: true")), 0666)
  6227  		require_NoError(t, err)
  6228  
  6229  		wg := sync.WaitGroup{}
  6230  		wg.Add(1)
  6231  		go func() {
  6232  			defer wg.Done()
  6233  			time.Sleep(10 * time.Millisecond)
  6234  			s.Shutdown()
  6235  		}()
  6236  
  6237  		time.Sleep(8 * time.Millisecond)
  6238  		err = s.Reload()
  6239  		require_NoError(t, err)
  6240  		wg.Wait()
  6241  	}
  6242  }