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

     1  // Copyright 2018-2023 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/sha256"
    19  	"encoding/json"
    20  	"errors"
    21  	"fmt"
    22  	"math/rand"
    23  	"net/http"
    24  	"net/http/httptest"
    25  	"os"
    26  	"reflect"
    27  	"strings"
    28  	"sync"
    29  	"sync/atomic"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/nats-io/jwt/v2"
    34  	"github.com/nats-io/nats.go"
    35  	"github.com/nats-io/nkeys"
    36  	"github.com/nats-io/nuid"
    37  )
    38  
    39  func createAccount(s *Server) (*Account, nkeys.KeyPair) {
    40  	okp, _ := nkeys.FromSeed(oSeed)
    41  	akp, _ := nkeys.CreateAccount()
    42  	pub, _ := akp.PublicKey()
    43  	nac := jwt.NewAccountClaims(pub)
    44  	jwt, _ := nac.Encode(okp)
    45  	addAccountToMemResolver(s, pub, jwt)
    46  	acc, err := s.LookupAccount(pub)
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	return acc, akp
    51  }
    52  
    53  func createUserCredsEx(t *testing.T, nuc *jwt.UserClaims, akp nkeys.KeyPair) nats.Option {
    54  	t.Helper()
    55  	kp, _ := nkeys.CreateUser()
    56  	nuc.Subject, _ = kp.PublicKey()
    57  	ujwt, err := nuc.Encode(akp)
    58  	if err != nil {
    59  		t.Fatalf("Error generating user JWT: %v", err)
    60  	}
    61  	userCB := func() (string, error) {
    62  		return ujwt, nil
    63  	}
    64  	sigCB := func(nonce []byte) ([]byte, error) {
    65  		sig, _ := kp.Sign(nonce)
    66  		return sig, nil
    67  	}
    68  	return nats.UserJWT(userCB, sigCB)
    69  }
    70  
    71  func createUserCreds(t *testing.T, s *Server, akp nkeys.KeyPair) nats.Option {
    72  	return createUserCredsEx(t, jwt.NewUserClaims("test"), akp)
    73  }
    74  
    75  func runTrustedServer(t *testing.T) (*Server, *Options) {
    76  	t.Helper()
    77  	opts := DefaultOptions()
    78  	kp, _ := nkeys.FromSeed(oSeed)
    79  	pub, _ := kp.PublicKey()
    80  	opts.TrustedKeys = []string{pub}
    81  	opts.AccountResolver = &MemAccResolver{}
    82  	s := RunServer(opts)
    83  	return s, opts
    84  }
    85  
    86  func runTrustedCluster(t *testing.T) (*Server, *Options, *Server, *Options, nkeys.KeyPair) {
    87  	t.Helper()
    88  
    89  	kp, _ := nkeys.FromSeed(oSeed)
    90  	pub, _ := kp.PublicKey()
    91  
    92  	mr := &MemAccResolver{}
    93  
    94  	// Now create a system account.
    95  	// NOTE: This can NOT be shared directly between servers.
    96  	// Set via server options.
    97  	okp, _ := nkeys.FromSeed(oSeed)
    98  	akp, _ := nkeys.CreateAccount()
    99  	apub, _ := akp.PublicKey()
   100  	nac := jwt.NewAccountClaims(apub)
   101  	jwt, _ := nac.Encode(okp)
   102  
   103  	mr.Store(apub, jwt)
   104  
   105  	optsA := DefaultOptions()
   106  	optsA.Cluster.Name = "TEST CLUSTER 22"
   107  	optsA.Cluster.Host = "127.0.0.1"
   108  	optsA.TrustedKeys = []string{pub}
   109  	optsA.AccountResolver = mr
   110  	optsA.SystemAccount = apub
   111  	optsA.ServerName = "A_SRV"
   112  	// Add in dummy gateway
   113  	optsA.Gateway.Name = "TEST CLUSTER 22"
   114  	optsA.Gateway.Host = "127.0.0.1"
   115  	optsA.Gateway.Port = -1
   116  	optsA.gatewaysSolicitDelay = 30 * time.Second
   117  
   118  	sa := RunServer(optsA)
   119  
   120  	optsB := nextServerOpts(optsA)
   121  	optsB.ServerName = "B_SRV"
   122  	optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", optsA.Cluster.Host, optsA.Cluster.Port))
   123  	sb := RunServer(optsB)
   124  
   125  	checkClusterFormed(t, sa, sb)
   126  
   127  	return sa, optsA, sb, optsB, akp
   128  }
   129  
   130  func runTrustedGateways(t *testing.T) (*Server, *Options, *Server, *Options, nkeys.KeyPair) {
   131  	t.Helper()
   132  
   133  	kp, _ := nkeys.FromSeed(oSeed)
   134  	pub, _ := kp.PublicKey()
   135  
   136  	mr := &MemAccResolver{}
   137  
   138  	// Now create a system account.
   139  	// NOTE: This can NOT be shared directly between servers.
   140  	// Set via server options.
   141  	okp, _ := nkeys.FromSeed(oSeed)
   142  	akp, _ := nkeys.CreateAccount()
   143  	apub, _ := akp.PublicKey()
   144  	nac := jwt.NewAccountClaims(apub)
   145  	jwt, _ := nac.Encode(okp)
   146  
   147  	mr.Store(apub, jwt)
   148  
   149  	optsA := testDefaultOptionsForGateway("A")
   150  	optsA.Cluster.Name = "A"
   151  	optsA.Cluster.Host = "127.0.0.1"
   152  	optsA.TrustedKeys = []string{pub}
   153  	optsA.AccountResolver = mr
   154  	optsA.SystemAccount = apub
   155  
   156  	sa := RunServer(optsA)
   157  
   158  	optsB := testGatewayOptionsFromToWithServers(t, "B", "A", sa)
   159  	optsB.Cluster.Name = "B"
   160  	optsB.TrustedKeys = []string{pub}
   161  	optsB.AccountResolver = mr
   162  	optsB.SystemAccount = apub
   163  
   164  	sb := RunServer(optsB)
   165  
   166  	waitForInboundGateways(t, sa, 1, time.Second)
   167  	waitForOutboundGateways(t, sa, 1, time.Second)
   168  	waitForInboundGateways(t, sb, 1, time.Second)
   169  	waitForOutboundGateways(t, sb, 1, time.Second)
   170  
   171  	return sa, optsA, sb, optsB, akp
   172  }
   173  
   174  func TestSystemAccount(t *testing.T) {
   175  	s, _ := runTrustedServer(t)
   176  	defer s.Shutdown()
   177  
   178  	acc, _ := createAccount(s)
   179  	s.setSystemAccount(acc)
   180  
   181  	s.mu.Lock()
   182  	defer s.mu.Unlock()
   183  
   184  	if s.sys == nil || s.sys.account == nil {
   185  		t.Fatalf("Expected sys.account to be non-nil")
   186  	}
   187  	if s.sys.client == nil {
   188  		t.Fatalf("Expected sys.client to be non-nil")
   189  	}
   190  
   191  	s.sys.client.mu.Lock()
   192  	defer s.sys.client.mu.Unlock()
   193  	if s.sys.client.echo {
   194  		t.Fatalf("Internal clients should always have echo false")
   195  	}
   196  }
   197  
   198  func TestSystemAccountNewConnection(t *testing.T) {
   199  	s, opts := runTrustedServer(t)
   200  	defer s.Shutdown()
   201  
   202  	acc, akp := createAccount(s)
   203  	s.setSystemAccount(acc)
   204  
   205  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   206  	ncs, err := nats.Connect(url, createUserCreds(t, s, akp))
   207  	if err != nil {
   208  		t.Fatalf("Error on connect: %v", err)
   209  	}
   210  	defer ncs.Close()
   211  
   212  	// We may not be able to hear ourselves (if the event is processed
   213  	// before we create the sub), so we need to create a second client to
   214  	// trigger the connect/disconnect events.
   215  	acc2, akp2 := createAccount(s)
   216  
   217  	// Be explicit to only receive the event for acc2.
   218  	sub, _ := ncs.SubscribeSync(fmt.Sprintf("$SYS.ACCOUNT.%s.>", acc2.Name))
   219  	defer sub.Unsubscribe()
   220  	ncs.Flush()
   221  
   222  	nc, err := nats.Connect(url, createUserCreds(t, s, akp2), nats.Name("TEST EVENTS"))
   223  	if err != nil {
   224  		t.Fatalf("Error on connect: %v", err)
   225  	}
   226  	defer nc.Close()
   227  
   228  	msg, err := sub.NextMsg(time.Second)
   229  	if err != nil {
   230  		t.Fatalf("Error receiving msg: %v", err)
   231  	}
   232  	connsMsg, err := sub.NextMsg(time.Second)
   233  	if err != nil {
   234  		t.Fatalf("Error receiving msg: %v", err)
   235  	}
   236  	if strings.HasPrefix(msg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.SERVER.CONNS", acc2.Name)) {
   237  		msg, connsMsg = connsMsg, msg
   238  	}
   239  	if !strings.HasPrefix(connsMsg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.SERVER.CONNS", acc2.Name)) {
   240  		t.Fatalf("Expected subject to start with %q, got %q", "$SYS.ACCOUNT.<account>.CONNECT", msg.Subject)
   241  	}
   242  	conns := AccountNumConns{}
   243  	if err := json.Unmarshal(connsMsg.Data, &conns); err != nil {
   244  		t.Fatalf("Error unmarshalling conns event message: %v", err)
   245  	} else if conns.Account != acc2.Name {
   246  		t.Fatalf("Wrong account in conns message: %v", conns)
   247  	} else if conns.Conns != 1 || conns.TotalConns != 1 || conns.LeafNodes != 0 {
   248  		t.Fatalf("Wrong counts in conns message: %v", conns)
   249  	}
   250  	if !strings.HasPrefix(msg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.CONNECT", acc2.Name)) {
   251  		t.Fatalf("Expected subject to start with %q, got %q", "$SYS.ACCOUNT.<account>.CONNECT", msg.Subject)
   252  	}
   253  	tokens := strings.Split(msg.Subject, ".")
   254  	if len(tokens) < 4 {
   255  		t.Fatalf("Expected 4 tokens, got %d", len(tokens))
   256  	}
   257  	account := tokens[2]
   258  	if account != acc2.Name {
   259  		t.Fatalf("Expected %q for account, got %q", acc2.Name, account)
   260  	}
   261  
   262  	cem := ConnectEventMsg{}
   263  	if err := json.Unmarshal(msg.Data, &cem); err != nil {
   264  		t.Fatalf("Error unmarshalling connect event message: %v", err)
   265  	}
   266  	if cem.Type != ConnectEventMsgType {
   267  		t.Fatalf("Incorrect schema in connect event: %s", cem.Type)
   268  	}
   269  	if cem.Time.IsZero() {
   270  		t.Fatalf("Event time is not set")
   271  	}
   272  	if len(cem.ID) != 22 {
   273  		t.Fatalf("Event ID is incorrectly set to len %d", len(cem.ID))
   274  	}
   275  	if cem.Server.ID != s.ID() {
   276  		t.Fatalf("Expected server to be %q, got %q", s.ID(), cem.Server.ID)
   277  	}
   278  	if cem.Server.Seq == 0 {
   279  		t.Fatalf("Expected sequence to be non-zero")
   280  	}
   281  	if cem.Client.Name != "TEST EVENTS" {
   282  		t.Fatalf("Expected client name to be %q, got %q", "TEST EVENTS", cem.Client.Name)
   283  	}
   284  	if cem.Client.Lang != "go" {
   285  		t.Fatalf("Expected client lang to be \"go\", got %q", cem.Client.Lang)
   286  	}
   287  
   288  	// Now close the other client. Should fire a disconnect event.
   289  	// First send and receive some messages.
   290  	sub2, _ := nc.SubscribeSync("foo")
   291  	defer sub2.Unsubscribe()
   292  	sub3, _ := nc.SubscribeSync("*")
   293  	defer sub3.Unsubscribe()
   294  
   295  	for i := 0; i < 10; i++ {
   296  		nc.Publish("foo", []byte("HELLO WORLD"))
   297  	}
   298  	nc.Flush()
   299  	nc.Close()
   300  
   301  	msg, err = sub.NextMsg(time.Second)
   302  	if err != nil {
   303  		t.Fatalf("Error receiving msg: %v", err)
   304  	}
   305  	connsMsg, err = sub.NextMsg(time.Second)
   306  	if err != nil {
   307  		t.Fatalf("Error receiving msg: %v", err)
   308  	}
   309  	if strings.HasPrefix(msg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.SERVER.CONNS", acc2.Name)) {
   310  		msg, connsMsg = connsMsg, msg
   311  	}
   312  	if !strings.HasPrefix(connsMsg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.SERVER.CONNS", acc2.Name)) {
   313  		t.Fatalf("Expected subject to start with %q, got %q", "$SYS.ACCOUNT.<account>.CONNECT", msg.Subject)
   314  	} else if !strings.Contains(string(connsMsg.Data), `"total_conns":0`) {
   315  		t.Fatalf("Expected event to reflect created connection, got: %s", string(connsMsg.Data))
   316  	}
   317  	conns = AccountNumConns{}
   318  	if err := json.Unmarshal(connsMsg.Data, &conns); err != nil {
   319  		t.Fatalf("Error unmarshalling conns event message: %v", err)
   320  	} else if conns.Account != acc2.Name {
   321  		t.Fatalf("Wrong account in conns message: %v", conns)
   322  	} else if conns.Conns != 0 || conns.TotalConns != 0 || conns.LeafNodes != 0 {
   323  		t.Fatalf("Wrong counts in conns message: %v", conns)
   324  	}
   325  	if !strings.HasPrefix(msg.Subject, fmt.Sprintf("$SYS.ACCOUNT.%s.DISCONNECT", acc2.Name)) {
   326  		t.Fatalf("Expected subject to start with %q, got %q", "$SYS.ACCOUNT.<account>.DISCONNECT", msg.Subject)
   327  	}
   328  	tokens = strings.Split(msg.Subject, ".")
   329  	if len(tokens) < 4 {
   330  		t.Fatalf("Expected 4 tokens, got %d", len(tokens))
   331  	}
   332  	account = tokens[2]
   333  	if account != acc2.Name {
   334  		t.Fatalf("Expected %q for account, got %q", acc2.Name, account)
   335  	}
   336  
   337  	dem := DisconnectEventMsg{}
   338  	if err := json.Unmarshal(msg.Data, &dem); err != nil {
   339  		t.Fatalf("Error unmarshalling disconnect event message: %v", err)
   340  	}
   341  	if dem.Type != DisconnectEventMsgType {
   342  		t.Fatalf("Incorrect schema in connect event: %s", cem.Type)
   343  	}
   344  	if dem.Time.IsZero() {
   345  		t.Fatalf("Event time is not set")
   346  	}
   347  	if len(dem.ID) != 22 {
   348  		t.Fatalf("Event ID is incorrectly set to len %d", len(cem.ID))
   349  	}
   350  	if dem.Server.ID != s.ID() {
   351  		t.Fatalf("Expected server to be %q, got %q", s.ID(), dem.Server.ID)
   352  	}
   353  	if dem.Server.Seq == 0 {
   354  		t.Fatalf("Expected sequence to be non-zero")
   355  	}
   356  	if dem.Server.Seq <= cem.Server.Seq {
   357  		t.Fatalf("Expected sequence to be increasing")
   358  	}
   359  
   360  	if cem.Client.Name != "TEST EVENTS" {
   361  		t.Fatalf("Expected client name to be %q, got %q", "TEST EVENTS", dem.Client.Name)
   362  	}
   363  	if dem.Client.Lang != "go" {
   364  		t.Fatalf("Expected client lang to be \"go\", got %q", dem.Client.Lang)
   365  	}
   366  
   367  	if dem.Sent.Msgs != 10 {
   368  		t.Fatalf("Expected 10 msgs sent, got %d", dem.Sent.Msgs)
   369  	}
   370  	if dem.Sent.Bytes != 110 {
   371  		t.Fatalf("Expected 110 bytes sent, got %d", dem.Sent.Bytes)
   372  	}
   373  	if dem.Received.Msgs != 20 {
   374  		t.Fatalf("Expected 20 msgs received, got %d", dem.Sent.Msgs)
   375  	}
   376  	if dem.Received.Bytes != 220 {
   377  		t.Fatalf("Expected 220 bytes sent, got %d", dem.Sent.Bytes)
   378  	}
   379  }
   380  
   381  func runTrustedLeafServer(t *testing.T) (*Server, *Options) {
   382  	t.Helper()
   383  	opts := DefaultOptions()
   384  	kp, _ := nkeys.FromSeed(oSeed)
   385  	pub, _ := kp.PublicKey()
   386  	opts.TrustedKeys = []string{pub}
   387  	opts.AccountResolver = &MemAccResolver{}
   388  	opts.LeafNode.Port = -1
   389  	s := RunServer(opts)
   390  	return s, opts
   391  }
   392  
   393  func genCredsFile(t *testing.T, jwt string, seed []byte) string {
   394  	creds := `
   395  		-----BEGIN NATS USER JWT-----
   396  		%s
   397  		------END NATS USER JWT------
   398  
   399  		************************* IMPORTANT *************************
   400  		NKEY Seed printed below can be used to sign and prove identity.
   401  		NKEYs are sensitive and should be treated as secrets.
   402  
   403  		-----BEGIN USER NKEY SEED-----
   404  		%s
   405  		------END USER NKEY SEED------
   406  
   407  		*************************************************************
   408  		`
   409  	return createConfFile(t, []byte(strings.Replace(fmt.Sprintf(creds, jwt, seed), "\t\t", "", -1)))
   410  }
   411  
   412  func runSolicitWithCredentials(t *testing.T, opts *Options, creds string) (*Server, *Options, string) {
   413  	content := `
   414  		port: -1
   415  		leafnodes {
   416  			remotes = [
   417  				{
   418  					url: nats-leaf://127.0.0.1:%d
   419  					credentials: '%s'
   420  				}
   421  			]
   422  		}
   423  		`
   424  	config := fmt.Sprintf(content, opts.LeafNode.Port, creds)
   425  	conf := createConfFile(t, []byte(config))
   426  	s, opts := RunServerWithConfig(conf)
   427  	return s, opts, conf
   428  }
   429  
   430  // Helper function to check that a leaf node has connected to our server.
   431  func checkLeafNodeConnected(t testing.TB, s *Server) {
   432  	t.Helper()
   433  	checkLeafNodeConnectedCount(t, s, 1)
   434  }
   435  
   436  // Helper function to check that a leaf node has connected to n server.
   437  func checkLeafNodeConnectedCount(t testing.TB, s *Server, lnCons int) {
   438  	t.Helper()
   439  	checkFor(t, 5*time.Second, 15*time.Millisecond, func() error {
   440  		if nln := s.NumLeafNodes(); nln != lnCons {
   441  			return fmt.Errorf("Expected %d connected leafnode(s) for server %v, got %d",
   442  				lnCons, s, nln)
   443  		}
   444  		return nil
   445  	})
   446  }
   447  
   448  func TestSystemAccountingWithLeafNodes(t *testing.T) {
   449  	s, opts := runTrustedLeafServer(t)
   450  	defer s.Shutdown()
   451  
   452  	acc, akp := createAccount(s)
   453  	s.setSystemAccount(acc)
   454  
   455  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   456  	ncs, err := nats.Connect(url, createUserCreds(t, s, akp))
   457  	if err != nil {
   458  		t.Fatalf("Error on connect: %v", err)
   459  	}
   460  	defer ncs.Close()
   461  
   462  	acc2, akp2 := createAccount(s)
   463  
   464  	// Be explicit to only receive the event for acc2 account.
   465  	sub, _ := ncs.SubscribeSync(fmt.Sprintf("$SYS.ACCOUNT.%s.DISCONNECT", acc2.Name))
   466  	defer sub.Unsubscribe()
   467  	ncs.Flush()
   468  
   469  	kp, _ := nkeys.CreateUser()
   470  	pub, _ := kp.PublicKey()
   471  	nuc := jwt.NewUserClaims(pub)
   472  	ujwt, err := nuc.Encode(akp2)
   473  	if err != nil {
   474  		t.Fatalf("Error generating user JWT: %v", err)
   475  	}
   476  	seed, _ := kp.Seed()
   477  	mycreds := genCredsFile(t, ujwt, seed)
   478  
   479  	// Create a server that solicits a leafnode connection.
   480  	sl, slopts, _ := runSolicitWithCredentials(t, opts, mycreds)
   481  	defer sl.Shutdown()
   482  
   483  	checkLeafNodeConnected(t, s)
   484  
   485  	// Compute the expected number of subs on "sl" based on number
   486  	// of existing subs before creating the sub on "s".
   487  	expected := int(sl.NumSubscriptions() + 1)
   488  
   489  	nc, err := nats.Connect(url, createUserCreds(t, s, akp2), nats.Name("TEST LEAFNODE EVENTS"))
   490  	if err != nil {
   491  		t.Fatalf("Error on connect: %v", err)
   492  	}
   493  	defer nc.Close()
   494  	fooSub := natsSubSync(t, nc, "foo")
   495  	natsFlush(t, nc)
   496  
   497  	checkExpectedSubs(t, expected, sl)
   498  
   499  	surl := fmt.Sprintf("nats://%s:%d", slopts.Host, slopts.Port)
   500  	nc2, err := nats.Connect(surl, nats.Name("TEST LEAFNODE EVENTS"))
   501  	if err != nil {
   502  		t.Fatalf("Error on connect: %v", err)
   503  	}
   504  	defer nc2.Close()
   505  
   506  	// Compute the expected number of subs on "s" based on number
   507  	// of existing subs before creating the sub on "sl".
   508  	expected = int(s.NumSubscriptions() + 1)
   509  
   510  	m := []byte("HELLO WORLD")
   511  
   512  	// Now generate some traffic
   513  	starSub := natsSubSync(t, nc2, "*")
   514  	for i := 0; i < 10; i++ {
   515  		nc2.Publish("foo", m)
   516  		nc2.Publish("bar", m)
   517  	}
   518  	natsFlush(t, nc2)
   519  
   520  	checkExpectedSubs(t, expected, s)
   521  
   522  	// Now send some from the cluster side too.
   523  	for i := 0; i < 10; i++ {
   524  		nc.Publish("foo", m)
   525  		nc.Publish("bar", m)
   526  	}
   527  	nc.Flush()
   528  
   529  	// Make sure all messages are received
   530  	for i := 0; i < 20; i++ {
   531  		if _, err := fooSub.NextMsg(time.Second); err != nil {
   532  			t.Fatalf("Did not get message: %v", err)
   533  		}
   534  	}
   535  	for i := 0; i < 40; i++ {
   536  		if _, err := starSub.NextMsg(time.Second); err != nil {
   537  			t.Fatalf("Did not get message: %v", err)
   538  		}
   539  	}
   540  
   541  	// Now shutdown the leafnode server since this is where the event tracking should
   542  	// happen. Right now we do not track local clients to the leafnode server that
   543  	// solicited to the cluster, but we should track usage once the leafnode connection stops.
   544  	sl.Shutdown()
   545  
   546  	// Make sure we get disconnect event and that tracking is correct.
   547  	msg, err := sub.NextMsg(time.Second)
   548  	if err != nil {
   549  		t.Fatalf("Error receiving msg: %v", err)
   550  	}
   551  
   552  	dem := DisconnectEventMsg{}
   553  	if err := json.Unmarshal(msg.Data, &dem); err != nil {
   554  		t.Fatalf("Error unmarshalling disconnect event message: %v", err)
   555  	}
   556  	if dem.Sent.Msgs != 10 {
   557  		t.Fatalf("Expected 10 msgs sent, got %d", dem.Sent.Msgs)
   558  	}
   559  	if dem.Sent.Bytes != 110 {
   560  		t.Fatalf("Expected 110 bytes sent, got %d", dem.Sent.Bytes)
   561  	}
   562  	if dem.Received.Msgs != 20 {
   563  		t.Fatalf("Expected 20 msgs received, got %d", dem.Received.Msgs)
   564  	}
   565  	if dem.Received.Bytes != 220 {
   566  		t.Fatalf("Expected 220 bytes sent, got %d", dem.Received.Bytes)
   567  	}
   568  }
   569  
   570  func TestSystemAccountDisconnectBadLogin(t *testing.T) {
   571  	s, opts := runTrustedServer(t)
   572  	defer s.Shutdown()
   573  
   574  	acc, akp := createAccount(s)
   575  	s.setSystemAccount(acc)
   576  
   577  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   578  	ncs, err := nats.Connect(url, createUserCreds(t, s, akp))
   579  	if err != nil {
   580  		t.Fatalf("Error on connect: %v", err)
   581  	}
   582  	defer ncs.Close()
   583  
   584  	// We should never hear $G account events for bad logins.
   585  	sub, _ := ncs.SubscribeSync("$SYS.ACCOUNT.$G.*")
   586  	defer sub.Unsubscribe()
   587  
   588  	// Listen for auth error events though.
   589  	asub, _ := ncs.SubscribeSync("$SYS.SERVER.*.CLIENT.AUTH.ERR")
   590  	defer asub.Unsubscribe()
   591  
   592  	ncs.Flush()
   593  
   594  	nats.Connect(url, nats.Name("TEST BAD LOGIN"))
   595  
   596  	// Should not hear these.
   597  	if _, err := sub.NextMsg(100 * time.Millisecond); err == nil {
   598  		t.Fatalf("Received a disconnect message from bad login, expected none")
   599  	}
   600  
   601  	m, err := asub.NextMsg(100 * time.Millisecond)
   602  	if err != nil {
   603  		t.Fatalf("Should have heard an auth error event")
   604  	}
   605  	dem := DisconnectEventMsg{}
   606  	if err := json.Unmarshal(m.Data, &dem); err != nil {
   607  		t.Fatalf("Error unmarshalling disconnect event message: %v", err)
   608  	}
   609  	if dem.Reason != "Authentication Failure" {
   610  		t.Fatalf("Expected auth error, got %q", dem.Reason)
   611  	}
   612  }
   613  
   614  func TestSysSubscribeRace(t *testing.T) {
   615  	s, opts := runTrustedServer(t)
   616  	defer s.Shutdown()
   617  
   618  	acc, akp := createAccount(s)
   619  	s.setSystemAccount(acc)
   620  
   621  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   622  
   623  	nc, err := nats.Connect(url, createUserCreds(t, s, akp))
   624  	if err != nil {
   625  		t.Fatalf("Error on connect: %v", err)
   626  	}
   627  	defer nc.Close()
   628  
   629  	done := make(chan struct{})
   630  	wg := sync.WaitGroup{}
   631  	wg.Add(1)
   632  	go func() {
   633  		defer wg.Done()
   634  		for {
   635  			nc.Publish("foo", []byte("hello"))
   636  			select {
   637  			case <-done:
   638  				return
   639  			default:
   640  			}
   641  		}
   642  	}()
   643  
   644  	time.Sleep(10 * time.Millisecond)
   645  
   646  	received := make(chan struct{})
   647  	// Create message callback handler.
   648  	cb := func(sub *subscription, producer *client, _ *Account, subject, reply string, msg []byte) {
   649  		select {
   650  		case received <- struct{}{}:
   651  		default:
   652  		}
   653  	}
   654  	// Now create an internal subscription
   655  	sub, err := s.sysSubscribe("foo", cb)
   656  	if sub == nil || err != nil {
   657  		t.Fatalf("Expected to subscribe, got %v", err)
   658  	}
   659  	select {
   660  	case <-received:
   661  		close(done)
   662  	case <-time.After(time.Second):
   663  		t.Fatalf("Did not receive the message")
   664  	}
   665  	wg.Wait()
   666  }
   667  
   668  func TestSystemAccountInternalSubscriptions(t *testing.T) {
   669  	s, opts := runTrustedServer(t)
   670  	defer s.Shutdown()
   671  
   672  	sub, err := s.sysSubscribe("foo", nil)
   673  	if sub != nil || err != ErrNoSysAccount {
   674  		t.Fatalf("Expected to get proper error, got %v", err)
   675  	}
   676  
   677  	acc, akp := createAccount(s)
   678  	s.setSystemAccount(acc)
   679  
   680  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   681  
   682  	nc, err := nats.Connect(url, createUserCreds(t, s, akp))
   683  	if err != nil {
   684  		t.Fatalf("Error on connect: %v", err)
   685  	}
   686  	defer nc.Close()
   687  
   688  	sub, err = s.sysSubscribe("foo", nil)
   689  	if sub != nil || err == nil {
   690  		t.Fatalf("Expected to get error for no handler, got %v", err)
   691  	}
   692  
   693  	received := make(chan *nats.Msg)
   694  	// Create message callback handler.
   695  	cb := func(sub *subscription, _ *client, _ *Account, subject, reply string, msg []byte) {
   696  		copy := append([]byte(nil), msg...)
   697  		received <- &nats.Msg{Subject: subject, Reply: reply, Data: copy}
   698  	}
   699  
   700  	// Now create an internal subscription
   701  	sub, err = s.sysSubscribe("foo", cb)
   702  	if sub == nil || err != nil {
   703  		t.Fatalf("Expected to subscribe, got %v", err)
   704  	}
   705  	// Now send out a message from our normal client.
   706  	nc.Publish("foo", []byte("HELLO WORLD"))
   707  
   708  	var msg *nats.Msg
   709  
   710  	select {
   711  	case msg = <-received:
   712  		if msg.Subject != "foo" {
   713  			t.Fatalf("Expected \"foo\" as subject, got %q", msg.Subject)
   714  		}
   715  		if msg.Reply != "" {
   716  			t.Fatalf("Expected no reply, got %q", msg.Reply)
   717  		}
   718  		if !bytes.Equal(msg.Data, []byte("HELLO WORLD")) {
   719  			t.Fatalf("Got the wrong msg payload: %q", msg.Data)
   720  		}
   721  		break
   722  	case <-time.After(time.Second):
   723  		t.Fatalf("Did not receive the message")
   724  	}
   725  	s.sysUnsubscribe(sub)
   726  
   727  	// Now send out a message from our normal client.
   728  	// We should not see this one.
   729  	nc.Publish("foo", []byte("You There?"))
   730  
   731  	select {
   732  	case <-received:
   733  		t.Fatalf("Received a message when we should not have")
   734  	case <-time.After(100 * time.Millisecond):
   735  		break
   736  	}
   737  
   738  	// Now make sure we do not hear ourselves. We optimize this for internally
   739  	// generated messages.
   740  	s.mu.Lock()
   741  	s.sendInternalMsg("foo", "", nil, msg.Data)
   742  	s.mu.Unlock()
   743  
   744  	select {
   745  	case <-received:
   746  		t.Fatalf("Received a message when we should not have")
   747  	case <-time.After(100 * time.Millisecond):
   748  		break
   749  	}
   750  }
   751  
   752  func TestSystemAccountConnectionUpdatesStopAfterNoLocal(t *testing.T) {
   753  	sa, _, sb, optsB, _ := runTrustedCluster(t)
   754  	defer sa.Shutdown()
   755  	defer sb.Shutdown()
   756  
   757  	// Normal Account
   758  	okp, _ := nkeys.FromSeed(oSeed)
   759  	akp, _ := nkeys.CreateAccount()
   760  	pub, _ := akp.PublicKey()
   761  	nac := jwt.NewAccountClaims(pub)
   762  	nac.Limits.Conn = 4 // Limit to 4 connections.
   763  	jwt, _ := nac.Encode(okp)
   764  
   765  	addAccountToMemResolver(sa, pub, jwt)
   766  
   767  	// Listen for updates to the new account connection activity.
   768  	received := make(chan *nats.Msg, 10)
   769  	cb := func(sub *subscription, _ *client, _ *Account, subject, reply string, msg []byte) {
   770  		copy := append([]byte(nil), msg...)
   771  		received <- &nats.Msg{Subject: subject, Reply: reply, Data: copy}
   772  	}
   773  	subj := fmt.Sprintf(accConnsEventSubjNew, pub)
   774  	sub, err := sa.sysSubscribe(subj, cb)
   775  	if sub == nil || err != nil {
   776  		t.Fatalf("Expected to subscribe, got %v", err)
   777  	}
   778  	defer sa.sysUnsubscribe(sub)
   779  
   780  	// Create a few users on the new account.
   781  	clients := []*nats.Conn{}
   782  
   783  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
   784  	for i := 0; i < 4; i++ {
   785  		nc, err := nats.Connect(url, createUserCreds(t, sb, akp))
   786  		if err != nil {
   787  			t.Fatalf("Error on connect: %v", err)
   788  		}
   789  		defer nc.Close()
   790  		clients = append(clients, nc)
   791  	}
   792  
   793  	// Wait for all 4 notifications.
   794  	checkFor(t, time.Second, 50*time.Millisecond, func() error {
   795  		if len(received) == 4 {
   796  			return nil
   797  		}
   798  		return fmt.Errorf("Not enough messages, %d vs 4", len(received))
   799  	})
   800  
   801  	// Now lookup the account doing the events on sb.
   802  	acc, _ := sb.LookupAccount(pub)
   803  	// Make sure we have the timer running.
   804  	acc.mu.RLock()
   805  	ctmr := acc.ctmr
   806  	acc.mu.RUnlock()
   807  	if ctmr == nil {
   808  		t.Fatalf("Expected event timer for acc conns to be running")
   809  	}
   810  
   811  	// Now close all of the connections.
   812  	for _, nc := range clients {
   813  		nc.Close()
   814  	}
   815  
   816  	// Wait for the 4 new notifications, 8 total (4 for connect, 4 for disconnect)
   817  	checkFor(t, time.Second, 50*time.Millisecond, func() error {
   818  		if len(received) == 8 {
   819  			return nil
   820  		}
   821  		return fmt.Errorf("Not enough messages, %d vs 4", len(received))
   822  	})
   823  	// Drain the messages.
   824  	for i := 0; i < 7; i++ {
   825  		<-received
   826  	}
   827  	// Check last one.
   828  	msg := <-received
   829  	m := AccountNumConns{}
   830  	if err := json.Unmarshal(msg.Data, &m); err != nil {
   831  		t.Fatalf("Error unmarshalling account connections request message: %v", err)
   832  	}
   833  	if m.Conns != 0 {
   834  		t.Fatalf("Expected Conns to be 0, got %d", m.Conns)
   835  	}
   836  
   837  	// Should not receive any more messages..
   838  	select {
   839  	case <-received:
   840  		t.Fatalf("Did not expect a message here")
   841  	case <-time.After(50 * time.Millisecond):
   842  		break
   843  	}
   844  
   845  	// Make sure we have the timer is NOT running.
   846  	acc.mu.RLock()
   847  	ctmr = acc.ctmr
   848  	acc.mu.RUnlock()
   849  	if ctmr != nil {
   850  		t.Fatalf("Expected event timer for acc conns to NOT be running after reaching zero local clients")
   851  	}
   852  }
   853  
   854  func TestSystemAccountConnectionLimits(t *testing.T) {
   855  	sa, optsA, sb, optsB, _ := runTrustedCluster(t)
   856  	defer sa.Shutdown()
   857  	defer sb.Shutdown()
   858  
   859  	// We want to test that we are limited to a certain number of active connections
   860  	// across multiple servers.
   861  
   862  	// Let's create a user account.
   863  	okp, _ := nkeys.FromSeed(oSeed)
   864  	akp, _ := nkeys.CreateAccount()
   865  	pub, _ := akp.PublicKey()
   866  	nac := jwt.NewAccountClaims(pub)
   867  	nac.Limits.Conn = 4 // Limit to 4 connections.
   868  	jwt, _ := nac.Encode(okp)
   869  
   870  	addAccountToMemResolver(sa, pub, jwt)
   871  
   872  	urlA := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
   873  	urlB := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
   874  
   875  	// Create a user on each server. Break on first failure.
   876  	for {
   877  		nca1, err := nats.Connect(urlA, createUserCreds(t, sa, akp))
   878  		if err != nil {
   879  			break
   880  		}
   881  		defer nca1.Close()
   882  		ncb1, err := nats.Connect(urlB, createUserCreds(t, sb, akp))
   883  		if err != nil {
   884  			break
   885  		}
   886  		defer ncb1.Close()
   887  	}
   888  
   889  	checkFor(t, 5*time.Second, 50*time.Millisecond, func() error {
   890  		total := sa.NumClients() + sb.NumClients()
   891  		if total > int(nac.Limits.Conn) {
   892  			return fmt.Errorf("Expected only %d connections, was allowed to connect %d", nac.Limits.Conn, total)
   893  		}
   894  		return nil
   895  	})
   896  }
   897  
   898  func TestBadAccountUpdate(t *testing.T) {
   899  	sa, _ := runTrustedServer(t)
   900  	defer sa.Shutdown()
   901  	akp1, _ := nkeys.CreateAccount()
   902  	pub, _ := akp1.PublicKey()
   903  	nac := jwt.NewAccountClaims(pub)
   904  	ajwt1, err := nac.Encode(oKp)
   905  	require_NoError(t, err)
   906  	addAccountToMemResolver(sa, pub, ajwt1)
   907  	akp2, _ := nkeys.CreateAccount()
   908  	pub2, _ := akp2.PublicKey()
   909  	nac.Subject = pub2 // maliciously use a different subject but pretend to remain pub
   910  	ajwt2, err := nac.Encode(oKp)
   911  	require_NoError(t, err)
   912  	acc, err := sa.fetchAccount(pub)
   913  	require_NoError(t, err)
   914  	if err := sa.updateAccountWithClaimJWT(acc, ajwt2); err != ErrAccountValidation {
   915  		t.Fatalf("expected %v but got %v", ErrAccountValidation, err)
   916  	}
   917  }
   918  
   919  // Make sure connection limits apply to the system account itself.
   920  func TestSystemAccountSystemConnectionLimitsHonored(t *testing.T) {
   921  	sa, optsA, sb, optsB, sakp := runTrustedCluster(t)
   922  	defer sa.Shutdown()
   923  	defer sb.Shutdown()
   924  
   925  	okp, _ := nkeys.FromSeed(oSeed)
   926  	// Update system account to have 10 connections
   927  	pub, _ := sakp.PublicKey()
   928  	nac := jwt.NewAccountClaims(pub)
   929  	nac.Limits.Conn = 10
   930  	ajwt, _ := nac.Encode(okp)
   931  
   932  	addAccountToMemResolver(sa, pub, ajwt)
   933  	addAccountToMemResolver(sb, pub, ajwt)
   934  
   935  	// Update the accounts on each server with new claims to force update.
   936  	sysAccA := sa.SystemAccount()
   937  	sa.updateAccountWithClaimJWT(sysAccA, ajwt)
   938  	sysAccB := sb.SystemAccount()
   939  	sb.updateAccountWithClaimJWT(sysAccB, ajwt)
   940  
   941  	// Check system here first, with no external it should be zero.
   942  	sacc := sa.SystemAccount()
   943  	if nlc := sacc.NumLocalConnections(); nlc != 0 {
   944  		t.Fatalf("Expected no local connections, got %d", nlc)
   945  	}
   946  
   947  	urlA := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
   948  	urlB := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
   949  
   950  	// Create a user on each server. Break on first failure.
   951  	tc := 0
   952  	for {
   953  		nca1, err := nats.Connect(urlA, createUserCreds(t, sa, sakp))
   954  		if err != nil {
   955  			break
   956  		}
   957  		defer nca1.Close()
   958  		tc++
   959  
   960  		ncb1, err := nats.Connect(urlB, createUserCreds(t, sb, sakp))
   961  		if err != nil {
   962  			break
   963  		}
   964  		defer ncb1.Close()
   965  		tc++
   966  
   967  		// The account's connection count is exchanged between servers
   968  		// so that the local count on each server reflects the total count.
   969  		// Pause a bit to give a chance to each server to process the update.
   970  		time.Sleep(15 * time.Millisecond)
   971  	}
   972  	if tc != 10 {
   973  		t.Fatalf("Expected to get 10 external connections, got %d", tc)
   974  	}
   975  
   976  	checkFor(t, 1*time.Second, 50*time.Millisecond, func() error {
   977  		total := sa.NumClients() + sb.NumClients()
   978  		if total > int(nac.Limits.Conn) {
   979  			return fmt.Errorf("Expected only %d connections, was allowed to connect %d", nac.Limits.Conn, total)
   980  		}
   981  		return nil
   982  	})
   983  }
   984  
   985  // Test that the remote accounting works when a server is started some time later.
   986  func TestSystemAccountConnectionLimitsServersStaggered(t *testing.T) {
   987  	sa, optsA, sb, optsB, _ := runTrustedCluster(t)
   988  	defer sa.Shutdown()
   989  	sb.Shutdown()
   990  
   991  	// Let's create a user account.
   992  	okp, _ := nkeys.FromSeed(oSeed)
   993  	akp, _ := nkeys.CreateAccount()
   994  	pub, _ := akp.PublicKey()
   995  	nac := jwt.NewAccountClaims(pub)
   996  	nac.Limits.Conn = 4 // Limit to 4 connections.
   997  	jwt, _ := nac.Encode(okp)
   998  
   999  	addAccountToMemResolver(sa, pub, jwt)
  1000  
  1001  	urlA := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
  1002  	// Create max connections on sa.
  1003  	for i := 0; i < int(nac.Limits.Conn); i++ {
  1004  		nc, err := nats.Connect(urlA, createUserCreds(t, sa, akp))
  1005  		if err != nil {
  1006  			t.Fatalf("Unexpected error on #%d try: %v", i+1, err)
  1007  		}
  1008  		defer nc.Close()
  1009  	}
  1010  
  1011  	// Restart server B.
  1012  	optsB.AccountResolver = sa.AccountResolver()
  1013  	optsB.SystemAccount = sa.SystemAccount().Name
  1014  	sb = RunServer(optsB)
  1015  	defer sb.Shutdown()
  1016  	checkClusterFormed(t, sa, sb)
  1017  
  1018  	// Trigger a load of the user account on the new server
  1019  	// NOTE: If we do not load the user, the user can be the first
  1020  	// to request this account, hence the connection will succeed.
  1021  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  1022  		if acc, err := sb.LookupAccount(pub); acc == nil || err != nil {
  1023  			return fmt.Errorf("LookupAccount did not return account or failed, err=%v", err)
  1024  		}
  1025  		return nil
  1026  	})
  1027  
  1028  	// Expect this to fail.
  1029  	urlB := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  1030  	if _, err := nats.Connect(urlB, createUserCreds(t, sb, akp)); err == nil {
  1031  		t.Fatalf("Expected connection to fail due to max limit")
  1032  	}
  1033  }
  1034  
  1035  // Test that the remote accounting works when a server is shutdown.
  1036  func TestSystemAccountConnectionLimitsServerShutdownGraceful(t *testing.T) {
  1037  	sa, optsA, sb, optsB, _ := runTrustedCluster(t)
  1038  	defer sa.Shutdown()
  1039  	defer sb.Shutdown()
  1040  
  1041  	// Let's create a user account.
  1042  	okp, _ := nkeys.FromSeed(oSeed)
  1043  	akp, _ := nkeys.CreateAccount()
  1044  	pub, _ := akp.PublicKey()
  1045  	nac := jwt.NewAccountClaims(pub)
  1046  	nac.Limits.Conn = 10 // Limit to 10 connections.
  1047  	jwt, _ := nac.Encode(okp)
  1048  
  1049  	addAccountToMemResolver(sa, pub, jwt)
  1050  	addAccountToMemResolver(sb, pub, jwt)
  1051  
  1052  	urlA := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
  1053  	urlB := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  1054  
  1055  	for i := 0; i < 5; i++ {
  1056  		nc, err := nats.Connect(urlA, nats.NoReconnect(), createUserCreds(t, sa, akp))
  1057  		if err != nil {
  1058  			t.Fatalf("Expected to connect, got %v", err)
  1059  		}
  1060  		defer nc.Close()
  1061  		nc, err = nats.Connect(urlB, nats.NoReconnect(), createUserCreds(t, sb, akp))
  1062  		if err != nil {
  1063  			t.Fatalf("Expected to connect, got %v", err)
  1064  		}
  1065  		defer nc.Close()
  1066  	}
  1067  
  1068  	// We are at capacity so both of these should fail.
  1069  	if _, err := nats.Connect(urlA, createUserCreds(t, sa, akp)); err == nil {
  1070  		t.Fatalf("Expected connection to fail due to max limit")
  1071  	}
  1072  	if _, err := nats.Connect(urlB, createUserCreds(t, sb, akp)); err == nil {
  1073  		t.Fatalf("Expected connection to fail due to max limit")
  1074  	}
  1075  
  1076  	// Now shutdown Server B.
  1077  	sb.Shutdown()
  1078  
  1079  	// Now we should be able to create more on A now.
  1080  	for i := 0; i < 5; i++ {
  1081  		nc, err := nats.Connect(urlA, createUserCreds(t, sa, akp))
  1082  		if err != nil {
  1083  			t.Fatalf("Expected to connect on %d, got %v", i, err)
  1084  		}
  1085  		defer nc.Close()
  1086  	}
  1087  }
  1088  
  1089  // Test that the remote accounting works when a server goes away.
  1090  func TestSystemAccountConnectionLimitsServerShutdownForced(t *testing.T) {
  1091  	sa, optsA, sb, optsB, _ := runTrustedCluster(t)
  1092  	defer sa.Shutdown()
  1093  
  1094  	// Let's create a user account.
  1095  	okp, _ := nkeys.FromSeed(oSeed)
  1096  	akp, _ := nkeys.CreateAccount()
  1097  	pub, _ := akp.PublicKey()
  1098  	nac := jwt.NewAccountClaims(pub)
  1099  	nac.Limits.Conn = 20 // Limit to 20 connections.
  1100  	jwt, _ := nac.Encode(okp)
  1101  
  1102  	addAccountToMemResolver(sa, pub, jwt)
  1103  	addAccountToMemResolver(sb, pub, jwt)
  1104  
  1105  	urlA := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
  1106  	urlB := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  1107  
  1108  	for i := 0; i < 10; i++ {
  1109  		c, err := nats.Connect(urlA, nats.NoReconnect(), createUserCreds(t, sa, akp))
  1110  		if err != nil {
  1111  			t.Fatalf("Expected to connect, got %v", err)
  1112  		}
  1113  		defer c.Close()
  1114  		c, err = nats.Connect(urlB, nats.NoReconnect(), createUserCreds(t, sb, akp))
  1115  		if err != nil {
  1116  			t.Fatalf("Expected to connect, got %v", err)
  1117  		}
  1118  		defer c.Close()
  1119  	}
  1120  
  1121  	// Now shutdown Server B. Do so such that no communications go out.
  1122  	sb.mu.Lock()
  1123  	sb.sys = nil
  1124  	sb.mu.Unlock()
  1125  	sb.Shutdown()
  1126  
  1127  	if _, err := nats.Connect(urlA, createUserCreds(t, sa, akp)); err == nil {
  1128  		t.Fatalf("Expected connection to fail due to max limit")
  1129  	}
  1130  
  1131  	// Let's speed up the checking process.
  1132  	sa.mu.Lock()
  1133  	sa.sys.chkOrph = 10 * time.Millisecond
  1134  	sa.sys.orphMax = 30 * time.Millisecond
  1135  	sa.sys.sweeper.Reset(sa.sys.chkOrph)
  1136  	sa.mu.Unlock()
  1137  
  1138  	// We should eventually be able to connect.
  1139  	checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  1140  		if c, err := nats.Connect(urlA, createUserCreds(t, sa, akp)); err != nil {
  1141  			return err
  1142  		} else {
  1143  			c.Close()
  1144  		}
  1145  		return nil
  1146  	})
  1147  }
  1148  
  1149  func TestSystemAccountFromConfig(t *testing.T) {
  1150  	kp, _ := nkeys.FromSeed(oSeed)
  1151  	opub, _ := kp.PublicKey()
  1152  	akp, _ := nkeys.CreateAccount()
  1153  	apub, _ := akp.PublicKey()
  1154  	nac := jwt.NewAccountClaims(apub)
  1155  	ajwt, err := nac.Encode(kp)
  1156  	if err != nil {
  1157  		t.Fatalf("Error generating account JWT: %v", err)
  1158  	}
  1159  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1160  		w.Write([]byte(ajwt))
  1161  	}))
  1162  	defer ts.Close()
  1163  
  1164  	confTemplate := `
  1165  		listen: -1
  1166  		trusted: %s
  1167  		system_account: %s
  1168  		resolver: URL("%s/jwt/v1/accounts/")
  1169      `
  1170  
  1171  	conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, opub, apub, ts.URL)))
  1172  
  1173  	s, _ := RunServerWithConfig(conf)
  1174  	defer s.Shutdown()
  1175  
  1176  	if acc := s.SystemAccount(); acc == nil || acc.Name != apub {
  1177  		t.Fatalf("System Account not properly set")
  1178  	}
  1179  }
  1180  
  1181  func TestAccountClaimsUpdates(t *testing.T) {
  1182  	test := func(subj string) {
  1183  		s, opts := runTrustedServer(t)
  1184  		defer s.Shutdown()
  1185  
  1186  		sacc, sakp := createAccount(s)
  1187  		s.setSystemAccount(sacc)
  1188  
  1189  		// Let's create a normal account with limits we can update.
  1190  		okp, _ := nkeys.FromSeed(oSeed)
  1191  		akp, _ := nkeys.CreateAccount()
  1192  		pub, _ := akp.PublicKey()
  1193  		nac := jwt.NewAccountClaims(pub)
  1194  		nac.Limits.Conn = 4
  1195  		ajwt, _ := nac.Encode(okp)
  1196  
  1197  		addAccountToMemResolver(s, pub, ajwt)
  1198  
  1199  		acc, _ := s.LookupAccount(pub)
  1200  		if acc.MaxActiveConnections() != 4 {
  1201  			t.Fatalf("Expected to see a limit of 4 connections")
  1202  		}
  1203  
  1204  		// Simulate a systems publisher so we can do an account claims update.
  1205  		url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1206  		nc, err := nats.Connect(url, createUserCreds(t, s, sakp))
  1207  		if err != nil {
  1208  			t.Fatalf("Error on connect: %v", err)
  1209  		}
  1210  		defer nc.Close()
  1211  
  1212  		// Update the account
  1213  		nac = jwt.NewAccountClaims(pub)
  1214  		nac.Limits.Conn = 8
  1215  		issAt := time.Now().Add(-30 * time.Second).Unix()
  1216  		nac.IssuedAt = issAt
  1217  		expires := time.Now().Add(2 * time.Second).Unix()
  1218  		nac.Expires = expires
  1219  		ajwt, _ = nac.Encode(okp)
  1220  
  1221  		// Publish to the system update subject.
  1222  		claimUpdateSubj := fmt.Sprintf(subj, pub)
  1223  		nc.Publish(claimUpdateSubj, []byte(ajwt))
  1224  		nc.Flush()
  1225  		time.Sleep(200 * time.Millisecond)
  1226  
  1227  		acc, _ = s.LookupAccount(pub)
  1228  		if acc.MaxActiveConnections() != 8 {
  1229  			t.Fatalf("Account was not updated")
  1230  		}
  1231  	}
  1232  	t.Run("new", func(t *testing.T) {
  1233  		test(accUpdateEventSubjNew)
  1234  	})
  1235  	t.Run("old", func(t *testing.T) {
  1236  		test(accUpdateEventSubjOld)
  1237  	})
  1238  }
  1239  
  1240  func TestAccountReqMonitoring(t *testing.T) {
  1241  	s, opts := runTrustedServer(t)
  1242  	defer s.Shutdown()
  1243  	sacc, sakp := createAccount(s)
  1244  	s.setSystemAccount(sacc)
  1245  	s.EnableJetStream(&JetStreamConfig{StoreDir: t.TempDir()})
  1246  	unusedAcc, _ := createAccount(s)
  1247  	acc, akp := createAccount(s)
  1248  	acc.EnableJetStream(nil)
  1249  	subsz := fmt.Sprintf(accDirectReqSubj, acc.Name, "SUBSZ")
  1250  	connz := fmt.Sprintf(accDirectReqSubj, acc.Name, "CONNZ")
  1251  	jsz := fmt.Sprintf(accDirectReqSubj, acc.Name, "JSZ")
  1252  
  1253  	pStatz := fmt.Sprintf(accPingReqSubj, "STATZ")
  1254  	statz := func(name string) string { return fmt.Sprintf(accDirectReqSubj, name, "STATZ") }
  1255  	// Create system account connection to query
  1256  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1257  	ncSys, err := nats.Connect(url, createUserCreds(t, s, sakp))
  1258  	if err != nil {
  1259  		t.Fatalf("Error on connect: %v", err)
  1260  	}
  1261  	defer ncSys.Close()
  1262  	// Create a connection that we can query
  1263  	nc, err := nats.Connect(url, createUserCreds(t, s, akp))
  1264  	if err != nil {
  1265  		t.Fatalf("Error on connect: %v", err)
  1266  	}
  1267  	defer nc.Close()
  1268  	// query SUBSZ for account
  1269  	resp, err := ncSys.Request(subsz, nil, time.Second)
  1270  	require_NoError(t, err)
  1271  	require_Contains(t, string(resp.Data), `"num_subscriptions":5,`)
  1272  	// create a subscription
  1273  	sub, err := nc.Subscribe("foo", func(msg *nats.Msg) {})
  1274  	require_NoError(t, err)
  1275  	defer sub.Unsubscribe()
  1276  
  1277  	require_NoError(t, nc.Flush())
  1278  	// query SUBSZ for account
  1279  	resp, err = ncSys.Request(subsz, nil, time.Second)
  1280  	require_NoError(t, err)
  1281  	require_Contains(t, string(resp.Data), `"num_subscriptions":6,`, `"subject":"foo"`)
  1282  	// query connections for account
  1283  	resp, err = ncSys.Request(connz, nil, time.Second)
  1284  	require_NoError(t, err)
  1285  	require_Contains(t, string(resp.Data), `"num_connections":1,`, `"total":1,`)
  1286  	// query connections for js account
  1287  	resp, err = ncSys.Request(jsz, nil, time.Second)
  1288  	require_NoError(t, err)
  1289  	require_Contains(t, string(resp.Data), `"memory":0,`, `"storage":0,`)
  1290  	// query statz/conns for account
  1291  	resp, err = ncSys.Request(statz(acc.Name), nil, time.Second)
  1292  	require_NoError(t, err)
  1293  	respContentAcc := []string{`"conns":1,`, `"total_conns":1`, `"slow_consumers":0`, `"sent":{"msgs":0,"bytes":0}`,
  1294  		`"received":{"msgs":0,"bytes":0}`, `"num_subscriptions":`, fmt.Sprintf(`"acc":"%s"`, acc.Name)}
  1295  	require_Contains(t, string(resp.Data), respContentAcc...)
  1296  
  1297  	rIb := ncSys.NewRespInbox()
  1298  	rSub, err := ncSys.SubscribeSync(rIb)
  1299  	require_NoError(t, err)
  1300  	require_NoError(t, ncSys.PublishRequest(pStatz, rIb, nil))
  1301  	minRespContentForBothAcc := []string{`"conns":1,`, `"total_conns":1`, `"slow_consumers":0`, `"acc":"`, `"num_subscriptions":`}
  1302  	resp, err = rSub.NextMsg(time.Second)
  1303  	require_NoError(t, err)
  1304  	require_Contains(t, string(resp.Data), minRespContentForBothAcc...)
  1305  	// expect one entry per account
  1306  	require_Contains(t, string(resp.Data), fmt.Sprintf(`"acc":"%s"`, acc.Name), fmt.Sprintf(`"acc":"%s"`, sacc.Name))
  1307  
  1308  	// Test ping with filter by account name
  1309  	require_NoError(t, ncSys.PublishRequest(pStatz, rIb, []byte(fmt.Sprintf(`{"accounts":["%s"]}`, sacc.Name))))
  1310  	m, err := rSub.NextMsg(time.Second)
  1311  	require_NoError(t, err)
  1312  	require_Contains(t, string(m.Data), minRespContentForBothAcc...)
  1313  
  1314  	require_NoError(t, ncSys.PublishRequest(pStatz, rIb, []byte(fmt.Sprintf(`{"accounts":["%s"]}`, acc.Name))))
  1315  	m, err = rSub.NextMsg(time.Second)
  1316  	require_NoError(t, err)
  1317  	require_Contains(t, string(m.Data), respContentAcc...)
  1318  
  1319  	// Test include unused for statz and ping of statz
  1320  	unusedContent := []string{`"conns":0,`, `"total_conns":0`, `"slow_consumers":0`,
  1321  		fmt.Sprintf(`"acc":"%s"`, unusedAcc.Name)}
  1322  
  1323  	resp, err = ncSys.Request(statz(unusedAcc.Name),
  1324  		[]byte(fmt.Sprintf(`{"accounts":["%s"], "include_unused":true}`, unusedAcc.Name)),
  1325  		time.Second)
  1326  	require_NoError(t, err)
  1327  	require_Contains(t, string(resp.Data), unusedContent...)
  1328  
  1329  	require_NoError(t, ncSys.PublishRequest(pStatz, rIb,
  1330  		[]byte(fmt.Sprintf(`{"accounts":["%s"], "include_unused":true}`, unusedAcc.Name))))
  1331  	resp, err = rSub.NextMsg(time.Second)
  1332  	require_NoError(t, err)
  1333  	require_Contains(t, string(resp.Data), unusedContent...)
  1334  
  1335  	require_NoError(t, ncSys.PublishRequest(pStatz, rIb, []byte(fmt.Sprintf(`{"accounts":["%s"]}`, unusedAcc.Name))))
  1336  	_, err = rSub.NextMsg(200 * time.Millisecond)
  1337  	require_Error(t, err)
  1338  
  1339  	// Test ping from within account, send extra message to check counters.
  1340  	require_NoError(t, nc.Publish("foo", nil))
  1341  	ib := nc.NewRespInbox()
  1342  	rSub, err = nc.SubscribeSync(ib)
  1343  	require_NoError(t, err)
  1344  	require_NoError(t, nc.PublishRequest(pStatz, ib, nil))
  1345  	require_NoError(t, nc.Flush())
  1346  	resp, err = rSub.NextMsg(time.Second)
  1347  	require_NoError(t, err)
  1348  
  1349  	// Since we now have processed our own message, sent msgs will be at least 1.
  1350  	payload := string(resp.Data)
  1351  	respContentAcc = []string{`"conns":1,`, `"total_conns":1`, `"slow_consumers":0`, `"sent":{"msgs":1,"bytes":0}`, fmt.Sprintf(`"acc":"%s"`, acc.Name)}
  1352  	require_Contains(t, payload, respContentAcc...)
  1353  
  1354  	// Depending on timing, statz message could be accounted too.
  1355  	receivedOK := strings.Contains(payload, `"received":{"msgs":1,"bytes":0}`) || strings.Contains(payload, `"received":{"msgs":2,"bytes":0}`)
  1356  	require_True(t, receivedOK)
  1357  	_, err = rSub.NextMsg(200 * time.Millisecond)
  1358  	require_Error(t, err)
  1359  }
  1360  
  1361  func TestAccountReqInfo(t *testing.T) {
  1362  	s, opts := runTrustedServer(t)
  1363  	defer s.Shutdown()
  1364  	sacc, sakp := createAccount(s)
  1365  	s.setSystemAccount(sacc)
  1366  	// Let's create an account with service export.
  1367  	akp, _ := nkeys.CreateAccount()
  1368  	pub1, _ := akp.PublicKey()
  1369  	nac1 := jwt.NewAccountClaims(pub1)
  1370  	nac1.Exports.Add(&jwt.Export{Subject: "req.*", Type: jwt.Service})
  1371  	ajwt1, _ := nac1.Encode(oKp)
  1372  	addAccountToMemResolver(s, pub1, ajwt1)
  1373  	s.LookupAccount(pub1)
  1374  	info1 := fmt.Sprintf(accDirectReqSubj, pub1, "INFO")
  1375  	// Now add an account with service imports.
  1376  	akp2, _ := nkeys.CreateAccount()
  1377  	pub2, _ := akp2.PublicKey()
  1378  	nac2 := jwt.NewAccountClaims(pub2)
  1379  	nac2.Imports.Add(&jwt.Import{Account: pub1, Subject: "req.1", Type: jwt.Service})
  1380  	ajwt2, _ := nac2.Encode(oKp)
  1381  	addAccountToMemResolver(s, pub2, ajwt2)
  1382  	s.LookupAccount(pub2)
  1383  	info2 := fmt.Sprintf(accDirectReqSubj, pub2, "INFO")
  1384  	// Create system account connection to query
  1385  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1386  	ncSys, err := nats.Connect(url, createUserCreds(t, s, sakp))
  1387  	if err != nil {
  1388  		t.Fatalf("Error on connect: %v", err)
  1389  	}
  1390  	defer ncSys.Close()
  1391  	checkCommon := func(info *AccountInfo, srv *ServerInfo, pub, jwt string) {
  1392  		if info.Complete != true {
  1393  			t.Fatalf("Unexpected value: %v", info.Complete)
  1394  		} else if info.Expired != false {
  1395  			t.Fatalf("Unexpected value: %v", info.Expired)
  1396  		} else if info.JetStream != false {
  1397  			t.Fatalf("Unexpected value: %v", info.JetStream)
  1398  		} else if info.ClientCnt != 0 {
  1399  			t.Fatalf("Unexpected value: %v", info.ClientCnt)
  1400  		} else if info.AccountName != pub {
  1401  			t.Fatalf("Unexpected value: %v", info.AccountName)
  1402  		} else if info.LeafCnt != 0 {
  1403  			t.Fatalf("Unexpected value: %v", info.LeafCnt)
  1404  		} else if info.Jwt != jwt {
  1405  			t.Fatalf("Unexpected value: %v", info.Jwt)
  1406  		} else if srv.Cluster != "abc" {
  1407  			t.Fatalf("Unexpected value: %v", srv.Cluster)
  1408  		} else if srv.Name != s.Name() {
  1409  			t.Fatalf("Unexpected value: %v", srv.Name)
  1410  		} else if srv.Host != opts.Host {
  1411  			t.Fatalf("Unexpected value: %v", srv.Host)
  1412  		} else if srv.Seq < 1 {
  1413  			t.Fatalf("Unexpected value: %v", srv.Seq)
  1414  		}
  1415  	}
  1416  	info := AccountInfo{}
  1417  	srv := ServerInfo{}
  1418  	msg := struct {
  1419  		Data *AccountInfo `json:"data"`
  1420  		Srv  *ServerInfo  `json:"server"`
  1421  	}{
  1422  		&info,
  1423  		&srv,
  1424  	}
  1425  	if resp, err := ncSys.Request(info1, nil, time.Second); err != nil {
  1426  		t.Fatalf("Error on request: %v", err)
  1427  	} else if err := json.Unmarshal(resp.Data, &msg); err != nil {
  1428  		t.Fatalf("Unmarshalling failed: %v", err)
  1429  	} else if len(info.Exports) != 1 {
  1430  		t.Fatalf("Unexpected value: %v", info.Exports)
  1431  	} else if len(info.Imports) != 4 {
  1432  		t.Fatalf("Unexpected value: %+v", info.Imports)
  1433  	} else if info.Exports[0].Subject != "req.*" {
  1434  		t.Fatalf("Unexpected value: %v", info.Exports)
  1435  	} else if info.Exports[0].Type != jwt.Service {
  1436  		t.Fatalf("Unexpected value: %v", info.Exports)
  1437  	} else if info.Exports[0].ResponseType != jwt.ResponseTypeSingleton {
  1438  		t.Fatalf("Unexpected value: %v", info.Exports)
  1439  	} else if info.SubCnt != 4 {
  1440  		t.Fatalf("Unexpected value: %v", info.SubCnt)
  1441  	} else {
  1442  		checkCommon(&info, &srv, pub1, ajwt1)
  1443  	}
  1444  	info = AccountInfo{}
  1445  	srv = ServerInfo{}
  1446  	if resp, err := ncSys.Request(info2, nil, time.Second); err != nil {
  1447  		t.Fatalf("Error on request: %v", err)
  1448  	} else if err := json.Unmarshal(resp.Data, &msg); err != nil {
  1449  		t.Fatalf("Unmarshalling failed: %v", err)
  1450  	} else if len(info.Exports) != 0 {
  1451  		t.Fatalf("Unexpected value: %v", info.Exports)
  1452  	} else if len(info.Imports) != 5 {
  1453  		t.Fatalf("Unexpected value: %+v", info.Imports)
  1454  	}
  1455  	// Here we need to find our import
  1456  	var si *ExtImport
  1457  	for _, im := range info.Imports {
  1458  		if im.Subject == "req.1" {
  1459  			si = &im
  1460  			break
  1461  		}
  1462  	}
  1463  	if si == nil {
  1464  		t.Fatalf("Could not find our import")
  1465  	}
  1466  	if si.Type != jwt.Service {
  1467  		t.Fatalf("Unexpected value: %+v", si)
  1468  	} else if si.Account != pub1 {
  1469  		t.Fatalf("Unexpected value: %+v", si)
  1470  	} else if info.SubCnt != 5 {
  1471  		t.Fatalf("Unexpected value: %+v", si)
  1472  	} else {
  1473  		checkCommon(&info, &srv, pub2, ajwt2)
  1474  	}
  1475  }
  1476  
  1477  func TestAccountClaimsUpdatesWithServiceImports(t *testing.T) {
  1478  	s, opts := runTrustedServer(t)
  1479  	defer s.Shutdown()
  1480  
  1481  	sacc, sakp := createAccount(s)
  1482  	s.setSystemAccount(sacc)
  1483  
  1484  	okp, _ := nkeys.FromSeed(oSeed)
  1485  
  1486  	// Let's create an account with service export.
  1487  	akp, _ := nkeys.CreateAccount()
  1488  	pub, _ := akp.PublicKey()
  1489  	nac := jwt.NewAccountClaims(pub)
  1490  	nac.Exports.Add(&jwt.Export{Subject: "req.*", Type: jwt.Service})
  1491  	ajwt, _ := nac.Encode(okp)
  1492  	addAccountToMemResolver(s, pub, ajwt)
  1493  	s.LookupAccount(pub)
  1494  
  1495  	// Now add an account with multiple service imports.
  1496  	akp2, _ := nkeys.CreateAccount()
  1497  	pub2, _ := akp2.PublicKey()
  1498  	nac2 := jwt.NewAccountClaims(pub2)
  1499  	nac2.Imports.Add(&jwt.Import{Account: pub, Subject: "req.1", Type: jwt.Service})
  1500  	ajwt2, _ := nac2.Encode(okp)
  1501  
  1502  	addAccountToMemResolver(s, pub2, ajwt2)
  1503  	s.LookupAccount(pub2)
  1504  
  1505  	startSubs := s.NumSubscriptions()
  1506  
  1507  	// Simulate a systems publisher so we can do an account claims update.
  1508  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1509  	nc, err := nats.Connect(url, createUserCreds(t, s, sakp))
  1510  	if err != nil {
  1511  		t.Fatalf("Error on connect: %v", err)
  1512  	}
  1513  	defer nc.Close()
  1514  
  1515  	// Update the account several times
  1516  	for i := 1; i <= 10; i++ {
  1517  		nac2 = jwt.NewAccountClaims(pub2)
  1518  		nac2.Limits.Conn = int64(i)
  1519  		nac2.Imports.Add(&jwt.Import{Account: pub, Subject: "req.1", Type: jwt.Service})
  1520  		ajwt2, _ = nac2.Encode(okp)
  1521  
  1522  		// Publish to the system update subject.
  1523  		claimUpdateSubj := fmt.Sprintf(accUpdateEventSubjNew, pub2)
  1524  		nc.Publish(claimUpdateSubj, []byte(ajwt2))
  1525  	}
  1526  	nc.Flush()
  1527  	time.Sleep(50 * time.Millisecond)
  1528  
  1529  	if startSubs < s.NumSubscriptions() {
  1530  		t.Fatalf("Subscriptions leaked: %d vs %d", startSubs, s.NumSubscriptions())
  1531  	}
  1532  }
  1533  
  1534  func TestAccountConnsLimitExceededAfterUpdate(t *testing.T) {
  1535  	s, opts := runTrustedServer(t)
  1536  	defer s.Shutdown()
  1537  
  1538  	sacc, _ := createAccount(s)
  1539  	s.setSystemAccount(sacc)
  1540  
  1541  	// Let's create a normal  account with limits we can update.
  1542  	okp, _ := nkeys.FromSeed(oSeed)
  1543  	akp, _ := nkeys.CreateAccount()
  1544  	pub, _ := akp.PublicKey()
  1545  	nac := jwt.NewAccountClaims(pub)
  1546  	nac.Limits.Conn = 10
  1547  	ajwt, _ := nac.Encode(okp)
  1548  
  1549  	addAccountToMemResolver(s, pub, ajwt)
  1550  	acc, _ := s.LookupAccount(pub)
  1551  
  1552  	// Now create the max connections.
  1553  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1554  	for {
  1555  		nc, err := nats.Connect(url, createUserCreds(t, s, akp))
  1556  		if err != nil {
  1557  			break
  1558  		}
  1559  		defer nc.Close()
  1560  	}
  1561  
  1562  	// We should have max here.
  1563  	checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  1564  		if total := s.NumClients(); total != acc.MaxActiveConnections() {
  1565  			return fmt.Errorf("Expected %d connections, got %d", acc.MaxActiveConnections(), total)
  1566  		}
  1567  		return nil
  1568  	})
  1569  
  1570  	// Now change limits to make current connections over the limit.
  1571  	nac = jwt.NewAccountClaims(pub)
  1572  	nac.Limits.Conn = 2
  1573  	ajwt, _ = nac.Encode(okp)
  1574  
  1575  	s.updateAccountWithClaimJWT(acc, ajwt)
  1576  	if acc.MaxActiveConnections() != 2 {
  1577  		t.Fatalf("Expected max connections to be set to 2, got %d", acc.MaxActiveConnections())
  1578  	}
  1579  	// We should have closed the excess connections.
  1580  	checkClientsCount(t, s, acc.MaxActiveConnections())
  1581  }
  1582  
  1583  func TestAccountConnsLimitExceededAfterUpdateDisconnectNewOnly(t *testing.T) {
  1584  	s, opts := runTrustedServer(t)
  1585  	defer s.Shutdown()
  1586  
  1587  	sacc, _ := createAccount(s)
  1588  	s.setSystemAccount(sacc)
  1589  
  1590  	// Let's create a normal  account with limits we can update.
  1591  	okp, _ := nkeys.FromSeed(oSeed)
  1592  	akp, _ := nkeys.CreateAccount()
  1593  	pub, _ := akp.PublicKey()
  1594  	nac := jwt.NewAccountClaims(pub)
  1595  	nac.Limits.Conn = 10
  1596  	ajwt, _ := nac.Encode(okp)
  1597  
  1598  	addAccountToMemResolver(s, pub, ajwt)
  1599  	acc, _ := s.LookupAccount(pub)
  1600  
  1601  	// Now create the max connections.
  1602  	// We create half then we will wait and then create the rest.
  1603  	// Will test that we disconnect the newest ones.
  1604  	newConns := make([]*nats.Conn, 0, 5)
  1605  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  1606  	for i := 0; i < 5; i++ {
  1607  		nc, err := nats.Connect(url, nats.NoReconnect(), createUserCreds(t, s, akp))
  1608  		require_NoError(t, err)
  1609  		defer nc.Close()
  1610  	}
  1611  	time.Sleep(500 * time.Millisecond)
  1612  	for i := 0; i < 5; i++ {
  1613  		nc, err := nats.Connect(url, nats.NoReconnect(), createUserCreds(t, s, akp))
  1614  		require_NoError(t, err)
  1615  		defer nc.Close()
  1616  		newConns = append(newConns, nc)
  1617  	}
  1618  
  1619  	// We should have max here.
  1620  	checkClientsCount(t, s, acc.MaxActiveConnections())
  1621  
  1622  	// Now change limits to make current connections over the limit.
  1623  	nac = jwt.NewAccountClaims(pub)
  1624  	nac.Limits.Conn = 5
  1625  	ajwt, _ = nac.Encode(okp)
  1626  
  1627  	s.updateAccountWithClaimJWT(acc, ajwt)
  1628  	if acc.MaxActiveConnections() != 5 {
  1629  		t.Fatalf("Expected max connections to be set to 2, got %d", acc.MaxActiveConnections())
  1630  	}
  1631  	// We should have closed the excess connections.
  1632  	checkClientsCount(t, s, acc.MaxActiveConnections())
  1633  
  1634  	// Now make sure that only the new ones were closed.
  1635  	var closed int
  1636  	for _, nc := range newConns {
  1637  		if !nc.IsClosed() {
  1638  			closed++
  1639  		}
  1640  	}
  1641  	if closed != 5 {
  1642  		t.Fatalf("Expected all new clients to be closed, only got %d of 5", closed)
  1643  	}
  1644  }
  1645  
  1646  func TestSystemAccountWithBadRemoteLatencyUpdate(t *testing.T) {
  1647  	s, _ := runTrustedServer(t)
  1648  	defer s.Shutdown()
  1649  
  1650  	acc, _ := createAccount(s)
  1651  	s.setSystemAccount(acc)
  1652  
  1653  	rl := remoteLatency{
  1654  		Account: "NONSENSE",
  1655  		ReqId:   "_INBOX.22",
  1656  	}
  1657  	b, _ := json.Marshal(&rl)
  1658  	s.remoteLatencyUpdate(nil, nil, nil, "foo", _EMPTY_, nil, b)
  1659  }
  1660  
  1661  func TestSystemAccountWithGateways(t *testing.T) {
  1662  	sa, oa, sb, ob, akp := runTrustedGateways(t)
  1663  	defer sa.Shutdown()
  1664  	defer sb.Shutdown()
  1665  
  1666  	// Create a client on A that will subscribe on $SYS.ACCOUNT.>
  1667  	urla := fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port)
  1668  	nca := natsConnect(t, urla, createUserCreds(t, sa, akp), nats.Name("SYS"))
  1669  	defer nca.Close()
  1670  	nca.Flush()
  1671  
  1672  	sub, _ := nca.SubscribeSync("$SYS.ACCOUNT.>")
  1673  	defer sub.Unsubscribe()
  1674  	nca.Flush()
  1675  
  1676  	// If this tests fails with wrong number after 10 seconds we may have
  1677  	// added a new inititial subscription for the eventing system.
  1678  	checkExpectedSubs(t, 56, sa)
  1679  
  1680  	// Create a client on B and see if we receive the event
  1681  	urlb := fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port)
  1682  	ncb := natsConnect(t, urlb, createUserCreds(t, sb, akp), nats.Name("TEST EVENTS"))
  1683  	defer ncb.Close()
  1684  
  1685  	// space for .CONNECT and .CONNS from SYS and $G as well as one extra message
  1686  	msgs := [4]*nats.Msg{}
  1687  	var err error
  1688  	msgs[0], err = sub.NextMsg(time.Second)
  1689  	require_NoError(t, err)
  1690  	msgs[1], err = sub.NextMsg(time.Second)
  1691  	require_NoError(t, err)
  1692  	// TODO: There is a race currently that can cause the server to process the
  1693  	// system event *after* the subscription on "A" has been registered, and so
  1694  	// the "nca" client would receive its own CONNECT message.
  1695  	msgs[2], _ = sub.NextMsg(250 * time.Millisecond)
  1696  
  1697  	findMsgs := func(sub string) []*nats.Msg {
  1698  		rMsgs := []*nats.Msg{}
  1699  		for _, m := range msgs {
  1700  			if m == nil {
  1701  				continue
  1702  			}
  1703  			if m.Subject == sub {
  1704  				rMsgs = append(rMsgs, m)
  1705  			}
  1706  		}
  1707  		return rMsgs
  1708  	}
  1709  
  1710  	msg := findMsgs(fmt.Sprintf("$SYS.ACCOUNT.%s.CONNECT", sa.SystemAccount().Name))
  1711  	var bMsg *nats.Msg
  1712  	if len(msg) < 1 {
  1713  		t.Fatal("Expected at least one message")
  1714  	}
  1715  	bMsg = msg[len(msg)-1]
  1716  
  1717  	require_Contains(t, string(bMsg.Data), sb.ID())
  1718  	require_Contains(t, string(bMsg.Data), `"cluster":"B"`)
  1719  	require_Contains(t, string(bMsg.Data), `"name":"TEST EVENTS"`)
  1720  
  1721  	connsMsgA := findMsgs(fmt.Sprintf("$SYS.ACCOUNT.%s.SERVER.CONNS", sa.SystemAccount().Name))
  1722  	if len(connsMsgA) != 1 {
  1723  		t.Fatal("Expected a message")
  1724  	}
  1725  }
  1726  
  1727  func TestSystemAccountNoAuthUser(t *testing.T) {
  1728  	conf := createConfFile(t, []byte(`
  1729  		listen: "127.0.0.1:-1"
  1730  		accounts {
  1731  			$SYS {
  1732  				users [{user: "admin", password: "pwd"}]
  1733  			}
  1734  		}
  1735  	`))
  1736  	defer os.Remove(conf)
  1737  	s, o := RunServerWithConfig(conf)
  1738  	defer s.Shutdown()
  1739  
  1740  	for _, test := range []struct {
  1741  		name    string
  1742  		usrInfo string
  1743  		ok      bool
  1744  		account string
  1745  	}{
  1746  		{"valid user/pwd", "admin:pwd@", true, "$SYS"},
  1747  		{"invalid pwd", "admin:wrong@", false, _EMPTY_},
  1748  		{"some token", "sometoken@", false, _EMPTY_},
  1749  		{"user used without pwd", "admin@", false, _EMPTY_}, // will be treated as a token
  1750  		{"user with empty password", "admin:@", false, _EMPTY_},
  1751  		{"no user means global account", _EMPTY_, true, globalAccountName},
  1752  	} {
  1753  		t.Run(test.name, func(t *testing.T) {
  1754  			url := fmt.Sprintf("nats://%s127.0.0.1:%d", test.usrInfo, o.Port)
  1755  			nc, err := nats.Connect(url)
  1756  			if err != nil {
  1757  				if test.ok {
  1758  					t.Fatalf("Unexpected error: %v", err)
  1759  				}
  1760  				return
  1761  			} else if !test.ok {
  1762  				nc.Close()
  1763  				t.Fatalf("Should have failed, did not")
  1764  			}
  1765  			var accName string
  1766  			s.mu.Lock()
  1767  			for _, c := range s.clients {
  1768  				c.mu.Lock()
  1769  				if c.acc != nil {
  1770  					accName = c.acc.Name
  1771  				}
  1772  				c.mu.Unlock()
  1773  				break
  1774  			}
  1775  			s.mu.Unlock()
  1776  			nc.Close()
  1777  			checkClientsCount(t, s, 0)
  1778  			if accName != test.account {
  1779  				t.Fatalf("The account should have been %q, got %q", test.account, accName)
  1780  			}
  1781  		})
  1782  	}
  1783  }
  1784  
  1785  func TestServerAccountConns(t *testing.T) {
  1786  	// speed up hb
  1787  	orgHBInterval := eventsHBInterval
  1788  	eventsHBInterval = time.Millisecond * 100
  1789  	defer func() { eventsHBInterval = orgHBInterval }()
  1790  	conf := createConfFile(t, []byte(`
  1791  	   host: 127.0.0.1
  1792  	   port: -1
  1793  	   system_account: SYS
  1794  	   accounts: {
  1795  			   SYS: {users: [{user: s, password: s}]}
  1796  			   ACC: {users: [{user: a, password: a}]}
  1797  	   }`))
  1798  	s, _ := RunServerWithConfig(conf)
  1799  	defer s.Shutdown()
  1800  
  1801  	nc := natsConnect(t, s.ClientURL(), nats.UserInfo("a", "a"))
  1802  	defer nc.Close()
  1803  
  1804  	subOut, err := nc.SubscribeSync("foo")
  1805  	require_NoError(t, err)
  1806  	hw := "HELLO WORLD"
  1807  	nc.Publish("foo", []byte(hw))
  1808  	nc.Publish("bar", []byte(hw)) // will only count towards received
  1809  	nc.Flush()
  1810  	m, err := subOut.NextMsg(time.Second)
  1811  	require_NoError(t, err)
  1812  	require_Equal(t, string(m.Data), hw)
  1813  
  1814  	ncs := natsConnect(t, s.ClientURL(), nats.UserInfo("s", "s"))
  1815  	defer ncs.Close()
  1816  	subs, err := ncs.SubscribeSync("$SYS.ACCOUNT.ACC.SERVER.CONNS")
  1817  	require_NoError(t, err)
  1818  
  1819  	m, err = subs.NextMsg(time.Second)
  1820  	require_NoError(t, err)
  1821  	accConns := &AccountNumConns{}
  1822  	err = json.Unmarshal(m.Data, accConns)
  1823  	require_NoError(t, err)
  1824  
  1825  	require_True(t, accConns.Received.Msgs == 2)
  1826  	require_True(t, accConns.Received.Bytes == 2*int64(len(hw)))
  1827  	require_True(t, accConns.Sent.Msgs == 1)
  1828  	require_True(t, accConns.Sent.Bytes == int64(len(hw)))
  1829  }
  1830  
  1831  func TestServerEventsStatsZ(t *testing.T) {
  1832  	serverStatsReqSubj := "$SYS.REQ.SERVER.%s.STATSZ"
  1833  	preStart := time.Now().UTC()
  1834  	// Add little bit of delay to make sure that time check
  1835  	// between pre-start and actual start does not fail.
  1836  	time.Sleep(5 * time.Millisecond)
  1837  	sa, optsA, sb, _, akp := runTrustedCluster(t)
  1838  	defer sa.Shutdown()
  1839  	defer sb.Shutdown()
  1840  	// Same between actual start and post start.
  1841  	time.Sleep(5 * time.Millisecond)
  1842  	postStart := time.Now().UTC()
  1843  
  1844  	url := fmt.Sprintf("nats://%s:%d", optsA.Host, optsA.Port)
  1845  	ncs, err := nats.Connect(url, createUserCreds(t, sa, akp))
  1846  	if err != nil {
  1847  		t.Fatalf("Error on connect: %v", err)
  1848  	}
  1849  	defer ncs.Close()
  1850  
  1851  	subj := fmt.Sprintf(serverStatsSubj, sa.ID())
  1852  	sub, _ := ncs.SubscribeSync(subj)
  1853  	defer sub.Unsubscribe()
  1854  	ncs.Publish("foo", []byte("HELLO WORLD"))
  1855  	ncs.Flush()
  1856  
  1857  	// Let's speed up the checking process.
  1858  	sa.mu.Lock()
  1859  	sa.sys.statsz = 10 * time.Millisecond
  1860  	sa.sys.stmr.Reset(sa.sys.statsz)
  1861  	sa.mu.Unlock()
  1862  
  1863  	_, err = sub.NextMsg(time.Second)
  1864  	if err != nil {
  1865  		t.Fatalf("Error receiving msg: %v", err)
  1866  	}
  1867  	// Get it the second time so we can check some stats
  1868  	msg, err := sub.NextMsg(time.Second)
  1869  	if err != nil {
  1870  		t.Fatalf("Error receiving msg: %v", err)
  1871  	}
  1872  	m := ServerStatsMsg{}
  1873  	if err := json.Unmarshal(msg.Data, &m); err != nil {
  1874  		t.Fatalf("Error unmarshalling the statz json: %v", err)
  1875  	}
  1876  	if m.Server.ID != sa.ID() {
  1877  		t.Fatalf("Did not match IDs")
  1878  	}
  1879  	if m.Server.Cluster != "TEST CLUSTER 22" {
  1880  		t.Fatalf("Did not match cluster name")
  1881  	}
  1882  	if m.Server.Version != VERSION {
  1883  		t.Fatalf("Did not match server version")
  1884  	}
  1885  	if !m.Stats.Start.After(preStart) && m.Stats.Start.Before(postStart) {
  1886  		t.Fatalf("Got a wrong start time for the server %v", m.Stats.Start)
  1887  	}
  1888  	if m.Stats.Connections != 1 {
  1889  		t.Fatalf("Did not match connections of 1, got %d", m.Stats.Connections)
  1890  	}
  1891  	if m.Stats.ActiveAccounts != 2 {
  1892  		t.Fatalf("Did not match active accounts of 2, got %d", m.Stats.ActiveAccounts)
  1893  	}
  1894  	if m.Stats.Sent.Msgs < 1 {
  1895  		t.Fatalf("Did not match sent msgs of >=1, got %d", m.Stats.Sent.Msgs)
  1896  	}
  1897  	if m.Stats.Received.Msgs < 1 {
  1898  		t.Fatalf("Did not match received msgs of >=1, got %d", m.Stats.Received.Msgs)
  1899  	}
  1900  	// Default pool size + 1 for system account
  1901  	expectedRoutes := DEFAULT_ROUTE_POOL_SIZE + 1
  1902  	if lr := len(m.Stats.Routes); lr != expectedRoutes {
  1903  		t.Fatalf("Expected %d routes, but got %d", expectedRoutes, lr)
  1904  	}
  1905  
  1906  	// Now let's prompt this server to send us the statsz
  1907  	subj = fmt.Sprintf(serverStatsReqSubj, sa.ID())
  1908  	msg, err = ncs.Request(subj, nil, time.Second)
  1909  	if err != nil {
  1910  		t.Fatalf("Error trying to request statsz: %v", err)
  1911  	}
  1912  	m2 := ServerStatsMsg{}
  1913  	if err := json.Unmarshal(msg.Data, &m2); err != nil {
  1914  		t.Fatalf("Error unmarshalling the statz json: %v", err)
  1915  	}
  1916  	if m2.Server.ID != sa.ID() {
  1917  		t.Fatalf("Did not match IDs")
  1918  	}
  1919  	if m2.Stats.Connections != 1 {
  1920  		t.Fatalf("Did not match connections of 1, got %d", m2.Stats.Connections)
  1921  	}
  1922  	if m2.Stats.ActiveAccounts != 2 {
  1923  		t.Fatalf("Did not match active accounts of 2, got %d", m2.Stats.ActiveAccounts)
  1924  	}
  1925  	if m2.Stats.Sent.Msgs < 3 {
  1926  		t.Fatalf("Did not match sent msgs of >= 3, got %d", m2.Stats.Sent.Msgs)
  1927  	}
  1928  	if m2.Stats.Received.Msgs < 1 {
  1929  		t.Fatalf("Did not match received msgs of >= 1, got %d", m2.Stats.Received.Msgs)
  1930  	}
  1931  	if lr := len(m2.Stats.Routes); lr != expectedRoutes {
  1932  		t.Fatalf("Expected %d routes, but got %d", expectedRoutes, lr)
  1933  	}
  1934  
  1935  	msg, err = ncs.Request(subj, nil, time.Second)
  1936  	if err != nil {
  1937  		t.Fatalf("Error trying to request statsz: %v", err)
  1938  	}
  1939  	m3 := ServerStatsMsg{}
  1940  	if err := json.Unmarshal(msg.Data, &m3); err != nil {
  1941  		t.Fatalf("Error unmarshalling the statz json: %v", err)
  1942  	}
  1943  	if m3.Server.ID != sa.ID() {
  1944  		t.Fatalf("Did not match IDs")
  1945  	}
  1946  	if m3.Stats.Connections != 1 {
  1947  		t.Fatalf("Did not match connections of 1, got %d", m3.Stats.Connections)
  1948  	}
  1949  	if m3.Stats.ActiveAccounts != 2 {
  1950  		t.Fatalf("Did not match active accounts of 2, got %d", m3.Stats.ActiveAccounts)
  1951  	}
  1952  	if m3.Stats.Sent.Msgs < 4 {
  1953  		t.Fatalf("Did not match sent msgs of >= 4, got %d", m3.Stats.Sent.Msgs)
  1954  	}
  1955  	if m3.Stats.Received.Msgs < 2 {
  1956  		t.Fatalf("Did not match received msgs of >= 2, got %d", m3.Stats.Received.Msgs)
  1957  	}
  1958  	if lr := len(m3.Stats.Routes); lr != expectedRoutes {
  1959  		t.Fatalf("Expected %d routes, but got %d", expectedRoutes, lr)
  1960  	}
  1961  	for _, sr := range m3.Stats.Routes {
  1962  		if sr.Name != "B_SRV" {
  1963  			t.Fatalf("Expected server A's route to B to have Name set to %q, got %q", "B", sr.Name)
  1964  		}
  1965  	}
  1966  
  1967  	// Now query B and check that route's name is "A"
  1968  	subj = fmt.Sprintf(serverStatsReqSubj, sb.ID())
  1969  	ncs.SubscribeSync(subj)
  1970  	msg, err = ncs.Request(subj, nil, time.Second)
  1971  	if err != nil {
  1972  		t.Fatalf("Error trying to request statsz: %v", err)
  1973  	}
  1974  	m = ServerStatsMsg{}
  1975  	if err := json.Unmarshal(msg.Data, &m); err != nil {
  1976  		t.Fatalf("Error unmarshalling the statz json: %v", err)
  1977  	}
  1978  	if lr := len(m.Stats.Routes); lr != expectedRoutes {
  1979  		t.Fatalf("Expected %d routes, but got %d", expectedRoutes, lr)
  1980  	}
  1981  	for _, sr := range m.Stats.Routes {
  1982  		if sr.Name != "A_SRV" {
  1983  			t.Fatalf("Expected server B's route to A to have Name set to %q, got %q", "A_SRV", sr.Name)
  1984  		}
  1985  	}
  1986  }
  1987  
  1988  func TestServerEventsHealthZSingleServer(t *testing.T) {
  1989  	type healthzResp struct {
  1990  		Healthz HealthStatus `json:"data"`
  1991  		Server  ServerInfo   `json:"server"`
  1992  	}
  1993  	cfg := fmt.Sprintf(`listen: 127.0.0.1:-1
  1994  
  1995  	jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  1996  
  1997  	no_auth_user: one
  1998  
  1999  	accounts {
  2000  		ONE { users = [ { user: "one", pass: "p" } ]; jetstream: enabled }
  2001  		$SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] }
  2002  	}`, t.TempDir())
  2003  
  2004  	serverHealthzReqSubj := "$SYS.REQ.SERVER.%s.HEALTHZ"
  2005  	s, _ := RunServerWithConfig(createConfFile(t, []byte(cfg)))
  2006  	defer s.Shutdown()
  2007  
  2008  	ncs, err := nats.Connect(s.ClientURL(), nats.UserInfo("admin", "s3cr3t!"))
  2009  	if err != nil {
  2010  		t.Fatalf("Error connecting to cluster: %v", err)
  2011  	}
  2012  
  2013  	defer ncs.Close()
  2014  	ncAcc, err := nats.Connect(s.ClientURL())
  2015  	if err != nil {
  2016  		t.Fatalf("Error on connect: %v", err)
  2017  	}
  2018  	defer ncAcc.Close()
  2019  	js, err := ncAcc.JetStream()
  2020  	if err != nil {
  2021  		t.Fatalf("Error creating JetStream context: %v", err)
  2022  	}
  2023  	_, err = js.AddStream(&nats.StreamConfig{
  2024  		Name:     "test",
  2025  		Subjects: []string{"foo"},
  2026  	})
  2027  	if err != nil {
  2028  		t.Fatalf("Error creating stream: %v", err)
  2029  	}
  2030  	_, err = js.AddConsumer("test", &nats.ConsumerConfig{
  2031  		Name: "cons",
  2032  	})
  2033  	if err != nil {
  2034  		t.Fatalf("Error creating consumer: %v", err)
  2035  	}
  2036  
  2037  	subj := fmt.Sprintf(serverHealthzReqSubj, s.ID())
  2038  
  2039  	tests := []struct {
  2040  		name     string
  2041  		req      *HealthzEventOptions
  2042  		expected HealthStatus
  2043  	}{
  2044  		{
  2045  			name:     "no parameters",
  2046  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2047  		},
  2048  		{
  2049  			name: "with js enabled only",
  2050  			req: &HealthzEventOptions{
  2051  				HealthzOptions: HealthzOptions{
  2052  					JSEnabledOnly: true,
  2053  				},
  2054  			},
  2055  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2056  		},
  2057  		{
  2058  			name: "with server only",
  2059  			req: &HealthzEventOptions{
  2060  				HealthzOptions: HealthzOptions{
  2061  					JSServerOnly: true,
  2062  				},
  2063  			},
  2064  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2065  		},
  2066  		{
  2067  			name: "with account name",
  2068  			req: &HealthzEventOptions{
  2069  				HealthzOptions: HealthzOptions{
  2070  					Account: "ONE",
  2071  				},
  2072  			},
  2073  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2074  		},
  2075  		{
  2076  			name: "with account name and stream",
  2077  			req: &HealthzEventOptions{
  2078  				HealthzOptions: HealthzOptions{
  2079  					Account: "ONE",
  2080  					Stream:  "test",
  2081  				},
  2082  			},
  2083  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2084  		},
  2085  		{
  2086  			name: "with account name, stream and consumer",
  2087  			req: &HealthzEventOptions{
  2088  				HealthzOptions: HealthzOptions{
  2089  					Account:  "ONE",
  2090  					Stream:   "test",
  2091  					Consumer: "cons",
  2092  				},
  2093  			},
  2094  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2095  		},
  2096  		{
  2097  			name: "with stream only",
  2098  			req: &HealthzEventOptions{
  2099  				HealthzOptions: HealthzOptions{
  2100  					Stream: "test",
  2101  				},
  2102  			},
  2103  			expected: HealthStatus{
  2104  				Status:     "error",
  2105  				StatusCode: 400,
  2106  				Error:      `"account" must not be empty when checking stream health`,
  2107  			},
  2108  		},
  2109  		{
  2110  			name: "with stream only, detailed",
  2111  			req: &HealthzEventOptions{
  2112  				HealthzOptions: HealthzOptions{
  2113  					Details: true,
  2114  					Stream:  "test",
  2115  				},
  2116  			},
  2117  			expected: HealthStatus{
  2118  				Status:     "error",
  2119  				StatusCode: 400,
  2120  				Errors: []HealthzError{
  2121  					{
  2122  						Type:  HealthzErrorBadRequest,
  2123  						Error: `"account" must not be empty when checking stream health`,
  2124  					},
  2125  				},
  2126  			},
  2127  		},
  2128  		{
  2129  			name: "with account and consumer",
  2130  			req: &HealthzEventOptions{
  2131  				HealthzOptions: HealthzOptions{
  2132  					Account:  "ONE",
  2133  					Consumer: "cons",
  2134  				},
  2135  			},
  2136  			expected: HealthStatus{
  2137  				Status:     "error",
  2138  				StatusCode: 400,
  2139  				Error:      `"stream" must not be empty when checking consumer health`,
  2140  			},
  2141  		},
  2142  		{
  2143  			name: "with account and consumer, detailed",
  2144  			req: &HealthzEventOptions{
  2145  				HealthzOptions: HealthzOptions{
  2146  					Account:  "ONE",
  2147  					Consumer: "cons",
  2148  					Details:  true,
  2149  				},
  2150  			},
  2151  			expected: HealthStatus{
  2152  				Status:     "error",
  2153  				StatusCode: 400,
  2154  				Errors: []HealthzError{
  2155  					{
  2156  						Type:  HealthzErrorBadRequest,
  2157  						Error: `"stream" must not be empty when checking consumer health`,
  2158  					},
  2159  				},
  2160  			},
  2161  		},
  2162  		{
  2163  			name: "account not found",
  2164  			req: &HealthzEventOptions{
  2165  				HealthzOptions: HealthzOptions{
  2166  					Account: "abc",
  2167  				},
  2168  			},
  2169  			expected: HealthStatus{
  2170  				Status:     "unavailable",
  2171  				StatusCode: 404,
  2172  				Error:      `JetStream account "abc" not found`,
  2173  			},
  2174  		},
  2175  		{
  2176  			name: "account not found, detailed",
  2177  			req: &HealthzEventOptions{
  2178  				HealthzOptions: HealthzOptions{
  2179  					Account: "abc",
  2180  					Details: true,
  2181  				},
  2182  			},
  2183  			expected: HealthStatus{
  2184  				Status:     "error",
  2185  				StatusCode: 404,
  2186  				Errors: []HealthzError{
  2187  					{
  2188  						Type:    HealthzErrorAccount,
  2189  						Account: "abc",
  2190  						Error:   `JetStream account "abc" not found`,
  2191  					},
  2192  				},
  2193  			},
  2194  		},
  2195  		{
  2196  			name: "stream not found",
  2197  			req: &HealthzEventOptions{
  2198  				HealthzOptions: HealthzOptions{
  2199  					Account: "ONE",
  2200  					Stream:  "abc",
  2201  				},
  2202  			},
  2203  			expected: HealthStatus{
  2204  				Status:     "unavailable",
  2205  				StatusCode: 404,
  2206  				Error:      `JetStream stream "abc" not found on account "ONE"`,
  2207  			},
  2208  		},
  2209  		{
  2210  			name: "stream not found, detailed",
  2211  			req: &HealthzEventOptions{
  2212  				HealthzOptions: HealthzOptions{
  2213  					Account: "ONE",
  2214  					Stream:  "abc",
  2215  					Details: true,
  2216  				},
  2217  			},
  2218  			expected: HealthStatus{
  2219  				Status:     "error",
  2220  				StatusCode: 404,
  2221  				Errors: []HealthzError{
  2222  					{
  2223  						Type:    HealthzErrorStream,
  2224  						Account: "ONE",
  2225  						Stream:  "abc",
  2226  						Error:   `JetStream stream "abc" not found on account "ONE"`,
  2227  					},
  2228  				},
  2229  			},
  2230  		},
  2231  		{
  2232  			name: "consumer not found",
  2233  			req: &HealthzEventOptions{
  2234  				HealthzOptions: HealthzOptions{
  2235  					Account:  "ONE",
  2236  					Stream:   "test",
  2237  					Consumer: "abc",
  2238  				},
  2239  			},
  2240  			expected: HealthStatus{
  2241  				Status:     "unavailable",
  2242  				StatusCode: 404,
  2243  				Error:      `JetStream consumer "abc" not found for stream "test" on account "ONE"`,
  2244  			},
  2245  		},
  2246  		{
  2247  			name: "consumer not found, detailed",
  2248  			req: &HealthzEventOptions{
  2249  				HealthzOptions: HealthzOptions{
  2250  					Account:  "ONE",
  2251  					Stream:   "test",
  2252  					Consumer: "abc",
  2253  					Details:  true,
  2254  				},
  2255  			},
  2256  			expected: HealthStatus{
  2257  				Status:     "error",
  2258  				StatusCode: 404,
  2259  				Errors: []HealthzError{
  2260  					{
  2261  						Type:     HealthzErrorConsumer,
  2262  						Account:  "ONE",
  2263  						Stream:   "test",
  2264  						Consumer: "abc",
  2265  						Error:    `JetStream consumer "abc" not found for stream "test" on account "ONE"`,
  2266  					},
  2267  				},
  2268  			},
  2269  		},
  2270  	}
  2271  	for _, test := range tests {
  2272  		t.Run(test.name, func(t *testing.T) {
  2273  			var body []byte
  2274  			var err error
  2275  			if test.req != nil {
  2276  				body, err = json.Marshal(test.req)
  2277  				if err != nil {
  2278  					t.Fatalf("Error marshaling request body: %v", err)
  2279  				}
  2280  			}
  2281  			msg, err := ncs.Request(subj, body, 1*time.Second)
  2282  			if err != nil {
  2283  				t.Fatalf("Error trying to request healthz: %v", err)
  2284  			}
  2285  			var health healthzResp
  2286  			if err := json.Unmarshal(msg.Data, &health); err != nil {
  2287  				t.Fatalf("Error unmarshalling the statz json: %v", err)
  2288  			}
  2289  			if !reflect.DeepEqual(health.Healthz, test.expected) {
  2290  				t.Errorf("Invalid healthz status; want: %+v; got: %+v", test.expected, health.Healthz)
  2291  			}
  2292  		})
  2293  	}
  2294  }
  2295  
  2296  func TestServerEventsHealthZClustered(t *testing.T) {
  2297  	type healthzResp struct {
  2298  		Healthz HealthStatus `json:"data"`
  2299  		Server  ServerInfo   `json:"server"`
  2300  	}
  2301  	serverHealthzReqSubj := "$SYS.REQ.SERVER.%s.HEALTHZ"
  2302  	c := createJetStreamClusterWithTemplate(t, jsClusterAccountsTempl, "JSC", 3)
  2303  	defer c.shutdown()
  2304  
  2305  	ncs, err := nats.Connect(c.randomServer().ClientURL(), nats.UserInfo("admin", "s3cr3t!"))
  2306  	if err != nil {
  2307  		t.Fatalf("Error connecting to cluster: %v", err)
  2308  	}
  2309  
  2310  	defer ncs.Close()
  2311  	ncAcc, err := nats.Connect(c.randomServer().ClientURL())
  2312  	if err != nil {
  2313  		t.Fatalf("Error on connect: %v", err)
  2314  	}
  2315  	defer ncAcc.Close()
  2316  	js, err := ncAcc.JetStream()
  2317  	if err != nil {
  2318  		t.Fatalf("Error creating JetStream context: %v", err)
  2319  	}
  2320  	_, err = js.AddStream(&nats.StreamConfig{
  2321  		Name:     "test",
  2322  		Subjects: []string{"foo"},
  2323  		Replicas: 3,
  2324  	})
  2325  	if err != nil {
  2326  		t.Fatalf("Error creating stream: %v", err)
  2327  	}
  2328  	_, err = js.AddConsumer("test", &nats.ConsumerConfig{
  2329  		Name:     "cons",
  2330  		Replicas: 3,
  2331  	})
  2332  	if err != nil {
  2333  		t.Fatalf("Error creating consumer: %v", err)
  2334  	}
  2335  
  2336  	subj := fmt.Sprintf(serverHealthzReqSubj, c.servers[0].ID())
  2337  	pingSubj := fmt.Sprintf(serverHealthzReqSubj, "PING")
  2338  
  2339  	tests := []struct {
  2340  		name          string
  2341  		req           *HealthzEventOptions
  2342  		expected      HealthStatus
  2343  		expectedError string
  2344  	}{
  2345  		{
  2346  			name:     "no parameters",
  2347  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2348  		},
  2349  		{
  2350  			name: "with js enabled only",
  2351  			req: &HealthzEventOptions{
  2352  				HealthzOptions: HealthzOptions{
  2353  					JSEnabledOnly: true,
  2354  				},
  2355  			},
  2356  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2357  		},
  2358  		{
  2359  			name: "with server only",
  2360  			req: &HealthzEventOptions{
  2361  				HealthzOptions: HealthzOptions{
  2362  					JSServerOnly: true,
  2363  				},
  2364  			},
  2365  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2366  		},
  2367  		{
  2368  			name: "with account name",
  2369  			req: &HealthzEventOptions{
  2370  				HealthzOptions: HealthzOptions{
  2371  					Account: "ONE",
  2372  				},
  2373  			},
  2374  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2375  		},
  2376  		{
  2377  			name: "with account name and stream",
  2378  			req: &HealthzEventOptions{
  2379  				HealthzOptions: HealthzOptions{
  2380  					Account: "ONE",
  2381  					Stream:  "test",
  2382  				},
  2383  			},
  2384  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2385  		},
  2386  		{
  2387  			name: "with account name, stream and consumer",
  2388  			req: &HealthzEventOptions{
  2389  				HealthzOptions: HealthzOptions{
  2390  					Account:  "ONE",
  2391  					Stream:   "test",
  2392  					Consumer: "cons",
  2393  				},
  2394  			},
  2395  			expected: HealthStatus{Status: "ok", StatusCode: 200},
  2396  		},
  2397  		{
  2398  			name: "with stream only",
  2399  			req: &HealthzEventOptions{
  2400  				HealthzOptions: HealthzOptions{
  2401  					Stream: "test",
  2402  				},
  2403  			},
  2404  			expected: HealthStatus{
  2405  				Status:     "error",
  2406  				StatusCode: 400,
  2407  				Error:      `"account" must not be empty when checking stream health`,
  2408  			},
  2409  			expectedError: "Bad request:",
  2410  		},
  2411  		{
  2412  			name: "with stream only, detailed",
  2413  			req: &HealthzEventOptions{
  2414  				HealthzOptions: HealthzOptions{
  2415  					Details: true,
  2416  					Stream:  "test",
  2417  				},
  2418  			},
  2419  			expected: HealthStatus{
  2420  				Status:     "error",
  2421  				StatusCode: 400,
  2422  				Errors: []HealthzError{
  2423  					{
  2424  						Type:  HealthzErrorBadRequest,
  2425  						Error: `"account" must not be empty when checking stream health`,
  2426  					},
  2427  				},
  2428  			},
  2429  		},
  2430  		{
  2431  			name: "account not found",
  2432  			req: &HealthzEventOptions{
  2433  				HealthzOptions: HealthzOptions{
  2434  					Account: "abc",
  2435  				},
  2436  			},
  2437  			expected: HealthStatus{
  2438  				Status:     "unavailable",
  2439  				StatusCode: 404,
  2440  				Error:      `JetStream account "abc" not found`,
  2441  			},
  2442  			expectedError: `account "abc" not found`,
  2443  		},
  2444  		{
  2445  			name: "account not found, detailed",
  2446  			req: &HealthzEventOptions{
  2447  				HealthzOptions: HealthzOptions{
  2448  					Account: "abc",
  2449  					Details: true,
  2450  				},
  2451  			},
  2452  			expected: HealthStatus{
  2453  				Status:     "error",
  2454  				StatusCode: 404,
  2455  				Errors: []HealthzError{
  2456  					{
  2457  						Type:    HealthzErrorAccount,
  2458  						Account: "abc",
  2459  						Error:   `JetStream account "abc" not found`,
  2460  					},
  2461  				},
  2462  			},
  2463  		},
  2464  		{
  2465  			name: "stream not found",
  2466  			req: &HealthzEventOptions{
  2467  				HealthzOptions: HealthzOptions{
  2468  					Account: "ONE",
  2469  					Stream:  "abc",
  2470  				},
  2471  			},
  2472  			expected: HealthStatus{
  2473  				Status:     "unavailable",
  2474  				StatusCode: 404,
  2475  				Error:      `JetStream stream "abc" not found on account "ONE"`,
  2476  			},
  2477  			expectedError: `stream "abc" not found`,
  2478  		},
  2479  		{
  2480  			name: "stream not found, detailed",
  2481  			req: &HealthzEventOptions{
  2482  				HealthzOptions: HealthzOptions{
  2483  					Account: "ONE",
  2484  					Stream:  "abc",
  2485  					Details: true,
  2486  				},
  2487  			},
  2488  			expected: HealthStatus{
  2489  				Status:     "error",
  2490  				StatusCode: 404,
  2491  				Errors: []HealthzError{
  2492  					{
  2493  						Type:    HealthzErrorStream,
  2494  						Account: "ONE",
  2495  						Stream:  "abc",
  2496  						Error:   `JetStream stream "abc" not found on account "ONE"`,
  2497  					},
  2498  				},
  2499  			},
  2500  		},
  2501  		{
  2502  			name: "consumer not found",
  2503  			req: &HealthzEventOptions{
  2504  				HealthzOptions: HealthzOptions{
  2505  					Account:  "ONE",
  2506  					Stream:   "test",
  2507  					Consumer: "abc",
  2508  				},
  2509  			},
  2510  			expected: HealthStatus{
  2511  				Status:     "unavailable",
  2512  				StatusCode: 404,
  2513  				Error:      `JetStream consumer "abc" not found for stream "test" on account "ONE"`,
  2514  			},
  2515  			expectedError: `consumer "abc" not found for stream "test"`,
  2516  		},
  2517  		{
  2518  			name: "consumer not found, detailed",
  2519  			req: &HealthzEventOptions{
  2520  				HealthzOptions: HealthzOptions{
  2521  					Account:  "ONE",
  2522  					Stream:   "test",
  2523  					Consumer: "abc",
  2524  					Details:  true,
  2525  				},
  2526  			},
  2527  			expected: HealthStatus{
  2528  				Status:     "error",
  2529  				StatusCode: 404,
  2530  				Errors: []HealthzError{
  2531  					{
  2532  						Type:     HealthzErrorConsumer,
  2533  						Account:  "ONE",
  2534  						Stream:   "test",
  2535  						Consumer: "abc",
  2536  						Error:    `JetStream consumer "abc" not found for stream "test" on account "ONE"`,
  2537  					},
  2538  				},
  2539  			},
  2540  		},
  2541  	}
  2542  	for _, test := range tests {
  2543  		t.Run(test.name, func(t *testing.T) {
  2544  			var body []byte
  2545  			var err error
  2546  			if test.req != nil {
  2547  				body, err = json.Marshal(test.req)
  2548  				if err != nil {
  2549  					t.Fatalf("Error marshaling request body: %v", err)
  2550  				}
  2551  			}
  2552  			msg, err := ncs.Request(subj, body, 1*time.Second)
  2553  			if err != nil {
  2554  				t.Fatalf("Error trying to request healthz: %v", err)
  2555  			}
  2556  			var health healthzResp
  2557  			if err := json.Unmarshal(msg.Data, &health); err != nil {
  2558  				t.Fatalf("Error unmarshalling the statz json: %v", err)
  2559  			}
  2560  			if !reflect.DeepEqual(health.Healthz, test.expected) {
  2561  				t.Errorf("Invalid healthz status; want: %+v; got: %+v", test.expected, health.Healthz)
  2562  			}
  2563  
  2564  			reply := ncs.NewRespInbox()
  2565  			sub, err := ncs.SubscribeSync(reply)
  2566  			if err != nil {
  2567  				t.Fatalf("Error creating subscription: %v", err)
  2568  			}
  2569  			defer sub.Unsubscribe()
  2570  
  2571  			// now PING all servers
  2572  			if err := ncs.PublishRequest(pingSubj, reply, body); err != nil {
  2573  				t.Fatalf("Publish error: %v", err)
  2574  			}
  2575  			for i := 0; i < 3; i++ {
  2576  				msg, err := sub.NextMsg(1 * time.Second)
  2577  				if err != nil {
  2578  					t.Fatalf("Error fetching healthz PING response: %v", err)
  2579  				}
  2580  				var health healthzResp
  2581  				if err := json.Unmarshal(msg.Data, &health); err != nil {
  2582  					t.Fatalf("Error unmarshalling the statz json: %v", err)
  2583  				}
  2584  				if !reflect.DeepEqual(health.Healthz, test.expected) {
  2585  					t.Errorf("Invalid healthz status; want: %+v; got: %+v", test.expected, health.Healthz)
  2586  				}
  2587  			}
  2588  			if _, err := sub.NextMsg(50 * time.Millisecond); !errors.Is(err, nats.ErrTimeout) {
  2589  				t.Fatalf("Expected timeout error; got: %v", err)
  2590  			}
  2591  		})
  2592  	}
  2593  }
  2594  
  2595  func TestServerEventsHealthZClustered_NoReplicas(t *testing.T) {
  2596  	type healthzResp struct {
  2597  		Healthz HealthStatus `json:"data"`
  2598  		Server  ServerInfo   `json:"server"`
  2599  	}
  2600  	serverHealthzReqSubj := "$SYS.REQ.SERVER.%s.HEALTHZ"
  2601  	c := createJetStreamClusterWithTemplate(t, jsClusterAccountsTempl, "JSC", 3)
  2602  	defer c.shutdown()
  2603  
  2604  	ncs, err := nats.Connect(c.randomServer().ClientURL(), nats.UserInfo("admin", "s3cr3t!"))
  2605  	if err != nil {
  2606  		t.Fatalf("Error connecting to cluster: %v", err)
  2607  	}
  2608  
  2609  	defer ncs.Close()
  2610  	ncAcc, err := nats.Connect(c.randomServer().ClientURL())
  2611  	if err != nil {
  2612  		t.Fatalf("Error on connect: %v", err)
  2613  	}
  2614  	defer ncAcc.Close()
  2615  	js, err := ncAcc.JetStream()
  2616  	if err != nil {
  2617  		t.Fatalf("Error creating JetStream context: %v", err)
  2618  	}
  2619  
  2620  	pingSubj := fmt.Sprintf(serverHealthzReqSubj, "PING")
  2621  
  2622  	t.Run("non-replicated stream", func(t *testing.T) {
  2623  		_, err = js.AddStream(&nats.StreamConfig{
  2624  			Name:     "test",
  2625  			Subjects: []string{"foo"},
  2626  		})
  2627  		if err != nil {
  2628  			t.Fatalf("Error creating stream: %v", err)
  2629  		}
  2630  		_, err = js.AddConsumer("test", &nats.ConsumerConfig{
  2631  			Name: "cons",
  2632  		})
  2633  		if err != nil {
  2634  			t.Fatalf("Error creating consumer: %v", err)
  2635  		}
  2636  		body, err := json.Marshal(HealthzEventOptions{
  2637  			HealthzOptions: HealthzOptions{
  2638  				Account: "ONE",
  2639  				Stream:  "test",
  2640  			},
  2641  		})
  2642  		if err != nil {
  2643  			t.Fatalf("Error marshaling request body: %v", err)
  2644  		}
  2645  
  2646  		reply := ncs.NewRespInbox()
  2647  		sub, err := ncs.SubscribeSync(reply)
  2648  		if err != nil {
  2649  			t.Fatalf("Error creating subscription: %v", err)
  2650  		}
  2651  		defer sub.Unsubscribe()
  2652  
  2653  		// now PING all servers
  2654  		if err := ncs.PublishRequest(pingSubj, reply, body); err != nil {
  2655  			t.Fatalf("Publish error: %v", err)
  2656  		}
  2657  		var healthy int
  2658  		for i := 0; i < 3; i++ {
  2659  			msg, err := sub.NextMsg(1 * time.Second)
  2660  			if err != nil {
  2661  				t.Fatalf("Error fetching healthz PING response: %v", err)
  2662  			}
  2663  			var health healthzResp
  2664  			if err := json.Unmarshal(msg.Data, &health); err != nil {
  2665  				t.Fatalf("Error unmarshalling the statz json: %v", err)
  2666  			}
  2667  			if health.Healthz.Status == "ok" {
  2668  				healthy++
  2669  				continue
  2670  			}
  2671  			if !strings.Contains(health.Healthz.Error, `stream "test" not found`) {
  2672  				t.Errorf("Expected error to contain: %q, got: %s", `stream "test" not found`, health.Healthz.Error)
  2673  			}
  2674  		}
  2675  		if healthy != 1 {
  2676  			t.Fatalf("Expected 1 healthy server; got: %d", healthy)
  2677  		}
  2678  		if _, err := sub.NextMsg(50 * time.Millisecond); !errors.Is(err, nats.ErrTimeout) {
  2679  			t.Fatalf("Expected timeout error; got: %v", err)
  2680  		}
  2681  	})
  2682  
  2683  	t.Run("non-replicated consumer", func(t *testing.T) {
  2684  		_, err = js.AddStream(&nats.StreamConfig{
  2685  			Name:     "test-repl",
  2686  			Subjects: []string{"bar"},
  2687  			Replicas: 3,
  2688  		})
  2689  		if err != nil {
  2690  			t.Fatalf("Error creating stream: %v", err)
  2691  		}
  2692  		_, err = js.AddConsumer("test-repl", &nats.ConsumerConfig{
  2693  			Name: "cons-single",
  2694  		})
  2695  		if err != nil {
  2696  			t.Fatalf("Error creating consumer: %v", err)
  2697  		}
  2698  		body, err := json.Marshal(HealthzEventOptions{
  2699  			HealthzOptions: HealthzOptions{
  2700  				Account:  "ONE",
  2701  				Stream:   "test-repl",
  2702  				Consumer: "cons-single",
  2703  			},
  2704  		})
  2705  		if err != nil {
  2706  			t.Fatalf("Error marshaling request body: %v", err)
  2707  		}
  2708  
  2709  		reply := ncs.NewRespInbox()
  2710  		sub, err := ncs.SubscribeSync(reply)
  2711  		if err != nil {
  2712  			t.Fatalf("Error creating subscription: %v", err)
  2713  		}
  2714  		defer sub.Unsubscribe()
  2715  
  2716  		// now PING all servers
  2717  		if err := ncs.PublishRequest(pingSubj, reply, body); err != nil {
  2718  			t.Fatalf("Publish error: %v", err)
  2719  		}
  2720  		var healthy int
  2721  		for i := 0; i < 3; i++ {
  2722  			msg, err := sub.NextMsg(1 * time.Second)
  2723  			if err != nil {
  2724  				t.Fatalf("Error fetching healthz PING response: %v", err)
  2725  			}
  2726  			var health healthzResp
  2727  			if err := json.Unmarshal(msg.Data, &health); err != nil {
  2728  				t.Fatalf("Error unmarshalling the statz json: %v", err)
  2729  			}
  2730  			if health.Healthz.Status == "ok" {
  2731  				healthy++
  2732  				continue
  2733  			}
  2734  			if !strings.Contains(health.Healthz.Error, `consumer "cons-single" not found`) {
  2735  				t.Errorf("Expected error to contain: %q, got: %s", `consumer "cons-single" not found`, health.Healthz.Error)
  2736  			}
  2737  		}
  2738  		if healthy != 1 {
  2739  			t.Fatalf("Expected 1 healthy server; got: %d", healthy)
  2740  		}
  2741  		if _, err := sub.NextMsg(50 * time.Millisecond); !errors.Is(err, nats.ErrTimeout) {
  2742  			t.Fatalf("Expected timeout error; got: %v", err)
  2743  		}
  2744  	})
  2745  
  2746  }
  2747  
  2748  func TestServerEventsHealthZJetStreamNotEnabled(t *testing.T) {
  2749  	type healthzResp struct {
  2750  		Healthz HealthStatus `json:"data"`
  2751  		Server  ServerInfo   `json:"server"`
  2752  	}
  2753  	cfg := `listen: 127.0.0.1:-1
  2754  
  2755  	accounts {
  2756  		$SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] }
  2757  	}`
  2758  
  2759  	serverHealthzReqSubj := "$SYS.REQ.SERVER.%s.HEALTHZ"
  2760  	s, _ := RunServerWithConfig(createConfFile(t, []byte(cfg)))
  2761  	defer s.Shutdown()
  2762  
  2763  	ncs, err := nats.Connect(s.ClientURL(), nats.UserInfo("admin", "s3cr3t!"))
  2764  	if err != nil {
  2765  		t.Fatalf("Error connecting to cluster: %v", err)
  2766  	}
  2767  
  2768  	defer ncs.Close()
  2769  
  2770  	subj := fmt.Sprintf(serverHealthzReqSubj, s.ID())
  2771  
  2772  	msg, err := ncs.Request(subj, nil, 1*time.Second)
  2773  	if err != nil {
  2774  		t.Fatalf("Error trying to request healthz: %v", err)
  2775  	}
  2776  	var health healthzResp
  2777  	if err := json.Unmarshal(msg.Data, &health); err != nil {
  2778  		t.Fatalf("Error unmarshalling the statz json: %v", err)
  2779  	}
  2780  	if health.Healthz.Status != "ok" {
  2781  		t.Errorf("Invalid healthz status; want: %q; got: %q", "ok", health.Healthz.Status)
  2782  	}
  2783  	if health.Healthz.Error != "" {
  2784  		t.Errorf("HealthZ error: %s", health.Healthz.Error)
  2785  	}
  2786  }
  2787  
  2788  func TestServerEventsPingStatsZ(t *testing.T) {
  2789  	sa, _, sb, optsB, akp := runTrustedCluster(t)
  2790  	defer sa.Shutdown()
  2791  	defer sb.Shutdown()
  2792  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  2793  	nc, err := nats.Connect(url, createUserCreds(t, sb, akp))
  2794  	if err != nil {
  2795  		t.Fatalf("Error on connect: %v", err)
  2796  	}
  2797  	defer nc.Close()
  2798  	test := func(req []byte) {
  2799  		reply := nc.NewRespInbox()
  2800  		sub, _ := nc.SubscribeSync(reply)
  2801  		nc.PublishRequest(serverStatsPingReqSubj, reply, req)
  2802  		// Make sure its a statsz
  2803  		m := ServerStatsMsg{}
  2804  		// Receive both manually.
  2805  		msg, err := sub.NextMsg(time.Second)
  2806  		if err != nil {
  2807  			t.Fatalf("Error receiving msg: %v", err)
  2808  		}
  2809  		if err := json.Unmarshal(msg.Data, &m); err != nil {
  2810  			t.Fatalf("Error unmarshalling the statz json: %v", err)
  2811  		}
  2812  		msg, err = sub.NextMsg(time.Second)
  2813  		if err != nil {
  2814  			t.Fatalf("Error receiving msg: %v", err)
  2815  		}
  2816  		if err := json.Unmarshal(msg.Data, &m); err != nil {
  2817  			t.Fatalf("Error unmarshalling the statz json: %v", err)
  2818  		}
  2819  	}
  2820  	strRequestTbl := []string{
  2821  		`{"cluster":"TEST"}`,
  2822  		`{"cluster":"CLUSTER"}`,
  2823  		`{"server_name":"SRV"}`,
  2824  		`{"server_name":"_"}`,
  2825  		fmt.Sprintf(`{"host":"%s"}`, optsB.Host),
  2826  		fmt.Sprintf(`{"host":"%s", "cluster":"CLUSTER", "name":"SRV"}`, optsB.Host),
  2827  	}
  2828  	for i, opt := range strRequestTbl {
  2829  		t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {
  2830  			test([]byte(opt))
  2831  		})
  2832  	}
  2833  	requestTbl := []StatszEventOptions{
  2834  		{EventFilterOptions: EventFilterOptions{Cluster: "TEST"}},
  2835  		{EventFilterOptions: EventFilterOptions{Cluster: "CLUSTER"}},
  2836  		{EventFilterOptions: EventFilterOptions{Name: "SRV"}},
  2837  		{EventFilterOptions: EventFilterOptions{Name: "_"}},
  2838  		{EventFilterOptions: EventFilterOptions{Host: optsB.Host}},
  2839  		{EventFilterOptions: EventFilterOptions{Host: optsB.Host, Cluster: "CLUSTER", Name: "SRV"}},
  2840  	}
  2841  	for i, opt := range requestTbl {
  2842  		t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {
  2843  			msg, _ := json.MarshalIndent(&opt, "", "  ")
  2844  			test(msg)
  2845  		})
  2846  	}
  2847  }
  2848  
  2849  func TestServerEventsPingStatsZFilter(t *testing.T) {
  2850  	sa, _, sb, optsB, akp := runTrustedCluster(t)
  2851  	defer sa.Shutdown()
  2852  	defer sb.Shutdown()
  2853  
  2854  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  2855  	nc, err := nats.Connect(url, createUserCreds(t, sb, akp))
  2856  	if err != nil {
  2857  		t.Fatalf("Error on connect: %v", err)
  2858  	}
  2859  	defer nc.Close()
  2860  
  2861  	requestTbl := []string{
  2862  		`{"cluster":"DOESNOTEXIST"}`,
  2863  		`{"host":"DOESNOTEXIST"}`,
  2864  		`{"server_name":"DOESNOTEXIST"}`,
  2865  	}
  2866  	for i, msg := range requestTbl {
  2867  		t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {
  2868  			// Receive both manually.
  2869  			if _, err := nc.Request(serverStatsPingReqSubj, []byte(msg), time.Second/4); err != nats.ErrTimeout {
  2870  				t.Fatalf("Error, expected timeout: %v", err)
  2871  			}
  2872  		})
  2873  	}
  2874  	requestObjTbl := []EventFilterOptions{
  2875  		{Cluster: "DOESNOTEXIST"},
  2876  		{Host: "DOESNOTEXIST"},
  2877  		{Name: "DOESNOTEXIST"},
  2878  	}
  2879  	for i, opt := range requestObjTbl {
  2880  		t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {
  2881  			msg, _ := json.MarshalIndent(&opt, "", "  ")
  2882  			// Receive both manually.
  2883  			if _, err := nc.Request(serverStatsPingReqSubj, []byte(msg), time.Second/4); err != nats.ErrTimeout {
  2884  				t.Fatalf("Error, expected timeout: %v", err)
  2885  			}
  2886  		})
  2887  	}
  2888  }
  2889  
  2890  func TestServerEventsPingStatsZFailFilter(t *testing.T) {
  2891  	sa, _, sb, optsB, akp := runTrustedCluster(t)
  2892  	defer sa.Shutdown()
  2893  	defer sb.Shutdown()
  2894  
  2895  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  2896  	nc, err := nats.Connect(url, createUserCreds(t, sb, akp))
  2897  	if err != nil {
  2898  		t.Fatalf("Error on connect: %v", err)
  2899  	}
  2900  	defer nc.Close()
  2901  
  2902  	// Receive both manually.
  2903  	if msg, err := nc.Request(serverStatsPingReqSubj, []byte(`{MALFORMEDJSON`), time.Second/4); err != nil {
  2904  		t.Fatalf("Error: %v", err)
  2905  	} else {
  2906  		resp := make(map[string]map[string]interface{})
  2907  		if err := json.Unmarshal(msg.Data, &resp); err != nil {
  2908  			t.Fatalf("Error unmarshalling the response json: %v", err)
  2909  		}
  2910  		if resp["error"]["code"].(float64) != http.StatusBadRequest {
  2911  			t.Fatal("bad error code")
  2912  		}
  2913  	}
  2914  }
  2915  
  2916  func TestServerEventsPingMonitorz(t *testing.T) {
  2917  	sa, _, sb, optsB, akp := runTrustedCluster(t)
  2918  	defer sa.Shutdown()
  2919  	defer sb.Shutdown()
  2920  	sysAcc, _ := akp.PublicKey()
  2921  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  2922  	nc, err := nats.Connect(url, createUserCreds(t, sb, akp))
  2923  	if err != nil {
  2924  		t.Fatalf("Error on connect: %v", err)
  2925  	}
  2926  	defer nc.Close()
  2927  
  2928  	nc.Flush()
  2929  
  2930  	tests := []struct {
  2931  		endpoint  string
  2932  		opt       interface{}
  2933  		resp      interface{}
  2934  		respField []string
  2935  	}{
  2936  		{"VARZ", nil, &Varz{},
  2937  			[]string{"now", "cpu", "system_account"}},
  2938  		{"SUBSZ", nil, &Subsz{},
  2939  			[]string{"num_subscriptions", "num_cache"}},
  2940  		{"CONNZ", nil, &Connz{},
  2941  			[]string{"now", "connections"}},
  2942  		{"ROUTEZ", nil, &Routez{},
  2943  			[]string{"now", "routes"}},
  2944  		{"GATEWAYZ", nil, &Gatewayz{},
  2945  			[]string{"now", "outbound_gateways", "inbound_gateways"}},
  2946  		{"LEAFZ", nil, &Leafz{},
  2947  			[]string{"now", "leafs"}},
  2948  
  2949  		{"SUBSZ", &SubszOptions{}, &Subsz{},
  2950  			[]string{"num_subscriptions", "num_cache"}},
  2951  		{"CONNZ", &ConnzOptions{}, &Connz{},
  2952  			[]string{"now", "connections"}},
  2953  		{"ROUTEZ", &RoutezOptions{}, &Routez{},
  2954  			[]string{"now", "routes"}},
  2955  		{"GATEWAYZ", &GatewayzOptions{}, &Gatewayz{},
  2956  			[]string{"now", "outbound_gateways", "inbound_gateways"}},
  2957  		{"LEAFZ", &LeafzOptions{}, &Leafz{},
  2958  			[]string{"now", "leafs"}},
  2959  		{"ACCOUNTZ", &AccountzOptions{}, &Accountz{},
  2960  			[]string{"now", "accounts"}},
  2961  
  2962  		{"SUBSZ", &SubszOptions{Limit: 5}, &Subsz{},
  2963  			[]string{"num_subscriptions", "num_cache"}},
  2964  		{"CONNZ", &ConnzOptions{Limit: 5}, &Connz{},
  2965  			[]string{"now", "connections"}},
  2966  		{"ROUTEZ", &RoutezOptions{SubscriptionsDetail: true}, &Routez{},
  2967  			[]string{"now", "routes"}},
  2968  		{"GATEWAYZ", &GatewayzOptions{Accounts: true}, &Gatewayz{},
  2969  			[]string{"now", "outbound_gateways", "inbound_gateways"}},
  2970  		{"LEAFZ", &LeafzOptions{Subscriptions: true}, &Leafz{},
  2971  			[]string{"now", "leafs"}},
  2972  		{"ACCOUNTZ", &AccountzOptions{Account: sysAcc}, &Accountz{},
  2973  			[]string{"now", "account_detail"}},
  2974  		{"LEAFZ", &LeafzOptions{Account: sysAcc}, &Leafz{},
  2975  			[]string{"now", "leafs"}},
  2976  
  2977  		{"ROUTEZ", json.RawMessage(`{"cluster":""}`), &Routez{},
  2978  			[]string{"now", "routes"}},
  2979  		{"ROUTEZ", json.RawMessage(`{"name":""}`), &Routez{},
  2980  			[]string{"now", "routes"}},
  2981  		{"ROUTEZ", json.RawMessage(`{"cluster":"TEST CLUSTER 22"}`), &Routez{},
  2982  			[]string{"now", "routes"}},
  2983  		{"ROUTEZ", json.RawMessage(`{"cluster":"CLUSTER"}`), &Routez{},
  2984  			[]string{"now", "routes"}},
  2985  		{"ROUTEZ", json.RawMessage(`{"cluster":"TEST CLUSTER 22", "subscriptions":true}`), &Routez{},
  2986  			[]string{"now", "routes"}},
  2987  
  2988  		{"JSZ", nil, &JSzOptions{}, []string{"now", "disabled"}},
  2989  
  2990  		{"HEALTHZ", nil, &JSzOptions{}, []string{"status"}},
  2991  		{"HEALTHZ", &HealthzOptions{JSEnabledOnly: true}, &JSzOptions{}, []string{"status"}},
  2992  		{"HEALTHZ", &HealthzOptions{JSServerOnly: true}, &JSzOptions{}, []string{"status"}},
  2993  	}
  2994  
  2995  	for i, test := range tests {
  2996  		t.Run(fmt.Sprintf("%s-%d", test.endpoint, i), func(t *testing.T) {
  2997  			var opt []byte
  2998  			if test.opt != nil {
  2999  				opt, err = json.Marshal(test.opt)
  3000  				if err != nil {
  3001  					t.Fatalf("Error marshaling opts: %v", err)
  3002  				}
  3003  			}
  3004  			reply := nc.NewRespInbox()
  3005  			replySubj, _ := nc.SubscribeSync(reply)
  3006  
  3007  			// set a header to make sure request parsing knows to ignore them
  3008  			nc.PublishMsg(&nats.Msg{
  3009  				Subject: fmt.Sprintf("%s.%s", serverStatsPingReqSubj, test.endpoint),
  3010  				Reply:   reply,
  3011  				Header:  nats.Header{"header": []string{"for header sake"}},
  3012  				Data:    opt,
  3013  			})
  3014  
  3015  			// Receive both manually.
  3016  			msg, err := replySubj.NextMsg(time.Second)
  3017  			if err != nil {
  3018  				t.Fatalf("Error receiving msg: %v", err)
  3019  			}
  3020  			response1 := make(map[string]map[string]interface{})
  3021  
  3022  			if err := json.Unmarshal(msg.Data, &response1); err != nil {
  3023  				t.Fatalf("Error unmarshalling response1 json: %v", err)
  3024  			}
  3025  
  3026  			serverName := ""
  3027  			if response1["server"]["name"] == "A_SRV" {
  3028  				serverName = "B_SRV"
  3029  			} else if response1["server"]["name"] == "B_SRV" {
  3030  				serverName = "A_SRV"
  3031  			} else {
  3032  				t.Fatalf("Error finding server in %s", string(msg.Data))
  3033  			}
  3034  			if resp, ok := response1["data"]; !ok {
  3035  				t.Fatalf("Error finding: %s in %s",
  3036  					strings.ToLower(test.endpoint), string(msg.Data))
  3037  			} else {
  3038  				for _, respField := range test.respField {
  3039  					if _, ok := resp[respField]; !ok {
  3040  						t.Fatalf("Error finding: %s in %s", respField, resp)
  3041  					}
  3042  				}
  3043  			}
  3044  
  3045  			msg, err = replySubj.NextMsg(time.Second)
  3046  			if err != nil {
  3047  				t.Fatalf("Error receiving msg: %v", err)
  3048  			}
  3049  			response2 := make(map[string]map[string]interface{})
  3050  			if err := json.Unmarshal(msg.Data, &response2); err != nil {
  3051  				t.Fatalf("Error unmarshalling the response2 json: %v", err)
  3052  			}
  3053  			if response2["server"]["name"] != serverName {
  3054  				t.Fatalf("Error finding server %s in %s", serverName, string(msg.Data))
  3055  			}
  3056  			if resp, ok := response2["data"]; !ok {
  3057  				t.Fatalf("Error finding: %s in %s",
  3058  					strings.ToLower(test.endpoint), string(msg.Data))
  3059  			} else {
  3060  				for _, respField := range test.respField {
  3061  					if _, ok := resp[respField]; !ok {
  3062  						t.Fatalf("Error finding: %s in %s", respField, resp)
  3063  					}
  3064  				}
  3065  			}
  3066  		})
  3067  	}
  3068  }
  3069  
  3070  func TestGatewayNameClientInfo(t *testing.T) {
  3071  	sa, _, sb, _, _ := runTrustedCluster(t)
  3072  	defer sa.Shutdown()
  3073  	defer sb.Shutdown()
  3074  
  3075  	c, _, l := newClientForServer(sa)
  3076  	defer c.close()
  3077  
  3078  	var info Info
  3079  	err := json.Unmarshal([]byte(l[5:]), &info)
  3080  	if err != nil {
  3081  		t.Fatalf("Could not parse INFO json: %v\n", err)
  3082  	}
  3083  	if info.Cluster != "TEST CLUSTER 22" {
  3084  		t.Fatalf("Expected a cluster name of 'TEST CLUSTER 22', got %q", info.Cluster)
  3085  	}
  3086  }
  3087  
  3088  type slowAccResolver struct {
  3089  	sync.Mutex
  3090  	AccountResolver
  3091  	acc string
  3092  }
  3093  
  3094  func (sr *slowAccResolver) Fetch(name string) (string, error) {
  3095  	sr.Lock()
  3096  	delay := sr.acc == name
  3097  	sr.Unlock()
  3098  	if delay {
  3099  		time.Sleep(200 * time.Millisecond)
  3100  	}
  3101  	return sr.AccountResolver.Fetch(name)
  3102  }
  3103  
  3104  func TestConnectionUpdatesTimerProperlySet(t *testing.T) {
  3105  	origEventsHBInterval := eventsHBInterval
  3106  	eventsHBInterval = 50 * time.Millisecond
  3107  	defer func() { eventsHBInterval = origEventsHBInterval }()
  3108  
  3109  	sa, _, sb, optsB, _ := runTrustedCluster(t)
  3110  	defer sa.Shutdown()
  3111  	defer sb.Shutdown()
  3112  
  3113  	// Normal Account
  3114  	okp, _ := nkeys.FromSeed(oSeed)
  3115  	akp, _ := nkeys.CreateAccount()
  3116  	pub, _ := akp.PublicKey()
  3117  	nac := jwt.NewAccountClaims(pub)
  3118  	nac.Limits.Conn = 10 // set any limit...
  3119  	jwt, _ := nac.Encode(okp)
  3120  
  3121  	addAccountToMemResolver(sa, pub, jwt)
  3122  
  3123  	// Listen for HB updates...
  3124  	count := int32(0)
  3125  	cb := func(sub *subscription, _ *client, _ *Account, subject, reply string, msg []byte) {
  3126  		atomic.AddInt32(&count, 1)
  3127  	}
  3128  	subj := fmt.Sprintf(accConnsEventSubjNew, pub)
  3129  	sub, err := sa.sysSubscribe(subj, cb)
  3130  	if sub == nil || err != nil {
  3131  		t.Fatalf("Expected to subscribe, got %v", err)
  3132  	}
  3133  	defer sa.sysUnsubscribe(sub)
  3134  
  3135  	url := fmt.Sprintf("nats://%s:%d", optsB.Host, optsB.Port)
  3136  	nc := natsConnect(t, url, createUserCreds(t, sb, akp))
  3137  	defer nc.Close()
  3138  
  3139  	time.Sleep(500 * time.Millisecond)
  3140  	// After waiting 500ms with HB interval of 50ms, we should get
  3141  	// about 10 updates, no much more
  3142  	if n := atomic.LoadInt32(&count); n > 15 {
  3143  		t.Fatalf("Expected about 10 updates, got %v", n)
  3144  	}
  3145  
  3146  	// Now lookup the account doing the events on sb.
  3147  	acc, _ := sb.LookupAccount(pub)
  3148  	// Make sure we have the timer running.
  3149  	acc.mu.RLock()
  3150  	ctmr := acc.ctmr
  3151  	acc.mu.RUnlock()
  3152  	if ctmr == nil {
  3153  		t.Fatalf("Expected event timer for acc conns to be running")
  3154  	}
  3155  
  3156  	nc.Close()
  3157  
  3158  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  3159  		// Make sure we have the timer is NOT running.
  3160  		acc.mu.RLock()
  3161  		ctmr = acc.ctmr
  3162  		acc.mu.RUnlock()
  3163  		if ctmr != nil {
  3164  			return fmt.Errorf("Expected event timer for acc conns to NOT be running after reaching zero local clients")
  3165  		}
  3166  		return nil
  3167  	})
  3168  }
  3169  
  3170  func TestServerEventsReceivedByQSubs(t *testing.T) {
  3171  	s, opts := runTrustedServer(t)
  3172  	defer s.Shutdown()
  3173  
  3174  	acc, akp := createAccount(s)
  3175  	s.setSystemAccount(acc)
  3176  
  3177  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  3178  	ncs, err := nats.Connect(url, createUserCreds(t, s, akp))
  3179  	if err != nil {
  3180  		t.Fatalf("Error on connect: %v", err)
  3181  	}
  3182  	defer ncs.Close()
  3183  
  3184  	// Listen for auth error events.
  3185  	qsub, _ := ncs.QueueSubscribeSync("$SYS.SERVER.*.CLIENT.AUTH.ERR", "queue")
  3186  	defer qsub.Unsubscribe()
  3187  
  3188  	ncs.Flush()
  3189  
  3190  	nats.Connect(url, nats.Name("TEST BAD LOGIN"))
  3191  
  3192  	m, err := qsub.NextMsg(time.Second)
  3193  	if err != nil {
  3194  		t.Fatalf("Should have heard an auth error event")
  3195  	}
  3196  	dem := DisconnectEventMsg{}
  3197  	if err := json.Unmarshal(m.Data, &dem); err != nil {
  3198  		t.Fatalf("Error unmarshalling disconnect event message: %v", err)
  3199  	}
  3200  	if dem.Reason != "Authentication Failure" {
  3201  		t.Fatalf("Expected auth error, got %q", dem.Reason)
  3202  	}
  3203  }
  3204  
  3205  func TestServerEventsFilteredByTag(t *testing.T) {
  3206  	confA := createConfFile(t, []byte(`
  3207  		listen: -1
  3208  		server_name: srv-A
  3209  		server_tags: ["foo", "bar"]
  3210  		cluster {
  3211  			name: clust
  3212  			listen: -1
  3213  			no_advertise: true
  3214  		}
  3215  		system_account: SYS
  3216  		accounts: {
  3217  			SYS: {
  3218  				users: [
  3219  					{user: b, password: b}
  3220  				]
  3221  			}
  3222  		}
  3223  		no_auth_user: b
  3224      `))
  3225  	sA, _ := RunServerWithConfig(confA)
  3226  	defer sA.Shutdown()
  3227  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  3228  		listen: -1
  3229  		server_name: srv-B
  3230  		server_tags: ["bar", "baz"]
  3231  		cluster {
  3232  			name: clust
  3233  			listen: -1
  3234  			no_advertise: true
  3235  			routes [
  3236  				nats-route://127.0.0.1:%d
  3237  			]
  3238  		}
  3239  		system_account: SYS
  3240  		accounts: {
  3241  			SYS: {
  3242  				users: [
  3243  					{user: b, password: b}
  3244  				]
  3245  			}
  3246  		}
  3247  		no_auth_user: b
  3248      `, sA.opts.Cluster.Port)))
  3249  	sB, _ := RunServerWithConfig(confB)
  3250  	defer sB.Shutdown()
  3251  	checkClusterFormed(t, sA, sB)
  3252  	nc := natsConnect(t, sA.ClientURL())
  3253  	defer nc.Close()
  3254  
  3255  	ib := nats.NewInbox()
  3256  	req := func(tags ...string) {
  3257  		t.Helper()
  3258  		r, err := json.Marshal(VarzEventOptions{EventFilterOptions: EventFilterOptions{Tags: tags}})
  3259  		require_NoError(t, err)
  3260  		err = nc.PublishRequest(fmt.Sprintf(serverPingReqSubj, "VARZ"), ib, r)
  3261  		require_NoError(t, err)
  3262  	}
  3263  
  3264  	msgs := make(chan *nats.Msg, 10)
  3265  	defer close(msgs)
  3266  	_, err := nc.ChanSubscribe(ib, msgs)
  3267  	require_NoError(t, err)
  3268  	req("none")
  3269  	select {
  3270  	case <-msgs:
  3271  		t.Fatalf("no message expected")
  3272  	case <-time.After(200 * time.Millisecond):
  3273  	}
  3274  	req("foo")
  3275  	m := <-msgs
  3276  	require_Contains(t, string(m.Data), "srv-A", "foo", "bar")
  3277  	req("foo", "bar")
  3278  	m = <-msgs
  3279  	require_Contains(t, string(m.Data), "srv-A", "foo", "bar")
  3280  	req("baz")
  3281  	m = <-msgs
  3282  	require_Contains(t, string(m.Data), "srv-B", "bar", "baz")
  3283  	req("bar")
  3284  	m1 := <-msgs
  3285  	m2 := <-msgs
  3286  	require_Contains(t, string(m1.Data)+string(m2.Data), "srv-A", "srv-B", "foo", "bar", "baz")
  3287  	require_Len(t, len(msgs), 0)
  3288  }
  3289  
  3290  // https://github.com/nats-io/nats-server/issues/3177
  3291  func TestServerEventsAndDQSubscribers(t *testing.T) {
  3292  	c := createJetStreamClusterWithTemplate(t, jsClusterAccountsTempl, "DDQ", 3)
  3293  	defer c.shutdown()
  3294  
  3295  	nc, err := nats.Connect(c.randomServer().ClientURL(), nats.UserInfo("admin", "s3cr3t!"))
  3296  	require_NoError(t, err)
  3297  	defer nc.Close()
  3298  
  3299  	sub, err := nc.QueueSubscribeSync("$SYS.ACCOUNT.*.DISCONNECT", "qq")
  3300  	require_NoError(t, err)
  3301  	nc.Flush()
  3302  
  3303  	// Create and disconnect 10 random connections.
  3304  	for i := 0; i < 10; i++ {
  3305  		nc, err := nats.Connect(c.randomServer().ClientURL())
  3306  		require_NoError(t, err)
  3307  		nc.Close()
  3308  	}
  3309  
  3310  	checkSubsPending(t, sub, 10)
  3311  }
  3312  
  3313  func TestServerEventsStatszSingleServer(t *testing.T) {
  3314  	conf := createConfFile(t, []byte(`
  3315  		listen: "127.0.0.1:-1"
  3316  		accounts { $SYS { users [{user: "admin", password: "p1d"}]} }
  3317  	`))
  3318  	s, _ := RunServerWithConfig(conf)
  3319  	defer s.Shutdown()
  3320  
  3321  	// Grab internal system client.
  3322  	s.mu.RLock()
  3323  	sysc := s.sys.client
  3324  	wait := s.sys.cstatsz + 25*time.Millisecond
  3325  	s.mu.RUnlock()
  3326  
  3327  	// Wait for when first statsz would have gone out..
  3328  	time.Sleep(wait)
  3329  
  3330  	sysc.mu.Lock()
  3331  	outMsgs := sysc.stats.outMsgs
  3332  	sysc.mu.Unlock()
  3333  
  3334  	require_True(t, outMsgs == 0)
  3335  
  3336  	// Connect as a system user and make sure if there is
  3337  	// subscription interest that we will receive updates.
  3338  	nc, _ := jsClientConnect(t, s, nats.UserInfo("admin", "p1d"))
  3339  	defer nc.Close()
  3340  
  3341  	sub, err := nc.SubscribeSync(fmt.Sprintf(serverStatsSubj, "*"))
  3342  	require_NoError(t, err)
  3343  
  3344  	checkSubsPending(t, sub, 1)
  3345  }
  3346  
  3347  func TestServerEventsReload(t *testing.T) {
  3348  	conf := createConfFile(t, []byte(`
  3349  		listen: "127.0.0.1:-1"
  3350  		accounts: {
  3351  			$SYS { users [{user: "admin", password: "p1d"}]}
  3352  			test { users [{user: "foo", password: "bar"}]}
  3353  		}
  3354  		ping_interval: "100ms"
  3355  	`))
  3356  	opts := LoadConfig(conf)
  3357  	s := RunServer(opts)
  3358  	defer s.Shutdown()
  3359  	subject := fmt.Sprintf(serverReloadReqSubj, s.info.ID)
  3360  
  3361  	// Connect as a test user and make sure the reload endpoint is not
  3362  	// accessible.
  3363  	ncTest, _ := jsClientConnect(t, s, nats.UserInfo("foo", "bar"))
  3364  	defer ncTest.Close()
  3365  	testReply := ncTest.NewRespInbox()
  3366  	sub, err := ncTest.SubscribeSync(testReply)
  3367  	require_NoError(t, err)
  3368  	err = ncTest.PublishRequest(subject, testReply, nil)
  3369  	require_NoError(t, err)
  3370  	_, err = sub.NextMsg(time.Second)
  3371  	require_Error(t, err)
  3372  
  3373  	require_True(t, s.getOpts().PingInterval == 100*time.Millisecond)
  3374  
  3375  	// Connect as a system user.
  3376  	nc, _ := jsClientConnect(t, s, nats.UserInfo("admin", "p1d"))
  3377  	defer nc.Close()
  3378  
  3379  	// rewrite the config file with a different ping interval
  3380  	err = os.WriteFile(conf, []byte(`
  3381  		listen: "127.0.0.1:-1"
  3382  		accounts: {
  3383  			$SYS { users [{user: "admin", password: "p1d"}]}
  3384  			test { users [{user: "foo", password: "bar"}]}
  3385  		}
  3386  		ping_interval: "200ms"
  3387  	`), 0666)
  3388  	require_NoError(t, err)
  3389  
  3390  	msg, err := nc.Request(subject, nil, time.Second)
  3391  	require_NoError(t, err)
  3392  
  3393  	var apiResp = ServerAPIResponse{}
  3394  	err = json.Unmarshal(msg.Data, &apiResp)
  3395  	require_NoError(t, err)
  3396  
  3397  	require_True(t, apiResp.Data == nil)
  3398  	require_True(t, apiResp.Error == nil)
  3399  
  3400  	// See that the ping interval has changed.
  3401  	require_True(t, s.getOpts().PingInterval == 200*time.Millisecond)
  3402  
  3403  	// rewrite the config file with a different ping interval
  3404  	err = os.WriteFile(conf, []byte(`garbage and nonsense`), 0666)
  3405  	require_NoError(t, err)
  3406  
  3407  	// Request the server to reload and wait for the response.
  3408  	msg, err = nc.Request(subject, nil, time.Second)
  3409  	require_NoError(t, err)
  3410  
  3411  	apiResp = ServerAPIResponse{}
  3412  	err = json.Unmarshal(msg.Data, &apiResp)
  3413  	require_NoError(t, err)
  3414  
  3415  	require_True(t, apiResp.Data == nil)
  3416  	require_Error(t, apiResp.Error, fmt.Errorf("Parse error on line 1: 'Expected a top-level value to end with a new line, comment or EOF, but got 'n' instead.'"))
  3417  
  3418  	// See that the ping interval has not changed.
  3419  	require_True(t, s.getOpts().PingInterval == 200*time.Millisecond)
  3420  }
  3421  
  3422  func TestServerEventsLDMKick(t *testing.T) {
  3423  	ldmed := make(chan bool, 1)
  3424  	disconnected := make(chan bool, 1)
  3425  
  3426  	s, opts := runTrustedServer(t)
  3427  	defer s.Shutdown()
  3428  
  3429  	acc, akp := createAccount(s)
  3430  	s.setSystemAccount(acc)
  3431  
  3432  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  3433  	ncs, err := nats.Connect(url, createUserCreds(t, s, akp))
  3434  	if err != nil {
  3435  		t.Fatalf("Error on connect: %v", err)
  3436  	}
  3437  	defer ncs.Close()
  3438  
  3439  	_, akp2 := createAccount(s)
  3440  
  3441  	nc, err := nats.Connect(url, createUserCreds(t, s, akp2), nats.Name("TEST EVENTS LDM+KICK"), nats.LameDuckModeHandler(func(_ *nats.Conn) { ldmed <- true }))
  3442  	if err != nil {
  3443  		t.Fatalf("Error on connect: %v", err)
  3444  	}
  3445  	defer nc.Close()
  3446  
  3447  	nc.SetDisconnectErrHandler(func(_ *nats.Conn, err error) { disconnected <- true })
  3448  
  3449  	cid, err := nc.GetClientID()
  3450  	if err != nil {
  3451  		t.Fatalf("Error on getting the CID: %v", err)
  3452  	}
  3453  
  3454  	reqldm := LDMClientReq{CID: cid}
  3455  	reqldmpayload, _ := json.Marshal(reqldm)
  3456  	reqkick := KickClientReq{CID: cid}
  3457  	reqkickpayload, _ := json.Marshal(reqkick)
  3458  
  3459  	_, err = ncs.Request(fmt.Sprintf("$SYS.REQ.SERVER.%s.LDM", s.ID()), reqldmpayload, time.Second)
  3460  	if err != nil {
  3461  		t.Fatalf("Error trying to publish the LDM request: %v", err)
  3462  	}
  3463  
  3464  	select {
  3465  	case <-ldmed:
  3466  	case <-time.After(time.Second):
  3467  		t.Fatalf("timeout waiting for the connection to receive the LDM signal")
  3468  	}
  3469  
  3470  	_, err = ncs.Request(fmt.Sprintf("$SYS.REQ.SERVER.%s.KICK", s.ID()), reqkickpayload, time.Second)
  3471  	if err != nil {
  3472  		t.Fatalf("Error trying to publish the KICK request: %v", err)
  3473  	}
  3474  
  3475  	select {
  3476  	case <-disconnected:
  3477  	case <-time.After(time.Second):
  3478  		t.Fatalf("timeout waiting for the client to get disconnected")
  3479  	}
  3480  }
  3481  
  3482  func Benchmark_GetHash(b *testing.B) {
  3483  	b.StopTimer()
  3484  	// Get 100 random names
  3485  	names := make([]string, 0, 100)
  3486  	for i := 0; i < 100; i++ {
  3487  		names = append(names, nuid.Next())
  3488  	}
  3489  	hashes := make([]string, 0, 100)
  3490  	for j := 0; j < 100; j++ {
  3491  		sha := sha256.New()
  3492  		sha.Write([]byte(names[j]))
  3493  		b := sha.Sum(nil)
  3494  		for i := 0; i < 8; i++ {
  3495  			b[i] = digits[int(b[i]%base)]
  3496  		}
  3497  		hashes = append(hashes, string(b[:8]))
  3498  	}
  3499  	wg := sync.WaitGroup{}
  3500  	wg.Add(8)
  3501  	errCh := make(chan error, 8)
  3502  	b.StartTimer()
  3503  	for i := 0; i < 8; i++ {
  3504  		go func() {
  3505  			defer wg.Done()
  3506  			for i := 0; i < b.N; i++ {
  3507  				idx := rand.Intn(100)
  3508  				if h := getHash(names[idx]); h != hashes[idx] {
  3509  					errCh <- fmt.Errorf("Hash for name %q was %q, but should be %q", names[idx], h, hashes[idx])
  3510  					return
  3511  				}
  3512  			}
  3513  		}()
  3514  	}
  3515  	wg.Wait()
  3516  	select {
  3517  	case err := <-errCh:
  3518  		b.Fatal(err.Error())
  3519  	default:
  3520  	}
  3521  }