get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/cluster_test.go (about) 1 // Copyright 2013-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 test 15 16 import ( 17 "errors" 18 "fmt" 19 "math/rand" 20 "runtime" 21 "strings" 22 "testing" 23 "time" 24 25 "get.pme.sh/pnats/server" 26 ) 27 28 // Helper function to check that a cluster is formed 29 func checkClusterFormed(t testing.TB, servers ...*server.Server) { 30 t.Helper() 31 expectedNumRoutes := len(servers) - 1 32 checkFor(t, 10*time.Second, 100*time.Millisecond, func() error { 33 for _, s := range servers { 34 if numRoutes := s.NumRoutes(); numRoutes != expectedNumRoutes { 35 return fmt.Errorf("Expected %d routes for server %q, got %d", expectedNumRoutes, s.ID(), numRoutes) 36 } 37 } 38 return nil 39 }) 40 } 41 42 func checkNumRoutes(t *testing.T, s *server.Server, expected int) { 43 t.Helper() 44 checkFor(t, 5*time.Second, 15*time.Millisecond, func() error { 45 if nr := s.NumRoutes(); nr != expected { 46 return fmt.Errorf("Expected %v routes, got %v", expected, nr) 47 } 48 return nil 49 }) 50 } 51 52 // Helper function to check that a server (or list of servers) have the 53 // expected number of subscriptions. 54 func checkExpectedSubs(expected int, servers ...*server.Server) error { 55 var err string 56 maxTime := time.Now().Add(10 * time.Second) 57 for time.Now().Before(maxTime) { 58 err = "" 59 for _, s := range servers { 60 if numSubs := int(s.NumSubscriptions()); numSubs != expected { 61 err = fmt.Sprintf("Expected %d subscriptions for server %q, got %d", expected, s.ID(), numSubs) 62 break 63 } 64 } 65 if err != "" { 66 time.Sleep(10 * time.Millisecond) 67 } else { 68 break 69 } 70 } 71 if err != "" { 72 return errors.New(err) 73 } 74 return nil 75 } 76 77 func checkSubInterest(t testing.TB, s *server.Server, accName, subject string, timeout time.Duration) { 78 t.Helper() 79 checkFor(t, timeout, 15*time.Millisecond, func() error { 80 acc, err := s.LookupAccount(accName) 81 if err != nil { 82 return fmt.Errorf("error looking up account %q: %v", accName, err) 83 } 84 if acc.SubscriptionInterest(subject) { 85 return nil 86 } 87 return fmt.Errorf("no subscription interest for account %q on %q", accName, subject) 88 }) 89 } 90 91 func checkNoSubInterest(t *testing.T, s *server.Server, accName, subject string, timeout time.Duration) { 92 t.Helper() 93 acc, err := s.LookupAccount(accName) 94 if err != nil { 95 t.Fatalf("error looking up account %q: %v", accName, err) 96 } 97 98 start := time.Now() 99 for time.Now().Before(start.Add(timeout)) { 100 if acc.SubscriptionInterest(subject) { 101 t.Fatalf("Did not expect interest for %q", subject) 102 } 103 time.Sleep(5 * time.Millisecond) 104 } 105 } 106 107 func runThreeServers(t *testing.T) (srvA, srvB, srvC *server.Server, optsA, optsB, optsC *server.Options) { 108 srvA, optsA = RunServerWithConfig("./configs/srv_a.conf") 109 srvB, optsB = RunServerWithConfig("./configs/srv_b.conf") 110 srvC, optsC = RunServerWithConfig("./configs/srv_c.conf") 111 112 checkClusterFormed(t, srvA, srvB, srvC) 113 return 114 } 115 116 func runServers(t *testing.T) (srvA, srvB *server.Server, optsA, optsB *server.Options) { 117 srvA, optsA = RunServerWithConfig("./configs/srv_a.conf") 118 srvB, optsB = RunServerWithConfig("./configs/srv_b.conf") 119 120 checkClusterFormed(t, srvA, srvB) 121 return 122 } 123 124 func TestProperServerWithRoutesShutdown(t *testing.T) { 125 before := runtime.NumGoroutine() 126 srvA, srvB, _, _ := runServers(t) 127 srvA.Shutdown() 128 srvB.Shutdown() 129 time.Sleep(100 * time.Millisecond) 130 131 after := runtime.NumGoroutine() 132 delta := after - before 133 // There may be some finalizers or IO, but in general more than 134 // 2 as a delta represents a problem. 135 if delta > 2 { 136 t.Fatalf("Expected same number of goroutines, %d vs %d\n", before, after) 137 } 138 } 139 140 func TestDoubleRouteConfig(t *testing.T) { 141 srvA, srvB, _, _ := runServers(t) 142 defer srvA.Shutdown() 143 defer srvB.Shutdown() 144 } 145 146 func TestBasicClusterPubSub(t *testing.T) { 147 srvA, srvB, optsA, optsB := runServers(t) 148 defer srvA.Shutdown() 149 defer srvB.Shutdown() 150 151 clientA := createClientConn(t, optsA.Host, optsA.Port) 152 defer clientA.Close() 153 154 clientB := createClientConn(t, optsB.Host, optsB.Port) 155 defer clientB.Close() 156 157 sendA, expectA := setupConn(t, clientA) 158 sendA("SUB foo 22\r\n") 159 sendA("PING\r\n") 160 expectA(pongRe) 161 162 if err := checkExpectedSubs(1, srvA, srvB); err != nil { 163 t.Fatalf("%v", err) 164 } 165 166 sendB, expectB := setupConn(t, clientB) 167 sendB("PUB foo 2\r\nok\r\n") 168 sendB("PING\r\n") 169 expectB(pongRe) 170 171 expectMsgs := expectMsgsCommand(t, expectA) 172 173 matches := expectMsgs(1) 174 checkMsg(t, matches[0], "foo", "22", "", "2", "ok") 175 } 176 177 func TestClusterQueueSubs(t *testing.T) { 178 srvA, srvB, optsA, optsB := runServers(t) 179 defer srvA.Shutdown() 180 defer srvB.Shutdown() 181 182 clientA := createClientConn(t, optsA.Host, optsA.Port) 183 defer clientA.Close() 184 185 clientB := createClientConn(t, optsB.Host, optsB.Port) 186 defer clientB.Close() 187 188 sendA, expectA := setupConn(t, clientA) 189 sendB, expectB := setupConn(t, clientB) 190 191 expectMsgsA := expectMsgsCommand(t, expectA) 192 expectMsgsB := expectMsgsCommand(t, expectB) 193 194 // Capture sids for checking later. 195 qg1SidsA := []string{"1", "2", "3"} 196 197 // Three queue subscribers 198 for _, sid := range qg1SidsA { 199 sendA(fmt.Sprintf("SUB foo qg1 %s\r\n", sid)) 200 } 201 sendA("PING\r\n") 202 expectA(pongRe) 203 204 // Make sure the subs have propagated to srvB before continuing 205 // New cluster proto this will only be 1. 206 if err := checkExpectedSubs(1, srvB); err != nil { 207 t.Fatalf("%v", err) 208 } 209 210 sendB("PUB foo 2\r\nok\r\n") 211 sendB("PING\r\n") 212 expectB(pongRe) 213 214 // Make sure we get only 1. 215 matches := expectMsgsA(1) 216 checkMsg(t, matches[0], "foo", "", "", "2", "ok") 217 218 // Capture sids for checking later. 219 pSids := []string{"4", "5", "6"} 220 221 // Create 3 normal subscribers 222 for _, sid := range pSids { 223 sendA(fmt.Sprintf("SUB foo %s\r\n", sid)) 224 } 225 226 // Create a FWC Subscriber 227 pSids = append(pSids, "7") 228 sendA("SUB > 7\r\n") 229 sendA("PING\r\n") 230 expectA(pongRe) 231 232 // Make sure the subs have propagated to srvB before continuing 233 // Normal foo and the queue group will be one a piece, so 2 + wc == 3 234 if err := checkExpectedSubs(3, srvB); err != nil { 235 t.Fatalf("%v", err) 236 } 237 238 // Send to B 239 sendB("PUB foo 2\r\nok\r\n") 240 sendB("PING\r\n") 241 expectB(pongRe) 242 243 // Give plenty of time for the messages to flush, so that we don't 244 // accidentally only read some of them. 245 time.Sleep(time.Millisecond * 250) 246 247 // Should receive 5. 248 matches = expectMsgsA(5) 249 checkForQueueSid(t, matches, qg1SidsA) 250 checkForPubSids(t, matches, pSids) 251 252 // Send to A 253 sendA("PUB foo 2\r\nok\r\n") 254 255 // Give plenty of time for the messages to flush, so that we don't 256 // accidentally only read some of them. 257 time.Sleep(time.Millisecond * 250) 258 259 // Should receive 5. 260 matches = expectMsgsA(5) 261 checkForQueueSid(t, matches, qg1SidsA) 262 checkForPubSids(t, matches, pSids) 263 264 // Now add queue subscribers to B 265 qg2SidsB := []string{"1", "2", "3"} 266 for _, sid := range qg2SidsB { 267 sendB(fmt.Sprintf("SUB foo qg2 %s\r\n", sid)) 268 } 269 sendB("PING\r\n") 270 expectB(pongRe) 271 272 // Make sure the subs have propagated to srvA before continuing 273 // This will be all the subs on A and just 1 from B that gets coalesced. 274 if err := checkExpectedSubs(len(qg1SidsA)+len(pSids)+1, srvA); err != nil { 275 t.Fatalf("%v", err) 276 } 277 278 // Send to B 279 sendB("PUB foo 2\r\nok\r\n") 280 281 // Give plenty of time for the messages to flush, so that we don't 282 // accidentally only read some of them. 283 time.Sleep(time.Millisecond * 250) 284 285 // Should receive 1 from B. 286 matches = expectMsgsB(1) 287 checkForQueueSid(t, matches, qg2SidsB) 288 289 // Should receive 5 still from A. 290 matches = expectMsgsA(5) 291 checkForQueueSid(t, matches, qg1SidsA) 292 checkForPubSids(t, matches, pSids) 293 294 // Now drop queue subscribers from A 295 for _, sid := range qg1SidsA { 296 sendA(fmt.Sprintf("UNSUB %s\r\n", sid)) 297 } 298 sendA("PING\r\n") 299 expectA(pongRe) 300 301 // Make sure the subs have propagated to srvB before continuing 302 if err := checkExpectedSubs(1+1+len(qg2SidsB), srvB); err != nil { 303 t.Fatalf("%v", err) 304 } 305 306 // Send to B 307 sendB("PUB foo 2\r\nok\r\n") 308 309 // Should receive 1 from B. 310 matches = expectMsgsB(1) 311 checkForQueueSid(t, matches, qg2SidsB) 312 313 sendB("PING\r\n") 314 expectB(pongRe) 315 316 // Should receive 4 now. 317 matches = expectMsgsA(4) 318 checkForPubSids(t, matches, pSids) 319 320 // Send to A 321 sendA("PUB foo 2\r\nok\r\n") 322 323 // Give plenty of time for the messages to flush, so that we don't 324 // accidentally only read some of them. 325 time.Sleep(time.Millisecond * 250) 326 327 // Should receive 4 now. 328 matches = expectMsgsA(4) 329 checkForPubSids(t, matches, pSids) 330 } 331 332 // Issue #22 333 func TestClusterDoubleMsgs(t *testing.T) { 334 srvA, srvB, optsA, optsB := runServers(t) 335 defer srvA.Shutdown() 336 defer srvB.Shutdown() 337 338 clientA1 := createClientConn(t, optsA.Host, optsA.Port) 339 defer clientA1.Close() 340 341 clientA2 := createClientConn(t, optsA.Host, optsA.Port) 342 defer clientA2.Close() 343 344 clientB := createClientConn(t, optsB.Host, optsB.Port) 345 defer clientB.Close() 346 347 sendA1, expectA1 := setupConn(t, clientA1) 348 sendA2, expectA2 := setupConn(t, clientA2) 349 sendB, expectB := setupConn(t, clientB) 350 351 expectMsgsA1 := expectMsgsCommand(t, expectA1) 352 expectMsgsA2 := expectMsgsCommand(t, expectA2) 353 354 // Capture sids for checking later. 355 qg1SidsA := []string{"1", "2", "3"} 356 357 // Three queue subscribers 358 for _, sid := range qg1SidsA { 359 sendA1(fmt.Sprintf("SUB foo qg1 %s\r\n", sid)) 360 } 361 sendA1("PING\r\n") 362 expectA1(pongRe) 363 364 // Make sure the subs have propagated to srvB before continuing 365 if err := checkExpectedSubs(1, srvB); err != nil { 366 t.Fatalf("%v", err) 367 } 368 369 sendB("PUB foo 2\r\nok\r\n") 370 sendB("PING\r\n") 371 expectB(pongRe) 372 373 // Make sure we get only 1. 374 matches := expectMsgsA1(1) 375 checkMsg(t, matches[0], "foo", "", "", "2", "ok") 376 checkForQueueSid(t, matches, qg1SidsA) 377 378 // Add a FWC subscriber on A2 379 sendA2("SUB > 1\r\n") 380 sendA2("SUB foo 2\r\n") 381 sendA2("PING\r\n") 382 expectA2(pongRe) 383 pSids := []string{"1", "2"} 384 385 // Make sure the subs have propagated to srvB before continuing 386 if err := checkExpectedSubs(1+2, srvB); err != nil { 387 t.Fatalf("%v", err) 388 } 389 390 sendB("PUB foo 2\r\nok\r\n") 391 sendB("PING\r\n") 392 expectB(pongRe) 393 394 matches = expectMsgsA1(1) 395 checkMsg(t, matches[0], "foo", "", "", "2", "ok") 396 checkForQueueSid(t, matches, qg1SidsA) 397 398 matches = expectMsgsA2(2) 399 checkMsg(t, matches[0], "foo", "", "", "2", "ok") 400 checkForPubSids(t, matches, pSids) 401 402 // Close ClientA1 403 clientA1.Close() 404 405 sendB("PUB foo 2\r\nok\r\n") 406 sendB("PING\r\n") 407 expectB(pongRe) 408 409 time.Sleep(10 * time.Millisecond) 410 411 matches = expectMsgsA2(2) 412 checkMsg(t, matches[0], "foo", "", "", "2", "ok") 413 checkForPubSids(t, matches, pSids) 414 } 415 416 // This will test that we drop remote sids correctly. 417 func TestClusterDropsRemoteSids(t *testing.T) { 418 srvA, srvB, optsA, _ := runServers(t) 419 defer srvA.Shutdown() 420 defer srvB.Shutdown() 421 422 clientA := createClientConn(t, optsA.Host, optsA.Port) 423 defer clientA.Close() 424 425 sendA, expectA := setupConn(t, clientA) 426 427 // Add a subscription 428 sendA("SUB foo 1\r\n") 429 sendA("PING\r\n") 430 expectA(pongRe) 431 432 // Wait for propagation. 433 time.Sleep(100 * time.Millisecond) 434 435 if sc := srvA.NumSubscriptions(); sc != 1 { 436 t.Fatalf("Expected one subscription for srvA, got %d\n", sc) 437 } 438 if sc := srvB.NumSubscriptions(); sc != 1 { 439 t.Fatalf("Expected one subscription for srvB, got %d\n", sc) 440 } 441 442 // Add another subscription 443 sendA("SUB bar 2\r\n") 444 sendA("PING\r\n") 445 expectA(pongRe) 446 447 // Wait for propagation. 448 time.Sleep(100 * time.Millisecond) 449 450 if sc := srvA.NumSubscriptions(); sc != 2 { 451 t.Fatalf("Expected two subscriptions for srvA, got %d\n", sc) 452 } 453 if sc := srvB.NumSubscriptions(); sc != 2 { 454 t.Fatalf("Expected two subscriptions for srvB, got %d\n", sc) 455 } 456 457 // unsubscription 458 sendA("UNSUB 1\r\n") 459 sendA("PING\r\n") 460 expectA(pongRe) 461 462 // Wait for propagation. 463 time.Sleep(100 * time.Millisecond) 464 465 if sc := srvA.NumSubscriptions(); sc != 1 { 466 t.Fatalf("Expected one subscription for srvA, got %d\n", sc) 467 } 468 if sc := srvB.NumSubscriptions(); sc != 1 { 469 t.Fatalf("Expected one subscription for srvB, got %d\n", sc) 470 } 471 472 // Close the client and make sure we remove subscription state. 473 clientA.Close() 474 475 // Wait for propagation. 476 time.Sleep(100 * time.Millisecond) 477 if sc := srvA.NumSubscriptions(); sc != 0 { 478 t.Fatalf("Expected no subscriptions for srvA, got %d\n", sc) 479 } 480 if sc := srvB.NumSubscriptions(); sc != 0 { 481 t.Fatalf("Expected no subscriptions for srvB, got %d\n", sc) 482 } 483 } 484 485 // This will test that we drop remote sids correctly. 486 func TestAutoUnsubscribePropagation(t *testing.T) { 487 srvA, srvB, optsA, _ := runServers(t) 488 defer srvA.Shutdown() 489 defer srvB.Shutdown() 490 491 clientA := createClientConn(t, optsA.Host, optsA.Port) 492 defer clientA.Close() 493 494 sendA, expectA := setupConn(t, clientA) 495 expectMsgs := expectMsgsCommand(t, expectA) 496 497 // We will create subscriptions that will auto-unsubscribe and make sure 498 // we are not accumulating orphan subscriptions on the other side. 499 for i := 1; i <= 100; i++ { 500 sub := fmt.Sprintf("SUB foo %d\r\n", i) 501 auto := fmt.Sprintf("UNSUB %d 1\r\n", i) 502 sendA(sub) 503 sendA(auto) 504 // This will trip the auto-unsubscribe 505 sendA("PUB foo 2\r\nok\r\n") 506 expectMsgs(1) 507 } 508 509 sendA("PING\r\n") 510 expectA(pongRe) 511 512 time.Sleep(50 * time.Millisecond) 513 514 // Make sure number of subscriptions on B is correct 515 if subs := srvB.NumSubscriptions(); subs != 0 { 516 t.Fatalf("Expected no subscriptions on remote server, got %d\n", subs) 517 } 518 } 519 520 func TestAutoUnsubscribePropagationOnClientDisconnect(t *testing.T) { 521 srvA, srvB, optsA, _ := runServers(t) 522 defer srvA.Shutdown() 523 defer srvB.Shutdown() 524 525 cluster := []*server.Server{srvA, srvB} 526 527 clientA := createClientConn(t, optsA.Host, optsA.Port) 528 defer clientA.Close() 529 530 sendA, expectA := setupConn(t, clientA) 531 532 // No subscriptions. Ready to test. 533 if err := checkExpectedSubs(0, cluster...); err != nil { 534 t.Fatalf("%v", err) 535 } 536 537 sendA("SUB foo 1\r\n") 538 sendA("UNSUB 1 1\r\n") 539 sendA("PING\r\n") 540 expectA(pongRe) 541 542 // Waiting cluster subs propagation 543 if err := checkExpectedSubs(1, cluster...); err != nil { 544 t.Fatalf("%v", err) 545 } 546 547 clientA.Close() 548 549 // No subs should be on the cluster when all clients is disconnected 550 if err := checkExpectedSubs(0, cluster...); err != nil { 551 t.Fatalf("%v", err) 552 } 553 } 554 555 func TestClusterNameOption(t *testing.T) { 556 conf := createConfFile(t, []byte(` 557 listen: 127.0.0.1:-1 558 cluster { 559 name: MyCluster 560 listen: 127.0.0.1:-1 561 } 562 `)) 563 564 s, opts := RunServerWithConfig(conf) 565 defer s.Shutdown() 566 567 c := createClientConn(t, opts.Host, opts.Port) 568 defer c.Close() 569 570 si := checkInfoMsg(t, c) 571 if si.Cluster != "MyCluster" { 572 t.Fatalf("Expected a cluster name of %q, got %q", "MyCluster", si.Cluster) 573 } 574 } 575 576 func TestEphemeralClusterName(t *testing.T) { 577 conf := createConfFile(t, []byte(` 578 listen: 127.0.0.1:-1 579 cluster { 580 listen: 127.0.0.1:-1 581 } 582 `)) 583 584 s, opts := RunServerWithConfig(conf) 585 defer s.Shutdown() 586 587 c := createClientConn(t, opts.Host, opts.Port) 588 defer c.Close() 589 590 si := checkInfoMsg(t, c) 591 if si.Cluster == "" { 592 t.Fatalf("Expected an ephemeral cluster name to be set") 593 } 594 } 595 596 type captureErrLogger struct { 597 dummyLogger 598 ch chan string 599 } 600 601 func (c *captureErrLogger) Errorf(format string, v ...interface{}) { 602 msg := fmt.Sprintf(format, v...) 603 select { 604 case c.ch <- msg: 605 default: 606 } 607 } 608 609 func TestClusterNameConflictsDropRoutes(t *testing.T) { 610 ll := &captureErrLogger{ch: make(chan string, 4)} 611 612 conf := createConfFile(t, []byte(` 613 listen: 127.0.0.1:-1 614 cluster { 615 name: MyCluster33 616 listen: 127.0.0.1:5244 617 } 618 `)) 619 620 s1, _ := RunServerWithConfig(conf) 621 defer s1.Shutdown() 622 s1.SetLogger(ll, false, false) 623 624 conf2 := createConfFile(t, []byte(` 625 listen: 127.0.0.1:-1 626 cluster { 627 name: MyCluster22 628 listen: 127.0.0.1:-1 629 routes = [nats-route://127.0.0.1:5244] 630 } 631 `)) 632 633 s2, _ := RunServerWithConfig(conf2) 634 defer s2.Shutdown() 635 s2.SetLogger(ll, false, false) 636 637 select { 638 case msg := <-ll.ch: 639 if !strings.Contains(msg, "Rejecting connection") || !strings.Contains(msg, "does not match") { 640 t.Fatalf("Got bad error about cluster name mismatch") 641 } 642 case <-time.After(time.Second): 643 t.Fatalf("Expected an error, timed out") 644 } 645 } 646 647 func TestClusterNameDynamicNegotiation(t *testing.T) { 648 conf := createConfFile(t, []byte(` 649 listen: 127.0.0.1:-1 650 cluster {listen: 127.0.0.1:5244} 651 `)) 652 653 seed, _ := RunServerWithConfig(conf) 654 defer seed.Shutdown() 655 656 oconf := createConfFile(t, []byte(` 657 listen: 127.0.0.1:-1 658 cluster { 659 listen: 127.0.0.1:-1 660 routes = [nats-route://127.0.0.1:5244] 661 } 662 `)) 663 664 // Create a random number of additional servers, up to 20. 665 numServers := rand.Intn(20) + 1 666 servers := make([]*server.Server, 0, numServers+1) 667 servers = append(servers, seed) 668 669 for i := 0; i < numServers; i++ { 670 s, _ := RunServerWithConfig(oconf) 671 defer s.Shutdown() 672 servers = append(servers, s) 673 } 674 675 // If this passes we should have all the same name. 676 checkClusterFormed(t, servers...) 677 678 clusterName := seed.ClusterName() 679 for _, s := range servers { 680 if s.ClusterName() != clusterName { 681 t.Fatalf("Expected the cluster names to all be the same as %q, got %q", clusterName, s.ClusterName()) 682 } 683 } 684 }