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 }