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