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

     1  // Copyright 2012-2019 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 test
    15  
    16  import (
    17  	"encoding/json"
    18  	"fmt"
    19  	"io"
    20  	"net"
    21  	"os"
    22  	"runtime"
    23  	"strconv"
    24  	"sync"
    25  	"testing"
    26  	"time"
    27  
    28  	"get.pme.sh/pnats/internal/testhelper"
    29  	"get.pme.sh/pnats/server"
    30  	"github.com/nats-io/nats.go"
    31  )
    32  
    33  const clientProtoInfo = 1
    34  
    35  func runRouteServer(t *testing.T) (*server.Server, *server.Options) {
    36  	return RunServerWithConfig("./configs/cluster.conf")
    37  }
    38  
    39  func runRouteServerOverrides(t *testing.T, cbo func(*server.Options), cbs func(*server.Server)) (*server.Server, *server.Options) {
    40  	return RunServerWithConfigOverrides("./configs/cluster.conf", cbo, cbs)
    41  }
    42  
    43  func TestRouterListeningSocket(t *testing.T) {
    44  	s, opts := runRouteServer(t)
    45  	defer s.Shutdown()
    46  
    47  	// Check that the cluster socket is able to be connected.
    48  	addr := fmt.Sprintf("%s:%d", opts.Cluster.Host, opts.Cluster.Port)
    49  	checkSocket(t, addr, 2*time.Second)
    50  }
    51  
    52  func TestRouteGoServerShutdown(t *testing.T) {
    53  	base := runtime.NumGoroutine()
    54  	s, _ := runRouteServer(t)
    55  	s.Shutdown()
    56  	time.Sleep(50 * time.Millisecond)
    57  	delta := (runtime.NumGoroutine() - base)
    58  	if delta > 1 {
    59  		t.Fatalf("%d Go routines still exist post Shutdown()", delta)
    60  	}
    61  }
    62  
    63  func TestSendRouteInfoOnConnect(t *testing.T) {
    64  	s, opts := runRouteServer(t)
    65  	defer s.Shutdown()
    66  
    67  	rc := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
    68  	defer rc.Close()
    69  
    70  	routeID := "RouteID"
    71  	routeSend, routeExpect := setupRouteEx(t, rc, opts, routeID)
    72  	buf := routeExpect(infoRe)
    73  
    74  	info := server.Info{}
    75  	if err := json.Unmarshal(buf[4:], &info); err != nil {
    76  		t.Fatalf("Could not unmarshal route info: %v", err)
    77  	}
    78  
    79  	if !info.AuthRequired {
    80  		t.Fatal("Expected to see AuthRequired")
    81  	}
    82  	if info.Port != opts.Cluster.Port {
    83  		t.Fatalf("Received wrong information for port, expected %d, got %d",
    84  			info.Port, opts.Cluster.Port)
    85  	}
    86  
    87  	// Need to send a different INFO than the one received, otherwise the server
    88  	// will detect as a "cycle" and close the connection.
    89  	info.ID = routeID
    90  	info.Name = ""
    91  	b, err := json.Marshal(info)
    92  	if err != nil {
    93  		t.Fatalf("Could not marshal test route info: %v", err)
    94  	}
    95  	infoJSON := fmt.Sprintf("INFO %s\r\n", b)
    96  	routeSend(infoJSON)
    97  	routeSend("PING\r\n")
    98  	routeExpect(pongRe)
    99  }
   100  
   101  func TestRouteToSelf(t *testing.T) {
   102  	l := testhelper.NewDummyLogger(100)
   103  	s, opts := runRouteServerOverrides(t, nil,
   104  		func(s *server.Server) {
   105  			s.SetLogger(l, true, true)
   106  		})
   107  	defer s.Shutdown()
   108  
   109  	rc := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   110  	defer rc.Close()
   111  
   112  	routeSend, routeExpect := setupRouteEx(t, rc, opts, s.ID())
   113  	buf := routeExpect(infoRe)
   114  
   115  	info := server.Info{}
   116  	if err := json.Unmarshal(buf[4:], &info); err != nil {
   117  		t.Fatalf("Could not unmarshal route info: %v", err)
   118  	}
   119  
   120  	if !info.AuthRequired {
   121  		t.Fatal("Expected to see AuthRequired")
   122  	}
   123  	if info.Port != opts.Cluster.Port {
   124  		t.Fatalf("Received wrong information for port, expected %d, got %d",
   125  			info.Port, opts.Cluster.Port)
   126  	}
   127  
   128  	// Now send it back and that should be detected as a route to self and the
   129  	// connection closed.
   130  	routeSend(string(buf))
   131  	routeSend("PING\r\n")
   132  	rc.SetReadDeadline(time.Now().Add(2 * time.Second))
   133  	if _, err := rc.Read(buf); err == nil {
   134  		t.Fatal("Expected route connection to be closed")
   135  	}
   136  	// This should have been removed by removePassFromTrace(), but we also check debug logs here
   137  	l.CheckForProhibited(t, "route authorization password found", "top_secret")
   138  }
   139  
   140  func TestSendRouteSubAndUnsub(t *testing.T) {
   141  	s, opts := runRouteServer(t)
   142  	defer s.Shutdown()
   143  
   144  	c := createClientConn(t, opts.Host, opts.Port)
   145  	defer c.Close()
   146  
   147  	send, _ := setupConn(t, c)
   148  
   149  	// We connect to the route.
   150  	rc := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   151  	defer rc.Close()
   152  
   153  	expectAuthRequired(t, rc)
   154  	routeSend, routeExpect := setupRouteEx(t, rc, opts, "ROUTER:xyz")
   155  	routeSend("INFO {\"server_id\":\"ROUTER:xyz\"}\r\n")
   156  
   157  	routeSend("PING\r\n")
   158  	routeExpect(pongRe)
   159  
   160  	// Send SUB via client connection
   161  	send("SUB foo 22\r\n")
   162  
   163  	// Make sure the RS+ is broadcast via the route
   164  	expectResult(t, rc, rsubRe)
   165  
   166  	// Send UNSUB via client connection
   167  	send("UNSUB 22\r\n")
   168  
   169  	// Make sure the RS- is broadcast via the route
   170  	expectResult(t, rc, runsubRe)
   171  
   172  	// Explicitly shutdown the server, otherwise this test would
   173  	// cause following test to fail.
   174  	s.Shutdown()
   175  }
   176  
   177  func TestSendRouteSolicit(t *testing.T) {
   178  	s, opts := runRouteServer(t)
   179  	defer s.Shutdown()
   180  
   181  	// Listen for a connection from the server on the first route.
   182  	if len(opts.Routes) <= 0 {
   183  		t.Fatalf("Need an outbound solicted route for this test")
   184  	}
   185  	rURL := opts.Routes[0]
   186  
   187  	conn := acceptRouteConn(t, rURL.Host, server.DEFAULT_ROUTE_CONNECT)
   188  	defer conn.Close()
   189  
   190  	// We should receive a connect message right away due to auth.
   191  	buf := expectResult(t, conn, connectRe)
   192  
   193  	// Check INFO follows. Could be inline, with first result, if not
   194  	// check follow-on buffer.
   195  	if !infoRe.Match(buf) {
   196  		expectResult(t, conn, infoRe)
   197  	}
   198  }
   199  
   200  func TestRouteForwardsMsgFromClients(t *testing.T) {
   201  	s, opts := runRouteServer(t)
   202  	defer s.Shutdown()
   203  
   204  	client := createClientConn(t, opts.Host, opts.Port)
   205  	defer client.Close()
   206  
   207  	clientSend, clientExpect := setupConn(t, client)
   208  
   209  	route := acceptRouteConn(t, opts.Routes[0].Host, server.DEFAULT_ROUTE_CONNECT)
   210  	defer route.Close()
   211  
   212  	routeSend, routeExpect := setupRoute(t, route, opts)
   213  	expectMsgs := expectMsgsCommand(t, routeExpect)
   214  
   215  	// Eat the CONNECT and INFO protos
   216  	buf := routeExpect(connectRe)
   217  	if !infoRe.Match(buf) {
   218  		routeExpect(infoRe)
   219  	}
   220  
   221  	// Send SUB via route connection, RS+
   222  	routeSend("RS+ $G foo\r\nPING\r\n")
   223  	routeExpect(pongRe)
   224  
   225  	// Send PUB via client connection
   226  	clientSend("PUB foo 2\r\nok\r\nPING\r\n")
   227  	clientExpect(pongRe)
   228  
   229  	matches := expectMsgs(1)
   230  	checkRmsg(t, matches[0], "$G", "foo", "", "2", "ok")
   231  }
   232  
   233  func TestRouteForwardsMsgToClients(t *testing.T) {
   234  	s, opts := runRouteServer(t)
   235  	defer s.Shutdown()
   236  
   237  	client := createClientConn(t, opts.Host, opts.Port)
   238  	defer client.Close()
   239  
   240  	clientSend, clientExpect := setupConn(t, client)
   241  	expectMsgs := expectMsgsCommand(t, clientExpect)
   242  
   243  	route := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   244  	defer route.Close()
   245  	expectAuthRequired(t, route)
   246  	routeSend, _ := setupRoute(t, route, opts)
   247  
   248  	// Subscribe to foo
   249  	clientSend("SUB foo 1\r\nPING\r\n")
   250  	// Use ping roundtrip to make sure its processed.
   251  	clientExpect(pongRe)
   252  
   253  	// Send RMSG proto via route connection
   254  	routeSend("RMSG $G foo 2\r\nok\r\n")
   255  
   256  	matches := expectMsgs(1)
   257  	checkMsg(t, matches[0], "foo", "1", "", "2", "ok")
   258  }
   259  
   260  func TestRouteOneHopSemantics(t *testing.T) {
   261  	s, opts := runRouteServer(t)
   262  	defer s.Shutdown()
   263  
   264  	route := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   265  	defer route.Close()
   266  
   267  	expectAuthRequired(t, route)
   268  	routeSend, _ := setupRoute(t, route, opts)
   269  
   270  	// Express interest on this route for foo.
   271  	routeSend("RS+ $G foo\r\n")
   272  
   273  	// Send MSG proto via route connection
   274  	routeSend("RMSG foo 2\r\nok\r\n")
   275  
   276  	// Make sure it does not come back!
   277  	expectNothing(t, route)
   278  }
   279  
   280  func TestRouteOnlySendOnce(t *testing.T) {
   281  	s, opts := runRouteServer(t)
   282  	defer s.Shutdown()
   283  
   284  	client := createClientConn(t, opts.Host, opts.Port)
   285  	defer client.Close()
   286  
   287  	clientSend, clientExpect := setupConn(t, client)
   288  
   289  	route := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   290  	defer route.Close()
   291  
   292  	expectAuthRequired(t, route)
   293  	routeSend, routeExpect := setupRoute(t, route, opts)
   294  	expectMsgs := expectMsgsCommand(t, routeExpect)
   295  
   296  	// Express multiple interest on this route for foo.
   297  	routeSend("RS+ $G foo\r\n")
   298  	routeSend("RS+ $G foo\r\n")
   299  	routeSend("PING\r\n")
   300  	routeExpect(pongRe)
   301  
   302  	// Send PUB via client connection
   303  	clientSend("PUB foo 2\r\nok\r\nPING\r\n")
   304  	clientExpect(pongRe)
   305  
   306  	expectMsgs(1)
   307  	routeSend("PING\r\n")
   308  	routeExpect(pongRe)
   309  }
   310  
   311  func TestRouteQueueSemantics(t *testing.T) {
   312  	s, opts := runRouteServer(t)
   313  	defer s.Shutdown()
   314  
   315  	client := createClientConn(t, opts.Host, opts.Port)
   316  	clientSend, clientExpect := setupConn(t, client)
   317  	clientExpectMsgs := expectMsgsCommand(t, clientExpect)
   318  
   319  	defer client.Close()
   320  
   321  	route := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   322  	defer route.Close()
   323  
   324  	expectAuthRequired(t, route)
   325  	routeSend, routeExpect := setupRouteEx(t, route, opts, "ROUTER:xyz")
   326  	routeSend("INFO {\"server_id\":\"ROUTER:xyz\"}\r\n")
   327  	expectMsgs := expectRmsgsCommand(t, routeExpect)
   328  
   329  	// Express multiple interest on this route for foo, queue group bar.
   330  	routeSend("RS+ $G foo bar 1\r\n")
   331  	routeSend("RS+ $G foo bar 2\r\n")
   332  
   333  	// Use ping roundtrip to make sure its processed.
   334  	routeSend("PING\r\n")
   335  	routeExpect(pongRe)
   336  
   337  	// Send PUB via client connection
   338  	clientSend("PUB foo 2\r\nok\r\n")
   339  	// Use ping roundtrip to make sure its processed.
   340  	clientSend("PING\r\n")
   341  	clientExpect(pongRe)
   342  
   343  	// Only 1
   344  	matches := expectMsgs(1)
   345  	checkRmsg(t, matches[0], "$G", "foo", "| bar", "2", "ok")
   346  
   347  	// Add normal Interest as well to route interest.
   348  	routeSend("RS+ $G foo\r\n")
   349  
   350  	// Use ping roundtrip to make sure its processed.
   351  	routeSend("PING\r\n")
   352  	routeExpect(pongRe)
   353  
   354  	// Send PUB via client connection
   355  	clientSend("PUB foo 2\r\nok\r\nPING\r\n")
   356  	// Use ping roundtrip to make sure its processed.
   357  	clientExpect(pongRe)
   358  
   359  	// Should be 1 now for everything. Always receive 1 message.
   360  	matches = expectMsgs(1)
   361  	checkRmsg(t, matches[0], "$G", "foo", "| bar", "2", "ok")
   362  
   363  	// Now create a queue subscription for the client as well as a normal one.
   364  	clientSend("SUB foo 1\r\n")
   365  	// Use ping roundtrip to make sure its processed.
   366  	clientSend("PING\r\n")
   367  	clientExpect(pongRe)
   368  	routeExpect(rsubRe)
   369  
   370  	clientSend("SUB foo bar 2\r\nPING\r\n")
   371  	// Use ping roundtrip to make sure its processed.
   372  	clientExpect(pongRe)
   373  	routeExpect(rsubRe)
   374  
   375  	// Deliver a MSG from the route itself, make sure the client receives both.
   376  	routeSend("RMSG $G foo | bar 2\r\nok\r\n")
   377  
   378  	// Use ping roundtrip to make sure its processed.
   379  	routeSend("PING\r\n")
   380  	routeExpect(pongRe)
   381  
   382  	// Should get 2 msgs.
   383  	matches = clientExpectMsgs(2)
   384  
   385  	// Expect first to be the normal subscriber, next will be the queue one.
   386  	checkMsg(t, matches[0], "foo", "", "", "2", "ok")
   387  }
   388  
   389  func TestSolicitRouteReconnect(t *testing.T) {
   390  	l := testhelper.NewDummyLogger(100)
   391  	s, opts := runRouteServerOverrides(t, nil,
   392  		func(s *server.Server) {
   393  			s.SetLogger(l, true, true)
   394  		})
   395  	defer s.Shutdown()
   396  
   397  	rURL := opts.Routes[0]
   398  
   399  	route := acceptRouteConn(t, rURL.Host, 2*server.DEFAULT_ROUTE_CONNECT)
   400  
   401  	// Go ahead and close the Route.
   402  	route.Close()
   403  
   404  	// We expect to get called back..
   405  	route = acceptRouteConn(t, rURL.Host, 2*server.DEFAULT_ROUTE_CONNECT)
   406  	route.Close()
   407  
   408  	// Now we want to check for the debug logs when it tries to reconnect
   409  	l.CheckForProhibited(t, "route authorization password found", ":bar")
   410  }
   411  
   412  func TestMultipleRoutesSameId(t *testing.T) {
   413  	s, opts := runRouteServer(t)
   414  	defer s.Shutdown()
   415  
   416  	route1 := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   417  	defer route1.Close()
   418  
   419  	expectAuthRequired(t, route1)
   420  	route1Send, route1Expect := setupRouteEx(t, route1, opts, "ROUTE:2222")
   421  
   422  	route2 := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   423  	defer route2.Close()
   424  
   425  	expectAuthRequired(t, route2)
   426  	route2Send, route2Expect := setupRouteEx(t, route2, opts, "ROUTE:2222")
   427  
   428  	// Send SUB via route connections
   429  	sub := "RS+ $G foo\r\nPING\r\n"
   430  	route1Send(sub)
   431  	route2Send(sub)
   432  	route1Expect(pongRe)
   433  	route2Expect(pongRe)
   434  
   435  	// Make sure we do not get anything on a RMSG send to a router.
   436  	// Send RMSG proto via route connection
   437  	route1Send("RMSG $G foo 2\r\nok\r\n")
   438  
   439  	expectNothing(t, route1)
   440  	expectNothing(t, route2)
   441  
   442  	// Setup a client
   443  	client := createClientConn(t, opts.Host, opts.Port)
   444  	clientSend, clientExpect := setupConn(t, client)
   445  	defer client.Close()
   446  
   447  	// Send PUB via client connection
   448  	clientSend("PUB foo 2\r\nok\r\nPING\r\n")
   449  	clientExpect(pongRe)
   450  
   451  	// We should only receive on one route, not both.
   452  	// Check both manually.
   453  	route1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   454  	buf, _ := io.ReadAll(route1)
   455  	route1.SetReadDeadline(time.Time{})
   456  	if len(buf) <= 0 {
   457  		route2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   458  		buf, _ = io.ReadAll(route2)
   459  		route2.SetReadDeadline(time.Time{})
   460  		if len(buf) <= 0 {
   461  			t.Fatal("Expected to get one message on a route, received none.")
   462  		}
   463  	}
   464  
   465  	matches := rmsgRe.FindAllSubmatch(buf, -1)
   466  	if len(matches) != 1 {
   467  		t.Fatalf("Expected 1 msg, got %d\n", len(matches))
   468  	}
   469  	checkRmsg(t, matches[0], "$G", "foo", "", "2", "ok")
   470  }
   471  
   472  func TestRouteResendsLocalSubsOnReconnect(t *testing.T) {
   473  	s, opts := runRouteServer(t)
   474  	defer s.Shutdown()
   475  
   476  	client := createClientConn(t, opts.Host, opts.Port)
   477  	defer client.Close()
   478  
   479  	clientSend, clientExpect := setupConn(t, client)
   480  
   481  	// Setup a local subscription, make sure it reaches.
   482  	clientSend("SUB foo 1\r\n")
   483  	clientSend("PING\r\n")
   484  	clientExpect(pongRe)
   485  
   486  	route := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   487  	defer route.Close()
   488  	routeSend, routeExpect := setupRouteEx(t, route, opts, "ROUTE:1234")
   489  
   490  	// Expect to see the local sub echoed through after we send our INFO.
   491  	time.Sleep(50 * time.Millisecond)
   492  	buf := routeExpect(infoRe)
   493  
   494  	// Generate our own INFO so we can send one to trigger the local subs.
   495  	info := server.Info{}
   496  	if err := json.Unmarshal(buf[4:], &info); err != nil {
   497  		t.Fatalf("Could not unmarshal route info: %v", err)
   498  	}
   499  	info.ID = "ROUTE:1234"
   500  	info.Name = ""
   501  	b, err := json.Marshal(info)
   502  	if err != nil {
   503  		t.Fatalf("Could not marshal test route info: %v", err)
   504  	}
   505  	infoJSON := fmt.Sprintf("INFO %s\r\n", b)
   506  
   507  	// Trigger the send of local subs.
   508  	routeSend(infoJSON)
   509  
   510  	routeExpect(rsubRe)
   511  
   512  	// Close and then re-open
   513  	route.Close()
   514  
   515  	// Give some time for the route close to be processed before trying to recreate.
   516  	checkNumRoutes(t, s, 0)
   517  
   518  	route = createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   519  	defer route.Close()
   520  
   521  	routeSend, routeExpect = setupRouteEx(t, route, opts, "ROUTE:1234")
   522  
   523  	routeExpect(infoRe)
   524  
   525  	routeSend(infoJSON)
   526  	routeExpect(rsubRe)
   527  }
   528  
   529  type ignoreLogger struct{}
   530  
   531  func (l *ignoreLogger) Fatalf(f string, args ...interface{}) {}
   532  func (l *ignoreLogger) Errorf(f string, args ...interface{}) {}
   533  
   534  func TestRouteConnectOnShutdownRace(t *testing.T) {
   535  	s, opts := runRouteServer(t)
   536  	defer s.Shutdown()
   537  
   538  	l := &ignoreLogger{}
   539  
   540  	var wg sync.WaitGroup
   541  
   542  	cQuit := make(chan bool, 1)
   543  
   544  	wg.Add(1)
   545  
   546  	go func() {
   547  		defer wg.Done()
   548  		for {
   549  			route := createRouteConn(l, opts.Cluster.Host, opts.Cluster.Port)
   550  			if route != nil {
   551  				setupRouteEx(l, route, opts, "ROUTE:1234")
   552  				route.Close()
   553  			}
   554  			select {
   555  			case <-cQuit:
   556  				return
   557  			default:
   558  			}
   559  		}
   560  	}()
   561  
   562  	time.Sleep(5 * time.Millisecond)
   563  	s.Shutdown()
   564  
   565  	cQuit <- true
   566  
   567  	wg.Wait()
   568  }
   569  
   570  func TestRouteSendAsyncINFOToClients(t *testing.T) {
   571  	f := func(opts *server.Options) {
   572  		s := RunServer(opts)
   573  		defer s.Shutdown()
   574  
   575  		clientURL := net.JoinHostPort(opts.Host, strconv.Itoa(opts.Port))
   576  
   577  		oldClient := createClientConn(t, opts.Host, opts.Port)
   578  		defer oldClient.Close()
   579  
   580  		oldClientSend, oldClientExpect := setupConn(t, oldClient)
   581  		oldClientSend("PING\r\n")
   582  		oldClientExpect(pongRe)
   583  
   584  		newClient := createClientConn(t, opts.Host, opts.Port)
   585  		defer newClient.Close()
   586  
   587  		newClientSend, newClientExpect := setupConnWithProto(t, newClient, clientProtoInfo)
   588  		newClientSend("PING\r\n")
   589  		newClientExpect(pongRe)
   590  
   591  		// Check that even a new client does not receive an async INFO at this point
   592  		// since there is no route created yet.
   593  		expectNothing(t, newClient)
   594  
   595  		routeID := "Server-B"
   596  
   597  		createRoute := func() (net.Conn, sendFun, expectFun) {
   598  			rc := createRouteConn(t, opts.Cluster.Host, opts.Cluster.Port)
   599  			routeSend, routeExpect := setupRouteEx(t, rc, opts, routeID)
   600  
   601  			buf := routeExpect(infoRe)
   602  
   603  			info := server.Info{}
   604  			if err := json.Unmarshal(buf[4:], &info); err != nil {
   605  				stackFatalf(t, "Could not unmarshal route info: %v", err)
   606  			}
   607  			if opts.Cluster.NoAdvertise {
   608  				if len(info.ClientConnectURLs) != 0 {
   609  					stackFatalf(t, "Expected ClientConnectURLs to be empty, got %v", info.ClientConnectURLs)
   610  				}
   611  			} else {
   612  				if len(info.ClientConnectURLs) == 0 {
   613  					stackFatalf(t, "Expected a list of URLs, got none")
   614  				}
   615  				if info.ClientConnectURLs[0] != clientURL {
   616  					stackFatalf(t, "Expected ClientConnectURLs to be %q, got %q", clientURL, info.ClientConnectURLs[0])
   617  				}
   618  			}
   619  
   620  			return rc, routeSend, routeExpect
   621  		}
   622  
   623  		sendRouteINFO := func(routeSend sendFun, routeExpect expectFun, urls []string) {
   624  			routeInfo := server.Info{}
   625  			routeInfo.ID = routeID
   626  			routeInfo.Cluster = "xyz"
   627  			routeInfo.Host = "127.0.0.1"
   628  			routeInfo.Port = 5222
   629  			routeInfo.ClientConnectURLs = urls
   630  			b, err := json.Marshal(routeInfo)
   631  			if err != nil {
   632  				stackFatalf(t, "Could not marshal test route info: %v", err)
   633  			}
   634  			infoJSON := fmt.Sprintf("INFO %s\r\n", b)
   635  			routeSend(infoJSON)
   636  			routeSend("PING\r\n")
   637  			routeExpect(pongRe)
   638  		}
   639  
   640  		checkClientConnectURLS := func(urls, expected []string) {
   641  			// Order of array is not guaranteed.
   642  			ok := false
   643  			if len(urls) == len(expected) {
   644  				m := make(map[string]struct{}, len(expected))
   645  				for _, url := range expected {
   646  					m[url] = struct{}{}
   647  				}
   648  				ok = true
   649  				for _, url := range urls {
   650  					if _, present := m[url]; !present {
   651  						ok = false
   652  						break
   653  					}
   654  				}
   655  			}
   656  			if !ok {
   657  				stackFatalf(t, "Expected ClientConnectURLs to be %v, got %v", expected, urls)
   658  			}
   659  		}
   660  
   661  		checkINFOReceived := func(client net.Conn, clientExpect expectFun, expectedURLs []string) {
   662  			if opts.Cluster.NoAdvertise {
   663  				expectNothing(t, client)
   664  				return
   665  			}
   666  			buf := clientExpect(infoRe)
   667  			info := server.Info{}
   668  			if err := json.Unmarshal(buf[4:], &info); err != nil {
   669  				stackFatalf(t, "Could not unmarshal route info: %v", err)
   670  			}
   671  			checkClientConnectURLS(info.ClientConnectURLs, expectedURLs)
   672  		}
   673  
   674  		// Create a route
   675  		rc, routeSend, routeExpect := createRoute()
   676  		defer rc.Close()
   677  
   678  		// Send an INFO with single URL
   679  		routeClientConnectURLs := []string{"127.0.0.1:5222"}
   680  		sendRouteINFO(routeSend, routeExpect, routeClientConnectURLs)
   681  
   682  		// Expect nothing for old clients
   683  		expectNothing(t, oldClient)
   684  
   685  		// We expect to get the one from the server we connect to and the other route.
   686  		expectedURLs := []string{clientURL, routeClientConnectURLs[0]}
   687  
   688  		// Expect new client to receive an INFO (unless disabled)
   689  		checkINFOReceived(newClient, newClientExpect, expectedURLs)
   690  
   691  		// Disconnect the route
   692  		rc.Close()
   693  
   694  		// Expect nothing for old clients
   695  		expectNothing(t, oldClient)
   696  
   697  		// Expect new client to receive an INFO (unless disabled).
   698  		// The content will now have the disconnected route ClientConnectURLs
   699  		// removed from the INFO. So it should be the one from the server the
   700  		// client is connected to.
   701  		checkINFOReceived(newClient, newClientExpect, []string{clientURL})
   702  
   703  		// Reconnect the route.
   704  		rc, routeSend, routeExpect = createRoute()
   705  		defer rc.Close()
   706  
   707  		// Resend the same route INFO json. The server will now send
   708  		// the INFO since the disconnected route ClientConnectURLs was
   709  		// removed in previous step.
   710  		sendRouteINFO(routeSend, routeExpect, routeClientConnectURLs)
   711  
   712  		// Expect nothing for old clients
   713  		expectNothing(t, oldClient)
   714  
   715  		// Expect new client to receive an INFO (unless disabled)
   716  		checkINFOReceived(newClient, newClientExpect, expectedURLs)
   717  
   718  		// Now stop the route and restart with an additional URL
   719  		rc.Close()
   720  
   721  		// On route disconnect, clients will receive an updated INFO
   722  		expectNothing(t, oldClient)
   723  		checkINFOReceived(newClient, newClientExpect, []string{clientURL})
   724  
   725  		rc, routeSend, routeExpect = createRoute()
   726  		defer rc.Close()
   727  
   728  		// Create a client not sending the CONNECT until after route is added
   729  		clientNoConnect := createClientConn(t, opts.Host, opts.Port)
   730  		defer clientNoConnect.Close()
   731  
   732  		// Create a client that does not send the first PING yet
   733  		clientNoPing := createClientConn(t, opts.Host, opts.Port)
   734  		defer clientNoPing.Close()
   735  		clientNoPingSend, clientNoPingExpect := setupConnWithProto(t, clientNoPing, clientProtoInfo)
   736  
   737  		// The route now has an additional URL
   738  		routeClientConnectURLs = append(routeClientConnectURLs, "127.0.0.1:7777")
   739  		expectedURLs = append(expectedURLs, "127.0.0.1:7777")
   740  		// This causes the server to add the route and send INFO to clients
   741  		sendRouteINFO(routeSend, routeExpect, routeClientConnectURLs)
   742  
   743  		// Expect nothing for old clients
   744  		expectNothing(t, oldClient)
   745  
   746  		// Expect new client to receive an INFO, and verify content as expected.
   747  		checkINFOReceived(newClient, newClientExpect, expectedURLs)
   748  
   749  		// Expect nothing yet for client that did not send the PING
   750  		expectNothing(t, clientNoPing)
   751  
   752  		// Now send the first PING
   753  		clientNoPingSend("PING\r\n")
   754  		// Should receive PONG followed by INFO
   755  		// Receive PONG only first
   756  		pongBuf := make([]byte, len("PONG\r\n"))
   757  		clientNoPing.SetReadDeadline(time.Now().Add(2 * time.Second))
   758  		n, err := clientNoPing.Read(pongBuf)
   759  		clientNoPing.SetReadDeadline(time.Time{})
   760  		if n <= 0 && err != nil {
   761  			t.Fatalf("Error reading from conn: %v\n", err)
   762  		}
   763  		if !pongRe.Match(pongBuf) {
   764  			t.Fatalf("Response did not match expected: \n\tReceived:'%q'\n\tExpected:'%s'\n", pongBuf, pongRe)
   765  		}
   766  		checkINFOReceived(clientNoPing, clientNoPingExpect, expectedURLs)
   767  
   768  		// Have the client that did not send the connect do it now
   769  		clientNoConnectSend, clientNoConnectExpect := setupConnWithProto(t, clientNoConnect, clientProtoInfo)
   770  		// Send the PING
   771  		clientNoConnectSend("PING\r\n")
   772  		// Should receive PONG followed by INFO
   773  		// Receive PONG only first
   774  		clientNoConnect.SetReadDeadline(time.Now().Add(2 * time.Second))
   775  		n, err = clientNoConnect.Read(pongBuf)
   776  		clientNoConnect.SetReadDeadline(time.Time{})
   777  		if n <= 0 && err != nil {
   778  			t.Fatalf("Error reading from conn: %v\n", err)
   779  		}
   780  		if !pongRe.Match(pongBuf) {
   781  			t.Fatalf("Response did not match expected: \n\tReceived:'%q'\n\tExpected:'%s'\n", pongBuf, pongRe)
   782  		}
   783  		checkINFOReceived(clientNoConnect, clientNoConnectExpect, expectedURLs)
   784  
   785  		// Create a client connection and verify content of initial INFO contains array
   786  		// (but empty if no advertise option is set)
   787  		cli := createClientConn(t, opts.Host, opts.Port)
   788  		defer cli.Close()
   789  		buf := expectResult(t, cli, infoRe)
   790  		js := infoRe.FindAllSubmatch(buf, 1)[0][1]
   791  		var sinfo server.Info
   792  		err = json.Unmarshal(js, &sinfo)
   793  		if err != nil {
   794  			t.Fatalf("Could not unmarshal INFO json: %v\n", err)
   795  		}
   796  		if opts.Cluster.NoAdvertise {
   797  			if len(sinfo.ClientConnectURLs) != 0 {
   798  				t.Fatalf("Expected ClientConnectURLs to be empty, got %v", sinfo.ClientConnectURLs)
   799  			}
   800  		} else {
   801  			checkClientConnectURLS(sinfo.ClientConnectURLs, expectedURLs)
   802  		}
   803  
   804  		// Add a new route
   805  		routeID = "Server-C"
   806  		rc2, route2Send, route2Expect := createRoute()
   807  		defer rc2.Close()
   808  
   809  		// Send an INFO with single URL
   810  		rc2ConnectURLs := []string{"127.0.0.1:8888"}
   811  		sendRouteINFO(route2Send, route2Expect, rc2ConnectURLs)
   812  
   813  		// This is the combined client connect URLs array
   814  		totalConnectURLs := expectedURLs
   815  		totalConnectURLs = append(totalConnectURLs, rc2ConnectURLs...)
   816  
   817  		// Expect nothing for old clients
   818  		expectNothing(t, oldClient)
   819  
   820  		// Expect new client to receive an INFO (unless disabled)
   821  		checkINFOReceived(newClient, newClientExpect, totalConnectURLs)
   822  
   823  		// Make first route disconnect
   824  		rc.Close()
   825  
   826  		// Expect nothing for old clients
   827  		expectNothing(t, oldClient)
   828  
   829  		// Expect new client to receive an INFO (unless disabled)
   830  		// The content should be the server client is connected to and the last route
   831  		checkINFOReceived(newClient, newClientExpect, []string{"127.0.0.1:5242", "127.0.0.1:8888"})
   832  	}
   833  
   834  	opts := LoadConfig("./configs/cluster.conf")
   835  	// For this test, be explicit about listen spec.
   836  	opts.Host = "127.0.0.1"
   837  	opts.Port = 5242
   838  	opts.DisableShortFirstPing = true
   839  
   840  	f(opts)
   841  	opts.Cluster.NoAdvertise = true
   842  	f(opts)
   843  }
   844  
   845  func TestRouteBasicPermissions(t *testing.T) {
   846  	srvA, optsA := RunServerWithConfig("./configs/srv_a_perms.conf")
   847  	defer srvA.Shutdown()
   848  
   849  	srvB, optsB := RunServerWithConfig("./configs/srv_b.conf")
   850  	defer srvB.Shutdown()
   851  
   852  	checkClusterFormed(t, srvA, srvB)
   853  
   854  	// Create a connection to server B
   855  	ncb, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsB.Port))
   856  	if err != nil {
   857  		t.Fatalf("Error on connect: %v", err)
   858  	}
   859  	defer ncb.Close()
   860  	ch := make(chan bool, 1)
   861  	cb := func(_ *nats.Msg) {
   862  		ch <- true
   863  	}
   864  	// Subscribe on Server B on "bar" and "baz", which should be accepted by server A across the route
   865  	// Due to allowing "*"
   866  	subBbar, err := ncb.Subscribe("bar", cb)
   867  	if err != nil {
   868  		t.Fatalf("Error on subscribe: %v", err)
   869  	}
   870  	defer subBbar.Unsubscribe()
   871  	subBbaz, err := ncb.Subscribe("baz", cb)
   872  	if err != nil {
   873  		t.Fatalf("Error on subscribe: %v", err)
   874  	}
   875  	defer subBbaz.Unsubscribe()
   876  	ncb.Flush()
   877  	if err := checkExpectedSubs(2, srvA, srvB); err != nil {
   878  		t.Fatal(err.Error())
   879  	}
   880  
   881  	// Create a connection to server A
   882  	nca, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Port))
   883  	if err != nil {
   884  		t.Fatalf("Error on connect: %v", err)
   885  	}
   886  	defer nca.Close()
   887  	// Publish on bar and baz, messages should be received.
   888  	if err := nca.Publish("bar", []byte("hello")); err != nil {
   889  		t.Fatalf("Error on publish: %v", err)
   890  	}
   891  	if err := nca.Publish("baz", []byte("hello")); err != nil {
   892  		t.Fatalf("Error on publish: %v", err)
   893  	}
   894  	for i := 0; i < 2; i++ {
   895  		select {
   896  		case <-ch:
   897  		case <-time.After(time.Second):
   898  			t.Fatal("Did not get the messages")
   899  		}
   900  	}
   901  
   902  	// From B, start a subscription on "foo", which server A should drop since
   903  	// it only exports on "bar" and "baz"
   904  	subBfoo, err := ncb.Subscribe("foo", cb)
   905  	if err != nil {
   906  		t.Fatalf("Error on subscribe: %v", err)
   907  	}
   908  	defer subBfoo.Unsubscribe()
   909  	ncb.Flush()
   910  	// B should have now 3 subs
   911  	if err := checkExpectedSubs(3, srvB); err != nil {
   912  		t.Fatal(err.Error())
   913  	}
   914  	// and A still 2.
   915  	if err := checkExpectedSubs(2, srvA); err != nil {
   916  		t.Fatal(err.Error())
   917  	}
   918  	// So producing on "foo" from A should not be forwarded to B.
   919  	if err := nca.Publish("foo", []byte("hello")); err != nil {
   920  		t.Fatalf("Error on publish: %v", err)
   921  	}
   922  	select {
   923  	case <-ch:
   924  		t.Fatal("Message should not have been received")
   925  	case <-time.After(100 * time.Millisecond):
   926  	}
   927  
   928  	// Now on A, create a subscription on something that A does not import,
   929  	// like "bat".
   930  	subAbat, err := nca.Subscribe("bat", cb)
   931  	if err != nil {
   932  		t.Fatalf("Error on subscribe: %v", err)
   933  	}
   934  	defer subAbat.Unsubscribe()
   935  	nca.Flush()
   936  	// A should have 3 subs
   937  	if err := checkExpectedSubs(3, srvA); err != nil {
   938  		t.Fatal(err.Error())
   939  	}
   940  	// And from B, send a message on that subject and make sure it is not received.
   941  	if err := ncb.Publish("bat", []byte("hello")); err != nil {
   942  		t.Fatalf("Error on publish: %v", err)
   943  	}
   944  	select {
   945  	case <-ch:
   946  		t.Fatal("Message should not have been received")
   947  	case <-time.After(100 * time.Millisecond):
   948  	}
   949  
   950  	// Stop subscription on foo from B
   951  	subBfoo.Unsubscribe()
   952  	ncb.Flush()
   953  	// Back to 2 subs on B
   954  	if err := checkExpectedSubs(2, srvB); err != nil {
   955  		t.Fatal(err.Error())
   956  	}
   957  
   958  	// Create subscription on foo from A, this should be forwared to B.
   959  	subAfoo, err := nca.Subscribe("foo", cb)
   960  	if err != nil {
   961  		t.Fatalf("Error on subscribe: %v", err)
   962  	}
   963  	defer subAfoo.Unsubscribe()
   964  	// Create another one so that test the import permissions cache
   965  	subAfoo2, err := nca.Subscribe("foo", cb)
   966  	if err != nil {
   967  		t.Fatalf("Error on subscribe: %v", err)
   968  	}
   969  	defer subAfoo2.Unsubscribe()
   970  	nca.Flush()
   971  	// A should have 5 subs
   972  	if err := checkExpectedSubs(5, srvA); err != nil {
   973  		t.Fatal(err.Error())
   974  	}
   975  	// B should have 3 since we coalesce te two for 'foo'
   976  	if err := checkExpectedSubs(3, srvB); err != nil {
   977  		t.Fatal(err.Error())
   978  	}
   979  	// Send a message from B and check that it is received.
   980  	if err := ncb.Publish("foo", []byte("hello")); err != nil {
   981  		t.Fatalf("Error on publish: %v", err)
   982  	}
   983  	for i := 0; i < 2; i++ {
   984  		select {
   985  		case <-ch:
   986  		case <-time.After(time.Second):
   987  			t.Fatal("Did not get the message")
   988  		}
   989  	}
   990  
   991  	// Close connection from B, and restart server B too.
   992  	// We want to make sure that
   993  	ncb.Close()
   994  	srvB.Shutdown()
   995  
   996  	// Since B had 2 local subs, A should still only go from 4 to 3
   997  	if err := checkExpectedSubs(3, srvA); err != nil {
   998  		t.Fatal(err.Error())
   999  	}
  1000  
  1001  	// Restart server B
  1002  	srvB, optsB = RunServerWithConfig("./configs/srv_b.conf")
  1003  	defer srvB.Shutdown()
  1004  	// Check that subs from A that can be sent to B are sent.
  1005  	// That would be 2 (the 2 subscriptions on foo) as one.
  1006  	if err := checkExpectedSubs(1, srvB); err != nil {
  1007  		t.Fatal(err.Error())
  1008  	}
  1009  
  1010  	// Connect to B and send on "foo" and make sure we receive
  1011  	ncb, err = nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsB.Port))
  1012  	if err != nil {
  1013  		t.Fatalf("Error on connect: %v", err)
  1014  	}
  1015  	defer ncb.Close()
  1016  	if err := ncb.Publish("foo", []byte("hello")); err != nil {
  1017  		t.Fatalf("Error on publish: %v", err)
  1018  	}
  1019  	for i := 0; i < 2; i++ {
  1020  		select {
  1021  		case <-ch:
  1022  		case <-time.After(time.Second):
  1023  			t.Fatal("Did not get the message")
  1024  		}
  1025  	}
  1026  
  1027  	// Send on "bat" and make sure that this is not received.
  1028  	if err := ncb.Publish("bat", []byte("hello")); err != nil {
  1029  		t.Fatalf("Error on publish: %v", err)
  1030  	}
  1031  	select {
  1032  	case <-ch:
  1033  		t.Fatal("Message should not have been received")
  1034  	case <-time.After(100 * time.Millisecond):
  1035  	}
  1036  
  1037  	nca.Close()
  1038  	ncb.Close()
  1039  
  1040  	srvA.Shutdown()
  1041  	srvB.Shutdown()
  1042  
  1043  	optsA.Cluster.Permissions.Export = nil
  1044  	srvA = RunServer(optsA)
  1045  	defer srvA.Shutdown()
  1046  
  1047  	srvB = RunServer(optsB)
  1048  	defer srvB.Shutdown()
  1049  
  1050  	checkClusterFormed(t, srvA, srvB)
  1051  
  1052  	nca, err = nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsA.Port))
  1053  	if err != nil {
  1054  		t.Fatalf("Error on connect: %v", err)
  1055  	}
  1056  	defer nca.Close()
  1057  	// Subscribe on "bar" which is not imported
  1058  	if _, err := nca.Subscribe("bar", cb); err != nil {
  1059  		t.Fatalf("Error on subscribe: %v", err)
  1060  	}
  1061  	if err := checkExpectedSubs(1, srvA); err != nil {
  1062  		t.Fatal(err.Error())
  1063  	}
  1064  
  1065  	// Publish from B, should not be received
  1066  	ncb, err = nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", optsB.Port))
  1067  	if err != nil {
  1068  		t.Fatalf("Error on connect: %v", err)
  1069  	}
  1070  	defer ncb.Close()
  1071  	if err := ncb.Publish("bar", []byte("hello")); err != nil {
  1072  		t.Fatalf("Error on publish: %v", err)
  1073  	}
  1074  	select {
  1075  	case <-ch:
  1076  		t.Fatal("Message should not have been received")
  1077  	case <-time.After(100 * time.Millisecond):
  1078  		//ok
  1079  	}
  1080  	// Subscribe on "baz" on B
  1081  	if _, err := ncb.Subscribe("baz", cb); err != nil {
  1082  		t.Fatalf("Error on subscribe: %v", err)
  1083  	}
  1084  	if err := checkExpectedSubs(1, srvB); err != nil {
  1085  		t.Fatal(err.Error())
  1086  	}
  1087  	if err := checkExpectedSubs(2, srvA); err != nil {
  1088  		t.Fatal(err.Error())
  1089  	}
  1090  	// Publish from A, since there is no export restriction, message should be received.
  1091  	if err := nca.Publish("baz", []byte("hello")); err != nil {
  1092  		t.Fatalf("Error on publish: %v", err)
  1093  	}
  1094  	select {
  1095  	case <-ch:
  1096  	// ok
  1097  	case <-time.After(250 * time.Millisecond):
  1098  		t.Fatal("Message should have been received")
  1099  	}
  1100  }
  1101  
  1102  func createConfFile(t testing.TB, content []byte) string {
  1103  	t.Helper()
  1104  	conf := createTempFile(t, "")
  1105  	fName := conf.Name()
  1106  	conf.Close()
  1107  	if err := os.WriteFile(fName, content, 0666); err != nil {
  1108  		t.Fatalf("Error writing conf file: %v", err)
  1109  	}
  1110  	return fName
  1111  }
  1112  
  1113  func TestRoutesOnlyImportOrExport(t *testing.T) {
  1114  	contents := []string{
  1115  		`import: "foo"`,
  1116  		`import: {
  1117  			allow: "foo"
  1118  		}`,
  1119  		`import: {
  1120  			deny: "foo"
  1121  		}`,
  1122  		`import: {
  1123  			allow: "foo"
  1124  			deny: "foo"
  1125  		}`,
  1126  		`export: "foo"`,
  1127  		`export: {
  1128  			allow: "foo"
  1129  		}`,
  1130  		`export: {
  1131  			deny: "foo"
  1132  		}`,
  1133  		`export: {
  1134  			allow: "foo"
  1135  			deny: "foo"
  1136  		}`,
  1137  	}
  1138  	f := func(c string) {
  1139  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  1140  			port: -1
  1141  			cluster {
  1142  				name: "Z"
  1143  				port: -1
  1144  				authorization {
  1145  					user: ivan
  1146  					password: pwd
  1147  					permissions {
  1148  						%s
  1149  					}
  1150  				}
  1151  			}
  1152  		`, c)))
  1153  		s, _ := RunServerWithConfig(cf)
  1154  		s.Shutdown()
  1155  	}
  1156  	for _, c := range contents {
  1157  		f(c)
  1158  	}
  1159  }