github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/jetstream_test.go (about) 1 // Copyright 2019-2024 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 //go:build !skip_js_tests 15 // +build !skip_js_tests 16 17 package server 18 19 import ( 20 "bytes" 21 "context" 22 crand "crypto/rand" 23 "encoding/base64" 24 "encoding/json" 25 "errors" 26 "fmt" 27 "io" 28 "math" 29 "math/rand" 30 "net/http" 31 "net/url" 32 "os" 33 "path/filepath" 34 "reflect" 35 "runtime" 36 "runtime/debug" 37 "sort" 38 "strconv" 39 "strings" 40 "sync" 41 "sync/atomic" 42 "testing" 43 "time" 44 45 "github.com/nats-io/jwt/v2" 46 "github.com/nats-io/nats-server/v2/server/sysmem" 47 "github.com/nats-io/nats.go" 48 "github.com/nats-io/nkeys" 49 "github.com/nats-io/nuid" 50 ) 51 52 func TestJetStreamBasicNilConfig(t *testing.T) { 53 s := RunRandClientPortServer(t) 54 defer s.Shutdown() 55 56 if err := s.EnableJetStream(nil); err != nil { 57 t.Fatalf("Expected no error, got %v", err) 58 } 59 if !s.JetStreamEnabled() { 60 t.Fatalf("Expected JetStream to be enabled") 61 } 62 if s.SystemAccount() == nil { 63 t.Fatalf("Expected system account to be created automatically") 64 } 65 // Grab our config since it was dynamically generated. 66 config := s.JetStreamConfig() 67 if config == nil { 68 t.Fatalf("Expected non-nil config") 69 } 70 // Check dynamic max memory. 71 hwMem := sysmem.Memory() 72 if hwMem != 0 { 73 // Check if memory being limited via GOMEMLIMIT if being set. 74 if gml := debug.SetMemoryLimit(-1); gml != math.MaxInt64 { 75 hwMem = gml 76 } 77 // Make sure its about 75% 78 est := hwMem / 4 * 3 79 if config.MaxMemory != est { 80 t.Fatalf("Expected memory to be 80 percent of system memory, got %v vs %v", config.MaxMemory, est) 81 } 82 } 83 // Make sure it was created. 84 stat, err := os.Stat(config.StoreDir) 85 if err != nil { 86 t.Fatalf("Expected the store directory to be present, %v", err) 87 } 88 if stat == nil || !stat.IsDir() { 89 t.Fatalf("Expected a directory") 90 } 91 } 92 93 func RunBasicJetStreamServer(t testing.TB) *Server { 94 opts := DefaultTestOptions 95 opts.Port = -1 96 opts.JetStream = true 97 opts.StoreDir = t.TempDir() 98 return RunServer(&opts) 99 } 100 101 func RunJetStreamServerOnPort(port int, sd string) *Server { 102 opts := DefaultTestOptions 103 opts.Port = port 104 opts.JetStream = true 105 opts.StoreDir = filepath.Dir(sd) 106 return RunServer(&opts) 107 } 108 109 func clientConnectToServer(t *testing.T, s *Server) *nats.Conn { 110 t.Helper() 111 nc, err := nats.Connect(s.ClientURL(), 112 nats.Name("JS-TEST"), 113 nats.ReconnectWait(5*time.Millisecond), 114 nats.MaxReconnects(-1)) 115 if err != nil { 116 t.Fatalf("Failed to create client: %v", err) 117 } 118 return nc 119 } 120 121 func clientConnectWithOldRequest(t *testing.T, s *Server) *nats.Conn { 122 nc, err := nats.Connect(s.ClientURL(), nats.UseOldRequestStyle()) 123 if err != nil { 124 t.Fatalf("Failed to create client: %v", err) 125 } 126 return nc 127 } 128 129 func TestJetStreamEnableAndDisableAccount(t *testing.T) { 130 s := RunBasicJetStreamServer(t) 131 defer s.Shutdown() 132 133 // Global in simple setup should be enabled already. 134 if !s.GlobalAccount().JetStreamEnabled() { 135 t.Fatalf("Expected to have jetstream enabled on global account") 136 } 137 if na := s.JetStreamNumAccounts(); na != 1 { 138 t.Fatalf("Expected 1 account, got %d", na) 139 } 140 141 if err := s.GlobalAccount().DisableJetStream(); err != nil { 142 t.Fatalf("Did not expect error on disabling account: %v", err) 143 } 144 if na := s.JetStreamNumAccounts(); na != 0 { 145 t.Fatalf("Expected no accounts, got %d", na) 146 } 147 // Make sure we unreserved resources. 148 if rm, rd, err := s.JetStreamReservedResources(); err != nil { 149 t.Fatalf("Unexpected error requesting jetstream reserved resources: %v", err) 150 } else if rm != 0 || rd != 0 { 151 t.Fatalf("Expected reserved memory and store to be 0, got %v and %v", friendlyBytes(rm), friendlyBytes(rd)) 152 } 153 154 acc, _ := s.LookupOrRegisterAccount("$FOO") 155 if err := acc.EnableJetStream(nil); err != nil { 156 t.Fatalf("Did not expect error on enabling account: %v", err) 157 } 158 if na := s.JetStreamNumAccounts(); na != 1 { 159 t.Fatalf("Expected 1 account, got %d", na) 160 } 161 if err := acc.DisableJetStream(); err != nil { 162 t.Fatalf("Did not expect error on disabling account: %v", err) 163 } 164 if na := s.JetStreamNumAccounts(); na != 0 { 165 t.Fatalf("Expected no accounts, got %d", na) 166 } 167 // We should get error if disabling something not enabled. 168 acc, _ = s.LookupOrRegisterAccount("$BAR") 169 if err := acc.DisableJetStream(); err == nil { 170 t.Fatalf("Expected error on disabling account that was not enabled") 171 } 172 // Should get an error for trying to enable a non-registered account. 173 acc = NewAccount("$BAZ") 174 if err := acc.EnableJetStream(nil); err == nil { 175 t.Fatalf("Expected error on enabling account that was not registered") 176 } 177 } 178 179 func TestJetStreamAddStream(t *testing.T) { 180 cases := []struct { 181 name string 182 mconfig *StreamConfig 183 }{ 184 {name: "MemoryStore", 185 mconfig: &StreamConfig{ 186 Name: "foo", 187 Retention: LimitsPolicy, 188 MaxAge: time.Hour, 189 Storage: MemoryStorage, 190 Replicas: 1, 191 }}, 192 {name: "FileStore", 193 mconfig: &StreamConfig{ 194 Name: "foo", 195 Retention: LimitsPolicy, 196 MaxAge: time.Hour, 197 Storage: FileStorage, 198 Replicas: 1, 199 }}, 200 } 201 for _, c := range cases { 202 t.Run(c.name, func(t *testing.T) { 203 s := RunBasicJetStreamServer(t) 204 defer s.Shutdown() 205 206 mset, err := s.GlobalAccount().addStream(c.mconfig) 207 if err != nil { 208 t.Fatalf("Unexpected error adding stream: %v", err) 209 } 210 defer mset.delete() 211 212 nc, js := jsClientConnect(t, s) 213 defer nc.Close() 214 215 js.Publish("foo", []byte("Hello World!")) 216 state := mset.state() 217 if state.Msgs != 1 { 218 t.Fatalf("Expected 1 message, got %d", state.Msgs) 219 } 220 if state.Bytes == 0 { 221 t.Fatalf("Expected non-zero bytes") 222 } 223 224 js.Publish("foo", []byte("Hello World Again!")) 225 state = mset.state() 226 if state.Msgs != 2 { 227 t.Fatalf("Expected 2 messages, got %d", state.Msgs) 228 } 229 230 if err := mset.delete(); err != nil { 231 t.Fatalf("Got an error deleting the stream: %v", err) 232 } 233 }) 234 } 235 } 236 237 func TestJetStreamAddStreamDiscardNew(t *testing.T) { 238 cases := []struct { 239 name string 240 mconfig *StreamConfig 241 }{ 242 {name: "MemoryStore", 243 mconfig: &StreamConfig{ 244 Name: "foo", 245 MaxMsgs: 10, 246 MaxBytes: 4096, 247 Discard: DiscardNew, 248 Storage: MemoryStorage, 249 Replicas: 1, 250 }}, 251 {name: "FileStore", 252 mconfig: &StreamConfig{ 253 Name: "foo", 254 MaxMsgs: 10, 255 MaxBytes: 4096, 256 Discard: DiscardNew, 257 Storage: FileStorage, 258 Replicas: 1, 259 }}, 260 } 261 for _, c := range cases { 262 t.Run(c.name, func(t *testing.T) { 263 s := RunBasicJetStreamServer(t) 264 defer s.Shutdown() 265 266 mset, err := s.GlobalAccount().addStream(c.mconfig) 267 if err != nil { 268 t.Fatalf("Unexpected error adding stream: %v", err) 269 } 270 defer mset.delete() 271 272 nc := clientConnectToServer(t, s) 273 defer nc.Close() 274 275 subj := "foo" 276 toSend := 10 277 for i := 0; i < toSend; i++ { 278 sendStreamMsg(t, nc, subj, fmt.Sprintf("MSG: %d", i+1)) 279 } 280 // We expect this one to fail due to discard policy. 281 resp, _ := nc.Request(subj, []byte("discard me"), 100*time.Millisecond) 282 if resp == nil { 283 t.Fatalf("No response, possible timeout?") 284 } 285 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error.Description != "maximum messages exceeded" || pa.Stream != "foo" { 286 t.Fatalf("Expected to get an error about maximum messages, got %q", resp.Data) 287 } 288 289 // Now do bytes. 290 mset.purge(nil) 291 292 big := make([]byte, 8192) 293 resp, _ = nc.Request(subj, big, 100*time.Millisecond) 294 if resp == nil { 295 t.Fatalf("No response, possible timeout?") 296 } 297 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error.Description != "maximum bytes exceeded" || pa.Stream != "foo" { 298 t.Fatalf("Expected to get an error about maximum bytes, got %q", resp.Data) 299 } 300 }) 301 } 302 } 303 304 func TestJetStreamAutoTuneFSConfig(t *testing.T) { 305 s := RunRandClientPortServer(t) 306 defer s.Shutdown() 307 308 jsconfig := &JetStreamConfig{MaxMemory: -1, MaxStore: 128 * 1024 * 1024, StoreDir: t.TempDir()} 309 if err := s.EnableJetStream(jsconfig); err != nil { 310 t.Fatalf("Expected no error, got %v", err) 311 } 312 313 maxMsgSize := int32(512) 314 streamConfig := func(name string, maxMsgs, maxBytes int64) *StreamConfig { 315 t.Helper() 316 cfg := &StreamConfig{Name: name, MaxMsgSize: maxMsgSize, Storage: FileStorage} 317 if maxMsgs > 0 { 318 cfg.MaxMsgs = maxMsgs 319 } 320 if maxBytes > 0 { 321 cfg.MaxBytes = maxBytes 322 } 323 return cfg 324 } 325 326 acc := s.GlobalAccount() 327 328 testBlkSize := func(subject string, maxMsgs, maxBytes int64, expectedBlkSize uint64) { 329 t.Helper() 330 mset, err := acc.addStream(streamConfig(subject, maxMsgs, maxBytes)) 331 if err != nil { 332 t.Fatalf("Unexpected error adding stream: %v", err) 333 } 334 defer mset.delete() 335 fsCfg, err := mset.fileStoreConfig() 336 if err != nil { 337 t.Fatalf("Unexpected error retrieving file store: %v", err) 338 } 339 if fsCfg.BlockSize != expectedBlkSize { 340 t.Fatalf("Expected auto tuned block size to be %d, got %d", expectedBlkSize, fsCfg.BlockSize) 341 } 342 } 343 344 testBlkSize("foo", 1, 0, FileStoreMinBlkSize) 345 testBlkSize("foo", 1, 512, FileStoreMinBlkSize) 346 testBlkSize("foo", 1, 1024*1024, defaultMediumBlockSize) 347 testBlkSize("foo", 1, 8*1024*1024, defaultMediumBlockSize) 348 testBlkSize("foo_bar_baz", -1, 32*1024*1024, FileStoreMaxBlkSize) 349 } 350 351 func TestJetStreamConsumerAndStreamDescriptions(t *testing.T) { 352 s := RunBasicJetStreamServer(t) 353 defer s.Shutdown() 354 355 descr := "foo asset" 356 acc := s.GlobalAccount() 357 358 // Check stream's first. 359 mset, err := acc.addStream(&StreamConfig{Name: "foo", Description: descr}) 360 if err != nil { 361 t.Fatalf("Unexpected error adding stream: %v", err) 362 } 363 if cfg := mset.config(); cfg.Description != descr { 364 t.Fatalf("Expected a description of %q, got %q", descr, cfg.Description) 365 } 366 367 // Now consumer 368 edescr := "analytics" 369 o, err := mset.addConsumer(&ConsumerConfig{ 370 Description: edescr, 371 DeliverSubject: "to", 372 AckPolicy: AckNone}) 373 if err != nil { 374 t.Fatalf("Unexpected error adding consumer: %v", err) 375 } 376 if cfg := o.config(); cfg.Description != edescr { 377 t.Fatalf("Expected a description of %q, got %q", edescr, cfg.Description) 378 } 379 380 // Test max. 381 data := make([]byte, JSMaxDescriptionLen+1) 382 crand.Read(data) 383 bigDescr := base64.StdEncoding.EncodeToString(data) 384 385 _, err = acc.addStream(&StreamConfig{Name: "bar", Description: bigDescr}) 386 if err == nil || !strings.Contains(err.Error(), "description is too long") { 387 t.Fatalf("Expected an error but got none") 388 } 389 390 _, err = mset.addConsumer(&ConsumerConfig{ 391 Description: bigDescr, 392 DeliverSubject: "to", 393 AckPolicy: AckNone}) 394 if err == nil || !strings.Contains(err.Error(), "description is too long") { 395 t.Fatalf("Expected an error but got none") 396 } 397 } 398 func TestJetStreamConsumerWithNameAndDurable(t *testing.T) { 399 s := RunBasicJetStreamServer(t) 400 defer s.Shutdown() 401 402 descr := "foo asset" 403 name := "name" 404 durable := "durable" 405 acc := s.GlobalAccount() 406 407 // Check stream's first. 408 mset, err := acc.addStream(&StreamConfig{Name: "foo", Description: descr}) 409 if err != nil { 410 t.Fatalf("Unexpected error adding stream: %v", err) 411 } 412 if cfg := mset.config(); cfg.Description != descr { 413 t.Fatalf("Expected a description of %q, got %q", descr, cfg.Description) 414 } 415 416 // it's ok to specify both durable and name, but they have to be the same. 417 _, err = mset.addConsumer(&ConsumerConfig{ 418 DeliverSubject: "to", 419 Durable: "consumer", 420 Name: "consumer", 421 AckPolicy: AckNone}) 422 if err != nil { 423 t.Fatalf("Unexpected error adding consumer: %v", err) 424 } 425 426 // if they're not the same, expect error 427 _, err = mset.addConsumer(&ConsumerConfig{ 428 DeliverSubject: "to", 429 Durable: durable, 430 Name: name, 431 AckPolicy: AckNone}) 432 433 if !strings.Contains(err.Error(), "Consumer Durable and Name have to be equal") { 434 t.Fatalf("Wrong error while adding consumer with not matching Name and Durable: %v", err) 435 } 436 437 } 438 439 func TestJetStreamPubAck(t *testing.T) { 440 s := RunBasicJetStreamServer(t) 441 defer s.Shutdown() 442 443 sname := "PUBACK" 444 acc := s.GlobalAccount() 445 mconfig := &StreamConfig{Name: sname, Subjects: []string{"foo"}, Storage: MemoryStorage} 446 mset, err := acc.addStream(mconfig) 447 if err != nil { 448 t.Fatalf("Unexpected error adding stream: %v", err) 449 } 450 defer mset.delete() 451 452 nc := clientConnectToServer(t, s) 453 defer nc.Close() 454 455 checkRespDetails := func(resp *nats.Msg, err error, seq uint64) { 456 if err != nil { 457 t.Fatalf("Unexpected error from send stream msg: %v", err) 458 } 459 if resp == nil { 460 t.Fatalf("No response from send stream msg") 461 } 462 pa := getPubAckResponse(resp.Data) 463 if pa == nil || pa.Error != nil { 464 t.Fatalf("Expected a valid JetStreamPubAck, got %q", resp.Data) 465 } 466 if pa.Stream != sname { 467 t.Fatalf("Expected %q for stream name, got %q", sname, pa.Stream) 468 } 469 if pa.Sequence != seq { 470 t.Fatalf("Expected %d for sequence, got %d", seq, pa.Sequence) 471 } 472 } 473 474 // Send messages and make sure pubAck details are correct. 475 for i := uint64(1); i <= 1000; i++ { 476 resp, err := nc.Request("foo", []byte("HELLO"), 100*time.Millisecond) 477 checkRespDetails(resp, err, i) 478 } 479 } 480 481 func TestJetStreamConsumerWithStartTime(t *testing.T) { 482 subj := "my_stream" 483 cases := []struct { 484 name string 485 mconfig *StreamConfig 486 }{ 487 {"MemoryStore", &StreamConfig{Name: subj, Storage: MemoryStorage}}, 488 {"FileStore", &StreamConfig{Name: subj, Storage: FileStorage}}, 489 } 490 for _, c := range cases { 491 t.Run(c.name, func(t *testing.T) { 492 s := RunBasicJetStreamServer(t) 493 defer s.Shutdown() 494 495 fsCfg := &FileStoreConfig{BlockSize: 100} 496 mset, err := s.GlobalAccount().addStreamWithStore(c.mconfig, fsCfg) 497 if err != nil { 498 t.Fatalf("Unexpected error adding stream: %v", err) 499 } 500 defer mset.delete() 501 502 nc := clientConnectToServer(t, s) 503 defer nc.Close() 504 505 toSend := 250 506 for i := 0; i < toSend; i++ { 507 sendStreamMsg(t, nc, subj, fmt.Sprintf("MSG: %d", i+1)) 508 } 509 510 time.Sleep(10 * time.Millisecond) 511 startTime := time.Now().UTC() 512 513 for i := 0; i < toSend; i++ { 514 sendStreamMsg(t, nc, subj, fmt.Sprintf("MSG: %d", i+1)) 515 } 516 517 if msgs := mset.state().Msgs; msgs != uint64(toSend*2) { 518 t.Fatalf("Expected %d messages, got %d", toSend*2, msgs) 519 } 520 521 o, err := mset.addConsumer(&ConsumerConfig{ 522 Durable: "d", 523 DeliverPolicy: DeliverByStartTime, 524 OptStartTime: &startTime, 525 AckPolicy: AckExplicit, 526 }) 527 require_NoError(t, err) 528 defer o.delete() 529 530 msg, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 531 require_NoError(t, err) 532 sseq, dseq, _, _, _ := replyInfo(msg.Reply) 533 if dseq != 1 { 534 t.Fatalf("Expected delivered seq of 1, got %d", dseq) 535 } 536 if sseq != uint64(toSend+1) { 537 t.Fatalf("Expected to get store seq of %d, got %d", toSend+1, sseq) 538 } 539 }) 540 } 541 } 542 543 // Test for https://github.com/nats-io/jetstream/issues/143 544 func TestJetStreamConsumerWithMultipleStartOptions(t *testing.T) { 545 subj := "my_stream" 546 cases := []struct { 547 name string 548 mconfig *StreamConfig 549 }{ 550 {"MemoryStore", &StreamConfig{Name: subj, Subjects: []string{"foo.>"}, Storage: MemoryStorage}}, 551 {"FileStore", &StreamConfig{Name: subj, Subjects: []string{"foo.>"}, Storage: FileStorage}}, 552 } 553 for _, c := range cases { 554 t.Run(c.name, func(t *testing.T) { 555 s := RunBasicJetStreamServer(t) 556 defer s.Shutdown() 557 558 mset, err := s.GlobalAccount().addStream(c.mconfig) 559 if err != nil { 560 t.Fatalf("Unexpected error adding stream: %v", err) 561 } 562 defer mset.delete() 563 564 nc := clientConnectToServer(t, s) 565 defer nc.Close() 566 567 obsReq := CreateConsumerRequest{ 568 Stream: subj, 569 Config: ConsumerConfig{ 570 Durable: "d", 571 DeliverPolicy: DeliverLast, 572 FilterSubject: "foo.22", 573 AckPolicy: AckExplicit, 574 }, 575 } 576 req, err := json.Marshal(obsReq) 577 require_NoError(t, err) 578 _, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, subj), req, time.Second) 579 require_NoError(t, err) 580 nc.Close() 581 s.Shutdown() 582 }) 583 } 584 } 585 586 func TestJetStreamConsumerMaxDeliveries(t *testing.T) { 587 cases := []struct { 588 name string 589 mconfig *StreamConfig 590 }{ 591 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage}}, 592 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage}}, 593 } 594 for _, c := range cases { 595 t.Run(c.name, func(t *testing.T) { 596 s := RunBasicJetStreamServer(t) 597 defer s.Shutdown() 598 599 mset, err := s.GlobalAccount().addStream(c.mconfig) 600 if err != nil { 601 t.Fatalf("Unexpected error adding stream: %v", err) 602 } 603 defer mset.delete() 604 605 nc := clientConnectToServer(t, s) 606 defer nc.Close() 607 608 // Queue up our work item. 609 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 610 611 sub, _ := nc.SubscribeSync(nats.NewInbox()) 612 defer sub.Unsubscribe() 613 nc.Flush() 614 615 maxDeliver := 5 616 ackWait := 10 * time.Millisecond 617 618 o, err := mset.addConsumer(&ConsumerConfig{ 619 DeliverSubject: sub.Subject, 620 AckPolicy: AckExplicit, 621 AckWait: ackWait, 622 MaxDeliver: maxDeliver, 623 }) 624 require_NoError(t, err) 625 defer o.delete() 626 627 // Wait for redeliveries to pile up. 628 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 629 if nmsgs, _, err := sub.Pending(); err != nil || nmsgs != maxDeliver { 630 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, maxDeliver) 631 } 632 return nil 633 }) 634 635 // Now wait a bit longer and make sure we do not have more than maxDeliveries. 636 time.Sleep(2 * ackWait) 637 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != maxDeliver { 638 t.Fatalf("Did not receive correct number of messages: %d vs %d", nmsgs, maxDeliver) 639 } 640 }) 641 } 642 } 643 644 func TestJetStreamNextReqFromMsg(t *testing.T) { 645 bef := time.Now() 646 expires, _, _, _, _, _, err := nextReqFromMsg([]byte(`{"expires":5000000000}`)) // nanoseconds 647 require_NoError(t, err) 648 now := time.Now() 649 if expires.Before(bef.Add(5*time.Second)) || expires.After(now.Add(5*time.Second)) { 650 t.Fatal("Expires out of expected range") 651 } 652 } 653 654 func TestJetStreamPullConsumerDelayedFirstPullWithReplayOriginal(t *testing.T) { 655 cases := []struct { 656 name string 657 mconfig *StreamConfig 658 }{ 659 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage}}, 660 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage}}, 661 } 662 for _, c := range cases { 663 t.Run(c.name, func(t *testing.T) { 664 s := RunBasicJetStreamServer(t) 665 defer s.Shutdown() 666 667 mset, err := s.GlobalAccount().addStream(c.mconfig) 668 if err != nil { 669 t.Fatalf("Unexpected error adding stream: %v", err) 670 } 671 defer mset.delete() 672 673 nc := clientConnectToServer(t, s) 674 defer nc.Close() 675 676 // Queue up our work item. 677 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 678 679 o, err := mset.addConsumer(&ConsumerConfig{ 680 Durable: "d", 681 AckPolicy: AckExplicit, 682 ReplayPolicy: ReplayOriginal, 683 }) 684 require_NoError(t, err) 685 defer o.delete() 686 687 // Force delay here which triggers the bug. 688 time.Sleep(250 * time.Millisecond) 689 690 if _, err = nc.Request(o.requestNextMsgSubject(), nil, time.Second); err != nil { 691 t.Fatalf("Unexpected error: %v", err) 692 } 693 }) 694 } 695 } 696 697 func TestJetStreamConsumerAckFloorFill(t *testing.T) { 698 cases := []struct { 699 name string 700 mconfig *StreamConfig 701 }{ 702 {"MemoryStore", &StreamConfig{Name: "MQ", Storage: MemoryStorage}}, 703 {"FileStore", &StreamConfig{Name: "MQ", Storage: FileStorage}}, 704 } 705 for _, c := range cases { 706 t.Run(c.name, func(t *testing.T) { 707 s := RunBasicJetStreamServer(t) 708 defer s.Shutdown() 709 710 mset, err := s.GlobalAccount().addStream(c.mconfig) 711 if err != nil { 712 t.Fatalf("Unexpected error adding stream: %v", err) 713 } 714 defer mset.delete() 715 716 nc := clientConnectToServer(t, s) 717 defer nc.Close() 718 719 for i := 1; i <= 4; i++ { 720 sendStreamMsg(t, nc, c.mconfig.Name, fmt.Sprintf("msg-%d", i)) 721 } 722 723 sub, _ := nc.SubscribeSync(nats.NewInbox()) 724 defer sub.Unsubscribe() 725 nc.Flush() 726 727 o, err := mset.addConsumer(&ConsumerConfig{ 728 Durable: "d", 729 DeliverSubject: sub.Subject, 730 AckPolicy: AckExplicit, 731 }) 732 require_NoError(t, err) 733 defer o.delete() 734 735 var first *nats.Msg 736 737 for i := 1; i <= 3; i++ { 738 m, err := sub.NextMsg(time.Second) 739 if err != nil { 740 t.Fatalf("Error receiving message %d: %v", i, err) 741 } 742 // Don't ack 1 or 4. 743 if i == 1 { 744 first = m 745 } else if i == 2 || i == 3 { 746 m.Respond(nil) 747 } 748 } 749 nc.Flush() 750 if info := o.info(); info.AckFloor.Consumer != 0 { 751 t.Fatalf("Expected the ack floor to be 0, got %d", info.AckFloor.Consumer) 752 } 753 // Now ack first, should move ack floor to 3. 754 first.Respond(nil) 755 nc.Flush() 756 757 checkFor(t, time.Second, 50*time.Millisecond, func() error { 758 if info := o.info(); info.AckFloor.Consumer != 3 { 759 return fmt.Errorf("Expected the ack floor to be 3, got %d", info.AckFloor.Consumer) 760 } 761 return nil 762 }) 763 }) 764 } 765 } 766 767 func TestJetStreamNoPanicOnRaceBetweenShutdownAndConsumerDelete(t *testing.T) { 768 cases := []struct { 769 name string 770 mconfig *StreamConfig 771 }{ 772 {"MemoryStore", &StreamConfig{Name: "MY_STREAM", Storage: MemoryStorage}}, 773 {"FileStore", &StreamConfig{Name: "MY_STREAM", Storage: FileStorage}}, 774 } 775 for _, c := range cases { 776 t.Run(c.name, func(t *testing.T) { 777 s := RunBasicJetStreamServer(t) 778 defer s.Shutdown() 779 780 mset, err := s.GlobalAccount().addStream(c.mconfig) 781 if err != nil { 782 t.Fatalf("Unexpected error adding stream: %v", err) 783 } 784 defer mset.delete() 785 786 var cons []*consumer 787 for i := 0; i < 100; i++ { 788 o, err := mset.addConsumer(&ConsumerConfig{ 789 Durable: fmt.Sprintf("d%d", i), 790 AckPolicy: AckExplicit, 791 }) 792 require_NoError(t, err) 793 defer o.delete() 794 cons = append(cons, o) 795 } 796 797 wg := sync.WaitGroup{} 798 wg.Add(1) 799 go func() { 800 defer wg.Done() 801 for _, c := range cons { 802 c.delete() 803 } 804 }() 805 time.Sleep(10 * time.Millisecond) 806 s.Shutdown() 807 }) 808 } 809 } 810 811 func TestJetStreamAddStreamMaxMsgSize(t *testing.T) { 812 cases := []struct { 813 name string 814 mconfig *StreamConfig 815 }{ 816 {name: "MemoryStore", 817 mconfig: &StreamConfig{ 818 Name: "foo", 819 Retention: LimitsPolicy, 820 MaxAge: time.Hour, 821 Storage: MemoryStorage, 822 MaxMsgSize: 22, 823 Replicas: 1, 824 }}, 825 {name: "FileStore", 826 mconfig: &StreamConfig{ 827 Name: "foo", 828 Retention: LimitsPolicy, 829 MaxAge: time.Hour, 830 Storage: FileStorage, 831 MaxMsgSize: 22, 832 Replicas: 1, 833 }}, 834 } 835 for _, c := range cases { 836 t.Run(c.name, func(t *testing.T) { 837 s := RunBasicJetStreamServer(t) 838 defer s.Shutdown() 839 840 mset, err := s.GlobalAccount().addStream(c.mconfig) 841 if err != nil { 842 t.Fatalf("Unexpected error adding stream: %v", err) 843 } 844 defer mset.delete() 845 846 nc := clientConnectToServer(t, s) 847 defer nc.Close() 848 849 if _, err := nc.Request("foo", []byte("Hello World!"), time.Second); err != nil { 850 t.Fatalf("Unexpected error: %v", err) 851 } 852 853 tooBig := []byte("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ") 854 resp, err := nc.Request("foo", tooBig, time.Second) 855 require_NoError(t, err) 856 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error.Description != "message size exceeds maximum allowed" { 857 t.Fatalf("Expected to get an error for maximum message size, got %q", pa.Error) 858 } 859 }) 860 } 861 } 862 863 func TestJetStreamAddStreamCanonicalNames(t *testing.T) { 864 s := RunBasicJetStreamServer(t) 865 defer s.Shutdown() 866 867 acc := s.GlobalAccount() 868 869 expectErr := func(_ *stream, err error) { 870 t.Helper() 871 if !IsNatsErr(err, JSStreamInvalidConfigF) { 872 t.Fatalf("Expected error but got none") 873 } 874 } 875 876 expectErr(acc.addStream(&StreamConfig{Name: "foo.bar"})) 877 expectErr(acc.addStream(&StreamConfig{Name: "foo.bar."})) 878 expectErr(acc.addStream(&StreamConfig{Name: "foo.*"})) 879 expectErr(acc.addStream(&StreamConfig{Name: "foo.>"})) 880 expectErr(acc.addStream(&StreamConfig{Name: "*"})) 881 expectErr(acc.addStream(&StreamConfig{Name: ">"})) 882 expectErr(acc.addStream(&StreamConfig{Name: "*>"})) 883 } 884 885 func TestJetStreamAddStreamBadSubjects(t *testing.T) { 886 s := RunBasicJetStreamServer(t) 887 defer s.Shutdown() 888 889 // Client for API requests. 890 nc := clientConnectToServer(t, s) 891 defer nc.Close() 892 893 expectAPIErr := func(cfg StreamConfig) { 894 t.Helper() 895 req, err := json.Marshal(cfg) 896 require_NoError(t, err) 897 resp, _ := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 898 var scResp JSApiStreamCreateResponse 899 if err := json.Unmarshal(resp.Data, &scResp); err != nil { 900 t.Fatalf("Unexpected error: %v", err) 901 } 902 903 require_Error(t, scResp.ToError(), NewJSStreamInvalidConfigError(fmt.Errorf("invalid subject"))) 904 } 905 906 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{"foo.bar."}}) 907 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{".."}}) 908 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{".*"}}) 909 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{".>"}}) 910 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{" x"}}) 911 expectAPIErr(StreamConfig{Name: "MyStream", Storage: MemoryStorage, Subjects: []string{"y "}}) 912 } 913 914 func TestJetStreamMaxConsumers(t *testing.T) { 915 s := RunBasicJetStreamServer(t) 916 defer s.Shutdown() 917 918 nc, js := jsClientConnect(t, s) 919 defer nc.Close() 920 921 cfg := &nats.StreamConfig{ 922 Name: "MAXC", 923 Storage: nats.MemoryStorage, 924 Subjects: []string{"in.maxc.>"}, 925 MaxConsumers: 1, 926 } 927 if _, err := js.AddStream(cfg); err != nil { 928 t.Fatalf("Unexpected error: %v", err) 929 } 930 si, err := js.StreamInfo("MAXC") 931 require_NoError(t, err) 932 if si.Config.MaxConsumers != 1 { 933 t.Fatalf("Expected max of 1, got %d", si.Config.MaxConsumers) 934 } 935 // Make sure we get the right error. 936 // This should succeed. 937 if _, err := js.SubscribeSync("in.maxc.foo"); err != nil { 938 t.Fatalf("Unexpected error: %v", err) 939 } 940 if _, err := js.SubscribeSync("in.maxc.bar"); err == nil { 941 t.Fatalf("Eexpected error but got none") 942 } 943 } 944 945 func TestJetStreamAddStreamOverlappingSubjects(t *testing.T) { 946 mconfig := &StreamConfig{ 947 Name: "ok", 948 Storage: MemoryStorage, 949 Subjects: []string{"foo", "bar", "baz.*", "foo.bar.baz.>"}, 950 } 951 952 s := RunBasicJetStreamServer(t) 953 defer s.Shutdown() 954 955 acc := s.GlobalAccount() 956 mset, err := acc.addStream(mconfig) 957 if err != nil { 958 t.Fatalf("Unexpected error adding stream: %v", err) 959 } 960 defer mset.delete() 961 962 expectErr := func(_ *stream, err error) { 963 t.Helper() 964 if err == nil || !strings.Contains(err.Error(), "subjects overlap") { 965 t.Fatalf("Expected error but got none") 966 } 967 } 968 969 // Test that any overlapping subjects will fail. 970 expectErr(acc.addStream(&StreamConfig{Name: "foo"})) 971 expectErr(acc.addStream(&StreamConfig{Name: "a", Subjects: []string{"baz", "bar"}})) 972 expectErr(acc.addStream(&StreamConfig{Name: "b", Subjects: []string{">"}})) 973 expectErr(acc.addStream(&StreamConfig{Name: "c", Subjects: []string{"baz.33"}})) 974 expectErr(acc.addStream(&StreamConfig{Name: "d", Subjects: []string{"*.33"}})) 975 expectErr(acc.addStream(&StreamConfig{Name: "e", Subjects: []string{"*.>"}})) 976 expectErr(acc.addStream(&StreamConfig{Name: "f", Subjects: []string{"foo.bar", "*.bar.>"}})) 977 } 978 979 func TestJetStreamAddStreamOverlapWithJSAPISubjects(t *testing.T) { 980 s := RunBasicJetStreamServer(t) 981 defer s.Shutdown() 982 983 acc := s.GlobalAccount() 984 985 expectErr := func(_ *stream, err error) { 986 t.Helper() 987 if err == nil || !strings.Contains(err.Error(), "subjects overlap") { 988 t.Fatalf("Expected error but got none") 989 } 990 } 991 992 // Test that any overlapping subjects with our JSAPI should fail. 993 expectErr(acc.addStream(&StreamConfig{Name: "a", Subjects: []string{"$JS.API.foo", "$JS.API.bar"}})) 994 expectErr(acc.addStream(&StreamConfig{Name: "b", Subjects: []string{"$JS.API.>"}})) 995 expectErr(acc.addStream(&StreamConfig{Name: "c", Subjects: []string{"$JS.API.*"}})) 996 997 // Events and Advisories etc should be ok. 998 if _, err := acc.addStream(&StreamConfig{Name: "a", Subjects: []string{"$JS.EVENT.>"}}); err != nil { 999 t.Fatalf("Expected this to work: %v", err) 1000 } 1001 } 1002 1003 func TestJetStreamAddStreamSameConfigOK(t *testing.T) { 1004 mconfig := &StreamConfig{ 1005 Name: "ok", 1006 Subjects: []string{"foo", "bar", "baz.*", "foo.bar.baz.>"}, 1007 Storage: MemoryStorage, 1008 } 1009 1010 s := RunBasicJetStreamServer(t) 1011 defer s.Shutdown() 1012 1013 acc := s.GlobalAccount() 1014 mset, err := acc.addStream(mconfig) 1015 if err != nil { 1016 t.Fatalf("Unexpected error adding stream: %v", err) 1017 } 1018 defer mset.delete() 1019 1020 // Adding again with same config should be idempotent. 1021 if _, err = acc.addStream(mconfig); err != nil { 1022 t.Fatalf("Unexpected error adding stream: %v", err) 1023 } 1024 } 1025 1026 func sendStreamMsg(t *testing.T, nc *nats.Conn, subject, msg string) *PubAck { 1027 t.Helper() 1028 resp, _ := nc.Request(subject, []byte(msg), 500*time.Millisecond) 1029 if resp == nil { 1030 t.Fatalf("No response for %q, possible timeout?", msg) 1031 } 1032 pa := getPubAckResponse(resp.Data) 1033 if pa == nil || pa.Error != nil { 1034 t.Fatalf("Expected a valid JetStreamPubAck, got %q", resp.Data) 1035 } 1036 return pa.PubAck 1037 } 1038 1039 func TestJetStreamBasicAckPublish(t *testing.T) { 1040 cases := []struct { 1041 name string 1042 mconfig *StreamConfig 1043 }{ 1044 {"MemoryStore", &StreamConfig{Name: "foo", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 1045 {"FileStore", &StreamConfig{Name: "foo", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 1046 } 1047 for _, c := range cases { 1048 t.Run(c.name, func(t *testing.T) { 1049 s := RunBasicJetStreamServer(t) 1050 defer s.Shutdown() 1051 1052 mset, err := s.GlobalAccount().addStream(c.mconfig) 1053 if err != nil { 1054 t.Fatalf("Unexpected error adding stream: %v", err) 1055 } 1056 defer mset.delete() 1057 1058 nc := clientConnectToServer(t, s) 1059 defer nc.Close() 1060 1061 for i := 0; i < 50; i++ { 1062 sendStreamMsg(t, nc, "foo.bar", "Hello World!") 1063 } 1064 state := mset.state() 1065 if state.Msgs != 50 { 1066 t.Fatalf("Expected 50 messages, got %d", state.Msgs) 1067 } 1068 }) 1069 } 1070 } 1071 1072 func TestJetStreamStateTimestamps(t *testing.T) { 1073 cases := []struct { 1074 name string 1075 mconfig *StreamConfig 1076 }{ 1077 {"MemoryStore", &StreamConfig{Name: "foo", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 1078 {"FileStore", &StreamConfig{Name: "foo", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 1079 } 1080 for _, c := range cases { 1081 t.Run(c.name, func(t *testing.T) { 1082 s := RunBasicJetStreamServer(t) 1083 defer s.Shutdown() 1084 1085 mset, err := s.GlobalAccount().addStream(c.mconfig) 1086 if err != nil { 1087 t.Fatalf("Unexpected error adding stream: %v", err) 1088 } 1089 defer mset.delete() 1090 1091 nc := clientConnectToServer(t, s) 1092 defer nc.Close() 1093 1094 start := time.Now() 1095 delay := 250 * time.Millisecond 1096 sendStreamMsg(t, nc, "foo.bar", "Hello World!") 1097 time.Sleep(delay) 1098 sendStreamMsg(t, nc, "foo.bar", "Hello World Again!") 1099 1100 state := mset.state() 1101 if state.FirstTime.Before(start) { 1102 t.Fatalf("Unexpected first message timestamp: %v", state.FirstTime) 1103 } 1104 if state.LastTime.Before(start.Add(delay)) { 1105 t.Fatalf("Unexpected last message timestamp: %v", state.LastTime) 1106 } 1107 }) 1108 } 1109 } 1110 1111 func TestJetStreamNoAckStream(t *testing.T) { 1112 cases := []struct { 1113 name string 1114 mconfig *StreamConfig 1115 }{ 1116 {"MemoryStore", &StreamConfig{Name: "foo", Storage: MemoryStorage, NoAck: true}}, 1117 {"FileStore", &StreamConfig{Name: "foo", Storage: FileStorage, NoAck: true}}, 1118 } 1119 for _, c := range cases { 1120 t.Run(c.name, func(t *testing.T) { 1121 s := RunBasicJetStreamServer(t) 1122 defer s.Shutdown() 1123 1124 // We can use NoAck to suppress acks even when reply subjects are present. 1125 mset, err := s.GlobalAccount().addStream(c.mconfig) 1126 if err != nil { 1127 t.Fatalf("Unexpected error adding stream: %v", err) 1128 } 1129 defer mset.delete() 1130 1131 nc := clientConnectToServer(t, s) 1132 defer nc.Close() 1133 1134 if _, err := nc.Request("foo", []byte("Hello World!"), 25*time.Millisecond); err != nats.ErrTimeout { 1135 t.Fatalf("Expected a timeout error and no response with acks suppressed") 1136 } 1137 1138 state := mset.state() 1139 if state.Msgs != 1 { 1140 t.Fatalf("Expected 1 message, got %d", state.Msgs) 1141 } 1142 }) 1143 } 1144 } 1145 1146 func TestJetStreamCreateConsumer(t *testing.T) { 1147 cases := []struct { 1148 name string 1149 mconfig *StreamConfig 1150 }{ 1151 {"MemoryStore", &StreamConfig{Name: "foo", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}, Retention: WorkQueuePolicy}}, 1152 {"FileStore", &StreamConfig{Name: "foo", Storage: FileStorage, Subjects: []string{"foo", "bar"}, Retention: WorkQueuePolicy}}, 1153 } 1154 for _, c := range cases { 1155 t.Run(c.name, func(t *testing.T) { 1156 s := RunBasicJetStreamServer(t) 1157 defer s.Shutdown() 1158 1159 mset, err := s.GlobalAccount().addStream(c.mconfig) 1160 if err != nil { 1161 t.Fatalf("Unexpected error adding stream: %v", err) 1162 } 1163 defer mset.delete() 1164 1165 // Check for basic errors. 1166 if _, err := mset.addConsumer(nil); err == nil { 1167 t.Fatalf("Expected an error for no config") 1168 } 1169 1170 // No deliver subject, meaning its in pull mode, work queue mode means it is required to 1171 // do explicit ack. 1172 if _, err := mset.addConsumer(&ConsumerConfig{}); err == nil { 1173 t.Fatalf("Expected an error on work queue / pull mode without explicit ack mode") 1174 } 1175 1176 // Check for delivery subject errors. 1177 1178 // Literal delivery subject required. 1179 if _, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: "foo.*"}); err == nil { 1180 t.Fatalf("Expected an error on bad delivery subject") 1181 } 1182 // Check for cycles 1183 if _, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: "foo"}); err == nil { 1184 t.Fatalf("Expected an error on delivery subject that forms a cycle") 1185 } 1186 if _, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: "bar"}); err == nil { 1187 t.Fatalf("Expected an error on delivery subject that forms a cycle") 1188 } 1189 if _, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: "*"}); err == nil { 1190 t.Fatalf("Expected an error on delivery subject that forms a cycle") 1191 } 1192 1193 // StartPosition conflicts 1194 now := time.Now().UTC() 1195 if _, err := mset.addConsumer(&ConsumerConfig{ 1196 DeliverSubject: "A", 1197 OptStartSeq: 1, 1198 OptStartTime: &now, 1199 }); err == nil { 1200 t.Fatalf("Expected an error on start position conflicts") 1201 } 1202 if _, err := mset.addConsumer(&ConsumerConfig{ 1203 DeliverSubject: "A", 1204 OptStartTime: &now, 1205 }); err == nil { 1206 t.Fatalf("Expected an error on start position conflicts") 1207 } 1208 1209 // Non-Durables need to have subscription to delivery subject. 1210 delivery := nats.NewInbox() 1211 nc := clientConnectToServer(t, s) 1212 defer nc.Close() 1213 sub, _ := nc.SubscribeSync(delivery) 1214 defer sub.Unsubscribe() 1215 nc.Flush() 1216 1217 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, AckPolicy: AckExplicit}) 1218 if err != nil { 1219 t.Fatalf("Expected no error with registered interest, got %v", err) 1220 } 1221 1222 if err := mset.deleteConsumer(o); err != nil { 1223 t.Fatalf("Expected no error on delete, got %v", err) 1224 } 1225 1226 // Now let's check that durables can be created and a duplicate call to add will be ok. 1227 dcfg := &ConsumerConfig{ 1228 Durable: "ddd", 1229 DeliverSubject: delivery, 1230 AckPolicy: AckExplicit, 1231 } 1232 if _, err = mset.addConsumer(dcfg); err != nil { 1233 t.Fatalf("Unexpected error creating consumer: %v", err) 1234 } 1235 if _, err = mset.addConsumer(dcfg); err != nil { 1236 t.Fatalf("Unexpected error creating second identical consumer: %v", err) 1237 } 1238 // Not test that we can change the delivery subject if that is only thing that has not 1239 // changed and we are not active. 1240 sub.Unsubscribe() 1241 sub, _ = nc.SubscribeSync("d.d.d") 1242 nc.Flush() 1243 defer sub.Unsubscribe() 1244 dcfg.DeliverSubject = "d.d.d" 1245 if _, err = mset.addConsumer(dcfg); err != nil { 1246 t.Fatalf("Unexpected error creating third consumer with just deliver subject changed: %v", err) 1247 } 1248 }) 1249 } 1250 } 1251 1252 func TestJetStreamBasicDeliverSubject(t *testing.T) { 1253 cases := []struct { 1254 name string 1255 mconfig *StreamConfig 1256 }{ 1257 {"MemoryStore", &StreamConfig{Name: "MSET", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 1258 {"FileStore", &StreamConfig{Name: "MSET", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 1259 } 1260 for _, c := range cases { 1261 t.Run(c.name, func(t *testing.T) { 1262 s := RunBasicJetStreamServer(t) 1263 defer s.Shutdown() 1264 1265 mset, err := s.GlobalAccount().addStream(c.mconfig) 1266 if err != nil { 1267 t.Fatalf("Unexpected error adding stream: %v", err) 1268 } 1269 defer mset.delete() 1270 1271 nc := clientConnectToServer(t, s) 1272 defer nc.Close() 1273 1274 toSend := 100 1275 sendSubj := "foo.bar" 1276 for i := 1; i <= toSend; i++ { 1277 sendStreamMsg(t, nc, sendSubj, strconv.Itoa(i)) 1278 } 1279 state := mset.state() 1280 if state.Msgs != uint64(toSend) { 1281 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 1282 } 1283 1284 // Now create an consumer. Use different connection. 1285 nc2 := clientConnectToServer(t, s) 1286 defer nc2.Close() 1287 1288 sub, _ := nc2.SubscribeSync(nats.NewInbox()) 1289 defer sub.Unsubscribe() 1290 nc2.Flush() 1291 1292 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 1293 if err != nil { 1294 t.Fatalf("Expected no error with registered interest, got %v", err) 1295 } 1296 defer o.delete() 1297 1298 // Check for our messages. 1299 checkMsgs := func(seqOff int) { 1300 t.Helper() 1301 1302 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 1303 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 1304 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 1305 } 1306 return nil 1307 }) 1308 1309 // Now let's check the messages 1310 for i := 0; i < toSend; i++ { 1311 m, _ := sub.NextMsg(time.Second) 1312 // JetStream will have the subject match the stream subject, not delivery subject. 1313 if m.Subject != sendSubj { 1314 t.Fatalf("Expected original subject of %q, but got %q", sendSubj, m.Subject) 1315 } 1316 // Now check that reply subject exists and has a sequence as the last token. 1317 if seq := o.seqFromReply(m.Reply); seq != uint64(i+seqOff) { 1318 t.Fatalf("Expected sequence of %d , got %d", i+seqOff, seq) 1319 } 1320 // Ack the message here. 1321 m.Respond(nil) 1322 } 1323 } 1324 1325 checkMsgs(1) 1326 1327 // Now send more and make sure delivery picks back up. 1328 for i := toSend + 1; i <= toSend*2; i++ { 1329 sendStreamMsg(t, nc, sendSubj, strconv.Itoa(i)) 1330 } 1331 state = mset.state() 1332 if state.Msgs != uint64(toSend*2) { 1333 t.Fatalf("Expected %d messages, got %d", toSend*2, state.Msgs) 1334 } 1335 1336 checkMsgs(101) 1337 1338 checkSubEmpty := func() { 1339 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 0 { 1340 t.Fatalf("Expected sub to have no pending") 1341 } 1342 } 1343 checkSubEmpty() 1344 o.delete() 1345 1346 // Now check for deliver last, deliver new and deliver by seq. 1347 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject, DeliverPolicy: DeliverLast}) 1348 if err != nil { 1349 t.Fatalf("Expected no error with registered interest, got %v", err) 1350 } 1351 defer o.delete() 1352 1353 m, err := sub.NextMsg(time.Second) 1354 if err != nil { 1355 t.Fatalf("Did not get expected message, got %v", err) 1356 } 1357 // All Consumers start with sequence #1. 1358 if seq := o.seqFromReply(m.Reply); seq != 1 { 1359 t.Fatalf("Expected sequence to be 1, but got %d", seq) 1360 } 1361 // Check that is the last msg we sent though. 1362 if mseq, _ := strconv.Atoi(string(m.Data)); mseq != 200 { 1363 t.Fatalf("Expected messag sequence to be 200, but got %d", mseq) 1364 } 1365 1366 checkSubEmpty() 1367 o.delete() 1368 1369 // Make sure we only got one message. 1370 if m, err := sub.NextMsg(5 * time.Millisecond); err == nil { 1371 t.Fatalf("Expected no msg, got %+v", m) 1372 } 1373 1374 checkSubEmpty() 1375 o.delete() 1376 1377 // Now try by sequence number. 1378 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject, DeliverPolicy: DeliverByStartSequence, OptStartSeq: 101}) 1379 if err != nil { 1380 t.Fatalf("Expected no error with registered interest, got %v", err) 1381 } 1382 defer o.delete() 1383 1384 checkMsgs(1) 1385 1386 // Now do push based queue-subscribers 1387 sub, _ = nc2.QueueSubscribeSync("_qg_", "dev") 1388 defer sub.Unsubscribe() 1389 nc2.Flush() 1390 1391 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject, DeliverGroup: "dev"}) 1392 if err != nil { 1393 t.Fatalf("Expected no error with registered interest, got %v", err) 1394 } 1395 defer o.delete() 1396 1397 // Since we sent another batch need check to be looking for 2x. 1398 toSend *= 2 1399 checkMsgs(1) 1400 }) 1401 } 1402 } 1403 1404 func workerModeConfig(name string) *ConsumerConfig { 1405 return &ConsumerConfig{Durable: name, AckPolicy: AckExplicit} 1406 } 1407 1408 func TestJetStreamBasicWorkQueue(t *testing.T) { 1409 cases := []struct { 1410 name string 1411 mconfig *StreamConfig 1412 }{ 1413 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 1414 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 1415 } 1416 for _, c := range cases { 1417 t.Run(c.name, func(t *testing.T) { 1418 s := RunBasicJetStreamServer(t) 1419 defer s.Shutdown() 1420 1421 mset, err := s.GlobalAccount().addStream(c.mconfig) 1422 if err != nil { 1423 t.Fatalf("Unexpected error adding stream: %v", err) 1424 } 1425 defer mset.delete() 1426 1427 // Create basic work queue mode consumer. 1428 oname := "WQ" 1429 o, err := mset.addConsumer(workerModeConfig(oname)) 1430 if err != nil { 1431 t.Fatalf("Expected no error with registered interest, got %v", err) 1432 } 1433 defer o.delete() 1434 1435 if o.nextSeq() != 1 { 1436 t.Fatalf("Expected to be starting at sequence 1") 1437 } 1438 1439 nc := clientConnectWithOldRequest(t, s) 1440 defer nc.Close() 1441 1442 // Now load up some messages. 1443 toSend := 100 1444 sendSubj := "bar" 1445 for i := 0; i < toSend; i++ { 1446 sendStreamMsg(t, nc, sendSubj, "Hello World!") 1447 } 1448 state := mset.state() 1449 if state.Msgs != uint64(toSend) { 1450 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 1451 } 1452 1453 getNext := func(seqno int) { 1454 t.Helper() 1455 nextMsg, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 1456 if err != nil { 1457 t.Fatalf("Unexpected error for seq %d: %v", seqno, err) 1458 } 1459 if nextMsg.Subject != "bar" { 1460 t.Fatalf("Expected subject of %q, got %q", "bar", nextMsg.Subject) 1461 } 1462 if seq := o.seqFromReply(nextMsg.Reply); seq != uint64(seqno) { 1463 t.Fatalf("Expected sequence of %d , got %d", seqno, seq) 1464 } 1465 } 1466 1467 // Make sure we can get the messages already there. 1468 for i := 1; i <= toSend; i++ { 1469 getNext(i) 1470 } 1471 1472 // Now we want to make sure we can get a message that is published to the message 1473 // set as we are waiting for it. 1474 nextDelay := 50 * time.Millisecond 1475 1476 go func() { 1477 time.Sleep(nextDelay) 1478 sendStreamMsg(t, nc, sendSubj, "Hello World!") 1479 }() 1480 1481 start := time.Now() 1482 getNext(toSend + 1) 1483 if time.Since(start) < nextDelay { 1484 t.Fatalf("Received message too quickly") 1485 } 1486 1487 // Now do same thing but combine waiting for new ones with sending. 1488 go func() { 1489 time.Sleep(nextDelay) 1490 for i := 0; i < toSend; i++ { 1491 nc.Request(sendSubj, []byte("Hello World!"), 50*time.Millisecond) 1492 } 1493 }() 1494 1495 for i := toSend + 2; i < toSend*2+2; i++ { 1496 getNext(i) 1497 } 1498 }) 1499 } 1500 } 1501 1502 func TestJetStreamWorkQueueMaxWaiting(t *testing.T) { 1503 cases := []struct { 1504 name string 1505 mconfig *StreamConfig 1506 }{ 1507 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 1508 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 1509 } 1510 for _, c := range cases { 1511 t.Run(c.name, func(t *testing.T) { 1512 s := RunBasicJetStreamServer(t) 1513 defer s.Shutdown() 1514 1515 mset, err := s.GlobalAccount().addStream(c.mconfig) 1516 if err != nil { 1517 t.Fatalf("Unexpected error adding stream: %v", err) 1518 } 1519 defer mset.delete() 1520 1521 // Make sure these cases fail 1522 cfg := &ConsumerConfig{Durable: "foo", AckPolicy: AckExplicit, MaxWaiting: 10, DeliverSubject: "_INBOX.22"} 1523 if _, err := mset.addConsumer(cfg); err == nil { 1524 t.Fatalf("Expected an error with MaxWaiting set on non-pull based consumer") 1525 } 1526 cfg = &ConsumerConfig{Durable: "foo", AckPolicy: AckExplicit, MaxWaiting: -1} 1527 if _, err := mset.addConsumer(cfg); err == nil { 1528 t.Fatalf("Expected an error with MaxWaiting being negative") 1529 } 1530 1531 // Create basic work queue mode consumer. 1532 wcfg := workerModeConfig("MAXWQ") 1533 o, err := mset.addConsumer(wcfg) 1534 if err != nil { 1535 t.Fatalf("Expected no error with registered interest, got %v", err) 1536 } 1537 defer o.delete() 1538 1539 // Make sure we set default correctly. 1540 if cfg := o.config(); cfg.MaxWaiting != JSWaitQueueDefaultMax { 1541 t.Fatalf("Expected default max waiting to have been set to %d, got %d", JSWaitQueueDefaultMax, cfg.MaxWaiting) 1542 } 1543 1544 expectWaiting := func(expected int) { 1545 t.Helper() 1546 checkFor(t, time.Second, 25*time.Millisecond, func() error { 1547 if oi := o.info(); oi.NumWaiting != expected { 1548 return fmt.Errorf("Expected %d waiting, got %d", expected, oi.NumWaiting) 1549 } 1550 return nil 1551 }) 1552 } 1553 1554 nc := clientConnectWithOldRequest(t, s) 1555 defer nc.Close() 1556 1557 // Like muxed new INBOX. 1558 sub, _ := nc.SubscribeSync("req.*") 1559 defer sub.Unsubscribe() 1560 nc.Flush() 1561 1562 checkSubPending := func(numExpected int) { 1563 t.Helper() 1564 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 1565 if nmsgs, _, err := sub.Pending(); err != nil || nmsgs != numExpected { 1566 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 1567 } 1568 return nil 1569 }) 1570 } 1571 1572 getSubj := o.requestNextMsgSubject() 1573 // Queue up JSWaitQueueDefaultMax requests. 1574 for i := 0; i < JSWaitQueueDefaultMax; i++ { 1575 nc.PublishRequest(getSubj, fmt.Sprintf("req.%d", i), nil) 1576 } 1577 expectWaiting(JSWaitQueueDefaultMax) 1578 1579 // We are at the max, so we should get a 409 saying that we have 1580 // exceeded the number of pull requests. 1581 m, err := nc.Request(getSubj, nil, 100*time.Millisecond) 1582 require_NoError(t, err) 1583 // Make sure this is the 409 1584 if v := m.Header.Get("Status"); v != "409" { 1585 t.Fatalf("Expected a 409 status code, got %q", v) 1586 } 1587 // The sub for the other requests should not have received anything 1588 checkSubPending(0) 1589 // Now send some messages that should make some of the requests complete 1590 sendStreamMsg(t, nc, "foo", "Hello World!") 1591 sendStreamMsg(t, nc, "bar", "Hello World!") 1592 expectWaiting(JSWaitQueueDefaultMax - 2) 1593 }) 1594 } 1595 } 1596 1597 func TestJetStreamWorkQueueWrapWaiting(t *testing.T) { 1598 cases := []struct { 1599 name string 1600 mconfig *StreamConfig 1601 }{ 1602 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 1603 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 1604 } 1605 for _, c := range cases { 1606 t.Run(c.name, func(t *testing.T) { 1607 s := RunBasicJetStreamServer(t) 1608 defer s.Shutdown() 1609 1610 mset, err := s.GlobalAccount().addStream(c.mconfig) 1611 if err != nil { 1612 t.Fatalf("Unexpected error adding stream: %v", err) 1613 } 1614 defer mset.delete() 1615 1616 maxWaiting := 8 1617 wcfg := workerModeConfig("WRAP") 1618 wcfg.MaxWaiting = maxWaiting 1619 1620 o, err := mset.addConsumer(wcfg) 1621 if err != nil { 1622 t.Fatalf("Expected no error with registered interest, got %v", err) 1623 } 1624 defer o.delete() 1625 1626 getSubj := o.requestNextMsgSubject() 1627 1628 expectWaiting := func(expected int) { 1629 t.Helper() 1630 checkFor(t, time.Second, 25*time.Millisecond, func() error { 1631 if oi := o.info(); oi.NumWaiting != expected { 1632 return fmt.Errorf("Expected %d waiting, got %d", expected, oi.NumWaiting) 1633 } 1634 return nil 1635 }) 1636 } 1637 1638 nc := clientConnectToServer(t, s) 1639 defer nc.Close() 1640 1641 sub, _ := nc.SubscribeSync("req.*") 1642 defer sub.Unsubscribe() 1643 nc.Flush() 1644 1645 // Fill up waiting. 1646 for i := 0; i < maxWaiting; i++ { 1647 nc.PublishRequest(getSubj, fmt.Sprintf("req.%d", i), nil) 1648 } 1649 expectWaiting(maxWaiting) 1650 1651 // Now use 1/2 of the waiting. 1652 for i := 0; i < maxWaiting/2; i++ { 1653 sendStreamMsg(t, nc, "foo", "Hello World!") 1654 } 1655 expectWaiting(maxWaiting / 2) 1656 1657 // Now add in two (2) more pull requests. 1658 for i := maxWaiting; i < maxWaiting+2; i++ { 1659 nc.PublishRequest(getSubj, fmt.Sprintf("req.%d", i), nil) 1660 } 1661 expectWaiting(maxWaiting/2 + 2) 1662 1663 // Now use second 1/2 of the waiting and the 2 extra. 1664 for i := 0; i < maxWaiting/2+2; i++ { 1665 sendStreamMsg(t, nc, "bar", "Hello World!") 1666 } 1667 expectWaiting(0) 1668 1669 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 1670 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != maxWaiting+2 { 1671 return fmt.Errorf("Expected sub to have %d pending, got %d", maxWaiting+2, nmsgs) 1672 } 1673 return nil 1674 }) 1675 }) 1676 } 1677 } 1678 1679 func TestJetStreamWorkQueueRequest(t *testing.T) { 1680 cases := []struct { 1681 name string 1682 mconfig *StreamConfig 1683 }{ 1684 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 1685 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 1686 } 1687 for _, c := range cases { 1688 t.Run(c.name, func(t *testing.T) { 1689 s := RunBasicJetStreamServer(t) 1690 defer s.Shutdown() 1691 1692 mset, err := s.GlobalAccount().addStream(c.mconfig) 1693 if err != nil { 1694 t.Fatalf("Unexpected error adding stream: %v", err) 1695 } 1696 defer mset.delete() 1697 1698 o, err := mset.addConsumer(workerModeConfig("WRAP")) 1699 if err != nil { 1700 t.Fatalf("Expected no error with registered interest, got %v", err) 1701 } 1702 defer o.delete() 1703 1704 nc := clientConnectToServer(t, s) 1705 defer nc.Close() 1706 1707 toSend := 25 1708 for i := 0; i < toSend; i++ { 1709 sendStreamMsg(t, nc, "bar", "Hello World!") 1710 } 1711 1712 reply := "_.consumer._" 1713 sub, _ := nc.SubscribeSync(reply) 1714 defer sub.Unsubscribe() 1715 1716 getSubj := o.requestNextMsgSubject() 1717 1718 checkSubPending := func(numExpected int) { 1719 t.Helper() 1720 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 1721 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != numExpected { 1722 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 1723 } 1724 return nil 1725 }) 1726 } 1727 1728 // Create a formal request object. 1729 req := &JSApiConsumerGetNextRequest{Batch: toSend} 1730 jreq, _ := json.Marshal(req) 1731 nc.PublishRequest(getSubj, reply, jreq) 1732 1733 checkSubPending(toSend) 1734 1735 // Now check that we can ask for NoWait 1736 req.Batch = 1 1737 req.NoWait = true 1738 jreq, _ = json.Marshal(req) 1739 1740 resp, err := nc.Request(getSubj, jreq, 100*time.Millisecond) 1741 require_NoError(t, err) 1742 if status := resp.Header.Get("Status"); !strings.HasPrefix(status, "404") { 1743 t.Fatalf("Expected status code of 404") 1744 } 1745 // Load up more messages. 1746 for i := 0; i < toSend; i++ { 1747 sendStreamMsg(t, nc, "foo", "Hello World!") 1748 } 1749 // Now we will ask for a batch larger then what is queued up. 1750 req.Batch = toSend + 10 1751 req.NoWait = true 1752 jreq, _ = json.Marshal(req) 1753 1754 nc.PublishRequest(getSubj, reply, jreq) 1755 // We should now have 2 * toSend + the 404 message. 1756 checkSubPending(2*toSend + 1) 1757 for i := 0; i < 2*toSend+1; i++ { 1758 sub.NextMsg(time.Millisecond) 1759 } 1760 checkSubPending(0) 1761 mset.purge(nil) 1762 1763 // Now do expiration 1764 req.Batch = 1 1765 req.NoWait = false 1766 req.Expires = 100 * time.Millisecond 1767 jreq, _ = json.Marshal(req) 1768 1769 nc.PublishRequest(getSubj, reply, jreq) 1770 // Let it expire 1771 time.Sleep(200 * time.Millisecond) 1772 1773 // Send a few more messages. These should not be delivered to the sub. 1774 sendStreamMsg(t, nc, "foo", "Hello World!") 1775 sendStreamMsg(t, nc, "bar", "Hello World!") 1776 time.Sleep(100 * time.Millisecond) 1777 1778 // Expect the request timed out message. 1779 checkSubPending(1) 1780 if resp, _ = sub.NextMsg(time.Millisecond); resp == nil { 1781 t.Fatalf("Expected an expired status message") 1782 } 1783 if status := resp.Header.Get("Status"); !strings.HasPrefix(status, "408") { 1784 t.Fatalf("Expected status code of 408") 1785 } 1786 1787 // Send a new request, we should not get the 408 because our previous request 1788 // should have expired. 1789 nc.PublishRequest(getSubj, reply, jreq) 1790 checkSubPending(1) 1791 sub.NextMsg(time.Second) 1792 checkSubPending(0) 1793 }) 1794 } 1795 } 1796 1797 func TestJetStreamSubjectFiltering(t *testing.T) { 1798 cases := []struct { 1799 name string 1800 mconfig *StreamConfig 1801 }{ 1802 {"MemoryStore", &StreamConfig{Name: "MSET", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 1803 {"FileStore", &StreamConfig{Name: "MSET", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 1804 } 1805 for _, c := range cases { 1806 t.Run(c.name, func(t *testing.T) { 1807 s := RunBasicJetStreamServer(t) 1808 defer s.Shutdown() 1809 1810 mset, err := s.GlobalAccount().addStream(c.mconfig) 1811 if err != nil { 1812 t.Fatalf("Unexpected error adding stream: %v", err) 1813 } 1814 defer mset.delete() 1815 1816 nc := clientConnectToServer(t, s) 1817 defer nc.Close() 1818 1819 toSend := 50 1820 subjA := "foo.A" 1821 subjB := "foo.B" 1822 1823 for i := 0; i < toSend; i++ { 1824 sendStreamMsg(t, nc, subjA, "Hello World!") 1825 sendStreamMsg(t, nc, subjB, "Hello World!") 1826 } 1827 state := mset.state() 1828 if state.Msgs != uint64(toSend*2) { 1829 t.Fatalf("Expected %d messages, got %d", toSend*2, state.Msgs) 1830 } 1831 1832 delivery := nats.NewInbox() 1833 sub, _ := nc.SubscribeSync(delivery) 1834 defer sub.Unsubscribe() 1835 nc.Flush() 1836 1837 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, FilterSubject: subjB}) 1838 if err != nil { 1839 t.Fatalf("Expected no error with registered interest, got %v", err) 1840 } 1841 defer o.delete() 1842 1843 // Now let's check the messages 1844 for i := 1; i <= toSend; i++ { 1845 m, err := sub.NextMsg(time.Second) 1846 require_NoError(t, err) 1847 // JetStream will have the subject match the stream subject, not delivery subject. 1848 // We want these to only be subjB. 1849 if m.Subject != subjB { 1850 t.Fatalf("Expected original subject of %q, but got %q", subjB, m.Subject) 1851 } 1852 // Now check that reply subject exists and has a sequence as the last token. 1853 if seq := o.seqFromReply(m.Reply); seq != uint64(i) { 1854 t.Fatalf("Expected sequence of %d , got %d", i, seq) 1855 } 1856 // Ack the message here. 1857 m.Respond(nil) 1858 } 1859 1860 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 0 { 1861 t.Fatalf("Expected sub to have no pending") 1862 } 1863 }) 1864 } 1865 } 1866 1867 func TestJetStreamWorkQueueSubjectFiltering(t *testing.T) { 1868 cases := []struct { 1869 name string 1870 mconfig *StreamConfig 1871 }{ 1872 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 1873 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 1874 } 1875 for _, c := range cases { 1876 t.Run(c.name, func(t *testing.T) { 1877 s := RunBasicJetStreamServer(t) 1878 defer s.Shutdown() 1879 1880 mset, err := s.GlobalAccount().addStream(c.mconfig) 1881 if err != nil { 1882 t.Fatalf("Unexpected error adding stream: %v", err) 1883 } 1884 defer mset.delete() 1885 1886 nc := clientConnectToServer(t, s) 1887 defer nc.Close() 1888 1889 toSend := 50 1890 subjA := "foo.A" 1891 subjB := "foo.B" 1892 1893 for i := 0; i < toSend; i++ { 1894 sendStreamMsg(t, nc, subjA, "Hello World!") 1895 sendStreamMsg(t, nc, subjB, "Hello World!") 1896 } 1897 state := mset.state() 1898 if state.Msgs != uint64(toSend*2) { 1899 t.Fatalf("Expected %d messages, got %d", toSend*2, state.Msgs) 1900 } 1901 1902 oname := "WQ" 1903 o, err := mset.addConsumer(&ConsumerConfig{Durable: oname, FilterSubject: subjA, AckPolicy: AckExplicit}) 1904 if err != nil { 1905 t.Fatalf("Expected no error with registered interest, got %v", err) 1906 } 1907 defer o.delete() 1908 1909 if o.nextSeq() != 1 { 1910 t.Fatalf("Expected to be starting at sequence 1") 1911 } 1912 1913 getNext := func(seqno int) { 1914 t.Helper() 1915 nextMsg, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 1916 require_NoError(t, err) 1917 if nextMsg.Subject != subjA { 1918 t.Fatalf("Expected subject of %q, got %q", subjA, nextMsg.Subject) 1919 } 1920 if seq := o.seqFromReply(nextMsg.Reply); seq != uint64(seqno) { 1921 t.Fatalf("Expected sequence of %d , got %d", seqno, seq) 1922 } 1923 nextMsg.Respond(nil) 1924 } 1925 1926 // Make sure we can get the messages already there. 1927 for i := 1; i <= toSend; i++ { 1928 getNext(i) 1929 } 1930 }) 1931 } 1932 } 1933 1934 func TestJetStreamWildcardSubjectFiltering(t *testing.T) { 1935 cases := []struct { 1936 name string 1937 mconfig *StreamConfig 1938 }{ 1939 {"MemoryStore", &StreamConfig{Name: "ORDERS", Storage: MemoryStorage, Subjects: []string{"orders.*.*"}}}, 1940 {"FileStore", &StreamConfig{Name: "ORDERS", Storage: FileStorage, Subjects: []string{"orders.*.*"}}}, 1941 } 1942 for _, c := range cases { 1943 t.Run(c.name, func(t *testing.T) { 1944 s := RunBasicJetStreamServer(t) 1945 defer s.Shutdown() 1946 1947 mset, err := s.GlobalAccount().addStream(c.mconfig) 1948 if err != nil { 1949 t.Fatalf("Unexpected error adding stream: %v", err) 1950 } 1951 defer mset.delete() 1952 1953 nc := clientConnectToServer(t, s) 1954 defer nc.Close() 1955 1956 toSend := 100 1957 for i := 1; i <= toSend; i++ { 1958 subj := fmt.Sprintf("orders.%d.%s", i, "NEW") 1959 sendStreamMsg(t, nc, subj, "new order") 1960 } 1961 // Randomly move 25 to shipped. 1962 toShip := 25 1963 shipped := make(map[int]bool) 1964 for i := 0; i < toShip; { 1965 orderId := rand.Intn(toSend-1) + 1 1966 if shipped[orderId] { 1967 continue 1968 } 1969 subj := fmt.Sprintf("orders.%d.%s", orderId, "SHIPPED") 1970 sendStreamMsg(t, nc, subj, "shipped order") 1971 shipped[orderId] = true 1972 i++ 1973 } 1974 state := mset.state() 1975 if state.Msgs != uint64(toSend+toShip) { 1976 t.Fatalf("Expected %d messages, got %d", toSend+toShip, state.Msgs) 1977 } 1978 1979 delivery := nats.NewInbox() 1980 sub, _ := nc.SubscribeSync(delivery) 1981 defer sub.Unsubscribe() 1982 nc.Flush() 1983 1984 // Get all shipped. 1985 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, FilterSubject: "orders.*.SHIPPED"}) 1986 if err != nil { 1987 t.Fatalf("Expected no error with registered interest, got %v", err) 1988 } 1989 defer o.delete() 1990 1991 checkFor(t, time.Second, 25*time.Millisecond, func() error { 1992 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toShip { 1993 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toShip) 1994 } 1995 return nil 1996 }) 1997 for nmsgs, _, _ := sub.Pending(); nmsgs > 0; nmsgs, _, _ = sub.Pending() { 1998 sub.NextMsg(time.Second) 1999 } 2000 if nmsgs, _, _ := sub.Pending(); nmsgs != 0 { 2001 t.Fatalf("Expected no pending, got %d", nmsgs) 2002 } 2003 2004 // Get all new 2005 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, FilterSubject: "orders.*.NEW"}) 2006 if err != nil { 2007 t.Fatalf("Expected no error with registered interest, got %v", err) 2008 } 2009 defer o.delete() 2010 2011 checkFor(t, time.Second, 25*time.Millisecond, func() error { 2012 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 2013 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 2014 } 2015 return nil 2016 }) 2017 for nmsgs, _, _ := sub.Pending(); nmsgs > 0; nmsgs, _, _ = sub.Pending() { 2018 sub.NextMsg(time.Second) 2019 } 2020 if nmsgs, _, _ := sub.Pending(); nmsgs != 0 { 2021 t.Fatalf("Expected no pending, got %d", nmsgs) 2022 } 2023 2024 // Now grab a single orderId that has shipped, so we should have two messages. 2025 var orderId int 2026 for orderId = range shipped { 2027 break 2028 } 2029 subj := fmt.Sprintf("orders.%d.*", orderId) 2030 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, FilterSubject: subj}) 2031 if err != nil { 2032 t.Fatalf("Expected no error with registered interest, got %v", err) 2033 } 2034 defer o.delete() 2035 2036 checkFor(t, time.Second, 25*time.Millisecond, func() error { 2037 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 2 { 2038 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, 2) 2039 } 2040 return nil 2041 }) 2042 }) 2043 } 2044 } 2045 2046 func TestJetStreamWorkQueueAckAndNext(t *testing.T) { 2047 cases := []struct { 2048 name string 2049 mconfig *StreamConfig 2050 }{ 2051 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 2052 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 2053 } 2054 for _, c := range cases { 2055 t.Run(c.name, func(t *testing.T) { 2056 s := RunBasicJetStreamServer(t) 2057 defer s.Shutdown() 2058 2059 mset, err := s.GlobalAccount().addStream(c.mconfig) 2060 if err != nil { 2061 t.Fatalf("Unexpected error adding stream: %v", err) 2062 } 2063 defer mset.delete() 2064 2065 // Create basic work queue mode consumer. 2066 oname := "WQ" 2067 o, err := mset.addConsumer(workerModeConfig(oname)) 2068 if err != nil { 2069 t.Fatalf("Expected no error with registered interest, got %v", err) 2070 } 2071 defer o.delete() 2072 2073 if o.nextSeq() != 1 { 2074 t.Fatalf("Expected to be starting at sequence 1") 2075 } 2076 2077 nc := clientConnectToServer(t, s) 2078 defer nc.Close() 2079 2080 // Now load up some messages. 2081 toSend := 100 2082 sendSubj := "bar" 2083 for i := 0; i < toSend; i++ { 2084 sendStreamMsg(t, nc, sendSubj, "Hello World!") 2085 } 2086 state := mset.state() 2087 if state.Msgs != uint64(toSend) { 2088 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2089 } 2090 2091 sub, _ := nc.SubscribeSync(nats.NewInbox()) 2092 defer sub.Unsubscribe() 2093 2094 // Kick things off. 2095 // For normal work queue semantics, you send requests to the subject with stream and consumer name. 2096 // We will do this to start it off then use ack+next to get other messages. 2097 nc.PublishRequest(o.requestNextMsgSubject(), sub.Subject, nil) 2098 2099 for i := 0; i < toSend; i++ { 2100 m, err := sub.NextMsg(time.Second) 2101 if err != nil { 2102 t.Fatalf("Unexpected error waiting for messages: %v", err) 2103 } 2104 2105 if !bytes.Equal(m.Data, []byte("Hello World!")) { 2106 t.Fatalf("Got an invalid message from the stream: %q", m.Data) 2107 } 2108 2109 nc.PublishRequest(m.Reply, sub.Subject, AckNext) 2110 } 2111 }) 2112 } 2113 } 2114 2115 func TestJetStreamWorkQueueRequestBatch(t *testing.T) { 2116 cases := []struct { 2117 name string 2118 mconfig *StreamConfig 2119 }{ 2120 {"MemoryStore", &StreamConfig{Name: "MY_MSG_SET", Storage: MemoryStorage, Subjects: []string{"foo", "bar"}}}, 2121 {"FileStore", &StreamConfig{Name: "MY_MSG_SET", Storage: FileStorage, Subjects: []string{"foo", "bar"}}}, 2122 } 2123 for _, c := range cases { 2124 t.Run(c.name, func(t *testing.T) { 2125 s := RunBasicJetStreamServer(t) 2126 defer s.Shutdown() 2127 2128 mset, err := s.GlobalAccount().addStream(c.mconfig) 2129 if err != nil { 2130 t.Fatalf("Unexpected error adding stream: %v", err) 2131 } 2132 defer mset.delete() 2133 2134 // Create basic work queue mode consumer. 2135 oname := "WQ" 2136 o, err := mset.addConsumer(workerModeConfig(oname)) 2137 if err != nil { 2138 t.Fatalf("Expected no error with registered interest, got %v", err) 2139 } 2140 defer o.delete() 2141 2142 if o.nextSeq() != 1 { 2143 t.Fatalf("Expected to be starting at sequence 1") 2144 } 2145 2146 nc := clientConnectToServer(t, s) 2147 defer nc.Close() 2148 2149 // Now load up some messages. 2150 toSend := 100 2151 sendSubj := "bar" 2152 for i := 0; i < toSend; i++ { 2153 sendStreamMsg(t, nc, sendSubj, "Hello World!") 2154 } 2155 state := mset.state() 2156 if state.Msgs != uint64(toSend) { 2157 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2158 } 2159 2160 sub, _ := nc.SubscribeSync(nats.NewInbox()) 2161 defer sub.Unsubscribe() 2162 2163 // For normal work queue semantics, you send requests to the subject with stream and consumer name. 2164 // We will do this to start it off then use ack+next to get other messages. 2165 // Kick things off with batch size of 50. 2166 batchSize := 50 2167 nc.PublishRequest(o.requestNextMsgSubject(), sub.Subject, []byte(strconv.Itoa(batchSize))) 2168 2169 // We should receive batchSize with no acks or additional requests. 2170 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 2171 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != batchSize { 2172 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, batchSize) 2173 } 2174 return nil 2175 }) 2176 2177 // Now queue up the request without messages and add them after. 2178 sub, _ = nc.SubscribeSync(nats.NewInbox()) 2179 defer sub.Unsubscribe() 2180 mset.purge(nil) 2181 2182 nc.PublishRequest(o.requestNextMsgSubject(), sub.Subject, []byte(strconv.Itoa(batchSize))) 2183 nc.Flush() // Make sure its registered. 2184 2185 for i := 0; i < toSend; i++ { 2186 sendStreamMsg(t, nc, sendSubj, "Hello World!") 2187 } 2188 2189 // We should receive batchSize with no acks or additional requests. 2190 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 2191 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != batchSize { 2192 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, batchSize) 2193 } 2194 return nil 2195 }) 2196 }) 2197 } 2198 } 2199 2200 func TestJetStreamWorkQueueRetentionStream(t *testing.T) { 2201 cases := []struct { 2202 name string 2203 mconfig *StreamConfig 2204 }{ 2205 {name: "MemoryStore", mconfig: &StreamConfig{ 2206 Name: "MWQ", 2207 Storage: MemoryStorage, 2208 Subjects: []string{"MY_WORK_QUEUE.>"}, 2209 Retention: WorkQueuePolicy}, 2210 }, 2211 {name: "FileStore", mconfig: &StreamConfig{ 2212 Name: "MWQ", 2213 Storage: FileStorage, 2214 Subjects: []string{"MY_WORK_QUEUE.>"}, 2215 Retention: WorkQueuePolicy}, 2216 }, 2217 } 2218 for _, c := range cases { 2219 t.Run(c.name, func(t *testing.T) { 2220 s := RunBasicJetStreamServer(t) 2221 defer s.Shutdown() 2222 2223 mset, err := s.GlobalAccount().addStream(c.mconfig) 2224 if err != nil { 2225 t.Fatalf("Unexpected error adding stream: %v", err) 2226 } 2227 defer mset.delete() 2228 2229 // This type of stream has restrictions which we will test here. 2230 // DeliverAll is only start mode allowed. 2231 if _, err := mset.addConsumer(&ConsumerConfig{DeliverPolicy: DeliverLast}); err == nil { 2232 t.Fatalf("Expected an error with anything but DeliverAll") 2233 } 2234 2235 // We will create a non-partitioned consumer. This should succeed. 2236 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit}) 2237 require_NoError(t, err) 2238 defer o.delete() 2239 2240 // Now if we create another this should fail, only can have one non-partitioned. 2241 if _, err := mset.addConsumer(&ConsumerConfig{}); err == nil { 2242 t.Fatalf("Expected an error on attempt for second consumer for a workqueue") 2243 } 2244 o.delete() 2245 2246 if numo := mset.numConsumers(); numo != 0 { 2247 t.Fatalf("Expected to have zero consumers, got %d", numo) 2248 } 2249 2250 // Now add in an consumer that has a partition. 2251 pindex := 1 2252 pConfig := func(pname string) *ConsumerConfig { 2253 dname := fmt.Sprintf("PPBO-%d", pindex) 2254 pindex += 1 2255 return &ConsumerConfig{Durable: dname, FilterSubject: pname, AckPolicy: AckExplicit} 2256 } 2257 o, err = mset.addConsumer(pConfig("MY_WORK_QUEUE.A")) 2258 require_NoError(t, err) 2259 defer o.delete() 2260 2261 // Now creating another with separate partition should work. 2262 o2, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.B")) 2263 require_NoError(t, err) 2264 defer o2.delete() 2265 2266 // Anything that would overlap should fail though. 2267 if _, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.A")); err == nil { 2268 t.Fatalf("Expected an error on attempt for partitioned consumer for a workqueue") 2269 } 2270 if _, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.B")); err == nil { 2271 t.Fatalf("Expected an error on attempt for partitioned consumer for a workqueue") 2272 } 2273 2274 o3, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.C")) 2275 require_NoError(t, err) 2276 2277 o.delete() 2278 o2.delete() 2279 o3.delete() 2280 2281 // Test with wildcards, first from wider to narrower 2282 o, err = mset.addConsumer(pConfig("MY_WORK_QUEUE.>")) 2283 require_NoError(t, err) 2284 if _, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.*.BAR")); err == nil { 2285 t.Fatalf("Expected an error on attempt for partitioned consumer for a workqueue") 2286 } 2287 o.delete() 2288 2289 // Now from narrower to wider 2290 o, err = mset.addConsumer(pConfig("MY_WORK_QUEUE.*.BAR")) 2291 require_NoError(t, err) 2292 if _, err := mset.addConsumer(pConfig("MY_WORK_QUEUE.>")); err == nil { 2293 t.Fatalf("Expected an error on attempt for partitioned consumer for a workqueue") 2294 } 2295 o.delete() 2296 2297 // Push based will be allowed now, including ephemerals. 2298 // They can not overlap etc meaning same rules as above apply. 2299 o4, err := mset.addConsumer(&ConsumerConfig{ 2300 Durable: "DURABLE", 2301 DeliverSubject: "SOME.SUBJ", 2302 AckPolicy: AckExplicit, 2303 }) 2304 if err != nil { 2305 t.Fatalf("Unexpected Error: %v", err) 2306 } 2307 defer o4.delete() 2308 2309 // Now try to create an ephemeral 2310 nc := clientConnectToServer(t, s) 2311 defer nc.Close() 2312 2313 sub, _ := nc.SubscribeSync(nats.NewInbox()) 2314 defer sub.Unsubscribe() 2315 nc.Flush() 2316 2317 // This should fail at first due to conflict above. 2318 ephCfg := &ConsumerConfig{DeliverSubject: sub.Subject, AckPolicy: AckExplicit} 2319 if _, err := mset.addConsumer(ephCfg); err == nil { 2320 t.Fatalf("Expected an error ") 2321 } 2322 // Delete of o4 should clear. 2323 o4.delete() 2324 o5, err := mset.addConsumer(ephCfg) 2325 if err != nil { 2326 t.Fatalf("Unexpected Error: %v", err) 2327 } 2328 defer o5.delete() 2329 }) 2330 } 2331 } 2332 2333 func TestJetStreamAckAllRedelivery(t *testing.T) { 2334 cases := []struct { 2335 name string 2336 mconfig *StreamConfig 2337 }{ 2338 {"MemoryStore", &StreamConfig{Name: "MY_S22", Storage: MemoryStorage}}, 2339 {"FileStore", &StreamConfig{Name: "MY_S22", Storage: FileStorage}}, 2340 } 2341 for _, c := range cases { 2342 t.Run(c.name, func(t *testing.T) { 2343 s := RunBasicJetStreamServer(t) 2344 defer s.Shutdown() 2345 2346 mset, err := s.GlobalAccount().addStream(c.mconfig) 2347 if err != nil { 2348 t.Fatalf("Unexpected error adding stream: %v", err) 2349 } 2350 defer mset.delete() 2351 2352 nc := clientConnectToServer(t, s) 2353 defer nc.Close() 2354 2355 // Now load up some messages. 2356 toSend := 100 2357 for i := 0; i < toSend; i++ { 2358 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 2359 } 2360 state := mset.state() 2361 if state.Msgs != uint64(toSend) { 2362 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2363 } 2364 2365 sub, _ := nc.SubscribeSync(nats.NewInbox()) 2366 defer sub.Unsubscribe() 2367 nc.Flush() 2368 2369 o, err := mset.addConsumer(&ConsumerConfig{ 2370 DeliverSubject: sub.Subject, 2371 AckWait: 50 * time.Millisecond, 2372 AckPolicy: AckAll, 2373 }) 2374 if err != nil { 2375 t.Fatalf("Unexpected error adding consumer: %v", err) 2376 } 2377 defer o.delete() 2378 2379 // Wait for messages. 2380 // We will do 5 redeliveries. 2381 for i := 1; i <= 5; i++ { 2382 checkFor(t, 500*time.Millisecond, 10*time.Millisecond, func() error { 2383 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend*i { 2384 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend*i) 2385 } 2386 return nil 2387 }) 2388 } 2389 // Stop redeliveries. 2390 o.delete() 2391 2392 // Now make sure that they are all redelivered in order for each redelivered batch. 2393 for l := 1; l <= 5; l++ { 2394 for i := 1; i <= toSend; i++ { 2395 m, _ := sub.NextMsg(time.Second) 2396 if seq := o.streamSeqFromReply(m.Reply); seq != uint64(i) { 2397 t.Fatalf("Expected stream sequence of %d, got %d", i, seq) 2398 } 2399 } 2400 } 2401 }) 2402 } 2403 } 2404 2405 func TestJetStreamAckReplyStreamPending(t *testing.T) { 2406 msc := StreamConfig{ 2407 Name: "MY_WQ", 2408 Subjects: []string{"foo.*"}, 2409 Storage: MemoryStorage, 2410 MaxAge: 1 * time.Second, 2411 Retention: WorkQueuePolicy, 2412 } 2413 fsc := msc 2414 fsc.Storage = FileStorage 2415 2416 cases := []struct { 2417 name string 2418 mconfig *StreamConfig 2419 }{ 2420 {"MemoryStore", &msc}, 2421 {"FileStore", &fsc}, 2422 } 2423 for _, c := range cases { 2424 t.Run(c.name, func(t *testing.T) { 2425 s := RunBasicJetStreamServer(t) 2426 defer s.Shutdown() 2427 2428 mset, err := s.GlobalAccount().addStream(c.mconfig) 2429 if err != nil { 2430 t.Fatalf("Unexpected error adding stream: %v", err) 2431 } 2432 defer mset.delete() 2433 2434 nc := clientConnectToServer(t, s) 2435 defer nc.Close() 2436 2437 // Now load up some messages. 2438 toSend := 100 2439 for i := 0; i < toSend; i++ { 2440 sendStreamMsg(t, nc, "foo.1", "Hello World!") 2441 } 2442 nc.Flush() 2443 2444 state := mset.state() 2445 if state.Msgs != uint64(toSend) { 2446 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2447 } 2448 2449 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit}) 2450 require_NoError(t, err) 2451 defer o.delete() 2452 2453 expectPending := func(ep int) { 2454 t.Helper() 2455 // Now check consumer info. 2456 checkFor(t, time.Second, 10*time.Millisecond, func() error { 2457 if info, pep := o.info(), ep+1; int(info.NumPending) != pep { 2458 return fmt.Errorf("Expected consumer info pending of %d, got %d", pep, info.NumPending) 2459 } 2460 return nil 2461 }) 2462 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 2463 if err != nil { 2464 t.Fatalf("Unexpected error: %v", err) 2465 } 2466 _, _, _, _, pending := replyInfo(m.Reply) 2467 if pending != uint64(ep) { 2468 t.Fatalf("Expected ack reply pending of %d, got %d - reply: %q", ep, pending, m.Reply) 2469 } 2470 } 2471 2472 expectPending(toSend - 1) 2473 // Send some more while we are connected. 2474 for i := 0; i < toSend; i++ { 2475 sendStreamMsg(t, nc, "foo.1", "Hello World!") 2476 } 2477 nc.Flush() 2478 2479 expectPending(toSend*2 - 2) 2480 // Purge and send a new one. 2481 mset.purge(nil) 2482 nc.Flush() 2483 2484 sendStreamMsg(t, nc, "foo.1", "Hello World!") 2485 expectPending(0) 2486 for i := 0; i < toSend; i++ { 2487 sendStreamMsg(t, nc, "foo.22", "Hello World!") 2488 } 2489 expectPending(toSend - 1) // 201 2490 // Test that delete will not register for consumed messages. 2491 mset.removeMsg(mset.state().FirstSeq) 2492 expectPending(toSend - 2) // 202 2493 // Now remove one that has not been delivered. 2494 mset.removeMsg(250) 2495 expectPending(toSend - 4) // 203 2496 2497 // Test Expiration. 2498 mset.purge(nil) 2499 for i := 0; i < toSend; i++ { 2500 sendStreamMsg(t, nc, "foo.1", "Hello World!") 2501 } 2502 nc.Flush() 2503 2504 // Wait for expiration to kick in. 2505 checkFor(t, 5*time.Second, time.Second, func() error { 2506 if state := mset.state(); state.Msgs != 0 { 2507 return fmt.Errorf("Stream still has messages") 2508 } 2509 return nil 2510 }) 2511 sendStreamMsg(t, nc, "foo.33", "Hello World!") 2512 expectPending(0) 2513 2514 // Now do filtered consumers. 2515 o.delete() 2516 o, err = mset.addConsumer(&ConsumerConfig{Durable: "PBO-FILTERED", AckPolicy: AckExplicit, FilterSubject: "foo.22"}) 2517 require_NoError(t, err) 2518 defer o.delete() 2519 2520 for i := 0; i < toSend; i++ { 2521 sendStreamMsg(t, nc, "foo.33", "Hello World!") 2522 } 2523 nc.Flush() 2524 2525 if info := o.info(); info.NumPending != 0 { 2526 t.Fatalf("Expected no pending, got %d", info.NumPending) 2527 } 2528 // Now send one message that will match us. 2529 sendStreamMsg(t, nc, "foo.22", "Hello World!") 2530 expectPending(0) 2531 sendStreamMsg(t, nc, "foo.22", "Hello World!") // 504 2532 sendStreamMsg(t, nc, "foo.22", "Hello World!") // 505 2533 sendStreamMsg(t, nc, "foo.22", "Hello World!") // 506 2534 sendStreamMsg(t, nc, "foo.22", "Hello World!") // 507 2535 expectPending(3) 2536 mset.removeMsg(506) 2537 expectPending(1) 2538 for i := 0; i < toSend; i++ { 2539 sendStreamMsg(t, nc, "foo.22", "Hello World!") 2540 } 2541 nc.Flush() 2542 expectPending(100) 2543 mset.purge(nil) 2544 sendStreamMsg(t, nc, "foo.22", "Hello World!") 2545 expectPending(0) 2546 }) 2547 } 2548 } 2549 2550 func TestJetStreamAckReplyStreamPendingWithAcks(t *testing.T) { 2551 msc := StreamConfig{ 2552 Name: "MY_STREAM", 2553 Subjects: []string{"foo", "bar", "baz"}, 2554 Storage: MemoryStorage, 2555 } 2556 fsc := msc 2557 fsc.Storage = FileStorage 2558 2559 cases := []struct { 2560 name string 2561 mconfig *StreamConfig 2562 }{ 2563 {"MemoryStore", &msc}, 2564 {"FileStore", &fsc}, 2565 } 2566 for _, c := range cases { 2567 t.Run(c.name, func(t *testing.T) { 2568 s := RunBasicJetStreamServer(t) 2569 defer s.Shutdown() 2570 2571 mset, err := s.GlobalAccount().addStream(c.mconfig) 2572 if err != nil { 2573 t.Fatalf("Unexpected error adding stream: %v", err) 2574 } 2575 defer mset.delete() 2576 2577 nc := clientConnectToServer(t, s) 2578 defer nc.Close() 2579 2580 // Now load up some messages. 2581 toSend := 500 2582 for i := 0; i < toSend; i++ { 2583 sendStreamMsg(t, nc, "foo", "Hello Foo!") 2584 sendStreamMsg(t, nc, "bar", "Hello Bar!") 2585 sendStreamMsg(t, nc, "baz", "Hello Baz!") 2586 } 2587 state := mset.state() 2588 if state.Msgs != uint64(toSend*3) { 2589 t.Fatalf("Expected %d messages, got %d", toSend*3, state.Msgs) 2590 } 2591 dsubj := "_d_" 2592 o, err := mset.addConsumer(&ConsumerConfig{ 2593 Durable: "D-1", 2594 AckPolicy: AckExplicit, 2595 FilterSubject: "foo", 2596 DeliverSubject: dsubj, 2597 }) 2598 require_NoError(t, err) 2599 defer o.delete() 2600 2601 if info := o.info(); int(info.NumPending) != toSend { 2602 t.Fatalf("Expected consumer info pending of %d, got %d", toSend, info.NumPending) 2603 } 2604 2605 sub, _ := nc.SubscribeSync(dsubj) 2606 defer sub.Unsubscribe() 2607 2608 checkFor(t, 500*time.Millisecond, 10*time.Millisecond, func() error { 2609 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 2610 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 2611 } 2612 return nil 2613 }) 2614 2615 // Should be zero. 2616 if info := o.info(); int(info.NumPending) != 0 { 2617 t.Fatalf("Expected consumer info pending of %d, got %d", 0, info.NumPending) 2618 } else if info.NumAckPending != toSend { 2619 t.Fatalf("Expected %d to be pending acks, got %d", toSend, info.NumAckPending) 2620 } 2621 }) 2622 } 2623 } 2624 2625 func TestJetStreamWorkQueueAckWaitRedelivery(t *testing.T) { 2626 cases := []struct { 2627 name string 2628 mconfig *StreamConfig 2629 }{ 2630 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage, Retention: WorkQueuePolicy}}, 2631 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage, Retention: WorkQueuePolicy}}, 2632 } 2633 for _, c := range cases { 2634 t.Run(c.name, func(t *testing.T) { 2635 s := RunBasicJetStreamServer(t) 2636 defer s.Shutdown() 2637 2638 mset, err := s.GlobalAccount().addStream(c.mconfig) 2639 if err != nil { 2640 t.Fatalf("Unexpected error adding stream: %v", err) 2641 } 2642 defer mset.delete() 2643 2644 nc := clientConnectToServer(t, s) 2645 defer nc.Close() 2646 2647 // Now load up some messages. 2648 toSend := 100 2649 for i := 0; i < toSend; i++ { 2650 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 2651 } 2652 state := mset.state() 2653 if state.Msgs != uint64(toSend) { 2654 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2655 } 2656 2657 ackWait := 100 * time.Millisecond 2658 2659 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit, AckWait: ackWait}) 2660 require_NoError(t, err) 2661 defer o.delete() 2662 2663 sub, _ := nc.SubscribeSync(nats.NewInbox()) 2664 defer sub.Unsubscribe() 2665 2666 reqNextMsgSubj := o.requestNextMsgSubject() 2667 2668 // Consume all the messages. But do not ack. 2669 for i := 0; i < toSend; i++ { 2670 nc.PublishRequest(reqNextMsgSubj, sub.Subject, nil) 2671 if _, err := sub.NextMsg(time.Second); err != nil { 2672 t.Fatalf("Unexpected error waiting for messages: %v", err) 2673 } 2674 } 2675 2676 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 0 { 2677 t.Fatalf("Did not consume all messages, still have %d", nmsgs) 2678 } 2679 2680 // All messages should still be there. 2681 state = mset.state() 2682 if int(state.Msgs) != toSend { 2683 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2684 } 2685 2686 // Now consume and ack. 2687 for i := 1; i <= toSend; i++ { 2688 nc.PublishRequest(reqNextMsgSubj, sub.Subject, nil) 2689 m, err := sub.NextMsg(time.Second) 2690 if err != nil { 2691 t.Fatalf("Unexpected error waiting for message[%d]: %v", i, err) 2692 } 2693 sseq, dseq, dcount, _, _ := replyInfo(m.Reply) 2694 if sseq != uint64(i) { 2695 t.Fatalf("Expected set sequence of %d , got %d", i, sseq) 2696 } 2697 // Delivery sequences should always increase. 2698 if dseq != uint64(toSend+i) { 2699 t.Fatalf("Expected delivery sequence of %d , got %d", toSend+i, dseq) 2700 } 2701 if dcount == 1 { 2702 t.Fatalf("Expected these to be marked as redelivered") 2703 } 2704 // Ack the message here. 2705 m.AckSync() 2706 } 2707 2708 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 0 { 2709 t.Fatalf("Did not consume all messages, still have %d", nmsgs) 2710 } 2711 2712 // Flush acks 2713 nc.Flush() 2714 2715 // Now check the mset as well, since we have a WorkQueue retention policy this should be empty. 2716 if state := mset.state(); state.Msgs != 0 { 2717 t.Fatalf("Expected no messages, got %d", state.Msgs) 2718 } 2719 }) 2720 } 2721 } 2722 2723 func TestJetStreamWorkQueueNakRedelivery(t *testing.T) { 2724 cases := []struct { 2725 name string 2726 mconfig *StreamConfig 2727 }{ 2728 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage, Retention: WorkQueuePolicy}}, 2729 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage, Retention: WorkQueuePolicy}}, 2730 } 2731 for _, c := range cases { 2732 t.Run(c.name, func(t *testing.T) { 2733 s := RunBasicJetStreamServer(t) 2734 defer s.Shutdown() 2735 2736 mset, err := s.GlobalAccount().addStream(c.mconfig) 2737 if err != nil { 2738 t.Fatalf("Unexpected error adding stream: %v", err) 2739 } 2740 defer mset.delete() 2741 2742 nc := clientConnectToServer(t, s) 2743 defer nc.Close() 2744 2745 // Now load up some messages. 2746 toSend := 10 2747 for i := 0; i < toSend; i++ { 2748 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 2749 } 2750 state := mset.state() 2751 if state.Msgs != uint64(toSend) { 2752 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2753 } 2754 2755 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit}) 2756 require_NoError(t, err) 2757 defer o.delete() 2758 2759 getMsg := func(sseq, dseq int) *nats.Msg { 2760 t.Helper() 2761 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 2762 if err != nil { 2763 t.Fatalf("Unexpected error: %v", err) 2764 } 2765 rsseq, rdseq, _, _, _ := replyInfo(m.Reply) 2766 if rdseq != uint64(dseq) { 2767 t.Fatalf("Expected delivered sequence of %d , got %d", dseq, rdseq) 2768 } 2769 if rsseq != uint64(sseq) { 2770 t.Fatalf("Expected store sequence of %d , got %d", sseq, rsseq) 2771 } 2772 return m 2773 } 2774 2775 for i := 1; i <= 5; i++ { 2776 m := getMsg(i, i) 2777 // Ack the message here. 2778 m.Respond(nil) 2779 } 2780 2781 // Grab #6 2782 m := getMsg(6, 6) 2783 // NAK this one and make sure its processed. 2784 m.Respond(AckNak) 2785 nc.Flush() 2786 2787 // When we request again should be store sequence 6 again. 2788 getMsg(6, 7) 2789 // Then we should get 7, 8, etc. 2790 getMsg(7, 8) 2791 getMsg(8, 9) 2792 }) 2793 } 2794 } 2795 2796 func TestJetStreamWorkQueueWorkingIndicator(t *testing.T) { 2797 cases := []struct { 2798 name string 2799 mconfig *StreamConfig 2800 }{ 2801 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage, Retention: WorkQueuePolicy}}, 2802 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage, Retention: WorkQueuePolicy}}, 2803 } 2804 for _, c := range cases { 2805 t.Run(c.name, func(t *testing.T) { 2806 s := RunBasicJetStreamServer(t) 2807 defer s.Shutdown() 2808 2809 mset, err := s.GlobalAccount().addStream(c.mconfig) 2810 if err != nil { 2811 t.Fatalf("Unexpected error adding stream: %v", err) 2812 } 2813 defer mset.delete() 2814 2815 nc := clientConnectToServer(t, s) 2816 defer nc.Close() 2817 2818 // Now load up some messages. 2819 toSend := 2 2820 for i := 0; i < toSend; i++ { 2821 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 2822 } 2823 state := mset.state() 2824 if state.Msgs != uint64(toSend) { 2825 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2826 } 2827 2828 ackWait := 100 * time.Millisecond 2829 2830 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit, AckWait: ackWait}) 2831 require_NoError(t, err) 2832 defer o.delete() 2833 2834 getMsg := func(sseq, dseq int) *nats.Msg { 2835 t.Helper() 2836 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 2837 if err != nil { 2838 t.Fatalf("Unexpected error: %v", err) 2839 } 2840 rsseq, rdseq, _, _, _ := replyInfo(m.Reply) 2841 if rdseq != uint64(dseq) { 2842 t.Fatalf("Expected delivered sequence of %d , got %d", dseq, rdseq) 2843 } 2844 if rsseq != uint64(sseq) { 2845 t.Fatalf("Expected store sequence of %d , got %d", sseq, rsseq) 2846 } 2847 return m 2848 } 2849 2850 getMsg(1, 1) 2851 // Now wait past ackWait 2852 time.Sleep(ackWait * 2) 2853 2854 // We should get 1 back. 2855 m := getMsg(1, 2) 2856 2857 // Now let's take longer than ackWait to process but signal we are working on the message. 2858 timeout := time.Now().Add(3 * ackWait) 2859 for time.Now().Before(timeout) { 2860 m.Respond(AckProgress) 2861 nc.Flush() 2862 time.Sleep(ackWait / 5) 2863 } 2864 // We should get 2 here, not 1 since we have indicated we are working on it. 2865 m2 := getMsg(2, 3) 2866 time.Sleep(ackWait / 2) 2867 m2.Respond(AckProgress) 2868 2869 // Now should get 1 back then 2. 2870 m = getMsg(1, 4) 2871 m.Respond(nil) 2872 getMsg(2, 5) 2873 }) 2874 } 2875 } 2876 2877 func TestJetStreamWorkQueueTerminateDelivery(t *testing.T) { 2878 cases := []struct { 2879 name string 2880 mconfig *StreamConfig 2881 }{ 2882 {"MemoryStore", &StreamConfig{Name: "MY_WQ", Storage: MemoryStorage, Retention: WorkQueuePolicy}}, 2883 {"FileStore", &StreamConfig{Name: "MY_WQ", Storage: FileStorage, Retention: WorkQueuePolicy}}, 2884 } 2885 for _, c := range cases { 2886 t.Run(c.name, func(t *testing.T) { 2887 s := RunBasicJetStreamServer(t) 2888 defer s.Shutdown() 2889 2890 mset, err := s.GlobalAccount().addStream(c.mconfig) 2891 if err != nil { 2892 t.Fatalf("Unexpected error adding stream: %v", err) 2893 } 2894 defer mset.delete() 2895 2896 nc := clientConnectToServer(t, s) 2897 defer nc.Close() 2898 2899 // Now load up some messages. 2900 toSend := 22 2901 for i := 0; i < toSend; i++ { 2902 sendStreamMsg(t, nc, c.mconfig.Name, "Hello World!") 2903 } 2904 state := mset.state() 2905 if state.Msgs != uint64(toSend) { 2906 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 2907 } 2908 2909 ackWait := 25 * time.Millisecond 2910 2911 o, err := mset.addConsumer(&ConsumerConfig{Durable: "PBO", AckPolicy: AckExplicit, AckWait: ackWait}) 2912 require_NoError(t, err) 2913 defer o.delete() 2914 2915 getMsg := func(sseq, dseq int) *nats.Msg { 2916 t.Helper() 2917 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 2918 if err != nil { 2919 t.Fatalf("Unexpected error: %v", err) 2920 } 2921 rsseq, rdseq, _, _, _ := replyInfo(m.Reply) 2922 if rdseq != uint64(dseq) { 2923 t.Fatalf("Expected delivered sequence of %d , got %d", dseq, rdseq) 2924 } 2925 if rsseq != uint64(sseq) { 2926 t.Fatalf("Expected store sequence of %d , got %d", sseq, rsseq) 2927 } 2928 return m 2929 } 2930 2931 // Make sure we get the correct advisory 2932 sub, _ := nc.SubscribeSync(JSAdvisoryConsumerMsgTerminatedPre + ".>") 2933 defer sub.Unsubscribe() 2934 2935 getMsg(1, 1) 2936 // Now wait past ackWait 2937 time.Sleep(ackWait * 2) 2938 2939 // We should get 1 back. 2940 m := getMsg(1, 2) 2941 // Now terminate 2942 m.Respond([]byte(fmt.Sprintf("%s with reason", string(AckTerm)))) 2943 time.Sleep(ackWait * 2) 2944 2945 // We should get 2 here, not 1 since we have indicated we wanted to terminate. 2946 getMsg(2, 3) 2947 2948 // Check advisory was delivered. 2949 am, err := sub.NextMsg(time.Second) 2950 if err != nil { 2951 t.Fatalf("Unexpected error: %v", err) 2952 } 2953 var adv JSConsumerDeliveryTerminatedAdvisory 2954 json.Unmarshal(am.Data, &adv) 2955 if adv.Stream != "MY_WQ" { 2956 t.Fatalf("Expected stream of %s, got %s", "MY_WQ", adv.Stream) 2957 } 2958 if adv.Consumer != "PBO" { 2959 t.Fatalf("Expected consumer of %s, got %s", "PBO", adv.Consumer) 2960 } 2961 if adv.StreamSeq != 1 { 2962 t.Fatalf("Expected stream sequence of %d, got %d", 1, adv.StreamSeq) 2963 } 2964 if adv.ConsumerSeq != 2 { 2965 t.Fatalf("Expected consumer sequence of %d, got %d", 2, adv.ConsumerSeq) 2966 } 2967 if adv.Deliveries != 2 { 2968 t.Fatalf("Expected delivery count of %d, got %d", 2, adv.Deliveries) 2969 } 2970 if adv.Reason != "with reason" { 2971 t.Fatalf("Advisory did not have a reason") 2972 } 2973 }) 2974 } 2975 } 2976 2977 func TestJetStreamConsumerAckAck(t *testing.T) { 2978 s := RunBasicJetStreamServer(t) 2979 defer s.Shutdown() 2980 2981 mname := "ACK-ACK" 2982 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: MemoryStorage}) 2983 if err != nil { 2984 t.Fatalf("Unexpected error adding stream: %v", err) 2985 } 2986 defer mset.delete() 2987 2988 o, err := mset.addConsumer(&ConsumerConfig{Durable: "worker", AckPolicy: AckExplicit}) 2989 if err != nil { 2990 t.Fatalf("Expected no error with registered interest, got %v", err) 2991 } 2992 defer o.delete() 2993 rqn := o.requestNextMsgSubject() 2994 2995 nc := clientConnectToServer(t, s) 2996 defer nc.Close() 2997 2998 // 4 for number of ack protocols to test them all. 2999 for i := 0; i < 4; i++ { 3000 sendStreamMsg(t, nc, mname, "Hello World!") 3001 } 3002 3003 testAck := func(ackType []byte) { 3004 m, err := nc.Request(rqn, nil, 10*time.Millisecond) 3005 if err != nil { 3006 t.Fatalf("Unexpected error: %v", err) 3007 } 3008 // Send a request for the ack and make sure the server "ack's" the ack. 3009 if _, err := nc.Request(m.Reply, ackType, 10*time.Millisecond); err != nil { 3010 t.Fatalf("Unexpected error on ack/ack: %v", err) 3011 } 3012 } 3013 3014 testAck(AckAck) 3015 testAck(AckNak) 3016 testAck(AckProgress) 3017 testAck(AckTerm) 3018 } 3019 3020 func TestJetStreamAckNext(t *testing.T) { 3021 s := RunBasicJetStreamServer(t) 3022 defer s.Shutdown() 3023 3024 mname := "ACKNXT" 3025 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: MemoryStorage}) 3026 if err != nil { 3027 t.Fatalf("Unexpected error adding stream: %v", err) 3028 } 3029 defer mset.delete() 3030 3031 o, err := mset.addConsumer(&ConsumerConfig{Durable: "worker", AckPolicy: AckExplicit}) 3032 if err != nil { 3033 t.Fatalf("Expected no error with registered interest, got %v", err) 3034 } 3035 defer o.delete() 3036 3037 nc := clientConnectToServer(t, s) 3038 defer nc.Close() 3039 3040 for i := 0; i < 12; i++ { 3041 sendStreamMsg(t, nc, mname, fmt.Sprintf("msg %d", i)) 3042 } 3043 3044 q := make(chan *nats.Msg, 10) 3045 sub, err := nc.ChanSubscribe(nats.NewInbox(), q) 3046 if err != nil { 3047 t.Fatalf("SubscribeSync failed: %s", err) 3048 } 3049 3050 nc.PublishRequest(o.requestNextMsgSubject(), sub.Subject, []byte("1")) 3051 3052 // normal next should imply 1 3053 msg := <-q 3054 err = msg.RespondMsg(&nats.Msg{Reply: sub.Subject, Subject: msg.Reply, Data: AckNext}) 3055 if err != nil { 3056 t.Fatalf("RespondMsg failed: %s", err) 3057 } 3058 3059 // read 1 message and check ack was done etc 3060 msg = <-q 3061 if len(q) != 0 { 3062 t.Fatalf("Expected empty q got %d", len(q)) 3063 } 3064 if o.info().AckFloor.Stream != 1 { 3065 t.Fatalf("First message was not acknowledged") 3066 } 3067 if !bytes.Equal(msg.Data, []byte("msg 1")) { 3068 t.Fatalf("wrong message received, expected: msg 1 got %q", msg.Data) 3069 } 3070 3071 // now ack and request 5 more using a naked number 3072 err = msg.RespondMsg(&nats.Msg{Reply: sub.Subject, Subject: msg.Reply, Data: append(AckNext, []byte(" 5")...)}) 3073 if err != nil { 3074 t.Fatalf("RespondMsg failed: %s", err) 3075 } 3076 3077 getMsgs := func(start, count int) { 3078 t.Helper() 3079 3080 ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) 3081 defer cancel() 3082 3083 for i := start; i < count+1; i++ { 3084 select { 3085 case msg := <-q: 3086 expect := fmt.Sprintf("msg %d", i+1) 3087 if !bytes.Equal(msg.Data, []byte(expect)) { 3088 t.Fatalf("wrong message received, expected: %s got %#v", expect, msg) 3089 } 3090 case <-ctx.Done(): 3091 t.Fatalf("did not receive all messages") 3092 } 3093 } 3094 3095 } 3096 3097 getMsgs(1, 5) 3098 3099 // now ack and request 5 more using the full request 3100 err = msg.RespondMsg(&nats.Msg{Reply: sub.Subject, Subject: msg.Reply, Data: append(AckNext, []byte(`{"batch": 5}`)...)}) 3101 if err != nil { 3102 t.Fatalf("RespondMsg failed: %s", err) 3103 } 3104 3105 getMsgs(6, 10) 3106 3107 if o.info().AckFloor.Stream != 2 { 3108 t.Fatalf("second message was not acknowledged") 3109 } 3110 } 3111 3112 func TestJetStreamPublishDeDupe(t *testing.T) { 3113 s := RunBasicJetStreamServer(t) 3114 defer s.Shutdown() 3115 3116 mname := "DeDupe" 3117 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: FileStorage, MaxAge: time.Hour, Subjects: []string{"foo.*"}}) 3118 if err != nil { 3119 t.Fatalf("Unexpected error adding stream: %v", err) 3120 } 3121 defer mset.delete() 3122 3123 // Check Duplicates setting. 3124 duplicates := mset.config().Duplicates 3125 if duplicates != StreamDefaultDuplicatesWindow { 3126 t.Fatalf("Expected a default of %v, got %v", StreamDefaultDuplicatesWindow, duplicates) 3127 } 3128 3129 cfg := mset.config() 3130 // Make sure can't be negative. 3131 cfg.Duplicates = -25 * time.Millisecond 3132 if err := mset.update(&cfg); err == nil { 3133 t.Fatalf("Expected an error but got none") 3134 } 3135 // Make sure can't be longer than age if its set. 3136 cfg.Duplicates = 2 * time.Hour 3137 if err := mset.update(&cfg); err == nil { 3138 t.Fatalf("Expected an error but got none") 3139 } 3140 3141 nc := clientConnectToServer(t, s) 3142 defer nc.Close() 3143 3144 sendMsg := func(seq uint64, id, msg string) *PubAck { 3145 t.Helper() 3146 m := nats.NewMsg(fmt.Sprintf("foo.%d", seq)) 3147 m.Header.Add(JSMsgId, id) 3148 m.Data = []byte(msg) 3149 resp, _ := nc.RequestMsg(m, 100*time.Millisecond) 3150 if resp == nil { 3151 t.Fatalf("No response for %q, possible timeout?", msg) 3152 } 3153 pa := getPubAckResponse(resp.Data) 3154 if pa == nil || pa.Error != nil { 3155 t.Fatalf("Expected a JetStreamPubAck, got %q", resp.Data) 3156 } 3157 if pa.Sequence != seq { 3158 t.Fatalf("Did not get correct sequence in PubAck, expected %d, got %d", seq, pa.Sequence) 3159 } 3160 return pa.PubAck 3161 } 3162 3163 expect := func(n uint64) { 3164 t.Helper() 3165 state := mset.state() 3166 if state.Msgs != n { 3167 t.Fatalf("Expected %d messages, got %d", n, state.Msgs) 3168 } 3169 } 3170 3171 sendMsg(1, "AA", "Hello DeDupe!") 3172 sendMsg(2, "BB", "Hello DeDupe!") 3173 sendMsg(3, "CC", "Hello DeDupe!") 3174 sendMsg(4, "ZZ", "Hello DeDupe!") 3175 expect(4) 3176 3177 sendMsg(1, "AA", "Hello DeDupe!") 3178 sendMsg(2, "BB", "Hello DeDupe!") 3179 sendMsg(4, "ZZ", "Hello DeDupe!") 3180 expect(4) 3181 3182 cfg = mset.config() 3183 cfg.Duplicates = 100 * time.Millisecond 3184 if err := mset.update(&cfg); err != nil { 3185 t.Fatalf("Unexpected error: %v", err) 3186 } 3187 3188 nmids := func(expected int) { 3189 t.Helper() 3190 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 3191 if nids := mset.numMsgIds(); nids != expected { 3192 return fmt.Errorf("Expected %d message ids, got %d", expected, nids) 3193 } 3194 return nil 3195 }) 3196 } 3197 3198 nmids(4) 3199 time.Sleep(cfg.Duplicates * 2) 3200 3201 sendMsg(5, "AAA", "Hello DeDupe!") 3202 sendMsg(6, "BBB", "Hello DeDupe!") 3203 sendMsg(7, "CCC", "Hello DeDupe!") 3204 sendMsg(8, "DDD", "Hello DeDupe!") 3205 sendMsg(9, "ZZZ", "Hello DeDupe!") 3206 nmids(5) 3207 // Eventually will drop to zero. 3208 nmids(0) 3209 3210 // Now test server restart 3211 cfg.Duplicates = 30 * time.Minute 3212 if err := mset.update(&cfg); err != nil { 3213 t.Fatalf("Unexpected error: %v", err) 3214 } 3215 mset.purge(nil) 3216 3217 // Send 5 new messages. 3218 sendMsg(10, "AAAA", "Hello DeDupe!") 3219 sendMsg(11, "BBBB", "Hello DeDupe!") 3220 sendMsg(12, "CCCC", "Hello DeDupe!") 3221 sendMsg(13, "DDDD", "Hello DeDupe!") 3222 sendMsg(14, "EEEE", "Hello DeDupe!") 3223 3224 // Stop current 3225 sd := s.JetStreamConfig().StoreDir 3226 s.Shutdown() 3227 // Restart. 3228 s = RunJetStreamServerOnPort(-1, sd) 3229 defer s.Shutdown() 3230 3231 nc = clientConnectToServer(t, s) 3232 defer nc.Close() 3233 3234 mset, _ = s.GlobalAccount().lookupStream(mname) 3235 if nms := mset.state().Msgs; nms != 5 { 3236 t.Fatalf("Expected 5 restored messages, got %d", nms) 3237 } 3238 nmids(5) 3239 3240 // Send same and make sure duplicate detection still works. 3241 // Send 5 duplicate messages. 3242 sendMsg(10, "AAAA", "Hello DeDupe!") 3243 sendMsg(11, "BBBB", "Hello DeDupe!") 3244 sendMsg(12, "CCCC", "Hello DeDupe!") 3245 sendMsg(13, "DDDD", "Hello DeDupe!") 3246 sendMsg(14, "EEEE", "Hello DeDupe!") 3247 3248 if nms := mset.state().Msgs; nms != 5 { 3249 t.Fatalf("Expected 5 restored messages, got %d", nms) 3250 } 3251 nmids(5) 3252 3253 // Check we set duplicate properly. 3254 pa := sendMsg(10, "AAAA", "Hello DeDupe!") 3255 if !pa.Duplicate { 3256 t.Fatalf("Expected duplicate to be set") 3257 } 3258 3259 // Purge should NOT wipe the msgIds. They should still persist. 3260 mset.purge(nil) 3261 nmids(5) 3262 } 3263 3264 func getPubAckResponse(msg []byte) *JSPubAckResponse { 3265 var par JSPubAckResponse 3266 if err := json.Unmarshal(msg, &par); err != nil { 3267 return nil 3268 } 3269 return &par 3270 } 3271 3272 func TestJetStreamPublishExpect(t *testing.T) { 3273 s := RunBasicJetStreamServer(t) 3274 defer s.Shutdown() 3275 3276 mname := "EXPECT" 3277 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: FileStorage, MaxAge: time.Hour, Subjects: []string{"foo.*"}}) 3278 if err != nil { 3279 t.Fatalf("Unexpected error adding stream: %v", err) 3280 } 3281 defer mset.delete() 3282 3283 nc := clientConnectToServer(t, s) 3284 defer nc.Close() 3285 3286 // Test that we get no error when expected stream is correct. 3287 m := nats.NewMsg("foo.bar") 3288 m.Data = []byte("HELLO") 3289 m.Header.Set(JSExpectedStream, mname) 3290 resp, err := nc.RequestMsg(m, 100*time.Millisecond) 3291 require_NoError(t, err) 3292 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error != nil { 3293 t.Fatalf("Expected a valid JetStreamPubAck, got %q", resp.Data) 3294 } 3295 3296 // Now test that we get an error back when expecting a different stream. 3297 m.Header.Set(JSExpectedStream, "ORDERS") 3298 resp, err = nc.RequestMsg(m, 100*time.Millisecond) 3299 require_NoError(t, err) 3300 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error == nil { 3301 t.Fatalf("Expected an error, got %q", resp.Data) 3302 } 3303 3304 // Now test that we get an error back when expecting a different sequence number. 3305 m.Header.Set(JSExpectedStream, mname) 3306 m.Header.Set(JSExpectedLastSeq, "10") 3307 resp, err = nc.RequestMsg(m, 100*time.Millisecond) 3308 require_NoError(t, err) 3309 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error == nil { 3310 t.Fatalf("Expected an error, got %q", resp.Data) 3311 } 3312 3313 // Or if we expect that there are no messages by setting "0" as the expected last seq 3314 m.Header.Set(JSExpectedLastSeq, "0") 3315 resp, err = nc.RequestMsg(m, 100*time.Millisecond) 3316 require_NoError(t, err) 3317 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error == nil { 3318 t.Fatalf("Expected an error, got %q", resp.Data) 3319 } 3320 3321 // Now send a message with a message ID and make sure we can match that. 3322 m = nats.NewMsg("foo.bar") 3323 m.Data = []byte("HELLO") 3324 m.Header.Set(JSMsgId, "AAA") 3325 if _, err = nc.RequestMsg(m, 100*time.Millisecond); err != nil { 3326 t.Fatalf("Unexpected error: %v", err) 3327 } 3328 3329 // Now try again with new message ID but require last one to be 'BBB' 3330 m.Header.Set(JSMsgId, "ZZZ") 3331 m.Header.Set(JSExpectedLastMsgId, "BBB") 3332 resp, err = nc.RequestMsg(m, 100*time.Millisecond) 3333 require_NoError(t, err) 3334 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error == nil { 3335 t.Fatalf("Expected an error, got %q", resp.Data) 3336 } 3337 3338 // Restart the server and make sure we remember/rebuild last seq and last msgId. 3339 // Stop current 3340 sd := s.JetStreamConfig().StoreDir 3341 s.Shutdown() 3342 // Restart. 3343 s = RunJetStreamServerOnPort(-1, sd) 3344 defer s.Shutdown() 3345 3346 nc = clientConnectToServer(t, s) 3347 defer nc.Close() 3348 3349 // Our last sequence was 2 and last msgId was "AAA" 3350 m = nats.NewMsg("foo.baz") 3351 m.Data = []byte("HELLO AGAIN") 3352 m.Header.Set(JSExpectedLastSeq, "2") 3353 m.Header.Set(JSExpectedLastMsgId, "AAA") 3354 m.Header.Set(JSMsgId, "BBB") 3355 resp, err = nc.RequestMsg(m, 100*time.Millisecond) 3356 require_NoError(t, err) 3357 if pa := getPubAckResponse(resp.Data); pa == nil || pa.Error != nil { 3358 t.Fatalf("Expected a valid JetStreamPubAck, got %q", resp.Data) 3359 } 3360 } 3361 3362 func TestJetStreamPullConsumerRemoveInterest(t *testing.T) { 3363 s := RunBasicJetStreamServer(t) 3364 defer s.Shutdown() 3365 3366 mname := "MYS-PULL" 3367 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: MemoryStorage}) 3368 if err != nil { 3369 t.Fatalf("Unexpected error adding stream: %v", err) 3370 } 3371 defer mset.delete() 3372 3373 wcfg := &ConsumerConfig{Durable: "worker", AckPolicy: AckExplicit} 3374 o, err := mset.addConsumer(wcfg) 3375 if err != nil { 3376 t.Fatalf("Expected no error with registered interest, got %v", err) 3377 } 3378 rqn := o.requestNextMsgSubject() 3379 defer o.delete() 3380 3381 nc := clientConnectToServer(t, s) 3382 defer nc.Close() 3383 3384 // Ask for a message even though one is not there. This will queue us up for waiting. 3385 if _, err := nc.Request(rqn, nil, 10*time.Millisecond); err == nil { 3386 t.Fatalf("Expected an error, got none") 3387 } 3388 3389 // This is using new style request mechanism. so drop the connection itself to get rid of interest. 3390 nc.Close() 3391 3392 // Wait for client cleanup 3393 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 3394 if n := s.NumClients(); err != nil || n != 0 { 3395 return fmt.Errorf("Still have %d clients", n) 3396 } 3397 return nil 3398 }) 3399 3400 nc = clientConnectToServer(t, s) 3401 defer nc.Close() 3402 3403 // Send a message 3404 sendStreamMsg(t, nc, mname, "Hello World!") 3405 3406 msg, err := nc.Request(rqn, nil, time.Second) 3407 require_NoError(t, err) 3408 _, dseq, dc, _, _ := replyInfo(msg.Reply) 3409 if dseq != 1 { 3410 t.Fatalf("Expected consumer sequence of 1, got %d", dseq) 3411 } 3412 if dc != 1 { 3413 t.Fatalf("Expected delivery count of 1, got %d", dc) 3414 } 3415 3416 // Now do old school request style and more than one waiting. 3417 nc = clientConnectWithOldRequest(t, s) 3418 defer nc.Close() 3419 3420 // Now queue up 10 waiting via failed requests. 3421 for i := 0; i < 10; i++ { 3422 if _, err := nc.Request(rqn, nil, 1*time.Millisecond); err == nil { 3423 t.Fatalf("Expected an error, got none") 3424 } 3425 } 3426 3427 // Send a second message 3428 sendStreamMsg(t, nc, mname, "Hello World!") 3429 3430 msg, err = nc.Request(rqn, nil, time.Second) 3431 require_NoError(t, err) 3432 _, dseq, dc, _, _ = replyInfo(msg.Reply) 3433 if dseq != 2 { 3434 t.Fatalf("Expected consumer sequence of 2, got %d", dseq) 3435 } 3436 if dc != 1 { 3437 t.Fatalf("Expected delivery count of 1, got %d", dc) 3438 } 3439 } 3440 3441 func TestJetStreamConsumerRateLimit(t *testing.T) { 3442 s := RunBasicJetStreamServer(t) 3443 defer s.Shutdown() 3444 3445 mname := "RATELIMIT" 3446 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: FileStorage}) 3447 if err != nil { 3448 t.Fatalf("Unexpected error adding stream: %v", err) 3449 } 3450 3451 nc := clientConnectToServer(t, s) 3452 defer nc.Close() 3453 3454 msgSize := 128 * 1024 3455 msg := make([]byte, msgSize) 3456 crand.Read(msg) 3457 3458 // 10MB 3459 totalSize := 10 * 1024 * 1024 3460 toSend := totalSize / msgSize 3461 for i := 0; i < toSend; i++ { 3462 nc.Publish(mname, msg) 3463 } 3464 nc.Flush() 3465 3466 checkFor(t, 5*time.Second, 100*time.Millisecond, func() error { 3467 state := mset.state() 3468 if state.Msgs != uint64(toSend) { 3469 return fmt.Errorf("Expected %d messages, got %d", toSend, state.Msgs) 3470 } 3471 return nil 3472 }) 3473 3474 // 100Mbit 3475 rateLimit := uint64(100 * 1024 * 1024) 3476 // Make sure if you set a rate with a pull based consumer it errors. 3477 _, err = mset.addConsumer(&ConsumerConfig{Durable: "to", AckPolicy: AckExplicit, RateLimit: rateLimit}) 3478 if err == nil { 3479 t.Fatalf("Expected an error, got none") 3480 } 3481 3482 // Now create one and measure the rate delivered. 3483 o, err := mset.addConsumer(&ConsumerConfig{ 3484 Durable: "rate", 3485 DeliverSubject: "to", 3486 RateLimit: rateLimit, 3487 AckPolicy: AckNone}) 3488 require_NoError(t, err) 3489 defer o.delete() 3490 3491 var received int 3492 done := make(chan bool) 3493 3494 start := time.Now() 3495 3496 nc.Subscribe("to", func(m *nats.Msg) { 3497 received++ 3498 if received >= toSend { 3499 done <- true 3500 } 3501 }) 3502 nc.Flush() 3503 3504 select { 3505 case <-done: 3506 case <-time.After(5 * time.Second): 3507 t.Fatalf("Did not receive all the messages in time") 3508 } 3509 3510 tt := time.Since(start) 3511 rate := float64(8*toSend*msgSize) / tt.Seconds() 3512 if rate > float64(rateLimit)*1.25 { 3513 t.Fatalf("Exceeded desired rate of %d mbps, got %0.f mbps", rateLimit/(1024*1024), rate/(1024*1024)) 3514 } 3515 } 3516 3517 func TestJetStreamEphemeralConsumerRecoveryAfterServerRestart(t *testing.T) { 3518 s := RunBasicJetStreamServer(t) 3519 defer s.Shutdown() 3520 3521 mname := "MYS" 3522 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: FileStorage}) 3523 if err != nil { 3524 t.Fatalf("Unexpected error adding stream: %v", err) 3525 } 3526 defer mset.delete() 3527 3528 nc := clientConnectToServer(t, s) 3529 defer nc.Close() 3530 3531 sub, _ := nc.SubscribeSync(nats.NewInbox()) 3532 defer sub.Unsubscribe() 3533 nc.Flush() 3534 3535 o, err := mset.addConsumer(&ConsumerConfig{ 3536 DeliverSubject: sub.Subject, 3537 AckPolicy: AckExplicit, 3538 }) 3539 if err != nil { 3540 t.Fatalf("Error creating consumer: %v", err) 3541 } 3542 defer o.delete() 3543 3544 // Snapshot our name. 3545 oname := o.String() 3546 3547 // Send 100 messages 3548 for i := 0; i < 100; i++ { 3549 sendStreamMsg(t, nc, mname, "Hello World!") 3550 } 3551 if state := mset.state(); state.Msgs != 100 { 3552 t.Fatalf("Expected %d messages, got %d", 100, state.Msgs) 3553 } 3554 3555 // Read 6 messages 3556 for i := 0; i <= 6; i++ { 3557 if m, err := sub.NextMsg(time.Second); err == nil { 3558 m.Respond(nil) 3559 } else { 3560 t.Fatalf("Unexpected error: %v", err) 3561 } 3562 } 3563 3564 // Capture port since it was dynamic. 3565 u, _ := url.Parse(s.ClientURL()) 3566 port, _ := strconv.Atoi(u.Port()) 3567 3568 restartServer := func() { 3569 t.Helper() 3570 // Stop current 3571 sd := s.JetStreamConfig().StoreDir 3572 s.Shutdown() 3573 // Restart. 3574 s = RunJetStreamServerOnPort(port, sd) 3575 } 3576 3577 // Do twice 3578 for i := 0; i < 2; i++ { 3579 // Restart. 3580 restartServer() 3581 defer s.Shutdown() 3582 3583 mset, err = s.GlobalAccount().lookupStream(mname) 3584 if err != nil { 3585 t.Fatalf("Expected to find a stream for %q", mname) 3586 } 3587 o = mset.lookupConsumer(oname) 3588 if o == nil { 3589 t.Fatalf("Error looking up consumer %q", oname) 3590 } 3591 // Make sure config does not have durable. 3592 if cfg := o.config(); cfg.Durable != _EMPTY_ { 3593 t.Fatalf("Expected no durable to be set") 3594 } 3595 // Wait for it to become active 3596 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 3597 if !o.isActive() { 3598 return fmt.Errorf("Consumer not active") 3599 } 3600 return nil 3601 }) 3602 } 3603 3604 // Now close the connection. Make sure this acts like an ephemeral and goes away. 3605 o.setInActiveDeleteThreshold(10 * time.Millisecond) 3606 nc.Close() 3607 3608 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 3609 if o := mset.lookupConsumer(oname); o != nil { 3610 return fmt.Errorf("Consumer still active") 3611 } 3612 return nil 3613 }) 3614 } 3615 3616 func TestJetStreamConsumerMaxDeliveryAndServerRestart(t *testing.T) { 3617 s := RunBasicJetStreamServer(t) 3618 defer s.Shutdown() 3619 3620 mname := "MYS" 3621 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname, Storage: FileStorage}) 3622 if err != nil { 3623 t.Fatalf("Unexpected error adding stream: %v", err) 3624 } 3625 defer mset.delete() 3626 3627 streamCreated := mset.createdTime() 3628 3629 dsubj := "D.TO" 3630 max := 3 3631 3632 o, err := mset.addConsumer(&ConsumerConfig{ 3633 Durable: "TO", 3634 DeliverSubject: dsubj, 3635 AckPolicy: AckExplicit, 3636 AckWait: 100 * time.Millisecond, 3637 MaxDeliver: max, 3638 }) 3639 defer o.delete() 3640 3641 consumerCreated := o.createdTime() 3642 // For calculation of consumer created times below. 3643 time.Sleep(5 * time.Millisecond) 3644 3645 nc := clientConnectToServer(t, s) 3646 defer nc.Close() 3647 3648 sub, _ := nc.SubscribeSync(dsubj) 3649 nc.Flush() 3650 defer sub.Unsubscribe() 3651 3652 // Send one message. 3653 sendStreamMsg(t, nc, mname, "order-1") 3654 3655 checkSubPending := func(numExpected int) { 3656 t.Helper() 3657 checkFor(t, time.Second, 10*time.Millisecond, func() error { 3658 if nmsgs, _, _ := sub.Pending(); nmsgs != numExpected { 3659 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 3660 } 3661 return nil 3662 }) 3663 } 3664 3665 checkNumMsgs := func(numExpected uint64) { 3666 t.Helper() 3667 mset, err = s.GlobalAccount().lookupStream(mname) 3668 if err != nil { 3669 t.Fatalf("Expected to find a stream for %q", mname) 3670 } 3671 state := mset.state() 3672 if state.Msgs != numExpected { 3673 t.Fatalf("Expected %d msgs, got %d", numExpected, state.Msgs) 3674 } 3675 } 3676 3677 // Wait til we know we have max queued up. 3678 checkSubPending(max) 3679 3680 // Once here we have gone over the limit for the 1st message for max deliveries. 3681 // Send second 3682 sendStreamMsg(t, nc, mname, "order-2") 3683 3684 // Just wait for first delivery + one redelivery. 3685 checkSubPending(max + 2) 3686 3687 // Capture port since it was dynamic. 3688 u, _ := url.Parse(s.ClientURL()) 3689 port, _ := strconv.Atoi(u.Port()) 3690 3691 restartServer := func() { 3692 t.Helper() 3693 sd := s.JetStreamConfig().StoreDir 3694 // Stop current 3695 s.Shutdown() 3696 // Restart. 3697 s = RunJetStreamServerOnPort(port, sd) 3698 } 3699 3700 waitForClientReconnect := func() { 3701 checkFor(t, 2500*time.Millisecond, 5*time.Millisecond, func() error { 3702 if !nc.IsConnected() { 3703 return fmt.Errorf("Not connected") 3704 } 3705 return nil 3706 }) 3707 } 3708 3709 // Restart. 3710 restartServer() 3711 defer s.Shutdown() 3712 3713 checkNumMsgs(2) 3714 3715 // Wait for client to be reconnected. 3716 waitForClientReconnect() 3717 3718 // Once we are here send third order. 3719 sendStreamMsg(t, nc, mname, "order-3") 3720 checkNumMsgs(3) 3721 3722 // Restart. 3723 restartServer() 3724 defer s.Shutdown() 3725 3726 checkNumMsgs(3) 3727 3728 // Wait for client to be reconnected. 3729 waitForClientReconnect() 3730 3731 // Now we should have max times three on our sub. 3732 checkSubPending(max * 3) 3733 3734 // Now do some checks on created timestamps. 3735 mset, err = s.GlobalAccount().lookupStream(mname) 3736 if err != nil { 3737 t.Fatalf("Expected to find a stream for %q", mname) 3738 } 3739 if mset.createdTime() != streamCreated { 3740 t.Fatalf("Stream creation time not restored, wanted %v, got %v", streamCreated, mset.createdTime()) 3741 } 3742 o = mset.lookupConsumer("TO") 3743 if o == nil { 3744 t.Fatalf("Error looking up consumer: %v", err) 3745 } 3746 // Consumer created times can have a very small skew. 3747 delta := o.createdTime().Sub(consumerCreated) 3748 if delta > 5*time.Millisecond { 3749 t.Fatalf("Consumer creation time not restored, wanted %v, got %v", consumerCreated, o.createdTime()) 3750 } 3751 } 3752 3753 func TestJetStreamDeleteConsumerAndServerRestart(t *testing.T) { 3754 s := RunBasicJetStreamServer(t) 3755 defer s.Shutdown() 3756 3757 sendSubj := "MYQ" 3758 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: sendSubj, Storage: FileStorage}) 3759 if err != nil { 3760 t.Fatalf("Unexpected error adding stream: %v", err) 3761 } 3762 defer mset.delete() 3763 3764 // Create basic work queue mode consumer. 3765 oname := "WQ" 3766 o, err := mset.addConsumer(workerModeConfig(oname)) 3767 if err != nil { 3768 t.Fatalf("Expected no error with registered interest, got %v", err) 3769 } 3770 3771 // Now delete and then we will restart the 3772 o.delete() 3773 3774 if numo := mset.numConsumers(); numo != 0 { 3775 t.Fatalf("Expected to have zero consumers, got %d", numo) 3776 } 3777 3778 // Capture port since it was dynamic. 3779 u, _ := url.Parse(s.ClientURL()) 3780 port, _ := strconv.Atoi(u.Port()) 3781 sd := s.JetStreamConfig().StoreDir 3782 3783 // Stop current 3784 s.Shutdown() 3785 3786 // Restart. 3787 s = RunJetStreamServerOnPort(port, sd) 3788 defer s.Shutdown() 3789 3790 mset, err = s.GlobalAccount().lookupStream(sendSubj) 3791 if err != nil { 3792 t.Fatalf("Expected to find a stream for %q", sendSubj) 3793 } 3794 3795 if numo := mset.numConsumers(); numo != 0 { 3796 t.Fatalf("Expected to have zero consumers, got %d", numo) 3797 } 3798 } 3799 3800 func TestJetStreamRedeliveryAfterServerRestart(t *testing.T) { 3801 s := RunBasicJetStreamServer(t) 3802 defer s.Shutdown() 3803 3804 sendSubj := "MYQ" 3805 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: sendSubj, Storage: FileStorage}) 3806 if err != nil { 3807 t.Fatalf("Unexpected error adding stream: %v", err) 3808 } 3809 defer mset.delete() 3810 3811 nc := clientConnectToServer(t, s) 3812 defer nc.Close() 3813 3814 // Now load up some messages. 3815 toSend := 25 3816 for i := 0; i < toSend; i++ { 3817 sendStreamMsg(t, nc, sendSubj, "Hello World!") 3818 } 3819 state := mset.state() 3820 if state.Msgs != uint64(toSend) { 3821 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 3822 } 3823 3824 sub, _ := nc.SubscribeSync(nats.NewInbox()) 3825 defer sub.Unsubscribe() 3826 nc.Flush() 3827 3828 o, err := mset.addConsumer(&ConsumerConfig{ 3829 Durable: "TO", 3830 DeliverSubject: sub.Subject, 3831 AckPolicy: AckExplicit, 3832 AckWait: 100 * time.Millisecond, 3833 }) 3834 require_NoError(t, err) 3835 defer o.delete() 3836 3837 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 3838 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 3839 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 3840 } 3841 return nil 3842 }) 3843 3844 // Capture port since it was dynamic. 3845 u, _ := url.Parse(s.ClientURL()) 3846 port, _ := strconv.Atoi(u.Port()) 3847 sd := s.JetStreamConfig().StoreDir 3848 3849 // Stop current 3850 s.Shutdown() 3851 3852 // Restart. 3853 s = RunJetStreamServerOnPort(port, sd) 3854 defer s.Shutdown() 3855 3856 // Don't wait for reconnect from old client. 3857 nc = clientConnectToServer(t, s) 3858 defer nc.Close() 3859 3860 sub, _ = nc.SubscribeSync(sub.Subject) 3861 defer sub.Unsubscribe() 3862 3863 checkFor(t, time.Second, 50*time.Millisecond, func() error { 3864 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 3865 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 3866 } 3867 return nil 3868 }) 3869 } 3870 3871 func TestJetStreamSnapshots(t *testing.T) { 3872 s := RunBasicJetStreamServer(t) 3873 defer s.Shutdown() 3874 3875 mname := "MY-STREAM" 3876 subjects := []string{"foo", "bar", "baz"} 3877 cfg := StreamConfig{ 3878 Name: mname, 3879 Storage: FileStorage, 3880 Subjects: subjects, 3881 MaxMsgs: 1000, 3882 } 3883 3884 acc := s.GlobalAccount() 3885 mset, err := acc.addStream(&cfg) 3886 if err != nil { 3887 t.Fatalf("Unexpected error adding stream: %v", err) 3888 } 3889 3890 nc := clientConnectToServer(t, s) 3891 defer nc.Close() 3892 3893 // Make sure we send some as floor. 3894 toSend := rand.Intn(200) + 22 3895 for i := 1; i <= toSend; i++ { 3896 msg := fmt.Sprintf("Hello World %d", i) 3897 subj := subjects[rand.Intn(len(subjects))] 3898 sendStreamMsg(t, nc, subj, msg) 3899 } 3900 3901 // Create up to 10 consumers. 3902 numConsumers := rand.Intn(10) + 1 3903 var obs []obsi 3904 for i := 1; i <= numConsumers; i++ { 3905 cname := fmt.Sprintf("WQ-%d", i) 3906 o, err := mset.addConsumer(workerModeConfig(cname)) 3907 if err != nil { 3908 t.Fatalf("Unexpected error: %v", err) 3909 } 3910 // Now grab some messages. 3911 toReceive := rand.Intn(toSend/2) + 1 3912 for r := 0; r < toReceive; r++ { 3913 resp, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 3914 if err != nil { 3915 t.Fatalf("Unexpected error: %v", err) 3916 } 3917 if resp != nil { 3918 resp.Respond(nil) 3919 } 3920 } 3921 obs = append(obs, obsi{o.config(), toReceive}) 3922 } 3923 nc.Flush() 3924 3925 // Snapshot state of the stream and consumers. 3926 info := info{mset.config(), mset.state(), obs} 3927 3928 sr, err := mset.snapshot(5*time.Second, false, true) 3929 if err != nil { 3930 t.Fatalf("Error getting snapshot: %v", err) 3931 } 3932 zr := sr.Reader 3933 snapshot, err := io.ReadAll(zr) 3934 if err != nil { 3935 t.Fatalf("Error reading snapshot") 3936 } 3937 // Try to restore from snapshot with current stream present, should error. 3938 r := bytes.NewReader(snapshot) 3939 if _, err := acc.RestoreStream(&info.cfg, r); err == nil { 3940 t.Fatalf("Expected an error trying to restore existing stream") 3941 } else if !strings.Contains(err.Error(), "name already in use") { 3942 t.Fatalf("Incorrect error received: %v", err) 3943 } 3944 // Now delete so we can restore. 3945 pusage := acc.JetStreamUsage() 3946 mset.delete() 3947 r.Reset(snapshot) 3948 3949 mset, err = acc.RestoreStream(&info.cfg, r) 3950 require_NoError(t, err) 3951 // Now compare to make sure they are equal. 3952 if nusage := acc.JetStreamUsage(); !reflect.DeepEqual(nusage, pusage) { 3953 t.Fatalf("Usage does not match after restore: %+v vs %+v", nusage, pusage) 3954 } 3955 if state := mset.state(); !reflect.DeepEqual(state, info.state) { 3956 t.Fatalf("State does not match: %+v vs %+v", state, info.state) 3957 } 3958 if cfg := mset.config(); !reflect.DeepEqual(cfg, info.cfg) { 3959 t.Fatalf("Configs do not match: %+v vs %+v", cfg, info.cfg) 3960 } 3961 // Consumers. 3962 if mset.numConsumers() != len(info.obs) { 3963 t.Fatalf("Number of consumers do not match: %d vs %d", mset.numConsumers(), len(info.obs)) 3964 } 3965 for _, oi := range info.obs { 3966 if o := mset.lookupConsumer(oi.cfg.Durable); o != nil { 3967 if uint64(oi.ack+1) != o.nextSeq() { 3968 t.Fatalf("[%v] Consumer next seq is not correct: %d vs %d", o.String(), oi.ack+1, o.nextSeq()) 3969 } 3970 } else { 3971 t.Fatalf("Expected to get an consumer") 3972 } 3973 } 3974 3975 // Now try restoring to a different 3976 s2 := RunBasicJetStreamServer(t) 3977 defer s2.Shutdown() 3978 3979 acc = s2.GlobalAccount() 3980 r.Reset(snapshot) 3981 mset, err = acc.RestoreStream(&info.cfg, r) 3982 require_NoError(t, err) 3983 3984 o := mset.lookupConsumer("WQ-1") 3985 if o == nil { 3986 t.Fatalf("Could not lookup consumer") 3987 } 3988 3989 nc2 := clientConnectToServer(t, s2) 3990 defer nc2.Close() 3991 3992 // Make sure we can read messages. 3993 if _, err := nc2.Request(o.requestNextMsgSubject(), nil, 5*time.Second); err != nil { 3994 t.Fatalf("Unexpected error getting next message: %v", err) 3995 } 3996 } 3997 3998 func TestJetStreamSnapshotsAPI(t *testing.T) { 3999 lopts := DefaultTestOptions 4000 lopts.ServerName = "LS" 4001 lopts.Port = -1 4002 lopts.LeafNode.Host = lopts.Host 4003 lopts.LeafNode.Port = -1 4004 4005 ls := RunServer(&lopts) 4006 defer ls.Shutdown() 4007 4008 opts := DefaultTestOptions 4009 opts.ServerName = "S" 4010 opts.Port = -1 4011 tdir := t.TempDir() 4012 opts.JetStream = true 4013 opts.JetStreamDomain = "domain" 4014 opts.StoreDir = tdir 4015 maxStore := int64(1024 * 1024 * 1024) 4016 opts.maxStoreSet = true 4017 opts.JetStreamMaxStore = maxStore 4018 rurl, _ := url.Parse(fmt.Sprintf("nats-leaf://%s:%d", lopts.LeafNode.Host, lopts.LeafNode.Port)) 4019 opts.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{rurl}}} 4020 4021 s := RunServer(&opts) 4022 defer s.Shutdown() 4023 4024 checkLeafNodeConnected(t, s) 4025 4026 mname := "MY-STREAM" 4027 subjects := []string{"foo", "bar", "baz"} 4028 cfg := StreamConfig{ 4029 Name: mname, 4030 Storage: FileStorage, 4031 Subjects: subjects, 4032 MaxMsgs: 1000, 4033 } 4034 4035 acc := s.GlobalAccount() 4036 mset, err := acc.addStreamWithStore(&cfg, &FileStoreConfig{BlockSize: 128}) 4037 if err != nil { 4038 t.Fatalf("Unexpected error adding stream: %v", err) 4039 } 4040 4041 nc := clientConnectToServer(t, s) 4042 defer nc.Close() 4043 4044 toSend := rand.Intn(100) + 1 4045 for i := 1; i <= toSend; i++ { 4046 msg := fmt.Sprintf("Hello World %d", i) 4047 subj := subjects[rand.Intn(len(subjects))] 4048 sendStreamMsg(t, nc, subj, msg) 4049 } 4050 4051 o, err := mset.addConsumer(workerModeConfig("WQ")) 4052 require_NoError(t, err) 4053 // Now grab some messages. 4054 toReceive := rand.Intn(toSend) + 1 4055 for r := 0; r < toReceive; r++ { 4056 resp, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 4057 if err != nil { 4058 t.Fatalf("Unexpected error: %v", err) 4059 } 4060 if resp != nil { 4061 resp.Respond(nil) 4062 } 4063 } 4064 4065 // Make sure we get proper error for non-existent request, streams,etc, 4066 rmsg, err := nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, "foo"), nil, time.Second) 4067 if err != nil { 4068 t.Fatalf("Unexpected error on snapshot request: %v", err) 4069 } 4070 var resp JSApiStreamSnapshotResponse 4071 json.Unmarshal(rmsg.Data, &resp) 4072 if resp.Error == nil || resp.Error.Code != 400 || resp.Error.Description != "bad request" { 4073 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4074 } 4075 4076 sreq := &JSApiStreamSnapshotRequest{} 4077 req, _ := json.Marshal(sreq) 4078 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, "foo"), req, time.Second) 4079 if err != nil { 4080 t.Fatalf("Unexpected error on snapshot request: %v", err) 4081 } 4082 json.Unmarshal(rmsg.Data, &resp) 4083 if resp.Error == nil || resp.Error.Code != 404 || resp.Error.Description != "stream not found" { 4084 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4085 } 4086 4087 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, mname), req, time.Second) 4088 if err != nil { 4089 t.Fatalf("Unexpected error on snapshot request: %v", err) 4090 } 4091 json.Unmarshal(rmsg.Data, &resp) 4092 if resp.Error == nil || resp.Error.Code != 400 || resp.Error.Description != "deliver subject not valid" { 4093 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4094 } 4095 4096 // Set delivery subject, do not subscribe yet. Want this to be an ok pattern. 4097 sreq.DeliverSubject = nats.NewInbox() 4098 // Just for test, usually left alone. 4099 sreq.ChunkSize = 1024 4100 req, _ = json.Marshal(sreq) 4101 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, mname), req, time.Second) 4102 if err != nil { 4103 t.Fatalf("Unexpected error on snapshot request: %v", err) 4104 } 4105 resp.Error = nil 4106 json.Unmarshal(rmsg.Data, &resp) 4107 if resp.Error != nil { 4108 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4109 } 4110 // Check that we have the config and the state. 4111 if resp.Config == nil { 4112 t.Fatalf("Expected a stream config in the response, got %+v\n", resp) 4113 } 4114 if resp.State == nil { 4115 t.Fatalf("Expected a stream state in the response, got %+v\n", resp) 4116 } 4117 4118 // Grab state for comparison. 4119 state := *resp.State 4120 config := *resp.Config 4121 4122 // Setup to process snapshot chunks. 4123 var snapshot []byte 4124 done := make(chan bool) 4125 4126 sub, _ := nc.Subscribe(sreq.DeliverSubject, func(m *nats.Msg) { 4127 // EOF 4128 if len(m.Data) == 0 { 4129 done <- true 4130 return 4131 } 4132 // Could be writing to a file here too. 4133 snapshot = append(snapshot, m.Data...) 4134 // Flow ack 4135 m.Respond(nil) 4136 }) 4137 defer sub.Unsubscribe() 4138 4139 // Wait to receive the snapshot. 4140 select { 4141 case <-done: 4142 case <-time.After(5 * time.Second): 4143 t.Fatalf("Did not receive our snapshot in time") 4144 } 4145 4146 // Now make sure this snapshot is legit. 4147 var rresp JSApiStreamRestoreResponse 4148 rreq := &JSApiStreamRestoreRequest{ 4149 Config: config, 4150 State: state, 4151 } 4152 req, _ = json.Marshal(rreq) 4153 4154 // Make sure we get an error since stream still exists. 4155 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamRestoreT, mname), req, time.Second) 4156 if err != nil { 4157 t.Fatalf("Unexpected error on snapshot request: %v", err) 4158 } 4159 json.Unmarshal(rmsg.Data, &rresp) 4160 if !IsNatsErr(rresp.Error, JSStreamNameExistRestoreFailedErr) { 4161 t.Fatalf("Did not get correct error response: %+v", rresp.Error) 4162 } 4163 4164 // Delete this stream. 4165 mset.delete() 4166 4167 // Sending no request message will error now. 4168 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamRestoreT, mname), nil, time.Second) 4169 if err != nil { 4170 t.Fatalf("Unexpected error on snapshot request: %v", err) 4171 } 4172 // Make sure to clear. 4173 rresp.Error = nil 4174 json.Unmarshal(rmsg.Data, &rresp) 4175 if rresp.Error == nil || rresp.Error.Code != 400 || rresp.Error.Description != "bad request" { 4176 t.Fatalf("Did not get correct error response: %+v", rresp.Error) 4177 } 4178 4179 // This should work. 4180 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamRestoreT, mname), req, time.Second) 4181 if err != nil { 4182 t.Fatalf("Unexpected error on snapshot request: %v", err) 4183 } 4184 // Make sure to clear. 4185 rresp.Error = nil 4186 json.Unmarshal(rmsg.Data, &rresp) 4187 if rresp.Error != nil { 4188 t.Fatalf("Got an unexpected error response: %+v", rresp.Error) 4189 } 4190 4191 // Can be any size message. 4192 var chunk [512]byte 4193 for r := bytes.NewReader(snapshot); ; { 4194 n, err := r.Read(chunk[:]) 4195 if err != nil { 4196 break 4197 } 4198 nc.Request(rresp.DeliverSubject, chunk[:n], time.Second) 4199 } 4200 nc.Request(rresp.DeliverSubject, nil, time.Second) 4201 4202 mset, err = acc.lookupStream(mname) 4203 if err != nil { 4204 t.Fatalf("Expected to find a stream for %q", mname) 4205 } 4206 if !reflect.DeepEqual(mset.state(), state) { 4207 t.Fatalf("Did not match states, %+v vs %+v", mset.state(), state) 4208 } 4209 4210 // Now ask that the stream be checked first. 4211 sreq.ChunkSize = 0 4212 sreq.CheckMsgs = true 4213 snapshot = snapshot[:0] 4214 4215 req, _ = json.Marshal(sreq) 4216 if _, err = nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, mname), req, 5*time.Second); err != nil { 4217 t.Fatalf("Unexpected error on snapshot request: %v", err) 4218 } 4219 // Wait to receive the snapshot. 4220 select { 4221 case <-done: 4222 case <-time.After(5 * time.Second): 4223 t.Fatalf("Did not receive our snapshot in time") 4224 } 4225 4226 // Now connect through a cluster server and make sure we can get things to work this way as well. 4227 // This client, connecting to a leaf without shared system account and domain needs to provide the domain explicitly. 4228 nc2 := clientConnectToServer(t, ls) 4229 defer nc2.Close() 4230 // Wait a bit for interest to propagate. 4231 time.Sleep(100 * time.Millisecond) 4232 4233 snapshot = snapshot[:0] 4234 4235 req, _ = json.Marshal(sreq) 4236 rmsg, err = nc2.Request(fmt.Sprintf(strings.ReplaceAll(JSApiStreamSnapshotT, JSApiPrefix, "$JS.domain.API"), mname), req, time.Second) 4237 if err != nil { 4238 t.Fatalf("Unexpected error on snapshot request: %v", err) 4239 } 4240 resp.Error = nil 4241 json.Unmarshal(rmsg.Data, &resp) 4242 if resp.Error != nil { 4243 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4244 } 4245 // Wait to receive the snapshot. 4246 select { 4247 case <-done: 4248 case <-time.After(5 * time.Second): 4249 t.Fatalf("Did not receive our snapshot in time") 4250 } 4251 4252 // Now do a restore through the new client connection. 4253 // Delete this stream first. 4254 mset, err = acc.lookupStream(mname) 4255 if err != nil { 4256 t.Fatalf("Expected to find a stream for %q", mname) 4257 } 4258 state = mset.state() 4259 mset.delete() 4260 4261 rmsg, err = nc2.Request(strings.ReplaceAll(JSApiStreamRestoreT, JSApiPrefix, "$JS.domain.API"), req, time.Second) 4262 if err != nil { 4263 t.Fatalf("Unexpected error on snapshot request: %v", err) 4264 } 4265 // Make sure to clear. 4266 rresp.Error = nil 4267 json.Unmarshal(rmsg.Data, &rresp) 4268 if rresp.Error != nil { 4269 t.Fatalf("Got an unexpected error response: %+v", rresp.Error) 4270 } 4271 4272 // Make sure when we send something without a reply subject the subscription is shutoff. 4273 r := bytes.NewReader(snapshot) 4274 n, _ := r.Read(chunk[:]) 4275 nc2.Publish(rresp.DeliverSubject, chunk[:n]) 4276 nc2.Flush() 4277 n, _ = r.Read(chunk[:]) 4278 if _, err := nc2.Request(rresp.DeliverSubject, chunk[:n], 100*time.Millisecond); err == nil { 4279 t.Fatalf("Expected restore subscription to be closed") 4280 } 4281 4282 req, _ = json.Marshal(rreq) 4283 rmsg, err = nc2.Request(strings.ReplaceAll(JSApiStreamRestoreT, JSApiPrefix, "$JS.domain.API"), req, time.Second) 4284 if err != nil { 4285 t.Fatalf("Unexpected error on snapshot request: %v", err) 4286 } 4287 // Make sure to clear. 4288 rresp.Error = nil 4289 json.Unmarshal(rmsg.Data, &rresp) 4290 if rresp.Error != nil { 4291 t.Fatalf("Got an unexpected error response: %+v", rresp.Error) 4292 } 4293 4294 for r := bytes.NewReader(snapshot); ; { 4295 n, err := r.Read(chunk[:]) 4296 if err != nil { 4297 break 4298 } 4299 // Make sure other side responds to reply subjects for ack flow. Optional. 4300 if _, err := nc2.Request(rresp.DeliverSubject, chunk[:n], time.Second); err != nil { 4301 t.Fatalf("Restore not honoring reply subjects for ack flow") 4302 } 4303 } 4304 4305 // For EOF this will send back stream info or an error. 4306 si, err := nc2.Request(rresp.DeliverSubject, nil, time.Second) 4307 if err != nil { 4308 t.Fatalf("Got an error restoring stream: %v", err) 4309 } 4310 var scResp JSApiStreamCreateResponse 4311 if err := json.Unmarshal(si.Data, &scResp); err != nil { 4312 t.Fatalf("Unexpected error: %v", err) 4313 } 4314 if scResp.Error != nil { 4315 t.Fatalf("Got an unexpected error from EOF on restore: %+v", scResp.Error) 4316 } 4317 4318 if !reflect.DeepEqual(scResp.StreamInfo.State, state) { 4319 t.Fatalf("Did not match states, %+v vs %+v", scResp.StreamInfo.State, state) 4320 } 4321 4322 // Now make sure that if we try to change the name/identity of the stream we get an error. 4323 mset, err = acc.lookupStream(mname) 4324 if err != nil { 4325 t.Fatalf("Expected to find a stream for %q", mname) 4326 } 4327 mset.state() 4328 mset.delete() 4329 4330 rreq.Config.Name = "NEW_STREAM" 4331 req, _ = json.Marshal(rreq) 4332 4333 rmsg, err = nc.Request(fmt.Sprintf(JSApiStreamRestoreT, rreq.Config.Name), req, time.Second) 4334 if err != nil { 4335 t.Fatalf("Unexpected error on snapshot request: %v", err) 4336 } 4337 // Make sure to clear. 4338 rresp.Error = nil 4339 json.Unmarshal(rmsg.Data, &rresp) 4340 // We should not get an error here. 4341 if rresp.Error != nil { 4342 t.Fatalf("Got an unexpected error response: %+v", rresp.Error) 4343 } 4344 for r := bytes.NewReader(snapshot); ; { 4345 n, err := r.Read(chunk[:]) 4346 if err != nil { 4347 break 4348 } 4349 nc.Request(rresp.DeliverSubject, chunk[:n], time.Second) 4350 } 4351 4352 si, err = nc2.Request(rresp.DeliverSubject, nil, time.Second) 4353 require_NoError(t, err) 4354 4355 scResp.Error = nil 4356 if err := json.Unmarshal(si.Data, &scResp); err != nil { 4357 t.Fatalf("Unexpected error: %v", err) 4358 } 4359 if scResp.Error == nil { 4360 t.Fatalf("Expected an error but got none") 4361 } 4362 expect := "names do not match" 4363 if !strings.Contains(scResp.Error.Description, expect) { 4364 t.Fatalf("Expected description of %q, got %q", expect, scResp.Error.Description) 4365 } 4366 } 4367 4368 func TestJetStreamPubAckPerf(t *testing.T) { 4369 // Comment out to run, holding place for now. 4370 t.SkipNow() 4371 4372 s := RunBasicJetStreamServer(t) 4373 defer s.Shutdown() 4374 4375 nc, js := jsClientConnect(t, s) 4376 defer nc.Close() 4377 4378 if _, err := js.AddStream(&nats.StreamConfig{Name: "foo", Storage: nats.MemoryStorage}); err != nil { 4379 t.Fatalf("Unexpected error: %v", err) 4380 } 4381 4382 toSend := 1_000_000 4383 start := time.Now() 4384 for i := 0; i < toSend; i++ { 4385 js.PublishAsync("foo", []byte("OK")) 4386 } 4387 <-js.PublishAsyncComplete() 4388 tt := time.Since(start) 4389 fmt.Printf("time is %v\n", tt) 4390 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 4391 } 4392 4393 func TestJetStreamPubPerfWithFullStream(t *testing.T) { 4394 // Comment out to run, holding place for now. 4395 t.SkipNow() 4396 4397 s := RunBasicJetStreamServer(t) 4398 defer s.Shutdown() 4399 4400 nc, js := jsClientConnect(t, s) 4401 defer nc.Close() 4402 4403 toSend, msg := 1_000_000, []byte("OK") 4404 4405 _, err := js.AddStream(&nats.StreamConfig{Name: "foo", MaxMsgs: int64(toSend)}) 4406 require_NoError(t, err) 4407 4408 start := time.Now() 4409 for i := 0; i < toSend; i++ { 4410 js.PublishAsync("foo", msg) 4411 } 4412 <-js.PublishAsyncComplete() 4413 tt := time.Since(start) 4414 fmt.Printf("time is %v\n", tt) 4415 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 4416 4417 // Now do same amount but knowing we are at our limit. 4418 start = time.Now() 4419 for i := 0; i < toSend; i++ { 4420 js.PublishAsync("foo", msg) 4421 } 4422 <-js.PublishAsyncComplete() 4423 tt = time.Since(start) 4424 fmt.Printf("\ntime is %v\n", tt) 4425 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 4426 } 4427 4428 func TestJetStreamSnapshotsAPIPerf(t *testing.T) { 4429 // Comment out to run, holding place for now. 4430 t.SkipNow() 4431 4432 s := RunBasicJetStreamServer(t) 4433 defer s.Shutdown() 4434 4435 cfg := StreamConfig{ 4436 Name: "snap-perf", 4437 Storage: FileStorage, 4438 } 4439 4440 acc := s.GlobalAccount() 4441 if _, err := acc.addStream(&cfg); err != nil { 4442 t.Fatalf("Unexpected error adding stream: %v", err) 4443 } 4444 4445 nc := clientConnectToServer(t, s) 4446 defer nc.Close() 4447 4448 msg := make([]byte, 128*1024) 4449 // If you don't give gzip some data will spend too much time compressing everything to zero. 4450 crand.Read(msg) 4451 4452 for i := 0; i < 10000; i++ { 4453 nc.Publish("snap-perf", msg) 4454 } 4455 nc.Flush() 4456 4457 sreq := &JSApiStreamSnapshotRequest{DeliverSubject: nats.NewInbox()} 4458 req, _ := json.Marshal(sreq) 4459 rmsg, err := nc.Request(fmt.Sprintf(JSApiStreamSnapshotT, "snap-perf"), req, time.Second) 4460 if err != nil { 4461 t.Fatalf("Unexpected error on snapshot request: %v", err) 4462 } 4463 4464 var resp JSApiStreamSnapshotResponse 4465 json.Unmarshal(rmsg.Data, &resp) 4466 if resp.Error != nil { 4467 t.Fatalf("Did not get correct error response: %+v", resp.Error) 4468 } 4469 4470 done := make(chan bool) 4471 total := 0 4472 sub, _ := nc.Subscribe(sreq.DeliverSubject, func(m *nats.Msg) { 4473 // EOF 4474 if len(m.Data) == 0 { 4475 m.Sub.Unsubscribe() 4476 done <- true 4477 return 4478 } 4479 // We don't do anything with the snapshot, just take 4480 // note of the size. 4481 total += len(m.Data) 4482 // Flow ack 4483 m.Respond(nil) 4484 }) 4485 defer sub.Unsubscribe() 4486 4487 start := time.Now() 4488 // Wait to receive the snapshot. 4489 select { 4490 case <-done: 4491 case <-time.After(30 * time.Second): 4492 t.Fatalf("Did not receive our snapshot in time") 4493 } 4494 td := time.Since(start) 4495 fmt.Printf("Received %d bytes in %v\n", total, td) 4496 fmt.Printf("Rate %.0f MB/s\n", float64(total)/td.Seconds()/(1024*1024)) 4497 } 4498 4499 func TestJetStreamActiveDelivery(t *testing.T) { 4500 cases := []struct { 4501 name string 4502 mconfig *StreamConfig 4503 }{ 4504 {"MemoryStore", &StreamConfig{Name: "ADS", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4505 {"FileStore", &StreamConfig{Name: "ADS", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4506 } 4507 for _, c := range cases { 4508 t.Run(c.name, func(t *testing.T) { 4509 s := RunBasicJetStreamServer(t) 4510 defer s.Shutdown() 4511 4512 mset, err := s.GlobalAccount().addStream(c.mconfig) 4513 if err != nil { 4514 t.Fatalf("Unexpected error adding stream: %v", err) 4515 } 4516 defer mset.delete() 4517 4518 nc := clientConnectToServer(t, s) 4519 defer nc.Close() 4520 4521 // Now load up some messages. 4522 toSend := 100 4523 sendSubj := "foo.22" 4524 for i := 0; i < toSend; i++ { 4525 sendStreamMsg(t, nc, sendSubj, "Hello World!") 4526 } 4527 state := mset.state() 4528 if state.Msgs != uint64(toSend) { 4529 t.Fatalf("Expected %d messages, got %d", toSend, state.Msgs) 4530 } 4531 4532 o, err := mset.addConsumer(&ConsumerConfig{Durable: "to", DeliverSubject: "d"}) 4533 if err != nil { 4534 t.Fatalf("Expected no error with registered interest, got %v", err) 4535 } 4536 defer o.delete() 4537 4538 // We have no active interest above. So consumer will be considered inactive. Let's subscribe and make sure 4539 // we get the messages instantly. This will test that we hook interest activation correctly. 4540 sub, _ := nc.SubscribeSync("d") 4541 defer sub.Unsubscribe() 4542 nc.Flush() 4543 4544 checkFor(t, 100*time.Millisecond, 10*time.Millisecond, func() error { 4545 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 4546 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 4547 } 4548 return nil 4549 }) 4550 }) 4551 } 4552 } 4553 4554 func TestJetStreamEphemeralConsumers(t *testing.T) { 4555 cases := []struct { 4556 name string 4557 mconfig *StreamConfig 4558 }{ 4559 {"MemoryStore", &StreamConfig{Name: "EP", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4560 {"FileStore", &StreamConfig{Name: "EP", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4561 } 4562 for _, c := range cases { 4563 t.Run(c.name, func(t *testing.T) { 4564 s := RunBasicJetStreamServer(t) 4565 defer s.Shutdown() 4566 4567 mset, err := s.GlobalAccount().addStream(c.mconfig) 4568 if err != nil { 4569 t.Fatalf("Unexpected error adding stream: %v", err) 4570 } 4571 defer mset.delete() 4572 4573 nc := clientConnectToServer(t, s) 4574 defer nc.Close() 4575 4576 sub, _ := nc.SubscribeSync(nats.NewInbox()) 4577 defer sub.Unsubscribe() 4578 nc.Flush() 4579 4580 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 4581 if err != nil { 4582 t.Fatalf("Unexpected error: %v", err) 4583 } 4584 if !o.isActive() { 4585 t.Fatalf("Expected the consumer to be considered active") 4586 } 4587 if numo := mset.numConsumers(); numo != 1 { 4588 t.Fatalf("Expected number of consumers to be 1, got %d", numo) 4589 } 4590 // Set our delete threshold to something low for testing purposes. 4591 o.setInActiveDeleteThreshold(100 * time.Millisecond) 4592 4593 // Make sure works now. 4594 nc.Request("foo.22", nil, 100*time.Millisecond) 4595 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 4596 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 1 { 4597 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, 1) 4598 } 4599 return nil 4600 }) 4601 4602 // Now close the subscription, this should trip active state on the ephemeral consumer. 4603 sub.Unsubscribe() 4604 checkFor(t, time.Second, 10*time.Millisecond, func() error { 4605 if o.isActive() { 4606 return fmt.Errorf("Expected the ephemeral consumer to be considered inactive") 4607 } 4608 return nil 4609 }) 4610 // The reason for this still being 1 is that we give some time in case of a reconnect scenario. 4611 // We detect right away on the interest change but we wait for interest to be re-established. 4612 // This is in case server goes away but app is fine, we do not want to recycle those consumers. 4613 if numo := mset.numConsumers(); numo != 1 { 4614 t.Fatalf("Expected number of consumers to be 1, got %d", numo) 4615 } 4616 4617 // We should delete this one after the delete threshold. 4618 checkFor(t, time.Second, 100*time.Millisecond, func() error { 4619 if numo := mset.numConsumers(); numo != 0 { 4620 return fmt.Errorf("Expected number of consumers to be 0, got %d", numo) 4621 } 4622 return nil 4623 }) 4624 }) 4625 } 4626 } 4627 4628 func TestJetStreamConsumerReconnect(t *testing.T) { 4629 cases := []struct { 4630 name string 4631 mconfig *StreamConfig 4632 }{ 4633 {"MemoryStore", &StreamConfig{Name: "ET", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4634 {"FileStore", &StreamConfig{Name: "ET", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4635 } 4636 for _, c := range cases { 4637 t.Run(c.name, func(t *testing.T) { 4638 s := RunBasicJetStreamServer(t) 4639 defer s.Shutdown() 4640 4641 mset, err := s.GlobalAccount().addStream(c.mconfig) 4642 if err != nil { 4643 t.Fatalf("Unexpected error adding stream: %v", err) 4644 } 4645 defer mset.delete() 4646 4647 nc := clientConnectToServer(t, s) 4648 defer nc.Close() 4649 4650 sub, _ := nc.SubscribeSync(nats.NewInbox()) 4651 defer sub.Unsubscribe() 4652 nc.Flush() 4653 4654 // Capture the subscription. 4655 delivery := sub.Subject 4656 4657 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, AckPolicy: AckExplicit}) 4658 if err != nil { 4659 t.Fatalf("Unexpected error: %v", err) 4660 } 4661 if !o.isActive() { 4662 t.Fatalf("Expected the consumer to be considered active") 4663 } 4664 if numo := mset.numConsumers(); numo != 1 { 4665 t.Fatalf("Expected number of consumers to be 1, got %d", numo) 4666 } 4667 4668 // We will simulate reconnect by unsubscribing on one connection and forming 4669 // the same on another. Once we have cluster tests we will do more testing on 4670 // reconnect scenarios. 4671 getMsg := func(seqno int) *nats.Msg { 4672 t.Helper() 4673 m, err := sub.NextMsg(time.Second) 4674 if err != nil { 4675 t.Fatalf("Unexpected error for %d: %v", seqno, err) 4676 } 4677 if seq := o.seqFromReply(m.Reply); seq != uint64(seqno) { 4678 t.Fatalf("Expected sequence of %d , got %d", seqno, seq) 4679 } 4680 m.Respond(nil) 4681 return m 4682 } 4683 4684 sendMsg := func() { 4685 t.Helper() 4686 if err := nc.Publish("foo.22", []byte("OK!")); err != nil { 4687 return 4688 } 4689 } 4690 4691 checkForInActive := func() { 4692 checkFor(t, 250*time.Millisecond, 50*time.Millisecond, func() error { 4693 if o.isActive() { 4694 return fmt.Errorf("Consumer is still active") 4695 } 4696 return nil 4697 }) 4698 } 4699 4700 // Send and Pull first message. 4701 sendMsg() // 1 4702 getMsg(1) 4703 // Cancel first one. 4704 sub.Unsubscribe() 4705 // Re-establish new sub on same subject. 4706 sub, _ = nc.SubscribeSync(delivery) 4707 nc.Flush() 4708 4709 // We should be getting 2 here. 4710 sendMsg() // 2 4711 getMsg(2) 4712 4713 sub.Unsubscribe() 4714 checkForInActive() 4715 4716 // send 3-10 4717 for i := 0; i <= 7; i++ { 4718 sendMsg() 4719 } 4720 // Make sure they are all queued up with no interest. 4721 nc.Flush() 4722 4723 // Restablish again. 4724 sub, _ = nc.SubscribeSync(delivery) 4725 nc.Flush() 4726 4727 // We should be getting 3-10 here. 4728 for i := 3; i <= 10; i++ { 4729 getMsg(i) 4730 } 4731 }) 4732 } 4733 } 4734 4735 func TestJetStreamDurableConsumerReconnect(t *testing.T) { 4736 cases := []struct { 4737 name string 4738 mconfig *StreamConfig 4739 }{ 4740 {"MemoryStore", &StreamConfig{Name: "DT", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4741 {"FileStore", &StreamConfig{Name: "DT", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4742 } 4743 for _, c := range cases { 4744 t.Run(c.name, func(t *testing.T) { 4745 s := RunBasicJetStreamServer(t) 4746 defer s.Shutdown() 4747 4748 mset, err := s.GlobalAccount().addStream(c.mconfig) 4749 if err != nil { 4750 t.Fatalf("Unexpected error adding stream: %v", err) 4751 } 4752 defer mset.delete() 4753 4754 nc := clientConnectToServer(t, s) 4755 defer nc.Close() 4756 4757 dname := "d22" 4758 subj1 := nats.NewInbox() 4759 4760 o, err := mset.addConsumer(&ConsumerConfig{ 4761 Durable: dname, 4762 DeliverSubject: subj1, 4763 AckPolicy: AckExplicit, 4764 AckWait: 50 * time.Millisecond}) 4765 if err != nil { 4766 t.Fatalf("Unexpected error: %v", err) 4767 } 4768 sendMsg := func() { 4769 t.Helper() 4770 if err := nc.Publish("foo.22", []byte("OK!")); err != nil { 4771 return 4772 } 4773 } 4774 4775 // Send 10 msgs 4776 toSend := 10 4777 for i := 0; i < toSend; i++ { 4778 sendMsg() 4779 } 4780 4781 sub, _ := nc.SubscribeSync(subj1) 4782 defer sub.Unsubscribe() 4783 4784 checkFor(t, 500*time.Millisecond, 10*time.Millisecond, func() error { 4785 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 4786 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 4787 } 4788 return nil 4789 }) 4790 4791 getMsg := func(seqno int) *nats.Msg { 4792 t.Helper() 4793 m, err := sub.NextMsg(time.Second) 4794 if err != nil { 4795 t.Fatalf("Unexpected error: %v", err) 4796 } 4797 if seq := o.streamSeqFromReply(m.Reply); seq != uint64(seqno) { 4798 t.Fatalf("Expected sequence of %d , got %d", seqno, seq) 4799 } 4800 m.Respond(nil) 4801 return m 4802 } 4803 4804 // Ack first half 4805 for i := 1; i <= toSend/2; i++ { 4806 m := getMsg(i) 4807 m.Respond(nil) 4808 } 4809 4810 // Now unsubscribe and wait to become inactive 4811 sub.Unsubscribe() 4812 checkFor(t, 250*time.Millisecond, 50*time.Millisecond, func() error { 4813 if o.isActive() { 4814 return fmt.Errorf("Consumer is still active") 4815 } 4816 return nil 4817 }) 4818 4819 // Now we should be able to replace the delivery subject. 4820 subj2 := nats.NewInbox() 4821 sub, _ = nc.SubscribeSync(subj2) 4822 defer sub.Unsubscribe() 4823 nc.Flush() 4824 4825 o, err = mset.addConsumer(&ConsumerConfig{ 4826 Durable: dname, 4827 DeliverSubject: subj2, 4828 AckPolicy: AckExplicit, 4829 AckWait: 50 * time.Millisecond}) 4830 if err != nil { 4831 t.Fatalf("Unexpected error trying to add a new durable consumer: %v", err) 4832 } 4833 4834 // We should get the remaining messages here. 4835 for i := toSend/2 + 1; i <= toSend; i++ { 4836 m := getMsg(i) 4837 m.Respond(nil) 4838 } 4839 }) 4840 } 4841 } 4842 4843 func TestJetStreamDurableConsumerReconnectWithOnlyPending(t *testing.T) { 4844 cases := []struct { 4845 name string 4846 mconfig *StreamConfig 4847 }{ 4848 {"MemoryStore", &StreamConfig{Name: "DT", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4849 {"FileStore", &StreamConfig{Name: "DT", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4850 } 4851 for _, c := range cases { 4852 t.Run(c.name, func(t *testing.T) { 4853 s := RunBasicJetStreamServer(t) 4854 defer s.Shutdown() 4855 4856 mset, err := s.GlobalAccount().addStream(c.mconfig) 4857 if err != nil { 4858 t.Fatalf("Unexpected error adding stream: %v", err) 4859 } 4860 defer mset.delete() 4861 4862 nc := clientConnectToServer(t, s) 4863 defer nc.Close() 4864 4865 dname := "d22" 4866 subj1 := nats.NewInbox() 4867 4868 o, err := mset.addConsumer(&ConsumerConfig{ 4869 Durable: dname, 4870 DeliverSubject: subj1, 4871 AckPolicy: AckExplicit, 4872 AckWait: 25 * time.Millisecond}) 4873 if err != nil { 4874 t.Fatalf("Unexpected error: %v", err) 4875 } 4876 4877 sendMsg := func(payload string) { 4878 t.Helper() 4879 if err := nc.Publish("foo.22", []byte(payload)); err != nil { 4880 return 4881 } 4882 } 4883 4884 sendMsg("1") 4885 4886 sub, _ := nc.SubscribeSync(subj1) 4887 defer sub.Unsubscribe() 4888 4889 checkFor(t, 500*time.Millisecond, 10*time.Millisecond, func() error { 4890 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != 1 { 4891 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, 1) 4892 } 4893 return nil 4894 }) 4895 4896 // Now unsubscribe and wait to become inactive 4897 sub.Unsubscribe() 4898 checkFor(t, 250*time.Millisecond, 50*time.Millisecond, func() error { 4899 if o.isActive() { 4900 return fmt.Errorf("Consumer is still active") 4901 } 4902 return nil 4903 }) 4904 4905 // Send the second message while delivery subscriber is not running 4906 sendMsg("2") 4907 4908 // Now we should be able to replace the delivery subject. 4909 subj2 := nats.NewInbox() 4910 o, err = mset.addConsumer(&ConsumerConfig{ 4911 Durable: dname, 4912 DeliverSubject: subj2, 4913 AckPolicy: AckExplicit, 4914 AckWait: 25 * time.Millisecond}) 4915 if err != nil { 4916 t.Fatalf("Unexpected error trying to add a new durable consumer: %v", err) 4917 } 4918 sub, _ = nc.SubscribeSync(subj2) 4919 defer sub.Unsubscribe() 4920 nc.Flush() 4921 4922 // We should get msg "1" and "2" delivered. They will be reversed. 4923 for i := 0; i < 2; i++ { 4924 msg, err := sub.NextMsg(500 * time.Millisecond) 4925 if err != nil { 4926 t.Fatalf("Unexpected error: %v", err) 4927 } 4928 sseq, _, dc, _, _ := replyInfo(msg.Reply) 4929 if sseq == 1 && dc == 1 { 4930 t.Fatalf("Expected a redelivery count greater then 1 for sseq 1, got %d", dc) 4931 } 4932 if sseq != 1 && sseq != 2 { 4933 t.Fatalf("Expected stream sequence of 1 or 2 but got %d", sseq) 4934 } 4935 } 4936 }) 4937 } 4938 } 4939 4940 func TestJetStreamDurableFilteredSubjectConsumerReconnect(t *testing.T) { 4941 cases := []struct { 4942 name string 4943 mconfig *StreamConfig 4944 }{ 4945 {"MemoryStore", &StreamConfig{Name: "DT", Storage: MemoryStorage, Subjects: []string{"foo.*"}}}, 4946 {"FileStore", &StreamConfig{Name: "DT", Storage: FileStorage, Subjects: []string{"foo.*"}}}, 4947 } 4948 for _, c := range cases { 4949 t.Run(c.name, func(t *testing.T) { 4950 s := RunBasicJetStreamServer(t) 4951 defer s.Shutdown() 4952 4953 mset, err := s.GlobalAccount().addStream(c.mconfig) 4954 if err != nil { 4955 t.Fatalf("Unexpected error adding stream: %v", err) 4956 } 4957 defer mset.delete() 4958 4959 nc, js := jsClientConnect(t, s) 4960 defer nc.Close() 4961 4962 sendMsgs := func(toSend int) { 4963 for i := 0; i < toSend; i++ { 4964 var subj string 4965 if i%2 == 0 { 4966 subj = "foo.AA" 4967 } else { 4968 subj = "foo.ZZ" 4969 } 4970 _, err := js.Publish(subj, []byte("OK!")) 4971 require_NoError(t, err) 4972 } 4973 } 4974 4975 // Send 50 msgs 4976 toSend := 50 4977 sendMsgs(toSend) 4978 4979 dname := "d33" 4980 dsubj := nats.NewInbox() 4981 4982 // Now create an consumer for foo.AA, only requesting the last one. 4983 _, err = mset.addConsumer(&ConsumerConfig{ 4984 Durable: dname, 4985 DeliverSubject: dsubj, 4986 FilterSubject: "foo.AA", 4987 DeliverPolicy: DeliverLast, 4988 AckPolicy: AckExplicit, 4989 AckWait: 100 * time.Millisecond, 4990 }) 4991 if err != nil { 4992 t.Fatalf("Unexpected error: %v", err) 4993 } 4994 sub, _ := nc.SubscribeSync(dsubj) 4995 defer sub.Unsubscribe() 4996 4997 // Used to calculate difference between store seq and delivery seq. 4998 storeBaseOff := 47 4999 5000 getMsg := func(seq int) *nats.Msg { 5001 t.Helper() 5002 sseq := 2*seq + storeBaseOff 5003 m, err := sub.NextMsg(time.Second) 5004 if err != nil { 5005 t.Fatalf("Unexpected error: %v", err) 5006 } 5007 rsseq, roseq, dcount, _, _ := replyInfo(m.Reply) 5008 if roseq != uint64(seq) { 5009 t.Fatalf("Expected consumer sequence of %d , got %d", seq, roseq) 5010 } 5011 if rsseq != uint64(sseq) { 5012 t.Fatalf("Expected stream sequence of %d , got %d", sseq, rsseq) 5013 } 5014 if dcount != 1 { 5015 t.Fatalf("Expected message to not be marked as redelivered") 5016 } 5017 return m 5018 } 5019 5020 getRedeliveredMsg := func(seq int) *nats.Msg { 5021 t.Helper() 5022 m, err := sub.NextMsg(time.Second) 5023 if err != nil { 5024 t.Fatalf("Unexpected error: %v", err) 5025 } 5026 _, roseq, dcount, _, _ := replyInfo(m.Reply) 5027 if roseq != uint64(seq) { 5028 t.Fatalf("Expected consumer sequence of %d , got %d", seq, roseq) 5029 } 5030 if dcount < 2 { 5031 t.Fatalf("Expected message to be marked as redelivered") 5032 } 5033 // Ack this message. 5034 m.Respond(nil) 5035 return m 5036 } 5037 5038 // All consumers start at 1 and always have increasing sequence numbers. 5039 m := getMsg(1) 5040 m.Respond(nil) 5041 5042 // Now send 50 more, so 100 total, 26 (last + 50/2) for this consumer. 5043 sendMsgs(toSend) 5044 5045 state := mset.state() 5046 if state.Msgs != uint64(toSend*2) { 5047 t.Fatalf("Expected %d messages, got %d", toSend*2, state.Msgs) 5048 } 5049 5050 // For tracking next expected. 5051 nextSeq := 2 5052 noAcks := 0 5053 for i := 0; i < toSend/2; i++ { 5054 m := getMsg(nextSeq) 5055 if i%2 == 0 { 5056 m.Respond(nil) // Ack evens. 5057 } else { 5058 noAcks++ 5059 } 5060 nextSeq++ 5061 } 5062 5063 // We should now get those redelivered. 5064 for i := 0; i < noAcks; i++ { 5065 getRedeliveredMsg(nextSeq) 5066 nextSeq++ 5067 } 5068 5069 // Now send 50 more. 5070 sendMsgs(toSend) 5071 5072 storeBaseOff -= noAcks * 2 5073 5074 for i := 0; i < toSend/2; i++ { 5075 m := getMsg(nextSeq) 5076 m.Respond(nil) 5077 nextSeq++ 5078 } 5079 }) 5080 } 5081 } 5082 5083 func TestJetStreamConsumerInactiveNoDeadlock(t *testing.T) { 5084 cases := []struct { 5085 name string 5086 mconfig *StreamConfig 5087 }{ 5088 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5089 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5090 } 5091 for _, c := range cases { 5092 t.Run(c.name, func(t *testing.T) { 5093 s := RunBasicJetStreamServer(t) 5094 defer s.Shutdown() 5095 5096 mset, err := s.GlobalAccount().addStream(c.mconfig) 5097 if err != nil { 5098 t.Fatalf("Unexpected error adding stream: %v", err) 5099 } 5100 defer mset.delete() 5101 5102 nc, js := jsClientConnect(t, s) 5103 defer nc.Close() 5104 5105 // Send lots of msgs and have them queued up. 5106 for i := 0; i < 10000; i++ { 5107 js.Publish("DC", []byte("OK!")) 5108 } 5109 5110 if state := mset.state(); state.Msgs != 10000 { 5111 t.Fatalf("Expected %d messages, got %d", 10000, state.Msgs) 5112 } 5113 5114 sub, _ := nc.SubscribeSync(nats.NewInbox()) 5115 sub.SetPendingLimits(-1, -1) 5116 defer sub.Unsubscribe() 5117 nc.Flush() 5118 5119 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 5120 if err != nil { 5121 t.Fatalf("Unexpected error: %v", err) 5122 } 5123 defer o.delete() 5124 5125 for i := 0; i < 10; i++ { 5126 if _, err := sub.NextMsg(time.Second); err != nil { 5127 t.Fatalf("Unexpected error: %v", err) 5128 } 5129 } 5130 // Force us to become inactive but we want to make sure we do not lock up 5131 // the internal sendq. 5132 sub.Unsubscribe() 5133 nc.Flush() 5134 }) 5135 } 5136 } 5137 5138 func TestJetStreamMetadata(t *testing.T) { 5139 cases := []struct { 5140 name string 5141 mconfig *StreamConfig 5142 }{ 5143 {"MemoryStore", &StreamConfig{Name: "DC", Retention: WorkQueuePolicy, Storage: MemoryStorage}}, 5144 {"FileStore", &StreamConfig{Name: "DC", Retention: WorkQueuePolicy, Storage: FileStorage}}, 5145 } 5146 5147 for _, c := range cases { 5148 t.Run(c.name, func(t *testing.T) { 5149 s := RunBasicJetStreamServer(t) 5150 defer s.Shutdown() 5151 5152 mset, err := s.GlobalAccount().addStream(c.mconfig) 5153 if err != nil { 5154 t.Fatalf("Unexpected error adding stream: %v", err) 5155 } 5156 defer mset.delete() 5157 5158 nc := clientConnectToServer(t, s) 5159 defer nc.Close() 5160 5161 for i := 0; i < 10; i++ { 5162 nc.Publish("DC", []byte("OK!")) 5163 nc.Flush() 5164 time.Sleep(time.Millisecond) 5165 } 5166 5167 if state := mset.state(); state.Msgs != 10 { 5168 t.Fatalf("Expected %d messages, got %d", 10, state.Msgs) 5169 } 5170 5171 o, err := mset.addConsumer(workerModeConfig("WQ")) 5172 if err != nil { 5173 t.Fatalf("Expected no error with registered interest, got %v", err) 5174 } 5175 defer o.delete() 5176 5177 for i := uint64(1); i <= 10; i++ { 5178 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 5179 if err != nil { 5180 t.Fatalf("Unexpected error: %v", err) 5181 } 5182 5183 sseq, dseq, dcount, ts, _ := replyInfo(m.Reply) 5184 5185 mreq := &JSApiMsgGetRequest{Seq: sseq} 5186 req, err := json.Marshal(mreq) 5187 if err != nil { 5188 t.Fatalf("Unexpected error: %v", err) 5189 } 5190 // Load the original message from the stream to verify ReplyInfo ts against stored message 5191 smsgj, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, c.mconfig.Name), req, time.Second) 5192 if err != nil { 5193 t.Fatalf("Could not retrieve stream message: %v", err) 5194 } 5195 5196 var resp JSApiMsgGetResponse 5197 err = json.Unmarshal(smsgj.Data, &resp) 5198 if err != nil { 5199 t.Fatalf("Could not parse stream message: %v", err) 5200 } 5201 if resp.Message == nil || resp.Error != nil { 5202 t.Fatalf("Did not receive correct response") 5203 } 5204 smsg := resp.Message 5205 if ts != smsg.Time.UnixNano() { 5206 t.Fatalf("Wrong timestamp in ReplyInfo for msg %d, expected %v got %v", i, ts, smsg.Time.UnixNano()) 5207 } 5208 if sseq != i { 5209 t.Fatalf("Expected set sequence of %d, got %d", i, sseq) 5210 } 5211 if dseq != i { 5212 t.Fatalf("Expected delivery sequence of %d, got %d", i, dseq) 5213 } 5214 if dcount != 1 { 5215 t.Fatalf("Expected delivery count to be 1, got %d", dcount) 5216 } 5217 m.Respond(AckAck) 5218 } 5219 5220 // Now make sure we get right response when message is missing. 5221 mreq := &JSApiMsgGetRequest{Seq: 1} 5222 req, err := json.Marshal(mreq) 5223 if err != nil { 5224 t.Fatalf("Unexpected error: %v", err) 5225 } 5226 // Load the original message from the stream to verify ReplyInfo ts against stored message 5227 rmsg, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, c.mconfig.Name), req, time.Second) 5228 if err != nil { 5229 t.Fatalf("Could not retrieve stream message: %v", err) 5230 } 5231 var resp JSApiMsgGetResponse 5232 err = json.Unmarshal(rmsg.Data, &resp) 5233 if err != nil { 5234 t.Fatalf("Could not parse stream message: %v", err) 5235 } 5236 if resp.Error == nil || resp.Error.Code != 404 || resp.Error.Description != "no message found" { 5237 t.Fatalf("Did not get correct error response: %+v", resp.Error) 5238 } 5239 }) 5240 } 5241 } 5242 func TestJetStreamRedeliverCount(t *testing.T) { 5243 cases := []struct { 5244 name string 5245 mconfig *StreamConfig 5246 }{ 5247 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5248 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5249 } 5250 for _, c := range cases { 5251 t.Run(c.name, func(t *testing.T) { 5252 s := RunBasicJetStreamServer(t) 5253 defer s.Shutdown() 5254 5255 mset, err := s.GlobalAccount().addStream(c.mconfig) 5256 if err != nil { 5257 t.Fatalf("Unexpected error adding stream: %v", err) 5258 } 5259 defer mset.delete() 5260 5261 nc, js := jsClientConnect(t, s) 5262 defer nc.Close() 5263 5264 if _, err = js.Publish("DC", []byte("OK!")); err != nil { 5265 t.Fatal(err) 5266 } 5267 checkFor(t, time.Second, time.Millisecond*250, func() error { 5268 if state := mset.state(); state.Msgs != 1 { 5269 return fmt.Errorf("Expected %d messages, got %d", 1, state.Msgs) 5270 } 5271 return nil 5272 }) 5273 5274 o, err := mset.addConsumer(workerModeConfig("WQ")) 5275 if err != nil { 5276 t.Fatalf("Expected no error with registered interest, got %v", err) 5277 } 5278 defer o.delete() 5279 5280 for i := uint64(1); i <= 10; i++ { 5281 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 5282 if err != nil { 5283 t.Fatalf("Unexpected error: %v", err) 5284 } 5285 5286 sseq, dseq, dcount, _, _ := replyInfo(m.Reply) 5287 5288 // Make sure we keep getting stream sequence #1 5289 if sseq != 1 { 5290 t.Fatalf("Expected set sequence of 1, got %d", sseq) 5291 } 5292 if dseq != i { 5293 t.Fatalf("Expected delivery sequence of %d, got %d", i, dseq) 5294 } 5295 // Now make sure dcount is same as dseq (or i). 5296 if dcount != i { 5297 t.Fatalf("Expected delivery count to be %d, got %d", i, dcount) 5298 } 5299 5300 // Make sure it keeps getting sent back. 5301 m.Respond(AckNak) 5302 nc.Flush() 5303 } 5304 }) 5305 } 5306 } 5307 5308 // We want to make sure that for pull based consumers that if we ack 5309 // late with no interest the redelivery attempt is removed and we do 5310 // not get the message back. 5311 func TestJetStreamRedeliverAndLateAck(t *testing.T) { 5312 s := RunBasicJetStreamServer(t) 5313 defer s.Shutdown() 5314 5315 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "LA", Storage: MemoryStorage}) 5316 if err != nil { 5317 t.Fatalf("Unexpected error adding stream: %v", err) 5318 } 5319 defer mset.delete() 5320 5321 o, err := mset.addConsumer(&ConsumerConfig{Durable: "DDD", AckPolicy: AckExplicit, AckWait: 100 * time.Millisecond}) 5322 if err != nil { 5323 t.Fatalf("Expected no error with registered interest, got %v", err) 5324 } 5325 defer o.delete() 5326 5327 nc := clientConnectToServer(t, s) 5328 defer nc.Close() 5329 5330 // Queue up message 5331 sendStreamMsg(t, nc, "LA", "Hello World!") 5332 5333 nextSubj := o.requestNextMsgSubject() 5334 msg, err := nc.Request(nextSubj, nil, time.Second) 5335 require_NoError(t, err) 5336 5337 // Wait for past ackwait time 5338 time.Sleep(150 * time.Millisecond) 5339 // Now ack! 5340 msg.AckSync() 5341 // We should not get this back. 5342 if _, err := nc.Request(nextSubj, nil, 10*time.Millisecond); err == nil { 5343 t.Fatalf("Message should not have been sent back") 5344 } 5345 } 5346 5347 // https://github.com/nats-io/nats-server/issues/1502 5348 func TestJetStreamPendingNextTimer(t *testing.T) { 5349 s := RunBasicJetStreamServer(t) 5350 defer s.Shutdown() 5351 5352 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "NT", Storage: MemoryStorage, Subjects: []string{"ORDERS.*"}}) 5353 if err != nil { 5354 t.Fatalf("Unexpected error adding stream: %v", err) 5355 } 5356 defer mset.delete() 5357 5358 o, err := mset.addConsumer(&ConsumerConfig{ 5359 Durable: "DDD", 5360 AckPolicy: AckExplicit, 5361 FilterSubject: "ORDERS.test", 5362 AckWait: 100 * time.Millisecond, 5363 }) 5364 if err != nil { 5365 t.Fatalf("Expected no error with registered interest, got %v", err) 5366 } 5367 defer o.delete() 5368 5369 sendAndReceive := func() { 5370 nc := clientConnectToServer(t, s) 5371 defer nc.Close() 5372 5373 // Queue up message 5374 sendStreamMsg(t, nc, "ORDERS.test", "Hello World! #1") 5375 sendStreamMsg(t, nc, "ORDERS.test", "Hello World! #2") 5376 5377 nextSubj := o.requestNextMsgSubject() 5378 for i := 0; i < 2; i++ { 5379 if _, err := nc.Request(nextSubj, nil, time.Second); err != nil { 5380 t.Fatalf("Unexpected error: %v", err) 5381 } 5382 } 5383 nc.Close() 5384 time.Sleep(200 * time.Millisecond) 5385 } 5386 5387 sendAndReceive() 5388 sendAndReceive() 5389 sendAndReceive() 5390 } 5391 5392 func TestJetStreamCanNotNakAckd(t *testing.T) { 5393 cases := []struct { 5394 name string 5395 mconfig *StreamConfig 5396 }{ 5397 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5398 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5399 } 5400 for _, c := range cases { 5401 t.Run(c.name, func(t *testing.T) { 5402 s := RunBasicJetStreamServer(t) 5403 defer s.Shutdown() 5404 5405 mset, err := s.GlobalAccount().addStream(c.mconfig) 5406 if err != nil { 5407 t.Fatalf("Unexpected error adding stream: %v", err) 5408 } 5409 defer mset.delete() 5410 5411 nc, js := jsClientConnect(t, s) 5412 defer nc.Close() 5413 5414 // Send 10 msgs 5415 for i := 0; i < 10; i++ { 5416 js.Publish("DC", []byte("OK!")) 5417 } 5418 if state := mset.state(); state.Msgs != 10 { 5419 t.Fatalf("Expected %d messages, got %d", 10, state.Msgs) 5420 } 5421 5422 o, err := mset.addConsumer(workerModeConfig("WQ")) 5423 if err != nil { 5424 t.Fatalf("Expected no error with registered interest, got %v", err) 5425 } 5426 defer o.delete() 5427 5428 for i := uint64(1); i <= 10; i++ { 5429 m, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 5430 if err != nil { 5431 t.Fatalf("Unexpected error: %v", err) 5432 } 5433 // Ack evens. 5434 if i%2 == 0 { 5435 m.Respond(nil) 5436 } 5437 } 5438 nc.Flush() 5439 5440 // Fake these for now. 5441 ackReplyT := "$JS.A.DC.WQ.1.%d.%d" 5442 checkBadNak := func(seq int) { 5443 t.Helper() 5444 if err := nc.Publish(fmt.Sprintf(ackReplyT, seq, seq), AckNak); err != nil { 5445 t.Fatalf("Error sending nak: %v", err) 5446 } 5447 nc.Flush() 5448 if _, err := nc.Request(o.requestNextMsgSubject(), nil, 10*time.Millisecond); err != nats.ErrTimeout { 5449 t.Fatalf("Did not expect new delivery on nak of %d", seq) 5450 } 5451 } 5452 5453 // If the nak took action it will deliver another message, incrementing the next delivery seq. 5454 // We ack evens above, so these should fail 5455 for i := 2; i <= 10; i += 2 { 5456 checkBadNak(i) 5457 } 5458 5459 // Now check we can not nak something we do not have. 5460 checkBadNak(22) 5461 }) 5462 } 5463 } 5464 5465 func TestJetStreamStreamPurge(t *testing.T) { 5466 cases := []struct { 5467 name string 5468 mconfig *StreamConfig 5469 }{ 5470 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5471 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5472 } 5473 for _, c := range cases { 5474 t.Run(c.name, func(t *testing.T) { 5475 s := RunBasicJetStreamServer(t) 5476 defer s.Shutdown() 5477 5478 mset, err := s.GlobalAccount().addStream(c.mconfig) 5479 if err != nil { 5480 t.Fatalf("Unexpected error adding stream: %v", err) 5481 } 5482 defer mset.delete() 5483 5484 nc, js := jsClientConnect(t, s) 5485 defer nc.Close() 5486 5487 // Send 100 msgs 5488 for i := 0; i < 100; i++ { 5489 js.Publish("DC", []byte("OK!")) 5490 } 5491 if state := mset.state(); state.Msgs != 100 { 5492 t.Fatalf("Expected %d messages, got %d", 100, state.Msgs) 5493 } 5494 mset.purge(nil) 5495 state := mset.state() 5496 if state.Msgs != 0 { 5497 t.Fatalf("Expected %d messages, got %d", 0, state.Msgs) 5498 } 5499 // Make sure first timestamp are reset. 5500 if !state.FirstTime.IsZero() { 5501 t.Fatalf("Expected the state's first time to be zero after purge") 5502 } 5503 time.Sleep(10 * time.Millisecond) 5504 now := time.Now() 5505 js.Publish("DC", []byte("OK!")) 5506 5507 state = mset.state() 5508 if state.Msgs != 1 { 5509 t.Fatalf("Expected %d message, got %d", 1, state.Msgs) 5510 } 5511 if state.FirstTime.Before(now) { 5512 t.Fatalf("First time is incorrect after adding messages back in") 5513 } 5514 if state.FirstTime != state.LastTime { 5515 t.Fatalf("Expected first and last times to be the same for only message") 5516 } 5517 }) 5518 } 5519 } 5520 5521 func TestJetStreamStreamPurgeWithConsumer(t *testing.T) { 5522 cases := []struct { 5523 name string 5524 mconfig *StreamConfig 5525 }{ 5526 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5527 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5528 } 5529 for _, c := range cases { 5530 t.Run(c.name, func(t *testing.T) { 5531 s := RunBasicJetStreamServer(t) 5532 defer s.Shutdown() 5533 5534 mset, err := s.GlobalAccount().addStream(c.mconfig) 5535 if err != nil { 5536 t.Fatalf("Unexpected error adding stream: %v", err) 5537 } 5538 defer mset.delete() 5539 5540 nc, js := jsClientConnect(t, s) 5541 defer nc.Close() 5542 5543 // Send 100 msgs 5544 for i := 0; i < 100; i++ { 5545 js.Publish("DC", []byte("OK!")) 5546 } 5547 if state := mset.state(); state.Msgs != 100 { 5548 t.Fatalf("Expected %d messages, got %d", 100, state.Msgs) 5549 } 5550 // Now create an consumer and make sure it functions properly. 5551 o, err := mset.addConsumer(workerModeConfig("WQ")) 5552 if err != nil { 5553 t.Fatalf("Expected no error with registered interest, got %v", err) 5554 } 5555 defer o.delete() 5556 nextSubj := o.requestNextMsgSubject() 5557 for i := 0; i < 50; i++ { 5558 msg, err := nc.Request(nextSubj, nil, time.Second) 5559 if err != nil { 5560 t.Fatalf("Unexpected error: %v", err) 5561 } 5562 // Ack. 5563 msg.Respond(nil) 5564 } 5565 // Now grab next 25 without ack. 5566 for i := 0; i < 25; i++ { 5567 if _, err := nc.Request(nextSubj, nil, time.Second); err != nil { 5568 t.Fatalf("Unexpected error: %v", err) 5569 } 5570 } 5571 state := o.info() 5572 if state.AckFloor.Consumer != 50 { 5573 t.Fatalf("Expected ack floor of 50, got %d", state.AckFloor.Consumer) 5574 } 5575 if state.NumAckPending != 25 { 5576 t.Fatalf("Expected len(pending) to be 25, got %d", state.NumAckPending) 5577 } 5578 // Now do purge. 5579 mset.purge(nil) 5580 if state := mset.state(); state.Msgs != 0 { 5581 t.Fatalf("Expected %d messages, got %d", 0, state.Msgs) 5582 } 5583 // Now re-acquire state and check that we did the right thing. 5584 // Pending should be cleared, and stream sequences should have been set 5585 // to the total messages before purge + 1. 5586 state = o.info() 5587 if state.NumAckPending != 0 { 5588 t.Fatalf("Expected no pending, got %d", state.NumAckPending) 5589 } 5590 if state.Delivered.Stream != 100 { 5591 t.Fatalf("Expected to have setseq now at next seq of 100, got %d", state.Delivered.Stream) 5592 } 5593 // Check AckFloors which should have also been adjusted. 5594 if state.AckFloor.Stream != 100 { 5595 t.Fatalf("Expected ackfloor for setseq to be 100, got %d", state.AckFloor.Stream) 5596 } 5597 if state.AckFloor.Consumer != 75 { 5598 t.Fatalf("Expected ackfloor for obsseq to be 75, got %d", state.AckFloor.Consumer) 5599 } 5600 // Also make sure we can get new messages correctly. 5601 js.Publish("DC", []byte("OK-22")) 5602 if msg, err := nc.Request(nextSubj, nil, time.Second); err != nil { 5603 t.Fatalf("Unexpected error: %v", err) 5604 } else if string(msg.Data) != "OK-22" { 5605 t.Fatalf("Received wrong message, wanted 'OK-22', got %q", msg.Data) 5606 } 5607 }) 5608 } 5609 } 5610 5611 func TestJetStreamStreamPurgeWithConsumerAndRedelivery(t *testing.T) { 5612 cases := []struct { 5613 name string 5614 mconfig *StreamConfig 5615 }{ 5616 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 5617 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 5618 } 5619 for _, c := range cases { 5620 t.Run(c.name, func(t *testing.T) { 5621 s := RunBasicJetStreamServer(t) 5622 defer s.Shutdown() 5623 5624 mset, err := s.GlobalAccount().addStream(c.mconfig) 5625 if err != nil { 5626 t.Fatalf("Unexpected error adding stream: %v", err) 5627 } 5628 defer mset.delete() 5629 5630 nc, js := jsClientConnect(t, s) 5631 defer nc.Close() 5632 5633 // Send 100 msgs 5634 for i := 0; i < 100; i++ { 5635 js.Publish("DC", []byte("OK!")) 5636 } 5637 if state := mset.state(); state.Msgs != 100 { 5638 t.Fatalf("Expected %d messages, got %d", 100, state.Msgs) 5639 } 5640 // Now create an consumer and make sure it functions properly. 5641 // This will test redelivery state and purge of the stream. 5642 wcfg := &ConsumerConfig{ 5643 Durable: "WQ", 5644 AckPolicy: AckExplicit, 5645 AckWait: 20 * time.Millisecond, 5646 } 5647 o, err := mset.addConsumer(wcfg) 5648 if err != nil { 5649 t.Fatalf("Expected no error with registered interest, got %v", err) 5650 } 5651 defer o.delete() 5652 nextSubj := o.requestNextMsgSubject() 5653 for i := 0; i < 50; i++ { 5654 // Do not ack these. 5655 if _, err := nc.Request(nextSubj, nil, time.Second); err != nil { 5656 t.Fatalf("Unexpected error: %v", err) 5657 } 5658 } 5659 // Now wait to make sure we are in a redelivered state. 5660 time.Sleep(wcfg.AckWait * 2) 5661 // Now do purge. 5662 mset.purge(nil) 5663 if state := mset.state(); state.Msgs != 0 { 5664 t.Fatalf("Expected %d messages, got %d", 0, state.Msgs) 5665 } 5666 // Now get the state and check that we did the right thing. 5667 // Pending should be cleared, and stream sequences should have been set 5668 // to the total messages before purge + 1. 5669 state := o.info() 5670 if state.NumAckPending != 0 { 5671 t.Fatalf("Expected no pending, got %d", state.NumAckPending) 5672 } 5673 if state.Delivered.Stream != 100 { 5674 t.Fatalf("Expected to have setseq now at next seq of 100, got %d", state.Delivered.Stream) 5675 } 5676 // Check AckFloors which should have also been adjusted. 5677 if state.AckFloor.Stream != 100 { 5678 t.Fatalf("Expected ackfloor for setseq to be 100, got %d", state.AckFloor.Stream) 5679 } 5680 if state.AckFloor.Consumer != 50 { 5681 t.Fatalf("Expected ackfloor for obsseq to be 75, got %d", state.AckFloor.Consumer) 5682 } 5683 // Also make sure we can get new messages correctly. 5684 js.Publish("DC", []byte("OK-22")) 5685 if msg, err := nc.Request(nextSubj, nil, time.Second); err != nil { 5686 t.Fatalf("Unexpected error: %v", err) 5687 } else if string(msg.Data) != "OK-22" { 5688 t.Fatalf("Received wrong message, wanted 'OK-22', got %q", msg.Data) 5689 } 5690 }) 5691 } 5692 } 5693 5694 func TestJetStreamInterestRetentionStream(t *testing.T) { 5695 cases := []struct { 5696 name string 5697 mconfig *StreamConfig 5698 }{ 5699 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage, Retention: InterestPolicy}}, 5700 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage, Retention: InterestPolicy}}, 5701 } 5702 for _, c := range cases { 5703 t.Run(c.name, func(t *testing.T) { 5704 s := RunBasicJetStreamServer(t) 5705 defer s.Shutdown() 5706 5707 mset, err := s.GlobalAccount().addStream(c.mconfig) 5708 if err != nil { 5709 t.Fatalf("Unexpected error adding stream: %v", err) 5710 } 5711 defer mset.delete() 5712 5713 nc, js := jsClientConnect(t, s) 5714 defer nc.Close() 5715 5716 // Send 100 msgs 5717 totalMsgs := 100 5718 5719 for i := 0; i < totalMsgs; i++ { 5720 js.Publish("DC", []byte("OK!")) 5721 } 5722 5723 checkNumMsgs := func(numExpected int) { 5724 t.Helper() 5725 checkFor(t, time.Second, 15*time.Millisecond, func() error { 5726 if state := mset.state(); state.Msgs != uint64(numExpected) { 5727 return fmt.Errorf("Expected %d messages, got %d", numExpected, state.Msgs) 5728 } 5729 return nil 5730 }) 5731 } 5732 5733 // Since we had no interest this should be 0. 5734 checkNumMsgs(0) 5735 5736 syncSub := func() *nats.Subscription { 5737 sub, _ := nc.SubscribeSync(nats.NewInbox()) 5738 nc.Flush() 5739 return sub 5740 } 5741 5742 // Now create three consumers. 5743 // 1. AckExplicit 5744 // 2. AckAll 5745 // 3. AckNone 5746 5747 sub1 := syncSub() 5748 mset.addConsumer(&ConsumerConfig{DeliverSubject: sub1.Subject, AckPolicy: AckExplicit}) 5749 5750 sub2 := syncSub() 5751 mset.addConsumer(&ConsumerConfig{DeliverSubject: sub2.Subject, AckPolicy: AckAll}) 5752 5753 sub3 := syncSub() 5754 mset.addConsumer(&ConsumerConfig{DeliverSubject: sub3.Subject, AckPolicy: AckNone}) 5755 5756 for i := 0; i < totalMsgs; i++ { 5757 js.Publish("DC", []byte("OK!")) 5758 } 5759 5760 checkNumMsgs(totalMsgs) 5761 5762 // Wait for all messsages to be pending for each sub. 5763 for i, sub := range []*nats.Subscription{sub1, sub2, sub3} { 5764 checkFor(t, 5*time.Second, 25*time.Millisecond, func() error { 5765 if nmsgs, _, _ := sub.Pending(); nmsgs != totalMsgs { 5766 return fmt.Errorf("Did not receive correct number of messages: %d vs %d for sub %d", nmsgs, totalMsgs, i+1) 5767 } 5768 return nil 5769 }) 5770 } 5771 5772 getAndAck := func(sub *nats.Subscription) { 5773 t.Helper() 5774 if m, err := sub.NextMsg(time.Second); err != nil { 5775 t.Fatalf("Unexpected error: %v", err) 5776 } else { 5777 m.Respond(nil) 5778 } 5779 nc.Flush() 5780 } 5781 5782 // Ack evens for the explicit ack sub. 5783 var odds []*nats.Msg 5784 for i := 1; i <= totalMsgs; i++ { 5785 if m, err := sub1.NextMsg(time.Second); err != nil { 5786 t.Fatalf("Unexpected error: %v", err) 5787 } else if i%2 == 0 { 5788 m.Respond(nil) // Ack evens. 5789 } else { 5790 odds = append(odds, m) 5791 } 5792 } 5793 nc.Flush() 5794 5795 checkNumMsgs(totalMsgs) 5796 5797 // Now ack first for AckAll sub2 5798 getAndAck(sub2) 5799 // We should be at the same number since we acked 1, explicit acked 2 5800 checkNumMsgs(totalMsgs) 5801 // Now ack second for AckAll sub2 5802 getAndAck(sub2) 5803 // We should now have 1 removed. 5804 checkNumMsgs(totalMsgs - 1) 5805 // Now ack third for AckAll sub2 5806 getAndAck(sub2) 5807 // We should still only have 1 removed. 5808 checkNumMsgs(totalMsgs - 1) 5809 5810 // Now ack odds from explicit. 5811 for _, m := range odds { 5812 m.Respond(nil) // Ack 5813 } 5814 nc.Flush() 5815 5816 // we should have 1, 2, 3 acks now. 5817 checkNumMsgs(totalMsgs - 3) 5818 5819 nm, _, _ := sub2.Pending() 5820 // Now ack last ackAll message. This should clear all of them. 5821 for i := 1; i <= nm; i++ { 5822 if m, err := sub2.NextMsg(time.Second); err != nil { 5823 t.Fatalf("Unexpected error: %v", err) 5824 } else if i == nm { 5825 m.Respond(nil) 5826 } 5827 } 5828 nc.Flush() 5829 5830 // Should be zero now. 5831 checkNumMsgs(0) 5832 }) 5833 } 5834 } 5835 5836 func TestJetStreamInterestRetentionStreamWithFilteredConsumers(t *testing.T) { 5837 cases := []struct { 5838 name string 5839 mconfig *StreamConfig 5840 }{ 5841 {"MemoryStore", &StreamConfig{Name: "DC", Subjects: []string{"*"}, Storage: MemoryStorage, Retention: InterestPolicy}}, 5842 {"FileStore", &StreamConfig{Name: "DC", Subjects: []string{"*"}, Storage: FileStorage, Retention: InterestPolicy}}, 5843 } 5844 for _, c := range cases { 5845 t.Run(c.name, func(t *testing.T) { 5846 s := RunBasicJetStreamServer(t) 5847 defer s.Shutdown() 5848 5849 mset, err := s.GlobalAccount().addStream(c.mconfig) 5850 if err != nil { 5851 t.Fatalf("Unexpected error adding stream: %v", err) 5852 } 5853 defer mset.delete() 5854 5855 nc, js := jsClientConnect(t, s) 5856 defer nc.Close() 5857 5858 fsub, err := js.SubscribeSync("foo") 5859 if err != nil { 5860 t.Fatalf("Unexpected error: %v", err) 5861 } 5862 defer fsub.Unsubscribe() 5863 5864 bsub, err := js.SubscribeSync("bar") 5865 if err != nil { 5866 t.Fatalf("Unexpected error: %v", err) 5867 } 5868 defer bsub.Unsubscribe() 5869 5870 msg := []byte("FILTERED") 5871 sendMsg := func(subj string) { 5872 t.Helper() 5873 if _, err = js.Publish(subj, msg); err != nil { 5874 t.Fatalf("Unexpected publish error: %v", err) 5875 } 5876 } 5877 5878 getAndAck := func(sub *nats.Subscription) { 5879 t.Helper() 5880 m, err := sub.NextMsg(time.Second) 5881 if err != nil { 5882 t.Fatalf("Unexpected error getting msg: %v", err) 5883 } 5884 m.AckSync() 5885 } 5886 5887 checkState := func(expected uint64) { 5888 t.Helper() 5889 si, err := js.StreamInfo("DC") 5890 if err != nil { 5891 t.Fatalf("Unexpected error: %v", err) 5892 } 5893 if si.State.Msgs != expected { 5894 t.Fatalf("Expected %d msgs, got %d", expected, si.State.Msgs) 5895 } 5896 } 5897 5898 sendMsg("foo") 5899 checkState(1) 5900 getAndAck(fsub) 5901 checkState(0) 5902 sendMsg("bar") 5903 sendMsg("foo") 5904 checkState(2) 5905 getAndAck(bsub) 5906 checkState(1) 5907 getAndAck(fsub) 5908 checkState(0) 5909 }) 5910 } 5911 } 5912 5913 func TestJetStreamInterestRetentionWithWildcardsAndFilteredConsumers(t *testing.T) { 5914 msc := StreamConfig{ 5915 Name: "DCWC", 5916 Subjects: []string{"foo.*"}, 5917 Storage: MemoryStorage, 5918 Retention: InterestPolicy, 5919 } 5920 fsc := msc 5921 fsc.Storage = FileStorage 5922 5923 cases := []struct { 5924 name string 5925 mconfig *StreamConfig 5926 }{ 5927 {"MemoryStore", &msc}, 5928 {"FileStore", &fsc}, 5929 } 5930 for _, c := range cases { 5931 t.Run(c.name, func(t *testing.T) { 5932 s := RunBasicJetStreamServer(t) 5933 defer s.Shutdown() 5934 5935 mset, err := s.GlobalAccount().addStream(c.mconfig) 5936 if err != nil { 5937 t.Fatalf("Unexpected error adding stream: %v", err) 5938 } 5939 defer mset.delete() 5940 5941 nc := clientConnectToServer(t, s) 5942 defer nc.Close() 5943 5944 // Send 10 msgs 5945 for i := 0; i < 10; i++ { 5946 sendStreamMsg(t, nc, "foo.bar", "Hello World!") 5947 } 5948 if state := mset.state(); state.Msgs != 0 { 5949 t.Fatalf("Expected %d messages, got %d", 0, state.Msgs) 5950 } 5951 5952 cfg := &ConsumerConfig{Durable: "ddd", FilterSubject: "foo.bar", AckPolicy: AckExplicit} 5953 o, err := mset.addConsumer(cfg) 5954 if err != nil { 5955 t.Fatalf("Unexpected error: %v", err) 5956 } 5957 defer o.delete() 5958 5959 sendStreamMsg(t, nc, "foo.bar", "Hello World!") 5960 if state := mset.state(); state.Msgs != 1 { 5961 t.Fatalf("Expected %d message, got %d", 1, state.Msgs) 5962 } else if state.FirstSeq != 11 { 5963 t.Fatalf("Expected %d for first seq, got %d", 11, state.FirstSeq) 5964 } 5965 // Now send to foo.baz, which has no interest, so we should not hold onto this message. 5966 sendStreamMsg(t, nc, "foo.baz", "Hello World!") 5967 if state := mset.state(); state.Msgs != 1 { 5968 t.Fatalf("Expected %d message, got %d", 1, state.Msgs) 5969 } 5970 }) 5971 } 5972 } 5973 5974 func TestJetStreamInterestRetentionStreamWithDurableRestart(t *testing.T) { 5975 cases := []struct { 5976 name string 5977 mconfig *StreamConfig 5978 }{ 5979 {"MemoryStore", &StreamConfig{Name: "IK", Storage: MemoryStorage, Retention: InterestPolicy}}, 5980 {"FileStore", &StreamConfig{Name: "IK", Storage: FileStorage, Retention: InterestPolicy}}, 5981 } 5982 for _, c := range cases { 5983 t.Run(c.name, func(t *testing.T) { 5984 s := RunBasicJetStreamServer(t) 5985 defer s.Shutdown() 5986 5987 mset, err := s.GlobalAccount().addStream(c.mconfig) 5988 if err != nil { 5989 t.Fatalf("Unexpected error adding stream: %v", err) 5990 } 5991 defer mset.delete() 5992 5993 checkNumMsgs := func(numExpected int) { 5994 t.Helper() 5995 checkFor(t, time.Second, 50*time.Millisecond, func() error { 5996 if state := mset.state(); state.Msgs != uint64(numExpected) { 5997 return fmt.Errorf("Expected %d messages, got %d", numExpected, state.Msgs) 5998 } 5999 return nil 6000 }) 6001 } 6002 6003 nc := clientConnectToServer(t, s) 6004 defer nc.Close() 6005 6006 sub, _ := nc.SubscribeSync(nats.NewInbox()) 6007 nc.Flush() 6008 6009 cfg := &ConsumerConfig{Durable: "ivan", DeliverPolicy: DeliverNew, DeliverSubject: sub.Subject, AckPolicy: AckNone} 6010 6011 o, _ := mset.addConsumer(cfg) 6012 6013 sendStreamMsg(t, nc, "IK", "M1") 6014 sendStreamMsg(t, nc, "IK", "M2") 6015 6016 checkSubPending := func(numExpected int) { 6017 t.Helper() 6018 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 6019 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != numExpected { 6020 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 6021 } 6022 return nil 6023 }) 6024 } 6025 6026 checkSubPending(2) 6027 checkNumMsgs(0) 6028 6029 // Now stop the subscription. 6030 sub.Unsubscribe() 6031 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 6032 if o.isActive() { 6033 return fmt.Errorf("Still active consumer") 6034 } 6035 return nil 6036 }) 6037 6038 sendStreamMsg(t, nc, "IK", "M3") 6039 sendStreamMsg(t, nc, "IK", "M4") 6040 6041 checkNumMsgs(2) 6042 6043 // Now restart the durable. 6044 sub, _ = nc.SubscribeSync(nats.NewInbox()) 6045 nc.Flush() 6046 cfg.DeliverSubject = sub.Subject 6047 if o, err = mset.addConsumer(cfg); err != nil { 6048 t.Fatalf("Error re-establishing the durable consumer: %v", err) 6049 } 6050 checkSubPending(2) 6051 6052 for _, expected := range []string{"M3", "M4"} { 6053 if m, err := sub.NextMsg(time.Second); err != nil { 6054 t.Fatalf("Unexpected error: %v", err) 6055 } else if string(m.Data) != expected { 6056 t.Fatalf("Expected %q, got %q", expected, m.Data) 6057 } 6058 } 6059 6060 // Should all be gone now. 6061 checkNumMsgs(0) 6062 6063 // Now restart again and make sure we do not get any messages. 6064 sub.Unsubscribe() 6065 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 6066 if o.isActive() { 6067 return fmt.Errorf("Still active consumer") 6068 } 6069 return nil 6070 }) 6071 o.delete() 6072 6073 sub, _ = nc.SubscribeSync(nats.NewInbox()) 6074 nc.Flush() 6075 6076 cfg.DeliverSubject = sub.Subject 6077 cfg.AckPolicy = AckExplicit // Set ack 6078 if o, err = mset.addConsumer(cfg); err != nil { 6079 t.Fatalf("Error re-establishing the durable consumer: %v", err) 6080 } 6081 time.Sleep(100 * time.Millisecond) 6082 checkSubPending(0) 6083 checkNumMsgs(0) 6084 6085 // Now queue up some messages. 6086 for i := 1; i <= 10; i++ { 6087 sendStreamMsg(t, nc, "IK", fmt.Sprintf("M%d", i)) 6088 } 6089 checkNumMsgs(10) 6090 checkSubPending(10) 6091 6092 // Create second consumer 6093 sub2, _ := nc.SubscribeSync(nats.NewInbox()) 6094 nc.Flush() 6095 cfg.DeliverSubject = sub2.Subject 6096 cfg.Durable = "derek" 6097 o2, err := mset.addConsumer(cfg) 6098 if err != nil { 6099 t.Fatalf("Error creating second durable consumer: %v", err) 6100 } 6101 6102 // Now queue up some messages. 6103 for i := 11; i <= 20; i++ { 6104 sendStreamMsg(t, nc, "IK", fmt.Sprintf("M%d", i)) 6105 } 6106 checkNumMsgs(20) 6107 checkSubPending(20) 6108 6109 // Now make sure deleting the consumers will remove messages from 6110 // the stream since we are interest retention based. 6111 o.delete() 6112 checkNumMsgs(10) 6113 6114 o2.delete() 6115 checkNumMsgs(0) 6116 }) 6117 } 6118 } 6119 6120 func TestJetStreamConsumerReplayRate(t *testing.T) { 6121 cases := []struct { 6122 name string 6123 mconfig *StreamConfig 6124 }{ 6125 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 6126 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 6127 } 6128 for _, c := range cases { 6129 t.Run(c.name, func(t *testing.T) { 6130 s := RunBasicJetStreamServer(t) 6131 defer s.Shutdown() 6132 6133 mset, err := s.GlobalAccount().addStream(c.mconfig) 6134 if err != nil { 6135 t.Fatalf("Unexpected error adding stream: %v", err) 6136 } 6137 defer mset.delete() 6138 6139 nc := clientConnectToServer(t, s) 6140 defer nc.Close() 6141 6142 // Send 10 msgs 6143 totalMsgs := 10 6144 6145 var gaps []time.Duration 6146 lst := time.Now() 6147 6148 for i := 0; i < totalMsgs; i++ { 6149 gaps = append(gaps, time.Since(lst)) 6150 lst = time.Now() 6151 nc.Publish("DC", []byte("OK!")) 6152 // Calculate a gap between messages. 6153 gap := 10*time.Millisecond + time.Duration(rand.Intn(20))*time.Millisecond 6154 time.Sleep(gap) 6155 } 6156 6157 if state := mset.state(); state.Msgs != uint64(totalMsgs) { 6158 t.Fatalf("Expected %d messages, got %d", totalMsgs, state.Msgs) 6159 } 6160 6161 sub, _ := nc.SubscribeSync(nats.NewInbox()) 6162 defer sub.Unsubscribe() 6163 nc.Flush() 6164 6165 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 6166 if err != nil { 6167 t.Fatalf("Unexpected error: %v", err) 6168 } 6169 defer o.delete() 6170 6171 // Firehose/instant which is default. 6172 last := time.Now() 6173 for i := 0; i < totalMsgs; i++ { 6174 if _, err := sub.NextMsg(time.Second); err != nil { 6175 t.Fatalf("Unexpected error: %v", err) 6176 } 6177 now := time.Now() 6178 // Delivery from addConsumer starts in a go routine, so be 6179 // more tolerant for the first message. 6180 limit := 5 * time.Millisecond 6181 if i == 0 { 6182 limit = 10 * time.Millisecond 6183 } 6184 if now.Sub(last) > limit { 6185 t.Fatalf("Expected firehose/instant delivery, got message gap of %v", now.Sub(last)) 6186 } 6187 last = now 6188 } 6189 6190 // Now do replay rate to match original. 6191 o, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject, ReplayPolicy: ReplayOriginal}) 6192 if err != nil { 6193 t.Fatalf("Unexpected error: %v", err) 6194 } 6195 defer o.delete() 6196 6197 // Original rate messsages were received for push based consumer. 6198 for i := 0; i < totalMsgs; i++ { 6199 start := time.Now() 6200 if _, err := sub.NextMsg(time.Second); err != nil { 6201 t.Fatalf("Unexpected error: %v", err) 6202 } 6203 gap := time.Since(start) 6204 // 15ms is high but on macs time.Sleep(delay) does not sleep only delay. 6205 // Also on travis if things get bogged down this could be delayed. 6206 gl, gh := gaps[i]-10*time.Millisecond, gaps[i]+15*time.Millisecond 6207 if gap < gl || gap > gh { 6208 t.Fatalf("Gap is off for %d, expected %v got %v", i, gaps[i], gap) 6209 } 6210 } 6211 6212 // Now create pull based. 6213 oc := workerModeConfig("PM") 6214 oc.ReplayPolicy = ReplayOriginal 6215 o, err = mset.addConsumer(oc) 6216 if err != nil { 6217 t.Fatalf("Unexpected error: %v", err) 6218 } 6219 defer o.delete() 6220 6221 for i := 0; i < totalMsgs; i++ { 6222 start := time.Now() 6223 if _, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second); err != nil { 6224 t.Fatalf("Unexpected error: %v", err) 6225 } 6226 gap := time.Since(start) 6227 // 10ms is high but on macs time.Sleep(delay) does not sleep only delay. 6228 gl, gh := gaps[i]-5*time.Millisecond, gaps[i]+10*time.Millisecond 6229 if gap < gl || gap > gh { 6230 t.Fatalf("Gap is incorrect for %d, expected %v got %v", i, gaps[i], gap) 6231 } 6232 } 6233 }) 6234 } 6235 } 6236 6237 func TestJetStreamConsumerReplayRateNoAck(t *testing.T) { 6238 cases := []struct { 6239 name string 6240 mconfig *StreamConfig 6241 }{ 6242 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 6243 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 6244 } 6245 for _, c := range cases { 6246 t.Run(c.name, func(t *testing.T) { 6247 s := RunBasicJetStreamServer(t) 6248 defer s.Shutdown() 6249 6250 mset, err := s.GlobalAccount().addStream(c.mconfig) 6251 if err != nil { 6252 t.Fatalf("Unexpected error adding stream: %v", err) 6253 } 6254 defer mset.delete() 6255 6256 nc := clientConnectToServer(t, s) 6257 defer nc.Close() 6258 6259 // Send 10 msgs 6260 totalMsgs := 10 6261 for i := 0; i < totalMsgs; i++ { 6262 nc.Request("DC", []byte("Hello World"), time.Second) 6263 time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond) 6264 } 6265 if state := mset.state(); state.Msgs != uint64(totalMsgs) { 6266 t.Fatalf("Expected %d messages, got %d", totalMsgs, state.Msgs) 6267 } 6268 subj := "d.dc" 6269 o, err := mset.addConsumer(&ConsumerConfig{ 6270 Durable: "derek", 6271 DeliverSubject: subj, 6272 AckPolicy: AckNone, 6273 ReplayPolicy: ReplayOriginal, 6274 }) 6275 if err != nil { 6276 t.Fatalf("Unexpected error: %v", err) 6277 } 6278 defer o.delete() 6279 // Sleep a random amount of time. 6280 time.Sleep(time.Duration(rand.Intn(20)) * time.Millisecond) 6281 6282 sub, _ := nc.SubscribeSync(subj) 6283 nc.Flush() 6284 6285 checkFor(t, time.Second, 25*time.Millisecond, func() error { 6286 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != totalMsgs { 6287 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, totalMsgs) 6288 } 6289 return nil 6290 }) 6291 }) 6292 } 6293 } 6294 6295 func TestJetStreamConsumerReplayQuit(t *testing.T) { 6296 cases := []struct { 6297 name string 6298 mconfig *StreamConfig 6299 }{ 6300 {"MemoryStore", &StreamConfig{Name: "DC", Storage: MemoryStorage}}, 6301 {"FileStore", &StreamConfig{Name: "DC", Storage: FileStorage}}, 6302 } 6303 for _, c := range cases { 6304 t.Run(c.name, func(t *testing.T) { 6305 s := RunBasicJetStreamServer(t) 6306 defer s.Shutdown() 6307 6308 mset, err := s.GlobalAccount().addStream(c.mconfig) 6309 if err != nil { 6310 t.Fatalf("Unexpected error adding stream: %v", err) 6311 } 6312 defer mset.delete() 6313 6314 nc := clientConnectToServer(t, s) 6315 defer nc.Close() 6316 6317 // Send 2 msgs 6318 nc.Request("DC", []byte("OK!"), time.Second) 6319 time.Sleep(100 * time.Millisecond) 6320 nc.Request("DC", []byte("OK!"), time.Second) 6321 6322 if state := mset.state(); state.Msgs != 2 { 6323 t.Fatalf("Expected %d messages, got %d", 2, state.Msgs) 6324 } 6325 6326 sub, _ := nc.SubscribeSync(nats.NewInbox()) 6327 defer sub.Unsubscribe() 6328 nc.Flush() 6329 6330 // Now do replay rate to match original. 6331 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject, ReplayPolicy: ReplayOriginal}) 6332 if err != nil { 6333 t.Fatalf("Unexpected error: %v", err) 6334 } 6335 6336 // Allow loop and deliver / replay go routine to spin up 6337 time.Sleep(50 * time.Millisecond) 6338 base := runtime.NumGoroutine() 6339 o.delete() 6340 6341 checkFor(t, 100*time.Millisecond, 10*time.Millisecond, func() error { 6342 if runtime.NumGoroutine() >= base { 6343 return fmt.Errorf("Consumer go routines still running") 6344 } 6345 return nil 6346 }) 6347 }) 6348 } 6349 } 6350 6351 func TestJetStreamSystemLimits(t *testing.T) { 6352 s := RunRandClientPortServer(t) 6353 defer s.Shutdown() 6354 6355 if _, _, err := s.JetStreamReservedResources(); err == nil { 6356 t.Fatalf("Expected error requesting jetstream reserved resources when not enabled") 6357 } 6358 // Create some accounts. 6359 facc, _ := s.LookupOrRegisterAccount("FOO") 6360 bacc, _ := s.LookupOrRegisterAccount("BAR") 6361 zacc, _ := s.LookupOrRegisterAccount("BAZ") 6362 6363 jsconfig := &JetStreamConfig{MaxMemory: 1024, MaxStore: 8192, StoreDir: t.TempDir()} 6364 if err := s.EnableJetStream(jsconfig); err != nil { 6365 t.Fatalf("Expected no error, got %v", err) 6366 } 6367 6368 if rm, rd, err := s.JetStreamReservedResources(); err != nil { 6369 t.Fatalf("Unexpected error requesting jetstream reserved resources: %v", err) 6370 } else if rm != 0 || rd != 0 { 6371 t.Fatalf("Expected reserved memory and store to be 0, got %d and %d", rm, rd) 6372 } 6373 6374 limits := func(mem int64, store int64) map[string]JetStreamAccountLimits { 6375 return map[string]JetStreamAccountLimits{ 6376 _EMPTY_: { 6377 MaxMemory: mem, 6378 MaxStore: store, 6379 MaxStreams: -1, 6380 MaxConsumers: -1, 6381 }, 6382 } 6383 } 6384 6385 if err := facc.EnableJetStream(limits(24, 192)); err != nil { 6386 t.Fatalf("Unexpected error: %v", err) 6387 } 6388 // Use up rest of our resources in memory 6389 if err := bacc.EnableJetStream(limits(1000, 0)); err != nil { 6390 t.Fatalf("Unexpected error: %v", err) 6391 } 6392 6393 // Now ask for more memory. Should error. 6394 if err := zacc.EnableJetStream(limits(1000, 0)); err == nil { 6395 t.Fatalf("Expected an error when exhausting memory resource limits") 6396 } 6397 // Disk too. 6398 if err := zacc.EnableJetStream(limits(0, 10000)); err == nil { 6399 t.Fatalf("Expected an error when exhausting memory resource limits") 6400 } 6401 facc.DisableJetStream() 6402 bacc.DisableJetStream() 6403 zacc.DisableJetStream() 6404 6405 // Make sure we unreserved resources. 6406 if rm, rd, err := s.JetStreamReservedResources(); err != nil { 6407 t.Fatalf("Unexpected error requesting jetstream reserved resources: %v", err) 6408 } else if rm != 0 || rd != 0 { 6409 t.Fatalf("Expected reserved memory and store to be 0, got %v and %v", friendlyBytes(rm), friendlyBytes(rd)) 6410 } 6411 6412 if err := facc.EnableJetStream(limits(24, 192)); err != nil { 6413 t.Fatalf("Unexpected error: %v", err) 6414 } 6415 // Test Adjust 6416 lim := limits(jsconfig.MaxMemory, jsconfig.MaxStore) 6417 l := lim[_EMPTY_] 6418 l.MaxStreams = 10 6419 l.MaxConsumers = 10 6420 lim[_EMPTY_] = l 6421 if err := facc.UpdateJetStreamLimits(lim); err != nil { 6422 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 6423 } 6424 6425 var msets []*stream 6426 // Now test max streams and max consumers. Note max consumers is per stream. 6427 for i := 0; i < 10; i++ { 6428 mname := fmt.Sprintf("foo.%d", i) 6429 mset, err := facc.addStream(&StreamConfig{Name: strconv.Itoa(i), Storage: MemoryStorage, Subjects: []string{mname}}) 6430 if err != nil { 6431 t.Fatalf("Unexpected error adding stream: %v", err) 6432 } 6433 msets = append(msets, mset) 6434 } 6435 6436 // Remove them all 6437 for _, mset := range msets { 6438 mset.delete() 6439 } 6440 6441 // Now try to add one with bytes limit that would exceed the account limit. 6442 if _, err := facc.addStream(&StreamConfig{Name: "22", Storage: MemoryStorage, MaxBytes: jsconfig.MaxStore * 2}); err == nil { 6443 t.Fatalf("Expected error adding stream over limit") 6444 } 6445 6446 // Replicas can't be > 1 6447 if _, err := facc.addStream(&StreamConfig{Name: "22", Storage: MemoryStorage, Replicas: 10}); err == nil { 6448 t.Fatalf("Expected error adding stream over limit") 6449 } 6450 6451 // Test consumers limit against account limit when the stream does not set a limit 6452 mset, err := facc.addStream(&StreamConfig{Name: "22", Storage: MemoryStorage, Subjects: []string{"foo.22"}}) 6453 if err != nil { 6454 t.Fatalf("Unexpected error adding stream: %v", err) 6455 } 6456 6457 for i := 0; i < 10; i++ { 6458 oname := fmt.Sprintf("O:%d", i) 6459 _, err := mset.addConsumer(&ConsumerConfig{Durable: oname, AckPolicy: AckExplicit}) 6460 if err != nil { 6461 t.Fatalf("Unexpected error: %v", err) 6462 } 6463 } 6464 6465 // This one should fail. 6466 if _, err := mset.addConsumer(&ConsumerConfig{Durable: "O:22", AckPolicy: AckExplicit}); err == nil { 6467 t.Fatalf("Expected error adding consumer over the limit") 6468 } 6469 6470 // Test consumer limit against stream limit 6471 mset.delete() 6472 mset, err = facc.addStream(&StreamConfig{Name: "22", Storage: MemoryStorage, Subjects: []string{"foo.22"}, MaxConsumers: 5}) 6473 if err != nil { 6474 t.Fatalf("Unexpected error adding stream: %v", err) 6475 } 6476 6477 for i := 0; i < 5; i++ { 6478 oname := fmt.Sprintf("O:%d", i) 6479 _, err := mset.addConsumer(&ConsumerConfig{Durable: oname, AckPolicy: AckExplicit}) 6480 if err != nil { 6481 t.Fatalf("Unexpected error: %v", err) 6482 } 6483 } 6484 6485 // This one should fail. 6486 if _, err := mset.addConsumer(&ConsumerConfig{Durable: "O:22", AckPolicy: AckExplicit}); err == nil { 6487 t.Fatalf("Expected error adding consumer over the limit") 6488 } 6489 6490 // Test the account having smaller limits than the stream 6491 mset.delete() 6492 6493 mset, err = facc.addStream(&StreamConfig{Name: "22", Storage: MemoryStorage, Subjects: []string{"foo.22"}, MaxConsumers: 10}) 6494 if err != nil { 6495 t.Fatalf("Unexpected error adding stream: %v", err) 6496 } 6497 6498 l.MaxConsumers = 5 6499 lim[_EMPTY_] = l 6500 if err := facc.UpdateJetStreamLimits(lim); err != nil { 6501 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 6502 } 6503 6504 for i := 0; i < 5; i++ { 6505 oname := fmt.Sprintf("O:%d", i) 6506 _, err := mset.addConsumer(&ConsumerConfig{Durable: oname, AckPolicy: AckExplicit}) 6507 if err != nil { 6508 t.Fatalf("Unexpected error: %v", err) 6509 } 6510 } 6511 6512 // This one should fail. 6513 if _, err := mset.addConsumer(&ConsumerConfig{Durable: "O:22", AckPolicy: AckExplicit}); err == nil { 6514 t.Fatalf("Expected error adding consumer over the limit") 6515 } 6516 } 6517 6518 func TestJetStreamSystemLimitsPlacement(t *testing.T) { 6519 const smallSystemLimit = 128 6520 const mediumSystemLimit = smallSystemLimit * 2 6521 const largeSystemLimit = smallSystemLimit * 3 6522 6523 tmpl := ` 6524 listen: 127.0.0.1:-1 6525 server_name: %s 6526 jetstream: { 6527 max_mem_store: _MAXMEM_ 6528 max_file_store: _MAXFILE_ 6529 store_dir: '%s' 6530 } 6531 6532 server_tags: [ 6533 _TAG_ 6534 ] 6535 6536 leaf { 6537 listen: 127.0.0.1:-1 6538 } 6539 cluster { 6540 name: %s 6541 listen: 127.0.0.1:%d 6542 routes = [%s] 6543 } 6544 ` 6545 storeCnf := func(serverName, clusterName, storeDir, conf string) string { 6546 switch serverName { 6547 case "S-1": 6548 conf = strings.Replace(conf, "_MAXMEM_", fmt.Sprint(smallSystemLimit), 1) 6549 conf = strings.Replace(conf, "_MAXFILE_", fmt.Sprint(smallSystemLimit), 1) 6550 return strings.Replace(conf, "_TAG_", "small", 1) 6551 case "S-2": 6552 conf = strings.Replace(conf, "_MAXMEM_", fmt.Sprint(mediumSystemLimit), 1) 6553 conf = strings.Replace(conf, "_MAXFILE_", fmt.Sprint(mediumSystemLimit), 1) 6554 return strings.Replace(conf, "_TAG_", "medium", 1) 6555 case "S-3": 6556 conf = strings.Replace(conf, "_MAXMEM_", fmt.Sprint(largeSystemLimit), 1) 6557 conf = strings.Replace(conf, "_MAXFILE_", fmt.Sprint(largeSystemLimit), 1) 6558 return strings.Replace(conf, "_TAG_", "large", 1) 6559 default: 6560 return conf 6561 } 6562 } 6563 6564 cluster := createJetStreamClusterWithTemplateAndModHook(t, tmpl, "cluster-a", 3, storeCnf) 6565 defer cluster.shutdown() 6566 6567 requestLeaderStepDown := func(clientURL string) error { 6568 nc, err := nats.Connect(clientURL) 6569 if err != nil { 6570 return err 6571 } 6572 defer nc.Close() 6573 6574 ncResp, err := nc.Request(JSApiLeaderStepDown, nil, 3*time.Second) 6575 if err != nil { 6576 return err 6577 } 6578 6579 var resp JSApiLeaderStepDownResponse 6580 if err := json.Unmarshal(ncResp.Data, &resp); err != nil { 6581 return err 6582 } 6583 if resp.Error != nil { 6584 return resp.Error 6585 } 6586 if !resp.Success { 6587 return fmt.Errorf("leader step down request not successful") 6588 } 6589 6590 return nil 6591 } 6592 6593 largeSrv := cluster.servers[2] 6594 // Force large server to be leader 6595 err := checkForErr(15*time.Second, 500*time.Millisecond, func() error { 6596 if largeSrv.JetStreamIsLeader() { 6597 return nil 6598 } 6599 6600 if err := requestLeaderStepDown(largeSrv.ClientURL()); err != nil { 6601 return err 6602 } 6603 return fmt.Errorf("large server is not leader") 6604 }) 6605 if err != nil { 6606 t.Skipf("failed to get desired layout: %s", err) 6607 } 6608 6609 nc, js := jsClientConnect(t, largeSrv) 6610 defer nc.Close() 6611 6612 cases := []struct { 6613 name string 6614 storage nats.StorageType 6615 createMaxBytes int64 6616 serverTag string 6617 wantErr bool 6618 }{ 6619 { 6620 name: "file create large stream on small server", 6621 storage: nats.FileStorage, 6622 createMaxBytes: largeSystemLimit, 6623 serverTag: "small", 6624 wantErr: true, 6625 }, 6626 { 6627 name: "memory create large stream on small server", 6628 storage: nats.MemoryStorage, 6629 createMaxBytes: largeSystemLimit, 6630 serverTag: "small", 6631 wantErr: true, 6632 }, 6633 { 6634 name: "file create large stream on medium server", 6635 storage: nats.FileStorage, 6636 createMaxBytes: largeSystemLimit, 6637 serverTag: "medium", 6638 wantErr: true, 6639 }, 6640 { 6641 name: "memory create large stream on medium server", 6642 storage: nats.MemoryStorage, 6643 createMaxBytes: largeSystemLimit, 6644 serverTag: "medium", 6645 wantErr: true, 6646 }, 6647 { 6648 name: "file create large stream on large server", 6649 storage: nats.FileStorage, 6650 createMaxBytes: largeSystemLimit, 6651 serverTag: "large", 6652 }, 6653 { 6654 name: "memory create large stream on large server", 6655 storage: nats.MemoryStorage, 6656 createMaxBytes: largeSystemLimit, 6657 serverTag: "large", 6658 }, 6659 } 6660 6661 for i := 0; i < len(cases) && !t.Failed(); i++ { 6662 c := cases[i] 6663 t.Run(c.name, func(st *testing.T) { 6664 _, err := js.AddStream(&nats.StreamConfig{ 6665 Name: "TEST", 6666 Subjects: []string{"foo"}, 6667 Storage: c.storage, 6668 MaxBytes: c.createMaxBytes, 6669 Placement: &nats.Placement{ 6670 Cluster: "cluster-a", 6671 Tags: []string{c.serverTag}, 6672 }, 6673 }) 6674 if c.wantErr && err == nil { 6675 st.Fatalf("unexpected stream create success, maxBytes=%d, tag=%s", 6676 c.createMaxBytes, c.serverTag) 6677 } else if !c.wantErr && err != nil { 6678 st.Fatalf("unexpected error: %s", err) 6679 } 6680 6681 if err == nil { 6682 err = js.DeleteStream("TEST") 6683 require_NoError(st, err) 6684 } 6685 }) 6686 } 6687 6688 // These next two tests should fail because although the stream fits in the 6689 // large and medium server, it doesn't fit on the small server. 6690 si, err := js.AddStream(&nats.StreamConfig{ 6691 Name: "TEST", 6692 Subjects: []string{"foo"}, 6693 Storage: nats.FileStorage, 6694 MaxBytes: smallSystemLimit + 1, 6695 Replicas: 3, 6696 }) 6697 if err == nil { 6698 t.Fatalf("unexpected file stream create success, maxBytes=%d, replicas=%d", 6699 si.Config.MaxBytes, si.Config.Replicas) 6700 } 6701 6702 si, err = js.AddStream(&nats.StreamConfig{ 6703 Name: "TEST", 6704 Subjects: []string{"foo"}, 6705 Storage: nats.MemoryStorage, 6706 MaxBytes: smallSystemLimit + 1, 6707 Replicas: 3, 6708 }) 6709 if err == nil { 6710 t.Fatalf("unexpected memory stream create success, maxBytes=%d, replicas=%d", 6711 si.Config.MaxBytes, si.Config.Replicas) 6712 } 6713 } 6714 6715 func TestJetStreamStreamLimitUpdate(t *testing.T) { 6716 s := RunBasicJetStreamServer(t) 6717 defer s.Shutdown() 6718 6719 err := s.GlobalAccount().UpdateJetStreamLimits(map[string]JetStreamAccountLimits{ 6720 _EMPTY_: { 6721 MaxMemory: 128, 6722 MaxStore: 128, 6723 MaxStreams: 1, 6724 }, 6725 }) 6726 require_NoError(t, err) 6727 6728 nc, js := jsClientConnect(t, s) 6729 defer nc.Close() 6730 6731 for _, storage := range []nats.StorageType{nats.MemoryStorage, nats.FileStorage} { 6732 _, err = js.AddStream(&nats.StreamConfig{ 6733 Name: "TEST", 6734 Subjects: []string{"foo"}, 6735 Storage: storage, 6736 MaxBytes: 32, 6737 }) 6738 require_NoError(t, err) 6739 6740 _, err = js.UpdateStream(&nats.StreamConfig{ 6741 Name: "TEST", 6742 Subjects: []string{"foo"}, 6743 Storage: storage, 6744 MaxBytes: 16, 6745 }) 6746 require_NoError(t, err) 6747 6748 require_NoError(t, js.DeleteStream("TEST")) 6749 } 6750 } 6751 6752 func TestJetStreamStreamStorageTrackingAndLimits(t *testing.T) { 6753 s := RunBasicJetStreamServer(t) 6754 defer s.Shutdown() 6755 6756 gacc := s.GlobalAccount() 6757 6758 al := map[string]JetStreamAccountLimits{ 6759 _EMPTY_: { 6760 MaxMemory: 8192, 6761 MaxStore: -1, 6762 MaxStreams: -1, 6763 MaxConsumers: -1, 6764 }, 6765 } 6766 6767 if err := gacc.UpdateJetStreamLimits(al); err != nil { 6768 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 6769 } 6770 6771 mset, err := gacc.addStream(&StreamConfig{Name: "LIMITS", Storage: MemoryStorage, Retention: WorkQueuePolicy}) 6772 if err != nil { 6773 t.Fatalf("Unexpected error adding stream: %v", err) 6774 } 6775 defer mset.delete() 6776 6777 nc := clientConnectToServer(t, s) 6778 defer nc.Close() 6779 6780 toSend := 100 6781 for i := 0; i < toSend; i++ { 6782 sendStreamMsg(t, nc, "LIMITS", "Hello World!") 6783 } 6784 6785 state := mset.state() 6786 usage := gacc.JetStreamUsage() 6787 6788 // Make sure these are working correctly. 6789 if state.Bytes != usage.Memory { 6790 t.Fatalf("Expected to have stream bytes match memory usage, %d vs %d", state.Bytes, usage.Memory) 6791 } 6792 if usage.Streams != 1 { 6793 t.Fatalf("Expected to have 1 stream, got %d", usage.Streams) 6794 } 6795 6796 // Do second stream. 6797 mset2, err := gacc.addStream(&StreamConfig{Name: "NUM22", Storage: MemoryStorage, Retention: WorkQueuePolicy}) 6798 if err != nil { 6799 t.Fatalf("Unexpected error adding stream: %v", err) 6800 } 6801 defer mset2.delete() 6802 6803 for i := 0; i < toSend; i++ { 6804 sendStreamMsg(t, nc, "NUM22", "Hello World!") 6805 } 6806 6807 stats2 := mset2.state() 6808 usage = gacc.JetStreamUsage() 6809 6810 if usage.Memory != (state.Bytes + stats2.Bytes) { 6811 t.Fatalf("Expected to track both streams, account is %v, stream1 is %v, stream2 is %v", usage.Memory, state.Bytes, stats2.Bytes) 6812 } 6813 6814 // Make sure delete works. 6815 mset2.delete() 6816 stats2 = mset2.state() 6817 usage = gacc.JetStreamUsage() 6818 6819 if usage.Memory != (state.Bytes + stats2.Bytes) { 6820 t.Fatalf("Expected to track both streams, account is %v, stream1 is %v, stream2 is %v", usage.Memory, state.Bytes, stats2.Bytes) 6821 } 6822 6823 // Now drain the first one by consuming the messages. 6824 o, err := mset.addConsumer(workerModeConfig("WQ")) 6825 if err != nil { 6826 t.Fatalf("Expected no error with registered interest, got %v", err) 6827 } 6828 defer o.delete() 6829 6830 for i := 0; i < toSend; i++ { 6831 msg, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 6832 if err != nil { 6833 t.Fatalf("Unexpected error: %v", err) 6834 } 6835 msg.Respond(nil) 6836 } 6837 nc.Flush() 6838 6839 state = mset.state() 6840 checkFor(t, time.Second, 15*time.Millisecond, func() error { 6841 usage = gacc.JetStreamUsage() 6842 if usage.Memory != 0 { 6843 return fmt.Errorf("Expected usage memory to be 0, got %d", usage.Memory) 6844 } 6845 return nil 6846 }) 6847 6848 // Now send twice the number of messages. Should receive an error at some point, and we will check usage against limits. 6849 var errSeen string 6850 for i := 0; i < toSend*2; i++ { 6851 resp, _ := nc.Request("LIMITS", []byte("The quick brown fox jumped over the..."), 50*time.Millisecond) 6852 if string(resp.Data) != OK { 6853 errSeen = string(resp.Data) 6854 break 6855 } 6856 } 6857 6858 if errSeen == "" { 6859 t.Fatalf("Expected to see an error when exceeding the account limits") 6860 } 6861 6862 state = mset.state() 6863 var lim JetStreamAccountLimits 6864 checkFor(t, time.Second, 15*time.Millisecond, func() error { 6865 usage = gacc.JetStreamUsage() 6866 lim = al[_EMPTY_] 6867 if usage.Memory > uint64(lim.MaxMemory) { 6868 return fmt.Errorf("Expected memory to not exceed limit of %d, got %d", lim.MaxMemory, usage.Memory) 6869 } 6870 return nil 6871 }) 6872 6873 // make sure that unlimited accounts work 6874 lim.MaxMemory = -1 6875 6876 if err := gacc.UpdateJetStreamLimits(al); err != nil { 6877 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 6878 } 6879 6880 for i := 0; i < toSend; i++ { 6881 sendStreamMsg(t, nc, "LIMITS", "Hello World!") 6882 } 6883 } 6884 6885 func TestJetStreamStreamFileTrackingAndLimits(t *testing.T) { 6886 s := RunBasicJetStreamServer(t) 6887 defer s.Shutdown() 6888 6889 gacc := s.GlobalAccount() 6890 6891 al := map[string]JetStreamAccountLimits{ 6892 _EMPTY_: { 6893 MaxMemory: 8192, 6894 MaxStore: 9600, 6895 MaxStreams: -1, 6896 MaxConsumers: -1, 6897 }, 6898 } 6899 6900 if err := gacc.UpdateJetStreamLimits(al); err != nil { 6901 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 6902 } 6903 6904 mconfig := &StreamConfig{Name: "LIMITS", Storage: FileStorage, Retention: WorkQueuePolicy} 6905 mset, err := gacc.addStream(mconfig) 6906 if err != nil { 6907 t.Fatalf("Unexpected error adding stream: %v", err) 6908 } 6909 defer mset.delete() 6910 6911 nc := clientConnectToServer(t, s) 6912 defer nc.Close() 6913 6914 toSend := 100 6915 for i := 0; i < toSend; i++ { 6916 sendStreamMsg(t, nc, "LIMITS", "Hello World!") 6917 } 6918 6919 state := mset.state() 6920 usage := gacc.JetStreamUsage() 6921 6922 // Make sure these are working correctly. 6923 if usage.Store != state.Bytes { 6924 t.Fatalf("Expected to have stream bytes match the store usage, %d vs %d", usage.Store, state.Bytes) 6925 } 6926 if usage.Streams != 1 { 6927 t.Fatalf("Expected to have 1 stream, got %d", usage.Streams) 6928 } 6929 6930 // Do second stream. 6931 mconfig2 := &StreamConfig{Name: "NUM22", Storage: FileStorage, Retention: WorkQueuePolicy} 6932 mset2, err := gacc.addStream(mconfig2) 6933 if err != nil { 6934 t.Fatalf("Unexpected error adding stream: %v", err) 6935 } 6936 defer mset2.delete() 6937 6938 for i := 0; i < toSend; i++ { 6939 sendStreamMsg(t, nc, "NUM22", "Hello World!") 6940 } 6941 6942 stats2 := mset2.state() 6943 usage = gacc.JetStreamUsage() 6944 6945 if usage.Store != (state.Bytes + stats2.Bytes) { 6946 t.Fatalf("Expected to track both streams, usage is %v, stream1 is %v, stream2 is %v", usage.Store, state.Bytes, stats2.Bytes) 6947 } 6948 6949 // Make sure delete works. 6950 mset2.delete() 6951 stats2 = mset2.state() 6952 usage = gacc.JetStreamUsage() 6953 6954 if usage.Store != (state.Bytes + stats2.Bytes) { 6955 t.Fatalf("Expected to track both streams, account is %v, stream1 is %v, stream2 is %v", usage.Store, state.Bytes, stats2.Bytes) 6956 } 6957 6958 // Now drain the first one by consuming the messages. 6959 o, err := mset.addConsumer(workerModeConfig("WQ")) 6960 if err != nil { 6961 t.Fatalf("Expected no error with registered interest, got %v", err) 6962 } 6963 defer o.delete() 6964 6965 for i := 0; i < toSend; i++ { 6966 msg, err := nc.Request(o.requestNextMsgSubject(), nil, time.Second) 6967 if err != nil { 6968 t.Fatalf("Unexpected error: %v", err) 6969 } 6970 msg.Respond(nil) 6971 } 6972 nc.Flush() 6973 6974 state = mset.state() 6975 usage = gacc.JetStreamUsage() 6976 6977 if usage.Memory != 0 { 6978 t.Fatalf("Expected usage memeory to be 0, got %d", usage.Memory) 6979 } 6980 6981 // Now send twice the number of messages. Should receive an error at some point, and we will check usage against limits. 6982 var errSeen string 6983 for i := 0; i < toSend*2; i++ { 6984 resp, _ := nc.Request("LIMITS", []byte("The quick brown fox jumped over the..."), 50*time.Millisecond) 6985 if string(resp.Data) != OK { 6986 errSeen = string(resp.Data) 6987 break 6988 } 6989 } 6990 6991 if errSeen == "" { 6992 t.Fatalf("Expected to see an error when exceeding the account limits") 6993 } 6994 6995 state = mset.state() 6996 usage = gacc.JetStreamUsage() 6997 6998 lim := al[_EMPTY_] 6999 if usage.Memory > uint64(lim.MaxMemory) { 7000 t.Fatalf("Expected memory to not exceed limit of %d, got %d", lim.MaxMemory, usage.Memory) 7001 } 7002 } 7003 7004 func TestJetStreamTieredLimits(t *testing.T) { 7005 s := RunBasicJetStreamServer(t) 7006 defer s.Shutdown() 7007 7008 gacc := s.GlobalAccount() 7009 7010 tFail := map[string]JetStreamAccountLimits{ 7011 "nottheer": { 7012 MaxMemory: 8192, 7013 MaxStore: 9600, 7014 MaxStreams: -1, 7015 MaxConsumers: -1, 7016 }, 7017 } 7018 7019 if err := gacc.UpdateJetStreamLimits(tFail); err != nil { 7020 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 7021 } 7022 7023 mconfig := &StreamConfig{Name: "LIMITS", Storage: FileStorage, Retention: WorkQueuePolicy} 7024 mset, err := gacc.addStream(mconfig) 7025 defer mset.delete() 7026 require_Error(t, err) 7027 require_Contains(t, err.Error(), "no JetStream default or applicable tiered limit present") 7028 7029 tPass := map[string]JetStreamAccountLimits{ 7030 "R1": { 7031 MaxMemory: 8192, 7032 MaxStore: 9600, 7033 MaxStreams: -1, 7034 MaxConsumers: -1, 7035 }, 7036 } 7037 7038 if err := gacc.UpdateJetStreamLimits(tPass); err != nil { 7039 t.Fatalf("Unexpected error updating jetstream account limits: %v", err) 7040 } 7041 } 7042 7043 type obsi struct { 7044 cfg ConsumerConfig 7045 ack int 7046 } 7047 7048 type info struct { 7049 cfg StreamConfig 7050 state StreamState 7051 obs []obsi 7052 } 7053 7054 func TestJetStreamSimpleFileRecovery(t *testing.T) { 7055 base := runtime.NumGoroutine() 7056 7057 s := RunBasicJetStreamServer(t) 7058 defer s.Shutdown() 7059 7060 acc := s.GlobalAccount() 7061 7062 ostate := make(map[string]info) 7063 7064 nid := nuid.New() 7065 randomSubject := func() string { 7066 nid.RandomizePrefix() 7067 return fmt.Sprintf("SUBJ.%s", nid.Next()) 7068 } 7069 7070 nc := clientConnectToServer(t, s) 7071 defer nc.Close() 7072 7073 numStreams := 10 7074 for i := 1; i <= numStreams; i++ { 7075 msetName := fmt.Sprintf("MMS-%d", i) 7076 subjects := []string{randomSubject(), randomSubject(), randomSubject()} 7077 msetConfig := StreamConfig{ 7078 Name: msetName, 7079 Storage: FileStorage, 7080 Subjects: subjects, 7081 MaxMsgs: 100, 7082 } 7083 mset, err := acc.addStream(&msetConfig) 7084 if err != nil { 7085 t.Fatalf("Unexpected error adding stream %q: %v", msetName, err) 7086 } 7087 7088 toSend := rand.Intn(100) + 1 7089 for n := 1; n <= toSend; n++ { 7090 msg := fmt.Sprintf("Hello %d", n*i) 7091 subj := subjects[rand.Intn(len(subjects))] 7092 sendStreamMsg(t, nc, subj, msg) 7093 } 7094 // Create up to 5 consumers. 7095 numObs := rand.Intn(5) + 1 7096 var obs []obsi 7097 for n := 1; n <= numObs; n++ { 7098 oname := fmt.Sprintf("WQ-%d-%d", i, n) 7099 o, err := mset.addConsumer(workerModeConfig(oname)) 7100 if err != nil { 7101 t.Fatalf("Unexpected error: %v", err) 7102 } 7103 // Now grab some messages. 7104 toReceive := rand.Intn(toSend) + 1 7105 rsubj := o.requestNextMsgSubject() 7106 for r := 0; r < toReceive; r++ { 7107 resp, err := nc.Request(rsubj, nil, time.Second) 7108 require_NoError(t, err) 7109 if resp != nil { 7110 resp.Respond(nil) 7111 } 7112 } 7113 obs = append(obs, obsi{o.config(), toReceive}) 7114 } 7115 ostate[msetName] = info{mset.config(), mset.state(), obs} 7116 } 7117 pusage := acc.JetStreamUsage() 7118 nc.Flush() 7119 7120 // Shutdown and restart and make sure things come back. 7121 sd := s.JetStreamConfig().StoreDir 7122 s.Shutdown() 7123 7124 checkFor(t, 2*time.Second, 200*time.Millisecond, func() error { 7125 delta := (runtime.NumGoroutine() - base) 7126 if delta > 3 { 7127 return fmt.Errorf("%d Go routines still exist post Shutdown()", delta) 7128 } 7129 return nil 7130 }) 7131 7132 s = RunJetStreamServerOnPort(-1, sd) 7133 defer s.Shutdown() 7134 7135 acc = s.GlobalAccount() 7136 7137 nusage := acc.JetStreamUsage() 7138 if !reflect.DeepEqual(nusage, pusage) { 7139 t.Fatalf("Usage does not match after restore: %+v vs %+v", nusage, pusage) 7140 } 7141 7142 for mname, info := range ostate { 7143 mset, err := acc.lookupStream(mname) 7144 if err != nil { 7145 t.Fatalf("Expected to find a stream for %q", mname) 7146 } 7147 if state := mset.state(); !reflect.DeepEqual(state, info.state) { 7148 t.Fatalf("State does not match: %+v vs %+v", state, info.state) 7149 } 7150 if cfg := mset.config(); !reflect.DeepEqual(cfg, info.cfg) { 7151 t.Fatalf("Configs do not match: %+v vs %+v", cfg, info.cfg) 7152 } 7153 // Consumers. 7154 if mset.numConsumers() != len(info.obs) { 7155 t.Fatalf("Number of consumers do not match: %d vs %d", mset.numConsumers(), len(info.obs)) 7156 } 7157 for _, oi := range info.obs { 7158 if o := mset.lookupConsumer(oi.cfg.Durable); o != nil { 7159 if uint64(oi.ack+1) != o.nextSeq() { 7160 t.Fatalf("Consumer next seq is not correct: %d vs %d", oi.ack+1, o.nextSeq()) 7161 } 7162 } else { 7163 t.Fatalf("Expected to get an consumer") 7164 } 7165 } 7166 } 7167 } 7168 7169 func TestJetStreamPushConsumerFlowControl(t *testing.T) { 7170 s := RunBasicJetStreamServer(t) 7171 defer s.Shutdown() 7172 7173 // Client for API requests. 7174 nc, js := jsClientConnect(t, s) 7175 defer nc.Close() 7176 7177 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 7178 t.Fatalf("Unexpected error: %v", err) 7179 } 7180 7181 sub, err := nc.SubscribeSync(nats.NewInbox()) 7182 require_NoError(t, err) 7183 defer sub.Unsubscribe() 7184 7185 obsReq := CreateConsumerRequest{ 7186 Stream: "TEST", 7187 Config: ConsumerConfig{ 7188 Durable: "dlc", 7189 DeliverSubject: sub.Subject, 7190 FlowControl: true, 7191 Heartbeat: 5 * time.Second, 7192 }, 7193 } 7194 req, err := json.Marshal(obsReq) 7195 require_NoError(t, err) 7196 resp, err := nc.Request(fmt.Sprintf(JSApiDurableCreateT, "TEST", "dlc"), req, time.Second) 7197 require_NoError(t, err) 7198 var ccResp JSApiConsumerCreateResponse 7199 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7200 t.Fatalf("Unexpected error: %v", err) 7201 } 7202 if ccResp.Error != nil { 7203 t.Fatalf("Unexpected error: %+v", ccResp.Error) 7204 } 7205 7206 // Grab the low level consumer so we can manually set the fc max. 7207 if mset, err := s.GlobalAccount().lookupStream("TEST"); err != nil { 7208 t.Fatalf("Error looking up stream: %v", err) 7209 } else if obs := mset.lookupConsumer("dlc"); obs == nil { 7210 t.Fatalf("Error looking up stream: %v", err) 7211 } else { 7212 obs.mu.Lock() 7213 obs.setMaxPendingBytes(16 * 1024) 7214 obs.mu.Unlock() 7215 } 7216 7217 msgSize := 1024 7218 msg := make([]byte, msgSize) 7219 crand.Read(msg) 7220 7221 sendBatch := func(n int) { 7222 for i := 0; i < n; i++ { 7223 if _, err := js.Publish("TEST", msg); err != nil { 7224 t.Fatalf("Unexpected publish error: %v", err) 7225 } 7226 } 7227 } 7228 7229 checkSubPending := func(numExpected int) { 7230 t.Helper() 7231 checkFor(t, time.Second, 100*time.Millisecond, func() error { 7232 if nmsgs, _, err := sub.Pending(); err != nil || nmsgs != numExpected { 7233 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 7234 } 7235 return nil 7236 }) 7237 } 7238 7239 sendBatch(100) 7240 checkSubPending(2) // First four data and flowcontrol from slow start pause. 7241 7242 var n int 7243 for m, err := sub.NextMsg(time.Second); err == nil; m, err = sub.NextMsg(time.Second) { 7244 if m.Subject == "TEST" { 7245 n++ 7246 } else { 7247 // This should be a FC control message. 7248 if m.Header.Get("Status") != "100" { 7249 t.Fatalf("Expected a 100 status code, got %q", m.Header.Get("Status")) 7250 } 7251 if m.Header.Get("Description") != "FlowControl Request" { 7252 t.Fatalf("Wrong description, got %q", m.Header.Get("Description")) 7253 } 7254 m.Respond(nil) 7255 } 7256 } 7257 7258 if n != 100 { 7259 t.Fatalf("Expected to receive all 100 messages but got %d", n) 7260 } 7261 } 7262 7263 func TestJetStreamFlowControlRequiresHeartbeats(t *testing.T) { 7264 s := RunBasicJetStreamServer(t) 7265 defer s.Shutdown() 7266 7267 nc, js := jsClientConnect(t, s) 7268 defer nc.Close() 7269 7270 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 7271 t.Fatalf("Unexpected error: %v", err) 7272 } 7273 7274 if _, err := js.AddConsumer("TEST", &nats.ConsumerConfig{ 7275 Durable: "dlc", 7276 DeliverSubject: nats.NewInbox(), 7277 FlowControl: true, 7278 }); err == nil || IsNatsErr(err, JSConsumerWithFlowControlNeedsHeartbeats) { 7279 t.Fatalf("Unexpected error: %v", err) 7280 } 7281 } 7282 7283 func TestJetStreamPushConsumerIdleHeartbeats(t *testing.T) { 7284 s := RunBasicJetStreamServer(t) 7285 defer s.Shutdown() 7286 7287 // Client for API requests. 7288 nc, js := jsClientConnect(t, s) 7289 defer nc.Close() 7290 7291 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 7292 t.Fatalf("Unexpected error: %v", err) 7293 } 7294 7295 sub, err := nc.SubscribeSync(nats.NewInbox()) 7296 require_NoError(t, err) 7297 defer sub.Unsubscribe() 7298 7299 // Test errors first 7300 obsReq := CreateConsumerRequest{ 7301 Stream: "TEST", 7302 Config: ConsumerConfig{ 7303 DeliverSubject: sub.Subject, 7304 Heartbeat: time.Millisecond, 7305 }, 7306 } 7307 req, err := json.Marshal(obsReq) 7308 require_NoError(t, err) 7309 resp, err := nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "TEST"), req, time.Second) 7310 require_NoError(t, err) 7311 var ccResp JSApiConsumerCreateResponse 7312 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7313 t.Fatalf("Unexpected error: %v", err) 7314 } 7315 if ccResp.Error == nil { 7316 t.Fatalf("Expected an error, got none") 7317 } 7318 // Set acceptable heartbeat. 7319 obsReq.Config.Heartbeat = 100 * time.Millisecond 7320 req, err = json.Marshal(obsReq) 7321 require_NoError(t, err) 7322 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "TEST"), req, time.Second) 7323 require_NoError(t, err) 7324 ccResp.Error = nil 7325 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7326 t.Fatalf("Unexpected error: %v", err) 7327 } 7328 checkFor(t, time.Second, 20*time.Millisecond, func() error { 7329 if nmsgs, _, err := sub.Pending(); err != nil || nmsgs < 9 { 7330 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, 9) 7331 } 7332 return nil 7333 }) 7334 m, _ := sub.NextMsg(0) 7335 if m.Header.Get("Status") != "100" { 7336 t.Fatalf("Expected a 100 status code, got %q", m.Header.Get("Status")) 7337 } 7338 if m.Header.Get("Description") != "Idle Heartbeat" { 7339 t.Fatalf("Wrong description, got %q", m.Header.Get("Description")) 7340 } 7341 } 7342 7343 func TestJetStreamPushConsumerIdleHeartbeatsWithFilterSubject(t *testing.T) { 7344 s := RunBasicJetStreamServer(t) 7345 defer s.Shutdown() 7346 7347 // Client for API requests. 7348 nc, js := jsClientConnect(t, s) 7349 defer nc.Close() 7350 7351 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"foo", "bar"}}); err != nil { 7352 t.Fatalf("Unexpected error: %v", err) 7353 } 7354 7355 hbC := make(chan *nats.Msg, 8) 7356 sub, err := nc.ChanSubscribe(nats.NewInbox(), hbC) 7357 require_NoError(t, err) 7358 defer sub.Unsubscribe() 7359 7360 obsReq := CreateConsumerRequest{ 7361 Stream: "TEST", 7362 Config: ConsumerConfig{ 7363 DeliverSubject: sub.Subject, 7364 FilterSubject: "bar", 7365 Heartbeat: 100 * time.Millisecond, 7366 }, 7367 } 7368 7369 req, err := json.Marshal(obsReq) 7370 require_NoError(t, err) 7371 resp, err := nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "TEST"), req, time.Second) 7372 require_NoError(t, err) 7373 var ccResp JSApiConsumerCreateResponse 7374 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7375 t.Fatalf("Unexpected error: %v", err) 7376 } 7377 7378 st := time.NewTicker(10 * time.Millisecond) 7379 defer st.Stop() 7380 7381 done := time.NewTimer(time.Second) 7382 defer done.Stop() 7383 7384 for { 7385 select { 7386 case <-st.C: 7387 js.Publish("foo", []byte("HELLO FOO")) 7388 case <-done.C: 7389 t.Fatalf("Expected to have seen idle heartbeats for consumer") 7390 case <-hbC: 7391 return 7392 } 7393 } 7394 } 7395 7396 func TestJetStreamPushConsumerIdleHeartbeatsWithNoInterest(t *testing.T) { 7397 s := RunBasicJetStreamServer(t) 7398 defer s.Shutdown() 7399 7400 // Client for API requests. 7401 nc, js := jsClientConnect(t, s) 7402 defer nc.Close() 7403 7404 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 7405 t.Fatalf("Unexpected error: %v", err) 7406 } 7407 7408 dsubj := "d.22" 7409 hbC := make(chan *nats.Msg, 8) 7410 sub, err := nc.ChanSubscribe("d.>", hbC) 7411 require_NoError(t, err) 7412 defer sub.Unsubscribe() 7413 7414 obsReq := CreateConsumerRequest{ 7415 Stream: "TEST", 7416 Config: ConsumerConfig{ 7417 DeliverSubject: dsubj, 7418 Heartbeat: 100 * time.Millisecond, 7419 }, 7420 } 7421 7422 req, err := json.Marshal(obsReq) 7423 require_NoError(t, err) 7424 resp, err := nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "TEST"), req, time.Second) 7425 require_NoError(t, err) 7426 var ccResp JSApiConsumerCreateResponse 7427 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7428 t.Fatalf("Unexpected error: %v", err) 7429 } 7430 if ccResp.Error != nil { 7431 t.Fatalf("Unexpected error: %+v", ccResp.Error) 7432 } 7433 7434 done := time.NewTimer(400 * time.Millisecond) 7435 defer done.Stop() 7436 7437 for { 7438 select { 7439 case <-done.C: 7440 return 7441 case m := <-hbC: 7442 if m.Header.Get("Status") == "100" { 7443 t.Fatalf("Did not expect to see a heartbeat with no formal interest") 7444 } 7445 } 7446 } 7447 } 7448 7449 func TestJetStreamInfoAPIWithHeaders(t *testing.T) { 7450 s := RunBasicJetStreamServer(t) 7451 defer s.Shutdown() 7452 7453 // Client for API requests. 7454 nc := clientConnectToServer(t, s) 7455 defer nc.Close() 7456 7457 m := nats.NewMsg(JSApiAccountInfo) 7458 m.Header.Add("Accept-Encoding", "json") 7459 m.Header.Add("Authorization", "s3cr3t") 7460 m.Data = []byte("HELLO-JS!") 7461 7462 resp, err := nc.RequestMsg(m, time.Second) 7463 require_NoError(t, err) 7464 7465 var info JSApiAccountInfoResponse 7466 if err := json.Unmarshal(resp.Data, &info); err != nil { 7467 t.Fatalf("Unexpected error: %v", err) 7468 } 7469 if info.Error != nil { 7470 t.Fatalf("Received an error: %+v", info.Error) 7471 } 7472 } 7473 7474 func TestJetStreamRequestAPI(t *testing.T) { 7475 s := RunBasicJetStreamServer(t) 7476 defer s.Shutdown() 7477 7478 // Client for API requests. 7479 nc := clientConnectToServer(t, s) 7480 defer nc.Close() 7481 7482 // This will get the current information about usage and limits for this account. 7483 resp, err := nc.Request(JSApiAccountInfo, nil, time.Second) 7484 require_NoError(t, err) 7485 var info JSApiAccountInfoResponse 7486 if err := json.Unmarshal(resp.Data, &info); err != nil { 7487 t.Fatalf("Unexpected error: %v", err) 7488 } 7489 7490 // Now create a stream. 7491 msetCfg := StreamConfig{ 7492 Name: "MSET22", 7493 Storage: FileStorage, 7494 Subjects: []string{"foo", "bar", "baz"}, 7495 MaxMsgs: 100, 7496 } 7497 req, err := json.Marshal(msetCfg) 7498 require_NoError(t, err) 7499 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamCreateT, msetCfg.Name), req, time.Second) 7500 var scResp JSApiStreamCreateResponse 7501 if err := json.Unmarshal(resp.Data, &scResp); err != nil { 7502 t.Fatalf("Unexpected error: %v", err) 7503 } 7504 if scResp.StreamInfo == nil || scResp.Error != nil { 7505 t.Fatalf("Did not receive correct response: %+v", scResp.Error) 7506 } 7507 if time.Since(scResp.Created) > time.Second { 7508 t.Fatalf("Created time seems wrong: %v\n", scResp.Created) 7509 } 7510 7511 // Check that the name in config has to match the name in the subject 7512 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamCreateT, "BOB"), req, time.Second) 7513 scResp.Error, scResp.StreamInfo = nil, nil 7514 if err := json.Unmarshal(resp.Data, &scResp); err != nil { 7515 t.Fatalf("Unexpected error: %v", err) 7516 } 7517 checkNatsError(t, scResp.Error, JSStreamMismatchErr) 7518 7519 // Check that update works. 7520 msetCfg.Subjects = []string{"foo", "bar", "baz"} 7521 msetCfg.MaxBytes = 2222222 7522 req, err = json.Marshal(msetCfg) 7523 require_NoError(t, err) 7524 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamUpdateT, msetCfg.Name), req, time.Second) 7525 scResp.Error, scResp.StreamInfo = nil, nil 7526 if err := json.Unmarshal(resp.Data, &scResp); err != nil { 7527 t.Fatalf("Unexpected error: %v", err) 7528 } 7529 if scResp.StreamInfo == nil || scResp.Error != nil { 7530 t.Fatalf("Did not receive correct response: %+v", scResp.Error) 7531 } 7532 7533 // Check that updating a non existing stream fails 7534 cfg := StreamConfig{ 7535 Name: "UNKNOWN_STREAM", 7536 Storage: FileStorage, 7537 Subjects: []string{"foo"}, 7538 } 7539 req, err = json.Marshal(cfg) 7540 require_NoError(t, err) 7541 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamUpdateT, cfg.Name), req, time.Second) 7542 scResp.Error, scResp.StreamInfo = nil, nil 7543 if err := json.Unmarshal(resp.Data, &scResp); err != nil { 7544 t.Fatalf("Unexpected error: %v", err) 7545 } 7546 if scResp.StreamInfo != nil || scResp.Error == nil || scResp.Error.Code != 404 { 7547 t.Fatalf("Unexpected error: %+v", scResp.Error) 7548 } 7549 7550 // Now lookup info again and see that we can see the new stream. 7551 resp, err = nc.Request(JSApiAccountInfo, nil, time.Second) 7552 require_NoError(t, err) 7553 if err = json.Unmarshal(resp.Data, &info); err != nil { 7554 t.Fatalf("Unexpected error: %v", err) 7555 } 7556 if info.Streams != 1 { 7557 t.Fatalf("Expected to see 1 Stream, got %d", info.Streams) 7558 } 7559 7560 // Make sure list names works. 7561 resp, err = nc.Request(JSApiStreams, nil, time.Second) 7562 require_NoError(t, err) 7563 var namesResponse JSApiStreamNamesResponse 7564 if err = json.Unmarshal(resp.Data, &namesResponse); err != nil { 7565 t.Fatalf("Unexpected error: %v", err) 7566 } 7567 7568 if len(namesResponse.Streams) != 1 { 7569 t.Fatalf("Expected only 1 stream but got %d", len(namesResponse.Streams)) 7570 } 7571 if namesResponse.Total != 1 { 7572 t.Fatalf("Expected total to be 1 but got %d", namesResponse.Total) 7573 } 7574 if namesResponse.Offset != 0 { 7575 t.Fatalf("Expected offset to be 0 but got %d", namesResponse.Offset) 7576 } 7577 if namesResponse.Limit != JSApiNamesLimit { 7578 t.Fatalf("Expected limit to be %d but got %d", JSApiNamesLimit, namesResponse.Limit) 7579 } 7580 if namesResponse.Streams[0] != msetCfg.Name { 7581 t.Fatalf("Expected to get %q, but got %q", msetCfg.Name, namesResponse.Streams[0]) 7582 } 7583 7584 // Now do detailed version. 7585 resp, err = nc.Request(JSApiStreamList, nil, time.Second) 7586 require_NoError(t, err) 7587 var listResponse JSApiStreamListResponse 7588 if err = json.Unmarshal(resp.Data, &listResponse); err != nil { 7589 t.Fatalf("Unexpected error: %v", err) 7590 } 7591 7592 if len(listResponse.Streams) != 1 { 7593 t.Fatalf("Expected only 1 stream but got %d", len(listResponse.Streams)) 7594 } 7595 if listResponse.Total != 1 { 7596 t.Fatalf("Expected total to be 1 but got %d", listResponse.Total) 7597 } 7598 if listResponse.Offset != 0 { 7599 t.Fatalf("Expected offset to be 0 but got %d", listResponse.Offset) 7600 } 7601 if listResponse.Limit != JSApiListLimit { 7602 t.Fatalf("Expected limit to be %d but got %d", JSApiListLimit, listResponse.Limit) 7603 } 7604 if listResponse.Streams[0].Config.Name != msetCfg.Name { 7605 t.Fatalf("Expected to get %q, but got %q", msetCfg.Name, listResponse.Streams[0].Config.Name) 7606 } 7607 7608 // Now send some messages, then we can poll for info on this stream. 7609 toSend := 10 7610 for i := 0; i < toSend; i++ { 7611 nc.Request("foo", []byte("WELCOME JETSTREAM"), time.Second) 7612 } 7613 7614 resp, err = nc.Request(fmt.Sprintf(JSApiStreamInfoT, msetCfg.Name), nil, time.Second) 7615 require_NoError(t, err) 7616 var msi StreamInfo 7617 if err = json.Unmarshal(resp.Data, &msi); err != nil { 7618 t.Fatalf("Unexpected error: %v", err) 7619 } 7620 if msi.State.Msgs != uint64(toSend) { 7621 t.Fatalf("Expected to get %d msgs, got %d", toSend, msi.State.Msgs) 7622 } 7623 if time.Since(msi.Created) > time.Second { 7624 t.Fatalf("Created time seems wrong: %v\n", msi.Created) 7625 } 7626 7627 // Looking up one that is not there should yield an error. 7628 resp, err = nc.Request(fmt.Sprintf(JSApiStreamInfoT, "BOB"), nil, time.Second) 7629 require_NoError(t, err) 7630 var bResp JSApiStreamInfoResponse 7631 if err = json.Unmarshal(resp.Data, &bResp); err != nil { 7632 t.Fatalf("Unexpected error: %v", err) 7633 } 7634 checkNatsError(t, bResp.Error, JSStreamNotFoundErr) 7635 7636 // Now create a consumer. 7637 delivery := nats.NewInbox() 7638 obsReq := CreateConsumerRequest{ 7639 Stream: msetCfg.Name, 7640 Config: ConsumerConfig{DeliverSubject: delivery}, 7641 } 7642 req, err = json.Marshal(obsReq) 7643 require_NoError(t, err) 7644 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, msetCfg.Name), req, time.Second) 7645 require_NoError(t, err) 7646 var ccResp JSApiConsumerCreateResponse 7647 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7648 t.Fatalf("Unexpected error: %v", err) 7649 } 7650 // Ephemerals are now not rejected when there is no interest. 7651 if ccResp.ConsumerInfo == nil || ccResp.Error != nil { 7652 t.Fatalf("Got a bad response %+v", ccResp) 7653 } 7654 if time.Since(ccResp.Created) > time.Second { 7655 t.Fatalf("Created time seems wrong: %v\n", ccResp.Created) 7656 } 7657 7658 // Now create subscription and make sure we get proper response. 7659 sub, _ := nc.SubscribeSync(delivery) 7660 nc.Flush() 7661 7662 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 7663 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != toSend { 7664 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, toSend) 7665 } 7666 return nil 7667 }) 7668 7669 // Check that we get an error if the stream name in the subject does not match the config. 7670 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "BOB"), req, time.Second) 7671 require_NoError(t, err) 7672 ccResp.Error, ccResp.ConsumerInfo = nil, nil 7673 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7674 t.Fatalf("Unexpected error: %v", err) 7675 } 7676 // Since we do not have interest this should have failed. 7677 checkNatsError(t, ccResp.Error, JSStreamMismatchErr) 7678 7679 // Get the list of all of the consumers for our stream. 7680 resp, err = nc.Request(fmt.Sprintf(JSApiConsumersT, msetCfg.Name), nil, time.Second) 7681 require_NoError(t, err) 7682 var clResponse JSApiConsumerNamesResponse 7683 if err = json.Unmarshal(resp.Data, &clResponse); err != nil { 7684 t.Fatalf("Unexpected error: %v", err) 7685 } 7686 if len(clResponse.Consumers) != 1 { 7687 t.Fatalf("Expected only 1 consumer but got %d", len(clResponse.Consumers)) 7688 } 7689 // Now let's get info about our consumer. 7690 cName := clResponse.Consumers[0] 7691 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerInfoT, msetCfg.Name, cName), nil, time.Second) 7692 require_NoError(t, err) 7693 var oinfo ConsumerInfo 7694 if err = json.Unmarshal(resp.Data, &oinfo); err != nil { 7695 t.Fatalf("Unexpected error: %v", err) 7696 } 7697 // Do some sanity checking. 7698 // Must match consumer.go 7699 const randConsumerNameLen = 8 7700 if len(oinfo.Name) != randConsumerNameLen { 7701 t.Fatalf("Expected ephemeral name, got %q", oinfo.Name) 7702 } 7703 if len(oinfo.Config.Durable) != 0 { 7704 t.Fatalf("Expected no durable name, but got %q", oinfo.Config.Durable) 7705 } 7706 if oinfo.Config.DeliverSubject != delivery { 7707 t.Fatalf("Expected to have delivery subject of %q, got %q", delivery, oinfo.Config.DeliverSubject) 7708 } 7709 if oinfo.Delivered.Consumer != 10 { 7710 t.Fatalf("Expected consumer delivered sequence of 10, got %d", oinfo.Delivered.Consumer) 7711 } 7712 if oinfo.AckFloor.Consumer != 10 { 7713 t.Fatalf("Expected ack floor to be 10, got %d", oinfo.AckFloor.Consumer) 7714 } 7715 7716 // Now delete the consumer. 7717 resp, _ = nc.Request(fmt.Sprintf(JSApiConsumerDeleteT, msetCfg.Name, cName), nil, time.Second) 7718 var cdResp JSApiConsumerDeleteResponse 7719 if err = json.Unmarshal(resp.Data, &cdResp); err != nil { 7720 t.Fatalf("Unexpected error: %v", err) 7721 } 7722 if !cdResp.Success || cdResp.Error != nil { 7723 t.Fatalf("Got a bad response %+v", ccResp) 7724 } 7725 7726 // Make sure we can't create a durable using the ephemeral API endpoint. 7727 obsReq = CreateConsumerRequest{ 7728 Stream: msetCfg.Name, 7729 Config: ConsumerConfig{Durable: "myd", DeliverSubject: delivery}, 7730 } 7731 req, err = json.Marshal(obsReq) 7732 require_NoError(t, err) 7733 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, msetCfg.Name), req, time.Second) 7734 require_NoError(t, err) 7735 ccResp.Error, ccResp.ConsumerInfo = nil, nil 7736 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7737 t.Fatalf("Unexpected error: %v", err) 7738 } 7739 checkNatsError(t, ccResp.Error, JSConsumerEphemeralWithDurableNameErr) 7740 7741 // Now make sure we can create a durable on the subject with the proper name. 7742 resp, err = nc.Request(fmt.Sprintf(JSApiDurableCreateT, msetCfg.Name, obsReq.Config.Durable), req, time.Second) 7743 ccResp.Error, ccResp.ConsumerInfo = nil, nil 7744 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7745 t.Fatalf("Unexpected error: %v", err) 7746 } 7747 if ccResp.ConsumerInfo == nil || ccResp.Error != nil { 7748 t.Fatalf("Did not receive correct response") 7749 } 7750 7751 // Make sure empty durable in cfg does not work 7752 obsReq2 := CreateConsumerRequest{ 7753 Stream: msetCfg.Name, 7754 Config: ConsumerConfig{DeliverSubject: delivery}, 7755 } 7756 req2, err := json.Marshal(obsReq2) 7757 require_NoError(t, err) 7758 resp, err = nc.Request(fmt.Sprintf(JSApiDurableCreateT, msetCfg.Name, obsReq.Config.Durable), req2, time.Second) 7759 require_NoError(t, err) 7760 ccResp.Error, ccResp.ConsumerInfo = nil, nil 7761 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 7762 t.Fatalf("Unexpected error: %v", err) 7763 } 7764 checkNatsError(t, ccResp.Error, JSConsumerDurableNameNotSetErr) 7765 7766 // Now delete a msg. 7767 dreq := JSApiMsgDeleteRequest{Seq: 2} 7768 dreqj, err := json.Marshal(dreq) 7769 require_NoError(t, err) 7770 resp, _ = nc.Request(fmt.Sprintf(JSApiMsgDeleteT, msetCfg.Name), dreqj, time.Second) 7771 var delMsgResp JSApiMsgDeleteResponse 7772 if err = json.Unmarshal(resp.Data, &delMsgResp); err != nil { 7773 t.Fatalf("Unexpected error: %v", err) 7774 } 7775 if !delMsgResp.Success || delMsgResp.Error != nil { 7776 t.Fatalf("Got a bad response %+v", delMsgResp.Error) 7777 } 7778 7779 // Now purge the stream. 7780 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamPurgeT, msetCfg.Name), nil, time.Second) 7781 var pResp JSApiStreamPurgeResponse 7782 if err = json.Unmarshal(resp.Data, &pResp); err != nil { 7783 t.Fatalf("Unexpected error: %v", err) 7784 } 7785 if !pResp.Success || pResp.Error != nil { 7786 t.Fatalf("Got a bad response %+v", pResp) 7787 } 7788 if pResp.Purged != 9 { 7789 t.Fatalf("Expected 9 purged, got %d", pResp.Purged) 7790 } 7791 7792 // Now delete the stream. 7793 resp, _ = nc.Request(fmt.Sprintf(JSApiStreamDeleteT, msetCfg.Name), nil, time.Second) 7794 var dResp JSApiStreamDeleteResponse 7795 if err = json.Unmarshal(resp.Data, &dResp); err != nil { 7796 t.Fatalf("Unexpected error: %v", err) 7797 } 7798 if !dResp.Success || dResp.Error != nil { 7799 t.Fatalf("Got a bad response %+v", dResp.Error) 7800 } 7801 7802 // Now grab stats again. 7803 // This will get the current information about usage and limits for this account. 7804 resp, err = nc.Request(JSApiAccountInfo, nil, time.Second) 7805 require_NoError(t, err) 7806 if err := json.Unmarshal(resp.Data, &info); err != nil { 7807 t.Fatalf("Unexpected error: %v", err) 7808 } 7809 if info.Streams != 0 { 7810 t.Fatalf("Expected no remaining streams, got %d", info.Streams) 7811 } 7812 7813 // Now do templates. 7814 mcfg := &StreamConfig{ 7815 Subjects: []string{"kv.*"}, 7816 Retention: LimitsPolicy, 7817 MaxAge: time.Hour, 7818 MaxMsgs: 4, 7819 Storage: MemoryStorage, 7820 Replicas: 1, 7821 } 7822 template := &StreamTemplateConfig{ 7823 Name: "kv", 7824 Config: mcfg, 7825 MaxStreams: 4, 7826 } 7827 req, err = json.Marshal(template) 7828 require_NoError(t, err) 7829 7830 // Check that the name in config has to match the name in the subject 7831 resp, _ = nc.Request(fmt.Sprintf(JSApiTemplateCreateT, "BOB"), req, time.Second) 7832 var stResp JSApiStreamTemplateCreateResponse 7833 if err = json.Unmarshal(resp.Data, &stResp); err != nil { 7834 t.Fatalf("Unexpected error: %v", err) 7835 } 7836 checkNatsError(t, stResp.Error, JSTemplateNameNotMatchSubjectErr) 7837 7838 resp, _ = nc.Request(fmt.Sprintf(JSApiTemplateCreateT, template.Name), req, time.Second) 7839 stResp.Error, stResp.StreamTemplateInfo = nil, nil 7840 if err = json.Unmarshal(resp.Data, &stResp); err != nil { 7841 t.Fatalf("Unexpected error: %v", err) 7842 } 7843 if stResp.StreamTemplateInfo == nil || stResp.Error != nil { 7844 t.Fatalf("Did not receive correct response") 7845 } 7846 7847 // Create a second one. 7848 template.Name = "ss" 7849 template.Config.Subjects = []string{"foo", "bar"} 7850 7851 req, err = json.Marshal(template) 7852 if err != nil { 7853 t.Fatalf("Unexpected error: %s", err) 7854 } 7855 7856 resp, _ = nc.Request(fmt.Sprintf(JSApiTemplateCreateT, template.Name), req, time.Second) 7857 stResp.Error, stResp.StreamTemplateInfo = nil, nil 7858 if err = json.Unmarshal(resp.Data, &stResp); err != nil { 7859 t.Fatalf("Unexpected error: %v", err) 7860 } 7861 if stResp.StreamTemplateInfo == nil || stResp.Error != nil { 7862 t.Fatalf("Did not receive correct response") 7863 } 7864 7865 // Now grab the list of templates 7866 var tListResp JSApiStreamTemplateNamesResponse 7867 resp, err = nc.Request(JSApiTemplates, nil, time.Second) 7868 if err = json.Unmarshal(resp.Data, &tListResp); err != nil { 7869 t.Fatalf("Unexpected error: %v", err) 7870 } 7871 if len(tListResp.Templates) != 2 { 7872 t.Fatalf("Expected 2 templates but got %d", len(tListResp.Templates)) 7873 } 7874 sort.Strings(tListResp.Templates) 7875 if tListResp.Templates[0] != "kv" { 7876 t.Fatalf("Expected to get %q, but got %q", "kv", tListResp.Templates[0]) 7877 } 7878 if tListResp.Templates[1] != "ss" { 7879 t.Fatalf("Expected to get %q, but got %q", "ss", tListResp.Templates[1]) 7880 } 7881 7882 // Now delete one. 7883 // Test bad name. 7884 resp, _ = nc.Request(fmt.Sprintf(JSApiTemplateDeleteT, "bob"), nil, time.Second) 7885 var tDeleteResp JSApiStreamTemplateDeleteResponse 7886 if err = json.Unmarshal(resp.Data, &tDeleteResp); err != nil { 7887 t.Fatalf("Unexpected error: %v", err) 7888 } 7889 checkNatsError(t, tDeleteResp.Error, JSStreamTemplateNotFoundErr) 7890 7891 resp, _ = nc.Request(fmt.Sprintf(JSApiTemplateDeleteT, "ss"), nil, time.Second) 7892 tDeleteResp.Error = nil 7893 if err = json.Unmarshal(resp.Data, &tDeleteResp); err != nil { 7894 t.Fatalf("Unexpected error: %v", err) 7895 } 7896 if !tDeleteResp.Success || tDeleteResp.Error != nil { 7897 t.Fatalf("Did not receive correct response: %+v", tDeleteResp.Error) 7898 } 7899 7900 resp, err = nc.Request(JSApiTemplates, nil, time.Second) 7901 tListResp.Error, tListResp.Templates = nil, nil 7902 if err = json.Unmarshal(resp.Data, &tListResp); err != nil { 7903 t.Fatalf("Unexpected error: %v", err) 7904 } 7905 if len(tListResp.Templates) != 1 { 7906 t.Fatalf("Expected 1 template but got %d", len(tListResp.Templates)) 7907 } 7908 if tListResp.Templates[0] != "kv" { 7909 t.Fatalf("Expected to get %q, but got %q", "kv", tListResp.Templates[0]) 7910 } 7911 7912 // First create a stream from the template 7913 sendStreamMsg(t, nc, "kv.22", "derek") 7914 // Last do info 7915 resp, err = nc.Request(fmt.Sprintf(JSApiTemplateInfoT, "kv"), nil, time.Second) 7916 require_NoError(t, err) 7917 var ti StreamTemplateInfo 7918 if err = json.Unmarshal(resp.Data, &ti); err != nil { 7919 t.Fatalf("Unexpected error: %v", err) 7920 } 7921 if len(ti.Streams) != 1 { 7922 t.Fatalf("Expected 1 stream, got %d", len(ti.Streams)) 7923 } 7924 if ti.Streams[0] != canonicalName("kv.22") { 7925 t.Fatalf("Expected stream with name %q, but got %q", canonicalName("kv.22"), ti.Streams[0]) 7926 } 7927 7928 // Test that we can send nil or an empty legal json for requests that take no args. 7929 // We know this stream does not exist, this just checking request processing. 7930 checkEmptyReqArg := func(arg string) { 7931 t.Helper() 7932 var req []byte 7933 if len(arg) > 0 { 7934 req = []byte(arg) 7935 } 7936 resp, err = nc.Request(fmt.Sprintf(JSApiStreamDeleteT, "foo_bar_baz"), req, time.Second) 7937 var dResp JSApiStreamDeleteResponse 7938 if err = json.Unmarshal(resp.Data, &dResp); err != nil { 7939 t.Fatalf("Unexpected error: %v", err) 7940 } 7941 if dResp.Error == nil || dResp.Error.Code != 404 { 7942 t.Fatalf("Got a bad response, expected a 404 response %+v", dResp.Error) 7943 } 7944 } 7945 7946 checkEmptyReqArg("") 7947 checkEmptyReqArg("{}") 7948 checkEmptyReqArg(" {} ") 7949 checkEmptyReqArg(" { } ") 7950 } 7951 7952 func TestJetStreamFilteredStreamNames(t *testing.T) { 7953 s := RunBasicJetStreamServer(t) 7954 defer s.Shutdown() 7955 7956 // Client for API requests. 7957 nc := clientConnectToServer(t, s) 7958 defer nc.Close() 7959 7960 // Create some streams. 7961 var snid int 7962 createStream := func(subjects []string) { 7963 t.Helper() 7964 snid++ 7965 name := fmt.Sprintf("S-%d", snid) 7966 sc := &StreamConfig{Name: name, Subjects: subjects} 7967 if _, err := s.GlobalAccount().addStream(sc); err != nil { 7968 t.Fatalf("Unexpected error adding stream: %v", err) 7969 } 7970 } 7971 7972 createStream([]string{"foo"}) // S1 7973 createStream([]string{"bar"}) // S2 7974 createStream([]string{"baz"}) // S3 7975 createStream([]string{"foo.*", "bar.*"}) // S4 7976 createStream([]string{"foo-1.22", "bar-1.33"}) // S5 7977 7978 expectStreams := func(filter string, streams []string) { 7979 t.Helper() 7980 req, _ := json.Marshal(&JSApiStreamNamesRequest{Subject: filter}) 7981 r, _ := nc.Request(JSApiStreams, req, time.Second) 7982 var resp JSApiStreamNamesResponse 7983 if err := json.Unmarshal(r.Data, &resp); err != nil { 7984 t.Fatalf("Unexpected error: %v", err) 7985 } 7986 if len(resp.Streams) != len(streams) { 7987 t.Fatalf("Expected %d results, got %d", len(streams), len(resp.Streams)) 7988 } 7989 } 7990 7991 expectStreams("foo", []string{"S1"}) 7992 expectStreams("bar", []string{"S2"}) 7993 expectStreams("baz", []string{"S3"}) 7994 expectStreams("*", []string{"S1", "S2", "S3"}) 7995 expectStreams(">", []string{"S1", "S2", "S3", "S4", "S5"}) 7996 expectStreams("*.*", []string{"S4", "S5"}) 7997 expectStreams("*.22", []string{"S4", "S5"}) 7998 } 7999 8000 func TestJetStreamUpdateStream(t *testing.T) { 8001 cases := []struct { 8002 name string 8003 mconfig *StreamConfig 8004 }{ 8005 {name: "MemoryStore", 8006 mconfig: &StreamConfig{ 8007 Name: "foo", 8008 Retention: LimitsPolicy, 8009 MaxAge: time.Hour, 8010 Storage: MemoryStorage, 8011 Replicas: 1, 8012 }}, 8013 {name: "FileStore", 8014 mconfig: &StreamConfig{ 8015 Name: "foo", 8016 Retention: LimitsPolicy, 8017 MaxAge: time.Hour, 8018 Storage: FileStorage, 8019 Replicas: 1, 8020 }}, 8021 } 8022 for _, c := range cases { 8023 t.Run(c.name, func(t *testing.T) { 8024 s := RunBasicJetStreamServer(t) 8025 defer s.Shutdown() 8026 8027 mset, err := s.GlobalAccount().addStream(c.mconfig) 8028 if err != nil { 8029 t.Fatalf("Unexpected error adding stream: %v", err) 8030 } 8031 defer mset.delete() 8032 8033 // Test basic updates. We allow changing the subjects, limits, and no_ack along with replicas(TBD w/ cluster) 8034 cfg := *c.mconfig 8035 8036 // Can't change name. 8037 cfg.Name = "bar" 8038 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "name must match") { 8039 t.Fatalf("Expected error trying to update name") 8040 } 8041 // Can't change max consumers for now. 8042 cfg = *c.mconfig 8043 cfg.MaxConsumers = 10 8044 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "can not change") { 8045 t.Fatalf("Expected error trying to change MaxConsumers") 8046 } 8047 // Can't change storage types. 8048 cfg = *c.mconfig 8049 if cfg.Storage == FileStorage { 8050 cfg.Storage = MemoryStorage 8051 } else { 8052 cfg.Storage = FileStorage 8053 } 8054 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "can not change") { 8055 t.Fatalf("Expected error trying to change Storage") 8056 } 8057 // Can't change replicas > 1 for now. 8058 cfg = *c.mconfig 8059 cfg.Replicas = 10 8060 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "maximum replicas") { 8061 t.Fatalf("Expected error trying to change Replicas") 8062 } 8063 // Can't have a template set for now. 8064 cfg = *c.mconfig 8065 cfg.Template = "baz" 8066 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "template") { 8067 t.Fatalf("Expected error trying to change Template owner") 8068 } 8069 // Can't change limits policy. 8070 cfg = *c.mconfig 8071 cfg.Retention = WorkQueuePolicy 8072 if err := mset.update(&cfg); err == nil || !strings.Contains(err.Error(), "can not change") { 8073 t.Fatalf("Expected error trying to change Retention") 8074 } 8075 8076 // Now test changing limits. 8077 nc := clientConnectToServer(t, s) 8078 defer nc.Close() 8079 8080 pending := uint64(100) 8081 for i := uint64(0); i < pending; i++ { 8082 sendStreamMsg(t, nc, "foo", "0123456789") 8083 } 8084 pendingBytes := mset.state().Bytes 8085 8086 checkPending := func(msgs, bts uint64) { 8087 t.Helper() 8088 state := mset.state() 8089 if state.Msgs != msgs { 8090 t.Fatalf("Expected %d messages, got %d", msgs, state.Msgs) 8091 } 8092 if state.Bytes != bts { 8093 t.Fatalf("Expected %d bytes, got %d", bts, state.Bytes) 8094 } 8095 } 8096 checkPending(pending, pendingBytes) 8097 8098 // Update msgs to higher. 8099 cfg = *c.mconfig 8100 cfg.MaxMsgs = int64(pending * 2) 8101 if err := mset.update(&cfg); err != nil { 8102 t.Fatalf("Unexpected error %v", err) 8103 } 8104 if mset.config().MaxMsgs != cfg.MaxMsgs { 8105 t.Fatalf("Expected the change to take effect, %d vs %d", mset.config().MaxMsgs, cfg.MaxMsgs) 8106 } 8107 checkPending(pending, pendingBytes) 8108 8109 // Update msgs to lower. 8110 cfg = *c.mconfig 8111 cfg.MaxMsgs = int64(pending / 2) 8112 if err := mset.update(&cfg); err != nil { 8113 t.Fatalf("Unexpected error %v", err) 8114 } 8115 if mset.config().MaxMsgs != cfg.MaxMsgs { 8116 t.Fatalf("Expected the change to take effect, %d vs %d", mset.config().MaxMsgs, cfg.MaxMsgs) 8117 } 8118 checkPending(pending/2, pendingBytes/2) 8119 // Now do bytes. 8120 cfg = *c.mconfig 8121 cfg.MaxBytes = int64(pendingBytes / 4) 8122 if err := mset.update(&cfg); err != nil { 8123 t.Fatalf("Unexpected error %v", err) 8124 } 8125 if mset.config().MaxBytes != cfg.MaxBytes { 8126 t.Fatalf("Expected the change to take effect, %d vs %d", mset.config().MaxBytes, cfg.MaxBytes) 8127 } 8128 checkPending(pending/4, pendingBytes/4) 8129 8130 // Now do age. 8131 cfg = *c.mconfig 8132 cfg.MaxAge = time.Second 8133 if err := mset.update(&cfg); err != nil { 8134 t.Fatalf("Unexpected error %v", err) 8135 } 8136 // Just wait a bit for expiration. 8137 time.Sleep(2 * time.Second) 8138 if mset.config().MaxAge != cfg.MaxAge { 8139 t.Fatalf("Expected the change to take effect, %d vs %d", mset.config().MaxAge, cfg.MaxAge) 8140 } 8141 checkPending(0, 0) 8142 8143 // Now put back to original. 8144 cfg = *c.mconfig 8145 if err := mset.update(&cfg); err != nil { 8146 t.Fatalf("Unexpected error %v", err) 8147 } 8148 for i := uint64(0); i < pending; i++ { 8149 sendStreamMsg(t, nc, "foo", "0123456789") 8150 } 8151 8152 // subject changes. 8153 // Add in a subject first. 8154 cfg = *c.mconfig 8155 cfg.Subjects = []string{"foo", "bar"} 8156 if err := mset.update(&cfg); err != nil { 8157 t.Fatalf("Unexpected error %v", err) 8158 } 8159 // Make sure we can still send to foo. 8160 sendStreamMsg(t, nc, "foo", "0123456789") 8161 // And we can now send to bar. 8162 sendStreamMsg(t, nc, "bar", "0123456789") 8163 // Now delete both and change to baz only. 8164 cfg.Subjects = []string{"baz"} 8165 if err := mset.update(&cfg); err != nil { 8166 t.Fatalf("Unexpected error %v", err) 8167 } 8168 // Make sure we do not get response acks for "foo" or "bar". 8169 if resp, err := nc.Request("foo", nil, 25*time.Millisecond); err == nil || resp != nil { 8170 t.Fatalf("Expected no response from jetstream for deleted subject: %q", "foo") 8171 } 8172 if resp, err := nc.Request("bar", nil, 25*time.Millisecond); err == nil || resp != nil { 8173 t.Fatalf("Expected no response from jetstream for deleted subject: %q", "bar") 8174 } 8175 // Make sure we can send to "baz" 8176 sendStreamMsg(t, nc, "baz", "0123456789") 8177 if nmsgs := mset.state().Msgs; nmsgs != pending+3 { 8178 t.Fatalf("Expected %d msgs, got %d", pending+3, nmsgs) 8179 } 8180 8181 // FileStore restarts for config save. 8182 cfg = *c.mconfig 8183 if cfg.Storage == FileStorage { 8184 cfg.Subjects = []string{"foo", "bar"} 8185 cfg.MaxMsgs = 2222 8186 cfg.MaxBytes = 3333333 8187 cfg.MaxAge = 22 * time.Hour 8188 if err := mset.update(&cfg); err != nil { 8189 t.Fatalf("Unexpected error %v", err) 8190 } 8191 // Pull since certain defaults etc are set in processing. 8192 cfg = mset.config() 8193 8194 // Restart the 8195 // Capture port since it was dynamic. 8196 u, _ := url.Parse(s.ClientURL()) 8197 port, _ := strconv.Atoi(u.Port()) 8198 8199 // Stop current 8200 sd := s.JetStreamConfig().StoreDir 8201 s.Shutdown() 8202 // Restart. 8203 s = RunJetStreamServerOnPort(port, sd) 8204 defer s.Shutdown() 8205 8206 mset, err = s.GlobalAccount().lookupStream(cfg.Name) 8207 if err != nil { 8208 t.Fatalf("Expected to find a stream for %q", cfg.Name) 8209 } 8210 restored_cfg := mset.config() 8211 if !reflect.DeepEqual(cfg, restored_cfg) { 8212 t.Fatalf("restored configuration does not match: \n%+v\n vs \n%+v", restored_cfg, cfg) 8213 } 8214 } 8215 }) 8216 } 8217 } 8218 8219 func TestJetStreamDeleteMsg(t *testing.T) { 8220 cases := []struct { 8221 name string 8222 mconfig *StreamConfig 8223 }{ 8224 {name: "MemoryStore", 8225 mconfig: &StreamConfig{ 8226 Name: "foo", 8227 Retention: LimitsPolicy, 8228 MaxAge: time.Hour, 8229 Storage: MemoryStorage, 8230 Replicas: 1, 8231 }}, 8232 {name: "FileStore", 8233 mconfig: &StreamConfig{ 8234 Name: "foo", 8235 Retention: LimitsPolicy, 8236 MaxAge: time.Hour, 8237 Storage: FileStorage, 8238 Replicas: 1, 8239 }}, 8240 } 8241 8242 for _, c := range cases { 8243 t.Run(c.name, func(t *testing.T) { 8244 8245 s := RunBasicJetStreamServer(t) 8246 defer s.Shutdown() 8247 8248 mset, err := s.GlobalAccount().addStream(c.mconfig) 8249 if err != nil { 8250 t.Fatalf("Unexpected error adding stream: %v", err) 8251 } 8252 8253 nc, js := jsClientConnect(t, s) 8254 defer nc.Close() 8255 8256 pubTen := func() { 8257 t.Helper() 8258 for i := 0; i < 10; i++ { 8259 js.Publish("foo", []byte("Hello World!")) 8260 } 8261 } 8262 8263 pubTen() 8264 8265 state := mset.state() 8266 if state.Msgs != 10 { 8267 t.Fatalf("Expected 10 messages, got %d", state.Msgs) 8268 } 8269 bytesPerMsg := state.Bytes / 10 8270 if bytesPerMsg == 0 { 8271 t.Fatalf("Expected non-zero bytes for msg size") 8272 } 8273 8274 deleteAndCheck := func(seq, expectedFirstSeq uint64) { 8275 t.Helper() 8276 beforeState := mset.state() 8277 if removed, _ := mset.deleteMsg(seq); !removed { 8278 t.Fatalf("Expected the delete of sequence %d to succeed", seq) 8279 } 8280 expectedState := beforeState 8281 expectedState.Msgs-- 8282 expectedState.Bytes -= bytesPerMsg 8283 expectedState.FirstSeq = expectedFirstSeq 8284 8285 sm, err := mset.getMsg(expectedFirstSeq) 8286 if err != nil { 8287 t.Fatalf("Error fetching message for seq: %d - %v", expectedFirstSeq, err) 8288 } 8289 expectedState.FirstTime = sm.Time 8290 expectedState.Deleted = nil 8291 expectedState.NumDeleted = 0 8292 8293 afterState := mset.state() 8294 afterState.Deleted = nil 8295 afterState.NumDeleted = 0 8296 8297 // Ignore first time in this test. 8298 if !reflect.DeepEqual(afterState, expectedState) { 8299 t.Fatalf("Stats not what we expected. Expected %+v, got %+v\n", expectedState, afterState) 8300 } 8301 } 8302 8303 // Delete one from the middle 8304 deleteAndCheck(5, 1) 8305 // Now make sure sequences are updated properly. 8306 // Delete first msg. 8307 deleteAndCheck(1, 2) 8308 // Now last 8309 deleteAndCheck(10, 2) 8310 // Now gaps. 8311 deleteAndCheck(3, 2) 8312 deleteAndCheck(2, 4) 8313 8314 mset.purge(nil) 8315 // Put ten more one. 8316 pubTen() 8317 deleteAndCheck(11, 12) 8318 deleteAndCheck(15, 12) 8319 deleteAndCheck(16, 12) 8320 deleteAndCheck(20, 12) 8321 8322 // Only file storage beyond here. 8323 if c.mconfig.Storage == MemoryStorage { 8324 return 8325 } 8326 8327 // Capture port since it was dynamic. 8328 u, _ := url.Parse(s.ClientURL()) 8329 port, _ := strconv.Atoi(u.Port()) 8330 sd := s.JetStreamConfig().StoreDir 8331 8332 // Shutdown the 8333 s.Shutdown() 8334 8335 s = RunJetStreamServerOnPort(port, sd) 8336 defer s.Shutdown() 8337 8338 mset, err = s.GlobalAccount().lookupStream("foo") 8339 if err != nil { 8340 t.Fatalf("Expected to get the stream back") 8341 } 8342 8343 expected := StreamState{Msgs: 6, Bytes: 6 * bytesPerMsg, FirstSeq: 12, LastSeq: 20, NumSubjects: 1} 8344 state = mset.state() 8345 state.FirstTime, state.LastTime, state.Deleted, state.NumDeleted = time.Time{}, time.Time{}, nil, 0 8346 8347 if !reflect.DeepEqual(expected, state) { 8348 t.Fatalf("State not what we expected. Expected %+v, got %+v\n", expected, state) 8349 } 8350 8351 // Now create an consumer and make sure we get the right sequence. 8352 nc = clientConnectToServer(t, s) 8353 defer nc.Close() 8354 8355 delivery := nats.NewInbox() 8356 sub, _ := nc.SubscribeSync(delivery) 8357 nc.Flush() 8358 8359 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: delivery, FilterSubject: "foo"}) 8360 if err != nil { 8361 t.Fatalf("Unexpected error: %v", err) 8362 } 8363 8364 expectedStoreSeq := []uint64{12, 13, 14, 17, 18, 19} 8365 8366 for i := 0; i < 6; i++ { 8367 m, err := sub.NextMsg(time.Second) 8368 if err != nil { 8369 t.Fatalf("Unexpected error: %v", err) 8370 } 8371 if o.streamSeqFromReply(m.Reply) != expectedStoreSeq[i] { 8372 t.Fatalf("Expected store seq of %d, got %d", expectedStoreSeq[i], o.streamSeqFromReply(m.Reply)) 8373 } 8374 } 8375 }) 8376 } 8377 } 8378 8379 // https://github.com/nats-io/jetstream/issues/396 8380 func TestJetStreamLimitLockBug(t *testing.T) { 8381 cases := []struct { 8382 name string 8383 mconfig *StreamConfig 8384 }{ 8385 {name: "MemoryStore", 8386 mconfig: &StreamConfig{ 8387 Name: "foo", 8388 Retention: LimitsPolicy, 8389 MaxMsgs: 10, 8390 Storage: MemoryStorage, 8391 Replicas: 1, 8392 }}, 8393 {name: "FileStore", 8394 mconfig: &StreamConfig{ 8395 Name: "foo", 8396 Retention: LimitsPolicy, 8397 MaxMsgs: 10, 8398 Storage: FileStorage, 8399 Replicas: 1, 8400 }}, 8401 } 8402 8403 for _, c := range cases { 8404 t.Run(c.name, func(t *testing.T) { 8405 8406 s := RunBasicJetStreamServer(t) 8407 defer s.Shutdown() 8408 8409 mset, err := s.GlobalAccount().addStream(c.mconfig) 8410 if err != nil { 8411 t.Fatalf("Unexpected error adding stream: %v", err) 8412 } 8413 8414 nc := clientConnectToServer(t, s) 8415 defer nc.Close() 8416 8417 for i := 0; i < 100; i++ { 8418 sendStreamMsg(t, nc, "foo", "ok") 8419 } 8420 8421 state := mset.state() 8422 if state.Msgs != 10 { 8423 t.Fatalf("Expected 10 messages, got %d", state.Msgs) 8424 } 8425 }) 8426 } 8427 } 8428 8429 func TestJetStreamNextMsgNoInterest(t *testing.T) { 8430 cases := []struct { 8431 name string 8432 mconfig *StreamConfig 8433 }{ 8434 {name: "MemoryStore", 8435 mconfig: &StreamConfig{ 8436 Name: "foo", 8437 Retention: LimitsPolicy, 8438 MaxAge: time.Hour, 8439 Storage: MemoryStorage, 8440 Replicas: 1, 8441 }}, 8442 {name: "FileStore", 8443 mconfig: &StreamConfig{ 8444 Name: "foo", 8445 Retention: LimitsPolicy, 8446 MaxAge: time.Hour, 8447 Storage: FileStorage, 8448 Replicas: 1, 8449 }}, 8450 } 8451 8452 for _, c := range cases { 8453 t.Run(c.name, func(t *testing.T) { 8454 s := RunBasicJetStreamServer(t) 8455 defer s.Shutdown() 8456 8457 cfg := &StreamConfig{Name: "foo", Storage: FileStorage} 8458 mset, err := s.GlobalAccount().addStream(cfg) 8459 if err != nil { 8460 t.Fatalf("Unexpected error adding stream: %v", err) 8461 } 8462 8463 nc := clientConnectWithOldRequest(t, s) 8464 defer nc.Close() 8465 8466 // Now create an consumer and make sure it functions properly. 8467 o, err := mset.addConsumer(workerModeConfig("WQ")) 8468 if err != nil { 8469 t.Fatalf("Expected no error with registered interest, got %v", err) 8470 } 8471 defer o.delete() 8472 8473 nextSubj := o.requestNextMsgSubject() 8474 8475 // Queue up a worker but use a short time out. 8476 if _, err := nc.Request(nextSubj, nil, time.Millisecond); err != nats.ErrTimeout { 8477 t.Fatalf("Expected a timeout error and no response with acks suppressed") 8478 } 8479 // Now send a message, the worker from above will still be known but we want to make 8480 // sure the system detects that so we will do a request for next msg right behind it. 8481 nc.Publish("foo", []byte("OK")) 8482 if msg, err := nc.Request(nextSubj, nil, 5*time.Millisecond); err != nil { 8483 t.Fatalf("Unexpected error: %v", err) 8484 } else { 8485 msg.Respond(nil) // Ack 8486 } 8487 // Now queue up 10 workers. 8488 for i := 0; i < 10; i++ { 8489 if _, err := nc.Request(nextSubj, nil, time.Microsecond); err != nats.ErrTimeout { 8490 t.Fatalf("Expected a timeout error and no response with acks suppressed") 8491 } 8492 } 8493 // Now publish ten messages. 8494 for i := 0; i < 10; i++ { 8495 nc.Publish("foo", []byte("OK")) 8496 } 8497 nc.Flush() 8498 for i := 0; i < 10; i++ { 8499 if msg, err := nc.Request(nextSubj, nil, 10*time.Millisecond); err != nil { 8500 t.Fatalf("Unexpected error for %d: %v", i, err) 8501 } else { 8502 msg.Respond(nil) // Ack 8503 } 8504 } 8505 nc.Flush() 8506 ostate := o.info() 8507 if ostate.AckFloor.Stream != 11 || ostate.NumAckPending > 0 { 8508 t.Fatalf("Inconsistent ack state: %+v", ostate) 8509 } 8510 }) 8511 } 8512 } 8513 8514 func TestJetStreamMsgHeaders(t *testing.T) { 8515 cases := []struct { 8516 name string 8517 mconfig *StreamConfig 8518 }{ 8519 {name: "MemoryStore", 8520 mconfig: &StreamConfig{ 8521 Name: "foo", 8522 Retention: LimitsPolicy, 8523 MaxAge: time.Hour, 8524 Storage: MemoryStorage, 8525 Replicas: 1, 8526 }}, 8527 {name: "FileStore", 8528 mconfig: &StreamConfig{ 8529 Name: "foo", 8530 Retention: LimitsPolicy, 8531 MaxAge: time.Hour, 8532 Storage: FileStorage, 8533 Replicas: 1, 8534 }}, 8535 } 8536 for _, c := range cases { 8537 t.Run(c.name, func(t *testing.T) { 8538 s := RunBasicJetStreamServer(t) 8539 defer s.Shutdown() 8540 8541 mset, err := s.GlobalAccount().addStream(c.mconfig) 8542 if err != nil { 8543 t.Fatalf("Unexpected error adding stream: %v", err) 8544 } 8545 defer mset.delete() 8546 8547 nc := clientConnectToServer(t, s) 8548 defer nc.Close() 8549 8550 m := nats.NewMsg("foo") 8551 m.Header.Add("Accept-Encoding", "json") 8552 m.Header.Add("Authorization", "s3cr3t") 8553 m.Data = []byte("Hello JetStream Headers - #1!") 8554 8555 nc.PublishMsg(m) 8556 nc.Flush() 8557 8558 checkFor(t, time.Second*2, time.Millisecond*250, func() error { 8559 state := mset.state() 8560 if state.Msgs != 1 { 8561 return fmt.Errorf("Expected 1 message, got %d", state.Msgs) 8562 } 8563 if state.Bytes == 0 { 8564 return fmt.Errorf("Expected non-zero bytes") 8565 } 8566 return nil 8567 }) 8568 8569 // Now access raw from stream. 8570 sm, err := mset.getMsg(1) 8571 if err != nil { 8572 t.Fatalf("Unexpected error getting stored message: %v", err) 8573 } 8574 // Calculate the []byte version of the headers. 8575 var b bytes.Buffer 8576 b.WriteString("NATS/1.0\r\n") 8577 http.Header(m.Header).Write(&b) 8578 b.WriteString("\r\n") 8579 hdr := b.Bytes() 8580 8581 if !bytes.Equal(sm.Header, hdr) { 8582 t.Fatalf("Message headers do not match, %q vs %q", hdr, sm.Header) 8583 } 8584 if !bytes.Equal(sm.Data, m.Data) { 8585 t.Fatalf("Message data do not match, %q vs %q", m.Data, sm.Data) 8586 } 8587 8588 // Now do consumer based. 8589 sub, _ := nc.SubscribeSync(nats.NewInbox()) 8590 defer sub.Unsubscribe() 8591 nc.Flush() 8592 8593 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 8594 if err != nil { 8595 t.Fatalf("Expected no error with registered interest, got %v", err) 8596 } 8597 defer o.delete() 8598 8599 cm, err := sub.NextMsg(time.Second) 8600 if err != nil { 8601 t.Fatalf("Error getting message: %v", err) 8602 } 8603 // Check the message. 8604 // Check out original headers. 8605 if cm.Header.Get("Accept-Encoding") != "json" || 8606 cm.Header.Get("Authorization") != "s3cr3t" { 8607 t.Fatalf("Original headers not present") 8608 } 8609 if !bytes.Equal(m.Data, cm.Data) { 8610 t.Fatalf("Message payloads are not the same: %q vs %q", cm.Data, m.Data) 8611 } 8612 }) 8613 } 8614 } 8615 8616 func TestJetStreamTemplateBasics(t *testing.T) { 8617 s := RunBasicJetStreamServer(t) 8618 defer s.Shutdown() 8619 8620 acc := s.GlobalAccount() 8621 8622 mcfg := &StreamConfig{ 8623 Subjects: []string{"kv.*"}, 8624 Retention: LimitsPolicy, 8625 MaxAge: time.Hour, 8626 MaxMsgs: 4, 8627 Storage: MemoryStorage, 8628 Replicas: 1, 8629 } 8630 template := &StreamTemplateConfig{ 8631 Name: "kv", 8632 Config: mcfg, 8633 MaxStreams: 4, 8634 } 8635 8636 if _, err := acc.addStreamTemplate(template); err != nil { 8637 t.Fatalf("Unexpected error: %v", err) 8638 } 8639 if templates := acc.templates(); len(templates) != 1 { 8640 t.Fatalf("Expected to get array of 1 template, got %d", len(templates)) 8641 } 8642 if err := acc.deleteStreamTemplate("foo"); err == nil { 8643 t.Fatalf("Expected an error for non-existent template") 8644 } 8645 if err := acc.deleteStreamTemplate(template.Name); err != nil { 8646 t.Fatalf("Unexpected error: %v", err) 8647 } 8648 if templates := acc.templates(); len(templates) != 0 { 8649 t.Fatalf("Expected to get array of no templates, got %d", len(templates)) 8650 } 8651 // Add it back in and test basics 8652 if _, err := acc.addStreamTemplate(template); err != nil { 8653 t.Fatalf("Unexpected error: %v", err) 8654 } 8655 8656 // Connect a client and send a message which should trigger the stream creation. 8657 nc := clientConnectToServer(t, s) 8658 defer nc.Close() 8659 8660 sendStreamMsg(t, nc, "kv.22", "derek") 8661 sendStreamMsg(t, nc, "kv.33", "cat") 8662 sendStreamMsg(t, nc, "kv.44", "sam") 8663 sendStreamMsg(t, nc, "kv.55", "meg") 8664 8665 if nms := acc.numStreams(); nms != 4 { 8666 t.Fatalf("Expected 4 auto-created streams, got %d", nms) 8667 } 8668 8669 // This one should fail due to max. 8670 if resp, err := nc.Request("kv.99", nil, 100*time.Millisecond); err == nil { 8671 t.Fatalf("Expected this to fail, but got %q", resp.Data) 8672 } 8673 8674 // Now delete template and make sure the underlying streams go away too. 8675 if err := acc.deleteStreamTemplate(template.Name); err != nil { 8676 t.Fatalf("Unexpected error: %v", err) 8677 } 8678 8679 if nms := acc.numStreams(); nms != 0 { 8680 t.Fatalf("Expected no auto-created streams to remain, got %d", nms) 8681 } 8682 } 8683 8684 func TestJetStreamTemplateFileStoreRecovery(t *testing.T) { 8685 s := RunBasicJetStreamServer(t) 8686 defer s.Shutdown() 8687 8688 acc := s.GlobalAccount() 8689 8690 mcfg := &StreamConfig{ 8691 Subjects: []string{"kv.*"}, 8692 Retention: LimitsPolicy, 8693 MaxAge: time.Hour, 8694 MaxMsgs: 50, 8695 Storage: FileStorage, 8696 Replicas: 1, 8697 } 8698 template := &StreamTemplateConfig{ 8699 Name: "kv", 8700 Config: mcfg, 8701 MaxStreams: 100, 8702 } 8703 8704 if _, err := acc.addStreamTemplate(template); err != nil { 8705 t.Fatalf("Unexpected error: %v", err) 8706 } 8707 8708 // Make sure we can not add in a stream on our own with a template owner. 8709 badCfg := *mcfg 8710 badCfg.Name = "bad" 8711 badCfg.Template = "kv" 8712 if _, err := acc.addStream(&badCfg); err == nil { 8713 t.Fatalf("Expected error adding stream with direct template owner") 8714 } 8715 8716 // Connect a client and send a message which should trigger the stream creation. 8717 nc := clientConnectToServer(t, s) 8718 defer nc.Close() 8719 8720 for i := 1; i <= 100; i++ { 8721 subj := fmt.Sprintf("kv.%d", i) 8722 for x := 0; x < 50; x++ { 8723 sendStreamMsg(t, nc, subj, "Hello") 8724 } 8725 } 8726 nc.Flush() 8727 8728 if nms := acc.numStreams(); nms != 100 { 8729 t.Fatalf("Expected 100 auto-created streams, got %d", nms) 8730 } 8731 8732 // Capture port since it was dynamic. 8733 u, _ := url.Parse(s.ClientURL()) 8734 port, _ := strconv.Atoi(u.Port()) 8735 8736 restartServer := func() { 8737 t.Helper() 8738 sd := s.JetStreamConfig().StoreDir 8739 // Stop current 8740 s.Shutdown() 8741 // Restart. 8742 s = RunJetStreamServerOnPort(port, sd) 8743 } 8744 8745 // Restart. 8746 restartServer() 8747 defer s.Shutdown() 8748 8749 acc = s.GlobalAccount() 8750 if nms := acc.numStreams(); nms != 100 { 8751 t.Fatalf("Expected 100 auto-created streams, got %d", nms) 8752 } 8753 tmpl, err := acc.lookupStreamTemplate(template.Name) 8754 require_NoError(t, err) 8755 // Make sure t.delete() survives restart. 8756 tmpl.delete() 8757 8758 // Restart. 8759 restartServer() 8760 defer s.Shutdown() 8761 8762 acc = s.GlobalAccount() 8763 if nms := acc.numStreams(); nms != 0 { 8764 t.Fatalf("Expected no auto-created streams, got %d", nms) 8765 } 8766 if _, err := acc.lookupStreamTemplate(template.Name); err == nil { 8767 t.Fatalf("Expected to not find the template after restart") 8768 } 8769 } 8770 8771 // This will be testing our ability to conditionally rewrite subjects for last mile 8772 // when working with JetStream. Consumers receive messages that have their subjects 8773 // rewritten to match the original subject. NATS routing is all subject based except 8774 // for the last mile to the client. 8775 func TestJetStreamSingleInstanceRemoteAccess(t *testing.T) { 8776 ca := createClusterWithName(t, "A", 1) 8777 defer shutdownCluster(ca) 8778 cb := createClusterWithName(t, "B", 1, ca) 8779 defer shutdownCluster(cb) 8780 8781 // Connect our leafnode server to cluster B. 8782 opts := cb.opts[rand.Intn(len(cb.opts))] 8783 s, _ := runSolicitLeafServer(opts) 8784 defer s.Shutdown() 8785 8786 checkLeafNodeConnected(t, s) 8787 8788 if err := s.EnableJetStream(&JetStreamConfig{StoreDir: t.TempDir()}); err != nil { 8789 t.Fatalf("Expected no error, got %v", err) 8790 } 8791 8792 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "foo", Storage: MemoryStorage}) 8793 if err != nil { 8794 t.Fatalf("Unexpected error adding stream: %v", err) 8795 } 8796 defer mset.delete() 8797 8798 nc := clientConnectToServer(t, s) 8799 defer nc.Close() 8800 8801 toSend := 10 8802 for i := 0; i < toSend; i++ { 8803 sendStreamMsg(t, nc, "foo", "Hello World!") 8804 } 8805 8806 // Now create a push based consumer. Connected to the non-jetstream server via a random server on cluster A. 8807 sl := ca.servers[rand.Intn(len(ca.servers))] 8808 nc2 := clientConnectToServer(t, sl) 8809 defer nc2.Close() 8810 8811 sub, _ := nc2.SubscribeSync(nats.NewInbox()) 8812 defer sub.Unsubscribe() 8813 8814 // Need to wait for interest to propagate across GW. 8815 nc2.Flush() 8816 time.Sleep(25 * time.Millisecond) 8817 8818 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: sub.Subject}) 8819 if err != nil { 8820 t.Fatalf("Expected no error with registered interest, got %v", err) 8821 } 8822 defer o.delete() 8823 8824 checkSubPending := func(numExpected int) { 8825 t.Helper() 8826 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 8827 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != numExpected { 8828 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 8829 } 8830 return nil 8831 }) 8832 } 8833 checkSubPending(toSend) 8834 8835 checkMsg := func(m *nats.Msg, err error, i int) { 8836 t.Helper() 8837 if err != nil { 8838 t.Fatalf("Got an error checking message: %v", err) 8839 } 8840 if m.Subject != "foo" { 8841 t.Fatalf("Expected original subject of %q, but got %q", "foo", m.Subject) 8842 } 8843 // Now check that reply subject exists and has a sequence as the last token. 8844 if seq := o.seqFromReply(m.Reply); seq != uint64(i) { 8845 t.Fatalf("Expected sequence of %d , got %d", i, seq) 8846 } 8847 } 8848 8849 // Now check the subject to make sure its the original one. 8850 for i := 1; i <= toSend; i++ { 8851 m, err := sub.NextMsg(time.Second) 8852 checkMsg(m, err, i) 8853 } 8854 8855 // Now do a pull based consumer. 8856 o, err = mset.addConsumer(workerModeConfig("p")) 8857 if err != nil { 8858 t.Fatalf("Expected no error with registered interest, got %v", err) 8859 } 8860 defer o.delete() 8861 8862 nextMsg := o.requestNextMsgSubject() 8863 for i := 1; i <= toSend; i++ { 8864 m, err := nc.Request(nextMsg, nil, time.Second) 8865 checkMsg(m, err, i) 8866 } 8867 } 8868 8869 func clientConnectToServerWithUP(t *testing.T, opts *Options, user, pass string) *nats.Conn { 8870 curl := fmt.Sprintf("nats://%s:%s@%s:%d", user, pass, opts.Host, opts.Port) 8871 nc, err := nats.Connect(curl, nats.Name("JS-UP-TEST"), nats.ReconnectWait(5*time.Millisecond), nats.MaxReconnects(-1)) 8872 if err != nil { 8873 t.Fatalf("Failed to create client: %v", err) 8874 } 8875 return nc 8876 } 8877 8878 func TestJetStreamCanNotEnableOnSystemAccount(t *testing.T) { 8879 s := RunBasicJetStreamServer(t) 8880 defer s.Shutdown() 8881 8882 sa := s.SystemAccount() 8883 if err := sa.EnableJetStream(nil); err == nil { 8884 t.Fatalf("Expected an error trying to enable on the system account") 8885 } 8886 } 8887 8888 func TestJetStreamMultipleAccountsBasics(t *testing.T) { 8889 tdir := t.TempDir() 8890 conf := createConfFile(t, []byte(fmt.Sprintf(` 8891 listen: 127.0.0.1:-1 8892 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 8893 accounts: { 8894 A: { 8895 jetstream: enabled 8896 users: [ {user: ua, password: pwd} ] 8897 }, 8898 B: { 8899 jetstream: {max_mem: 1GB, max_store: 1TB, max_streams: 10, max_consumers: 1k} 8900 users: [ {user: ub, password: pwd} ] 8901 }, 8902 C: { 8903 users: [ {user: uc, password: pwd} ] 8904 }, 8905 } 8906 `, tdir))) 8907 8908 s, opts := RunServerWithConfig(conf) 8909 defer s.Shutdown() 8910 8911 if !s.JetStreamEnabled() { 8912 t.Fatalf("Expected JetStream to be enabled") 8913 } 8914 8915 nca := clientConnectToServerWithUP(t, opts, "ua", "pwd") 8916 defer nca.Close() 8917 8918 ncb := clientConnectToServerWithUP(t, opts, "ub", "pwd") 8919 defer ncb.Close() 8920 8921 resp, err := ncb.Request(JSApiAccountInfo, nil, time.Second) 8922 require_NoError(t, err) 8923 var info JSApiAccountInfoResponse 8924 if err := json.Unmarshal(resp.Data, &info); err != nil { 8925 t.Fatalf("Unexpected error: %v", err) 8926 } 8927 limits := info.Limits 8928 if limits.MaxStreams != 10 { 8929 t.Fatalf("Expected 10 for MaxStreams, got %d", limits.MaxStreams) 8930 } 8931 if limits.MaxConsumers != 1000 { 8932 t.Fatalf("Expected MaxConsumers of %d, got %d", 1000, limits.MaxConsumers) 8933 } 8934 gb := int64(1024 * 1024 * 1024) 8935 if limits.MaxMemory != gb { 8936 t.Fatalf("Expected MaxMemory to be 1GB, got %d", limits.MaxMemory) 8937 } 8938 if limits.MaxStore != 1024*gb { 8939 t.Fatalf("Expected MaxStore to be 1TB, got %d", limits.MaxStore) 8940 } 8941 8942 ncc := clientConnectToServerWithUP(t, opts, "uc", "pwd") 8943 defer ncc.Close() 8944 8945 expectNotEnabled := func(resp *nats.Msg, err error) { 8946 t.Helper() 8947 if err != nil { 8948 t.Fatalf("Unexpected error requesting enabled status: %v", err) 8949 } 8950 if resp == nil { 8951 t.Fatalf("No response, possible timeout?") 8952 } 8953 var iResp JSApiAccountInfoResponse 8954 if err := json.Unmarshal(resp.Data, &iResp); err != nil { 8955 t.Fatalf("Unexpected error: %v", err) 8956 } 8957 if iResp.Error == nil { 8958 t.Fatalf("Expected an error on not enabled account") 8959 } 8960 } 8961 8962 // Check C is not enabled. We expect a negative response, not a timeout. 8963 expectNotEnabled(ncc.Request(JSApiAccountInfo, nil, 250*time.Millisecond)) 8964 8965 // Now do simple reload and check that we do the right thing. Testing enable and disable and also change in limits 8966 newConf := []byte(fmt.Sprintf(` 8967 listen: 127.0.0.1:-1 8968 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 8969 accounts: { 8970 A: { 8971 jetstream: disabled 8972 users: [ {user: ua, password: pwd} ] 8973 }, 8974 B: { 8975 jetstream: {max_mem: 32GB, max_store: 512GB, max_streams: 100, max_consumers: 4k} 8976 users: [ {user: ub, password: pwd} ] 8977 }, 8978 C: { 8979 jetstream: {max_mem: 1GB, max_store: 1TB, max_streams: 10, max_consumers: 1k} 8980 users: [ {user: uc, password: pwd} ] 8981 }, 8982 } 8983 `, tdir)) 8984 if err := os.WriteFile(conf, newConf, 0600); err != nil { 8985 t.Fatalf("Error rewriting server's config file: %v", err) 8986 } 8987 if err := s.Reload(); err != nil { 8988 t.Fatalf("Error on server reload: %v", err) 8989 } 8990 expectNotEnabled(nca.Request(JSApiAccountInfo, nil, 250*time.Millisecond)) 8991 8992 resp, _ = ncb.Request(JSApiAccountInfo, nil, 250*time.Millisecond) 8993 if err := json.Unmarshal(resp.Data, &info); err != nil { 8994 t.Fatalf("Unexpected error: %v", err) 8995 } 8996 if info.Error != nil { 8997 t.Fatalf("Expected JetStream to be enabled, got %+v", info.Error) 8998 } 8999 9000 resp, _ = ncc.Request(JSApiAccountInfo, nil, 250*time.Millisecond) 9001 if err := json.Unmarshal(resp.Data, &info); err != nil { 9002 t.Fatalf("Unexpected error: %v", err) 9003 } 9004 if info.Error != nil { 9005 t.Fatalf("Expected JetStream to be enabled, got %+v", info.Error) 9006 } 9007 9008 // Now check that limits have been updated. 9009 // Account B 9010 resp, err = ncb.Request(JSApiAccountInfo, nil, time.Second) 9011 require_NoError(t, err) 9012 if err := json.Unmarshal(resp.Data, &info); err != nil { 9013 t.Fatalf("Unexpected error: %v", err) 9014 } 9015 limits = info.Limits 9016 if limits.MaxStreams != 100 { 9017 t.Fatalf("Expected 100 for MaxStreams, got %d", limits.MaxStreams) 9018 } 9019 if limits.MaxConsumers != 4000 { 9020 t.Fatalf("Expected MaxConsumers of %d, got %d", 4000, limits.MaxConsumers) 9021 } 9022 if limits.MaxMemory != 32*gb { 9023 t.Fatalf("Expected MaxMemory to be 32GB, got %d", limits.MaxMemory) 9024 } 9025 if limits.MaxStore != 512*gb { 9026 t.Fatalf("Expected MaxStore to be 512GB, got %d", limits.MaxStore) 9027 } 9028 9029 // Account C 9030 resp, err = ncc.Request(JSApiAccountInfo, nil, time.Second) 9031 require_NoError(t, err) 9032 if err := json.Unmarshal(resp.Data, &info); err != nil { 9033 t.Fatalf("Unexpected error: %v", err) 9034 } 9035 limits = info.Limits 9036 if limits.MaxStreams != 10 { 9037 t.Fatalf("Expected 10 for MaxStreams, got %d", limits.MaxStreams) 9038 } 9039 if limits.MaxConsumers != 1000 { 9040 t.Fatalf("Expected MaxConsumers of %d, got %d", 1000, limits.MaxConsumers) 9041 } 9042 if limits.MaxMemory != gb { 9043 t.Fatalf("Expected MaxMemory to be 1GB, got %d", limits.MaxMemory) 9044 } 9045 if limits.MaxStore != 1024*gb { 9046 t.Fatalf("Expected MaxStore to be 1TB, got %d", limits.MaxStore) 9047 } 9048 } 9049 9050 func TestJetStreamServerResourcesConfig(t *testing.T) { 9051 conf := createConfFile(t, []byte(fmt.Sprintf(` 9052 listen: 127.0.0.1:-1 9053 jetstream: {max_mem_store: 2GB, max_file_store: 1TB, store_dir: %q} 9054 `, t.TempDir()))) 9055 9056 s, _ := RunServerWithConfig(conf) 9057 defer s.Shutdown() 9058 9059 if !s.JetStreamEnabled() { 9060 t.Fatalf("Expected JetStream to be enabled") 9061 } 9062 9063 gb := int64(1024 * 1024 * 1024) 9064 jsc := s.JetStreamConfig() 9065 if jsc.MaxMemory != 2*gb { 9066 t.Fatalf("Expected MaxMemory to be %d, got %d", 2*gb, jsc.MaxMemory) 9067 } 9068 if jsc.MaxStore != 1024*gb { 9069 t.Fatalf("Expected MaxStore to be %d, got %d", 1024*gb, jsc.MaxStore) 9070 } 9071 } 9072 9073 // From 2.2.2 to 2.2.3 we fixed a bug that would not consistently place a jetstream directory 9074 // under the store directory configured. However there were some cases where the directory was 9075 // created that way and therefore 2.2.3 would start and not recognize the existing accounts, 9076 // streams and consumers. 9077 func TestJetStreamStoreDirectoryFix(t *testing.T) { 9078 sd := filepath.Join(os.TempDir(), "sd_test") 9079 defer removeDir(t, sd) 9080 9081 conf := createConfFile(t, []byte(fmt.Sprintf("listen: 127.0.0.1:-1\njetstream: {store_dir: %q}\n", sd))) 9082 9083 s, _ := RunServerWithConfig(conf) 9084 defer s.Shutdown() 9085 9086 nc, js := jsClientConnect(t, s) 9087 defer nc.Close() 9088 9089 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 9090 t.Fatalf("Unexpected error: %v", err) 9091 } 9092 if _, err := js.Publish("TEST", []byte("TSS")); err != nil { 9093 t.Fatalf("Unexpected publish error: %v", err) 9094 } 9095 // Push based. 9096 sub, err := js.SubscribeSync("TEST", nats.Durable("dlc")) 9097 require_NoError(t, err) 9098 defer sub.Unsubscribe() 9099 9100 // Now shutdown the server. 9101 nc.Close() 9102 s.Shutdown() 9103 9104 // Now move stuff up from the jetstream directory etc. 9105 jssd := filepath.Join(sd, JetStreamStoreDir) 9106 fis, _ := os.ReadDir(jssd) 9107 // This will be accounts, move them up one directory. 9108 for _, fi := range fis { 9109 os.Rename(filepath.Join(jssd, fi.Name()), filepath.Join(sd, fi.Name())) 9110 } 9111 removeDir(t, jssd) 9112 9113 // Restart our server. Make sure our assets got moved. 9114 s, _ = RunServerWithConfig(conf) 9115 defer s.Shutdown() 9116 9117 nc, js = jsClientConnect(t, s) 9118 defer nc.Close() 9119 9120 var names []string 9121 for name := range js.StreamNames() { 9122 names = append(names, name) 9123 } 9124 if len(names) != 1 { 9125 t.Fatalf("Expected only 1 stream but got %d", len(names)) 9126 } 9127 names = names[:0] 9128 for name := range js.ConsumerNames("TEST") { 9129 names = append(names, name) 9130 } 9131 if len(names) != 1 { 9132 t.Fatalf("Expected only 1 consumer but got %d", len(names)) 9133 } 9134 } 9135 9136 func TestJetStreamPushConsumersPullError(t *testing.T) { 9137 s := RunBasicJetStreamServer(t) 9138 defer s.Shutdown() 9139 9140 nc, js := jsClientConnect(t, s) 9141 defer nc.Close() 9142 9143 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 9144 t.Fatalf("Unexpected error: %v", err) 9145 } 9146 if _, err := js.Publish("TEST", []byte("TSS")); err != nil { 9147 t.Fatalf("Unexpected publish error: %v", err) 9148 } 9149 // Push based. 9150 sub, err := js.SubscribeSync("TEST") 9151 require_NoError(t, err) 9152 defer sub.Unsubscribe() 9153 ci, err := sub.ConsumerInfo() 9154 require_NoError(t, err) 9155 9156 // Now do a pull. Make sure we get an error. 9157 m, err := nc.Request(fmt.Sprintf(JSApiRequestNextT, "TEST", ci.Name), nil, time.Second) 9158 require_NoError(t, err) 9159 if m.Header.Get("Status") != "409" { 9160 t.Fatalf("Expected a 409 status code, got %q", m.Header.Get("Status")) 9161 } 9162 } 9163 9164 func TestJetStreamPullConsumerMaxWaitingOfOne(t *testing.T) { 9165 s := RunBasicJetStreamServer(t) 9166 defer s.Shutdown() 9167 9168 nc, js := jsClientConnect(t, s) 9169 defer nc.Close() 9170 9171 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"TEST.A"}}) 9172 require_NoError(t, err) 9173 9174 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 9175 Durable: "dur", 9176 MaxWaiting: 1, 9177 AckPolicy: nats.AckExplicitPolicy, 9178 }) 9179 require_NoError(t, err) 9180 9181 // First check that a request can timeout (we had an issue where this was 9182 // not the case for MaxWaiting of 1). 9183 req := JSApiConsumerGetNextRequest{Batch: 1, Expires: 250 * time.Millisecond} 9184 reqb, _ := json.Marshal(req) 9185 msg, err := nc.Request("$JS.API.CONSUMER.MSG.NEXT.TEST.dur", reqb, 13000*time.Millisecond) 9186 require_NoError(t, err) 9187 if v := msg.Header.Get("Status"); v != "408" { 9188 t.Fatalf("Expected 408, got: %s", v) 9189 } 9190 9191 // Now have a request waiting... 9192 req = JSApiConsumerGetNextRequest{Batch: 1} 9193 reqb, _ = json.Marshal(req) 9194 // Send the request, but do not block since we want then to send an extra 9195 // request that should be rejected. 9196 sub := natsSubSync(t, nc, nats.NewInbox()) 9197 err = nc.PublishRequest("$JS.API.CONSUMER.MSG.NEXT.TEST.dur", sub.Subject, reqb) 9198 require_NoError(t, err) 9199 9200 // Send a new request, this should be rejected as a 409. 9201 req = JSApiConsumerGetNextRequest{Batch: 1, Expires: 250 * time.Millisecond} 9202 reqb, _ = json.Marshal(req) 9203 msg, err = nc.Request("$JS.API.CONSUMER.MSG.NEXT.TEST.dur", reqb, 300*time.Millisecond) 9204 require_NoError(t, err) 9205 if v := msg.Header.Get("Status"); v != "409" { 9206 t.Fatalf("Expected 409, got: %s", v) 9207 } 9208 if v := msg.Header.Get("Description"); v != "Exceeded MaxWaiting" { 9209 t.Fatalf("Expected error about exceeded max waiting, got: %s", v) 9210 } 9211 } 9212 9213 func TestJetStreamPullConsumerMaxWaiting(t *testing.T) { 9214 s := RunBasicJetStreamServer(t) 9215 defer s.Shutdown() 9216 9217 nc, js := jsClientConnect(t, s) 9218 defer nc.Close() 9219 9220 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"test.*"}}) 9221 require_NoError(t, err) 9222 9223 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 9224 Durable: "dur", 9225 AckPolicy: nats.AckExplicitPolicy, 9226 MaxWaiting: 10, 9227 }) 9228 require_NoError(t, err) 9229 9230 // Cannot be updated. 9231 _, err = js.UpdateConsumer("TEST", &nats.ConsumerConfig{ 9232 Durable: "dur", 9233 AckPolicy: nats.AckExplicitPolicy, 9234 MaxWaiting: 1, 9235 }) 9236 if !strings.Contains(err.Error(), "can not be updated") { 9237 t.Fatalf(`expected "cannot be updated" error, got %s`, err) 9238 } 9239 } 9240 9241 //////////////////////////////////////// 9242 // Benchmark placeholders 9243 // TODO(dlc) - move 9244 //////////////////////////////////////// 9245 9246 func TestJetStreamPubPerf(t *testing.T) { 9247 // Comment out to run, holding place for now. 9248 t.SkipNow() 9249 9250 s := RunBasicJetStreamServer(t) 9251 defer s.Shutdown() 9252 9253 acc := s.GlobalAccount() 9254 9255 msetConfig := StreamConfig{ 9256 Name: "sr22", 9257 Storage: FileStorage, 9258 Subjects: []string{"foo"}, 9259 } 9260 9261 if _, err := acc.addStream(&msetConfig); err != nil { 9262 t.Fatalf("Unexpected error adding stream: %v", err) 9263 } 9264 9265 nc := clientConnectToServer(t, s) 9266 defer nc.Close() 9267 9268 toSend := 5_000_000 9269 numProducers := 5 9270 9271 payload := []byte("Hello World") 9272 9273 startCh := make(chan bool) 9274 var wg sync.WaitGroup 9275 9276 for n := 0; n < numProducers; n++ { 9277 wg.Add(1) 9278 go func() { 9279 defer wg.Done() 9280 <-startCh 9281 for i := 0; i < int(toSend)/numProducers; i++ { 9282 nc.Publish("foo", payload) 9283 } 9284 nc.Flush() 9285 }() 9286 } 9287 9288 // Wait for Go routines. 9289 time.Sleep(20 * time.Millisecond) 9290 start := time.Now() 9291 close(startCh) 9292 wg.Wait() 9293 9294 tt := time.Since(start) 9295 fmt.Printf("time is %v\n", tt) 9296 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 9297 9298 // Stop current 9299 sd := s.JetStreamConfig().StoreDir 9300 s.Shutdown() 9301 // Restart. 9302 start = time.Now() 9303 s = RunJetStreamServerOnPort(-1, sd) 9304 defer s.Shutdown() 9305 fmt.Printf("Took %v to restart!\n", time.Since(start)) 9306 } 9307 9308 func TestJetStreamPubWithAsyncResponsePerf(t *testing.T) { 9309 // Comment out to run, holding place for now. 9310 t.SkipNow() 9311 9312 s := RunBasicJetStreamServer(t) 9313 defer s.Shutdown() 9314 9315 acc := s.GlobalAccount() 9316 9317 msetConfig := StreamConfig{ 9318 Name: "sr33", 9319 Storage: FileStorage, 9320 Subjects: []string{"foo"}, 9321 } 9322 9323 if _, err := acc.addStream(&msetConfig); err != nil { 9324 t.Fatalf("Unexpected error adding stream: %v", err) 9325 } 9326 9327 nc := clientConnectToServer(t, s) 9328 defer nc.Close() 9329 9330 toSend := 1_000_000 9331 payload := []byte("Hello World") 9332 9333 start := time.Now() 9334 for i := 0; i < toSend; i++ { 9335 nc.PublishRequest("foo", "bar", payload) 9336 } 9337 nc.Flush() 9338 9339 tt := time.Since(start) 9340 fmt.Printf("time is %v\n", tt) 9341 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 9342 } 9343 9344 func TestJetStreamPubWithSyncPerf(t *testing.T) { 9345 // Comment out to run, holding place for now. 9346 t.SkipNow() 9347 9348 s := RunBasicJetStreamServer(t) 9349 defer s.Shutdown() 9350 9351 nc, js := jsClientConnect(t, s) 9352 defer nc.Close() 9353 9354 _, err := js.AddStream(&nats.StreamConfig{Name: "foo"}) 9355 require_NoError(t, err) 9356 9357 toSend := 1_000_000 9358 payload := []byte("Hello World") 9359 9360 start := time.Now() 9361 for i := 0; i < toSend; i++ { 9362 js.Publish("foo", payload) 9363 } 9364 9365 tt := time.Since(start) 9366 fmt.Printf("time is %v\n", tt) 9367 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 9368 } 9369 9370 func TestJetStreamConsumerPerf(t *testing.T) { 9371 // Comment out to run, holding place for now. 9372 t.SkipNow() 9373 9374 s := RunBasicJetStreamServer(t) 9375 defer s.Shutdown() 9376 9377 acc := s.GlobalAccount() 9378 9379 msetConfig := StreamConfig{ 9380 Name: "sr22", 9381 Storage: MemoryStorage, 9382 Subjects: []string{"foo"}, 9383 } 9384 9385 mset, err := acc.addStream(&msetConfig) 9386 if err != nil { 9387 t.Fatalf("Unexpected error adding stream: %v", err) 9388 } 9389 9390 nc := clientConnectToServer(t, s) 9391 defer nc.Close() 9392 9393 payload := []byte("Hello World") 9394 9395 toStore := 2000000 9396 for i := 0; i < toStore; i++ { 9397 nc.Publish("foo", payload) 9398 } 9399 nc.Flush() 9400 9401 _, err = mset.addConsumer(&ConsumerConfig{ 9402 Durable: "d", 9403 DeliverSubject: "d", 9404 AckPolicy: AckNone, 9405 }) 9406 if err != nil { 9407 t.Fatalf("Error creating consumer: %v", err) 9408 } 9409 9410 var received int 9411 done := make(chan bool) 9412 9413 nc.Subscribe("d", func(m *nats.Msg) { 9414 received++ 9415 if received >= toStore { 9416 done <- true 9417 } 9418 }) 9419 start := time.Now() 9420 nc.Flush() 9421 9422 <-done 9423 tt := time.Since(start) 9424 fmt.Printf("time is %v\n", tt) 9425 fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds()) 9426 } 9427 9428 func TestJetStreamConsumerAckFileStorePerf(t *testing.T) { 9429 // Comment out to run, holding place for now. 9430 t.SkipNow() 9431 9432 s := RunBasicJetStreamServer(t) 9433 defer s.Shutdown() 9434 9435 acc := s.GlobalAccount() 9436 9437 msetConfig := StreamConfig{ 9438 Name: "sr22", 9439 Storage: FileStorage, 9440 Subjects: []string{"foo"}, 9441 } 9442 9443 mset, err := acc.addStream(&msetConfig) 9444 if err != nil { 9445 t.Fatalf("Unexpected error adding stream: %v", err) 9446 } 9447 9448 nc := clientConnectToServer(t, s) 9449 defer nc.Close() 9450 9451 payload := []byte("Hello World") 9452 9453 toStore := uint64(200000) 9454 for i := uint64(0); i < toStore; i++ { 9455 nc.Publish("foo", payload) 9456 } 9457 nc.Flush() 9458 9459 if msgs := mset.state().Msgs; msgs != uint64(toStore) { 9460 t.Fatalf("Expected %d messages, got %d", toStore, msgs) 9461 } 9462 9463 o, err := mset.addConsumer(&ConsumerConfig{ 9464 Durable: "d", 9465 DeliverSubject: "d", 9466 AckPolicy: AckExplicit, 9467 AckWait: 10 * time.Minute, 9468 }) 9469 if err != nil { 9470 t.Fatalf("Error creating consumer: %v", err) 9471 } 9472 defer o.stop() 9473 9474 var received uint64 9475 done := make(chan bool) 9476 9477 sub, _ := nc.Subscribe("d", func(m *nats.Msg) { 9478 m.Respond(nil) // Ack 9479 received++ 9480 if received >= toStore { 9481 done <- true 9482 } 9483 }) 9484 sub.SetPendingLimits(-1, -1) 9485 9486 start := time.Now() 9487 nc.Flush() 9488 9489 <-done 9490 tt := time.Since(start) 9491 fmt.Printf("time is %v\n", tt) 9492 fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds()) 9493 } 9494 9495 func TestJetStreamPubSubPerf(t *testing.T) { 9496 // Comment out to run, holding place for now. 9497 t.SkipNow() 9498 9499 s := RunBasicJetStreamServer(t) 9500 defer s.Shutdown() 9501 9502 acc := s.GlobalAccount() 9503 9504 msetConfig := StreamConfig{ 9505 Name: "MSET22", 9506 Storage: FileStorage, 9507 Subjects: []string{"foo"}, 9508 } 9509 9510 mset, err := acc.addStream(&msetConfig) 9511 if err != nil { 9512 t.Fatalf("Unexpected error adding stream: %v", err) 9513 } 9514 9515 nc := clientConnectToServer(t, s) 9516 defer nc.Close() 9517 9518 var toSend = 1_000_000 9519 var received int 9520 done := make(chan bool) 9521 9522 delivery := "d" 9523 9524 nc.Subscribe(delivery, func(m *nats.Msg) { 9525 received++ 9526 if received >= toSend { 9527 done <- true 9528 } 9529 }) 9530 nc.Flush() 9531 9532 _, err = mset.addConsumer(&ConsumerConfig{ 9533 DeliverSubject: delivery, 9534 AckPolicy: AckNone, 9535 }) 9536 if err != nil { 9537 t.Fatalf("Error creating consumer: %v", err) 9538 } 9539 9540 payload := []byte("Hello World") 9541 9542 start := time.Now() 9543 9544 for i := 0; i < toSend; i++ { 9545 nc.Publish("foo", payload) 9546 } 9547 9548 <-done 9549 tt := time.Since(start) 9550 fmt.Printf("time is %v\n", tt) 9551 fmt.Printf("%.0f msgs/sec\n", float64(toSend)/tt.Seconds()) 9552 } 9553 9554 func TestJetStreamAckExplicitMsgRemoval(t *testing.T) { 9555 cases := []struct { 9556 name string 9557 mconfig *StreamConfig 9558 }{ 9559 {"MemoryStore", &StreamConfig{ 9560 Name: "MY_STREAM", 9561 Storage: MemoryStorage, 9562 Subjects: []string{"foo.*"}, 9563 Retention: InterestPolicy, 9564 }}, 9565 {"FileStore", &StreamConfig{ 9566 Name: "MY_STREAM", 9567 Storage: FileStorage, 9568 Subjects: []string{"foo.*"}, 9569 Retention: InterestPolicy, 9570 }}, 9571 } 9572 for _, c := range cases { 9573 t.Run(c.name, func(t *testing.T) { 9574 s := RunBasicJetStreamServer(t) 9575 defer s.Shutdown() 9576 9577 mset, err := s.GlobalAccount().addStream(c.mconfig) 9578 if err != nil { 9579 t.Fatalf("Unexpected error adding stream: %v", err) 9580 } 9581 defer mset.delete() 9582 9583 nc1 := clientConnectToServer(t, s) 9584 defer nc1.Close() 9585 9586 nc2 := clientConnectToServer(t, s) 9587 defer nc2.Close() 9588 9589 // Create two durable consumers on the same subject 9590 sub1, _ := nc1.SubscribeSync(nats.NewInbox()) 9591 defer sub1.Unsubscribe() 9592 nc1.Flush() 9593 9594 o1, err := mset.addConsumer(&ConsumerConfig{ 9595 Durable: "dur1", 9596 DeliverSubject: sub1.Subject, 9597 FilterSubject: "foo.bar", 9598 AckPolicy: AckExplicit, 9599 }) 9600 if err != nil { 9601 t.Fatalf("Unexpected error adding consumer: %v", err) 9602 } 9603 defer o1.delete() 9604 9605 sub2, _ := nc2.SubscribeSync(nats.NewInbox()) 9606 defer sub2.Unsubscribe() 9607 nc2.Flush() 9608 9609 o2, err := mset.addConsumer(&ConsumerConfig{ 9610 Durable: "dur2", 9611 DeliverSubject: sub2.Subject, 9612 FilterSubject: "foo.bar", 9613 AckPolicy: AckExplicit, 9614 AckWait: 100 * time.Millisecond, 9615 }) 9616 if err != nil { 9617 t.Fatalf("Unexpected error adding consumer: %v", err) 9618 } 9619 defer o2.delete() 9620 9621 // Send 2 messages 9622 toSend := 2 9623 for i := 0; i < toSend; i++ { 9624 sendStreamMsg(t, nc1, "foo.bar", fmt.Sprintf("msg%v", i+1)) 9625 } 9626 state := mset.state() 9627 if state.Msgs != uint64(toSend) { 9628 t.Fatalf("Expected %v messages, got %d", toSend, state.Msgs) 9629 } 9630 9631 // Receive the messages and ack them. 9632 subs := []*nats.Subscription{sub1, sub2} 9633 for _, sub := range subs { 9634 for i := 0; i < toSend; i++ { 9635 m, err := sub.NextMsg(time.Second) 9636 if err != nil { 9637 t.Fatalf("Error acking message: %v", err) 9638 } 9639 m.Respond(nil) 9640 } 9641 } 9642 // To make sure acks are processed for checking state after sending new ones. 9643 checkFor(t, time.Second, 25*time.Millisecond, func() error { 9644 if state = mset.state(); state.Msgs != 0 { 9645 return fmt.Errorf("Stream still has messages") 9646 } 9647 return nil 9648 }) 9649 9650 // Now close the 2nd subscription... 9651 sub2.Unsubscribe() 9652 nc2.Flush() 9653 9654 // Send 2 more new messages 9655 for i := 0; i < toSend; i++ { 9656 sendStreamMsg(t, nc1, "foo.bar", fmt.Sprintf("msg%v", 2+i+1)) 9657 } 9658 state = mset.state() 9659 if state.Msgs != uint64(toSend) { 9660 t.Fatalf("Expected %v messages, got %d", toSend, state.Msgs) 9661 } 9662 9663 // first subscription should get it and will ack it. 9664 for i := 0; i < toSend; i++ { 9665 m, err := sub1.NextMsg(time.Second) 9666 if err != nil { 9667 t.Fatalf("Error getting message to ack: %v", err) 9668 } 9669 m.Respond(nil) 9670 } 9671 // For acks from m.Respond above 9672 nc1.Flush() 9673 9674 // Now recreate the subscription for the 2nd JS consumer 9675 sub2, _ = nc2.SubscribeSync(nats.NewInbox()) 9676 defer sub2.Unsubscribe() 9677 9678 o2, err = mset.addConsumer(&ConsumerConfig{ 9679 Durable: "dur2", 9680 DeliverSubject: sub2.Subject, 9681 FilterSubject: "foo.bar", 9682 AckPolicy: AckExplicit, 9683 AckWait: 100 * time.Millisecond, 9684 }) 9685 if err != nil { 9686 t.Fatalf("Unexpected error adding consumer: %v", err) 9687 } 9688 defer o2.delete() 9689 9690 // Those messages should be redelivered to the 2nd consumer 9691 for i := 1; i <= toSend; i++ { 9692 m, err := sub2.NextMsg(time.Second) 9693 if err != nil { 9694 t.Fatalf("Error receiving message %d: %v", i, err) 9695 } 9696 m.Respond(nil) 9697 9698 sseq := o2.streamSeqFromReply(m.Reply) 9699 // Depending on timing from above we could receive stream sequences out of order but 9700 // we know we want 3 & 4. 9701 if sseq != 3 && sseq != 4 { 9702 t.Fatalf("Expected stream sequence of 3 or 4 but got %d", sseq) 9703 } 9704 } 9705 }) 9706 } 9707 } 9708 9709 // This test is in support fo clients that want to match on subject, they 9710 // can set the filter subject always. We always store the subject so that 9711 // should the stream later be edited to expand into more subjects the consumer 9712 // still gets what was actually requested 9713 func TestJetStreamConsumerFilterSubject(t *testing.T) { 9714 s := RunBasicJetStreamServer(t) 9715 defer s.Shutdown() 9716 9717 sc := &StreamConfig{Name: "MY_STREAM", Subjects: []string{"foo"}} 9718 mset, err := s.GlobalAccount().addStream(sc) 9719 if err != nil { 9720 t.Fatalf("Unexpected error adding stream: %v", err) 9721 } 9722 defer mset.delete() 9723 9724 cfg := &ConsumerConfig{ 9725 Durable: "d", 9726 DeliverSubject: "A", 9727 AckPolicy: AckExplicit, 9728 FilterSubject: "foo", 9729 } 9730 9731 o, err := mset.addConsumer(cfg) 9732 if err != nil { 9733 t.Fatalf("Unexpected error adding consumer: %v", err) 9734 } 9735 defer o.delete() 9736 9737 if o.info().Config.FilterSubject != "foo" { 9738 t.Fatalf("Expected the filter to be stored") 9739 } 9740 9741 // Now use the original cfg with updated delivery subject and make sure that works ok. 9742 cfg = &ConsumerConfig{ 9743 Durable: "d", 9744 DeliverSubject: "B", 9745 AckPolicy: AckExplicit, 9746 FilterSubject: "foo", 9747 } 9748 9749 o, err = mset.addConsumer(cfg) 9750 if err != nil { 9751 t.Fatalf("Unexpected error adding consumer: %v", err) 9752 } 9753 defer o.delete() 9754 } 9755 9756 func TestJetStreamStoredMsgsDontDisappearAfterCacheExpiration(t *testing.T) { 9757 sc := &StreamConfig{ 9758 Name: "MY_STREAM", 9759 Storage: FileStorage, 9760 Subjects: []string{"foo.>"}, 9761 Retention: InterestPolicy, 9762 } 9763 9764 s := RunBasicJetStreamServer(t) 9765 defer s.Shutdown() 9766 9767 mset, err := s.GlobalAccount().addStreamWithStore(sc, &FileStoreConfig{BlockSize: 128, CacheExpire: 15 * time.Millisecond}) 9768 if err != nil { 9769 t.Fatalf("Unexpected error adding stream: %v", err) 9770 } 9771 defer mset.delete() 9772 9773 nc1 := clientConnectWithOldRequest(t, s) 9774 defer nc1.Close() 9775 9776 // Create a durable consumers 9777 sub, _ := nc1.SubscribeSync(nats.NewInbox()) 9778 defer sub.Unsubscribe() 9779 nc1.Flush() 9780 9781 o, err := mset.addConsumer(&ConsumerConfig{ 9782 Durable: "dur", 9783 DeliverSubject: sub.Subject, 9784 FilterSubject: "foo.bar", 9785 DeliverPolicy: DeliverNew, 9786 AckPolicy: AckExplicit, 9787 }) 9788 if err != nil { 9789 t.Fatalf("Unexpected error adding consumer: %v", err) 9790 } 9791 defer o.delete() 9792 9793 nc2 := clientConnectWithOldRequest(t, s) 9794 defer nc2.Close() 9795 9796 sendStreamMsg(t, nc2, "foo.bar", "msg1") 9797 9798 msg, err := sub.NextMsg(time.Second) 9799 if err != nil { 9800 t.Fatalf("Did not get message: %v", err) 9801 } 9802 if string(msg.Data) != "msg1" { 9803 t.Fatalf("Unexpected message: %q", msg.Data) 9804 } 9805 9806 nc1.Close() 9807 9808 // Get the message from the stream 9809 getMsgSeq := func(seq uint64) { 9810 t.Helper() 9811 mreq := &JSApiMsgGetRequest{Seq: seq} 9812 req, err := json.Marshal(mreq) 9813 if err != nil { 9814 t.Fatalf("Unexpected error: %v", err) 9815 } 9816 smsgj, err := nc2.Request(fmt.Sprintf(JSApiMsgGetT, sc.Name), req, time.Second) 9817 if err != nil { 9818 t.Fatalf("Could not retrieve stream message: %v", err) 9819 } 9820 if strings.Contains(string(smsgj.Data), "code") { 9821 t.Fatalf("Error: %q", smsgj.Data) 9822 } 9823 } 9824 9825 getMsgSeq(1) 9826 9827 time.Sleep(time.Second) 9828 9829 sendStreamMsg(t, nc2, "foo.bar", "msg2") 9830 sendStreamMsg(t, nc2, "foo.bar", "msg3") 9831 9832 getMsgSeq(1) 9833 getMsgSeq(2) 9834 getMsgSeq(3) 9835 } 9836 9837 func TestJetStreamConsumerUpdateRedelivery(t *testing.T) { 9838 cases := []struct { 9839 name string 9840 mconfig *StreamConfig 9841 }{ 9842 {"MemoryStore", &StreamConfig{ 9843 Name: "MY_STREAM", 9844 Storage: MemoryStorage, 9845 Subjects: []string{"foo.>"}, 9846 Retention: InterestPolicy, 9847 }}, 9848 {"FileStore", &StreamConfig{ 9849 Name: "MY_STREAM", 9850 Storage: FileStorage, 9851 Subjects: []string{"foo.>"}, 9852 Retention: InterestPolicy, 9853 }}, 9854 } 9855 for _, c := range cases { 9856 t.Run(c.name, func(t *testing.T) { 9857 s := RunBasicJetStreamServer(t) 9858 defer s.Shutdown() 9859 9860 mset, err := s.GlobalAccount().addStream(c.mconfig) 9861 if err != nil { 9862 t.Fatalf("Unexpected error adding stream: %v", err) 9863 } 9864 defer mset.delete() 9865 9866 nc := clientConnectToServer(t, s) 9867 defer nc.Close() 9868 9869 // Create a durable consumer. 9870 sub, _ := nc.SubscribeSync(nats.NewInbox()) 9871 defer sub.Unsubscribe() 9872 9873 o, err := mset.addConsumer(&ConsumerConfig{ 9874 Durable: "dur22", 9875 DeliverSubject: sub.Subject, 9876 FilterSubject: "foo.bar", 9877 AckPolicy: AckExplicit, 9878 AckWait: 100 * time.Millisecond, 9879 MaxDeliver: 3, 9880 }) 9881 if err != nil { 9882 t.Fatalf("Unexpected error adding consumer: %v", err) 9883 } 9884 defer o.delete() 9885 9886 // Send 20 messages 9887 toSend := 20 9888 for i := 1; i <= toSend; i++ { 9889 sendStreamMsg(t, nc, "foo.bar", fmt.Sprintf("msg-%v", i)) 9890 } 9891 state := mset.state() 9892 if state.Msgs != uint64(toSend) { 9893 t.Fatalf("Expected %v messages, got %d", toSend, state.Msgs) 9894 } 9895 9896 // Receive the messages and ack only every 4th 9897 for i := 0; i < toSend; i++ { 9898 m, err := sub.NextMsg(time.Second) 9899 if err != nil { 9900 t.Fatalf("Error getting message: %v", err) 9901 } 9902 seq, _, _, _, _ := replyInfo(m.Reply) 9903 // 4, 8, 12, 16, 20 9904 if seq%4 == 0 { 9905 m.Respond(nil) 9906 } 9907 } 9908 9909 // Now close the sub and open a new one and update the consumer. 9910 sub.Unsubscribe() 9911 9912 // Wait for it to become inactive 9913 checkFor(t, 200*time.Millisecond, 10*time.Millisecond, func() error { 9914 if o.isActive() { 9915 return fmt.Errorf("Consumer still active") 9916 } 9917 return nil 9918 }) 9919 9920 // Send 20 more messages. 9921 for i := toSend; i < toSend*2; i++ { 9922 sendStreamMsg(t, nc, "foo.bar", fmt.Sprintf("msg-%v", i)) 9923 } 9924 9925 // Create new subscription. 9926 sub, _ = nc.SubscribeSync(nats.NewInbox()) 9927 defer sub.Unsubscribe() 9928 nc.Flush() 9929 9930 o, err = mset.addConsumer(&ConsumerConfig{ 9931 Durable: "dur22", 9932 DeliverSubject: sub.Subject, 9933 FilterSubject: "foo.bar", 9934 AckPolicy: AckExplicit, 9935 AckWait: 100 * time.Millisecond, 9936 MaxDeliver: 3, 9937 }) 9938 if err != nil { 9939 t.Fatalf("Unexpected error adding consumer: %v", err) 9940 } 9941 defer o.delete() 9942 9943 expect := toSend + toSend - 5 // mod 4 acks 9944 checkFor(t, time.Second, 5*time.Millisecond, func() error { 9945 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != expect { 9946 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, expect) 9947 } 9948 return nil 9949 }) 9950 9951 for i, eseq := 0, uint64(1); i < expect; i++ { 9952 m, err := sub.NextMsg(time.Second) 9953 if err != nil { 9954 t.Fatalf("Error getting message: %v", err) 9955 } 9956 // Skip the ones we ack'd from above. We should not get them back here. 9957 if eseq <= uint64(toSend) && eseq%4 == 0 { 9958 eseq++ 9959 } 9960 seq, _, dc, _, _ := replyInfo(m.Reply) 9961 if seq != eseq { 9962 t.Fatalf("Expected stream sequence of %d, got %d", eseq, seq) 9963 } 9964 if seq <= uint64(toSend) && dc != 2 { 9965 t.Fatalf("Expected delivery count of 2 for sequence of %d, got %d", seq, dc) 9966 } 9967 if seq > uint64(toSend) && dc != 1 { 9968 t.Fatalf("Expected delivery count of 1 for sequence of %d, got %d", seq, dc) 9969 } 9970 if seq > uint64(toSend) { 9971 m.Respond(nil) // Ack 9972 } 9973 eseq++ 9974 } 9975 9976 // We should get the second half back since we did not ack those from above. 9977 expect = toSend - 5 9978 checkFor(t, time.Second, 5*time.Millisecond, func() error { 9979 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != expect { 9980 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, expect) 9981 } 9982 return nil 9983 }) 9984 9985 for i, eseq := 0, uint64(1); i < expect; i++ { 9986 m, err := sub.NextMsg(time.Second) 9987 if err != nil { 9988 t.Fatalf("Error getting message: %v", err) 9989 } 9990 // Skip the ones we ack'd from above. We should not get them back here. 9991 if eseq <= uint64(toSend) && eseq%4 == 0 { 9992 eseq++ 9993 } 9994 seq, _, dc, _, _ := replyInfo(m.Reply) 9995 if seq != eseq { 9996 t.Fatalf("Expected stream sequence of %d, got %d", eseq, seq) 9997 } 9998 if dc != 3 { 9999 t.Fatalf("Expected delivery count of 3 for sequence of %d, got %d", seq, dc) 10000 } 10001 eseq++ 10002 } 10003 }) 10004 } 10005 } 10006 10007 func TestJetStreamConsumerMaxAckPending(t *testing.T) { 10008 cases := []struct { 10009 name string 10010 mconfig *StreamConfig 10011 }{ 10012 {"MemoryStore", &StreamConfig{ 10013 Name: "MY_STREAM", 10014 Storage: MemoryStorage, 10015 Subjects: []string{"foo.*"}, 10016 }}, 10017 {"FileStore", &StreamConfig{ 10018 Name: "MY_STREAM", 10019 Storage: FileStorage, 10020 Subjects: []string{"foo.*"}, 10021 }}, 10022 } 10023 for _, c := range cases { 10024 t.Run(c.name, func(t *testing.T) { 10025 s := RunBasicJetStreamServer(t) 10026 defer s.Shutdown() 10027 10028 mset, err := s.GlobalAccount().addStream(c.mconfig) 10029 if err != nil { 10030 t.Fatalf("Unexpected error adding stream: %v", err) 10031 } 10032 defer mset.delete() 10033 10034 nc := clientConnectToServer(t, s) 10035 defer nc.Close() 10036 10037 // Do error scenarios. 10038 _, err = mset.addConsumer(&ConsumerConfig{ 10039 Durable: "d22", 10040 DeliverSubject: nats.NewInbox(), 10041 AckPolicy: AckNone, 10042 MaxAckPending: 1, 10043 }) 10044 if err == nil { 10045 t.Fatalf("Expected error, MaxAckPending only applicable to ack != AckNone") 10046 } 10047 10048 // Queue up 100 messages. 10049 toSend := 100 10050 for i := 0; i < toSend; i++ { 10051 sendStreamMsg(t, nc, "foo.bar", fmt.Sprintf("MSG: %d", i+1)) 10052 } 10053 10054 // Limit to 33 10055 maxAckPending := 33 10056 10057 o, err := mset.addConsumer(&ConsumerConfig{ 10058 Durable: "d22", 10059 DeliverSubject: nats.NewInbox(), 10060 AckPolicy: AckExplicit, 10061 MaxAckPending: maxAckPending, 10062 }) 10063 require_NoError(t, err) 10064 10065 defer o.delete() 10066 10067 sub, _ := nc.SubscribeSync(o.info().Config.DeliverSubject) 10068 defer sub.Unsubscribe() 10069 10070 checkSubPending := func(numExpected int) { 10071 t.Helper() 10072 checkFor(t, time.Second, 20*time.Millisecond, func() error { 10073 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != numExpected { 10074 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 10075 } 10076 return nil 10077 }) 10078 } 10079 10080 checkSubPending(maxAckPending) 10081 // We hit the limit, double check we stayed there. 10082 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != maxAckPending { 10083 t.Fatalf("Too many messages received: %d vs %d", nmsgs, maxAckPending) 10084 } 10085 10086 // Now ack them all. 10087 for i := 0; i < maxAckPending; i++ { 10088 m, err := sub.NextMsg(time.Second) 10089 if err != nil { 10090 t.Fatalf("Error receiving message %d: %v", i, err) 10091 } 10092 m.Respond(nil) 10093 } 10094 checkSubPending(maxAckPending) 10095 10096 o.stop() 10097 mset.purge(nil) 10098 10099 // Now test a consumer that is live while we publish messages to the stream. 10100 o, err = mset.addConsumer(&ConsumerConfig{ 10101 Durable: "d33", 10102 DeliverSubject: nats.NewInbox(), 10103 AckPolicy: AckExplicit, 10104 MaxAckPending: maxAckPending, 10105 }) 10106 require_NoError(t, err) 10107 10108 defer o.delete() 10109 10110 sub, _ = nc.SubscribeSync(o.info().Config.DeliverSubject) 10111 defer sub.Unsubscribe() 10112 nc.Flush() 10113 10114 checkSubPending(0) 10115 10116 // Now stream more then maxAckPending. 10117 for i := 0; i < toSend; i++ { 10118 sendStreamMsg(t, nc, "foo.baz", fmt.Sprintf("MSG: %d", i+1)) 10119 } 10120 checkSubPending(maxAckPending) 10121 // We hit the limit, double check we stayed there. 10122 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != maxAckPending { 10123 t.Fatalf("Too many messages received: %d vs %d", nmsgs, maxAckPending) 10124 } 10125 }) 10126 } 10127 } 10128 10129 func TestJetStreamPullConsumerMaxAckPending(t *testing.T) { 10130 cases := []struct { 10131 name string 10132 mconfig *StreamConfig 10133 }{ 10134 {"MemoryStore", &StreamConfig{ 10135 Name: "MY_STREAM", 10136 Storage: MemoryStorage, 10137 Subjects: []string{"foo.*"}, 10138 }}, 10139 {"FileStore", &StreamConfig{ 10140 Name: "MY_STREAM", 10141 Storage: FileStorage, 10142 Subjects: []string{"foo.*"}, 10143 }}, 10144 } 10145 for _, c := range cases { 10146 t.Run(c.name, func(t *testing.T) { 10147 s := RunBasicJetStreamServer(t) 10148 defer s.Shutdown() 10149 10150 mset, err := s.GlobalAccount().addStream(c.mconfig) 10151 if err != nil { 10152 t.Fatalf("Unexpected error adding stream: %v", err) 10153 } 10154 defer mset.delete() 10155 10156 nc := clientConnectToServer(t, s) 10157 defer nc.Close() 10158 10159 // Queue up 100 messages. 10160 toSend := 100 10161 for i := 0; i < toSend; i++ { 10162 sendStreamMsg(t, nc, "foo.bar", fmt.Sprintf("MSG: %d", i+1)) 10163 } 10164 10165 // Limit to 33 10166 maxAckPending := 33 10167 10168 o, err := mset.addConsumer(&ConsumerConfig{ 10169 Durable: "d22", 10170 AckPolicy: AckExplicit, 10171 MaxAckPending: maxAckPending, 10172 }) 10173 require_NoError(t, err) 10174 10175 defer o.delete() 10176 10177 getSubj := o.requestNextMsgSubject() 10178 10179 var toAck []*nats.Msg 10180 10181 for i := 0; i < maxAckPending; i++ { 10182 if m, err := nc.Request(getSubj, nil, time.Second); err != nil { 10183 t.Fatalf("Unexpected error: %v", err) 10184 } else { 10185 toAck = append(toAck, m) 10186 } 10187 } 10188 10189 // Now ack them all. 10190 for _, m := range toAck { 10191 m.Respond(nil) 10192 } 10193 10194 // Now do batch above the max. 10195 sub, _ := nc.SubscribeSync(nats.NewInbox()) 10196 defer sub.Unsubscribe() 10197 10198 checkSubPending := func(numExpected int) { 10199 t.Helper() 10200 checkFor(t, time.Second, 10*time.Millisecond, func() error { 10201 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != numExpected { 10202 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, numExpected) 10203 } 10204 return nil 10205 }) 10206 } 10207 10208 req := &JSApiConsumerGetNextRequest{Batch: maxAckPending} 10209 jreq, _ := json.Marshal(req) 10210 nc.PublishRequest(getSubj, sub.Subject, jreq) 10211 10212 checkSubPending(maxAckPending) 10213 // We hit the limit, double check we stayed there. 10214 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != maxAckPending { 10215 t.Fatalf("Too many messages received: %d vs %d", nmsgs, maxAckPending) 10216 } 10217 }) 10218 } 10219 } 10220 10221 func TestJetStreamPullConsumerMaxAckPendingRedeliveries(t *testing.T) { 10222 cases := []struct { 10223 name string 10224 mconfig *StreamConfig 10225 }{ 10226 {"MemoryStore", &StreamConfig{ 10227 Name: "MY_STREAM", 10228 Storage: MemoryStorage, 10229 Subjects: []string{"foo.*"}, 10230 }}, 10231 {"FileStore", &StreamConfig{ 10232 Name: "MY_STREAM", 10233 Storage: FileStorage, 10234 Subjects: []string{"foo.*"}, 10235 }}, 10236 } 10237 for _, c := range cases { 10238 t.Run(c.name, func(t *testing.T) { 10239 s := RunBasicJetStreamServer(t) 10240 defer s.Shutdown() 10241 10242 mset, err := s.GlobalAccount().addStream(c.mconfig) 10243 if err != nil { 10244 t.Fatalf("Unexpected error adding stream: %v", err) 10245 } 10246 defer mset.delete() 10247 10248 nc := clientConnectToServer(t, s) 10249 defer nc.Close() 10250 10251 // Queue up 10 messages. 10252 toSend := 10 10253 for i := 0; i < toSend; i++ { 10254 sendStreamMsg(t, nc, "foo.bar", fmt.Sprintf("MSG: %d", i+1)) 10255 } 10256 10257 // Limit to 1 10258 maxAckPending := 1 10259 ackWait := 20 * time.Millisecond 10260 expSeq := uint64(4) 10261 10262 o, err := mset.addConsumer(&ConsumerConfig{ 10263 Durable: "d22", 10264 DeliverPolicy: DeliverByStartSequence, 10265 OptStartSeq: expSeq, 10266 AckPolicy: AckExplicit, 10267 AckWait: ackWait, 10268 MaxAckPending: maxAckPending, 10269 }) 10270 require_NoError(t, err) 10271 10272 defer o.delete() 10273 10274 getSubj := o.requestNextMsgSubject() 10275 delivery := uint64(1) 10276 10277 getNext := func() { 10278 t.Helper() 10279 m, err := nc.Request(getSubj, nil, time.Second) 10280 if err != nil { 10281 t.Fatalf("Unexpected error: %v", err) 10282 } 10283 sseq, dseq, dcount, _, pending := replyInfo(m.Reply) 10284 if sseq != expSeq { 10285 t.Fatalf("Expected stream sequence of %d, got %d", expSeq, sseq) 10286 } 10287 if dseq != delivery { 10288 t.Fatalf("Expected consumer sequence of %d, got %d", delivery, dseq) 10289 } 10290 if dcount != delivery { 10291 t.Fatalf("Expected delivery count of %d, got %d", delivery, dcount) 10292 } 10293 if pending != uint64(toSend)-expSeq { 10294 t.Fatalf("Expected pending to be %d, got %d", uint64(toSend)-expSeq, pending) 10295 } 10296 delivery++ 10297 } 10298 10299 getNext() 10300 getNext() 10301 getNext() 10302 getNext() 10303 getNext() 10304 }) 10305 } 10306 } 10307 10308 func TestJetStreamDeliveryAfterServerRestart(t *testing.T) { 10309 opts := DefaultTestOptions 10310 opts.Port = -1 10311 opts.JetStream = true 10312 opts.StoreDir = t.TempDir() 10313 s := RunServer(&opts) 10314 defer s.Shutdown() 10315 10316 mset, err := s.GlobalAccount().addStream(&StreamConfig{ 10317 Name: "MY_STREAM", 10318 Storage: FileStorage, 10319 Subjects: []string{"foo.>"}, 10320 Retention: InterestPolicy, 10321 }) 10322 if err != nil { 10323 t.Fatalf("Unexpected error adding stream: %v", err) 10324 } 10325 defer mset.delete() 10326 10327 nc := clientConnectToServer(t, s) 10328 defer nc.Close() 10329 10330 inbox := nats.NewInbox() 10331 o, err := mset.addConsumer(&ConsumerConfig{ 10332 Durable: "dur", 10333 DeliverSubject: inbox, 10334 DeliverPolicy: DeliverNew, 10335 AckPolicy: AckExplicit, 10336 }) 10337 if err != nil { 10338 t.Fatalf("Expected no error, got %v", err) 10339 } 10340 defer o.delete() 10341 10342 sub, err := nc.SubscribeSync(inbox) 10343 if err != nil { 10344 t.Fatalf("Error on subscribe: %v", err) 10345 } 10346 nc.Flush() 10347 10348 // Send 1 message 10349 sendStreamMsg(t, nc, "foo.bar", "msg1") 10350 10351 // Make sure we receive it and ack it. 10352 msg, err := sub.NextMsg(250 * time.Millisecond) 10353 if err != nil { 10354 t.Fatalf("Did not get message: %v", err) 10355 } 10356 // Ack it! 10357 msg.Respond(nil) 10358 nc.Flush() 10359 10360 // Shutdown client and server 10361 nc.Close() 10362 10363 dir := strings.TrimSuffix(s.JetStreamConfig().StoreDir, JetStreamStoreDir) 10364 s.Shutdown() 10365 10366 opts.Port = -1 10367 opts.StoreDir = dir 10368 s = RunServer(&opts) 10369 defer s.Shutdown() 10370 10371 // Lookup stream. 10372 mset, err = s.GlobalAccount().lookupStream("MY_STREAM") 10373 if err != nil { 10374 t.Fatalf("Error looking up stream: %v", err) 10375 } 10376 10377 // Update consumer's deliver subject with new inbox 10378 inbox = nats.NewInbox() 10379 o, err = mset.addConsumer(&ConsumerConfig{ 10380 Durable: "dur", 10381 DeliverSubject: inbox, 10382 DeliverPolicy: DeliverNew, 10383 AckPolicy: AckExplicit, 10384 }) 10385 if err != nil { 10386 t.Fatalf("Expected no error, got %v", err) 10387 } 10388 defer o.delete() 10389 10390 nc = clientConnectToServer(t, s) 10391 defer nc.Close() 10392 10393 // Send 2nd message 10394 sendStreamMsg(t, nc, "foo.bar", "msg2") 10395 10396 // Start sub on new inbox 10397 sub, err = nc.SubscribeSync(inbox) 10398 if err != nil { 10399 t.Fatalf("Error on subscribe: %v", err) 10400 } 10401 nc.Flush() 10402 10403 // Should receive message 2. 10404 if _, err := sub.NextMsg(500 * time.Millisecond); err != nil { 10405 t.Fatalf("Did not get message: %v", err) 10406 } 10407 } 10408 10409 // This is for the basics of importing the ability to send to a stream and consume 10410 // from a consumer that is pull based on push based on a well known delivery subject. 10411 func TestJetStreamAccountImportBasics(t *testing.T) { 10412 conf := createConfFile(t, []byte(fmt.Sprintf(` 10413 listen: 127.0.0.1:-1 10414 no_auth_user: rip 10415 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 10416 accounts: { 10417 JS: { 10418 jetstream: enabled 10419 users: [ {user: dlc, password: foo} ] 10420 exports [ 10421 # This is for sending into a stream from other accounts. 10422 { service: "ORDERS.*" } 10423 # This is for accessing a pull based consumer. 10424 { service: "$JS.API.CONSUMER.MSG.NEXT.*.*" } 10425 # This is streaming to a delivery subject for a push based consumer. 10426 { stream: "deliver.ORDERS" } 10427 # This is to ack received messages. This is a service to ack acks.. 10428 { service: "$JS.ACK.ORDERS.*.>" } 10429 ] 10430 }, 10431 IU: { 10432 users: [ {user: rip, password: bar} ] 10433 imports [ 10434 { service: { subject: "ORDERS.*", account: JS }, to: "my.orders.$1" } 10435 { service: { subject: "$JS.API.CONSUMER.MSG.NEXT.ORDERS.d", account: JS }, to: "nxt.msg" } 10436 { stream: { subject: "deliver.ORDERS", account: JS }, to: "d" } 10437 { service: { subject: "$JS.ACK.ORDERS.*.>", account: JS } } 10438 ] 10439 }, 10440 } 10441 `, t.TempDir()))) 10442 10443 s, _ := RunServerWithConfig(conf) 10444 defer s.Shutdown() 10445 10446 acc, err := s.LookupAccount("JS") 10447 if err != nil { 10448 t.Fatalf("Unexpected error looking up account: %v", err) 10449 } 10450 10451 mset, err := acc.addStream(&StreamConfig{Name: "ORDERS", Subjects: []string{"ORDERS.*"}}) 10452 if err != nil { 10453 t.Fatalf("Unexpected error adding stream: %v", err) 10454 } 10455 defer mset.delete() 10456 10457 // This should be the rip user, the one that imports some JS. 10458 nc := clientConnectToServer(t, s) 10459 defer nc.Close() 10460 10461 // Simple publish to a stream. 10462 pubAck := sendStreamMsg(t, nc, "my.orders.foo", "ORDERS-1") 10463 if pubAck.Stream != "ORDERS" || pubAck.Sequence != 1 { 10464 t.Fatalf("Bad pubAck received: %+v", pubAck) 10465 } 10466 if msgs := mset.state().Msgs; msgs != 1 { 10467 t.Fatalf("Expected 1 message, got %d", msgs) 10468 } 10469 10470 total := 2 10471 for i := 2; i <= total; i++ { 10472 sendStreamMsg(t, nc, "my.orders.bar", fmt.Sprintf("ORDERS-%d", i)) 10473 } 10474 if msgs := mset.state().Msgs; msgs != uint64(total) { 10475 t.Fatalf("Expected %d messages, got %d", total, msgs) 10476 } 10477 10478 // Now test access to a pull based consumer, e.g. workqueue. 10479 o, err := mset.addConsumer(&ConsumerConfig{ 10480 Durable: "d", 10481 AckPolicy: AckExplicit, 10482 }) 10483 if err != nil { 10484 t.Fatalf("Expected no error, got %v", err) 10485 } 10486 defer o.delete() 10487 10488 // We mapped the next message request, "$JS.API.CONSUMER.MSG.NEXT.ORDERS.d" -> "nxt.msg" 10489 m, err := nc.Request("nxt.msg", nil, time.Second) 10490 require_NoError(t, err) 10491 if string(m.Data) != "ORDERS-1" { 10492 t.Fatalf("Expected to receive %q, got %q", "ORDERS-1", m.Data) 10493 } 10494 10495 // Now test access to a push based consumer 10496 o, err = mset.addConsumer(&ConsumerConfig{ 10497 Durable: "p", 10498 DeliverSubject: "deliver.ORDERS", 10499 AckPolicy: AckExplicit, 10500 }) 10501 if err != nil { 10502 t.Fatalf("Expected no error, got %v", err) 10503 } 10504 defer o.delete() 10505 10506 // We remapped from above, deliver.ORDERS -> d 10507 sub, _ := nc.SubscribeSync("d") 10508 defer sub.Unsubscribe() 10509 10510 checkFor(t, 250*time.Millisecond, 10*time.Millisecond, func() error { 10511 if nmsgs, _, _ := sub.Pending(); err != nil || nmsgs != total { 10512 return fmt.Errorf("Did not receive correct number of messages: %d vs %d", nmsgs, total) 10513 } 10514 return nil 10515 }) 10516 10517 m, _ = sub.NextMsg(time.Second) 10518 // Make sure we remapped subject correctly across the account boundary. 10519 if m.Subject != "ORDERS.foo" { 10520 t.Fatalf("Expected subject of %q, got %q", "ORDERS.foo", m.Subject) 10521 } 10522 // Now make sure we can ack messages correctly. 10523 m.Respond(AckAck) 10524 nc.Flush() 10525 10526 if info := o.info(); info.AckFloor.Consumer != 1 { 10527 t.Fatalf("Did not receive the ack properly") 10528 } 10529 10530 // Grab second one now. 10531 m, _ = sub.NextMsg(time.Second) 10532 // Make sure we remapped subject correctly across the account boundary. 10533 if m.Subject != "ORDERS.bar" { 10534 t.Fatalf("Expected subject of %q, got %q", "ORDERS.bar", m.Subject) 10535 } 10536 // Now make sure we can ack messages and get back an ack as well. 10537 resp, _ := nc.Request(m.Reply, nil, 100*time.Millisecond) 10538 if resp == nil { 10539 t.Fatalf("No response, possible timeout?") 10540 } 10541 if info := o.info(); info.AckFloor.Consumer != 2 { 10542 t.Fatalf("Did not receive the ack properly") 10543 } 10544 } 10545 10546 // This tests whether we are able to aggregate all JetStream advisory events 10547 // from all accounts into a single account. Config for this test uses 10548 // service imports and exports as that allows for gathering all events 10549 // without having to know the account name and without separate entries 10550 // for each account in aggregate account config. 10551 // This test fails as it is not receiving the api audit event ($JS.EVENT.ADVISORY.API). 10552 func TestJetStreamAccountImportJSAdvisoriesAsService(t *testing.T) { 10553 conf := createConfFile(t, []byte(fmt.Sprintf(` 10554 listen=127.0.0.1:-1 10555 no_auth_user: pp 10556 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 10557 accounts { 10558 JS { 10559 jetstream: enabled 10560 users: [ {user: pp, password: foo} ] 10561 imports [ 10562 { service: { account: AGG, subject: '$JS.EVENT.ADVISORY.ACC.JS.>' }, to: '$JS.EVENT.ADVISORY.>' } 10563 ] 10564 } 10565 AGG { 10566 users: [ {user: agg, password: foo} ] 10567 exports: [ 10568 { service: '$JS.EVENT.ADVISORY.ACC.*.>', response: Singleton, account_token_position: 5 } 10569 ] 10570 } 10571 } 10572 `, t.TempDir()))) 10573 10574 s, _ := RunServerWithConfig(conf) 10575 defer s.Shutdown() 10576 10577 // This should be the pp user, one which manages JetStream assets 10578 ncJS, err := nats.Connect(s.ClientURL()) 10579 if err != nil { 10580 t.Fatalf("Unexpected error during connect: %v", err) 10581 } 10582 defer ncJS.Close() 10583 10584 // This is the agg user, which should aggregate all JS advisory events. 10585 ncAgg, err := nats.Connect(s.ClientURL(), nats.UserInfo("agg", "foo")) 10586 if err != nil { 10587 t.Fatalf("Unexpected error during connect: %v", err) 10588 } 10589 defer ncAgg.Close() 10590 10591 js, err := ncJS.JetStream() 10592 if err != nil { 10593 t.Fatalf("Unexpected error: %v", err) 10594 } 10595 10596 // user from JS account should receive events on $JS.EVENT.ADVISORY.> subject 10597 subJS, err := ncJS.SubscribeSync("$JS.EVENT.ADVISORY.>") 10598 if err != nil { 10599 t.Fatalf("Unexpected error: %v", err) 10600 } 10601 defer subJS.Unsubscribe() 10602 10603 // user from AGG account should receive events on mapped $JS.EVENT.ADVISORY.ACC.JS.> subject (with account name) 10604 subAgg, err := ncAgg.SubscribeSync("$JS.EVENT.ADVISORY.ACC.JS.>") 10605 if err != nil { 10606 t.Fatalf("Unexpected error: %v", err) 10607 } 10608 10609 // add stream using JS account 10610 // this should trigger 2 events: 10611 // - an action event on $JS.EVENT.ADVISORY.STREAM.CREATED.ORDERS 10612 // - an api audit event on $JS.EVENT.ADVISORY.API 10613 _, err = js.AddStream(&nats.StreamConfig{Name: "ORDERS", Subjects: []string{"ORDERS.*"}}) 10614 if err != nil { 10615 t.Fatalf("Unexpected error adding stream: %v", err) 10616 } 10617 10618 gotEvents := map[string]int{} 10619 for i := 0; i < 2; i++ { 10620 msg, err := subJS.NextMsg(time.Second * 2) 10621 if err != nil { 10622 t.Fatalf("Unexpected error: %v", err) 10623 } 10624 gotEvents[msg.Subject]++ 10625 } 10626 if c := gotEvents["$JS.EVENT.ADVISORY.STREAM.CREATED.ORDERS"]; c != 1 { 10627 t.Fatalf("Should have received one advisory from $JS.EVENT.ADVISORY.STREAM.CREATED.ORDERS but got %d", c) 10628 } 10629 if c := gotEvents["$JS.EVENT.ADVISORY.API"]; c != 1 { 10630 t.Fatalf("Should have received one advisory from $JS.EVENT.ADVISORY.API but got %d", c) 10631 } 10632 10633 // same set of events should be received by AGG account 10634 // on subjects containing account name (ACC.JS) 10635 gotEvents = map[string]int{} 10636 for i := 0; i < 2; i++ { 10637 msg, err := subAgg.NextMsg(time.Second * 2) 10638 require_NoError(t, err) 10639 var adv JSAPIAudit 10640 require_NoError(t, json.Unmarshal(msg.Data, &adv)) 10641 // Make sure we have full fidelity info via implicit share. 10642 if adv.Client != nil { 10643 require_True(t, adv.Client.Host != _EMPTY_) 10644 require_True(t, adv.Client.User != _EMPTY_) 10645 require_True(t, adv.Client.Lang != _EMPTY_) 10646 } 10647 gotEvents[msg.Subject]++ 10648 } 10649 if c := gotEvents["$JS.EVENT.ADVISORY.ACC.JS.STREAM.CREATED.ORDERS"]; c != 1 { 10650 t.Fatalf("Should have received one advisory from $JS.EVENT.ADVISORY.ACC.JS.STREAM.CREATED.ORDERS but got %d", c) 10651 } 10652 if c := gotEvents["$JS.EVENT.ADVISORY.ACC.JS.API"]; c != 1 { 10653 t.Fatalf("Should have received one advisory from $JS.EVENT.ADVISORY.ACC.JS.API but got %d", c) 10654 } 10655 } 10656 10657 // This tests whether we are able to aggregate all JetStream advisory events 10658 // from all accounts into a single account. Config for this test uses 10659 // stream imports and exports as that allows for gathering all events 10660 // as long as there is a separate stream import entry for each account 10661 // in aggregate account config. 10662 func TestJetStreamAccountImportJSAdvisoriesAsStream(t *testing.T) { 10663 conf := createConfFile(t, []byte(fmt.Sprintf(` 10664 listen=127.0.0.1:-1 10665 no_auth_user: pp 10666 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 10667 accounts { 10668 JS { 10669 jetstream: enabled 10670 users: [ {user: pp, password: foo} ] 10671 exports [ 10672 { stream: '$JS.EVENT.ADVISORY.>' } 10673 ] 10674 } 10675 AGG { 10676 users: [ {user: agg, password: foo} ] 10677 imports: [ 10678 { stream: { account: JS, subject: '$JS.EVENT.ADVISORY.>' }, to: '$JS.EVENT.ADVISORY.ACC.JS.>' } 10679 ] 10680 } 10681 } 10682 `, t.TempDir()))) 10683 10684 s, _ := RunServerWithConfig(conf) 10685 defer s.Shutdown() 10686 10687 // This should be the pp user, one which manages JetStream assets 10688 ncJS, err := nats.Connect(s.ClientURL()) 10689 if err != nil { 10690 t.Fatalf("Unexpected error during connect: %v", err) 10691 } 10692 defer ncJS.Close() 10693 10694 // This is the agg user, which should aggregate all JS advisory events. 10695 ncAgg, err := nats.Connect(s.ClientURL(), nats.UserInfo("agg", "foo")) 10696 if err != nil { 10697 t.Fatalf("Unexpected error during connect: %v", err) 10698 } 10699 defer ncAgg.Close() 10700 10701 js, err := ncJS.JetStream() 10702 if err != nil { 10703 t.Fatalf("Unexpected error: %v", err) 10704 } 10705 10706 // user from JS account should receive events on $JS.EVENT.ADVISORY.> subject 10707 subJS, err := ncJS.SubscribeSync("$JS.EVENT.ADVISORY.>") 10708 if err != nil { 10709 t.Fatalf("Unexpected error: %v", err) 10710 } 10711 defer subJS.Unsubscribe() 10712 10713 // user from AGG account should receive events on mapped $JS.EVENT.ADVISORY.ACC.JS.> subject (with account name) 10714 subAgg, err := ncAgg.SubscribeSync("$JS.EVENT.ADVISORY.ACC.JS.>") 10715 if err != nil { 10716 t.Fatalf("Unexpected error: %v", err) 10717 } 10718 10719 // add stream using JS account 10720 // this should trigger 2 events: 10721 // - an action event on $JS.EVENT.ADVISORY.STREAM.CREATED.ORDERS 10722 // - an api audit event on $JS.EVENT.ADVISORY.API 10723 _, err = js.AddStream(&nats.StreamConfig{Name: "ORDERS", Subjects: []string{"ORDERS.*"}}) 10724 if err != nil { 10725 t.Fatalf("Unexpected error adding stream: %v", err) 10726 } 10727 10728 var gotAPIAdvisory, gotCreateAdvisory bool 10729 for i := 0; i < 2; i++ { 10730 msg, err := subJS.NextMsg(time.Second * 2) 10731 if err != nil { 10732 t.Fatalf("Unexpected error on JS account: %v", err) 10733 } 10734 switch msg.Subject { 10735 case "$JS.EVENT.ADVISORY.STREAM.CREATED.ORDERS": 10736 gotCreateAdvisory = true 10737 case "$JS.EVENT.ADVISORY.API": 10738 gotAPIAdvisory = true 10739 default: 10740 t.Fatalf("Unexpected subject: %q", msg.Subject) 10741 } 10742 } 10743 if !gotAPIAdvisory || !gotCreateAdvisory { 10744 t.Fatalf("Expected to have received both advisories on JS account (API advisory %v, create advisory %v)", gotAPIAdvisory, gotCreateAdvisory) 10745 } 10746 10747 // same set of events should be received by AGG account 10748 // on subjects containing account name (ACC.JS) 10749 gotAPIAdvisory, gotCreateAdvisory = false, false 10750 for i := 0; i < 2; i++ { 10751 msg, err := subAgg.NextMsg(time.Second * 2) 10752 if err != nil { 10753 t.Fatalf("Unexpected error on AGG account: %v", err) 10754 } 10755 switch msg.Subject { 10756 case "$JS.EVENT.ADVISORY.ACC.JS.STREAM.CREATED.ORDERS": 10757 gotCreateAdvisory = true 10758 case "$JS.EVENT.ADVISORY.ACC.JS.API": 10759 gotAPIAdvisory = true 10760 default: 10761 t.Fatalf("Unexpected subject: %q", msg.Subject) 10762 } 10763 } 10764 if !gotAPIAdvisory || !gotCreateAdvisory { 10765 t.Fatalf("Expected to have received both advisories on AGG account (API advisory %v, create advisory %v)", gotAPIAdvisory, gotCreateAdvisory) 10766 } 10767 } 10768 10769 // This is for importing all of JetStream into another account for admin purposes. 10770 func TestJetStreamAccountImportAll(t *testing.T) { 10771 conf := createConfFile(t, []byte(fmt.Sprintf(` 10772 listen: 127.0.0.1:-1 10773 no_auth_user: rip 10774 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 10775 accounts: { 10776 JS: { 10777 jetstream: enabled 10778 users: [ {user: dlc, password: foo} ] 10779 exports [ { service: "$JS.API.>" } ] 10780 }, 10781 IU: { 10782 users: [ {user: rip, password: bar} ] 10783 imports [ { service: { subject: "$JS.API.>", account: JS }, to: "jsapi.>"} ] 10784 }, 10785 } 10786 `, t.TempDir()))) 10787 10788 s, _ := RunServerWithConfig(conf) 10789 defer s.Shutdown() 10790 10791 acc, err := s.LookupAccount("JS") 10792 if err != nil { 10793 t.Fatalf("Unexpected error looking up account: %v", err) 10794 } 10795 10796 mset, err := acc.addStream(&StreamConfig{Name: "ORDERS", Subjects: []string{"ORDERS.*"}}) 10797 if err != nil { 10798 t.Fatalf("Unexpected error adding stream: %v", err) 10799 } 10800 defer mset.delete() 10801 10802 // This should be the rip user, the one that imports all of JS. 10803 nc := clientConnectToServer(t, s) 10804 defer nc.Close() 10805 10806 mapSubj := func(subject string) string { 10807 return strings.Replace(subject, "$JS.API.", "jsapi.", 1) 10808 } 10809 10810 // This will get the current information about usage and limits for this account. 10811 resp, err := nc.Request(mapSubj(JSApiAccountInfo), nil, time.Second) 10812 require_NoError(t, err) 10813 var info JSApiAccountInfoResponse 10814 if err := json.Unmarshal(resp.Data, &info); err != nil { 10815 t.Fatalf("Unexpected error: %v", err) 10816 } 10817 if info.Error != nil { 10818 t.Fatalf("Unexpected error: %+v", info.Error) 10819 } 10820 // Lookup streams. 10821 resp, err = nc.Request(mapSubj(JSApiStreams), nil, time.Second) 10822 require_NoError(t, err) 10823 var namesResponse JSApiStreamNamesResponse 10824 if err = json.Unmarshal(resp.Data, &namesResponse); err != nil { 10825 t.Fatalf("Unexpected error: %v", err) 10826 } 10827 if namesResponse.Error != nil { 10828 t.Fatalf("Unexpected error: %+v", namesResponse.Error) 10829 } 10830 } 10831 10832 // https://github.com/nats-io/nats-server/issues/1736 10833 func TestJetStreamServerReload(t *testing.T) { 10834 conf := createConfFile(t, []byte(fmt.Sprintf(` 10835 listen: 127.0.0.1:-1 10836 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q } 10837 accounts: { 10838 A: { users: [ {user: ua, password: pwd} ] }, 10839 B: { 10840 jetstream: {max_mem: 1GB, max_store: 1TB, max_streams: 10, max_consumers: 1k} 10841 users: [ {user: ub, password: pwd} ] 10842 }, 10843 SYS: { users: [ {user: uc, password: pwd} ] }, 10844 } 10845 no_auth_user: ub 10846 system_account: SYS 10847 `, t.TempDir()))) 10848 10849 s, _ := RunServerWithConfig(conf) 10850 defer s.Shutdown() 10851 10852 if !s.JetStreamEnabled() { 10853 t.Fatalf("Expected JetStream to be enabled") 10854 } 10855 10856 // Client for API requests. 10857 nc := clientConnectToServer(t, s) 10858 defer nc.Close() 10859 10860 checkJSAccount := func() { 10861 t.Helper() 10862 resp, err := nc.Request(JSApiAccountInfo, nil, time.Second) 10863 if err != nil { 10864 t.Fatalf("Unexpected error: %v", err) 10865 } 10866 var info JSApiAccountInfoResponse 10867 if err := json.Unmarshal(resp.Data, &info); err != nil { 10868 t.Fatalf("Unexpected error: %v", err) 10869 } 10870 } 10871 10872 checkJSAccount() 10873 10874 acc, err := s.LookupAccount("B") 10875 if err != nil { 10876 t.Fatalf("Unexpected error looking up account: %v", err) 10877 } 10878 mset, err := acc.addStream(&StreamConfig{Name: "22"}) 10879 require_NoError(t, err) 10880 10881 toSend := 10 10882 for i := 0; i < toSend; i++ { 10883 sendStreamMsg(t, nc, "22", fmt.Sprintf("MSG: %d", i+1)) 10884 } 10885 if msgs := mset.state().Msgs; msgs != uint64(toSend) { 10886 t.Fatalf("Expected %d messages, got %d", toSend, msgs) 10887 } 10888 10889 if err := s.Reload(); err != nil { 10890 t.Fatalf("Error on server reload: %v", err) 10891 } 10892 10893 // Wait to get reconnected. 10894 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 10895 if !nc.IsConnected() { 10896 return fmt.Errorf("Not connected") 10897 } 10898 return nil 10899 }) 10900 10901 checkJSAccount() 10902 sendStreamMsg(t, nc, "22", "MSG: 22") 10903 } 10904 10905 func TestJetStreamConfigReloadWithGlobalAccount(t *testing.T) { 10906 tdir := t.TempDir() 10907 template := ` 10908 listen: 127.0.0.1:-1 10909 authorization { 10910 users [ 10911 {user: anonymous} 10912 {user: user1, password: %s} 10913 ] 10914 } 10915 no_auth_user: anonymous 10916 jetstream { 10917 store_dir = %q 10918 } 10919 ` 10920 conf := createConfFile(t, []byte(fmt.Sprintf(template, "pwd", tdir))) 10921 10922 s, _ := RunServerWithConfig(conf) 10923 defer s.Shutdown() 10924 10925 // Client for API requests. 10926 nc, js := jsClientConnect(t, s) 10927 defer nc.Close() 10928 10929 checkJSAccount := func() { 10930 t.Helper() 10931 if _, err := js.AccountInfo(); err != nil { 10932 t.Fatalf("Unexpected error: %v", err) 10933 } 10934 } 10935 10936 checkJSAccount() 10937 10938 if _, err := js.AddStream(&nats.StreamConfig{Name: "foo"}); err != nil { 10939 t.Fatalf("Unexpected error: %v", err) 10940 } 10941 10942 toSend := 10 10943 for i := 0; i < toSend; i++ { 10944 if _, err := js.Publish("foo", []byte(fmt.Sprintf("MSG: %d", i+1))); err != nil { 10945 t.Fatalf("Unexpected publish error: %v", err) 10946 } 10947 } 10948 si, err := js.StreamInfo("foo") 10949 require_NoError(t, err) 10950 if si.State.Msgs != uint64(toSend) { 10951 t.Fatalf("Expected %d msgs after restart, got %d", toSend, si.State.Msgs) 10952 } 10953 10954 if err := os.WriteFile(conf, []byte(fmt.Sprintf(template, "pwd2", tdir)), 0666); err != nil { 10955 t.Fatalf("Error writing config: %v", err) 10956 } 10957 10958 if err := s.Reload(); err != nil { 10959 t.Fatalf("Error during config reload: %v", err) 10960 } 10961 10962 nc, js = jsClientConnect(t, s) 10963 defer nc.Close() 10964 10965 // Try to add a new stream to the global account 10966 if _, err := js.AddStream(&nats.StreamConfig{Name: "bar"}); err != nil { 10967 t.Fatalf("Unexpected error: %v", err) 10968 } 10969 10970 checkJSAccount() 10971 } 10972 10973 // Test that we properly enforce per subject msg limits. 10974 func TestJetStreamMaxMsgsPerSubject(t *testing.T) { 10975 const maxPer = 5 10976 msc := StreamConfig{ 10977 Name: "TEST", 10978 Subjects: []string{"foo", "bar", "baz.*"}, 10979 Storage: MemoryStorage, 10980 MaxMsgsPer: maxPer, 10981 } 10982 fsc := msc 10983 fsc.Storage = FileStorage 10984 10985 cases := []struct { 10986 name string 10987 mconfig *StreamConfig 10988 }{ 10989 {"MemoryStore", &msc}, 10990 {"FileStore", &fsc}, 10991 } 10992 10993 for _, c := range cases { 10994 t.Run(c.name, func(t *testing.T) { 10995 s := RunBasicJetStreamServer(t) 10996 defer s.Shutdown() 10997 10998 mset, err := s.GlobalAccount().addStream(c.mconfig) 10999 if err != nil { 11000 t.Fatalf("Unexpected error adding stream: %v", err) 11001 } 11002 defer mset.delete() 11003 11004 // Client for API requests. 11005 nc, js := jsClientConnect(t, s) 11006 defer nc.Close() 11007 11008 pubAndCheck := func(subj string, num int, expectedNumMsgs uint64) { 11009 t.Helper() 11010 for i := 0; i < num; i++ { 11011 if _, err = js.Publish(subj, []byte("TSLA")); err != nil { 11012 t.Fatalf("Unexpected publish error: %v", err) 11013 } 11014 } 11015 si, err := js.StreamInfo("TEST") 11016 if err != nil { 11017 t.Fatalf("Unexpected error: %v", err) 11018 } 11019 if si.State.Msgs != expectedNumMsgs { 11020 t.Fatalf("Expected %d msgs, got %d", expectedNumMsgs, si.State.Msgs) 11021 } 11022 } 11023 11024 pubAndCheck("foo", 1, 1) 11025 pubAndCheck("foo", 4, 5) 11026 // Now make sure our per subject limits kick in.. 11027 pubAndCheck("foo", 2, 5) 11028 pubAndCheck("baz.22", 5, 10) 11029 pubAndCheck("baz.33", 5, 15) 11030 // We are maxed so totals should be same no matter what we add here. 11031 pubAndCheck("baz.22", 5, 15) 11032 pubAndCheck("baz.33", 5, 15) 11033 11034 // Now purge and make sure all is still good. 11035 mset.purge(nil) 11036 pubAndCheck("foo", 1, 1) 11037 pubAndCheck("foo", 4, 5) 11038 pubAndCheck("baz.22", 5, 10) 11039 pubAndCheck("baz.33", 5, 15) 11040 }) 11041 } 11042 } 11043 11044 func TestJetStreamGetLastMsgBySubject(t *testing.T) { 11045 for _, st := range []StorageType{FileStorage, MemoryStorage} { 11046 t.Run(st.String(), func(t *testing.T) { 11047 c := createJetStreamClusterExplicit(t, "JSC", 3) 11048 defer c.shutdown() 11049 11050 nc, js := jsClientConnect(t, c.randomServer()) 11051 defer nc.Close() 11052 11053 cfg := StreamConfig{ 11054 Name: "KV", 11055 Subjects: []string{"kv.>"}, 11056 Storage: st, 11057 Replicas: 2, 11058 MaxMsgsPer: 20, 11059 } 11060 11061 req, err := json.Marshal(cfg) 11062 if err != nil { 11063 t.Fatalf("Unexpected error: %v", err) 11064 } 11065 // Do manually for now. 11066 nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 11067 si, err := js.StreamInfo("KV") 11068 if err != nil { 11069 t.Fatalf("Unexpected error: %v", err) 11070 } 11071 if si == nil || si.Config.Name != "KV" { 11072 t.Fatalf("StreamInfo is not correct %+v", si) 11073 } 11074 11075 for i := 0; i < 1000; i++ { 11076 msg := []byte(fmt.Sprintf("VAL-%d", i+1)) 11077 js.PublishAsync("kv.foo", msg) 11078 js.PublishAsync("kv.bar", msg) 11079 js.PublishAsync("kv.baz", msg) 11080 } 11081 select { 11082 case <-js.PublishAsyncComplete(): 11083 case <-time.After(5 * time.Second): 11084 t.Fatalf("Did not receive completion signal") 11085 } 11086 11087 // Check that if both set that errors. 11088 b, _ := json.Marshal(JSApiMsgGetRequest{LastFor: "kv.foo", Seq: 950}) 11089 rmsg, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, "KV"), b, time.Second) 11090 if err != nil { 11091 t.Fatalf("Unexpected error: %v", err) 11092 } 11093 var resp JSApiMsgGetResponse 11094 err = json.Unmarshal(rmsg.Data, &resp) 11095 if err != nil { 11096 t.Fatalf("Could not parse stream message: %v", err) 11097 } 11098 if resp.Error == nil { 11099 t.Fatalf("Expected an error when both are set, got %+v", resp.Error) 11100 } 11101 11102 // Need to do stream GetMsg by hand for now until Go client support lands. 11103 getLast := func(subject string) *StoredMsg { 11104 t.Helper() 11105 req := &JSApiMsgGetRequest{LastFor: subject} 11106 b, _ := json.Marshal(req) 11107 rmsg, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, "KV"), b, time.Second) 11108 if err != nil { 11109 t.Fatalf("Unexpected error: %v", err) 11110 } 11111 var resp JSApiMsgGetResponse 11112 err = json.Unmarshal(rmsg.Data, &resp) 11113 if err != nil { 11114 t.Fatalf("Could not parse stream message: %v", err) 11115 } 11116 if resp.Message == nil || resp.Error != nil { 11117 t.Fatalf("Did not receive correct response: %+v", resp.Error) 11118 } 11119 return resp.Message 11120 } 11121 // Do basic checks. 11122 basicCheck := func(subject string, expectedSeq uint64) { 11123 sm := getLast(subject) 11124 if sm == nil { 11125 t.Fatalf("Expected a message but got none") 11126 } else if string(sm.Data) != "VAL-1000" { 11127 t.Fatalf("Wrong message payload, wanted %q but got %q", "VAL-1000", sm.Data) 11128 } else if sm.Sequence != expectedSeq { 11129 t.Fatalf("Wrong message sequence, wanted %d but got %d", expectedSeq, sm.Sequence) 11130 } else if !subjectIsSubsetMatch(sm.Subject, subject) { 11131 t.Fatalf("Wrong subject, wanted %q but got %q", subject, sm.Subject) 11132 } 11133 } 11134 11135 basicCheck("kv.foo", 2998) 11136 basicCheck("kv.bar", 2999) 11137 basicCheck("kv.baz", 3000) 11138 basicCheck("kv.*", 3000) 11139 basicCheck(">", 3000) 11140 }) 11141 } 11142 } 11143 11144 // https://github.com/nats-io/nats-server/issues/2329 11145 func TestJetStreamGetLastMsgBySubjectAfterUpdate(t *testing.T) { 11146 c := createJetStreamClusterExplicit(t, "JSC", 3) 11147 defer c.shutdown() 11148 11149 nc, js := jsClientConnect(t, c.randomServer()) 11150 defer nc.Close() 11151 11152 sc := &nats.StreamConfig{ 11153 Name: "TEST", 11154 Subjects: []string{"foo"}, 11155 Replicas: 2, 11156 } 11157 if _, err := js.AddStream(sc); err != nil { 11158 t.Fatalf("Unexpected error: %v", err) 11159 } 11160 // Now Update and add in other subjects. 11161 sc.Subjects = append(sc.Subjects, "bar", "baz") 11162 if _, err := js.UpdateStream(sc); err != nil { 11163 t.Fatalf("Unexpected error: %v", err) 11164 } 11165 11166 js.Publish("foo", []byte("OK1")) // 1 11167 js.Publish("bar", []byte("OK1")) // 2 11168 js.Publish("foo", []byte("OK2")) // 3 11169 js.Publish("bar", []byte("OK2")) // 4 11170 11171 // Need to do stream GetMsg by hand for now until Go client support lands. 11172 getLast := func(subject string) *StoredMsg { 11173 t.Helper() 11174 req := &JSApiMsgGetRequest{LastFor: subject} 11175 b, _ := json.Marshal(req) 11176 rmsg, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, "TEST"), b, time.Second) 11177 if err != nil { 11178 t.Fatalf("Unexpected error: %v", err) 11179 } 11180 var resp JSApiMsgGetResponse 11181 err = json.Unmarshal(rmsg.Data, &resp) 11182 if err != nil { 11183 t.Fatalf("Could not parse stream message: %v", err) 11184 } 11185 if resp.Message == nil || resp.Error != nil { 11186 t.Fatalf("Did not receive correct response: %+v", resp.Error) 11187 } 11188 return resp.Message 11189 } 11190 // Do basic checks. 11191 basicCheck := func(subject string, expectedSeq uint64) { 11192 sm := getLast(subject) 11193 if sm == nil { 11194 t.Fatalf("Expected a message but got none") 11195 } else if sm.Sequence != expectedSeq { 11196 t.Fatalf("Wrong message sequence, wanted %d but got %d", expectedSeq, sm.Sequence) 11197 } else if !subjectIsSubsetMatch(sm.Subject, subject) { 11198 t.Fatalf("Wrong subject, wanted %q but got %q", subject, sm.Subject) 11199 } 11200 } 11201 11202 basicCheck("foo", 3) 11203 basicCheck("bar", 4) 11204 } 11205 11206 func TestJetStreamLastSequenceBySubject(t *testing.T) { 11207 for _, st := range []StorageType{FileStorage, MemoryStorage} { 11208 t.Run(st.String(), func(t *testing.T) { 11209 c := createJetStreamClusterExplicit(t, "JSC", 3) 11210 defer c.shutdown() 11211 11212 nc, js := jsClientConnect(t, c.randomServer()) 11213 defer nc.Close() 11214 11215 cfg := StreamConfig{ 11216 Name: "KV", 11217 Subjects: []string{"kv.>"}, 11218 Storage: st, 11219 Replicas: 3, 11220 MaxMsgsPer: 1, 11221 } 11222 11223 req, err := json.Marshal(cfg) 11224 if err != nil { 11225 t.Fatalf("Unexpected error: %v", err) 11226 } 11227 // Do manually for now. 11228 m, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 11229 require_NoError(t, err) 11230 si, err := js.StreamInfo("KV") 11231 if err != nil { 11232 t.Fatalf("Unexpected error: %v, respmsg: %q", err, string(m.Data)) 11233 } 11234 if si == nil || si.Config.Name != "KV" { 11235 t.Fatalf("StreamInfo is not correct %+v", si) 11236 } 11237 11238 js.PublishAsync("kv.foo", []byte("1")) 11239 js.PublishAsync("kv.bar", []byte("2")) 11240 js.PublishAsync("kv.baz", []byte("3")) 11241 11242 select { 11243 case <-js.PublishAsyncComplete(): 11244 case <-time.After(time.Second): 11245 t.Fatalf("Did not receive completion signal") 11246 } 11247 11248 // Now make sure we get an error if the last sequence is not correct per subject. 11249 pubAndCheck := func(subj, seq string, ok bool) { 11250 t.Helper() 11251 m := nats.NewMsg(subj) 11252 m.Data = []byte("HELLO") 11253 m.Header.Set(JSExpectedLastSubjSeq, seq) 11254 _, err := js.PublishMsg(m) 11255 if ok && err != nil { 11256 t.Fatalf("Unexpected error: %v", err) 11257 } 11258 if !ok && err == nil { 11259 t.Fatalf("Expected to get an error and got none") 11260 } 11261 } 11262 11263 pubAndCheck("kv.foo", "1", true) // So last is now 4. 11264 pubAndCheck("kv.foo", "1", false) // This should fail. 11265 pubAndCheck("kv.bar", "2", true) 11266 pubAndCheck("kv.bar", "5", true) 11267 pubAndCheck("kv.xxx", "5", false) 11268 }) 11269 } 11270 } 11271 11272 func TestJetStreamFilteredConsumersWithWiderFilter(t *testing.T) { 11273 s := RunBasicJetStreamServer(t) 11274 defer s.Shutdown() 11275 11276 // Client for API requests. 11277 nc, js := jsClientConnect(t, s) 11278 defer nc.Close() 11279 11280 // Origin 11281 _, err := js.AddStream(&nats.StreamConfig{ 11282 Name: "TEST", 11283 Subjects: []string{"foo", "bar", "baz", "N.*"}, 11284 }) 11285 require_NoError(t, err) 11286 11287 // Add in some messages. 11288 js.Publish("foo", []byte("OK")) 11289 js.Publish("bar", []byte("OK")) 11290 js.Publish("baz", []byte("OK")) 11291 for i := 0; i < 12; i++ { 11292 js.Publish(fmt.Sprintf("N.%d", i+1), []byte("OK")) 11293 } 11294 11295 checkFor(t, 5*time.Second, 250*time.Millisecond, func() error { 11296 si, err := js.StreamInfo("TEST") 11297 require_NoError(t, err) 11298 11299 if si.State.Msgs != 15 { 11300 return fmt.Errorf("Expected 15 msgs, got state: %+v", si.State) 11301 } 11302 return nil 11303 }) 11304 11305 checkWider := func(subj string, numExpected int) { 11306 sub, err := js.SubscribeSync(subj) 11307 require_NoError(t, err) 11308 11309 defer sub.Unsubscribe() 11310 checkSubsPending(t, sub, numExpected) 11311 } 11312 11313 checkWider("*", 3) 11314 checkWider("N.*", 12) 11315 checkWider("*.*", 12) 11316 checkWider("N.>", 12) 11317 checkWider(">", 15) 11318 } 11319 11320 func TestJetStreamMirrorAndSourcesFilteredConsumers(t *testing.T) { 11321 s := RunBasicJetStreamServer(t) 11322 defer s.Shutdown() 11323 11324 // Client for API requests. 11325 nc, js := jsClientConnect(t, s) 11326 defer nc.Close() 11327 11328 // Origin 11329 _, err := js.AddStream(&nats.StreamConfig{ 11330 Name: "TEST", 11331 Subjects: []string{"foo", "bar", "baz.*"}, 11332 }) 11333 require_NoError(t, err) 11334 11335 // Create Mirror now. 11336 _, err = js.AddStream(&nats.StreamConfig{ 11337 Name: "M", 11338 Mirror: &nats.StreamSource{Name: "TEST"}, 11339 }) 11340 require_NoError(t, err) 11341 11342 dsubj := nats.NewInbox() 11343 nc.SubscribeSync(dsubj) 11344 nc.Flush() 11345 11346 createConsumer := func(sn, fs string) { 11347 t.Helper() 11348 _, err = js.AddConsumer(sn, &nats.ConsumerConfig{DeliverSubject: dsubj, FilterSubject: fs}) 11349 require_NoError(t, err) 11350 11351 } 11352 11353 createConsumer("M", "foo") 11354 createConsumer("M", "bar") 11355 createConsumer("M", "baz.foo") 11356 11357 // Now do some sources. 11358 if _, err := js.AddStream(&nats.StreamConfig{Name: "O1", Subjects: []string{"foo.*"}}); err != nil { 11359 t.Fatalf("Unexpected error: %v", err) 11360 } 11361 if _, err := js.AddStream(&nats.StreamConfig{Name: "O2", Subjects: []string{"bar.*"}}); err != nil { 11362 t.Fatalf("Unexpected error: %v", err) 11363 } 11364 11365 // Create Mirror now. 11366 _, err = js.AddStream(&nats.StreamConfig{ 11367 Name: "S", 11368 Sources: []*nats.StreamSource{{Name: "O1"}, {Name: "O2"}}, 11369 }) 11370 require_NoError(t, err) 11371 11372 createConsumer("S", "foo.1") 11373 createConsumer("S", "bar.1") 11374 11375 // Chaining 11376 // Create Mirror now. 11377 _, err = js.AddStream(&nats.StreamConfig{ 11378 Name: "M2", 11379 Mirror: &nats.StreamSource{Name: "M"}, 11380 }) 11381 require_NoError(t, err) 11382 11383 createConsumer("M2", "foo") 11384 createConsumer("M2", "bar") 11385 createConsumer("M2", "baz.foo") 11386 } 11387 11388 func TestJetStreamMirrorBasics(t *testing.T) { 11389 s := RunBasicJetStreamServer(t) 11390 defer s.Shutdown() 11391 11392 // Client for API requests. 11393 nc, js := jsClientConnect(t, s) 11394 defer nc.Close() 11395 11396 createStream := func(cfg *nats.StreamConfig) (*nats.StreamInfo, error) { 11397 return js.AddStream(cfg) 11398 } 11399 11400 createStreamOk := func(cfg *nats.StreamConfig) { 11401 t.Helper() 11402 if _, err := createStream(cfg); err != nil { 11403 t.Fatalf("Expected no error, got %+v", err) 11404 } 11405 } 11406 11407 // Test we get right config errors etc. 11408 cfg := &nats.StreamConfig{ 11409 Name: "M1", 11410 Subjects: []string{"foo", "bar", "baz"}, 11411 Mirror: &nats.StreamSource{Name: "S1"}, 11412 } 11413 _, err := createStream(cfg) 11414 if err == nil || !strings.Contains(err.Error(), "stream mirrors can not") { 11415 t.Fatalf("Expected error, got %+v", err) 11416 } 11417 11418 // Clear subjects. 11419 cfg.Subjects = nil 11420 11421 // Mirrored 11422 scfg := &nats.StreamConfig{ 11423 Name: "S1", 11424 Subjects: []string{"foo", "bar", "baz"}, 11425 } 11426 11427 // Create mirrored stream 11428 createStreamOk(scfg) 11429 11430 // Now create our mirror stream. 11431 createStreamOk(cfg) 11432 11433 // For now wait for the consumer state to register. 11434 time.Sleep(250 * time.Millisecond) 11435 11436 // Send 100 messages. 11437 for i := 0; i < 100; i++ { 11438 if _, err := js.Publish("foo", []byte("OK")); err != nil { 11439 t.Fatalf("Unexpected publish error: %v", err) 11440 } 11441 } 11442 11443 // Faster timeout since we loop below checking for condition. 11444 js2, err := nc.JetStream(nats.MaxWait(500 * time.Millisecond)) 11445 require_NoError(t, err) 11446 11447 checkFor(t, 5*time.Second, 250*time.Millisecond, func() error { 11448 si, err := js2.StreamInfo("M1") 11449 require_NoError(t, err) 11450 11451 if si.State.Msgs != 100 { 11452 return fmt.Errorf("Expected 100 msgs, got state: %+v", si.State) 11453 } 11454 return nil 11455 }) 11456 11457 // Purge the mirrored stream. 11458 if err := js.PurgeStream("S1"); err != nil { 11459 t.Fatalf("Unexpected purge error: %v", err) 11460 } 11461 // Send 50 more msgs now. 11462 for i := 0; i < 50; i++ { 11463 if _, err := js.Publish("bar", []byte("OK")); err != nil { 11464 t.Fatalf("Unexpected publish error: %v", err) 11465 } 11466 } 11467 11468 cfg = &nats.StreamConfig{ 11469 Name: "M2", 11470 Storage: nats.FileStorage, 11471 Mirror: &nats.StreamSource{Name: "S1"}, 11472 } 11473 11474 // Now create our second mirror stream. 11475 createStreamOk(cfg) 11476 11477 checkFor(t, 5*time.Second, 250*time.Millisecond, func() error { 11478 si, err := js2.StreamInfo("M2") 11479 require_NoError(t, err) 11480 11481 if si.State.Msgs != 50 { 11482 return fmt.Errorf("Expected 50 msgs, got state: %+v", si.State) 11483 } 11484 if si.State.FirstSeq != 101 { 11485 return fmt.Errorf("Expected start seq of 101, got state: %+v", si.State) 11486 } 11487 return nil 11488 }) 11489 11490 // Send 100 more msgs now. Should be 150 total, 101 first. 11491 for i := 0; i < 100; i++ { 11492 if _, err := js.Publish("baz", []byte("OK")); err != nil { 11493 t.Fatalf("Unexpected publish error: %v", err) 11494 } 11495 } 11496 11497 cfg = &nats.StreamConfig{ 11498 Name: "M3", 11499 Mirror: &nats.StreamSource{Name: "S1", OptStartSeq: 150}, 11500 } 11501 11502 createStreamOk(cfg) 11503 11504 checkFor(t, 5*time.Second, 250*time.Millisecond, func() error { 11505 si, err := js2.StreamInfo("M3") 11506 require_NoError(t, err) 11507 11508 if si.State.Msgs != 101 { 11509 return fmt.Errorf("Expected 101 msgs, got state: %+v", si.State) 11510 } 11511 if si.State.FirstSeq != 150 { 11512 return fmt.Errorf("Expected start seq of 150, got state: %+v", si.State) 11513 } 11514 return nil 11515 }) 11516 11517 // Make sure setting time works ok. 11518 start := time.Now().UTC().Add(-2 * time.Hour) 11519 cfg = &nats.StreamConfig{ 11520 Name: "M4", 11521 Mirror: &nats.StreamSource{Name: "S1", OptStartTime: &start}, 11522 } 11523 createStreamOk(cfg) 11524 11525 checkFor(t, 5*time.Second, 250*time.Millisecond, func() error { 11526 si, err := js2.StreamInfo("M4") 11527 require_NoError(t, err) 11528 11529 if si.State.Msgs != 150 { 11530 return fmt.Errorf("Expected 150 msgs, got state: %+v", si.State) 11531 } 11532 if si.State.FirstSeq != 101 { 11533 return fmt.Errorf("Expected start seq of 101, got state: %+v", si.State) 11534 } 11535 return nil 11536 }) 11537 11538 // Test subject filtering and transformation 11539 createStreamServerStreamConfig := func(cfg *StreamConfig, errToCheck uint16) { 11540 t.Helper() 11541 req, err := json.Marshal(cfg) 11542 require_NoError(t, err) 11543 11544 rm, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 11545 require_NoError(t, err) 11546 11547 var resp JSApiStreamCreateResponse 11548 if err := json.Unmarshal(rm.Data, &resp); err != nil { 11549 t.Fatalf("Unexpected error: %v", err) 11550 } 11551 11552 if errToCheck == 0 { 11553 if resp.Error != nil { 11554 t.Fatalf("Unexpected error: %+v", resp.Error) 11555 } 11556 } else { 11557 if resp.Error.ErrCode != errToCheck { 11558 t.Fatalf("Expected error %+v, got: %+v", errToCheck, resp.Error) 11559 } 11560 } 11561 } 11562 11563 // check for errors 11564 createStreamServerStreamConfig(&StreamConfig{ 11565 Name: "MBAD", 11566 Storage: FileStorage, 11567 Mirror: &StreamSource{Name: "S1", FilterSubject: "foo", SubjectTransforms: []SubjectTransformConfig{{Source: "foo", Destination: "foo3"}}}, 11568 }, ApiErrors[JSMirrorMultipleFiltersNotAllowed].ErrCode) 11569 11570 createStreamServerStreamConfig(&StreamConfig{ 11571 Name: "MBAD", 11572 Storage: FileStorage, 11573 Mirror: &StreamSource{Name: "S1", SubjectTransforms: []SubjectTransformConfig{{Source: ".*.", Destination: "foo3"}}}, 11574 }, ApiErrors[JSMirrorInvalidSubjectFilter].ErrCode) 11575 11576 createStreamServerStreamConfig(&StreamConfig{ 11577 Name: "MBAD", 11578 Storage: FileStorage, 11579 Mirror: &StreamSource{Name: "S1", SubjectTransforms: []SubjectTransformConfig{{Source: "*", Destination: "{{wildcard(2)}}"}}}, 11580 }, ApiErrors[JSStreamCreateErrF].ErrCode) 11581 11582 createStreamServerStreamConfig(&StreamConfig{ 11583 Name: "MBAD", 11584 Storage: FileStorage, 11585 Mirror: &StreamSource{Name: "S1", SubjectTransforms: []SubjectTransformConfig{{Source: "foo", Destination: ""}, {Source: "foo", Destination: "bar"}}}, 11586 }, ApiErrors[JSMirrorOverlappingSubjectFilters].ErrCode) 11587 11588 createStreamServerStreamConfig(&StreamConfig{ 11589 Name: "M5", 11590 Storage: FileStorage, 11591 Mirror: &StreamSource{Name: "S1", SubjectTransforms: []SubjectTransformConfig{{Source: "foo", Destination: "foo2"}}}, 11592 }, 0) 11593 11594 createStreamServerStreamConfig(&StreamConfig{ 11595 Name: "M6", 11596 Storage: FileStorage, 11597 Mirror: &StreamSource{Name: "S1", SubjectTransforms: []SubjectTransformConfig{{Source: "bar", Destination: "bar2"}, {Source: "baz", Destination: "baz2"}}}, 11598 }, 0) 11599 11600 // Send 100 messages on foo (there should already be 50 messages on bar and 100 on baz in the stream) 11601 for i := 0; i < 100; i++ { 11602 if _, err := js.Publish("foo", []byte("OK")); err != nil { 11603 t.Fatalf("Unexpected publish error: %v", err) 11604 } 11605 } 11606 11607 var f = func(streamName string, subject string, subjectNumMsgs uint64, streamNumMsg uint64, firstSeq uint64, lastSeq uint64) func() error { 11608 return func() error { 11609 si, err := js2.StreamInfo(streamName, &nats.StreamInfoRequest{SubjectsFilter: subject}) 11610 require_NoError(t, err) 11611 if ss, ok := si.State.Subjects[subject]; !ok { 11612 return fmt.Errorf("expected messages with the transformed subject %s", subject) 11613 } else { 11614 if ss != subjectNumMsgs { 11615 return fmt.Errorf("expected %d messages on the transformed subject %s but got %d", subjectNumMsgs, subject, ss) 11616 } 11617 } 11618 if si.State.Msgs != streamNumMsg { 11619 return fmt.Errorf("expected %d stream messages, got state: %+v", streamNumMsg, si.State) 11620 } 11621 if si.State.FirstSeq != firstSeq || si.State.LastSeq != lastSeq { 11622 return fmt.Errorf("expected first sequence=%d and last sequence=%d, but got state: %+v", firstSeq, lastSeq, si.State) 11623 } 11624 return nil 11625 } 11626 } 11627 11628 checkFor(t, 10*time.Second, 500*time.Millisecond, f("M5", "foo2", 100, 100, 251, 350)) 11629 checkFor(t, 10*time.Second, 500*time.Millisecond, f("M6", "bar2", 50, 150, 101, 250)) 11630 checkFor(t, 10*time.Second, 500*time.Millisecond, f("M6", "baz2", 100, 150, 101, 250)) 11631 11632 } 11633 11634 func TestJetStreamMirrorUpdatePreventsSubjects(t *testing.T) { 11635 s := RunBasicJetStreamServer(t) 11636 defer s.Shutdown() 11637 11638 // Client for API requests. 11639 nc, js := jsClientConnect(t, s) 11640 defer nc.Close() 11641 11642 _, err := js.AddStream(&nats.StreamConfig{Name: "ORIGINAL"}) 11643 require_NoError(t, err) 11644 11645 _, err = js.AddStream(&nats.StreamConfig{Name: "MIRROR", Mirror: &nats.StreamSource{Name: "ORIGINAL"}}) 11646 require_NoError(t, err) 11647 11648 _, err = js.UpdateStream(&nats.StreamConfig{Name: "MIRROR", Mirror: &nats.StreamSource{Name: "ORIGINAL"}, Subjects: []string{"x"}}) 11649 if err == nil || err.Error() != "nats: stream mirrors can not contain subjects" { 11650 t.Fatalf("Expected to not be able to put subjects on a stream, got: %+v", err) 11651 } 11652 } 11653 11654 func TestJetStreamSourceBasics(t *testing.T) { 11655 s := RunBasicJetStreamServer(t) 11656 defer s.Shutdown() 11657 11658 // Client for API requests. 11659 nc, js := jsClientConnect(t, s) 11660 defer nc.Close() 11661 11662 createStream := func(cfg *StreamConfig) { 11663 t.Helper() 11664 req, err := json.Marshal(cfg) 11665 require_NoError(t, err) 11666 11667 rm, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 11668 require_NoError(t, err) 11669 11670 var resp JSApiStreamCreateResponse 11671 if err := json.Unmarshal(rm.Data, &resp); err != nil { 11672 t.Fatalf("Unexpected error: %v", err) 11673 } 11674 if resp.Error != nil { 11675 t.Fatalf("Unexpected error: %+v", resp.Error) 11676 } 11677 } 11678 11679 if _, err := js.AddStream(&nats.StreamConfig{Name: "test", Sources: []*nats.StreamSource{{Name: ""}}}); err.Error() == "source stream name is invalid" { 11680 t.Fatal("Expected a source stream name is invalid error") 11681 } 11682 11683 for _, sname := range []string{"foo", "bar", "baz"} { 11684 if _, err := js.AddStream(&nats.StreamConfig{Name: sname}); err != nil { 11685 t.Fatalf("Unexpected error: %v", err) 11686 } 11687 } 11688 sendBatch := func(subject string, n int) { 11689 for i := 0; i < n; i++ { 11690 if _, err := js.Publish(subject, []byte("OK")); err != nil { 11691 t.Fatalf("Unexpected publish error: %v", err) 11692 } 11693 } 11694 } 11695 // Populate each one. 11696 sendBatch("foo", 10) 11697 sendBatch("bar", 15) 11698 sendBatch("baz", 25) 11699 11700 cfg := &StreamConfig{ 11701 Name: "MS", 11702 Storage: FileStorage, 11703 Sources: []*StreamSource{ 11704 {Name: "foo", SubjectTransforms: []SubjectTransformConfig{{Source: ">", Destination: "foo2.>"}}}, 11705 {Name: "bar"}, 11706 {Name: "baz"}, 11707 }, 11708 } 11709 11710 createStream(cfg) 11711 11712 // Faster timeout since we loop below checking for condition. 11713 js2, err := nc.JetStream(nats.MaxWait(250 * time.Millisecond)) 11714 require_NoError(t, err) 11715 11716 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11717 si, err := js2.StreamInfo("MS") 11718 require_NoError(t, err) 11719 11720 if si.State.Msgs != 50 { 11721 return fmt.Errorf("Expected 50 msgs, got state: %+v", si.State) 11722 } 11723 return nil 11724 }) 11725 11726 ss, err := js.SubscribeSync("foo2.foo", nats.BindStream("MS")) 11727 require_NoError(t, err) 11728 // we must have at least one message on the transformed subject name (ie no timeout) 11729 _, err = ss.NextMsg(time.Millisecond) 11730 require_NoError(t, err) 11731 ss.Drain() 11732 11733 // Test Source Updates 11734 ncfg := &nats.StreamConfig{ 11735 Name: "MS", 11736 Sources: []*nats.StreamSource{ 11737 // Keep foo, bar, remove baz, add dlc 11738 {Name: "foo"}, 11739 {Name: "bar"}, 11740 {Name: "dlc"}, 11741 }, 11742 } 11743 if _, err := js.UpdateStream(ncfg); err != nil { 11744 t.Fatalf("Unexpected error: %v", err) 11745 } 11746 11747 // Test optional start times, filtered subjects etc. 11748 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"dlc", "rip", "jnm"}}); err != nil { 11749 t.Fatalf("Unexpected error: %v", err) 11750 } 11751 sendBatch("dlc", 20) 11752 sendBatch("rip", 20) 11753 sendBatch("dlc", 10) 11754 sendBatch("jnm", 10) 11755 11756 cfg = &StreamConfig{ 11757 Name: "FMS", 11758 Storage: FileStorage, 11759 Sources: []*StreamSource{ 11760 {Name: "TEST", OptStartSeq: 26}, 11761 }, 11762 } 11763 createStream(cfg) 11764 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11765 si, err := js2.StreamInfo("FMS") 11766 require_NoError(t, err) 11767 if si.State.Msgs != 35 { 11768 return fmt.Errorf("Expected 35 msgs, got state: %+v", si.State) 11769 } 11770 return nil 11771 }) 11772 // Double check first starting. 11773 m, err := js.GetMsg("FMS", 1) 11774 require_NoError(t, err) 11775 if shdr := m.Header.Get(JSStreamSource); shdr == _EMPTY_ { 11776 t.Fatalf("Expected a header, got none") 11777 } else if _, _, sseq := streamAndSeq(shdr); sseq != 26 { 11778 t.Fatalf("Expected header sequence of 26, got %d", sseq) 11779 } 11780 11781 // Test Filters 11782 cfg = &StreamConfig{ 11783 Name: "FMS2", 11784 Storage: FileStorage, 11785 Sources: []*StreamSource{ 11786 {Name: "TEST", OptStartSeq: 11, SubjectTransforms: []SubjectTransformConfig{{Source: "dlc", Destination: "dlc2"}}}, 11787 }, 11788 } 11789 createStream(cfg) 11790 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11791 si, err := js2.StreamInfo("FMS2") 11792 require_NoError(t, err) 11793 if si.State.Msgs != 20 { 11794 return fmt.Errorf("Expected 20 msgs, got state: %+v", si.State) 11795 } 11796 return nil 11797 }) 11798 11799 // Double check first starting. 11800 if m, err = js.GetMsg("FMS2", 1); err != nil { 11801 t.Fatalf("Unexpected error: %v", err) 11802 } 11803 if shdr := m.Header.Get(JSStreamSource); shdr == _EMPTY_ { 11804 t.Fatalf("Expected a header, got none") 11805 } else if _, _, sseq := streamAndSeq(shdr); sseq != 11 { 11806 t.Fatalf("Expected header sequence of 11, got %d", sseq) 11807 } 11808 if m.Subject != "dlc2" { 11809 t.Fatalf("Expected transformed subject dlc2, but got %s instead", m.Subject) 11810 } 11811 11812 // Test Filters 11813 cfg = &StreamConfig{ 11814 Name: "FMS3", 11815 Storage: FileStorage, 11816 Sources: []*StreamSource{ 11817 {Name: "TEST", SubjectTransforms: []SubjectTransformConfig{{Source: "dlc", Destination: "dlc2"}, {Source: "rip", Destination: ""}}}, 11818 }, 11819 } 11820 createStream(cfg) 11821 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11822 si, err := js2.StreamInfo("FMS3") 11823 require_NoError(t, err) 11824 if si.State.Msgs != 50 { 11825 return fmt.Errorf("Expected 50 msgs, got state: %+v", si.State) 11826 } 11827 return nil 11828 }) 11829 11830 // Double check first message 11831 if m, err = js.GetMsg("FMS3", 1); err != nil { 11832 t.Fatalf("Unexpected error: %v", err) 11833 } 11834 if shdr := m.Header.Get(JSStreamSource); shdr == _EMPTY_ { 11835 t.Fatalf("Expected a header, got none") 11836 } else if m.Subject != "dlc2" { 11837 t.Fatalf("Expected subject 'dlc2' and got %s", m.Subject) 11838 } 11839 11840 // Double check first message with the other subject 11841 if m, err = js.GetMsg("FMS3", 21); err != nil { 11842 t.Fatalf("Unexpected error: %v", err) 11843 } 11844 if shdr := m.Header.Get(JSStreamSource); shdr == _EMPTY_ { 11845 t.Fatalf("Expected a header, got none") 11846 } else if m.Subject != "rip" { 11847 t.Fatalf("Expected subject 'rip' and got %s", m.Subject) 11848 } 11849 11850 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11851 si, err := js2.StreamInfo("FMS3") 11852 require_NoError(t, err) 11853 if si.State.Subjects["jnm"] != 0 { 11854 return fmt.Errorf("Unexpected messages from the source found") 11855 } 11856 return nil 11857 }) 11858 11859 // pre 2.10 backwards compatibility 11860 transformConfig := nats.SubjectTransformConfig{Source: "B.*", Destination: "A.{{Wildcard(1)}}"} 11861 aConfig := nats.StreamConfig{Name: "A", Subjects: []string{"B.*"}, SubjectTransform: &transformConfig} 11862 if _, err := js.AddStream(&aConfig); err != nil { 11863 t.Fatalf("Unexpected error: %v", err) 11864 } 11865 11866 sendBatch("B.A", 1) 11867 sendBatch("B.B", 1) 11868 bConfig := nats.StreamConfig{Name: "B", Subjects: []string{"A.*"}} 11869 11870 if _, err := js.AddStream(&bConfig); err != nil { 11871 t.Fatalf("Unexpected error: %v", err) 11872 } 11873 11874 // fake a message that would have been sourced with pre 2.10 11875 msg := nats.NewMsg("A.A") 11876 // pre 2.10 header format just stream name and sequence number 11877 msg.Header.Set(JSStreamSource, "A 1") 11878 msg.Data = []byte("OK") 11879 11880 if _, err := js.PublishMsg(msg); err != nil { 11881 t.Fatalf("Unexpected publish error: %v", err) 11882 } 11883 11884 bConfig.Sources = []*nats.StreamSource{{Name: "A"}} 11885 if _, err := js.UpdateStream(&bConfig); err != nil { 11886 t.Fatalf("Unexpected error: %v", err) 11887 } 11888 11889 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 11890 si, err := js2.StreamInfo("B") 11891 require_NoError(t, err) 11892 if si.State.Msgs != 2 { 11893 return fmt.Errorf("Expected 2 msgs, got state: %+v", si.State) 11894 } 11895 return nil 11896 }) 11897 } 11898 11899 func TestJetStreamSourceWorkingQueueWithLimit(t *testing.T) { 11900 s := RunBasicJetStreamServer(t) 11901 defer s.Shutdown() 11902 11903 // Client for API requests. 11904 nc, js := jsClientConnect(t, s) 11905 defer nc.Close() 11906 11907 _, err := js.AddStream(&nats.StreamConfig{Name: "test", Subjects: []string{"test"}}) 11908 require_NoError(t, err) 11909 11910 _, err = js.AddStream(&nats.StreamConfig{Name: "wq", MaxMsgs: 100, Discard: nats.DiscardNew, Retention: nats.WorkQueuePolicy, 11911 Sources: []*nats.StreamSource{{Name: "test"}}}) 11912 require_NoError(t, err) 11913 11914 sendBatch := func(subject string, n int) { 11915 for i := 0; i < n; i++ { 11916 _, err = js.Publish(subject, []byte("OK")) 11917 require_NoError(t, err) 11918 } 11919 } 11920 // Populate each one. 11921 sendBatch("test", 300) 11922 11923 checkFor(t, 3*time.Second, 250*time.Millisecond, func() error { 11924 si, err := js.StreamInfo("wq") 11925 require_NoError(t, err) 11926 if si.State.Msgs != 100 { 11927 return fmt.Errorf("Expected 100 msgs, got state: %+v", si.State) 11928 } 11929 return nil 11930 }) 11931 11932 _, err = js.AddConsumer("wq", &nats.ConsumerConfig{Durable: "wqc", FilterSubject: "test", AckPolicy: nats.AckExplicitPolicy}) 11933 require_NoError(t, err) 11934 11935 ss, err := js.PullSubscribe("test", "wqc", nats.Bind("wq", "wqc")) 11936 require_NoError(t, err) 11937 // we must have at least one message on the transformed subject name (ie no timeout) 11938 f := func(done chan bool) { 11939 for i := 0; i < 300; i++ { 11940 m, err := ss.Fetch(1, nats.MaxWait(3*time.Second)) 11941 require_NoError(t, err) 11942 time.Sleep(11 * time.Millisecond) 11943 err = m[0].Ack() 11944 require_NoError(t, err) 11945 } 11946 done <- true 11947 } 11948 11949 var doneChan = make(chan bool) 11950 go f(doneChan) 11951 11952 checkFor(t, 6*time.Second, 100*time.Millisecond, func() error { 11953 si, err := js.StreamInfo("wq") 11954 require_NoError(t, err) 11955 if si.State.Msgs > 0 && si.State.Msgs <= 100 { 11956 return fmt.Errorf("Expected 0 msgs, got: %d", si.State.Msgs) 11957 } else if si.State.Msgs > 100 { 11958 t.Fatalf("Got more than our 100 message limit: %+v", si.State) 11959 } 11960 return nil 11961 }) 11962 11963 select { 11964 case <-doneChan: 11965 ss.Drain() 11966 case <-time.After(5 * time.Second): 11967 t.Fatalf("Did not receive completion signal") 11968 } 11969 } 11970 11971 func TestJetStreamStreamSourceFromKV(t *testing.T) { 11972 s := RunBasicJetStreamServer(t) 11973 defer s.Shutdown() 11974 11975 // Client for API reuqests. 11976 nc, js := jsClientConnect(t, s) 11977 defer nc.Close() 11978 11979 // Create a kv store 11980 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "test"}) 11981 require_NoError(t, err) 11982 11983 // Create a stream with a source from the kv store 11984 _, err = js.AddStream(&nats.StreamConfig{Name: "test", Retention: nats.InterestPolicy, Sources: []*nats.StreamSource{{Name: "KV_" + kv.Bucket()}}}) 11985 require_NoError(t, err) 11986 11987 // Create a interested consumer 11988 _, err = js.AddConsumer("test", &nats.ConsumerConfig{Durable: "durable", AckPolicy: nats.AckExplicitPolicy}) 11989 require_NoError(t, err) 11990 11991 ss, err := js.PullSubscribe("", "", nats.Bind("test", "durable")) 11992 require_NoError(t, err) 11993 11994 rev1, err := kv.Create("key", []byte("value1")) 11995 require_NoError(t, err) 11996 11997 m, err := ss.Fetch(1, nats.MaxWait(500*time.Millisecond)) 11998 require_NoError(t, err) 11999 require_NoError(t, m[0].Ack()) 12000 if string(m[0].Data) != "value1" { 12001 t.Fatalf("Expected value1, got %s", m[0].Data) 12002 } 12003 12004 rev2, err := kv.Update("key", []byte("value2"), rev1) 12005 require_NoError(t, err) 12006 12007 _, err = kv.Update("key", []byte("value3"), rev2) 12008 require_NoError(t, err) 12009 12010 m, err = ss.Fetch(1, nats.MaxWait(500*time.Millisecond)) 12011 require_NoError(t, err) 12012 require_NoError(t, m[0].Ack()) 12013 if string(m[0].Data) != "value2" { 12014 t.Fatalf("Expected value2, got %s", m[0].Data) 12015 } 12016 12017 m, err = ss.Fetch(1, nats.MaxWait(500*time.Millisecond)) 12018 require_NoError(t, err) 12019 require_NoError(t, m[0].Ack()) 12020 if string(m[0].Data) != "value3" { 12021 t.Fatalf("Expected value3, got %s", m[0].Data) 12022 } 12023 } 12024 12025 func TestJetStreamInputTransform(t *testing.T) { 12026 s := RunBasicJetStreamServer(t) 12027 defer s.Shutdown() 12028 12029 // Client for API requests. 12030 nc, js := jsClientConnect(t, s) 12031 defer nc.Close() 12032 12033 createStream := func(cfg *StreamConfig) { 12034 t.Helper() 12035 req, err := json.Marshal(cfg) 12036 require_NoError(t, err) 12037 12038 rm, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 12039 require_NoError(t, err) 12040 12041 var resp JSApiStreamCreateResponse 12042 if err := json.Unmarshal(rm.Data, &resp); err != nil { 12043 t.Fatalf("Unexpected error: %v", err) 12044 } 12045 if resp.Error != nil { 12046 t.Fatalf("Unexpected error: %+v", resp.Error) 12047 } 12048 } 12049 12050 createStream(&StreamConfig{Name: "T1", Subjects: []string{"foo"}, SubjectTransform: &SubjectTransformConfig{Source: ">", Destination: "transformed.>"}, Storage: MemoryStorage}) 12051 12052 // publish a message 12053 if _, err := js.Publish("foo", []byte("OK")); err != nil { 12054 t.Fatalf("Unexpected publish error: %v", err) 12055 } 12056 12057 m, err := js.GetMsg("T1", 1) 12058 require_NoError(t, err) 12059 12060 if m.Subject != "transformed.foo" { 12061 t.Fatalf("Expected message subject transformed.foo, got %s", m.Subject) 12062 } 12063 } 12064 12065 func TestJetStreamOperatorAccounts(t *testing.T) { 12066 s, _ := RunServerWithConfig("./configs/js-op.conf") 12067 if config := s.JetStreamConfig(); config != nil { 12068 defer removeDir(t, config.StoreDir) 12069 } 12070 defer s.Shutdown() 12071 12072 nc, js := jsClientConnect(t, s, nats.UserCredentials("./configs/one.creds")) 12073 defer nc.Close() 12074 12075 if _, err := js.AddStream(&nats.StreamConfig{Name: "TEST"}); err != nil { 12076 t.Fatalf("Unexpected error: %v", err) 12077 } 12078 12079 toSend := 100 12080 for i := 0; i < toSend; i++ { 12081 if _, err := js.Publish("TEST", []byte("OK")); err != nil { 12082 t.Fatalf("Unexpected publish error: %v", err) 12083 } 12084 } 12085 12086 // Close our user for account one. 12087 nc.Close() 12088 12089 // Restart the server. 12090 s.Shutdown() 12091 s, _ = RunServerWithConfig("./configs/js-op.conf") 12092 defer s.Shutdown() 12093 12094 jsz, err := s.Jsz(nil) 12095 require_NoError(t, err) 12096 12097 if jsz.Streams != 1 { 12098 t.Fatalf("Expected jsz to report our stream on restart") 12099 } 12100 if jsz.Messages != uint64(toSend) { 12101 t.Fatalf("Expected jsz to report our %d messages on restart, got %d", toSend, jsz.Messages) 12102 } 12103 } 12104 12105 func TestJetStreamServerDomainBadConfig(t *testing.T) { 12106 shouldFail := func(domain string) { 12107 t.Helper() 12108 opts := DefaultTestOptions 12109 opts.JetStreamDomain = domain 12110 if err := validateOptions(&opts); err == nil || !strings.Contains(err.Error(), "invalid domain name") { 12111 t.Fatalf("Expected bad domain error, got %v", err) 12112 } 12113 } 12114 12115 shouldFail("HU..B") 12116 shouldFail("HU B") 12117 shouldFail(" ") 12118 shouldFail("\t") 12119 shouldFail("CORE.") 12120 shouldFail(".CORE") 12121 shouldFail("C.*.O. RE") 12122 shouldFail("C.ORE") 12123 } 12124 12125 func TestJetStreamServerDomainConfig(t *testing.T) { 12126 conf := createConfFile(t, []byte(fmt.Sprintf(` 12127 listen: 127.0.0.1:-1 12128 jetstream: {domain: "HUB", store_dir: %q} 12129 `, t.TempDir()))) 12130 12131 s, _ := RunServerWithConfig(conf) 12132 defer s.Shutdown() 12133 12134 if !s.JetStreamEnabled() { 12135 t.Fatalf("Expected JetStream to be enabled") 12136 } 12137 12138 config := s.JetStreamConfig() 12139 if config.Domain != "HUB" { 12140 t.Fatalf("Expected %q as domain name, got %q", "HUB", config.Domain) 12141 } 12142 } 12143 12144 func TestJetStreamServerDomainConfigButDisabled(t *testing.T) { 12145 conf := createConfFile(t, []byte(` 12146 listen: 127.0.0.1:-1 12147 jetstream: {domain: "HUB", enabled: false} 12148 `)) 12149 12150 s, _ := RunServerWithConfig(conf) 12151 defer s.Shutdown() 12152 12153 if s.JetStreamEnabled() { 12154 t.Fatalf("Expected JetStream NOT to be enabled") 12155 } 12156 12157 opts := s.getOpts() 12158 if opts.JetStreamDomain != "HUB" { 12159 t.Fatalf("Expected %q as opts domain name, got %q", "HUB", opts.JetStreamDomain) 12160 } 12161 } 12162 12163 func TestJetStreamDomainInPubAck(t *testing.T) { 12164 conf := createConfFile(t, []byte(fmt.Sprintf(` 12165 listen: 127.0.0.1:-1 12166 jetstream: {domain: "HUB", store_dir: %q} 12167 `, t.TempDir()))) 12168 12169 s, _ := RunServerWithConfig(conf) 12170 defer s.Shutdown() 12171 12172 nc, js := jsClientConnect(t, s) 12173 defer nc.Close() 12174 12175 cfg := &nats.StreamConfig{ 12176 Name: "TEST", 12177 Storage: nats.MemoryStorage, 12178 Subjects: []string{"foo"}, 12179 } 12180 if _, err := js.AddStream(cfg); err != nil { 12181 t.Fatalf("Unexpected error: %v", err) 12182 } 12183 12184 // Check by hand for now til it makes its way into Go client. 12185 am, err := nc.Request("foo", nil, time.Second) 12186 require_NoError(t, err) 12187 var pa PubAck 12188 json.Unmarshal(am.Data, &pa) 12189 if pa.Domain != "HUB" { 12190 t.Fatalf("Expected PubAck to have domain of %q, got %q", "HUB", pa.Domain) 12191 } 12192 } 12193 12194 // Issue #2213 12195 func TestJetStreamDirectConsumersBeingReported(t *testing.T) { 12196 s := RunBasicJetStreamServer(t) 12197 defer s.Shutdown() 12198 12199 // Client for API requests. 12200 nc, js := jsClientConnect(t, s) 12201 defer nc.Close() 12202 12203 _, err := js.AddStream(&nats.StreamConfig{ 12204 Name: "TEST", 12205 Subjects: []string{"foo"}, 12206 }) 12207 require_NoError(t, err) 12208 12209 _, err = js.AddStream(&nats.StreamConfig{ 12210 Name: "S", 12211 Sources: []*nats.StreamSource{{ 12212 Name: "TEST", 12213 }}, 12214 }) 12215 require_NoError(t, err) 12216 12217 if _, err = js.Publish("foo", nil); err != nil { 12218 t.Fatalf("Unexpected publish error: %v", err) 12219 } 12220 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 12221 si, err := js.StreamInfo("S") 12222 if err != nil { 12223 return fmt.Errorf("Could not get stream info: %v", err) 12224 } 12225 if si.State.Msgs != 1 { 12226 return fmt.Errorf("Expected 1 msg, got state: %+v", si.State) 12227 } 12228 return nil 12229 }) 12230 12231 si, err := js.StreamInfo("TEST") 12232 require_NoError(t, err) 12233 12234 // Direct consumers should not be reported 12235 if si.State.Consumers != 0 { 12236 t.Fatalf("Did not expect any consumers, got %d", si.State.Consumers) 12237 } 12238 12239 // Now check for consumer in consumer names list. 12240 var names []string 12241 for name := range js.ConsumerNames("TEST") { 12242 names = append(names, name) 12243 } 12244 if len(names) != 0 { 12245 t.Fatalf("Expected no consumers but got %+v", names) 12246 } 12247 12248 // Now check detailed list. 12249 var cis []*nats.ConsumerInfo 12250 for ci := range js.ConsumersInfo("TEST") { 12251 cis = append(cis, ci) 12252 } 12253 if len(cis) != 0 { 12254 t.Fatalf("Expected no consumers but got %+v", cis) 12255 } 12256 } 12257 12258 // https://github.com/nats-io/nats-server/issues/2290 12259 func TestJetStreamTemplatedErrorsBug(t *testing.T) { 12260 s := RunBasicJetStreamServer(t) 12261 defer s.Shutdown() 12262 12263 // Client for API requests. 12264 nc, js := jsClientConnect(t, s) 12265 defer nc.Close() 12266 12267 _, err := js.AddStream(&nats.StreamConfig{ 12268 Name: "TEST", 12269 Subjects: []string{"foo"}, 12270 }) 12271 require_NoError(t, err) 12272 12273 _, err = js.PullSubscribe("foo", "") 12274 if err != nil && strings.Contains(err.Error(), "{err}") { 12275 t.Fatalf("Error is not filled in: %v", err) 12276 } 12277 } 12278 12279 func TestJetStreamServerEncryption(t *testing.T) { 12280 cases := []struct { 12281 name string 12282 cstr string 12283 cipher StoreCipher 12284 }{ 12285 {"Default", _EMPTY_, ChaCha}, 12286 {"ChaCha", ", cipher: chacha", ChaCha}, 12287 {"AES", ", cipher: aes", AES}, 12288 } 12289 12290 for _, c := range cases { 12291 t.Run(c.name, func(t *testing.T) { 12292 tmpl := ` 12293 server_name: S22 12294 listen: 127.0.0.1:-1 12295 jetstream: {key: $JS_KEY, store_dir: '%s' %s} 12296 ` 12297 storeDir := t.TempDir() 12298 12299 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, storeDir, c.cstr))) 12300 12301 os.Setenv("JS_KEY", "s3cr3t!!") 12302 defer os.Unsetenv("JS_KEY") 12303 12304 s, _ := RunServerWithConfig(conf) 12305 defer s.Shutdown() 12306 12307 config := s.JetStreamConfig() 12308 if config == nil { 12309 t.Fatalf("Expected config but got none") 12310 } 12311 defer removeDir(t, config.StoreDir) 12312 12313 // Client based API 12314 nc, js := jsClientConnect(t, s) 12315 defer nc.Close() 12316 12317 cfg := &nats.StreamConfig{ 12318 Name: "TEST", 12319 Subjects: []string{"foo", "bar", "baz"}, 12320 } 12321 if _, err := js.AddStream(cfg); err != nil { 12322 t.Fatalf("Unexpected error: %v", err) 12323 } 12324 12325 msg := []byte("ENCRYPTED PAYLOAD!!") 12326 sendMsg := func(subj string) { 12327 t.Helper() 12328 if _, err := js.Publish(subj, msg); err != nil { 12329 t.Fatalf("Unexpected publish error: %v", err) 12330 } 12331 } 12332 // Send 10 msgs 12333 for i := 0; i < 10; i++ { 12334 sendMsg("foo") 12335 } 12336 12337 // Now create a consumer. 12338 sub, err := js.PullSubscribe("foo", "dlc") 12339 if err != nil { 12340 t.Fatalf("Unexpected error: %v", err) 12341 } 12342 for i, m := range fetchMsgs(t, sub, 10, 5*time.Second) { 12343 if i < 5 { 12344 m.AckSync() 12345 } 12346 } 12347 12348 // Grab our state to compare after restart. 12349 si, _ := js.StreamInfo("TEST") 12350 ci, _ := js.ConsumerInfo("TEST", "dlc") 12351 12352 // Quick check to make sure everything not just plaintext still. 12353 sdir := filepath.Join(config.StoreDir, "$G", "streams", "TEST") 12354 // Make sure we can not find any plaintext strings in the target file. 12355 checkFor := func(fn string, strs ...string) { 12356 t.Helper() 12357 data, err := os.ReadFile(fn) 12358 if err != nil { 12359 t.Fatalf("Unexpected error: %v", err) 12360 } 12361 for _, str := range strs { 12362 if bytes.Contains(data, []byte(str)) { 12363 t.Fatalf("Found %q in body of file contents", str) 12364 } 12365 } 12366 } 12367 checkKeyFile := func(fn string) { 12368 t.Helper() 12369 if _, err := os.Stat(fn); err != nil { 12370 t.Fatalf("Expected a key file at %q", fn) 12371 } 12372 } 12373 12374 // Check stream meta. 12375 checkEncrypted := func() { 12376 t.Helper() 12377 checkKeyFile(filepath.Join(sdir, JetStreamMetaFileKey)) 12378 checkFor(filepath.Join(sdir, JetStreamMetaFile), "TEST", "foo", "bar", "baz", "max_msgs", "max_bytes") 12379 // Check a message block. 12380 checkKeyFile(filepath.Join(sdir, "msgs", "1.key")) 12381 checkFor(filepath.Join(sdir, "msgs", "1.blk"), "ENCRYPTED PAYLOAD!!", "foo", "bar", "baz") 12382 12383 // Check consumer meta and state. 12384 checkKeyFile(filepath.Join(sdir, "obs", "dlc", JetStreamMetaFileKey)) 12385 checkFor(filepath.Join(sdir, "obs", "dlc", JetStreamMetaFile), "TEST", "dlc", "foo", "bar", "baz", "max_msgs", "ack_policy") 12386 // Load and see if we can parse the consumer state. 12387 state, err := os.ReadFile(filepath.Join(sdir, "obs", "dlc", "o.dat")) 12388 require_NoError(t, err) 12389 12390 if _, err := decodeConsumerState(state); err == nil { 12391 t.Fatalf("Expected decoding consumer state to fail") 12392 } 12393 } 12394 12395 // Stop current 12396 s.Shutdown() 12397 12398 checkEncrypted() 12399 12400 // Restart. 12401 s, _ = RunServerWithConfig(conf) 12402 defer s.Shutdown() 12403 12404 // Connect again. 12405 nc, js = jsClientConnect(t, s) 12406 defer nc.Close() 12407 12408 si2, err := js.StreamInfo("TEST") 12409 require_NoError(t, err) 12410 12411 if !reflect.DeepEqual(si, si2) { 12412 t.Fatalf("Stream infos did not match\n%+v\nvs\n%+v", si, si2) 12413 } 12414 12415 ci2, _ := js.ConsumerInfo("TEST", "dlc") 12416 // Consumer create times can be slightly off after restore from disk. 12417 now := time.Now() 12418 ci.Created, ci2.Created = now, now 12419 ci.Delivered.Last, ci2.Delivered.Last = nil, nil 12420 ci.AckFloor.Last, ci2.AckFloor.Last = nil, nil 12421 // Also clusters will be different. 12422 ci.Cluster, ci2.Cluster = nil, nil 12423 if !reflect.DeepEqual(ci, ci2) { 12424 t.Fatalf("Consumer infos did not match\n%+v\nvs\n%+v", ci, ci2) 12425 } 12426 12427 // Send 10 more msgs 12428 for i := 0; i < 10; i++ { 12429 sendMsg("foo") 12430 } 12431 if si, err = js.StreamInfo("TEST"); err != nil { 12432 t.Fatalf("Unexpected error: %v", err) 12433 } 12434 if si.State.Msgs != 20 { 12435 t.Fatalf("Expected 20 msgs total, got %d", si.State.Msgs) 12436 } 12437 12438 // Now test snapshots etc. 12439 acc := s.GlobalAccount() 12440 mset, err := acc.lookupStream("TEST") 12441 require_NoError(t, err) 12442 scfg := mset.config() 12443 sr, err := mset.snapshot(5*time.Second, false, true) 12444 if err != nil { 12445 t.Fatalf("Error getting snapshot: %v", err) 12446 } 12447 snapshot, err := io.ReadAll(sr.Reader) 12448 if err != nil { 12449 t.Fatalf("Error reading snapshot") 12450 } 12451 12452 // Run new server w/o encryption. Make sure we can restore properly (meaning encryption was stripped etc). 12453 ns := RunBasicJetStreamServer(t) 12454 defer ns.Shutdown() 12455 12456 nacc := ns.GlobalAccount() 12457 r := bytes.NewReader(snapshot) 12458 mset, err = nacc.RestoreStream(&scfg, r) 12459 require_NoError(t, err) 12460 ss := mset.store.State() 12461 if ss.Msgs != si.State.Msgs || ss.FirstSeq != si.State.FirstSeq || ss.LastSeq != si.State.LastSeq { 12462 t.Fatalf("Stream states do not match: %+v vs %+v", ss, si.State) 12463 } 12464 12465 // Now restore to our encrypted server as well. 12466 if err := js.DeleteStream("TEST"); err != nil { 12467 t.Fatalf("Unexpected error: %v", err) 12468 } 12469 12470 acc = s.GlobalAccount() 12471 r.Reset(snapshot) 12472 mset, err = acc.RestoreStream(&scfg, r) 12473 require_NoError(t, err) 12474 ss = mset.store.State() 12475 if ss.Msgs != si.State.Msgs || ss.FirstSeq != si.State.FirstSeq || ss.LastSeq != si.State.LastSeq { 12476 t.Fatalf("Stream states do not match: %+v vs %+v", ss, si.State) 12477 } 12478 12479 // Check that all is encrypted like above since we know we need to convert since snapshots always plaintext. 12480 checkEncrypted() 12481 }) 12482 } 12483 } 12484 12485 // User report of bug. 12486 func TestJetStreamConsumerBadNumPending(t *testing.T) { 12487 s := RunBasicJetStreamServer(t) 12488 defer s.Shutdown() 12489 12490 // Client for API requests. 12491 nc, js := jsClientConnect(t, s) 12492 defer nc.Close() 12493 12494 _, err := js.AddStream(&nats.StreamConfig{ 12495 Name: "ORDERS", 12496 Subjects: []string{"orders.*"}, 12497 }) 12498 require_NoError(t, err) 12499 12500 newOrders := func(n int) { 12501 // Queue up new orders. 12502 for i := 0; i < n; i++ { 12503 js.Publish("orders.created", []byte("NEW")) 12504 } 12505 } 12506 12507 newOrders(10) 12508 12509 // Create to subscribers. 12510 process := func(m *nats.Msg) { 12511 js.Publish("orders.approved", []byte("APPROVED")) 12512 } 12513 12514 op, err := js.Subscribe("orders.created", process) 12515 require_NoError(t, err) 12516 12517 defer op.Unsubscribe() 12518 12519 mon, err := js.SubscribeSync("orders.*") 12520 require_NoError(t, err) 12521 12522 defer mon.Unsubscribe() 12523 12524 waitForMsgs := func(n uint64) { 12525 t.Helper() 12526 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 12527 si, err := js.StreamInfo("ORDERS") 12528 if err != nil { 12529 t.Fatalf("Unexpected error: %v", err) 12530 } 12531 if si.State.Msgs != n { 12532 return fmt.Errorf("Expected %d msgs, got state: %+v", n, si.State) 12533 } 12534 return nil 12535 }) 12536 } 12537 12538 checkForNoPending := func(sub *nats.Subscription) { 12539 t.Helper() 12540 if ci, err := sub.ConsumerInfo(); err != nil || ci == nil || ci.NumPending != 0 { 12541 if ci != nil && ci.NumPending != 0 { 12542 t.Fatalf("Bad consumer NumPending, expected 0 but got %d", ci.NumPending) 12543 } else { 12544 t.Fatalf("Bad consumer info: %+v", ci) 12545 } 12546 } 12547 } 12548 12549 waitForMsgs(20) 12550 checkForNoPending(op) 12551 checkForNoPending(mon) 12552 12553 newOrders(10) 12554 12555 waitForMsgs(40) 12556 checkForNoPending(op) 12557 checkForNoPending(mon) 12558 } 12559 12560 func TestJetStreamDeliverLastPerSubject(t *testing.T) { 12561 for _, st := range []StorageType{FileStorage, MemoryStorage} { 12562 t.Run(st.String(), func(t *testing.T) { 12563 s := RunBasicJetStreamServer(t) 12564 defer s.Shutdown() 12565 12566 // Client for API requests. 12567 nc, js := jsClientConnect(t, s) 12568 defer nc.Close() 12569 12570 cfg := StreamConfig{ 12571 Name: "KV", 12572 Subjects: []string{"kv.>"}, 12573 Storage: st, 12574 MaxMsgsPer: 5, 12575 } 12576 12577 req, err := json.Marshal(cfg) 12578 if err != nil { 12579 t.Fatalf("Unexpected error: %v", err) 12580 } 12581 // Do manually for now. 12582 nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 12583 si, err := js.StreamInfo("KV") 12584 if err != nil { 12585 t.Fatalf("Unexpected error: %v", err) 12586 } 12587 if si == nil || si.Config.Name != "KV" { 12588 t.Fatalf("StreamInfo is not correct %+v", si) 12589 } 12590 12591 // Interleave them on purpose. 12592 for i := 1; i <= 11; i++ { 12593 msg := []byte(fmt.Sprintf("%d", i)) 12594 js.PublishAsync("kv.b1.foo", msg) 12595 js.PublishAsync("kv.b2.foo", msg) 12596 12597 js.PublishAsync("kv.b1.bar", msg) 12598 js.PublishAsync("kv.b2.bar", msg) 12599 12600 js.PublishAsync("kv.b1.baz", msg) 12601 js.PublishAsync("kv.b2.baz", msg) 12602 } 12603 12604 select { 12605 case <-js.PublishAsyncComplete(): 12606 case <-time.After(2 * time.Second): 12607 t.Fatalf("Did not receive completion signal") 12608 } 12609 12610 // Do quick check that config needs FilteredSubjects otherwise bad config. 12611 badReq := CreateConsumerRequest{ 12612 Stream: "KV", 12613 Config: ConsumerConfig{ 12614 DeliverSubject: "b", 12615 DeliverPolicy: DeliverLastPerSubject, 12616 }, 12617 } 12618 req, err = json.Marshal(badReq) 12619 if err != nil { 12620 t.Fatalf("Unexpected error: %v", err) 12621 } 12622 resp, err := nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "KV"), req, time.Second) 12623 if err != nil { 12624 t.Fatalf("Unexpected error: %v", err) 12625 } 12626 var ccResp JSApiConsumerCreateResponse 12627 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 12628 t.Fatalf("Unexpected error: %v", err) 12629 } 12630 if ccResp.Error == nil || !strings.Contains(ccResp.Error.Description, "filter subject is not set") { 12631 t.Fatalf("Expected an error, got none") 12632 } 12633 12634 // Now let's consume these via last per subject. 12635 obsReq := CreateConsumerRequest{ 12636 Stream: "KV", 12637 Config: ConsumerConfig{ 12638 DeliverSubject: "d", 12639 DeliverPolicy: DeliverLastPerSubject, 12640 FilterSubject: "kv.b1.*", 12641 }, 12642 } 12643 req, err = json.Marshal(obsReq) 12644 if err != nil { 12645 t.Fatalf("Unexpected error: %v", err) 12646 } 12647 resp, err = nc.Request(fmt.Sprintf(JSApiConsumerCreateT, "KV"), req, time.Second) 12648 if err != nil { 12649 t.Fatalf("Unexpected error: %v", err) 12650 } 12651 ccResp.Error = nil 12652 if err = json.Unmarshal(resp.Data, &ccResp); err != nil { 12653 t.Fatalf("Unexpected error: %v", err) 12654 } 12655 12656 sub, _ := nc.SubscribeSync("d") 12657 defer sub.Unsubscribe() 12658 12659 // Helper to check messages are correct. 12660 checkNext := func(subject string, sseq uint64, v string) { 12661 t.Helper() 12662 m, err := sub.NextMsg(time.Second) 12663 if err != nil { 12664 t.Fatalf("Error receiving message: %v", err) 12665 } 12666 if m.Subject != subject { 12667 t.Fatalf("Expected subject %q but got %q", subject, m.Subject) 12668 } 12669 meta, err := m.Metadata() 12670 if err != nil { 12671 t.Fatalf("didn't get metadata: %s", err) 12672 } 12673 if meta.Sequence.Stream != sseq { 12674 t.Fatalf("Expected stream seq %d but got %d", sseq, meta.Sequence.Stream) 12675 } 12676 if string(m.Data) != v { 12677 t.Fatalf("Expected data of %q but got %q", v, m.Data) 12678 } 12679 } 12680 12681 checkSubsPending(t, sub, 3) 12682 12683 // Now make sure they are what we expect. 12684 checkNext("kv.b1.foo", 61, "11") 12685 checkNext("kv.b1.bar", 63, "11") 12686 checkNext("kv.b1.baz", 65, "11") 12687 12688 msg := []byte(fmt.Sprintf("%d", 22)) 12689 js.Publish("kv.b1.bar", msg) 12690 js.Publish("kv.b2.foo", msg) // Not filtered through.. 12691 12692 checkSubsPending(t, sub, 1) 12693 checkNext("kv.b1.bar", 67, "22") 12694 }) 12695 } 12696 } 12697 12698 func TestJetStreamDeliverLastPerSubjectNumPending(t *testing.T) { 12699 s := RunBasicJetStreamServer(t) 12700 defer s.Shutdown() 12701 12702 // Client for API requests. 12703 nc, js := jsClientConnect(t, s) 12704 defer nc.Close() 12705 12706 if _, err := js.AddStream(&nats.StreamConfig{ 12707 Name: "KV", 12708 Subjects: []string{"KV.>"}, 12709 MaxMsgsPerSubject: 5, 12710 Replicas: 1, 12711 }); err != nil { 12712 t.Fatalf("Error adding stream: %v", err) 12713 } 12714 12715 for i := 0; i < 5; i++ { 12716 msg := []byte(fmt.Sprintf("msg%d", i)) 12717 js.Publish("KV.foo", msg) 12718 js.Publish("KV.bar", msg) 12719 js.Publish("KV.baz", msg) 12720 js.Publish("KV.bat", msg) 12721 } 12722 12723 // Delete some messages 12724 js.DeleteMsg("KV", 2) 12725 js.DeleteMsg("KV", 5) 12726 12727 ci, err := js.AddConsumer("KV", &nats.ConsumerConfig{ 12728 DeliverSubject: nats.NewInbox(), 12729 AckPolicy: nats.AckExplicitPolicy, 12730 DeliverPolicy: nats.DeliverLastPerSubjectPolicy, 12731 FilterSubject: "KV.>", 12732 }) 12733 if err != nil { 12734 t.Fatalf("Error adding consumer: %v", err) 12735 } 12736 if ci.NumPending != 4 { 12737 t.Fatalf("Expected 4 pending msgs, got %v", ci.NumPending) 12738 } 12739 } 12740 12741 // We had a report of a consumer delete crashing the server when in interest retention mode. 12742 // This I believe is only really possible in clustered mode, but we will force the issue here. 12743 func TestJetStreamConsumerCleanupWithRetentionPolicy(t *testing.T) { 12744 s := RunBasicJetStreamServer(t) 12745 defer s.Shutdown() 12746 12747 // Client for API requests. 12748 nc, js := jsClientConnect(t, s) 12749 defer nc.Close() 12750 12751 _, err := js.AddStream(&nats.StreamConfig{ 12752 Name: "ORDERS", 12753 Subjects: []string{"orders.*"}, 12754 Retention: nats.InterestPolicy, 12755 }) 12756 require_NoError(t, err) 12757 12758 sub, err := js.SubscribeSync("orders.*") 12759 require_NoError(t, err) 12760 12761 payload := []byte("Hello World") 12762 for i := 0; i < 10; i++ { 12763 subj := fmt.Sprintf("orders.%d", i+1) 12764 js.Publish(subj, payload) 12765 } 12766 12767 checkSubsPending(t, sub, 10) 12768 12769 for i := 0; i < 10; i++ { 12770 m, err := sub.NextMsg(time.Second) 12771 if err != nil { 12772 t.Fatalf("Unexpected error: %v", err) 12773 } 12774 m.AckSync() 12775 } 12776 12777 ci, err := sub.ConsumerInfo() 12778 if err != nil { 12779 t.Fatalf("Unexpected error getting consumer info: %v", err) 12780 } 12781 12782 acc := s.GlobalAccount() 12783 mset, err := acc.lookupStream("ORDERS") 12784 require_NoError(t, err) 12785 12786 o := mset.lookupConsumer(ci.Name) 12787 if o == nil { 12788 t.Fatalf("Error looking up consumer %q", ci.Name) 12789 } 12790 lseq := mset.lastSeq() 12791 o.mu.Lock() 12792 // Force boundary condition here. 12793 o.asflr = lseq + 2 12794 o.mu.Unlock() 12795 sub.Unsubscribe() 12796 12797 // Make sure server still available. 12798 if _, err := js.StreamInfo("ORDERS"); err != nil { 12799 t.Fatalf("Unexpected error: %v", err) 12800 } 12801 } 12802 12803 // Issue #2392 12804 func TestJetStreamPurgeEffectsConsumerDelivery(t *testing.T) { 12805 s := RunBasicJetStreamServer(t) 12806 defer s.Shutdown() 12807 12808 // Client for API requests. 12809 nc, js := jsClientConnect(t, s) 12810 defer nc.Close() 12811 12812 _, err := js.AddStream(&nats.StreamConfig{ 12813 Name: "TEST", 12814 Subjects: []string{"foo.*"}, 12815 }) 12816 require_NoError(t, err) 12817 12818 js.Publish("foo.a", []byte("show once")) 12819 12820 sub, err := js.SubscribeSync("foo.*", nats.AckWait(250*time.Millisecond), nats.DeliverAll(), nats.AckExplicit()) 12821 require_NoError(t, err) 12822 12823 defer sub.Unsubscribe() 12824 12825 checkSubsPending(t, sub, 1) 12826 12827 // Do not ack. 12828 if _, err := sub.NextMsg(time.Second); err != nil { 12829 t.Fatalf("Error receiving message: %v", err) 12830 } 12831 12832 // Now purge stream. 12833 if err := js.PurgeStream("TEST"); err != nil { 12834 t.Fatalf("Unexpected purge error: %v", err) 12835 } 12836 12837 js.Publish("foo.b", []byte("show twice?")) 12838 // Do not ack again, should show back up. 12839 if _, err := sub.NextMsg(time.Second); err != nil { 12840 t.Fatalf("Error receiving message: %v", err) 12841 } 12842 // Make sure we get it back. 12843 if _, err := sub.NextMsg(time.Second); err != nil { 12844 t.Fatalf("Error receiving message: %v", err) 12845 } 12846 } 12847 12848 // Issue #2403 12849 func TestJetStreamExpireCausesDeadlock(t *testing.T) { 12850 s := RunBasicJetStreamServer(t) 12851 defer s.Shutdown() 12852 12853 // Client for API requests. 12854 nc, js := jsClientConnect(t, s) 12855 defer nc.Close() 12856 12857 _, err := js.AddStream(&nats.StreamConfig{ 12858 Name: "TEST", 12859 Subjects: []string{"foo.*"}, 12860 Storage: nats.MemoryStorage, 12861 MaxMsgs: 10, 12862 Retention: nats.InterestPolicy, 12863 }) 12864 require_NoError(t, err) 12865 12866 sub, err := js.SubscribeSync("foo.bar") 12867 require_NoError(t, err) 12868 12869 defer sub.Unsubscribe() 12870 12871 // Publish from two connections to get the write lock request wedged in between 12872 // having the RLock and wanting it again deeper in the stack. 12873 nc2, js2 := jsClientConnect(t, s) 12874 defer nc2.Close() 12875 12876 for i := 0; i < 1000; i++ { 12877 js.PublishAsync("foo.bar", []byte("HELLO")) 12878 js2.PublishAsync("foo.bar", []byte("HELLO")) 12879 } 12880 select { 12881 case <-js.PublishAsyncComplete(): 12882 case <-time.After(5 * time.Second): 12883 t.Fatalf("Did not receive completion signal") 12884 } 12885 12886 // If we deadlocked then we will not be able to get stream info. 12887 if _, err := js.StreamInfo("TEST"); err != nil { 12888 t.Fatalf("Unexpected error: %v", err) 12889 } 12890 } 12891 12892 func TestJetStreamConsumerPendingBugWithKV(t *testing.T) { 12893 msc := StreamConfig{ 12894 Name: "KV", 12895 Subjects: []string{"kv.>"}, 12896 Storage: MemoryStorage, 12897 MaxMsgsPer: 1, 12898 } 12899 fsc := msc 12900 fsc.Storage = FileStorage 12901 12902 cases := []struct { 12903 name string 12904 mconfig *StreamConfig 12905 }{ 12906 {"MemoryStore", &msc}, 12907 {"FileStore", &fsc}, 12908 } 12909 for _, c := range cases { 12910 t.Run(c.name, func(t *testing.T) { 12911 12912 s := RunBasicJetStreamServer(t) 12913 defer s.Shutdown() 12914 12915 // Client based API 12916 nc, js := jsClientConnect(t, s) 12917 defer nc.Close() 12918 12919 // Not in Go client under server yet. 12920 mset, err := s.GlobalAccount().addStream(c.mconfig) 12921 if err != nil { 12922 t.Fatalf("Unexpected error: %v", err) 12923 } 12924 12925 js.Publish("kv.1", []byte("1")) 12926 js.Publish("kv.2", []byte("2")) 12927 js.Publish("kv.3", []byte("3")) 12928 js.Publish("kv.1", []byte("4")) 12929 12930 si, err := js.StreamInfo("KV") 12931 if err != nil { 12932 t.Fatalf("Unexpected error: %v", err) 12933 } 12934 if si.State.Msgs != 3 { 12935 t.Fatalf("Expected 3 total msgs, got %d", si.State.Msgs) 12936 } 12937 12938 o, err := mset.addConsumer(&ConsumerConfig{ 12939 Durable: "dlc", 12940 DeliverSubject: "xxx", 12941 DeliverPolicy: DeliverLastPerSubject, 12942 FilterSubject: ">", 12943 }) 12944 if err != nil { 12945 t.Fatalf("Unexpected error: %v", err) 12946 } 12947 if ci := o.info(); ci.NumPending != 3 { 12948 t.Fatalf("Expected pending of 3, got %d", ci.NumPending) 12949 } 12950 }) 12951 } 12952 } 12953 12954 // Issue #2420 12955 func TestJetStreamDefaultMaxMsgsPer(t *testing.T) { 12956 s := RunBasicJetStreamServer(t) 12957 defer s.Shutdown() 12958 12959 // Client for API requests. 12960 nc, js := jsClientConnect(t, s) 12961 defer nc.Close() 12962 12963 si, err := js.AddStream(&nats.StreamConfig{ 12964 Name: "TEST", 12965 Subjects: []string{"foo.*"}, 12966 Storage: nats.MemoryStorage, 12967 MaxMsgs: 10, 12968 }) 12969 require_NoError(t, err) 12970 12971 if si.Config.MaxMsgsPerSubject != -1 { 12972 t.Fatalf("Expected default of -1, got %d", si.Config.MaxMsgsPerSubject) 12973 } 12974 } 12975 12976 // Issue #2423 12977 func TestJetStreamBadConsumerCreateErr(t *testing.T) { 12978 s := RunBasicJetStreamServer(t) 12979 defer s.Shutdown() 12980 12981 // Client for API requests. 12982 nc, js := jsClientConnect(t, s) 12983 defer nc.Close() 12984 12985 _, err := js.AddStream(&nats.StreamConfig{ 12986 Name: "TEST", 12987 Subjects: []string{"foo.*"}, 12988 Storage: nats.MemoryStorage, 12989 }) 12990 require_NoError(t, err) 12991 12992 // When adding a consumer with both deliver subject and max wait (push vs pull), 12993 // we got the wrong err about deliver subject having a wildcard. 12994 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 12995 Durable: "nowcerr", 12996 DeliverSubject: "X", 12997 MaxWaiting: 100, 12998 }) 12999 if err == nil { 13000 t.Fatalf("Expected an error but got none") 13001 } 13002 if !strings.Contains(err.Error(), "push mode can not set max waiting") { 13003 t.Fatalf("Incorrect error returned: %v", err) 13004 } 13005 } 13006 13007 func TestJetStreamConsumerPushBound(t *testing.T) { 13008 s := RunBasicJetStreamServer(t) 13009 defer s.Shutdown() 13010 13011 nc, js := jsClientConnect(t, s) 13012 defer nc.Close() 13013 13014 cfg := &nats.StreamConfig{ 13015 Name: "TEST", 13016 Storage: nats.MemoryStorage, 13017 Subjects: []string{"foo"}, 13018 } 13019 if _, err := js.AddStream(cfg); err != nil { 13020 t.Fatalf("Unexpected error: %v", err) 13021 } 13022 13023 // We want to test extended consumer info for push based consumers. 13024 // We need to do these by hand for now. 13025 createConsumer := func(name, deliver string) { 13026 t.Helper() 13027 creq := CreateConsumerRequest{ 13028 Stream: "TEST", 13029 Config: ConsumerConfig{ 13030 Durable: name, 13031 DeliverSubject: deliver, 13032 AckPolicy: AckExplicit, 13033 }, 13034 } 13035 req, err := json.Marshal(creq) 13036 if err != nil { 13037 t.Fatalf("Unexpected error: %v", err) 13038 } 13039 resp, err := nc.Request(fmt.Sprintf(JSApiDurableCreateT, "TEST", name), req, time.Second) 13040 if err != nil { 13041 t.Fatalf("Unexpected error: %v", err) 13042 } 13043 var ccResp JSApiConsumerCreateResponse 13044 if err := json.Unmarshal(resp.Data, &ccResp); err != nil { 13045 t.Fatalf("Unexpected error: %v", err) 13046 } 13047 if ccResp.ConsumerInfo == nil || ccResp.Error != nil { 13048 t.Fatalf("Got a bad response %+v", ccResp) 13049 } 13050 } 13051 13052 consumerInfo := func(name string) *ConsumerInfo { 13053 t.Helper() 13054 resp, err := nc.Request(fmt.Sprintf(JSApiConsumerInfoT, "TEST", name), nil, time.Second) 13055 if err != nil { 13056 t.Fatalf("Unexpected error: %v", err) 13057 } 13058 var cinfo JSApiConsumerInfoResponse 13059 if err := json.Unmarshal(resp.Data, &cinfo); err != nil { 13060 t.Fatalf("Unexpected error: %v", err) 13061 } 13062 if cinfo.ConsumerInfo == nil || cinfo.Error != nil { 13063 t.Fatalf("Got a bad response %+v", cinfo) 13064 } 13065 return cinfo.ConsumerInfo 13066 } 13067 13068 // First create a durable push and make sure we show now active status. 13069 createConsumer("dlc", "d.X") 13070 if ci := consumerInfo("dlc"); ci.PushBound { 13071 t.Fatalf("Expected push bound to be false") 13072 } 13073 // Now bind the deliver subject. 13074 sub, _ := nc.SubscribeSync("d.X") 13075 nc.Flush() // Make sure it registers. 13076 // Check that its reported. 13077 if ci := consumerInfo("dlc"); !ci.PushBound { 13078 t.Fatalf("Expected push bound to be set") 13079 } 13080 sub.Unsubscribe() 13081 nc.Flush() // Make sure it registers. 13082 if ci := consumerInfo("dlc"); ci.PushBound { 13083 t.Fatalf("Expected push bound to be false") 13084 } 13085 13086 // Now make sure we have queue groups indictated as needed. 13087 createConsumer("ik", "d.Z") 13088 // Now bind the deliver subject with a queue group. 13089 sub, _ = nc.QueueSubscribeSync("d.Z", "g22") 13090 defer sub.Unsubscribe() 13091 nc.Flush() // Make sure it registers. 13092 // Check that queue group is not reported. 13093 if ci := consumerInfo("ik"); ci.PushBound { 13094 t.Fatalf("Expected push bound to be false") 13095 } 13096 sub.Unsubscribe() 13097 nc.Flush() // Make sure it registers. 13098 if ci := consumerInfo("ik"); ci.PushBound { 13099 t.Fatalf("Expected push bound to be false") 13100 } 13101 13102 // Make sure pull consumers report PushBound as false by default. 13103 createConsumer("rip", _EMPTY_) 13104 if ci := consumerInfo("rip"); ci.PushBound { 13105 t.Fatalf("Expected push bound to be false") 13106 } 13107 } 13108 13109 // Got a report of memory leaking, tracked it to internal clients for consumers. 13110 func TestJetStreamConsumerInternalClientLeak(t *testing.T) { 13111 s := RunBasicJetStreamServer(t) 13112 defer s.Shutdown() 13113 13114 nc, js := jsClientConnect(t, s) 13115 defer nc.Close() 13116 13117 cfg := &nats.StreamConfig{ 13118 Name: "TEST", 13119 Storage: nats.MemoryStorage, 13120 } 13121 if _, err := js.AddStream(cfg); err != nil { 13122 t.Fatalf("Unexpected error: %v", err) 13123 } 13124 13125 ga, sa := s.GlobalAccount(), s.SystemAccount() 13126 ncb, nscb := ga.NumConnections(), sa.NumConnections() 13127 13128 // Create 10 consumers 13129 for i := 0; i < 10; i++ { 13130 ci, err := js.AddConsumer("TEST", &nats.ConsumerConfig{DeliverSubject: "x"}) 13131 if err != nil { 13132 t.Fatalf("Unexpected error: %v", err) 13133 } 13134 // Accelerate ephemeral cleanup. 13135 mset, err := ga.lookupStream("TEST") 13136 if err != nil { 13137 t.Fatalf("Expected to find a stream for %q", "TEST") 13138 } 13139 o := mset.lookupConsumer(ci.Name) 13140 if o == nil { 13141 t.Fatalf("Error looking up consumer %q", ci.Name) 13142 } 13143 o.setInActiveDeleteThreshold(500 * time.Millisecond) 13144 } 13145 13146 // Wait for them to all go away. 13147 checkFor(t, 2*time.Second, 100*time.Millisecond, func() error { 13148 si, err := js.StreamInfo("TEST") 13149 if err != nil { 13150 t.Fatalf("Unexpected error: %v", err) 13151 } 13152 if si.State.Consumers == 0 { 13153 return nil 13154 } 13155 return fmt.Errorf("Consumers still present") 13156 }) 13157 // Make sure we are not leaking clients/connections. 13158 // Server does not see these so need to look at account. 13159 if nca := ga.NumConnections(); nca != ncb { 13160 t.Fatalf("Leaked clients in global account: %d vs %d", ncb, nca) 13161 } 13162 if nsca := sa.NumConnections(); nsca != nscb { 13163 t.Fatalf("Leaked clients in system account: %d vs %d", nscb, nsca) 13164 } 13165 } 13166 13167 func TestJetStreamConsumerEventingRaceOnShutdown(t *testing.T) { 13168 s := RunBasicJetStreamServer(t) 13169 defer s.Shutdown() 13170 13171 nc, js := jsClientConnect(t, s, nats.NoReconnect()) 13172 defer nc.Close() 13173 13174 cfg := &nats.StreamConfig{ 13175 Name: "TEST", 13176 Subjects: []string{"foo"}, 13177 Storage: nats.MemoryStorage, 13178 } 13179 if _, err := js.AddStream(cfg); err != nil { 13180 t.Fatalf("Unexpected error: %v", err) 13181 } 13182 13183 wg := sync.WaitGroup{} 13184 wg.Add(1) 13185 go func() { 13186 defer wg.Done() 13187 13188 for { 13189 if _, err := js.SubscribeSync("foo", nats.BindStream("TEST")); err != nil { 13190 return 13191 } 13192 } 13193 }() 13194 13195 time.Sleep(50 * time.Millisecond) 13196 s.Shutdown() 13197 13198 wg.Wait() 13199 } 13200 13201 // Got a report of streams that expire all messages while the server is down report errors when clients reconnect 13202 // and try to send new messages. 13203 func TestJetStreamExpireAllWhileServerDown(t *testing.T) { 13204 s := RunBasicJetStreamServer(t) 13205 defer s.Shutdown() 13206 13207 nc, js := jsClientConnect(t, s) 13208 defer nc.Close() 13209 13210 cfg := &nats.StreamConfig{ 13211 Name: "TEST", 13212 MaxAge: 250 * time.Millisecond, 13213 } 13214 if _, err := js.AddStream(cfg); err != nil { 13215 t.Fatalf("Unexpected error: %v", err) 13216 } 13217 toSend := 10_000 13218 for i := 0; i < toSend; i++ { 13219 js.PublishAsync("TEST", []byte("OK")) 13220 } 13221 select { 13222 case <-js.PublishAsyncComplete(): 13223 case <-time.After(time.Second): 13224 t.Fatalf("Did not receive completion signal") 13225 } 13226 13227 sd := s.JetStreamConfig().StoreDir 13228 s.Shutdown() 13229 13230 time.Sleep(300 * time.Millisecond) 13231 13232 // Restart after expire. 13233 s = RunJetStreamServerOnPort(-1, sd) 13234 defer s.Shutdown() 13235 13236 nc, js = jsClientConnect(t, s) 13237 defer nc.Close() 13238 13239 if si, err := js.StreamInfo("TEST"); err != nil || si.State.Msgs != 0 { 13240 t.Fatalf("Unexpected stream info state: %+v", si) 13241 } 13242 13243 for i := 0; i < 10; i++ { 13244 if _, err := js.Publish("TEST", []byte("OK")); err != nil { 13245 t.Fatalf("Unexpected error: %v", err) 13246 } 13247 } 13248 13249 if si, err := js.StreamInfo("TEST"); err != nil || si.State.Msgs != 10 { 13250 t.Fatalf("Unexpected stream info state: %+v", si) 13251 } 13252 } 13253 13254 func TestJetStreamLongStreamNamesAndPubAck(t *testing.T) { 13255 s := RunBasicJetStreamServer(t) 13256 defer s.Shutdown() 13257 13258 nc, js := jsClientConnect(t, s) 13259 defer nc.Close() 13260 13261 cfg := &nats.StreamConfig{ 13262 Name: strings.Repeat("ZABC", 256/4)[:255], 13263 Subjects: []string{"foo"}, 13264 } 13265 if _, err := js.AddStream(cfg); err != nil { 13266 t.Fatalf("Unexpected error: %v", err) 13267 } 13268 js.Publish("foo", []byte("HELLO")) 13269 } 13270 13271 func TestJetStreamPerSubjectPending(t *testing.T) { 13272 for _, st := range []nats.StorageType{nats.FileStorage, nats.MemoryStorage} { 13273 t.Run(st.String(), func(t *testing.T) { 13274 13275 s := RunBasicJetStreamServer(t) 13276 defer s.Shutdown() 13277 13278 nc, js := jsClientConnect(t, s) 13279 defer nc.Close() 13280 13281 _, err := js.AddStream(&nats.StreamConfig{ 13282 Name: "KV_X", 13283 Subjects: []string{"$KV.X.>"}, 13284 MaxMsgsPerSubject: 5, 13285 Storage: st, 13286 }) 13287 if err != nil { 13288 t.Fatalf("add stream failed: %s", err) 13289 } 13290 13291 // the message we will care for 13292 _, err = js.Publish("$KV.X.x.y.z", []byte("hello world")) 13293 if err != nil { 13294 t.Fatalf("publish failed: %s", err) 13295 } 13296 13297 // make sure there's some unrelated message after 13298 _, err = js.Publish("$KV.X.1", []byte("hello world")) 13299 if err != nil { 13300 t.Fatalf("publish failed: %s", err) 13301 } 13302 13303 // we expect the wildcard filter subject to match only the one message and so pending will be 0 13304 sub, err := js.SubscribeSync("$KV.X.x.>", nats.DeliverLastPerSubject()) 13305 if err != nil { 13306 t.Fatalf("subscribe failed: %s", err) 13307 } 13308 13309 msg, err := sub.NextMsg(time.Second) 13310 if err != nil { 13311 t.Fatalf("next failed: %s", err) 13312 } 13313 13314 meta, err := msg.Metadata() 13315 if err != nil { 13316 t.Fatalf("meta failed: %s", err) 13317 } 13318 13319 // with DeliverLastPerSubject set this is never 0, but without setting that its 0 correctly 13320 if meta.NumPending != 0 { 13321 t.Fatalf("expected numpending 0 got %d", meta.NumPending) 13322 } 13323 }) 13324 } 13325 } 13326 13327 func TestJetStreamPublishExpectNoMsg(t *testing.T) { 13328 s := RunBasicJetStreamServer(t) 13329 defer s.Shutdown() 13330 13331 nc, js := jsClientConnect(t, s) 13332 defer nc.Close() 13333 13334 _, err := js.AddStream(&nats.StreamConfig{ 13335 Name: "KV", 13336 Subjects: []string{"KV.>"}, 13337 MaxMsgsPerSubject: 5, 13338 }) 13339 if err != nil { 13340 t.Fatalf("add stream failed: %s", err) 13341 } 13342 13343 if _, err = js.Publish("KV.22", []byte("hello world")); err != nil { 13344 t.Fatalf("Unexpected error: %v", err) 13345 } 13346 13347 // This should succeed. 13348 m := nats.NewMsg("KV.33") 13349 m.Header.Set(JSExpectedLastSubjSeq, "0") 13350 if _, err := js.PublishMsg(m); err != nil { 13351 t.Fatalf("Unexpected error: %v", err) 13352 } 13353 13354 // This should fail. 13355 m = nats.NewMsg("KV.22") 13356 m.Header.Set(JSExpectedLastSubjSeq, "0") 13357 if _, err := js.PublishMsg(m); err == nil { 13358 t.Fatalf("Expected error: %v", err) 13359 } 13360 13361 if err := js.PurgeStream("KV"); err != nil { 13362 t.Fatalf("Unexpected purge error: %v", err) 13363 } 13364 13365 // This should succeed now. 13366 if _, err := js.PublishMsg(m); err != nil { 13367 t.Fatalf("Unexpected error: %v", err) 13368 } 13369 } 13370 13371 func TestJetStreamPullLargeBatchExpired(t *testing.T) { 13372 s := RunBasicJetStreamServer(t) 13373 defer s.Shutdown() 13374 13375 nc, js := jsClientConnect(t, s) 13376 defer nc.Close() 13377 13378 _, err := js.AddStream(&nats.StreamConfig{ 13379 Name: "TEST", 13380 Subjects: []string{"foo"}, 13381 }) 13382 if err != nil { 13383 t.Fatalf("add stream failed: %s", err) 13384 } 13385 13386 sub, err := js.PullSubscribe("foo", "dlc", nats.PullMaxWaiting(10), nats.MaxAckPending(10*50_000_000)) 13387 if err != nil { 13388 t.Fatalf("Error creating pull subscriber: %v", err) 13389 } 13390 13391 // Queue up 10 batch requests with timeout. 13392 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 13393 req := &JSApiConsumerGetNextRequest{Batch: 50_000_000, Expires: 100 * time.Millisecond} 13394 jreq, _ := json.Marshal(req) 13395 for i := 0; i < 10; i++ { 13396 nc.PublishRequest(rsubj, "bar", jreq) 13397 } 13398 nc.Flush() 13399 13400 // Let them all expire. 13401 time.Sleep(150 * time.Millisecond) 13402 13403 // Now do another and measure how long to timeout and shutdown the server. 13404 start := time.Now() 13405 sub.Fetch(1, nats.MaxWait(100*time.Millisecond)) 13406 s.Shutdown() 13407 13408 if delta := time.Since(start); delta > 200*time.Millisecond { 13409 t.Fatalf("Took too long to expire: %v", delta) 13410 } 13411 } 13412 13413 func TestJetStreamNegativeDupeWindow(t *testing.T) { 13414 s := RunBasicJetStreamServer(t) 13415 defer s.Shutdown() 13416 13417 nc, js := jsClientConnect(t, s) 13418 defer nc.Close() 13419 13420 // we incorrectly set MaxAge to -1 which then as a side effect sets dupe window to -1 which should fail 13421 _, err := js.AddStream(&nats.StreamConfig{ 13422 Name: "TEST", 13423 Subjects: nil, 13424 Retention: nats.WorkQueuePolicy, 13425 MaxConsumers: 1, 13426 MaxMsgs: -1, 13427 MaxBytes: -1, 13428 Discard: nats.DiscardNew, 13429 MaxAge: -1, 13430 MaxMsgsPerSubject: -1, 13431 MaxMsgSize: -1, 13432 Storage: nats.FileStorage, 13433 Replicas: 1, 13434 NoAck: false, 13435 }) 13436 if err == nil || err.Error() != "nats: duplicates window can not be negative" { 13437 t.Fatalf("Expected dupe window error got: %v", err) 13438 } 13439 } 13440 13441 // Issue #2551 13442 func TestJetStreamMirroredConsumerFailAfterRestart(t *testing.T) { 13443 s := RunBasicJetStreamServer(t) 13444 defer s.Shutdown() 13445 13446 nc, js := jsClientConnect(t, s) 13447 defer nc.Close() 13448 13449 _, err := js.AddStream(&nats.StreamConfig{ 13450 Name: "S1", 13451 Storage: nats.FileStorage, 13452 Subjects: []string{"foo", "bar", "baz"}, 13453 }) 13454 if err != nil { 13455 t.Fatalf("create failed: %s", err) 13456 } 13457 13458 _, err = js.AddStream(&nats.StreamConfig{ 13459 Name: "M1", 13460 Storage: nats.FileStorage, 13461 Mirror: &nats.StreamSource{Name: "S1"}, 13462 }) 13463 if err != nil { 13464 t.Fatalf("create failed: %s", err) 13465 } 13466 13467 _, err = js.AddConsumer("M1", &nats.ConsumerConfig{ 13468 Durable: "C1", 13469 FilterSubject: ">", 13470 AckPolicy: nats.AckExplicitPolicy, 13471 }) 13472 if err != nil { 13473 t.Fatalf("consumer create failed: %s", err) 13474 } 13475 13476 // Stop current 13477 sd := s.JetStreamConfig().StoreDir 13478 s.Shutdown() 13479 s.WaitForShutdown() 13480 13481 // Restart. 13482 s = RunJetStreamServerOnPort(-1, sd) 13483 defer s.Shutdown() 13484 13485 nc, js = jsClientConnect(t, s) 13486 defer nc.Close() 13487 13488 _, err = js.StreamInfo("M1") 13489 if err != nil { 13490 t.Fatalf("%s did not exist after start: %s", "M1", err) 13491 } 13492 13493 _, err = js.ConsumerInfo("M1", "C1") 13494 if err != nil { 13495 t.Fatalf("C1 did not exist after start: %s", err) 13496 } 13497 } 13498 13499 func TestJetStreamDisabledLimitsEnforcementJWT(t *testing.T) { 13500 updateJwt := func(url string, akp nkeys.KeyPair, pubKey string, jwt string) { 13501 t.Helper() 13502 c := natsConnect(t, url, createUserCreds(t, nil, akp)) 13503 defer c.Close() 13504 if msg, err := c.Request(fmt.Sprintf(accUpdateEventSubjNew, pubKey), []byte(jwt), time.Second); err != nil { 13505 t.Fatal("error not expected in this test", err) 13506 } else { 13507 content := make(map[string]any) 13508 if err := json.Unmarshal(msg.Data, &content); err != nil { 13509 t.Fatalf("%v", err) 13510 } else if _, ok := content["data"]; !ok { 13511 t.Fatalf("did not get an ok response got: %v", content) 13512 } 13513 } 13514 } 13515 // create system account 13516 sysKp, _ := nkeys.CreateAccount() 13517 sysPub, _ := sysKp.PublicKey() 13518 // limits to apply and check 13519 limits1 := jwt.JetStreamLimits{MemoryStorage: 1024, DiskStorage: 0, Streams: 1, Consumer: 2} 13520 akp, _ := nkeys.CreateAccount() 13521 aPub, _ := akp.PublicKey() 13522 claim := jwt.NewAccountClaims(aPub) 13523 claim.Limits.JetStreamLimits = limits1 13524 aJwt1, err := claim.Encode(oKp) 13525 require_NoError(t, err) 13526 dir := t.TempDir() 13527 storeDir1 := t.TempDir() 13528 conf := createConfFile(t, []byte(fmt.Sprintf(` 13529 listen: -1 13530 jetstream: {store_dir: '%s'} 13531 operator: %s 13532 resolver: { 13533 type: full 13534 dir: '%s' 13535 } 13536 system_account: %s 13537 `, storeDir1, ojwt, dir, sysPub))) 13538 s, _ := RunServerWithConfig(conf) 13539 defer s.Shutdown() 13540 updateJwt(s.ClientURL(), sysKp, aPub, aJwt1) 13541 c := natsConnect(t, s.ClientURL(), createUserCreds(t, nil, akp), nats.ReconnectWait(200*time.Millisecond)) 13542 defer c.Close() 13543 // keep using the same connection 13544 js, err := c.JetStream() 13545 require_NoError(t, err) 13546 _, err = js.AddStream(&nats.StreamConfig{ 13547 Name: "disk", 13548 Storage: nats.FileStorage, 13549 Subjects: []string{"disk"}, 13550 }) 13551 require_Error(t, err) 13552 } 13553 13554 func TestJetStreamDisabledLimitsEnforcement(t *testing.T) { 13555 storeDir1 := t.TempDir() 13556 conf1 := createConfFile(t, []byte(fmt.Sprintf(` 13557 listen: 127.0.0.1:-1 13558 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'} 13559 accounts { 13560 one { 13561 jetstream: { 13562 mem: 1024 13563 disk: 0 13564 streams: 1 13565 consumers: 2 13566 } 13567 users [{user: one, password: password}] 13568 } 13569 } 13570 no_auth_user: one 13571 `, storeDir1))) 13572 s, _ := RunServerWithConfig(conf1) 13573 defer s.Shutdown() 13574 13575 c := natsConnect(t, s.ClientURL()) 13576 defer c.Close() 13577 // keep using the same connection 13578 js, err := c.JetStream() 13579 require_NoError(t, err) 13580 _, err = js.AddStream(&nats.StreamConfig{ 13581 Name: "disk", 13582 Storage: nats.FileStorage, 13583 Subjects: []string{"disk"}, 13584 }) 13585 require_Error(t, err) 13586 } 13587 13588 func TestJetStreamConsumerNoMsgPayload(t *testing.T) { 13589 s := RunBasicJetStreamServer(t) 13590 defer s.Shutdown() 13591 13592 nc, js := jsClientConnect(t, s) 13593 defer nc.Close() 13594 13595 _, err := js.AddStream(&nats.StreamConfig{Name: "S"}) 13596 require_NoError(t, err) 13597 13598 msg := nats.NewMsg("S") 13599 msg.Header.Set("name", "derek") 13600 msg.Data = bytes.Repeat([]byte("A"), 128) 13601 for i := 0; i < 10; i++ { 13602 msg.Reply = _EMPTY_ // Fixed in Go client but not in embdedded on yet. 13603 _, err = js.PublishMsgAsync(msg) 13604 require_NoError(t, err) 13605 } 13606 13607 mset, err := s.GlobalAccount().lookupStream("S") 13608 require_NoError(t, err) 13609 13610 // Now create our consumer with no payload option. 13611 _, err = mset.addConsumer(&ConsumerConfig{DeliverSubject: "_d_", Durable: "d22", HeadersOnly: true}) 13612 require_NoError(t, err) 13613 13614 sub, err := js.SubscribeSync("S", nats.Durable("d22")) 13615 require_NoError(t, err) 13616 13617 for i := 0; i < 10; i++ { 13618 m, err := sub.NextMsg(time.Second) 13619 require_NoError(t, err) 13620 if len(m.Data) > 0 { 13621 t.Fatalf("Expected no payload") 13622 } 13623 if ms := m.Header.Get(JSMsgSize); ms != "128" { 13624 t.Fatalf("Expected a header with msg size, got %q", ms) 13625 } 13626 } 13627 } 13628 13629 // Issue #2607 13630 func TestJetStreamPurgeAndFilteredConsumers(t *testing.T) { 13631 s := RunBasicJetStreamServer(t) 13632 defer s.Shutdown() 13633 13634 nc, js := jsClientConnect(t, s) 13635 defer nc.Close() 13636 13637 _, err := js.AddStream(&nats.StreamConfig{Name: "S", Subjects: []string{"FOO.*"}}) 13638 require_NoError(t, err) 13639 13640 for i := 0; i < 10; i++ { 13641 _, err = js.Publish("FOO.adam", []byte("M")) 13642 require_NoError(t, err) 13643 _, err = js.Publish("FOO.eve", []byte("F")) 13644 require_NoError(t, err) 13645 } 13646 13647 ci, err := js.AddConsumer("S", &nats.ConsumerConfig{ 13648 Durable: "adam", 13649 AckPolicy: nats.AckExplicitPolicy, 13650 FilterSubject: "FOO.adam", 13651 }) 13652 require_NoError(t, err) 13653 if ci.NumPending != 10 { 13654 t.Fatalf("Expected NumPending to be 10, got %d", ci.NumPending) 13655 } 13656 13657 ci, err = js.AddConsumer("S", &nats.ConsumerConfig{ 13658 Durable: "eve", 13659 AckPolicy: nats.AckExplicitPolicy, 13660 FilterSubject: "FOO.eve", 13661 }) 13662 require_NoError(t, err) 13663 if ci.NumPending != 10 { 13664 t.Fatalf("Expected NumPending to be 10, got %d", ci.NumPending) 13665 } 13666 13667 // Also check unfiltered with interleaving messages. 13668 _, err = js.AddConsumer("S", &nats.ConsumerConfig{ 13669 Durable: "all", 13670 AckPolicy: nats.AckExplicitPolicy, 13671 }) 13672 require_NoError(t, err) 13673 13674 // Now purge only adam. 13675 jr, _ := json.Marshal(&JSApiStreamPurgeRequest{Subject: "FOO.adam"}) 13676 _, err = nc.Request(fmt.Sprintf(JSApiStreamPurgeT, "S"), jr, time.Second) 13677 require_NoError(t, err) 13678 13679 si, err := js.StreamInfo("S") 13680 require_NoError(t, err) 13681 if si.State.Msgs != 10 { 13682 t.Fatalf("Expected 10 messages after purge, got %d", si.State.Msgs) 13683 } 13684 13685 ci, err = js.ConsumerInfo("S", "eve") 13686 require_NoError(t, err) 13687 if ci.NumPending != 10 { 13688 t.Fatalf("Expected NumPending to be 10, got %d", ci.NumPending) 13689 } 13690 13691 ci, err = js.ConsumerInfo("S", "adam") 13692 require_NoError(t, err) 13693 if ci.NumPending != 0 { 13694 t.Fatalf("Expected NumPending to be 0, got %d", ci.NumPending) 13695 } 13696 if ci.AckFloor.Stream != 20 { 13697 t.Fatalf("Expected AckFloor for stream to be 20, got %d", ci.AckFloor.Stream) 13698 } 13699 13700 ci, err = js.ConsumerInfo("S", "all") 13701 require_NoError(t, err) 13702 if ci.NumPending != 10 { 13703 t.Fatalf("Expected NumPending to be 10, got %d", ci.NumPending) 13704 } 13705 } 13706 13707 // Issue #2662 13708 func TestJetStreamLargeExpiresAndServerRestart(t *testing.T) { 13709 s := RunBasicJetStreamServer(t) 13710 defer s.Shutdown() 13711 13712 nc, js := jsClientConnect(t, s) 13713 defer nc.Close() 13714 13715 maxAge := 2 * time.Second 13716 13717 _, err := js.AddStream(&nats.StreamConfig{ 13718 Name: "S", 13719 Subjects: []string{"foo"}, 13720 MaxAge: maxAge, 13721 }) 13722 require_NoError(t, err) 13723 13724 start := time.Now() 13725 _, err = js.Publish("foo", []byte("ok")) 13726 require_NoError(t, err) 13727 13728 // Wait total of maxAge - 1s. 13729 time.Sleep(maxAge - time.Since(start) - time.Second) 13730 13731 // Stop current 13732 sd := s.JetStreamConfig().StoreDir 13733 s.Shutdown() 13734 // Restart. 13735 s = RunJetStreamServerOnPort(-1, sd) 13736 defer s.Shutdown() 13737 13738 nc, js = jsClientConnect(t, s) 13739 defer nc.Close() 13740 13741 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 13742 si, err := js.StreamInfo("S") 13743 require_NoError(t, err) 13744 if si.State.Msgs != 0 { 13745 return fmt.Errorf("Expected no messages, got %d", si.State.Msgs) 13746 } 13747 return nil 13748 }) 13749 13750 if waited := time.Since(start); waited > maxAge+time.Second { 13751 t.Fatalf("Waited to long %v vs %v for messages to expire", waited, maxAge) 13752 } 13753 } 13754 13755 // Bug that was reported showing memstore not handling max per subject of 1. 13756 func TestJetStreamMessagePerSubjectKeepBug(t *testing.T) { 13757 test := func(t *testing.T, keep int64, store nats.StorageType) { 13758 s := RunBasicJetStreamServer(t) 13759 defer s.Shutdown() 13760 13761 nc, js := jsClientConnect(t, s) 13762 defer nc.Close() 13763 13764 _, err := js.AddStream(&nats.StreamConfig{ 13765 Name: "TEST", 13766 MaxMsgsPerSubject: keep, 13767 Storage: store, 13768 }) 13769 require_NoError(t, err) 13770 13771 for i := 0; i < 100; i++ { 13772 _, err = js.Publish("TEST", []byte(fmt.Sprintf("test %d", i))) 13773 require_NoError(t, err) 13774 } 13775 13776 nfo, err := js.StreamInfo("TEST") 13777 require_NoError(t, err) 13778 13779 if nfo.State.Msgs != uint64(keep) { 13780 t.Fatalf("Expected %d message got %d", keep, nfo.State.Msgs) 13781 } 13782 } 13783 13784 t.Run("FileStore", func(t *testing.T) { 13785 t.Run("Keep 10", func(t *testing.T) { test(t, 10, nats.FileStorage) }) 13786 t.Run("Keep 1", func(t *testing.T) { test(t, 1, nats.FileStorage) }) 13787 }) 13788 13789 t.Run("MemStore", func(t *testing.T) { 13790 t.Run("Keep 10", func(t *testing.T) { test(t, 10, nats.MemoryStorage) }) 13791 t.Run("Keep 1", func(t *testing.T) { test(t, 1, nats.MemoryStorage) }) 13792 }) 13793 } 13794 13795 func TestJetStreamInvalidDeliverSubject(t *testing.T) { 13796 s := RunBasicJetStreamServer(t) 13797 defer s.Shutdown() 13798 13799 nc, js := jsClientConnect(t, s) 13800 defer nc.Close() 13801 13802 _, err := js.AddStream(&nats.StreamConfig{ 13803 Name: "TEST", 13804 }) 13805 require_NoError(t, err) 13806 13807 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{DeliverSubject: " x"}) 13808 require_Error(t, err, NewJSConsumerInvalidDeliverSubjectError()) 13809 } 13810 13811 func TestJetStreamMemoryCorruption(t *testing.T) { 13812 s := RunBasicJetStreamServer(t) 13813 defer s.Shutdown() 13814 13815 nc, js := jsClientConnect(t, s) 13816 defer nc.Close() 13817 13818 errCh := make(chan error, 10) 13819 nc.SetErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, e error) { 13820 select { 13821 case errCh <- e: 13822 default: 13823 } 13824 }) 13825 13826 // The storage has to be MemoryStorage to show the issue 13827 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "bucket", Storage: nats.MemoryStorage}) 13828 require_NoError(t, err) 13829 13830 w1, err := kv.WatchAll() 13831 require_NoError(t, err) 13832 13833 w2, err := kv.WatchAll(nats.MetaOnly()) 13834 require_NoError(t, err) 13835 13836 kv.Put("key1", []byte("aaa")) 13837 kv.Put("key1", []byte("aab")) 13838 kv.Put("key2", []byte("zza")) 13839 kv.Put("key2", []byte("zzb")) 13840 kv.Delete("key1") 13841 kv.Delete("key2") 13842 kv.Put("key1", []byte("aac")) 13843 kv.Put("key2", []byte("zzc")) 13844 kv.Delete("key1") 13845 kv.Delete("key2") 13846 kv.Purge("key1") 13847 kv.Purge("key2") 13848 13849 checkUpdates := func(updates <-chan nats.KeyValueEntry) { 13850 t.Helper() 13851 count := 0 13852 for { 13853 select { 13854 case <-updates: 13855 count++ 13856 if count == 13 { 13857 return 13858 } 13859 case <-time.After(time.Second): 13860 t.Fatal("Did not receive all updates") 13861 } 13862 } 13863 } 13864 checkUpdates(w1.Updates()) 13865 checkUpdates(w2.Updates()) 13866 13867 select { 13868 case e := <-errCh: 13869 t.Fatal(e) 13870 case <-time.After(250 * time.Millisecond): 13871 // OK 13872 } 13873 } 13874 13875 func TestJetStreamRecoverBadStreamSubjects(t *testing.T) { 13876 s := RunBasicJetStreamServer(t) 13877 sd := s.JetStreamConfig().StoreDir 13878 s.Shutdown() 13879 13880 f := filepath.Join(sd, "$G", "streams", "TEST") 13881 fs, err := newFileStore(FileStoreConfig{StoreDir: f}, StreamConfig{ 13882 Name: "TEST", 13883 Subjects: []string{"foo", "bar", " baz "}, // baz has spaces 13884 Storage: FileStorage, 13885 }) 13886 require_NoError(t, err) 13887 fs.Stop() 13888 13889 s = RunJetStreamServerOnPort(-1, sd) 13890 defer s.Shutdown() 13891 13892 nc, js := jsClientConnect(t, s) 13893 defer nc.Close() 13894 13895 si, err := js.StreamInfo("TEST") 13896 require_NoError(t, err) 13897 13898 if len(si.Config.Subjects) != 3 { 13899 t.Fatalf("Expected to recover all subjects") 13900 } 13901 } 13902 13903 func TestJetStreamRecoverBadMirrorConfigWithSubjects(t *testing.T) { 13904 s := RunBasicJetStreamServer(t) 13905 defer s.Shutdown() 13906 sd := s.JetStreamConfig().StoreDir 13907 13908 // Client for API requests. 13909 nc, js := jsClientConnect(t, s) 13910 defer nc.Close() 13911 13912 // Origin 13913 _, err := js.AddStream(&nats.StreamConfig{ 13914 Name: "S", 13915 Subjects: []string{"foo"}, 13916 }) 13917 require_NoError(t, err) 13918 13919 s.Shutdown() 13920 13921 f := filepath.Join(sd, "$G", "streams", "M") 13922 fs, err := newFileStore(FileStoreConfig{StoreDir: f}, StreamConfig{ 13923 Name: "M", 13924 Subjects: []string{"foo", "bar", "baz"}, // Mirrors should not have spaces. 13925 Mirror: &StreamSource{Name: "S"}, 13926 Storage: FileStorage, 13927 }) 13928 require_NoError(t, err) 13929 fs.Stop() 13930 13931 s = RunJetStreamServerOnPort(-1, sd) 13932 defer s.Shutdown() 13933 13934 nc, js = jsClientConnect(t, s) 13935 defer nc.Close() 13936 13937 si, err := js.StreamInfo("M") 13938 require_NoError(t, err) 13939 13940 if len(si.Config.Subjects) != 0 { 13941 t.Fatalf("Expected to have NO subjects on mirror") 13942 } 13943 } 13944 13945 func TestJetStreamCrossAccountsDeliverSubjectInterest(t *testing.T) { 13946 conf := createConfFile(t, []byte(fmt.Sprintf(` 13947 listen: 127.0.0.1:-1 13948 jetstream: {max_mem_store: 4GB, max_file_store: 1TB, store_dir: %q} 13949 accounts: { 13950 A: { 13951 jetstream: enabled 13952 users: [ {user: a, password: pwd} ] 13953 exports [ 13954 { stream: "_d_" } # For the delivery subject for the consumer 13955 ] 13956 }, 13957 B: { 13958 users: [ {user: b, password: pwd} ] 13959 imports [ 13960 { stream: { account: A, subject: "_d_"}, to: "foo" } 13961 ] 13962 }, 13963 } 13964 `, t.TempDir()))) 13965 13966 s, _ := RunServerWithConfig(conf) 13967 defer s.Shutdown() 13968 13969 nc, js := jsClientConnect(t, s, nats.UserInfo("a", "pwd")) 13970 defer nc.Close() 13971 13972 _, err := js.AddStream(&nats.StreamConfig{ 13973 Name: "TEST", 13974 Subjects: []string{"foo"}, 13975 }) 13976 require_NoError(t, err) 13977 13978 msg, toSend := []byte("OK"), 100 13979 for i := 0; i < toSend; i++ { 13980 if _, err := js.PublishAsync("foo", msg); err != nil { 13981 t.Fatalf("Unexpected publish error: %v", err) 13982 } 13983 } 13984 select { 13985 case <-js.PublishAsyncComplete(): 13986 case <-time.After(5 * time.Second): 13987 t.Fatalf("Did not receive completion signal") 13988 } 13989 13990 // Now create the consumer as well here manually that we will want to reference from Account B. 13991 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{Durable: "dlc", DeliverSubject: "_d_"}) 13992 require_NoError(t, err) 13993 13994 // Wait to see if the stream import signals to deliver messages with no real subscriber interest. 13995 time.Sleep(200 * time.Millisecond) 13996 13997 ci, err := js.ConsumerInfo("TEST", "dlc") 13998 require_NoError(t, err) 13999 14000 // Make sure we have not delivered any messages based on the import signal alone. 14001 if ci.NumPending != uint64(toSend) || ci.Delivered.Consumer != 0 { 14002 t.Fatalf("Bad consumer info, looks like we started delivering: %+v", ci) 14003 } 14004 14005 // Now create interest in the delivery subject through the import on account B. 14006 nc, _ = jsClientConnect(t, s, nats.UserInfo("b", "pwd")) 14007 defer nc.Close() 14008 sub, err := nc.SubscribeSync("foo") 14009 require_NoError(t, err) 14010 checkSubsPending(t, sub, toSend) 14011 14012 ci, err = js.ConsumerInfo("TEST", "dlc") 14013 require_NoError(t, err) 14014 14015 // Make sure our consumer info reflects we delivered the messages. 14016 if ci.NumPending != 0 || ci.Delivered.Consumer != uint64(toSend) { 14017 t.Fatalf("Bad consumer info, looks like we did not deliver: %+v", ci) 14018 } 14019 } 14020 14021 func TestJetStreamPullConsumerRequestCleanup(t *testing.T) { 14022 s := RunBasicJetStreamServer(t) 14023 defer s.Shutdown() 14024 14025 nc, js := jsClientConnect(t, s) 14026 defer nc.Close() 14027 14028 _, err := js.AddStream(&nats.StreamConfig{Name: "T", Storage: nats.MemoryStorage}) 14029 require_NoError(t, err) 14030 14031 _, err = js.AddConsumer("T", &nats.ConsumerConfig{Durable: "dlc", AckPolicy: nats.AckExplicitPolicy}) 14032 require_NoError(t, err) 14033 14034 req := &JSApiConsumerGetNextRequest{Batch: 10, Expires: 100 * time.Millisecond} 14035 jreq, err := json.Marshal(req) 14036 require_NoError(t, err) 14037 14038 // Need interest otherwise the requests will be recycled based on that. 14039 _, err = nc.SubscribeSync("xx") 14040 require_NoError(t, err) 14041 14042 // Queue up 100 requests. 14043 rsubj := fmt.Sprintf(JSApiRequestNextT, "T", "dlc") 14044 for i := 0; i < 100; i++ { 14045 err = nc.PublishRequest(rsubj, "xx", jreq) 14046 require_NoError(t, err) 14047 } 14048 // Wait to expire 14049 time.Sleep(200 * time.Millisecond) 14050 14051 ci, err := js.ConsumerInfo("T", "dlc") 14052 require_NoError(t, err) 14053 14054 if ci.NumWaiting != 0 { 14055 t.Fatalf("Expected to see no waiting requests, got %d", ci.NumWaiting) 14056 } 14057 } 14058 14059 func TestJetStreamPullConsumerRequestMaximums(t *testing.T) { 14060 s := RunBasicJetStreamServer(t) 14061 defer s.Shutdown() 14062 14063 nc, _ := jsClientConnect(t, s) 14064 defer nc.Close() 14065 14066 // Need to do this via server for now. 14067 acc := s.GlobalAccount() 14068 mset, err := acc.addStream(&StreamConfig{Name: "TEST", Storage: MemoryStorage}) 14069 require_NoError(t, err) 14070 14071 _, err = mset.addConsumer(&ConsumerConfig{ 14072 Durable: "dlc", 14073 MaxRequestBatch: 10, 14074 MaxRequestMaxBytes: 10_000, 14075 MaxRequestExpires: time.Second, 14076 AckPolicy: AckExplicit, 14077 }) 14078 require_NoError(t, err) 14079 14080 genReq := func(b, mb int, e time.Duration) []byte { 14081 req := &JSApiConsumerGetNextRequest{Batch: b, Expires: e, MaxBytes: mb} 14082 jreq, err := json.Marshal(req) 14083 require_NoError(t, err) 14084 return jreq 14085 } 14086 14087 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 14088 14089 // Exceeds max batch size. 14090 resp, err := nc.Request(rsubj, genReq(11, 0, 100*time.Millisecond), time.Second) 14091 require_NoError(t, err) 14092 if status := resp.Header.Get("Status"); status != "409" { 14093 t.Fatalf("Expected a 409 status code, got %q", status) 14094 } 14095 14096 // Exceeds max expires. 14097 resp, err = nc.Request(rsubj, genReq(1, 0, 10*time.Minute), time.Second) 14098 require_NoError(t, err) 14099 if status := resp.Header.Get("Status"); status != "409" { 14100 t.Fatalf("Expected a 409 status code, got %q", status) 14101 } 14102 14103 // Exceeds max bytes. 14104 resp, err = nc.Request(rsubj, genReq(10, 10_000*2, 10*time.Minute), time.Second) 14105 require_NoError(t, err) 14106 if status := resp.Header.Get("Status"); status != "409" { 14107 t.Fatalf("Expected a 409 status code, got %q", status) 14108 } 14109 } 14110 14111 func TestJetStreamEphemeralPullConsumers(t *testing.T) { 14112 s := RunBasicJetStreamServer(t) 14113 defer s.Shutdown() 14114 14115 nc, js := jsClientConnect(t, s) 14116 defer nc.Close() 14117 14118 _, err := js.AddStream(&nats.StreamConfig{Name: "EC", Storage: nats.MemoryStorage}) 14119 require_NoError(t, err) 14120 14121 ci, err := js.AddConsumer("EC", &nats.ConsumerConfig{AckPolicy: nats.AckExplicitPolicy}) 14122 require_NoError(t, err) 14123 14124 mset, err := s.GlobalAccount().lookupStream("EC") 14125 require_NoError(t, err) 14126 o := mset.lookupConsumer(ci.Name) 14127 if o == nil { 14128 t.Fatalf("Error looking up consumer %q", ci.Name) 14129 } 14130 err = o.setInActiveDeleteThreshold(50 * time.Millisecond) 14131 require_NoError(t, err) 14132 14133 time.Sleep(100 * time.Millisecond) 14134 // Should no longer be around. 14135 if o := mset.lookupConsumer(ci.Name); o != nil { 14136 t.Fatalf("Expected consumer to be closed and removed") 14137 } 14138 14139 // Make sure timer keeps firing etc. and does not delete until interest is gone. 14140 ci, err = js.AddConsumer("EC", &nats.ConsumerConfig{AckPolicy: nats.AckExplicitPolicy}) 14141 require_NoError(t, err) 14142 if o = mset.lookupConsumer(ci.Name); o == nil { 14143 t.Fatalf("Error looking up consumer %q", ci.Name) 14144 } 14145 err = o.setInActiveDeleteThreshold(50 * time.Millisecond) 14146 require_NoError(t, err) 14147 14148 // Need interest otherwise the requests will be recycled based on no real interest. 14149 sub, err := nc.SubscribeSync("xx") 14150 require_NoError(t, err) 14151 14152 req := &JSApiConsumerGetNextRequest{Batch: 10, Expires: 250 * time.Millisecond} 14153 jreq, err := json.Marshal(req) 14154 require_NoError(t, err) 14155 rsubj := fmt.Sprintf(JSApiRequestNextT, "EC", ci.Name) 14156 err = nc.PublishRequest(rsubj, "xx", jreq) 14157 require_NoError(t, err) 14158 nc.Flush() 14159 14160 time.Sleep(100 * time.Millisecond) 14161 // Should still be alive here. 14162 if o := mset.lookupConsumer(ci.Name); o == nil { 14163 t.Fatalf("Expected consumer to still be active") 14164 } 14165 // Remove interest. 14166 sub.Unsubscribe() 14167 // Make sure this EPC goes away now. 14168 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14169 if o := mset.lookupConsumer(ci.Name); o != nil { 14170 return fmt.Errorf("Consumer still present") 14171 } 14172 return nil 14173 }) 14174 } 14175 14176 func TestJetStreamEphemeralPullConsumersInactiveThresholdAndNoWait(t *testing.T) { 14177 s := RunBasicJetStreamServer(t) 14178 defer s.Shutdown() 14179 14180 nc, js := jsClientConnect(t, s) 14181 defer nc.Close() 14182 14183 _, err := js.AddStream(&nats.StreamConfig{Name: "ECIT", Storage: nats.MemoryStorage}) 14184 require_NoError(t, err) 14185 14186 ci, err := js.AddConsumer("ECIT", &nats.ConsumerConfig{ 14187 AckPolicy: nats.AckExplicitPolicy, 14188 InactiveThreshold: 100 * time.Millisecond, 14189 }) 14190 require_NoError(t, err) 14191 14192 // Send 10 no_wait requests every 25ms and consumer should still be present. 14193 req := &JSApiConsumerGetNextRequest{Batch: 10, NoWait: true} 14194 jreq, err := json.Marshal(req) 14195 require_NoError(t, err) 14196 rsubj := fmt.Sprintf(JSApiRequestNextT, "ECIT", ci.Name) 14197 for i := 0; i < 10; i++ { 14198 err = nc.PublishRequest(rsubj, "xx", jreq) 14199 require_NoError(t, err) 14200 nc.Flush() 14201 time.Sleep(25 * time.Millisecond) 14202 } 14203 14204 _, err = js.ConsumerInfo("ECIT", ci.Name) 14205 require_NoError(t, err) 14206 } 14207 14208 func TestJetStreamPullConsumerCrossAccountExpires(t *testing.T) { 14209 conf := createConfFile(t, []byte(fmt.Sprintf(` 14210 listen: 127.0.0.1:-1 14211 jetstream: {max_mem_store: 4GB, max_file_store: 1TB, store_dir: %q} 14212 accounts: { 14213 JS: { 14214 jetstream: enabled 14215 users: [ {user: dlc, password: foo} ] 14216 exports [ { service: "$JS.API.CONSUMER.MSG.NEXT.>", response: stream } ] 14217 }, 14218 IU: { 14219 users: [ {user: mh, password: bar} ] 14220 imports [ { service: { subject: "$JS.API.CONSUMER.MSG.NEXT.*.*", account: JS } }] 14221 # Re-export for dasiy chain test. 14222 exports [ { service: "$JS.API.CONSUMER.MSG.NEXT.>", response: stream } ] 14223 }, 14224 IU2: { 14225 users: [ {user: ik, password: bar} ] 14226 imports [ { service: { subject: "$JS.API.CONSUMER.MSG.NEXT.*.*", account: IU } } ] 14227 }, 14228 } 14229 `, t.TempDir()))) 14230 14231 s, _ := RunServerWithConfig(conf) 14232 defer s.Shutdown() 14233 14234 // Connect to JS account and create stream, put some messages into it. 14235 nc, js := jsClientConnect(t, s, nats.UserInfo("dlc", "foo")) 14236 defer nc.Close() 14237 14238 _, err := js.AddStream(&nats.StreamConfig{Name: "PC", Subjects: []string{"foo"}}) 14239 require_NoError(t, err) 14240 14241 toSend := 50 14242 for i := 0; i < toSend; i++ { 14243 _, err := js.Publish("foo", []byte("OK")) 14244 require_NoError(t, err) 14245 } 14246 14247 // Now create pull consumer. 14248 _, err = js.AddConsumer("PC", &nats.ConsumerConfig{Durable: "PC", AckPolicy: nats.AckExplicitPolicy}) 14249 require_NoError(t, err) 14250 14251 // Now access from the importing account. 14252 nc2, _ := jsClientConnect(t, s, nats.UserInfo("mh", "bar")) 14253 defer nc2.Close() 14254 14255 // Make sure batch request works properly with stream response. 14256 req := &JSApiConsumerGetNextRequest{Batch: 10} 14257 jreq, err := json.Marshal(req) 14258 require_NoError(t, err) 14259 rsubj := fmt.Sprintf(JSApiRequestNextT, "PC", "PC") 14260 // Make sure we can get a batch correctly etc. 14261 // This requires response stream above in the export definition. 14262 sub, err := nc2.SubscribeSync("xx") 14263 require_NoError(t, err) 14264 err = nc2.PublishRequest(rsubj, "xx", jreq) 14265 require_NoError(t, err) 14266 checkSubsPending(t, sub, 10) 14267 14268 // Now let's queue up a bunch of requests and then delete interest to make sure the system 14269 // removes those requests. 14270 14271 // Purge stream 14272 err = js.PurgeStream("PC") 14273 require_NoError(t, err) 14274 14275 // Queue up 10 requests 14276 for i := 0; i < 10; i++ { 14277 err = nc2.PublishRequest(rsubj, "xx", jreq) 14278 require_NoError(t, err) 14279 } 14280 // Since using different connection, flush to make sure processed. 14281 nc2.Flush() 14282 14283 ci, err := js.ConsumerInfo("PC", "PC") 14284 require_NoError(t, err) 14285 if ci.NumWaiting != 10 { 14286 t.Fatalf("Expected to see 10 waiting requests, got %d", ci.NumWaiting) 14287 } 14288 14289 // Now remove interest and make sure requests are removed. 14290 sub.Unsubscribe() 14291 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14292 ci, err := js.ConsumerInfo("PC", "PC") 14293 require_NoError(t, err) 14294 if ci.NumWaiting != 0 { 14295 return fmt.Errorf("Requests still present") 14296 } 14297 return nil 14298 }) 14299 14300 // Now let's test that ephemerals will go away as well when interest etc is no longer around. 14301 ci, err = js.AddConsumer("PC", &nats.ConsumerConfig{AckPolicy: nats.AckExplicitPolicy}) 14302 require_NoError(t, err) 14303 14304 // Set the inactivity threshold by hand for now. 14305 jsacc, err := s.LookupAccount("JS") 14306 require_NoError(t, err) 14307 mset, err := jsacc.lookupStream("PC") 14308 require_NoError(t, err) 14309 o := mset.lookupConsumer(ci.Name) 14310 if o == nil { 14311 t.Fatalf("Error looking up consumer %q", ci.Name) 14312 } 14313 err = o.setInActiveDeleteThreshold(50 * time.Millisecond) 14314 require_NoError(t, err) 14315 14316 rsubj = fmt.Sprintf(JSApiRequestNextT, "PC", ci.Name) 14317 sub, err = nc2.SubscribeSync("zz") 14318 require_NoError(t, err) 14319 err = nc2.PublishRequest(rsubj, "zz", jreq) 14320 require_NoError(t, err) 14321 14322 // Wait past inactive threshold. 14323 time.Sleep(100 * time.Millisecond) 14324 // Make sure it is still there.. 14325 ci, err = js.ConsumerInfo("PC", ci.Name) 14326 require_NoError(t, err) 14327 if ci.NumWaiting != 1 { 14328 t.Fatalf("Expected to see 1 waiting request, got %d", ci.NumWaiting) 14329 } 14330 14331 // Now release interest. 14332 sub.Unsubscribe() 14333 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14334 _, err := js.ConsumerInfo("PC", ci.Name) 14335 if err == nil { 14336 return fmt.Errorf("Consumer still present") 14337 } 14338 return nil 14339 }) 14340 14341 // Now test daisy chained. 14342 toSend = 10 14343 for i := 0; i < toSend; i++ { 14344 _, err := js.Publish("foo", []byte("OK")) 14345 require_NoError(t, err) 14346 } 14347 14348 ci, err = js.AddConsumer("PC", &nats.ConsumerConfig{AckPolicy: nats.AckExplicitPolicy}) 14349 require_NoError(t, err) 14350 14351 // Set the inactivity threshold by hand for now. 14352 o = mset.lookupConsumer(ci.Name) 14353 if o == nil { 14354 t.Fatalf("Error looking up consumer %q", ci.Name) 14355 } 14356 // Make this one longer so we test request purge and ephemerals in same test. 14357 err = o.setInActiveDeleteThreshold(500 * time.Millisecond) 14358 require_NoError(t, err) 14359 14360 // Now access from the importing account. 14361 nc3, _ := jsClientConnect(t, s, nats.UserInfo("ik", "bar")) 14362 defer nc3.Close() 14363 14364 sub, err = nc3.SubscribeSync("yy") 14365 require_NoError(t, err) 14366 14367 rsubj = fmt.Sprintf(JSApiRequestNextT, "PC", ci.Name) 14368 err = nc3.PublishRequest(rsubj, "yy", jreq) 14369 require_NoError(t, err) 14370 checkSubsPending(t, sub, 10) 14371 14372 // Purge stream 14373 err = js.PurgeStream("PC") 14374 require_NoError(t, err) 14375 14376 // Queue up 10 requests 14377 for i := 0; i < 10; i++ { 14378 err = nc3.PublishRequest(rsubj, "yy", jreq) 14379 require_NoError(t, err) 14380 } 14381 // Since using different connection, flush to make sure processed. 14382 nc3.Flush() 14383 14384 ci, err = js.ConsumerInfo("PC", ci.Name) 14385 require_NoError(t, err) 14386 if ci.NumWaiting != 10 { 14387 t.Fatalf("Expected to see 10 waiting requests, got %d", ci.NumWaiting) 14388 } 14389 14390 // Now remove interest and make sure requests are removed. 14391 sub.Unsubscribe() 14392 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14393 ci, err := js.ConsumerInfo("PC", ci.Name) 14394 require_NoError(t, err) 14395 if ci.NumWaiting != 0 { 14396 return fmt.Errorf("Requests still present") 14397 } 14398 return nil 14399 }) 14400 // Now make sure the ephemeral goes away too. 14401 // Ephemerals have jitter by default of up to 1s. 14402 checkFor(t, 6*time.Second, 10*time.Millisecond, func() error { 14403 _, err := js.ConsumerInfo("PC", ci.Name) 14404 if err == nil { 14405 return fmt.Errorf("Consumer still present") 14406 } 14407 return nil 14408 }) 14409 } 14410 14411 func TestJetStreamPullConsumerCrossAccountExpiresNoDataRace(t *testing.T) { 14412 conf := createConfFile(t, []byte(fmt.Sprintf(` 14413 listen: 127.0.0.1:-1 14414 jetstream: {max_mem_store: 4GB, max_file_store: 1TB, store_dir: %q} 14415 accounts: { 14416 JS: { 14417 jetstream: enabled 14418 users: [ {user: dlc, password: foo} ] 14419 exports [ { service: "$JS.API.CONSUMER.MSG.NEXT.>", response: stream } ] 14420 }, 14421 IU: { 14422 jetstream: enabled 14423 users: [ {user: ik, password: bar} ] 14424 imports [ { service: { subject: "$JS.API.CONSUMER.MSG.NEXT.*.*", account: JS } }] 14425 }, 14426 } 14427 `, t.TempDir()))) 14428 14429 test := func() { 14430 s, _ := RunServerWithConfig(conf) 14431 defer s.Shutdown() 14432 14433 // Connect to JS account and create stream, put some messages into it. 14434 nc, js := jsClientConnect(t, s, nats.UserInfo("dlc", "foo")) 14435 defer nc.Close() 14436 14437 _, err := js.AddStream(&nats.StreamConfig{Name: "PC", Subjects: []string{"foo"}}) 14438 require_NoError(t, err) 14439 14440 toSend := 100 14441 for i := 0; i < toSend; i++ { 14442 _, err := js.Publish("foo", []byte("OK")) 14443 require_NoError(t, err) 14444 } 14445 14446 // Create pull consumer. 14447 _, err = js.AddConsumer("PC", &nats.ConsumerConfig{Durable: "PC", AckPolicy: nats.AckExplicitPolicy}) 14448 require_NoError(t, err) 14449 14450 // Now access from the importing account. 14451 nc2, _ := jsClientConnect(t, s, nats.UserInfo("ik", "bar")) 14452 defer nc2.Close() 14453 14454 req := &JSApiConsumerGetNextRequest{Batch: 1} 14455 jreq, err := json.Marshal(req) 14456 require_NoError(t, err) 14457 rsubj := fmt.Sprintf(JSApiRequestNextT, "PC", "PC") 14458 sub, err := nc2.SubscribeSync("xx") 14459 require_NoError(t, err) 14460 14461 wg := sync.WaitGroup{} 14462 wg.Add(1) 14463 go func() { 14464 time.Sleep(5 * time.Millisecond) 14465 sub.Unsubscribe() 14466 wg.Done() 14467 }() 14468 for i := 0; i < toSend; i++ { 14469 nc2.PublishRequest(rsubj, "xx", jreq) 14470 } 14471 wg.Wait() 14472 } 14473 // Need to rerun this test several times to get the race (which then would possible be panic 14474 // such as: "fatal error: concurrent map read and map write" 14475 for iter := 0; iter < 10; iter++ { 14476 test() 14477 } 14478 } 14479 14480 // This tests account export/import replies across a LN connection with account import/export 14481 // on both sides of the LN. 14482 func TestJetStreamPullConsumerCrossAccountsAndLeafNodes(t *testing.T) { 14483 conf := createConfFile(t, []byte(fmt.Sprintf(` 14484 server_name: SJS 14485 listen: 127.0.0.1:-1 14486 jetstream: {max_mem_store: 4GB, max_file_store: 1TB, domain: JSD, store_dir: %q } 14487 accounts: { 14488 JS: { 14489 jetstream: enabled 14490 users: [ {user: dlc, password: foo} ] 14491 exports [ { service: "$JS.API.CONSUMER.MSG.NEXT.>", response: stream } ] 14492 }, 14493 IU: { 14494 users: [ {user: mh, password: bar} ] 14495 imports [ { service: { subject: "$JS.API.CONSUMER.MSG.NEXT.*.*", account: JS } }] 14496 }, 14497 } 14498 leaf { listen: "127.0.0.1:-1" } 14499 `, t.TempDir()))) 14500 14501 s, o := RunServerWithConfig(conf) 14502 defer s.Shutdown() 14503 14504 conf2 := createConfFile(t, []byte(fmt.Sprintf(` 14505 server_name: SLN 14506 listen: 127.0.0.1:-1 14507 accounts: { 14508 A: { 14509 users: [ {user: l, password: p} ] 14510 exports [ { service: "$JS.JSD.API.CONSUMER.MSG.NEXT.>", response: stream } ] 14511 }, 14512 B: { 14513 users: [ {user: m, password: p} ] 14514 imports [ { service: { subject: "$JS.JSD.API.CONSUMER.MSG.NEXT.*.*", account: A } }] 14515 }, 14516 } 14517 # bind local A to IU account on other side of LN. 14518 leaf { remotes [ { url: nats://mh:bar@127.0.0.1:%d; account: A } ] } 14519 `, o.LeafNode.Port))) 14520 14521 s2, _ := RunServerWithConfig(conf2) 14522 defer s2.Shutdown() 14523 14524 checkLeafNodeConnectedCount(t, s, 1) 14525 14526 // Connect to JS account, create stream and consumer and put in some messages. 14527 nc, js := jsClientConnect(t, s, nats.UserInfo("dlc", "foo")) 14528 defer nc.Close() 14529 14530 _, err := js.AddStream(&nats.StreamConfig{Name: "PC", Subjects: []string{"foo"}}) 14531 require_NoError(t, err) 14532 14533 toSend := 10 14534 for i := 0; i < toSend; i++ { 14535 _, err := js.Publish("foo", []byte("OK")) 14536 require_NoError(t, err) 14537 } 14538 14539 // Now create durable pull consumer. 14540 _, err = js.AddConsumer("PC", &nats.ConsumerConfig{Durable: "PC", AckPolicy: nats.AckExplicitPolicy}) 14541 require_NoError(t, err) 14542 14543 // Now access from the account on the leafnode, so importing on both sides and crossing a leafnode connection. 14544 nc2, _ := jsClientConnect(t, s2, nats.UserInfo("m", "p")) 14545 defer nc2.Close() 14546 14547 req := &JSApiConsumerGetNextRequest{Batch: toSend, Expires: 500 * time.Millisecond} 14548 jreq, err := json.Marshal(req) 14549 require_NoError(t, err) 14550 14551 // Make sure we can get a batch correctly etc. 14552 // This requires response stream above in the export definition. 14553 sub, err := nc2.SubscribeSync("xx") 14554 require_NoError(t, err) 14555 14556 rsubj := "$JS.JSD.API.CONSUMER.MSG.NEXT.PC.PC" 14557 err = nc2.PublishRequest(rsubj, "xx", jreq) 14558 require_NoError(t, err) 14559 checkSubsPending(t, sub, 10) 14560 14561 // Queue up a bunch of requests. 14562 for i := 0; i < 10; i++ { 14563 err = nc2.PublishRequest(rsubj, "xx", jreq) 14564 require_NoError(t, err) 14565 } 14566 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14567 ci, err := js.ConsumerInfo("PC", "PC") 14568 require_NoError(t, err) 14569 if ci.NumWaiting != 10 { 14570 return fmt.Errorf("Expected to see 10 waiting requests, got %d", ci.NumWaiting) 14571 } 14572 return nil 14573 }) 14574 14575 // Remove interest. 14576 sub.Unsubscribe() 14577 // Make sure requests go away eventually after they expire. 14578 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 14579 ci, err := js.ConsumerInfo("PC", "PC") 14580 require_NoError(t, err) 14581 if ci.NumWaiting != 0 { 14582 return fmt.Errorf("Expected to see no waiting requests, got %d", ci.NumWaiting) 14583 } 14584 return nil 14585 }) 14586 } 14587 14588 // This test is to explicitly test for all combinations of pull consumer behavior. 14589 // 1. Long poll, will be used to emulate push. A request is only invalidated when batch is filled, it expires, or we lose interest. 14590 // 2. Batch 1, will return no messages or a message. Works today. 14591 // 3. Conditional wait, or one shot. This is what the clients do when the do a fetch(). 14592 // They expect to wait up to a given time for any messages but will return once they have any to deliver, so parital fills. 14593 // 4. Try, which never waits at all ever. 14594 func TestJetStreamPullConsumersOneShotBehavior(t *testing.T) { 14595 s := RunBasicJetStreamServer(t) 14596 defer s.Shutdown() 14597 14598 // Client for API requests. 14599 nc, js := jsClientConnect(t, s) 14600 defer nc.Close() 14601 14602 _, err := js.AddStream(&nats.StreamConfig{ 14603 Name: "TEST", 14604 Subjects: []string{"foo"}, 14605 }) 14606 require_NoError(t, err) 14607 14608 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 14609 Durable: "dlc", 14610 AckPolicy: nats.AckExplicitPolicy, 14611 FilterSubject: "foo", 14612 }) 14613 require_NoError(t, err) 14614 14615 // We will do low level requests by hand for this test as to not depend on any client impl. 14616 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 14617 14618 getNext := func(batch int, expires time.Duration, noWait bool) (numMsgs int, elapsed time.Duration, hdr *nats.Header) { 14619 t.Helper() 14620 req := &JSApiConsumerGetNextRequest{Batch: batch, Expires: expires, NoWait: noWait} 14621 jreq, err := json.Marshal(req) 14622 require_NoError(t, err) 14623 // Create listener. 14624 reply, msgs := nats.NewInbox(), make(chan *nats.Msg, batch) 14625 sub, err := nc.ChanSubscribe(reply, msgs) 14626 require_NoError(t, err) 14627 defer sub.Unsubscribe() 14628 14629 // Send request. 14630 start := time.Now() 14631 err = nc.PublishRequest(rsubj, reply, jreq) 14632 require_NoError(t, err) 14633 14634 for { 14635 select { 14636 case m := <-msgs: 14637 if len(m.Data) == 0 && m.Header != nil { 14638 return numMsgs, time.Since(start), &m.Header 14639 } 14640 numMsgs++ 14641 if numMsgs >= batch { 14642 return numMsgs, time.Since(start), nil 14643 } 14644 case <-time.After(expires + 250*time.Millisecond): 14645 t.Fatalf("Did not receive all the msgs in time") 14646 } 14647 } 14648 } 14649 14650 expect := func(batch int, expires time.Duration, noWait bool, ne int, he *nats.Header, lt time.Duration, gt time.Duration) { 14651 t.Helper() 14652 n, e, h := getNext(batch, expires, noWait) 14653 if n != ne { 14654 t.Fatalf("Expected %d msgs, got %d", ne, n) 14655 } 14656 if !reflect.DeepEqual(h, he) { 14657 t.Fatalf("Expected %+v hdr, got %+v", he, h) 14658 } 14659 if lt > 0 && e > lt { 14660 t.Fatalf("Expected elapsed of %v to be less than %v", e, lt) 14661 } 14662 if gt > 0 && e < gt { 14663 t.Fatalf("Expected elapsed of %v to be greater than %v", e, gt) 14664 } 14665 } 14666 expectAfter := func(batch int, expires time.Duration, noWait bool, ne int, he *nats.Header, gt time.Duration) { 14667 t.Helper() 14668 expect(batch, expires, noWait, ne, he, 0, gt) 14669 } 14670 expectInstant := func(batch int, expires time.Duration, noWait bool, ne int, he *nats.Header) { 14671 t.Helper() 14672 expect(batch, expires, noWait, ne, he, 5*time.Millisecond, 0) 14673 } 14674 expectOK := func(batch int, expires time.Duration, noWait bool, ne int) { 14675 t.Helper() 14676 expectInstant(batch, expires, noWait, ne, nil) 14677 } 14678 14679 noMsgs := &nats.Header{"Status": []string{"404"}, "Description": []string{"No Messages"}} 14680 reqTimeout := &nats.Header{"Status": []string{"408"}, "Description": []string{"Request Timeout"}, "Nats-Pending-Bytes": []string{"0"}, "Nats-Pending-Messages": []string{"1"}} 14681 14682 // We are empty here, meaning no messages available. 14683 // Do not wait, should get noMsgs. 14684 expectInstant(1, 0, true, 0, noMsgs) 14685 // We should wait here for the full second. 14686 expectAfter(1, 250*time.Millisecond, false, 0, reqTimeout, 250*time.Millisecond) 14687 // This should also wait since no messages are available. This is the one shot scenario, or wait for at least a message if none are there. 14688 expectAfter(1, 500*time.Millisecond, true, 0, reqTimeout, 500*time.Millisecond) 14689 14690 // Now let's put some messages into the system. 14691 for i := 0; i < 20; i++ { 14692 _, err := js.Publish("foo", []byte("HELLO")) 14693 require_NoError(t, err) 14694 } 14695 14696 // Now run same 3 scenarios. 14697 expectOK(1, 0, true, 1) 14698 expectOK(5, 500*time.Millisecond, false, 5) 14699 expectOK(5, 500*time.Millisecond, true, 5) 14700 } 14701 14702 func TestJetStreamPullConsumersMultipleRequestsExpireOutOfOrder(t *testing.T) { 14703 s := RunBasicJetStreamServer(t) 14704 defer s.Shutdown() 14705 14706 // Client for API requests. 14707 nc, js := jsClientConnect(t, s) 14708 defer nc.Close() 14709 14710 _, err := js.AddStream(&nats.StreamConfig{ 14711 Name: "TEST", 14712 Subjects: []string{"foo"}, 14713 }) 14714 require_NoError(t, err) 14715 14716 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 14717 Durable: "dlc", 14718 AckPolicy: nats.AckExplicitPolicy, 14719 FilterSubject: "foo", 14720 }) 14721 require_NoError(t, err) 14722 14723 // We will now queue up 4 requests. All should expire but they will do so out of order. 14724 // We want to make sure we get them in correct order. 14725 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 14726 sub, err := nc.SubscribeSync("i.*") 14727 require_NoError(t, err) 14728 defer sub.Unsubscribe() 14729 14730 for _, expires := range []time.Duration{200, 100, 25, 75} { 14731 reply := fmt.Sprintf("i.%d", expires) 14732 req := &JSApiConsumerGetNextRequest{Expires: expires * time.Millisecond} 14733 jreq, err := json.Marshal(req) 14734 require_NoError(t, err) 14735 err = nc.PublishRequest(rsubj, reply, jreq) 14736 require_NoError(t, err) 14737 } 14738 start := time.Now() 14739 checkSubsPending(t, sub, 4) 14740 elapsed := time.Since(start) 14741 14742 if elapsed < 200*time.Millisecond || elapsed > 500*time.Millisecond { 14743 t.Fatalf("Expected elapsed to be close to %v, but got %v", 200*time.Millisecond, elapsed) 14744 } 14745 14746 var rs []string 14747 for i := 0; i < 4; i++ { 14748 m, err := sub.NextMsg(0) 14749 require_NoError(t, err) 14750 rs = append(rs, m.Subject) 14751 } 14752 if expected := []string{"i.25", "i.75", "i.100", "i.200"}; !reflect.DeepEqual(rs, expected) { 14753 t.Fatalf("Received in wrong order, wanted %+v, got %+v", expected, rs) 14754 } 14755 } 14756 14757 func TestJetStreamConsumerUpdateSurvival(t *testing.T) { 14758 s := RunBasicJetStreamServer(t) 14759 defer s.Shutdown() 14760 14761 nc, js := jsClientConnect(t, s) 14762 defer nc.Close() 14763 14764 _, err := js.AddStream(&nats.StreamConfig{Name: "X"}) 14765 require_NoError(t, err) 14766 14767 // First create a consumer with max ack pending. 14768 _, err = js.AddConsumer("X", &nats.ConsumerConfig{ 14769 Durable: "dlc", 14770 AckPolicy: nats.AckExplicitPolicy, 14771 MaxAckPending: 1024, 14772 }) 14773 require_NoError(t, err) 14774 14775 // Now do same name but pull. This will update the MaxAcKPending 14776 ci, err := js.UpdateConsumer("X", &nats.ConsumerConfig{ 14777 Durable: "dlc", 14778 AckPolicy: nats.AckExplicitPolicy, 14779 MaxAckPending: 22, 14780 }) 14781 require_NoError(t, err) 14782 14783 if ci.Config.MaxAckPending != 22 { 14784 t.Fatalf("Expected MaxAckPending to be 22, got %d", ci.Config.MaxAckPending) 14785 } 14786 14787 // Make sure this survives across a restart. 14788 sd := s.JetStreamConfig().StoreDir 14789 s.Shutdown() 14790 // Restart. 14791 s = RunJetStreamServerOnPort(-1, sd) 14792 defer s.Shutdown() 14793 14794 nc, js = jsClientConnect(t, s) 14795 defer nc.Close() 14796 14797 ci, err = js.ConsumerInfo("X", "dlc") 14798 require_NoError(t, err) 14799 14800 if ci.Config.MaxAckPending != 22 { 14801 t.Fatalf("Expected MaxAckPending to be 22, got %d", ci.Config.MaxAckPending) 14802 } 14803 } 14804 14805 func TestJetStreamNakRedeliveryWithNoWait(t *testing.T) { 14806 s := RunBasicJetStreamServer(t) 14807 defer s.Shutdown() 14808 14809 nc, js := jsClientConnect(t, s) 14810 defer nc.Close() 14811 14812 _, err := js.AddStream(&nats.StreamConfig{ 14813 Name: "TEST", 14814 Subjects: []string{"foo"}, 14815 }) 14816 require_NoError(t, err) 14817 14818 _, err = js.Publish("foo", []byte("NAK")) 14819 require_NoError(t, err) 14820 14821 ccReq := &CreateConsumerRequest{ 14822 Stream: "TEST", 14823 Config: ConsumerConfig{ 14824 Durable: "dlc", 14825 AckPolicy: AckExplicit, 14826 MaxDeliver: 3, 14827 AckWait: time.Minute, 14828 BackOff: []time.Duration{5 * time.Second, 10 * time.Second}, 14829 }, 14830 } 14831 // Do by hand for now until Go client catches up. 14832 req, err := json.Marshal(ccReq) 14833 require_NoError(t, err) 14834 resp, err := nc.Request(fmt.Sprintf(JSApiDurableCreateT, "TEST", "dlc"), req, time.Second) 14835 require_NoError(t, err) 14836 var ccResp JSApiConsumerCreateResponse 14837 err = json.Unmarshal(resp.Data, &ccResp) 14838 require_NoError(t, err) 14839 if ccResp.Error != nil { 14840 t.Fatalf("Unexpected error: %+v", ccResp.Error) 14841 } 14842 14843 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 14844 m, err := nc.Request(rsubj, nil, time.Second) 14845 require_NoError(t, err) 14846 14847 // NAK this message. 14848 delay, err := json.Marshal(&ConsumerNakOptions{Delay: 500 * time.Millisecond}) 14849 require_NoError(t, err) 14850 dnak := []byte(fmt.Sprintf("%s %s", AckNak, delay)) 14851 m.Respond(dnak) 14852 14853 // This message should come back to us after 500ms. If we do a one-shot request, with NoWait and Expires 14854 // this will do the right thing and we get the message. 14855 // What we want to test here is a true NoWait request with Expires==0 and eventually seeing the message be redelivered. 14856 expires := time.Now().Add(time.Second) 14857 for time.Now().Before(expires) { 14858 m, err = nc.Request(rsubj, []byte(`{"batch":1, "no_wait": true}`), time.Second) 14859 require_NoError(t, err) 14860 if len(m.Data) > 0 { 14861 // We got our message, so we are good. 14862 return 14863 } 14864 // So we do not spin. 14865 time.Sleep(100 * time.Millisecond) 14866 } 14867 t.Fatalf("Did not get the message in time") 14868 } 14869 14870 // Test that we properly enforce per subject msg limits when DiscardNew is set. 14871 // DiscardNew should only apply to stream limits, subject based limits should always be DiscardOld. 14872 func TestJetStreamMaxMsgsPerSubjectWithDiscardNew(t *testing.T) { 14873 msc := StreamConfig{ 14874 Name: "TEST", 14875 Subjects: []string{"foo", "bar", "baz", "x"}, 14876 Discard: DiscardNew, 14877 Storage: MemoryStorage, 14878 MaxMsgsPer: 4, 14879 MaxMsgs: 10, 14880 MaxBytes: 500, 14881 } 14882 fsc := msc 14883 fsc.Storage = FileStorage 14884 14885 cases := []struct { 14886 name string 14887 mconfig *StreamConfig 14888 }{ 14889 {"MemoryStore", &msc}, 14890 {"FileStore", &fsc}, 14891 } 14892 14893 for _, c := range cases { 14894 t.Run(c.name, func(t *testing.T) { 14895 s := RunBasicJetStreamServer(t) 14896 defer s.Shutdown() 14897 14898 mset, err := s.GlobalAccount().addStream(c.mconfig) 14899 require_NoError(t, err) 14900 defer mset.delete() 14901 14902 // Client for API requests. 14903 nc, js := jsClientConnect(t, s) 14904 defer nc.Close() 14905 14906 pubAndCheck := func(subj string, num int, expectedNumMsgs uint64) { 14907 t.Helper() 14908 for i := 0; i < num; i++ { 14909 _, err = js.Publish(subj, []byte("TSLA")) 14910 require_NoError(t, err) 14911 } 14912 si, err := js.StreamInfo("TEST") 14913 require_NoError(t, err) 14914 if si.State.Msgs != expectedNumMsgs { 14915 t.Fatalf("Expected %d msgs, got %d", expectedNumMsgs, si.State.Msgs) 14916 } 14917 } 14918 14919 pubExpectErr := func(subj string, sz int) { 14920 t.Helper() 14921 _, err = js.Publish(subj, bytes.Repeat([]byte("X"), sz)) 14922 require_Error(t, err, errors.New("nats: maximum bytes exceeded"), errors.New("nats: maximum messages exceeded")) 14923 } 14924 14925 pubAndCheck("foo", 1, 1) 14926 // We should treat this as DiscardOld and only have 4 msgs after. 14927 pubAndCheck("foo", 4, 4) 14928 // Same thing here, shoud only have 4 foo and 4 bar for total of 8. 14929 pubAndCheck("bar", 8, 8) 14930 // We have 8 here, so only 2 left. If we add in a new subject when we have room it will be accepted. 14931 pubAndCheck("baz", 2, 10) 14932 // Now we are full, but makeup is foo-4 bar-4 baz-2. 14933 // We can add to foo and bar since they are at their max and adding new ones there stays the same in terms of total of 10. 14934 pubAndCheck("foo", 1, 10) 14935 pubAndCheck("bar", 1, 10) 14936 // Try to send a large message under an established subject that will exceed the 500 maximum. 14937 // Even though we have a bar subject and its at its maximum, the message to be dropped is not big enough, so this should err. 14938 pubExpectErr("bar", 300) 14939 // Also even though we have room bytes wise, if we introduce a new subject this should fail too on msg limit exceeded. 14940 pubExpectErr("x", 2) 14941 }) 14942 } 14943 } 14944 14945 func TestJetStreamStreamInfoSubjectsDetails(t *testing.T) { 14946 s := RunBasicJetStreamServer(t) 14947 defer s.Shutdown() 14948 14949 nc, js := jsClientConnect(t, s) 14950 defer nc.Close() 14951 14952 getInfo := func(t *testing.T, filter string) *StreamInfo { 14953 t.Helper() 14954 // Need to grab StreamInfo by hand for now. 14955 req, err := json.Marshal(&JSApiStreamInfoRequest{SubjectsFilter: filter}) 14956 require_NoError(t, err) 14957 resp, err := nc.Request(fmt.Sprintf(JSApiStreamInfoT, "TEST"), req, time.Second) 14958 require_NoError(t, err) 14959 var si StreamInfo 14960 err = json.Unmarshal(resp.Data, &si) 14961 require_NoError(t, err) 14962 if si.State.NumSubjects != 3 { 14963 t.Fatalf("Expected NumSubjects to be 3, but got %d", si.State.NumSubjects) 14964 } 14965 return &si 14966 } 14967 14968 testSubjects := func(t *testing.T, st nats.StorageType) { 14969 _, err := js.AddStream(&nats.StreamConfig{ 14970 Name: "TEST", 14971 Subjects: []string{"*"}, 14972 Storage: st, 14973 }) 14974 require_NoError(t, err) 14975 defer js.DeleteStream("TEST") 14976 14977 counts, msg := []int{22, 33, 44}, []byte("ok") 14978 // Now place msgs, foo-22, bar-33 and baz-44. 14979 for i, subj := range []string{"foo", "bar", "baz"} { 14980 for n := 0; n < counts[i]; n++ { 14981 _, err = js.Publish(subj, msg) 14982 require_NoError(t, err) 14983 } 14984 } 14985 14986 // Test all subjects first. 14987 expected := map[string]uint64{"foo": 22, "bar": 33, "baz": 44} 14988 if si := getInfo(t, nats.AllKeys); !reflect.DeepEqual(si.State.Subjects, expected) { 14989 t.Fatalf("Expected subjects of %+v, but got %+v", expected, si.State.Subjects) 14990 } 14991 if si := getInfo(t, "*"); !reflect.DeepEqual(si.State.Subjects, expected) { 14992 t.Fatalf("Expected subjects of %+v, but got %+v", expected, si.State.Subjects) 14993 } 14994 // Filtered to 1. 14995 expected = map[string]uint64{"foo": 22} 14996 if si := getInfo(t, "foo"); !reflect.DeepEqual(si.State.Subjects, expected) { 14997 t.Fatalf("Expected subjects of %+v, but got %+v", expected, si.State.Subjects) 14998 } 14999 } 15000 15001 t.Run("MemoryStore", func(t *testing.T) { testSubjects(t, nats.MemoryStorage) }) 15002 t.Run("FileStore", func(t *testing.T) { testSubjects(t, nats.FileStorage) }) 15003 } 15004 15005 func TestJetStreamStreamInfoSubjectsDetailsWithDeleteAndPurge(t *testing.T) { 15006 s := RunBasicJetStreamServer(t) 15007 defer s.Shutdown() 15008 15009 nc, js := jsClientConnect(t, s) 15010 defer nc.Close() 15011 15012 getInfo := func(t *testing.T, filter string) *StreamInfo { 15013 t.Helper() 15014 // Need to grab StreamInfo by hand for now. 15015 req, err := json.Marshal(&JSApiStreamInfoRequest{SubjectsFilter: filter}) 15016 require_NoError(t, err) 15017 resp, err := nc.Request(fmt.Sprintf(JSApiStreamInfoT, "TEST"), req, time.Second) 15018 require_NoError(t, err) 15019 var si StreamInfo 15020 err = json.Unmarshal(resp.Data, &si) 15021 require_NoError(t, err) 15022 return &si 15023 } 15024 15025 checkResults := func(t *testing.T, expected map[string]uint64) { 15026 t.Helper() 15027 si := getInfo(t, nats.AllKeys) 15028 if !reflect.DeepEqual(si.State.Subjects, expected) { 15029 t.Fatalf("Expected subjects of %+v, but got %+v", expected, si.State.Subjects) 15030 } 15031 if si.State.NumSubjects != len(expected) { 15032 t.Fatalf("Expected NumSubjects to be %d, but got %d", len(expected), si.State.NumSubjects) 15033 } 15034 } 15035 15036 testSubjects := func(t *testing.T, st nats.StorageType) { 15037 _, err := js.AddStream(&nats.StreamConfig{ 15038 Name: "TEST", 15039 Subjects: []string{"*"}, 15040 Storage: st, 15041 }) 15042 require_NoError(t, err) 15043 defer js.DeleteStream("TEST") 15044 15045 msg := []byte("ok") 15046 js.Publish("foo", msg) // 1 15047 js.Publish("foo", msg) // 2 15048 js.Publish("bar", msg) // 3 15049 js.Publish("baz", msg) // 4 15050 js.Publish("baz", msg) // 5 15051 js.Publish("bar", msg) // 6 15052 js.Publish("bar", msg) // 7 15053 15054 checkResults(t, map[string]uint64{"foo": 2, "bar": 3, "baz": 2}) 15055 15056 // Now delete some messages. 15057 js.DeleteMsg("TEST", 6) 15058 15059 checkResults(t, map[string]uint64{"foo": 2, "bar": 2, "baz": 2}) 15060 15061 // Delete and add right back, so no-op 15062 js.DeleteMsg("TEST", 5) // baz 15063 js.Publish("baz", msg) // 8 15064 15065 checkResults(t, map[string]uint64{"foo": 2, "bar": 2, "baz": 2}) 15066 15067 // Now do a purge only of bar. 15068 jr, _ := json.Marshal(&JSApiStreamPurgeRequest{Subject: "bar"}) 15069 _, err = nc.Request(fmt.Sprintf(JSApiStreamPurgeT, "TEST"), jr, time.Second) 15070 require_NoError(t, err) 15071 15072 checkResults(t, map[string]uint64{"foo": 2, "baz": 2}) 15073 15074 // Now purge everything 15075 err = js.PurgeStream("TEST") 15076 require_NoError(t, err) 15077 15078 si := getInfo(t, nats.AllKeys) 15079 if len(si.State.Subjects) != 0 { 15080 t.Fatalf("Expected no subjects, but got %+v", si.State.Subjects) 15081 } 15082 if si.State.NumSubjects != 0 { 15083 t.Fatalf("Expected NumSubjects to be 0, but got %d", si.State.NumSubjects) 15084 } 15085 } 15086 15087 t.Run("MemoryStore", func(t *testing.T) { testSubjects(t, nats.MemoryStorage) }) 15088 t.Run("FileStore", func(t *testing.T) { testSubjects(t, nats.FileStorage) }) 15089 } 15090 15091 func TestJetStreamStreamInfoSubjectsDetailsAfterRestart(t *testing.T) { 15092 s := RunBasicJetStreamServer(t) 15093 defer s.Shutdown() 15094 15095 nc, js := jsClientConnect(t, s) 15096 defer nc.Close() 15097 15098 getInfo := func(t *testing.T, filter string) *StreamInfo { 15099 t.Helper() 15100 // Need to grab StreamInfo by hand for now. 15101 req, err := json.Marshal(&JSApiStreamInfoRequest{SubjectsFilter: filter}) 15102 require_NoError(t, err) 15103 resp, err := nc.Request(fmt.Sprintf(JSApiStreamInfoT, "TEST"), req, time.Second) 15104 require_NoError(t, err) 15105 var si StreamInfo 15106 err = json.Unmarshal(resp.Data, &si) 15107 require_NoError(t, err) 15108 return &si 15109 } 15110 15111 _, err := js.AddStream(&nats.StreamConfig{ 15112 Name: "TEST", 15113 Subjects: []string{"*"}, 15114 }) 15115 require_NoError(t, err) 15116 defer js.DeleteStream("TEST") 15117 15118 msg := []byte("ok") 15119 js.Publish("foo", msg) // 1 15120 js.Publish("foo", msg) // 2 15121 js.Publish("bar", msg) // 3 15122 js.Publish("baz", msg) // 4 15123 js.Publish("baz", msg) // 5 15124 15125 si := getInfo(t, nats.AllKeys) 15126 if si.State.NumSubjects != 3 { 15127 t.Fatalf("Expected 3 subjects, but got %d", si.State.NumSubjects) 15128 } 15129 15130 // Stop current 15131 nc.Close() 15132 sd := s.JetStreamConfig().StoreDir 15133 s.Shutdown() 15134 // Restart. 15135 s = RunJetStreamServerOnPort(-1, sd) 15136 defer s.Shutdown() 15137 15138 nc, _ = jsClientConnect(t, s) 15139 defer nc.Close() 15140 15141 si = getInfo(t, nats.AllKeys) 15142 if si.State.NumSubjects != 3 { 15143 t.Fatalf("Expected 3 subjects, but got %d", si.State.NumSubjects) 15144 } 15145 } 15146 15147 // Issue #2836 15148 func TestJetStreamInterestRetentionBug(t *testing.T) { 15149 s := RunBasicJetStreamServer(t) 15150 defer s.Shutdown() 15151 15152 nc, js := jsClientConnect(t, s) 15153 defer nc.Close() 15154 15155 _, err := js.AddStream(&nats.StreamConfig{ 15156 Name: "TEST", 15157 Subjects: []string{"foo.>"}, 15158 Retention: nats.InterestPolicy, 15159 }) 15160 require_NoError(t, err) 15161 15162 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{Durable: "c1", AckPolicy: nats.AckExplicitPolicy}) 15163 require_NoError(t, err) 15164 15165 test := func(token string, fseq, msgs uint64) { 15166 t.Helper() 15167 subj := fmt.Sprintf("foo.%s", token) 15168 _, err = js.Publish(subj, nil) 15169 require_NoError(t, err) 15170 si, err := js.StreamInfo("TEST") 15171 require_NoError(t, err) 15172 if si.State.FirstSeq != fseq { 15173 t.Fatalf("Expected first to be %d, got %d", fseq, si.State.FirstSeq) 15174 } 15175 if si.State.Msgs != msgs { 15176 t.Fatalf("Expected msgs to be %d, got %d", msgs, si.State.Msgs) 15177 } 15178 } 15179 15180 test("bar", 1, 1) 15181 15182 // Create second filtered consumer. 15183 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{Durable: "c2", FilterSubject: "foo.foo", AckPolicy: nats.AckExplicitPolicy}) 15184 require_NoError(t, err) 15185 15186 test("bar", 1, 2) 15187 } 15188 15189 // Under load testing for K3S and the KINE interface we saw some stalls. 15190 // These were caused by a dynamic that would not send a second FC item with one 15191 // pending, but when we sent the next message and got blocked, if that msg would 15192 // exceed the outstanding FC we would become stalled. 15193 func TestJetStreamFlowControlStall(t *testing.T) { 15194 s := RunBasicJetStreamServer(t) 15195 defer s.Shutdown() 15196 15197 nc, js := jsClientConnect(t, s) 15198 defer nc.Close() 15199 15200 _, err := js.AddStream(&nats.StreamConfig{Name: "FC"}) 15201 require_NoError(t, err) 15202 15203 msg := []byte(strings.Repeat("X", 32768)) 15204 _, err = js.Publish("FC", msg) 15205 require_NoError(t, err) 15206 15207 msg = []byte(strings.Repeat("X", 8*32768)) 15208 _, err = js.Publish("FC", msg) 15209 require_NoError(t, err) 15210 _, err = js.Publish("FC", msg) 15211 require_NoError(t, err) 15212 15213 sub, err := js.SubscribeSync("FC", nats.OrderedConsumer()) 15214 require_NoError(t, err) 15215 15216 checkSubsPending(t, sub, 3) 15217 } 15218 15219 func TestJetStreamConsumerPendingCountWithRedeliveries(t *testing.T) { 15220 s := RunBasicJetStreamServer(t) 15221 defer s.Shutdown() 15222 15223 nc, js := jsClientConnect(t, s) 15224 defer nc.Close() 15225 15226 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"foo"}}) 15227 require_NoError(t, err) 15228 15229 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 15230 Durable: "test", 15231 AckPolicy: nats.AckExplicitPolicy, 15232 AckWait: 50 * time.Millisecond, 15233 MaxDeliver: 1, 15234 }) 15235 require_NoError(t, err) 15236 15237 // Publish 1st message 15238 _, err = js.Publish("foo", []byte("msg1")) 15239 require_NoError(t, err) 15240 15241 sub, err := js.PullSubscribe("foo", "test") 15242 require_NoError(t, err) 15243 msgs, err := sub.Fetch(1) 15244 require_NoError(t, err) 15245 for _, m := range msgs { 15246 require_Equal(t, string(m.Data), "msg1") 15247 // Do not ack the message 15248 } 15249 // Check consumer info, pending should be 0 15250 ci, err := js.ConsumerInfo("TEST", "test") 15251 require_NoError(t, err) 15252 if ci.NumPending != 0 { 15253 t.Fatalf("Expected consumer info pending count to be 0, got %v", ci.NumPending) 15254 } 15255 15256 // Wait for more than expiration 15257 time.Sleep(100 * time.Millisecond) 15258 15259 // Publish 2nd message 15260 _, err = js.Publish("foo", []byte("msg2")) 15261 require_NoError(t, err) 15262 15263 msgs, err = sub.Fetch(1) 15264 require_NoError(t, err) 15265 for _, m := range msgs { 15266 require_Equal(t, string(m.Data), "msg2") 15267 // Its deliver count should be 1 15268 meta, err := m.Metadata() 15269 require_NoError(t, err) 15270 if meta.NumDelivered != 1 { 15271 t.Fatalf("Expected message's deliver count to be 1, got %v", meta.NumDelivered) 15272 } 15273 } 15274 // Check consumer info, pending should be 0 15275 ci, err = js.ConsumerInfo("TEST", "test") 15276 require_NoError(t, err) 15277 if ci.NumPending != 0 { 15278 t.Fatalf("Expected consumer info pending count to be 0, got %v", ci.NumPending) 15279 } 15280 } 15281 15282 func TestJetStreamPullConsumerHeartBeats(t *testing.T) { 15283 s := RunBasicJetStreamServer(t) 15284 defer s.Shutdown() 15285 15286 nc, js := jsClientConnect(t, s) 15287 defer nc.Close() 15288 15289 _, err := js.AddStream(&nats.StreamConfig{Name: "T", Storage: nats.MemoryStorage}) 15290 require_NoError(t, err) 15291 15292 _, err = js.AddConsumer("T", &nats.ConsumerConfig{Durable: "dlc", AckPolicy: nats.AckExplicitPolicy}) 15293 require_NoError(t, err) 15294 15295 rsubj := fmt.Sprintf(JSApiRequestNextT, "T", "dlc") 15296 15297 type tsMsg struct { 15298 received time.Time 15299 msg *nats.Msg 15300 } 15301 15302 doReq := func(batch int, hb, expires time.Duration, expected int) []*tsMsg { 15303 t.Helper() 15304 req := &JSApiConsumerGetNextRequest{Batch: batch, Expires: expires, Heartbeat: hb} 15305 jreq, err := json.Marshal(req) 15306 require_NoError(t, err) 15307 reply := nats.NewInbox() 15308 var msgs []*tsMsg 15309 var mu sync.Mutex 15310 15311 sub, err := nc.Subscribe(reply, func(m *nats.Msg) { 15312 mu.Lock() 15313 msgs = append(msgs, &tsMsg{time.Now(), m}) 15314 mu.Unlock() 15315 }) 15316 require_NoError(t, err) 15317 15318 err = nc.PublishRequest(rsubj, reply, jreq) 15319 require_NoError(t, err) 15320 checkFor(t, time.Second, 50*time.Millisecond, func() error { 15321 mu.Lock() 15322 nr := len(msgs) 15323 mu.Unlock() 15324 if nr >= expected { 15325 return nil 15326 } 15327 return fmt.Errorf("Only have seen %d of %d responses", nr, expected) 15328 }) 15329 sub.Unsubscribe() 15330 return msgs 15331 } 15332 15333 reqBad := nats.Header{"Status": []string{"400"}, "Description": []string{"Bad Request - heartbeat value too large"}} 15334 expectErr := func(msgs []*tsMsg) { 15335 t.Helper() 15336 if len(msgs) != 1 { 15337 t.Fatalf("Expected 1 msg, got %d", len(msgs)) 15338 } 15339 if !reflect.DeepEqual(msgs[0].msg.Header, reqBad) { 15340 t.Fatalf("Expected %+v hdr, got %+v", reqBad, msgs[0].msg.Header) 15341 } 15342 } 15343 15344 // Test errors first. 15345 // Setting HB with no expires. 15346 expectErr(doReq(1, 100*time.Millisecond, 0, 1)) 15347 // If HB larger than 50% of expires.. 15348 expectErr(doReq(1, 75*time.Millisecond, 100*time.Millisecond, 1)) 15349 15350 expectHBs := func(start time.Time, msgs []*tsMsg, expected int, hbi time.Duration) { 15351 t.Helper() 15352 if len(msgs) != expected { 15353 t.Fatalf("Expected %d but got %d", expected, len(msgs)) 15354 } 15355 // expected -1 should be all HBs. 15356 for i, ts := 0, start; i < expected-1; i++ { 15357 tr, m := msgs[i].received, msgs[i].msg 15358 if m.Header.Get("Status") != "100" { 15359 t.Fatalf("Expected a 100 status code, got %q", m.Header.Get("Status")) 15360 } 15361 if m.Header.Get("Description") != "Idle Heartbeat" { 15362 t.Fatalf("Wrong description, got %q", m.Header.Get("Description")) 15363 } 15364 ts = ts.Add(hbi) 15365 if tr.Before(ts) { 15366 t.Fatalf("Received at wrong time: %v vs %v", tr, ts) 15367 } 15368 } 15369 // Last msg should be timeout. 15370 lm := msgs[len(msgs)-1].msg 15371 if key := lm.Header.Get("Status"); key != "408" { 15372 t.Fatalf("Expected 408 Request Timeout, got %s", key) 15373 } 15374 } 15375 15376 // These should work. Test idle first. 15377 start, msgs := time.Now(), doReq(1, 50*time.Millisecond, 250*time.Millisecond, 5) 15378 expectHBs(start, msgs, 5, 50*time.Millisecond) 15379 15380 // Now test that we do not send heartbeats while we receive traffic. 15381 go func() { 15382 for i := 0; i < 5; i++ { 15383 time.Sleep(50 * time.Millisecond) 15384 js.Publish("T", nil) 15385 } 15386 }() 15387 15388 msgs = doReq(10, 75*time.Millisecond, 350*time.Millisecond, 6) 15389 // The first 5 should be msgs, no HBs. 15390 for i := 0; i < 5; i++ { 15391 if m := msgs[i].msg; len(m.Header) > 0 { 15392 t.Fatalf("Got a potential heartbeat msg when we should not have: %+v", m.Header) 15393 } 15394 } 15395 // Last should be timeout. 15396 lm := msgs[len(msgs)-1].msg 15397 if key := lm.Header.Get("Status"); key != "408" { 15398 t.Fatalf("Expected 408 Request Timeout, got %s", key) 15399 } 15400 } 15401 15402 func TestJetStreamStorageReservedBytes(t *testing.T) { 15403 const systemLimit = 1024 15404 opts := DefaultTestOptions 15405 opts.Port = -1 15406 opts.JetStream = true 15407 opts.JetStreamMaxMemory = systemLimit 15408 opts.JetStreamMaxStore = systemLimit 15409 opts.StoreDir = t.TempDir() 15410 opts.HTTPPort = -1 15411 s := RunServer(&opts) 15412 15413 defer s.Shutdown() 15414 15415 // Client for API requests. 15416 nc, js := jsClientConnect(t, s) 15417 defer nc.Close() 15418 15419 getJetStreamVarz := func(hc *http.Client, addr string) (JetStreamVarz, error) { 15420 resp, err := hc.Get(addr) 15421 if err != nil { 15422 return JetStreamVarz{}, err 15423 } 15424 defer resp.Body.Close() 15425 15426 var v Varz 15427 if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { 15428 return JetStreamVarz{}, err 15429 } 15430 15431 return v.JetStream, nil 15432 } 15433 getReserved := func(hc *http.Client, addr string, st nats.StorageType) (uint64, error) { 15434 jsv, err := getJetStreamVarz(hc, addr) 15435 if err != nil { 15436 return 0, err 15437 } 15438 if st == nats.MemoryStorage { 15439 return jsv.Stats.ReservedMemory, nil 15440 } 15441 return jsv.Stats.ReservedStore, nil 15442 } 15443 15444 varzAddr := fmt.Sprintf("http://127.0.0.1:%d/varz", s.MonitorAddr().Port) 15445 hc := &http.Client{Timeout: 5 * time.Second} 15446 15447 jsv, err := getJetStreamVarz(hc, varzAddr) 15448 require_NoError(t, err) 15449 15450 if got, want := systemLimit, int(jsv.Config.MaxMemory); got != want { 15451 t.Fatalf("Unexpected max memory: got=%d, want=%d", got, want) 15452 } 15453 if got, want := systemLimit, int(jsv.Config.MaxStore); got != want { 15454 t.Fatalf("Unexpected max store: got=%d, want=%d", got, want) 15455 } 15456 15457 cases := []struct { 15458 name string 15459 accountLimit int64 15460 storage nats.StorageType 15461 createMaxBytes int64 15462 updateMaxBytes int64 15463 wantUpdateError bool 15464 }{ 15465 { 15466 name: "file reserve 66% of system limit", 15467 accountLimit: -1, 15468 storage: nats.FileStorage, 15469 createMaxBytes: int64(math.Round(float64(systemLimit) * .666)), 15470 updateMaxBytes: int64(math.Round(float64(systemLimit)*.666)) + 1, 15471 }, 15472 { 15473 name: "memory reserve 66% of system limit", 15474 accountLimit: -1, 15475 storage: nats.MemoryStorage, 15476 createMaxBytes: int64(math.Round(float64(systemLimit) * .666)), 15477 updateMaxBytes: int64(math.Round(float64(systemLimit)*.666)) + 1, 15478 }, 15479 { 15480 name: "file update past system limit", 15481 accountLimit: -1, 15482 storage: nats.FileStorage, 15483 createMaxBytes: systemLimit, 15484 updateMaxBytes: systemLimit + 1, 15485 wantUpdateError: true, 15486 }, 15487 { 15488 name: "memory update past system limit", 15489 accountLimit: -1, 15490 storage: nats.MemoryStorage, 15491 createMaxBytes: systemLimit, 15492 updateMaxBytes: systemLimit + 1, 15493 wantUpdateError: true, 15494 }, 15495 { 15496 name: "file update to system limit", 15497 accountLimit: -1, 15498 storage: nats.FileStorage, 15499 createMaxBytes: systemLimit - 1, 15500 updateMaxBytes: systemLimit, 15501 }, 15502 { 15503 name: "memory update to system limit", 15504 accountLimit: -1, 15505 storage: nats.MemoryStorage, 15506 createMaxBytes: systemLimit - 1, 15507 updateMaxBytes: systemLimit, 15508 }, 15509 { 15510 name: "file reserve 66% of account limit", 15511 accountLimit: systemLimit / 2, 15512 storage: nats.FileStorage, 15513 createMaxBytes: int64(math.Round(float64(systemLimit/2) * .666)), 15514 updateMaxBytes: int64(math.Round(float64(systemLimit/2)*.666)) + 1, 15515 }, 15516 { 15517 name: "memory reserve 66% of account limit", 15518 accountLimit: systemLimit / 2, 15519 storage: nats.MemoryStorage, 15520 createMaxBytes: int64(math.Round(float64(systemLimit/2) * .666)), 15521 updateMaxBytes: int64(math.Round(float64(systemLimit/2)*.666)) + 1, 15522 }, 15523 { 15524 name: "file update past account limit", 15525 accountLimit: systemLimit / 2, 15526 storage: nats.FileStorage, 15527 createMaxBytes: (systemLimit / 2), 15528 updateMaxBytes: (systemLimit / 2) + 1, 15529 wantUpdateError: true, 15530 }, 15531 { 15532 name: "memory update past account limit", 15533 accountLimit: systemLimit / 2, 15534 storage: nats.MemoryStorage, 15535 createMaxBytes: (systemLimit / 2), 15536 updateMaxBytes: (systemLimit / 2) + 1, 15537 wantUpdateError: true, 15538 }, 15539 { 15540 name: "file update to account limit", 15541 accountLimit: systemLimit / 2, 15542 storage: nats.FileStorage, 15543 createMaxBytes: (systemLimit / 2) - 1, 15544 updateMaxBytes: (systemLimit / 2), 15545 }, 15546 { 15547 name: "memory update to account limit", 15548 accountLimit: systemLimit / 2, 15549 storage: nats.MemoryStorage, 15550 createMaxBytes: (systemLimit / 2) - 1, 15551 updateMaxBytes: (systemLimit / 2), 15552 }, 15553 } 15554 for i := 0; i < len(cases) && !t.Failed(); i++ { 15555 c := cases[i] 15556 t.Run(c.name, func(st *testing.T) { 15557 // Setup limits 15558 err = s.GlobalAccount().UpdateJetStreamLimits(map[string]JetStreamAccountLimits{ 15559 _EMPTY_: { 15560 MaxMemory: c.accountLimit, 15561 MaxStore: c.accountLimit, 15562 }, 15563 }) 15564 require_NoError(st, err) 15565 15566 // Create initial stream 15567 cfg := &nats.StreamConfig{ 15568 Name: "TEST", 15569 Subjects: []string{"foo"}, 15570 Storage: c.storage, 15571 MaxBytes: c.createMaxBytes, 15572 } 15573 _, err = js.AddStream(cfg) 15574 require_NoError(st, err) 15575 15576 // Update stream MaxBytes 15577 cfg.MaxBytes = c.updateMaxBytes 15578 info, err := js.UpdateStream(cfg) 15579 if c.wantUpdateError && err == nil { 15580 got := info.Config.MaxBytes 15581 st.Fatalf("Unexpected update success, newMaxBytes=%d; systemLimit=%d; accountLimit=%d", 15582 got, systemLimit, c.accountLimit) 15583 } else if !c.wantUpdateError && err != nil { 15584 st.Fatalf("Unexpected update error: %s", err) 15585 } 15586 15587 if !c.wantUpdateError && err == nil { 15588 // If update was successful, then ensure reserved shows new 15589 // amount 15590 reserved, err := getReserved(hc, varzAddr, c.storage) 15591 require_NoError(st, err) 15592 if got, want := reserved, uint64(c.updateMaxBytes); got != want { 15593 st.Fatalf("Unexpected reserved: %d, want %d", got, want) 15594 } 15595 } 15596 15597 // Delete stream 15598 err = js.DeleteStream("TEST") 15599 require_NoError(st, err) 15600 15601 // Ensure reserved shows 0 because we've deleted the stream 15602 reserved, err := getReserved(hc, varzAddr, c.storage) 15603 require_NoError(st, err) 15604 if reserved != 0 { 15605 st.Fatalf("Unexpected reserved: %d, want 0", reserved) 15606 } 15607 }) 15608 } 15609 } 15610 15611 func TestJetStreamRestoreBadStream(t *testing.T) { 15612 s := RunBasicJetStreamServer(t) 15613 defer s.Shutdown() 15614 15615 nc, _ := jsClientConnect(t, s) 15616 defer nc.Close() 15617 15618 var rreq JSApiStreamRestoreRequest 15619 buf, err := os.ReadFile("../test/configs/jetstream/restore_bad_stream/backup.json") 15620 require_NoError(t, err) 15621 err = json.Unmarshal(buf, &rreq) 15622 require_NoError(t, err) 15623 15624 data, err := os.Open("../test/configs/jetstream/restore_bad_stream/stream.tar.s2") 15625 require_NoError(t, err) 15626 defer data.Close() 15627 15628 var rresp JSApiStreamRestoreResponse 15629 msg, err := nc.Request(fmt.Sprintf(JSApiStreamRestoreT, rreq.Config.Name), buf, 5*time.Second) 15630 require_NoError(t, err) 15631 json.Unmarshal(msg.Data, &rresp) 15632 if rresp.Error != nil { 15633 t.Fatalf("Error on restore: %+v", rresp.Error) 15634 } 15635 15636 var chunk [1024]byte 15637 for { 15638 n, err := data.Read(chunk[:]) 15639 if err == io.EOF { 15640 break 15641 } 15642 require_NoError(t, err) 15643 15644 msg, err = nc.Request(rresp.DeliverSubject, chunk[:n], 5*time.Second) 15645 require_NoError(t, err) 15646 json.Unmarshal(msg.Data, &rresp) 15647 if rresp.Error != nil { 15648 t.Fatalf("Error on restore: %+v", rresp.Error) 15649 } 15650 } 15651 msg, err = nc.Request(rresp.DeliverSubject, nil, 5*time.Second) 15652 require_NoError(t, err) 15653 json.Unmarshal(msg.Data, &rresp) 15654 if rresp.Error == nil || !strings.Contains(rresp.Error.Description, "unexpected") { 15655 t.Fatalf("Expected error about unexpected content, got: %+v", rresp.Error) 15656 } 15657 15658 dir := filepath.Join(s.JetStreamConfig().StoreDir, globalAccountName) 15659 f1 := filepath.Join(dir, "fail1.txt") 15660 f2 := filepath.Join(dir, "fail2.txt") 15661 for _, f := range []string{f1, f2} { 15662 if _, err := os.Stat(f); err == nil { 15663 t.Fatalf("Found file %s", f) 15664 } 15665 } 15666 } 15667 15668 func TestJetStreamConsumerAckSampling(t *testing.T) { 15669 s := RunBasicJetStreamServer(t) 15670 defer s.Shutdown() 15671 15672 nc, js := jsClientConnect(t, s) 15673 defer nc.Close() 15674 15675 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"foo"}}) 15676 require_NoError(t, err) 15677 15678 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 15679 Durable: "dlc", 15680 AckPolicy: nats.AckExplicitPolicy, 15681 FilterSubject: "foo", 15682 SampleFrequency: "100%", 15683 }) 15684 require_NoError(t, err) 15685 15686 sub, err := js.PullSubscribe("foo", "dlc") 15687 require_NoError(t, err) 15688 15689 _, err = js.Publish("foo", []byte("Hello")) 15690 require_NoError(t, err) 15691 15692 msub, err := nc.SubscribeSync("$JS.EVENT.METRIC.>") 15693 require_NoError(t, err) 15694 15695 for _, m := range fetchMsgs(t, sub, 1, time.Second) { 15696 err = m.AckSync() 15697 require_NoError(t, err) 15698 } 15699 15700 m, err := msub.NextMsg(time.Second) 15701 require_NoError(t, err) 15702 15703 var am JSConsumerAckMetric 15704 err = json.Unmarshal(m.Data, &am) 15705 require_NoError(t, err) 15706 15707 if am.Stream != "TEST" || am.Consumer != "dlc" || am.ConsumerSeq != 1 { 15708 t.Fatalf("Not a proper ack metric: %+v", am) 15709 } 15710 15711 // Do less than 100% 15712 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 15713 Durable: "alps", 15714 AckPolicy: nats.AckExplicitPolicy, 15715 FilterSubject: "foo", 15716 SampleFrequency: "50%", 15717 }) 15718 require_NoError(t, err) 15719 15720 asub, err := js.PullSubscribe("foo", "alps") 15721 require_NoError(t, err) 15722 15723 total := 500 15724 for i := 0; i < total; i++ { 15725 _, err = js.Publish("foo", []byte("Hello")) 15726 require_NoError(t, err) 15727 } 15728 15729 mp := 0 15730 for _, m := range fetchMsgs(t, asub, total, time.Second) { 15731 err = m.AckSync() 15732 require_NoError(t, err) 15733 mp++ 15734 } 15735 nc.Flush() 15736 15737 if mp != total { 15738 t.Fatalf("Got only %d msgs out of %d", mp, total) 15739 } 15740 15741 nmsgs, _, err := msub.Pending() 15742 require_NoError(t, err) 15743 15744 // Should be ~250 15745 if nmsgs < 200 || nmsgs > 300 { 15746 t.Fatalf("Expected about 250, got %d", nmsgs) 15747 } 15748 } 15749 15750 func TestJetStreamConsumerAckSamplingSpecifiedUsingUpdateConsumer(t *testing.T) { 15751 s := RunBasicJetStreamServer(t) 15752 defer s.Shutdown() 15753 15754 nc, js := jsClientConnect(t, s) 15755 defer nc.Close() 15756 15757 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"foo"}}) 15758 require_NoError(t, err) 15759 15760 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 15761 Durable: "dlc", 15762 AckPolicy: nats.AckExplicitPolicy, 15763 FilterSubject: "foo", 15764 }) 15765 require_NoError(t, err) 15766 15767 _, err = js.UpdateConsumer("TEST", &nats.ConsumerConfig{ 15768 Durable: "dlc", 15769 AckPolicy: nats.AckExplicitPolicy, 15770 FilterSubject: "foo", 15771 SampleFrequency: "100%", 15772 }) 15773 require_NoError(t, err) 15774 15775 sub, err := js.PullSubscribe("foo", "dlc") 15776 require_NoError(t, err) 15777 15778 _, err = js.Publish("foo", []byte("Hello")) 15779 require_NoError(t, err) 15780 15781 msub, err := nc.SubscribeSync("$JS.EVENT.METRIC.>") 15782 require_NoError(t, err) 15783 15784 for _, m := range fetchMsgs(t, sub, 1, time.Second) { 15785 err = m.AckSync() 15786 require_NoError(t, err) 15787 } 15788 15789 m, err := msub.NextMsg(time.Second) 15790 require_NoError(t, err) 15791 15792 var am JSConsumerAckMetric 15793 err = json.Unmarshal(m.Data, &am) 15794 require_NoError(t, err) 15795 15796 if am.Stream != "TEST" || am.Consumer != "dlc" || am.ConsumerSeq != 1 { 15797 t.Fatalf("Not a proper ack metric: %+v", am) 15798 } 15799 } 15800 15801 func TestJetStreamConsumerMaxDeliverUpdate(t *testing.T) { 15802 s := RunBasicJetStreamServer(t) 15803 defer s.Shutdown() 15804 15805 nc, js := jsClientConnect(t, s) 15806 defer nc.Close() 15807 15808 _, err := js.AddStream(&nats.StreamConfig{Name: "TEST", Subjects: []string{"foo"}}) 15809 require_NoError(t, err) 15810 15811 maxDeliver := 2 15812 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 15813 Durable: "ard", 15814 AckPolicy: nats.AckExplicitPolicy, 15815 FilterSubject: "foo", 15816 MaxDeliver: maxDeliver, 15817 }) 15818 require_NoError(t, err) 15819 15820 sub, err := js.PullSubscribe("foo", "ard") 15821 require_NoError(t, err) 15822 15823 checkMaxDeliver := func() { 15824 t.Helper() 15825 for i := 0; i <= maxDeliver; i++ { 15826 msgs, err := sub.Fetch(2, nats.MaxWait(100*time.Millisecond)) 15827 if i < maxDeliver { 15828 require_NoError(t, err) 15829 require_Len(t, 1, len(msgs)) 15830 _ = msgs[0].Nak() 15831 } else { 15832 require_Error(t, err, nats.ErrTimeout) 15833 } 15834 } 15835 } 15836 15837 _, err = js.Publish("foo", []byte("Hello")) 15838 require_NoError(t, err) 15839 checkMaxDeliver() 15840 15841 // update maxDeliver 15842 maxDeliver++ 15843 _, err = js.UpdateConsumer("TEST", &nats.ConsumerConfig{ 15844 Durable: "ard", 15845 AckPolicy: nats.AckExplicitPolicy, 15846 FilterSubject: "foo", 15847 MaxDeliver: maxDeliver, 15848 }) 15849 require_NoError(t, err) 15850 15851 _, err = js.Publish("foo", []byte("Hello")) 15852 require_NoError(t, err) 15853 checkMaxDeliver() 15854 } 15855 15856 func TestJetStreamRemoveExternalSource(t *testing.T) { 15857 ho := DefaultTestOptions 15858 ho.Port = 4000 //-1 15859 ho.LeafNode.Host = "127.0.0.1" 15860 ho.LeafNode.Port = -1 15861 hs := RunServer(&ho) 15862 defer hs.Shutdown() 15863 15864 lu, err := url.Parse(fmt.Sprintf("nats://127.0.0.1:%d", ho.LeafNode.Port)) 15865 require_NoError(t, err) 15866 15867 lo1 := DefaultTestOptions 15868 lo1.Port = 4111 //-1 15869 lo1.ServerName = "a-leaf" 15870 lo1.JetStream = true 15871 lo1.StoreDir = t.TempDir() 15872 lo1.JetStreamDomain = "a-leaf" 15873 lo1.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{lu}}} 15874 l1 := RunServer(&lo1) 15875 defer l1.Shutdown() 15876 15877 lo2 := DefaultTestOptions 15878 lo2.Port = 2111 //-1 15879 lo2.ServerName = "b-leaf" 15880 lo2.JetStream = true 15881 lo2.StoreDir = t.TempDir() 15882 lo2.JetStreamDomain = "b-leaf" 15883 lo2.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{lu}}} 15884 l2 := RunServer(&lo2) 15885 defer l2.Shutdown() 15886 15887 checkLeafNodeConnected(t, l1) 15888 checkLeafNodeConnected(t, l2) 15889 15890 checkStreamMsgs := func(js nats.JetStreamContext, stream string, expected uint64) { 15891 t.Helper() 15892 checkFor(t, 2*time.Second, 15*time.Millisecond, func() error { 15893 si, err := js.StreamInfo(stream) 15894 if err != nil { 15895 return err 15896 } 15897 if si.State.Msgs != expected { 15898 return fmt.Errorf("Expected %v messages, got %v", expected, si.State.Msgs) 15899 } 15900 return nil 15901 }) 15902 } 15903 15904 sendToStreamTest := func(js nats.JetStreamContext) { 15905 t.Helper() 15906 for i := 0; i < 10; i++ { 15907 _, err = js.Publish("test", []byte("hello")) 15908 require_NoError(t, err) 15909 } 15910 } 15911 15912 nca, jsa := jsClientConnect(t, l1) 15913 defer nca.Close() 15914 _, err = jsa.AddStream(&nats.StreamConfig{Name: "queue", Subjects: []string{"queue"}}) 15915 require_NoError(t, err) 15916 15917 _, err = jsa.AddStream(&nats.StreamConfig{Name: "testdel", Subjects: []string{"testdel"}}) 15918 require_NoError(t, err) 15919 15920 ncb, jsb := jsClientConnect(t, l2) 15921 defer ncb.Close() 15922 _, err = jsb.AddStream(&nats.StreamConfig{Name: "test", Subjects: []string{"test"}}) 15923 require_NoError(t, err) 15924 sendToStreamTest(jsb) 15925 checkStreamMsgs(jsb, "test", 10) 15926 15927 _, err = jsb.AddStream(&nats.StreamConfig{Name: "testdelsrc1", Subjects: []string{"testdelsrc1"}}) 15928 require_NoError(t, err) 15929 _, err = jsb.AddStream(&nats.StreamConfig{Name: "testdelsrc2", Subjects: []string{"testdelsrc2"}}) 15930 require_NoError(t, err) 15931 15932 // Add test as source to queue 15933 si, err := jsa.UpdateStream(&nats.StreamConfig{ 15934 Name: "queue", 15935 Subjects: []string{"queue"}, 15936 Sources: []*nats.StreamSource{ 15937 { 15938 Name: "test", 15939 External: &nats.ExternalStream{ 15940 APIPrefix: "$JS.b-leaf.API", 15941 }, 15942 }, 15943 }, 15944 }) 15945 require_NoError(t, err) 15946 require_True(t, len(si.Config.Sources) == 1) 15947 checkStreamMsgs(jsa, "queue", 10) 15948 15949 // add more entries to "test" 15950 sendToStreamTest(jsb) 15951 15952 // verify entries are both in "test" and "queue" 15953 checkStreamMsgs(jsb, "test", 20) 15954 checkStreamMsgs(jsa, "queue", 20) 15955 15956 // Remove source 15957 si, err = jsa.UpdateStream(&nats.StreamConfig{ 15958 Name: "queue", 15959 Subjects: []string{"queue"}, 15960 }) 15961 require_NoError(t, err) 15962 require_True(t, len(si.Config.Sources) == 0) 15963 15964 // add more entries to "test" 15965 sendToStreamTest(jsb) 15966 // verify entries are in "test" 15967 checkStreamMsgs(jsb, "test", 30) 15968 15969 // But they should not be in "queue". We will wait a bit before checking 15970 // to make sure that we are letting enough time for the sourcing to 15971 // incorrectly happen if there is a bug. 15972 time.Sleep(250 * time.Millisecond) 15973 checkStreamMsgs(jsa, "queue", 20) 15974 15975 // Test that we delete correctly. First add source to a "testdel" 15976 si, err = jsa.UpdateStream(&nats.StreamConfig{ 15977 Name: "testdel", 15978 Subjects: []string{"testdel"}, 15979 Sources: []*nats.StreamSource{ 15980 { 15981 Name: "testdelsrc1", 15982 External: &nats.ExternalStream{ 15983 APIPrefix: "$JS.b-leaf.API", 15984 }, 15985 }, 15986 }, 15987 }) 15988 require_NoError(t, err) 15989 require_True(t, len(si.Config.Sources) == 1) 15990 // Now add the second one... 15991 si, err = jsa.UpdateStream(&nats.StreamConfig{ 15992 Name: "testdel", 15993 Subjects: []string{"testdel"}, 15994 Sources: []*nats.StreamSource{ 15995 { 15996 Name: "testdelsrc1", 15997 External: &nats.ExternalStream{ 15998 APIPrefix: "$JS.b-leaf.API", 15999 }, 16000 }, 16001 { 16002 Name: "testdelsrc2", 16003 External: &nats.ExternalStream{ 16004 APIPrefix: "$JS.b-leaf.API", 16005 }, 16006 }, 16007 }, 16008 }) 16009 require_NoError(t, err) 16010 require_True(t, len(si.Config.Sources) == 2) 16011 // Now check that the stream testdel has still 2 source consumers... 16012 acc, err := l1.lookupAccount(globalAccountName) 16013 require_NoError(t, err) 16014 mset, err := acc.lookupStream("testdel") 16015 require_NoError(t, err) 16016 mset.mu.RLock() 16017 n := len(mset.sources) 16018 mset.mu.RUnlock() 16019 if n != 2 { 16020 t.Fatalf("Expected 2 sources, got %v", n) 16021 } 16022 16023 // Restart leaf "a" 16024 nca.Close() 16025 l1.Shutdown() 16026 l1 = RunServer(&lo1) 16027 defer l1.Shutdown() 16028 16029 // add more entries to "test" 16030 sendToStreamTest(jsb) 16031 checkStreamMsgs(jsb, "test", 40) 16032 16033 nca, jsa = jsClientConnect(t, l1) 16034 defer nca.Close() 16035 time.Sleep(250 * time.Millisecond) 16036 checkStreamMsgs(jsa, "queue", 20) 16037 } 16038 16039 func TestJetStreamAddStreamWithFilestoreFailure(t *testing.T) { 16040 s := RunBasicJetStreamServer(t) 16041 defer s.Shutdown() 16042 16043 // Cause failure to create stream with filestore. 16044 // In one of ipQueue changes, this could cause a panic, so verify that we get 16045 // a failure to create, but no panic. 16046 if _, err := s.globalAccount().addStreamWithStore( 16047 &StreamConfig{Name: "TEST"}, 16048 &FileStoreConfig{BlockSize: 2 * maxBlockSize}); err == nil { 16049 t.Fatal("Expected failure, did not get one") 16050 } 16051 } 16052 16053 type checkFastState struct { 16054 count int64 16055 StreamStore 16056 } 16057 16058 func (s *checkFastState) FastState(state *StreamState) { 16059 // Keep track only when called from checkPending() 16060 if bytes.Contains(debug.Stack(), []byte("checkPending(")) { 16061 atomic.AddInt64(&s.count, 1) 16062 } 16063 s.StreamStore.FastState(state) 16064 } 16065 16066 func TestJetStreamBackOffCheckPending(t *testing.T) { 16067 s := RunBasicJetStreamServer(t) 16068 defer s.Shutdown() 16069 16070 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "TEST", Subjects: []string{"foo"}}) 16071 if err != nil { 16072 t.Fatalf("Unexpected error adding stream: %v", err) 16073 } 16074 defer mset.delete() 16075 16076 // Plug or store to see how many times we invoke FastState, which is done in checkPending 16077 mset.mu.Lock() 16078 st := &checkFastState{StreamStore: mset.store} 16079 mset.store = st 16080 mset.mu.Unlock() 16081 16082 nc := clientConnectToServer(t, s) 16083 defer nc.Close() 16084 16085 sendStreamMsg(t, nc, "foo", "Hello World!") 16086 16087 sub, _ := nc.SubscribeSync(nats.NewInbox()) 16088 defer sub.Unsubscribe() 16089 nc.Flush() 16090 16091 o, err := mset.addConsumer(&ConsumerConfig{ 16092 DeliverSubject: sub.Subject, 16093 AckPolicy: AckExplicit, 16094 MaxDeliver: 1000, 16095 BackOff: []time.Duration{50 * time.Millisecond, 250 * time.Millisecond, time.Second}, 16096 }) 16097 if err != nil { 16098 t.Fatalf("Expected no error, got %v", err) 16099 } 16100 defer o.delete() 16101 16102 // Check the first delivery and the following 2 redeliveries 16103 start := time.Now() 16104 natsNexMsg(t, sub, time.Second) 16105 if dur := time.Since(start); dur >= 50*time.Millisecond { 16106 t.Fatalf("Expected first delivery to be fast, took: %v", dur) 16107 } 16108 start = time.Now() 16109 natsNexMsg(t, sub, time.Second) 16110 if dur := time.Since(start); dur < 25*time.Millisecond || dur > 75*time.Millisecond { 16111 t.Fatalf("Expected first redelivery to be ~50ms, took: %v", dur) 16112 } 16113 start = time.Now() 16114 natsNexMsg(t, sub, time.Second) 16115 if dur := time.Since(start); dur < 200*time.Millisecond || dur > 300*time.Millisecond { 16116 t.Fatalf("Expected first redelivery to be ~250ms, took: %v", dur) 16117 } 16118 // There was a bug that would cause checkPending to be invoked based on the 16119 // ackWait (which in this case would be the first value of BackOff, which 16120 // is 50ms). So we would call checkPending() too many times. 16121 time.Sleep(500 * time.Millisecond) 16122 // Check now, it should have been invoked twice. 16123 if n := atomic.LoadInt64(&st.count); n != 2 { 16124 t.Fatalf("Expected checkPending to be invoked 2 times, was %v", n) 16125 } 16126 } 16127 16128 func TestJetStreamCrossAccounts(t *testing.T) { 16129 conf := createConfFile(t, []byte(fmt.Sprintf(` 16130 listen: 127.0.0.1:-1 16131 jetstream { 16132 store_dir = %q 16133 } 16134 accounts: { 16135 A: { 16136 users: [ {user: a, password: a} ] 16137 jetstream: enabled 16138 exports: [ 16139 {service: '$JS.API.>' } 16140 {service: '$KV.>'} 16141 {stream: 'accI.>'} 16142 ] 16143 }, 16144 I: { 16145 users: [ {user: i, password: i} ] 16146 imports: [ 16147 {service: {account: A, subject: '$JS.API.>'}, to: 'fromA.>' } 16148 {service: {account: A, subject: '$KV.>'}, to: 'fromA.$KV.>' } 16149 {stream: {subject: 'accI.>', account: A}} 16150 ] 16151 } 16152 }`, t.TempDir()))) 16153 s, _ := RunServerWithConfig(conf) 16154 defer s.Shutdown() 16155 16156 watchNext := func(w nats.KeyWatcher) nats.KeyValueEntry { 16157 t.Helper() 16158 select { 16159 case e := <-w.Updates(): 16160 return e 16161 case <-time.After(time.Second): 16162 t.Fatal("Fail to get the next update") 16163 } 16164 return nil 16165 } 16166 16167 nc1, js1 := jsClientConnect(t, s, nats.UserInfo("a", "a")) 16168 defer nc1.Close() 16169 16170 kv1, err := js1.CreateKeyValue(&nats.KeyValueConfig{Bucket: "Map", History: 10}) 16171 if err != nil { 16172 t.Fatalf("Error creating kv store: %v", err) 16173 } 16174 16175 w1, err := kv1.Watch("map") 16176 if err != nil { 16177 t.Fatalf("Error creating watcher: %v", err) 16178 } 16179 if e := watchNext(w1); e != nil { 16180 t.Fatalf("Expected nil entry, got %+v", e) 16181 } 16182 16183 nc2, err := nats.Connect(s.ClientURL(), nats.UserInfo("i", "i"), nats.CustomInboxPrefix("accI")) 16184 if err != nil { 16185 t.Fatalf("Error on connect: %v", err) 16186 } 16187 defer nc2.Close() 16188 js2, err := nc2.JetStream(nats.APIPrefix("fromA")) 16189 if err != nil { 16190 t.Fatalf("Error getting jetstream context: %v", err) 16191 } 16192 16193 kv2, err := js2.CreateKeyValue(&nats.KeyValueConfig{Bucket: "Map", History: 10}) 16194 if err != nil { 16195 t.Fatalf("Error creating kv store: %v", err) 16196 } 16197 16198 w2, err := kv2.Watch("map") 16199 if err != nil { 16200 t.Fatalf("Error creating watcher: %v", err) 16201 } 16202 if e := watchNext(w2); e != nil { 16203 t.Fatalf("Expected nil entry, got %+v", e) 16204 } 16205 16206 // Do a Put from kv2 16207 rev, err := kv2.Put("map", []byte("value")) 16208 if err != nil { 16209 t.Fatalf("Error on put: %v", err) 16210 } 16211 16212 // Get from kv1 16213 e, err := kv1.Get("map") 16214 if err != nil { 16215 t.Fatalf("Error on get: %v", err) 16216 } 16217 if e.Key() != "map" || string(e.Value()) != "value" { 16218 t.Fatalf("Unexpected entry: +%v", e) 16219 } 16220 16221 // Get from kv2 16222 e, err = kv2.Get("map") 16223 if err != nil { 16224 t.Fatalf("Error on get: %v", err) 16225 } 16226 if e.Key() != "map" || string(e.Value()) != "value" { 16227 t.Fatalf("Unexpected entry: +%v", e) 16228 } 16229 16230 // Watcher 1 16231 if e := watchNext(w1); e == nil || e.Key() != "map" || string(e.Value()) != "value" { 16232 t.Fatalf("Unexpected entry: %+v", e) 16233 } 16234 16235 // Watcher 2 16236 if e := watchNext(w2); e == nil || e.Key() != "map" || string(e.Value()) != "value" { 16237 t.Fatalf("Unexpected entry: %+v", e) 16238 } 16239 16240 // Try an update form kv2 16241 if _, err := kv2.Update("map", []byte("updated"), rev); err != nil { 16242 t.Fatalf("Failed to update: %v", err) 16243 } 16244 16245 // Get from kv1 16246 e, err = kv1.Get("map") 16247 if err != nil { 16248 t.Fatalf("Error on get: %v", err) 16249 } 16250 if e.Key() != "map" || string(e.Value()) != "updated" { 16251 t.Fatalf("Unexpected entry: +%v", e) 16252 } 16253 16254 // Get from kv2 16255 e, err = kv2.Get("map") 16256 if err != nil { 16257 t.Fatalf("Error on get: %v", err) 16258 } 16259 if e.Key() != "map" || string(e.Value()) != "updated" { 16260 t.Fatalf("Unexpected entry: +%v", e) 16261 } 16262 16263 // Watcher 1 16264 if e := watchNext(w1); e == nil || e.Key() != "map" || string(e.Value()) != "updated" { 16265 t.Fatalf("Unexpected entry: %+v", e) 16266 } 16267 16268 // Watcher 2 16269 if e := watchNext(w2); e == nil || e.Key() != "map" || string(e.Value()) != "updated" { 16270 t.Fatalf("Unexpected entry: %+v", e) 16271 } 16272 16273 // Purge from kv2 16274 if err := kv2.Purge("map"); err != nil { 16275 t.Fatalf("Error on purge: %v", err) 16276 } 16277 16278 // Check purge ok from w1 16279 if e := watchNext(w1); e == nil || e.Operation() != nats.KeyValuePurge { 16280 t.Fatalf("Unexpected entry: %+v", e) 16281 } 16282 16283 // Check purge ok from w2 16284 if e := watchNext(w2); e == nil || e.Operation() != nats.KeyValuePurge { 16285 t.Fatalf("Unexpected entry: %+v", e) 16286 } 16287 16288 // Delete purge records from kv2 16289 if err := kv2.PurgeDeletes(nats.DeleteMarkersOlderThan(-1)); err != nil { 16290 t.Fatalf("Error on purge deletes: %v", err) 16291 } 16292 16293 // Check all gone from js1 16294 if si, err := js1.StreamInfo("KV_Map"); err != nil || si == nil || si.State.Msgs != 0 { 16295 t.Fatalf("Error getting stream info: err=%v si=%+v", err, si) 16296 } 16297 16298 // Delete key from kv2 16299 if err := kv2.Delete("map"); err != nil { 16300 t.Fatalf("Error on delete: %v", err) 16301 } 16302 16303 // Check key gone from kv1 16304 if e, err := kv1.Get("map"); err != nats.ErrKeyNotFound || e != nil { 16305 t.Fatalf("Expected key not found, got err=%v e=%+v", err, e) 16306 } 16307 } 16308 16309 func TestJetStreamInvalidRestoreRequests(t *testing.T) { 16310 test := func(t *testing.T, s *Server, replica int) { 16311 nc := natsConnect(t, s.ClientURL()) 16312 defer nc.Close() 16313 // test invalid stream config in restore request 16314 require_fail := func(cfg StreamConfig, errDesc string) { 16315 t.Helper() 16316 rreq := &JSApiStreamRestoreRequest{ 16317 Config: cfg, 16318 } 16319 req, err := json.Marshal(rreq) 16320 require_NoError(t, err) 16321 rmsg, err := nc.Request(fmt.Sprintf(JSApiStreamRestoreT, "fail"), req, time.Second) 16322 if err != nil { 16323 t.Fatalf("Unexpected error: %v", err) 16324 } 16325 var rresp JSApiStreamRestoreResponse 16326 json.Unmarshal(rmsg.Data, &rresp) 16327 require_True(t, rresp.Error != nil) 16328 require_Equal(t, rresp.Error.Description, errDesc) 16329 } 16330 require_fail(StreamConfig{Name: "fail", MaxBytes: 1024, Storage: FileStorage, Replicas: 6}, 16331 "maximum replicas is 5") 16332 require_fail(StreamConfig{Name: "fail", MaxBytes: 2 * 1012 * 1024, Storage: FileStorage, Replicas: replica}, 16333 "insufficient storage resources available") 16334 js, err := nc.JetStream() 16335 require_NoError(t, err) 16336 _, err = js.AddStream(&nats.StreamConfig{Name: "stream", MaxBytes: 1024, Storage: nats.FileStorage, Replicas: 1}) 16337 require_NoError(t, err) 16338 require_fail(StreamConfig{Name: "fail", MaxBytes: 1024, Storage: FileStorage}, 16339 "maximum number of streams reached") 16340 } 16341 16342 commonAccSection := ` 16343 no_auth_user: u 16344 accounts { 16345 ONE { 16346 users = [ { user: "u", pass: "s3cr3t!" } ] 16347 jetstream: { 16348 max_store: 1Mb 16349 max_streams: 1 16350 } 16351 } 16352 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 16353 }` 16354 16355 t.Run("clustered", func(t *testing.T) { 16356 c := createJetStreamClusterWithTemplate(t, ` 16357 listen: 127.0.0.1:-1 16358 server_name: %s 16359 jetstream: { 16360 max_mem_store: 2MB, 16361 max_file_store: 8MB, 16362 store_dir: '%s', 16363 } 16364 cluster { 16365 name: %s 16366 listen: 127.0.0.1:%d 16367 routes = [%s] 16368 }`+commonAccSection, "clust", 3) 16369 defer c.shutdown() 16370 s := c.randomServer() 16371 test(t, s, 3) 16372 }) 16373 t.Run("single", func(t *testing.T) { 16374 storeDir := t.TempDir() 16375 conf := createConfFile(t, []byte(fmt.Sprintf(` 16376 listen: 127.0.0.1:-1 16377 jetstream: {max_mem_store: 2MB, max_file_store: 8MB, store_dir: '%s'} 16378 %s`, storeDir, commonAccSection))) 16379 s, _ := RunServerWithConfig(conf) 16380 defer s.Shutdown() 16381 test(t, s, 1) 16382 }) 16383 } 16384 16385 func TestJetStreamLimits(t *testing.T) { 16386 test := func(t *testing.T, s *Server) { 16387 nc := natsConnect(t, s.ClientURL()) 16388 defer nc.Close() 16389 16390 js, err := nc.JetStream() 16391 require_NoError(t, err) 16392 16393 si, err := js.AddStream(&nats.StreamConfig{Name: "foo"}) 16394 require_NoError(t, err) 16395 require_True(t, si.Config.Duplicates == time.Minute) 16396 16397 si, err = js.AddStream(&nats.StreamConfig{Name: "bar", Duplicates: 1500 * time.Millisecond}) 16398 require_NoError(t, err) 16399 require_True(t, si.Config.Duplicates == 1500*time.Millisecond) 16400 16401 _, err = js.UpdateStream(&nats.StreamConfig{Name: "bar", Duplicates: 2 * time.Minute}) 16402 require_Error(t, err) 16403 require_Equal(t, err.Error(), "nats: duplicates window can not be larger then server limit of 1m0s") 16404 16405 _, err = js.AddStream(&nats.StreamConfig{Name: "baz", Duplicates: 2 * time.Minute}) 16406 require_Error(t, err) 16407 require_Equal(t, err.Error(), "nats: duplicates window can not be larger then server limit of 1m0s") 16408 16409 ci, err := js.AddConsumer("foo", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy}) 16410 require_NoError(t, err) 16411 require_True(t, ci.Config.MaxAckPending == 1000) 16412 require_True(t, ci.Config.MaxRequestBatch == 250) 16413 16414 _, err = js.AddConsumer("foo", &nats.ConsumerConfig{Durable: "dur2", AckPolicy: nats.AckExplicitPolicy, MaxRequestBatch: 500}) 16415 require_Error(t, err) 16416 require_Equal(t, err.Error(), "nats: consumer max request batch exceeds server limit of 250") 16417 16418 ci, err = js.AddConsumer("foo", &nats.ConsumerConfig{Durable: "dur2", AckPolicy: nats.AckExplicitPolicy, MaxAckPending: 500}) 16419 require_NoError(t, err) 16420 require_True(t, ci.Config.MaxAckPending == 500) 16421 require_True(t, ci.Config.MaxRequestBatch == 250) 16422 16423 _, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{Durable: "dur2", AckPolicy: nats.AckExplicitPolicy, MaxAckPending: 2000}) 16424 require_Error(t, err) 16425 require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000") 16426 16427 _, err = js.AddConsumer("foo", &nats.ConsumerConfig{Durable: "dur3", AckPolicy: nats.AckExplicitPolicy, MaxAckPending: 2000}) 16428 require_Error(t, err) 16429 require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000") 16430 } 16431 16432 t.Run("clustered", func(t *testing.T) { 16433 tmpl := ` 16434 listen: 127.0.0.1:-1 16435 server_name: %s 16436 jetstream: { 16437 max_mem_store: 2MB, 16438 max_file_store: 8MB, 16439 store_dir: '%s', 16440 limits: {duplicate_window: "1m", max_request_batch: 250} 16441 } 16442 cluster { 16443 name: %s 16444 listen: 127.0.0.1:%d 16445 routes = [%s] 16446 } 16447 no_auth_user: u 16448 accounts { 16449 ONE { 16450 users = [ { user: "u", pass: "s3cr3t!" } ] 16451 jetstream: enabled 16452 } 16453 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 16454 }` 16455 limitsTest := func(t *testing.T, tmpl string) { 16456 c := createJetStreamClusterWithTemplate(t, tmpl, "clust", 3) 16457 defer c.shutdown() 16458 s := c.randomServer() 16459 test(t, s) 16460 } 16461 // test with max_ack_pending being defined in operator or account 16462 t.Run("operator", func(t *testing.T) { 16463 limitsTest(t, strings.Replace(tmpl, "duplicate_window", "max_ack_pending: 1000, duplicate_window", 1)) 16464 }) 16465 t.Run("account", func(t *testing.T) { 16466 limitsTest(t, strings.Replace(tmpl, "jetstream: enabled", "jetstream: {max_ack_pending: 1000}", 1)) 16467 }) 16468 }) 16469 16470 t.Run("single", func(t *testing.T) { 16471 tmpl := ` 16472 listen: 127.0.0.1:-1 16473 jetstream: { 16474 max_mem_store: 2MB, 16475 max_file_store: 8MB, 16476 store_dir: '%s', 16477 limits: {duplicate_window: "1m", max_request_batch: 250} 16478 } 16479 no_auth_user: u 16480 accounts { 16481 ONE { 16482 users = [ { user: "u", pass: "s3cr3t!" } ] 16483 jetstream: enabled 16484 } 16485 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 16486 }` 16487 limitsTest := func(t *testing.T, tmpl string) { 16488 storeDir := t.TempDir() 16489 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, storeDir))) 16490 s, opts := RunServerWithConfig(conf) 16491 defer s.Shutdown() 16492 require_True(t, opts.JetStreamLimits.Duplicates == time.Minute) 16493 test(t, s) 16494 } 16495 // test with max_ack_pending being defined in operator or account 16496 t.Run("operator", func(t *testing.T) { 16497 limitsTest(t, strings.Replace(tmpl, "duplicate_window", "max_ack_pending: 1000, duplicate_window", 1)) 16498 }) 16499 t.Run("account", func(t *testing.T) { 16500 limitsTest(t, strings.Replace(tmpl, "jetstream: enabled", "jetstream: {max_ack_pending: 1000}", 1)) 16501 }) 16502 }) 16503 } 16504 16505 func TestJetStreamConsumerStreamUpdate(t *testing.T) { 16506 test := func(t *testing.T, s *Server, replica int) { 16507 nc := natsConnect(t, s.ClientURL()) 16508 defer nc.Close() 16509 js, err := nc.JetStream() 16510 require_NoError(t, err) 16511 _, err = js.AddStream(&nats.StreamConfig{Name: "foo", Duplicates: 1 * time.Minute, Replicas: replica}) 16512 defer js.DeleteStream("foo") 16513 require_NoError(t, err) 16514 // Update with no change 16515 _, err = js.UpdateStream(&nats.StreamConfig{Name: "foo", Duplicates: 1 * time.Minute, Replicas: replica}) 16516 require_NoError(t, err) 16517 // Update with change 16518 _, err = js.UpdateStream(&nats.StreamConfig{Description: "stream", Name: "foo", Duplicates: 1 * time.Minute, Replicas: replica}) 16519 require_NoError(t, err) 16520 _, err = js.AddConsumer("foo", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy}) 16521 require_NoError(t, err) 16522 // Update with no change 16523 _, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy}) 16524 require_NoError(t, err) 16525 // Update with change 16526 _, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{Description: "consumer", Durable: "dur1", AckPolicy: nats.AckExplicitPolicy}) 16527 require_NoError(t, err) 16528 } 16529 t.Run("clustered", func(t *testing.T) { 16530 c := createJetStreamClusterWithTemplate(t, ` 16531 listen: 127.0.0.1:-1 16532 server_name: %s 16533 jetstream: { 16534 max_mem_store: 2MB, 16535 max_file_store: 8MB, 16536 store_dir: '%s', 16537 } 16538 cluster { 16539 name: %s 16540 listen: 127.0.0.1:%d 16541 routes = [%s] 16542 } 16543 no_auth_user: u 16544 accounts { 16545 ONE { 16546 users = [ { user: "u", pass: "s3cr3t!" } ] 16547 jetstream: enabled 16548 } 16549 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 16550 }`, "clust", 3) 16551 defer c.shutdown() 16552 s := c.randomServer() 16553 t.Run("r3", func(t *testing.T) { 16554 test(t, s, 3) 16555 }) 16556 t.Run("r1", func(t *testing.T) { 16557 test(t, s, 1) 16558 }) 16559 }) 16560 t.Run("single", func(t *testing.T) { 16561 storeDir := t.TempDir() 16562 conf := createConfFile(t, []byte(fmt.Sprintf(` 16563 listen: 127.0.0.1:-1 16564 jetstream: {max_mem_store: 2MB, max_file_store: 8MB, store_dir: '%s'}`, 16565 storeDir))) 16566 s, _ := RunServerWithConfig(conf) 16567 defer s.Shutdown() 16568 test(t, s, 1) 16569 }) 16570 } 16571 16572 func TestJetStreamImportReload(t *testing.T) { 16573 storeDir := t.TempDir() 16574 16575 conf := createConfFile(t, []byte(fmt.Sprintf(` 16576 listen: 127.0.0.1:-1 16577 jetstream: {max_mem_store: 2MB, max_file_store: 8MB, store_dir: '%s'} 16578 accounts: { 16579 account_a: { 16580 users: [{user: user_a, password: pwd}] 16581 exports: [{stream: news.>}] 16582 } 16583 account_b: { 16584 users: [{user: user_b, password: pwd}] 16585 jetstream: enabled 16586 imports: [{stream: {subject: news.>, account: account_a}}] 16587 } 16588 }`, storeDir))) 16589 s, _ := RunServerWithConfig(conf) 16590 defer s.Shutdown() 16591 16592 ncA := natsConnect(t, s.ClientURL(), nats.UserInfo("user_a", "pwd")) 16593 defer ncA.Close() 16594 16595 ncB := natsConnect(t, s.ClientURL(), nats.UserInfo("user_b", "pwd")) 16596 defer ncB.Close() 16597 16598 jsB, err := ncB.JetStream() 16599 require_NoError(t, err) 16600 16601 _, err = jsB.AddStream(&nats.StreamConfig{Name: "news", Subjects: []string{"news.>"}}) 16602 require_NoError(t, err) 16603 16604 require_NoError(t, ncA.Publish("news.article", nil)) 16605 require_NoError(t, ncA.Flush()) 16606 16607 si, err := jsB.StreamInfo("news") 16608 require_NoError(t, err) 16609 require_True(t, si.State.Msgs == 1) 16610 16611 // Remove exports/imports 16612 reloadUpdateConfig(t, s, conf, fmt.Sprintf(` 16613 listen: 127.0.0.1:-1 16614 jetstream: {max_mem_store: 2MB, max_file_store: 8MB, store_dir: '%s'} 16615 accounts: { 16616 account_a: { 16617 users: [{user: user_a, password: pwd}] 16618 } 16619 account_b: { 16620 users: [{user: user_b, password: pwd}] 16621 jetstream: enabled 16622 } 16623 }`, storeDir)) 16624 16625 require_NoError(t, ncA.Publish("news.article", nil)) 16626 require_NoError(t, ncA.Flush()) 16627 16628 si, err = jsB.StreamInfo("news") 16629 require_NoError(t, err) 16630 require_True(t, si.State.Msgs == 1) 16631 } 16632 16633 func TestJetStreamRecoverSealedAfterServerRestart(t *testing.T) { 16634 s := RunBasicJetStreamServer(t) 16635 defer s.Shutdown() 16636 16637 nc, js := jsClientConnect(t, s) 16638 defer nc.Close() 16639 16640 _, err := js.AddStream(&nats.StreamConfig{Name: "foo"}) 16641 require_NoError(t, err) 16642 16643 for i := 0; i < 100; i++ { 16644 js.PublishAsync("foo", []byte("OK")) 16645 } 16646 <-js.PublishAsyncComplete() 16647 16648 _, err = js.UpdateStream(&nats.StreamConfig{Name: "foo", Sealed: true}) 16649 require_NoError(t, err) 16650 16651 nc.Close() 16652 16653 // Stop current 16654 sd := s.JetStreamConfig().StoreDir 16655 s.Shutdown() 16656 // Restart. 16657 s = RunJetStreamServerOnPort(-1, sd) 16658 defer s.Shutdown() 16659 16660 nc, js = jsClientConnect(t, s) 16661 defer nc.Close() 16662 16663 si, err := js.StreamInfo("foo") 16664 require_NoError(t, err) 16665 require_True(t, si.State.Msgs == 100) 16666 } 16667 16668 func TestJetStreamImportConsumerStreamSubjectRemapSingle(t *testing.T) { 16669 conf := createConfFile(t, []byte(fmt.Sprintf(` 16670 listen: 127.0.0.1:-1 16671 jetstream: {max_mem_store: 4GB, max_file_store: 1TB, store_dir: %q} 16672 accounts: { 16673 JS: { 16674 jetstream: enabled 16675 users: [ {user: js, password: pwd} ] 16676 exports [ 16677 # This is streaming to a delivery subject for a push based consumer. 16678 { stream: "deliver.*" } 16679 { stream: "foo.*" } 16680 # This is to ack received messages. This is a service to support sync ack. 16681 { service: "$JS.ACK.ORDERS.*.>" } 16682 # To support ordered consumers, flow control. 16683 { service: "$JS.FC.>" } 16684 ] 16685 }, 16686 IM: { 16687 users: [ {user: im, password: pwd} ] 16688 imports [ 16689 { stream: { account: JS, subject: "deliver.ORDERS" }, to: "d.*" } 16690 { stream: { account: JS, subject: "foo.*" }, to: "bar.*" } 16691 { service: { account: JS, subject: "$JS.FC.>" }} 16692 ] 16693 }, 16694 } 16695 `, t.TempDir()))) 16696 16697 test := func(t *testing.T, queue bool) { 16698 s, _ := RunServerWithConfig(conf) 16699 defer s.Shutdown() 16700 16701 nc, js := jsClientConnect(t, s, nats.UserInfo("js", "pwd")) 16702 defer nc.Close() 16703 16704 _, err := js.AddStream(&nats.StreamConfig{ 16705 Name: "ORDERS", 16706 Subjects: []string{"foo"}, // The JS subject. 16707 Storage: nats.MemoryStorage}, 16708 ) 16709 require_NoError(t, err) 16710 16711 _, err = js.Publish("foo", []byte("OK")) 16712 require_NoError(t, err) 16713 16714 queueName := "" 16715 if queue { 16716 queueName = "queue" 16717 } 16718 16719 _, err = js.AddConsumer("ORDERS", &nats.ConsumerConfig{ 16720 DeliverSubject: "deliver.ORDERS", 16721 AckPolicy: nats.AckExplicitPolicy, 16722 DeliverGroup: queueName, 16723 }) 16724 require_NoError(t, err) 16725 16726 nc2, err := nats.Connect(s.ClientURL(), nats.UserInfo("im", "pwd")) 16727 require_NoError(t, err) 16728 defer nc2.Close() 16729 16730 var sub *nats.Subscription 16731 if queue { 16732 sub, err = nc2.QueueSubscribeSync("d.ORDERS", queueName) 16733 require_NoError(t, err) 16734 } else { 16735 sub, err = nc2.SubscribeSync("d.ORDERS") 16736 require_NoError(t, err) 16737 } 16738 16739 m, err := sub.NextMsg(time.Second) 16740 require_NoError(t, err) 16741 16742 if m.Subject != "foo" { 16743 t.Fatalf("Subject not mapped correctly across account boundary, expected %q got %q", "foo", m.Subject) 16744 } 16745 16746 // Now do one that would kick in a transform. 16747 _, err = js.AddConsumer("ORDERS", &nats.ConsumerConfig{ 16748 DeliverSubject: "foo.ORDERS", 16749 AckPolicy: nats.AckExplicitPolicy, 16750 DeliverGroup: queueName, 16751 }) 16752 require_NoError(t, err) 16753 16754 if queue { 16755 sub, err = nc2.QueueSubscribeSync("bar.ORDERS", queueName) 16756 require_NoError(t, err) 16757 } else { 16758 sub, err = nc2.SubscribeSync("bar.ORDERS") 16759 require_NoError(t, err) 16760 } 16761 m, err = sub.NextMsg(time.Second) 16762 require_NoError(t, err) 16763 16764 if m.Subject != "foo" { 16765 t.Fatalf("Subject not mapped correctly across account boundary, expected %q got %q", "foo", m.Subject) 16766 } 16767 } 16768 16769 t.Run("noqueue", func(t *testing.T) { 16770 test(t, false) 16771 }) 16772 t.Run("queue", func(t *testing.T) { 16773 test(t, true) 16774 }) 16775 } 16776 16777 func TestJetStreamWorkQueueSourceRestart(t *testing.T) { 16778 s := RunBasicJetStreamServer(t) 16779 defer s.Shutdown() 16780 16781 nc, js := jsClientConnect(t, s) 16782 defer nc.Close() 16783 16784 sent := 10 16785 _, err := js.AddStream(&nats.StreamConfig{ 16786 Name: "FOO", 16787 Replicas: 1, 16788 Subjects: []string{"foo"}, 16789 }) 16790 require_NoError(t, err) 16791 16792 for i := 0; i < sent; i++ { 16793 _, err = js.Publish("foo", nil) 16794 require_NoError(t, err) 16795 } 16796 16797 _, err = js.AddStream(&nats.StreamConfig{ 16798 Name: "TEST", 16799 Replicas: 1, 16800 // TODO test will pass when retention commented out 16801 Retention: nats.WorkQueuePolicy, 16802 Sources: []*nats.StreamSource{{Name: "FOO"}}}) 16803 require_NoError(t, err) 16804 16805 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{Durable: "dur", AckPolicy: nats.AckExplicitPolicy}) 16806 require_NoError(t, err) 16807 16808 sub, err := js.PullSubscribe("foo", "dur", nats.BindStream("TEST")) 16809 require_NoError(t, err) 16810 16811 time.Sleep(100 * time.Millisecond) 16812 16813 ci, err := js.ConsumerInfo("TEST", "dur") 16814 require_NoError(t, err) 16815 require_True(t, ci.NumPending == uint64(sent)) 16816 16817 msgs, err := sub.Fetch(sent) 16818 require_NoError(t, err) 16819 require_True(t, len(msgs) == sent) 16820 16821 for i := 0; i < sent; i++ { 16822 err = msgs[i].AckSync() 16823 require_NoError(t, err) 16824 } 16825 16826 ci, err = js.ConsumerInfo("TEST", "dur") 16827 require_NoError(t, err) 16828 require_True(t, ci.NumPending == 0) 16829 16830 si, err := js.StreamInfo("TEST") 16831 require_NoError(t, err) 16832 require_True(t, si.State.Msgs == 0) 16833 16834 // Restart server 16835 nc.Close() 16836 sd := s.JetStreamConfig().StoreDir 16837 s.Shutdown() 16838 time.Sleep(200 * time.Millisecond) 16839 s = RunJetStreamServerOnPort(-1, sd) 16840 defer s.Shutdown() 16841 16842 checkFor(t, 10*time.Second, 200*time.Millisecond, func() error { 16843 hs := s.healthz(nil) 16844 if hs.Status == "ok" && hs.Error == _EMPTY_ { 16845 return nil 16846 } 16847 return fmt.Errorf("healthz %s %s", hs.Error, hs.Status) 16848 }) 16849 16850 nc, js = jsClientConnect(t, s) 16851 defer nc.Close() 16852 16853 si, err = js.StreamInfo("TEST") 16854 require_NoError(t, err) 16855 16856 if si.State.Msgs != 0 { 16857 t.Fatalf("Expected 0 messages on restart, got %d", si.State.Msgs) 16858 } 16859 16860 ctest, err := js.ConsumerInfo("TEST", "dur") 16861 require_NoError(t, err) 16862 16863 //TODO (mh) I have experienced in other tests that NumPending has a value of 1 post restart. 16864 // seems to go awary in single server setup. It's also unrelated to work queue 16865 // but that error seems benign. 16866 if ctest.NumPending != 0 { 16867 t.Fatalf("Expected pending of 0 but got %d", ctest.NumPending) 16868 } 16869 16870 sub, err = js.PullSubscribe("foo", "dur", nats.BindStream("TEST")) 16871 require_NoError(t, err) 16872 _, err = sub.Fetch(1, nats.MaxWait(time.Second)) 16873 if err != nats.ErrTimeout { 16874 require_NoError(t, err) 16875 } 16876 } 16877 16878 func TestJetStreamWorkQueueSourceNamingRestart(t *testing.T) { 16879 s := RunBasicJetStreamServer(t) 16880 defer s.Shutdown() 16881 16882 nc, js := jsClientConnect(t, s) 16883 defer nc.Close() 16884 16885 _, err := js.AddStream(&nats.StreamConfig{Name: "C1", Subjects: []string{"foo.*"}}) 16886 require_NoError(t, err) 16887 _, err = js.AddStream(&nats.StreamConfig{Name: "C2", Subjects: []string{"bar.*"}}) 16888 require_NoError(t, err) 16889 16890 sendCount := 10 16891 for i := 0; i < sendCount; i++ { 16892 _, err = js.Publish(fmt.Sprintf("foo.%d", i), nil) 16893 require_NoError(t, err) 16894 _, err = js.Publish(fmt.Sprintf("bar.%d", i), nil) 16895 require_NoError(t, err) 16896 } 16897 16898 // TODO Test will always pass if pending is 0 16899 pending := 1 16900 // For some yet unknown reason this failure seems to require 2 streams to source from. 16901 // This might possibly be timing, as the test sometimes passes 16902 streams := 2 16903 totalPending := uint64(streams * pending) 16904 totalMsgs := streams * sendCount 16905 totalNonPending := streams * (sendCount - pending) 16906 16907 // TODO Test will always pass if this is named A (go returns directory names sorted) 16908 // A: this stream is recovered BEFORE C1/C2, tbh, I'd expect this to be the case to fail, but it isn't 16909 // D: this stream is recovered AFTER C1/C2, which is the case that fails (perhaps it is timing) 16910 srcName := "D" 16911 _, err = js.AddStream(&nats.StreamConfig{ 16912 Name: srcName, 16913 Retention: nats.WorkQueuePolicy, 16914 Sources: []*nats.StreamSource{{Name: "C1"}, {Name: "C2"}}, 16915 }) 16916 require_NoError(t, err) 16917 16918 // Add a consumer and consume all but totalPending messages 16919 _, err = js.AddConsumer(srcName, &nats.ConsumerConfig{Durable: "dur", AckPolicy: nats.AckExplicitPolicy}) 16920 require_NoError(t, err) 16921 16922 sub, err := js.PullSubscribe("", "dur", nats.BindStream(srcName)) 16923 require_NoError(t, err) 16924 16925 checkFor(t, 5*time.Second, time.Millisecond*200, func() error { 16926 if ci, err := js.ConsumerInfo(srcName, "dur"); err != nil { 16927 return err 16928 } else if ci.NumPending != uint64(totalMsgs) { 16929 return fmt.Errorf("not enough messages: %d", ci.NumPending) 16930 } 16931 return nil 16932 }) 16933 16934 // consume all but messages we want pending 16935 msgs, err := sub.Fetch(totalNonPending) 16936 require_NoError(t, err) 16937 require_True(t, len(msgs) == totalNonPending) 16938 16939 for _, m := range msgs { 16940 err = m.AckSync() 16941 require_NoError(t, err) 16942 } 16943 16944 ci, err := js.ConsumerInfo(srcName, "dur") 16945 require_NoError(t, err) 16946 require_True(t, ci.NumPending == totalPending) 16947 16948 si, err := js.StreamInfo(srcName) 16949 require_NoError(t, err) 16950 require_True(t, si.State.Msgs == totalPending) 16951 16952 // Restart server 16953 nc.Close() 16954 sd := s.JetStreamConfig().StoreDir 16955 s.Shutdown() 16956 time.Sleep(200 * time.Millisecond) 16957 s = RunJetStreamServerOnPort(-1, sd) 16958 defer s.Shutdown() 16959 16960 checkFor(t, 10*time.Second, 200*time.Millisecond, func() error { 16961 hs := s.healthz(nil) 16962 if hs.Status == "ok" && hs.Error == _EMPTY_ { 16963 return nil 16964 } 16965 return fmt.Errorf("healthz %s %s", hs.Error, hs.Status) 16966 }) 16967 16968 nc, js = jsClientConnect(t, s) 16969 defer nc.Close() 16970 16971 si, err = js.StreamInfo(srcName) 16972 require_NoError(t, err) 16973 16974 if si.State.Msgs != totalPending { 16975 t.Fatalf("Expected 0 messages on restart, got %d", si.State.Msgs) 16976 } 16977 } 16978 16979 func TestJetStreamDisabledHealthz(t *testing.T) { 16980 s := RunBasicJetStreamServer(t) 16981 defer s.Shutdown() 16982 16983 if !s.JetStreamEnabled() { 16984 t.Fatalf("Expected JetStream to be enabled") 16985 } 16986 16987 s.DisableJetStream() 16988 16989 hs := s.healthz(&HealthzOptions{JSEnabledOnly: true}) 16990 if hs.Status == "unavailable" && hs.Error == NewJSNotEnabledError().Error() { 16991 return 16992 } 16993 16994 t.Fatalf("Expected healthz to return error if JetStream is disabled, got status: %s", hs.Status) 16995 } 16996 16997 func TestJetStreamPullTimeout(t *testing.T) { 16998 s := RunBasicJetStreamServer(t) 16999 defer s.Shutdown() 17000 17001 nc, js := jsClientConnect(t, s) 17002 defer nc.Close() 17003 17004 _, err := js.AddStream(&nats.StreamConfig{ 17005 Name: "TEST", 17006 }) 17007 require_NoError(t, err) 17008 17009 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 17010 Durable: "pr", 17011 AckPolicy: nats.AckExplicitPolicy, 17012 }) 17013 require_NoError(t, err) 17014 17015 const numMessages = 1000 17016 // Send messages in small intervals. 17017 go func() { 17018 for i := 0; i < numMessages; i++ { 17019 time.Sleep(time.Millisecond * 10) 17020 sendStreamMsg(t, nc, "TEST", "data") 17021 } 17022 }() 17023 17024 // Prepare manual Pull Request. 17025 req := &JSApiConsumerGetNextRequest{Batch: 200, NoWait: false, Expires: time.Millisecond * 100} 17026 jreq, _ := json.Marshal(req) 17027 17028 subj := fmt.Sprintf(JSApiRequestNextT, "TEST", "pr") 17029 reply := "_pr_" 17030 var got atomic.Int32 17031 nc.PublishRequest(subj, reply, jreq) 17032 17033 // Manually subscribe to inbox subject and send new request only if we get `408 Request Timeout`. 17034 sub, _ := nc.Subscribe(reply, func(msg *nats.Msg) { 17035 if msg.Header.Get("Status") == "408" && msg.Header.Get("Description") == "Request Timeout" { 17036 nc.PublishRequest(subj, reply, jreq) 17037 nc.Flush() 17038 } else { 17039 got.Add(1) 17040 msg.Ack() 17041 } 17042 }) 17043 defer sub.Unsubscribe() 17044 17045 // Check if we're not stuck. 17046 checkFor(t, time.Second*30, time.Second*1, func() error { 17047 if got.Load() < int32(numMessages) { 17048 return fmt.Errorf("expected %d messages", numMessages) 17049 } 17050 return nil 17051 }) 17052 } 17053 17054 func TestJetStreamPullMaxBytes(t *testing.T) { 17055 s := RunBasicJetStreamServer(t) 17056 defer s.Shutdown() 17057 17058 nc, js := jsClientConnect(t, s) 17059 defer nc.Close() 17060 17061 _, err := js.AddStream(&nats.StreamConfig{ 17062 Name: "TEST", 17063 }) 17064 require_NoError(t, err) 17065 17066 // Put in ~2MB, each ~100k 17067 msz, dsz := 100_000, 99_950 17068 total, msg := 20, []byte(strings.Repeat("Z", dsz)) 17069 17070 for i := 0; i < total; i++ { 17071 if _, err := js.Publish("TEST", msg); err != nil { 17072 t.Fatalf("Unexpected publish error: %v", err) 17073 } 17074 } 17075 17076 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 17077 Durable: "pr", 17078 AckPolicy: nats.AckExplicitPolicy, 17079 }) 17080 require_NoError(t, err) 17081 17082 req := &JSApiConsumerGetNextRequest{MaxBytes: 100, NoWait: true} 17083 jreq, _ := json.Marshal(req) 17084 17085 subj := fmt.Sprintf(JSApiRequestNextT, "TEST", "pr") 17086 reply := "_pr_" 17087 sub, _ := nc.SubscribeSync(reply) 17088 defer sub.Unsubscribe() 17089 17090 checkHeader := func(m *nats.Msg, expected *nats.Header) { 17091 t.Helper() 17092 if len(m.Data) != 0 { 17093 t.Fatalf("Did not expect data, got %d bytes", len(m.Data)) 17094 } 17095 expectedStatus, givenStatus := expected.Get("Status"), m.Header.Get("Status") 17096 expectedDesc, givenDesc := expected.Get("Description"), m.Header.Get("Description") 17097 if expectedStatus != givenStatus || expectedDesc != givenDesc { 17098 t.Fatalf("expected %s %s, got %s %s", expectedStatus, expectedDesc, givenStatus, givenDesc) 17099 } 17100 } 17101 17102 // If we ask for less MaxBytes then a single message make sure we get an error. 17103 badReq := &nats.Header{"Status": []string{"409"}, "Description": []string{"Message Size Exceeds MaxBytes"}} 17104 17105 nc.PublishRequest(subj, reply, jreq) 17106 m, err := sub.NextMsg(time.Second) 17107 require_NoError(t, err) 17108 checkSubsPending(t, sub, 0) 17109 checkHeader(m, badReq) 17110 17111 // If we request a ton of max bytes make sure batch size overrides. 17112 req = &JSApiConsumerGetNextRequest{Batch: 1, MaxBytes: 10_000_000, NoWait: true} 17113 jreq, _ = json.Marshal(req) 17114 nc.PublishRequest(subj, reply, jreq) 17115 // we expect two messages, as the second one should be `Batch Completed` status. 17116 checkSubsPending(t, sub, 2) 17117 17118 // first one is message from the stream. 17119 m, err = sub.NextMsg(time.Second) 17120 require_NoError(t, err) 17121 require_True(t, len(m.Data) == dsz) 17122 require_True(t, len(m.Header) == 0) 17123 // second one is the status. 17124 m, err = sub.NextMsg(time.Second) 17125 require_NoError(t, err) 17126 if v := m.Header.Get("Description"); v != "Batch Completed" { 17127 t.Fatalf("Expected Batch Completed, got: %s", v) 17128 } 17129 checkSubsPending(t, sub, 0) 17130 17131 // Same but with batch > 1 17132 req = &JSApiConsumerGetNextRequest{Batch: 5, MaxBytes: 10_000_000, NoWait: true} 17133 jreq, _ = json.Marshal(req) 17134 nc.PublishRequest(subj, reply, jreq) 17135 // 6, not 5, as 6th is the status. 17136 checkSubsPending(t, sub, 6) 17137 for i := 0; i < 5; i++ { 17138 m, err = sub.NextMsg(time.Second) 17139 require_NoError(t, err) 17140 require_True(t, len(m.Data) == dsz) 17141 require_True(t, len(m.Header) == 0) 17142 } 17143 m, err = sub.NextMsg(time.Second) 17144 require_NoError(t, err) 17145 if v := m.Header.Get("Description"); v != "Batch Completed" { 17146 t.Fatalf("Expected Batch Completed, got: %s", v) 17147 } 17148 checkSubsPending(t, sub, 0) 17149 17150 // Now ask for large batch but make sure we are limited by batch size. 17151 req = &JSApiConsumerGetNextRequest{Batch: 1_000, MaxBytes: msz * 4, NoWait: true} 17152 jreq, _ = json.Marshal(req) 17153 nc.PublishRequest(subj, reply, jreq) 17154 // Receive 4 messages + the 409 17155 checkSubsPending(t, sub, 5) 17156 for i := 0; i < 4; i++ { 17157 m, err = sub.NextMsg(time.Second) 17158 require_NoError(t, err) 17159 require_True(t, len(m.Data) == dsz) 17160 require_True(t, len(m.Header) == 0) 17161 } 17162 m, err = sub.NextMsg(time.Second) 17163 require_NoError(t, err) 17164 checkHeader(m, badReq) 17165 checkSubsPending(t, sub, 0) 17166 17167 req = &JSApiConsumerGetNextRequest{Batch: 1_000, MaxBytes: msz, NoWait: true} 17168 jreq, _ = json.Marshal(req) 17169 nc.PublishRequest(subj, reply, jreq) 17170 // Receive 1 message + 409 17171 checkSubsPending(t, sub, 2) 17172 m, err = sub.NextMsg(time.Second) 17173 require_NoError(t, err) 17174 require_True(t, len(m.Data) == dsz) 17175 require_True(t, len(m.Header) == 0) 17176 m, err = sub.NextMsg(time.Second) 17177 require_NoError(t, err) 17178 checkHeader(m, badReq) 17179 checkSubsPending(t, sub, 0) 17180 } 17181 17182 func TestJetStreamStreamRepublishCycle(t *testing.T) { 17183 s := RunBasicJetStreamServer(t) 17184 defer s.Shutdown() 17185 17186 nc, _ := jsClientConnect(t, s) 17187 defer nc.Close() 17188 17189 // Do by hand for now. 17190 cfg := &StreamConfig{ 17191 Name: "RPC", 17192 Storage: MemoryStorage, 17193 Subjects: []string{"foo.>", "bar.*", "baz"}, 17194 } 17195 17196 expectFail := func() { 17197 t.Helper() 17198 req, err := json.Marshal(cfg) 17199 require_NoError(t, err) 17200 rmsg, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 17201 require_NoError(t, err) 17202 var resp JSApiStreamCreateResponse 17203 err = json.Unmarshal(rmsg.Data, &resp) 17204 require_NoError(t, err) 17205 if resp.Type != JSApiStreamCreateResponseType { 17206 t.Fatalf("Invalid response type %s expected %s", resp.Type, JSApiStreamCreateResponseType) 17207 } 17208 if resp.Error == nil { 17209 t.Fatalf("Expected error but got none") 17210 } 17211 if !strings.Contains(resp.Error.Description, "republish destination forms a cycle") { 17212 t.Fatalf("Expected cycle error, got %q", resp.Error.Description) 17213 } 17214 } 17215 17216 cfg.RePublish = &RePublish{ 17217 Source: "foo.>", 17218 Destination: "foo.>", 17219 } 17220 expectFail() 17221 17222 cfg.RePublish = &RePublish{ 17223 Source: "bar.bar", 17224 Destination: "foo.bar", 17225 } 17226 expectFail() 17227 17228 cfg.RePublish = &RePublish{ 17229 Source: "baz", 17230 Destination: "bar.bar", 17231 } 17232 expectFail() 17233 } 17234 17235 func TestJetStreamStreamRepublishOneTokenMatch(t *testing.T) { 17236 s := RunBasicJetStreamServer(t) 17237 defer s.Shutdown() 17238 17239 nc, js := jsClientConnect(t, s) 17240 defer nc.Close() 17241 17242 // Do by hand for now. 17243 cfg := &StreamConfig{ 17244 Name: "Stream1", 17245 Storage: MemoryStorage, 17246 Subjects: []string{"one", "four"}, 17247 RePublish: &RePublish{ 17248 Source: "one", 17249 Destination: "uno", 17250 HeadersOnly: false, 17251 }, 17252 } 17253 addStream(t, nc, cfg) 17254 17255 sub, err := nc.SubscribeSync("uno") 17256 require_NoError(t, err) 17257 17258 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17259 for i := 0; i < toSend; i++ { 17260 js.PublishAsync("one", msg) 17261 } 17262 select { 17263 case <-js.PublishAsyncComplete(): 17264 case <-time.After(5 * time.Second): 17265 t.Fatalf("Did not receive completion signal") 17266 } 17267 17268 checkSubsPending(t, sub, toSend) 17269 m, err := sub.NextMsg(time.Second) 17270 require_NoError(t, err) 17271 17272 if !(len(m.Data) > 0) { 17273 t.Fatalf("Expected msg data") 17274 } 17275 } 17276 17277 func TestJetStreamStreamRepublishMultiTokenMatch(t *testing.T) { 17278 s := RunBasicJetStreamServer(t) 17279 defer s.Shutdown() 17280 17281 nc, js := jsClientConnect(t, s) 17282 defer nc.Close() 17283 17284 // Do by hand for now. 17285 cfg := &StreamConfig{ 17286 Name: "Stream1", 17287 Storage: MemoryStorage, 17288 Subjects: []string{"one.>", "four.>"}, 17289 RePublish: &RePublish{ 17290 Source: "one.two.>", 17291 Destination: "uno.dos.>", 17292 HeadersOnly: false, 17293 }, 17294 } 17295 addStream(t, nc, cfg) 17296 17297 sub, err := nc.SubscribeSync("uno.dos.>") 17298 require_NoError(t, err) 17299 17300 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17301 for i := 0; i < toSend; i++ { 17302 js.PublishAsync("one.two.three", msg) 17303 } 17304 select { 17305 case <-js.PublishAsyncComplete(): 17306 case <-time.After(5 * time.Second): 17307 t.Fatalf("Did not receive completion signal") 17308 } 17309 17310 checkSubsPending(t, sub, toSend) 17311 m, err := sub.NextMsg(time.Second) 17312 require_NoError(t, err) 17313 17314 if !(len(m.Data) > 0) { 17315 t.Fatalf("Expected msg data") 17316 } 17317 } 17318 17319 func TestJetStreamStreamRepublishAnySubjectMatch(t *testing.T) { 17320 s := RunBasicJetStreamServer(t) 17321 defer s.Shutdown() 17322 17323 nc, js := jsClientConnect(t, s) 17324 defer nc.Close() 17325 17326 // Do by hand for now. 17327 cfg := &StreamConfig{ 17328 Name: "Stream1", 17329 Storage: MemoryStorage, 17330 Subjects: []string{"one.>", "four.>"}, 17331 RePublish: &RePublish{ 17332 Destination: "uno.dos.>", 17333 HeadersOnly: false, 17334 }, 17335 } 17336 addStream(t, nc, cfg) 17337 17338 sub, err := nc.SubscribeSync("uno.dos.>") 17339 require_NoError(t, err) 17340 17341 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17342 for i := 0; i < toSend; i++ { 17343 js.PublishAsync("one.two.three", msg) 17344 } 17345 select { 17346 case <-js.PublishAsyncComplete(): 17347 case <-time.After(5 * time.Second): 17348 t.Fatalf("Did not receive completion signal") 17349 } 17350 17351 checkSubsPending(t, sub, toSend) 17352 m, err := sub.NextMsg(time.Second) 17353 require_NoError(t, err) 17354 17355 if !(len(m.Data) > 0) { 17356 t.Fatalf("Expected msg data") 17357 } 17358 } 17359 17360 func TestJetStreamStreamRepublishMultiTokenNoMatch(t *testing.T) { 17361 s := RunBasicJetStreamServer(t) 17362 defer s.Shutdown() 17363 17364 nc, js := jsClientConnect(t, s) 17365 defer nc.Close() 17366 17367 // Do by hand for now. 17368 cfg := &StreamConfig{ 17369 Name: "Stream1", 17370 Storage: MemoryStorage, 17371 Subjects: []string{"one.>", "four.>"}, 17372 RePublish: &RePublish{ 17373 Source: "one.two.>", 17374 Destination: "uno.dos.>", 17375 HeadersOnly: true, 17376 }, 17377 } 17378 addStream(t, nc, cfg) 17379 17380 sub, err := nc.SubscribeSync("uno.dos.>") 17381 require_NoError(t, err) 17382 17383 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17384 for i := 0; i < toSend; i++ { 17385 js.PublishAsync("four.five.six", msg) 17386 } 17387 select { 17388 case <-js.PublishAsyncComplete(): 17389 case <-time.After(5 * time.Second): 17390 t.Fatalf("Did not receive completion signal") 17391 } 17392 17393 checkSubsPending(t, sub, 0) 17394 require_NoError(t, err) 17395 } 17396 17397 func TestJetStreamStreamRepublishOneTokenNoMatch(t *testing.T) { 17398 s := RunBasicJetStreamServer(t) 17399 defer s.Shutdown() 17400 17401 nc, js := jsClientConnect(t, s) 17402 defer nc.Close() 17403 17404 // Do by hand for now. 17405 cfg := &StreamConfig{ 17406 Name: "Stream1", 17407 Storage: MemoryStorage, 17408 Subjects: []string{"one", "four"}, 17409 RePublish: &RePublish{ 17410 Source: "one", 17411 Destination: "uno", 17412 HeadersOnly: true, 17413 }, 17414 } 17415 addStream(t, nc, cfg) 17416 17417 sub, err := nc.SubscribeSync("uno") 17418 require_NoError(t, err) 17419 17420 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17421 for i := 0; i < toSend; i++ { 17422 js.PublishAsync("four", msg) 17423 } 17424 select { 17425 case <-js.PublishAsyncComplete(): 17426 case <-time.After(5 * time.Second): 17427 t.Fatalf("Did not receive completion signal") 17428 } 17429 17430 checkSubsPending(t, sub, 0) 17431 require_NoError(t, err) 17432 } 17433 17434 func TestJetStreamStreamRepublishHeadersOnly(t *testing.T) { 17435 s := RunBasicJetStreamServer(t) 17436 defer s.Shutdown() 17437 17438 nc, js := jsClientConnect(t, s) 17439 defer nc.Close() 17440 17441 // Do by hand for now. 17442 cfg := &StreamConfig{ 17443 Name: "RPC", 17444 Storage: MemoryStorage, 17445 Subjects: []string{"foo", "bar", "baz"}, 17446 RePublish: &RePublish{ 17447 Destination: "RP.>", 17448 HeadersOnly: true, 17449 }, 17450 } 17451 addStream(t, nc, cfg) 17452 17453 sub, err := nc.SubscribeSync("RP.>") 17454 require_NoError(t, err) 17455 17456 msg, toSend := bytes.Repeat([]byte("Z"), 512), 100 17457 for i := 0; i < toSend; i++ { 17458 js.PublishAsync("foo", msg) 17459 } 17460 select { 17461 case <-js.PublishAsyncComplete(): 17462 case <-time.After(5 * time.Second): 17463 t.Fatalf("Did not receive completion signal") 17464 } 17465 17466 checkSubsPending(t, sub, toSend) 17467 m, err := sub.NextMsg(time.Second) 17468 require_NoError(t, err) 17469 17470 if len(m.Data) > 0 { 17471 t.Fatalf("Expected no msg just headers, but got %d bytes", len(m.Data)) 17472 } 17473 if sz := m.Header.Get(JSMsgSize); sz != "512" { 17474 t.Fatalf("Expected msg size hdr, got %q", sz) 17475 } 17476 } 17477 17478 func TestJetStreamConsumerDeliverNewNotConsumingBeforeRestart(t *testing.T) { 17479 s := RunBasicJetStreamServer(t) 17480 defer s.Shutdown() 17481 17482 nc, js := jsClientConnect(t, s) 17483 defer nc.Close() 17484 17485 _, err := js.AddStream(&nats.StreamConfig{ 17486 Name: "TEST", 17487 Subjects: []string{"foo"}, 17488 }) 17489 require_NoError(t, err) 17490 17491 inbox := nats.NewInbox() 17492 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 17493 DeliverSubject: inbox, 17494 Durable: "dur", 17495 AckPolicy: nats.AckExplicitPolicy, 17496 DeliverPolicy: nats.DeliverNewPolicy, 17497 FilterSubject: "foo", 17498 }) 17499 require_NoError(t, err) 17500 17501 for i := 0; i < 10; i++ { 17502 sendStreamMsg(t, nc, "foo", "msg") 17503 } 17504 17505 checkCount := func(expected int) { 17506 t.Helper() 17507 checkFor(t, 2*time.Second, 15*time.Millisecond, func() error { 17508 ci, err := js.ConsumerInfo("TEST", "dur") 17509 if err != nil { 17510 return err 17511 } 17512 if n := int(ci.NumPending); n != expected { 17513 return fmt.Errorf("Expected %v pending, got %v", expected, n) 17514 } 17515 return nil 17516 }) 17517 } 17518 checkCount(10) 17519 17520 time.Sleep(300 * time.Millisecond) 17521 17522 // Check server restart 17523 nc.Close() 17524 sd := s.JetStreamConfig().StoreDir 17525 s.Shutdown() 17526 // Restart. 17527 s = RunJetStreamServerOnPort(-1, sd) 17528 defer s.Shutdown() 17529 17530 nc, js = jsClientConnect(t, s) 17531 defer nc.Close() 17532 17533 checkCount(10) 17534 17535 // Make sure messages can be consumed 17536 sub := natsSubSync(t, nc, inbox) 17537 for i := 0; i < 10; i++ { 17538 msg, err := sub.NextMsg(time.Second) 17539 if err != nil { 17540 t.Fatalf("i=%v next msg error: %v", i, err) 17541 } 17542 msg.AckSync() 17543 } 17544 checkCount(0) 17545 } 17546 17547 func TestJetStreamConsumerNumPendingWithMaxPerSubjectGreaterThanOne(t *testing.T) { 17548 s := RunBasicJetStreamServer(t) 17549 defer s.Shutdown() 17550 17551 nc, js := jsClientConnect(t, s) 17552 defer nc.Close() 17553 17554 test := func(t *testing.T, st nats.StorageType) { 17555 _, err := js.AddStream(&nats.StreamConfig{ 17556 Name: "TEST", 17557 Subjects: []string{"KV.*.*"}, 17558 MaxMsgsPerSubject: 2, 17559 Storage: st, 17560 }) 17561 require_NoError(t, err) 17562 17563 // If we allow more than one msg per subject, consumer's num pending can be off (bug in store level). 17564 // This requires a filtered state, simple states work ok. 17565 // Since we now rely on stream's filtered state when asked directly for consumer info in >=2.8.3. 17566 js.PublishAsync("KV.plans.foo", []byte("OK")) 17567 js.PublishAsync("KV.plans.bar", []byte("OK")) 17568 js.PublishAsync("KV.plans.baz", []byte("OK")) 17569 // These are required, the consumer needs to filter these out to see the bug. 17570 js.PublishAsync("KV.config.foo", []byte("OK")) 17571 js.PublishAsync("KV.config.bar", []byte("OK")) 17572 js.PublishAsync("KV.config.baz", []byte("OK")) 17573 17574 // Double up some now. 17575 js.PublishAsync("KV.plans.bar", []byte("OK")) 17576 js.PublishAsync("KV.plans.baz", []byte("OK")) 17577 17578 ci, err := js.AddConsumer("TEST", &nats.ConsumerConfig{ 17579 Durable: "d", 17580 AckPolicy: nats.AckExplicitPolicy, 17581 DeliverPolicy: nats.DeliverLastPerSubjectPolicy, 17582 FilterSubject: "KV.plans.*", 17583 }) 17584 require_NoError(t, err) 17585 17586 err = js.DeleteStream("TEST") 17587 require_NoError(t, err) 17588 17589 if ci.NumPending != 3 { 17590 t.Fatalf("Expected 3 NumPending, but got %d", ci.NumPending) 17591 } 17592 } 17593 17594 t.Run("MemoryStore", func(t *testing.T) { test(t, nats.MemoryStorage) }) 17595 t.Run("FileStore", func(t *testing.T) { test(t, nats.FileStorage) }) 17596 } 17597 17598 func TestJetStreamMsgGetNoAdvisory(t *testing.T) { 17599 s := RunBasicJetStreamServer(t) 17600 defer s.Shutdown() 17601 17602 nc, js := jsClientConnect(t, s) 17603 defer nc.Close() 17604 17605 _, err := js.AddStream(&nats.StreamConfig{Name: "foo"}) 17606 require_NoError(t, err) 17607 17608 for i := 0; i < 100; i++ { 17609 js.PublishAsync("foo", []byte("ok")) 17610 } 17611 select { 17612 case <-js.PublishAsyncComplete(): 17613 case <-time.After(5 * time.Second): 17614 t.Fatalf("Did not receive completion signal") 17615 } 17616 17617 sub, err := nc.SubscribeSync("$JS.EVENT.ADVISORY.>") 17618 require_NoError(t, err) 17619 17620 _, err = js.GetMsg("foo", 1) 17621 require_NoError(t, err) 17622 17623 checkSubsPending(t, sub, 0) 17624 } 17625 17626 func TestJetStreamDirectMsgGet(t *testing.T) { 17627 s := RunBasicJetStreamServer(t) 17628 defer s.Shutdown() 17629 17630 nc, _ := jsClientConnect(t, s) 17631 defer nc.Close() 17632 17633 // Do by hand for now. 17634 cfg := &StreamConfig{ 17635 Name: "DSMG", 17636 Storage: MemoryStorage, 17637 Subjects: []string{"foo", "bar", "baz"}, 17638 MaxMsgsPer: 1, 17639 AllowDirect: true, 17640 } 17641 addStream(t, nc, cfg) 17642 17643 sendStreamMsg(t, nc, "foo", "foo") 17644 sendStreamMsg(t, nc, "bar", "bar") 17645 sendStreamMsg(t, nc, "baz", "baz") 17646 17647 getSubj := fmt.Sprintf(JSDirectMsgGetT, "DSMG") 17648 getMsg := func(req *JSApiMsgGetRequest) *nats.Msg { 17649 var b []byte 17650 var err error 17651 if req != nil { 17652 b, err = json.Marshal(req) 17653 require_NoError(t, err) 17654 } 17655 m, err := nc.Request(getSubj, b, time.Second) 17656 require_NoError(t, err) 17657 return m 17658 } 17659 17660 m := getMsg(&JSApiMsgGetRequest{LastFor: "foo"}) 17661 require_True(t, string(m.Data) == "foo") 17662 require_True(t, m.Header.Get(JSStream) == "DSMG") 17663 require_True(t, m.Header.Get(JSSequence) == "1") 17664 require_True(t, m.Header.Get(JSSubject) == "foo") 17665 require_True(t, m.Subject != "foo") 17666 require_True(t, m.Header.Get(JSTimeStamp) != _EMPTY_) 17667 17668 m = getMsg(&JSApiMsgGetRequest{LastFor: "bar"}) 17669 require_True(t, string(m.Data) == "bar") 17670 require_True(t, m.Header.Get(JSStream) == "DSMG") 17671 require_True(t, m.Header.Get(JSSequence) == "2") 17672 require_True(t, m.Header.Get(JSSubject) == "bar") 17673 require_True(t, m.Subject != "bar") 17674 require_True(t, m.Header.Get(JSTimeStamp) != _EMPTY_) 17675 17676 m = getMsg(&JSApiMsgGetRequest{LastFor: "baz"}) 17677 require_True(t, string(m.Data) == "baz") 17678 require_True(t, m.Header.Get(JSStream) == "DSMG") 17679 require_True(t, m.Header.Get(JSSequence) == "3") 17680 require_True(t, m.Header.Get(JSSubject) == "baz") 17681 require_True(t, m.Subject != "baz") 17682 require_True(t, m.Header.Get(JSTimeStamp) != _EMPTY_) 17683 17684 // Test error conditions 17685 17686 // Nil request 17687 m = getMsg(nil) 17688 require_True(t, len(m.Data) == 0) 17689 require_True(t, m.Header.Get("Status") == "408") 17690 require_True(t, m.Header.Get("Description") == "Empty Request") 17691 17692 // Empty request 17693 m = getMsg(&JSApiMsgGetRequest{}) 17694 require_True(t, len(m.Data) == 0) 17695 require_True(t, m.Header.Get("Status") == "408") 17696 require_True(t, m.Header.Get("Description") == "Empty Request") 17697 17698 // Both set 17699 m = getMsg(&JSApiMsgGetRequest{Seq: 1, LastFor: "foo"}) 17700 require_True(t, len(m.Data) == 0) 17701 require_True(t, m.Header.Get("Status") == "408") 17702 require_True(t, m.Header.Get("Description") == "Bad Request") 17703 17704 // Not found 17705 m = getMsg(&JSApiMsgGetRequest{LastFor: "foobar"}) 17706 require_True(t, len(m.Data) == 0) 17707 require_True(t, m.Header.Get("Status") == "404") 17708 require_True(t, m.Header.Get("Description") == "Message Not Found") 17709 17710 m = getMsg(&JSApiMsgGetRequest{Seq: 22}) 17711 require_True(t, len(m.Data) == 0) 17712 require_True(t, m.Header.Get("Status") == "404") 17713 require_True(t, m.Header.Get("Description") == "Message Not Found") 17714 } 17715 17716 // This allows support for a get next given a sequence as a starting. 17717 // This allows these to be chained together if needed for sparse streams. 17718 func TestJetStreamDirectMsgGetNext(t *testing.T) { 17719 s := RunBasicJetStreamServer(t) 17720 defer s.Shutdown() 17721 17722 nc, _ := jsClientConnect(t, s) 17723 defer nc.Close() 17724 17725 // Do by hand for now. 17726 cfg := &StreamConfig{ 17727 Name: "DSMG", 17728 Storage: MemoryStorage, 17729 Subjects: []string{"foo", "bar", "baz"}, 17730 AllowDirect: true, 17731 } 17732 addStream(t, nc, cfg) 17733 17734 sendStreamMsg(t, nc, "foo", "foo") 17735 for i := 0; i < 10; i++ { 17736 sendStreamMsg(t, nc, "bar", "bar") 17737 } 17738 for i := 0; i < 10; i++ { 17739 sendStreamMsg(t, nc, "baz", "baz") 17740 } 17741 sendStreamMsg(t, nc, "foo", "foo") 17742 17743 getSubj := fmt.Sprintf(JSDirectMsgGetT, "DSMG") 17744 getMsg := func(seq uint64, subj string) *nats.Msg { 17745 req := []byte(fmt.Sprintf(`{"seq": %d, "next_by_subj": %q}`, seq, subj)) 17746 m, err := nc.Request(getSubj, req, time.Second) 17747 require_NoError(t, err) 17748 return m 17749 } 17750 17751 m := getMsg(0, "foo") 17752 require_True(t, m.Header.Get(JSSequence) == "1") 17753 require_True(t, m.Header.Get(JSSubject) == "foo") 17754 17755 m = getMsg(1, "foo") 17756 require_True(t, m.Header.Get(JSSequence) == "1") 17757 require_True(t, m.Header.Get(JSSubject) == "foo") 17758 17759 m = getMsg(2, "foo") 17760 require_True(t, m.Header.Get(JSSequence) == "22") 17761 require_True(t, m.Header.Get(JSSubject) == "foo") 17762 17763 m = getMsg(2, "bar") 17764 require_True(t, m.Header.Get(JSSequence) == "2") 17765 require_True(t, m.Header.Get(JSSubject) == "bar") 17766 17767 m = getMsg(5, "baz") 17768 require_True(t, m.Header.Get(JSSequence) == "12") 17769 require_True(t, m.Header.Get(JSSubject) == "baz") 17770 17771 m = getMsg(14, "baz") 17772 require_True(t, m.Header.Get(JSSequence) == "14") 17773 require_True(t, m.Header.Get(JSSubject) == "baz") 17774 } 17775 17776 func TestJetStreamConsumerAndStreamNamesWithPathSeparators(t *testing.T) { 17777 s := RunBasicJetStreamServer(t) 17778 defer s.Shutdown() 17779 17780 nc, js := jsClientConnect(t, s) 17781 defer nc.Close() 17782 17783 _, err := js.AddStream(&nats.StreamConfig{Name: "usr/bin"}) 17784 require_Error(t, err, NewJSStreamNameContainsPathSeparatorsError(), nats.ErrInvalidStreamName) 17785 _, err = js.AddStream(&nats.StreamConfig{Name: `Documents\readme.txt`}) 17786 require_Error(t, err, NewJSStreamNameContainsPathSeparatorsError(), nats.ErrInvalidStreamName) 17787 17788 // Now consumers. 17789 _, err = js.AddStream(&nats.StreamConfig{Name: "T"}) 17790 require_NoError(t, err) 17791 17792 _, err = js.AddConsumer("T", &nats.ConsumerConfig{Durable: "a/b", AckPolicy: nats.AckExplicitPolicy}) 17793 require_Error(t, err, NewJSConsumerNameContainsPathSeparatorsError(), nats.ErrInvalidConsumerName) 17794 17795 _, err = js.AddConsumer("T", &nats.ConsumerConfig{Durable: `a\b`, AckPolicy: nats.AckExplicitPolicy}) 17796 require_Error(t, err, NewJSConsumerNameContainsPathSeparatorsError(), nats.ErrInvalidConsumerName) 17797 } 17798 17799 func TestJetStreamConsumerUpdateFilterSubject(t *testing.T) { 17800 s := RunBasicJetStreamServer(t) 17801 defer s.Shutdown() 17802 17803 nc, js := jsClientConnect(t, s) 17804 defer nc.Close() 17805 17806 _, err := js.AddStream(&nats.StreamConfig{Name: "T", Subjects: []string{"foo", "bar", "baz"}}) 17807 require_NoError(t, err) 17808 17809 // 10 foo 17810 for i := 0; i < 10; i++ { 17811 js.PublishAsync("foo", []byte("OK")) 17812 } 17813 // 20 bar 17814 for i := 0; i < 20; i++ { 17815 js.PublishAsync("bar", []byte("OK")) 17816 } 17817 select { 17818 case <-js.PublishAsyncComplete(): 17819 case <-time.After(5 * time.Second): 17820 t.Fatalf("Did not receive completion signal") 17821 } 17822 17823 sub, err := js.PullSubscribe("foo", "d") 17824 require_NoError(t, err) 17825 17826 // Consume 5 msgs 17827 msgs, err := sub.Fetch(5) 17828 require_NoError(t, err) 17829 require_True(t, len(msgs) == 5) 17830 17831 // Now update to different filter subject. 17832 _, err = js.UpdateConsumer("T", &nats.ConsumerConfig{ 17833 Durable: "d", 17834 FilterSubject: "bar", 17835 AckPolicy: nats.AckExplicitPolicy, 17836 }) 17837 require_NoError(t, err) 17838 17839 sub, err = js.PullSubscribe("bar", "d") 17840 require_NoError(t, err) 17841 17842 msgs, err = sub.Fetch(1) 17843 require_NoError(t, err) 17844 17845 // Make sure meta and pending etc are all correct. 17846 m := msgs[0] 17847 meta, err := m.Metadata() 17848 require_NoError(t, err) 17849 17850 if meta.Sequence.Consumer != 6 || meta.Sequence.Stream != 11 { 17851 t.Fatalf("Sequence incorrect %+v", meta.Sequence) 17852 } 17853 if meta.NumDelivered != 1 { 17854 t.Fatalf("Expected NumDelivered to be 1, got %d", meta.NumDelivered) 17855 } 17856 if meta.NumPending != 19 { 17857 t.Fatalf("Expected NumPending to be 19, got %d", meta.NumPending) 17858 } 17859 } 17860 17861 // Originally pull consumers were FIFO with respect to the request, not delivery of messages. 17862 // We have changed to have the behavior be FIFO but on an individual message basis. 17863 // So after a message is delivered, the request, if still outstanding, effectively 17864 // goes to the end of the queue of requests pending. 17865 func TestJetStreamConsumerPullConsumerFIFO(t *testing.T) { 17866 s := RunBasicJetStreamServer(t) 17867 defer s.Shutdown() 17868 17869 nc, js := jsClientConnect(t, s) 17870 defer nc.Close() 17871 17872 _, err := js.AddStream(&nats.StreamConfig{Name: "T"}) 17873 require_NoError(t, err) 17874 17875 // Create pull consumer. 17876 _, err = js.AddConsumer("T", &nats.ConsumerConfig{Durable: "d", AckPolicy: nats.AckExplicitPolicy}) 17877 require_NoError(t, err) 17878 17879 // Simulate 10 pull requests each asking for 10 messages. 17880 var subs []*nats.Subscription 17881 for i := 0; i < 10; i++ { 17882 inbox := nats.NewInbox() 17883 sub := natsSubSync(t, nc, inbox) 17884 subs = append(subs, sub) 17885 req := &JSApiConsumerGetNextRequest{Batch: 10, Expires: 60 * time.Second} 17886 jreq, err := json.Marshal(req) 17887 require_NoError(t, err) 17888 err = nc.PublishRequest(fmt.Sprintf(JSApiRequestNextT, "T", "d"), inbox, jreq) 17889 require_NoError(t, err) 17890 } 17891 17892 // Now send 100 messages. 17893 for i := 0; i < 100; i++ { 17894 js.PublishAsync("T", []byte("FIFO FTW!")) 17895 } 17896 select { 17897 case <-js.PublishAsyncComplete(): 17898 case <-time.After(5 * time.Second): 17899 t.Fatalf("Did not receive completion signal") 17900 } 17901 17902 // Wait for messages 17903 for index, sub := range subs { 17904 checkSubsPending(t, sub, 10) 17905 for i := 0; i < 10; i++ { 17906 m, err := sub.NextMsg(time.Second) 17907 require_NoError(t, err) 17908 meta, err := m.Metadata() 17909 require_NoError(t, err) 17910 // We expect these to be FIFO per message. E.g. sub #1 = [1, 11, 21, 31, ..] 17911 if sseq := meta.Sequence.Stream; sseq != uint64(index+1+(10*i)) { 17912 t.Fatalf("Expected message #%d for sub #%d to be %d, but got %d", i+1, index+1, index+1+(10*i), sseq) 17913 } 17914 } 17915 } 17916 } 17917 17918 // Make sure that when we reach an ack limit that we follow one shot semantics. 17919 func TestJetStreamConsumerPullConsumerOneShotOnMaxAckLimit(t *testing.T) { 17920 s := RunBasicJetStreamServer(t) 17921 defer s.Shutdown() 17922 17923 nc, js := jsClientConnect(t, s) 17924 defer nc.Close() 17925 17926 _, err := js.AddStream(&nats.StreamConfig{Name: "T"}) 17927 require_NoError(t, err) 17928 17929 for i := 0; i < 10; i++ { 17930 js.Publish("T", []byte("OK")) 17931 } 17932 17933 sub, err := js.PullSubscribe("T", "d", nats.MaxAckPending(5)) 17934 require_NoError(t, err) 17935 17936 start := time.Now() 17937 msgs, err := sub.Fetch(10, nats.MaxWait(2*time.Second)) 17938 require_NoError(t, err) 17939 17940 if elapsed := time.Since(start); elapsed >= 2*time.Second { 17941 t.Fatalf("Took too long, not one shot behavior: %v", elapsed) 17942 } 17943 17944 if len(msgs) != 5 { 17945 t.Fatalf("Expected 5 msgs, got %d", len(msgs)) 17946 } 17947 } 17948 17949 /////////////////////////////////////////////////////////////////////////// 17950 // Simple JetStream Benchmarks 17951 /////////////////////////////////////////////////////////////////////////// 17952 17953 func Benchmark__JetStreamPubWithAck(b *testing.B) { 17954 s := RunBasicJetStreamServer(b) 17955 defer s.Shutdown() 17956 17957 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "foo"}) 17958 if err != nil { 17959 b.Fatalf("Unexpected error adding stream: %v", err) 17960 } 17961 defer mset.delete() 17962 17963 nc, err := nats.Connect(s.ClientURL()) 17964 if err != nil { 17965 b.Fatalf("Failed to create client: %v", err) 17966 } 17967 defer nc.Close() 17968 17969 b.ResetTimer() 17970 for i := 0; i < b.N; i++ { 17971 nc.Request("foo", []byte("Hello World!"), 50*time.Millisecond) 17972 } 17973 b.StopTimer() 17974 17975 state := mset.state() 17976 if int(state.Msgs) != b.N { 17977 b.Fatalf("Expected %d messages, got %d", b.N, state.Msgs) 17978 } 17979 } 17980 17981 func Benchmark____JetStreamPubNoAck(b *testing.B) { 17982 s := RunBasicJetStreamServer(b) 17983 defer s.Shutdown() 17984 17985 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "foo"}) 17986 if err != nil { 17987 b.Fatalf("Unexpected error adding stream: %v", err) 17988 } 17989 defer mset.delete() 17990 17991 nc, err := nats.Connect(s.ClientURL()) 17992 if err != nil { 17993 b.Fatalf("Failed to create client: %v", err) 17994 } 17995 defer nc.Close() 17996 17997 b.ResetTimer() 17998 for i := 0; i < b.N; i++ { 17999 if err := nc.Publish("foo", []byte("Hello World!")); err != nil { 18000 b.Fatalf("Unexpected error: %v", err) 18001 } 18002 } 18003 nc.Flush() 18004 b.StopTimer() 18005 18006 state := mset.state() 18007 if int(state.Msgs) != b.N { 18008 b.Fatalf("Expected %d messages, got %d", b.N, state.Msgs) 18009 } 18010 } 18011 18012 func Benchmark_JetStreamPubAsyncAck(b *testing.B) { 18013 s := RunBasicJetStreamServer(b) 18014 defer s.Shutdown() 18015 18016 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: "foo"}) 18017 if err != nil { 18018 b.Fatalf("Unexpected error adding stream: %v", err) 18019 } 18020 defer mset.delete() 18021 18022 nc, err := nats.Connect(s.ClientURL(), nats.NoReconnect()) 18023 if err != nil { 18024 b.Fatalf("Failed to create client: %v", err) 18025 } 18026 defer nc.Close() 18027 18028 // Put ack stream on its own connection. 18029 anc, err := nats.Connect(s.ClientURL()) 18030 if err != nil { 18031 b.Fatalf("Failed to create client: %v", err) 18032 } 18033 defer anc.Close() 18034 18035 acks := nats.NewInbox() 18036 sub, _ := anc.Subscribe(acks, func(m *nats.Msg) { 18037 // Just eat them for this test. 18038 }) 18039 // set max pending to unlimited. 18040 sub.SetPendingLimits(-1, -1) 18041 defer sub.Unsubscribe() 18042 18043 anc.Flush() 18044 runtime.GC() 18045 18046 b.ResetTimer() 18047 for i := 0; i < b.N; i++ { 18048 if err := nc.PublishRequest("foo", acks, []byte("Hello World!")); err != nil { 18049 b.Fatalf("[%d] Unexpected error: %v", i, err) 18050 } 18051 } 18052 nc.Flush() 18053 b.StopTimer() 18054 18055 state := mset.state() 18056 if int(state.Msgs) != b.N { 18057 b.Fatalf("Expected %d messages, got %d", b.N, state.Msgs) 18058 } 18059 } 18060 18061 func Benchmark____JetStreamSubNoAck(b *testing.B) { 18062 if b.N < 10000 { 18063 return 18064 } 18065 18066 s := RunBasicJetStreamServer(b) 18067 defer s.Shutdown() 18068 18069 mname := "foo" 18070 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname}) 18071 if err != nil { 18072 b.Fatalf("Unexpected error adding stream: %v", err) 18073 } 18074 defer mset.delete() 18075 18076 nc, err := nats.Connect(s.ClientURL(), nats.NoReconnect()) 18077 if err != nil { 18078 b.Fatalf("Failed to create client: %v", err) 18079 } 18080 defer nc.Close() 18081 18082 // Queue up messages. 18083 for i := 0; i < b.N; i++ { 18084 nc.Publish(mname, []byte("Hello World!")) 18085 } 18086 nc.Flush() 18087 18088 state := mset.state() 18089 if state.Msgs != uint64(b.N) { 18090 b.Fatalf("Expected %d messages, got %d", b.N, state.Msgs) 18091 } 18092 18093 total := int32(b.N) 18094 received := int32(0) 18095 done := make(chan bool) 18096 18097 deliverTo := "DM" 18098 oname := "O" 18099 18100 nc.Subscribe(deliverTo, func(m *nats.Msg) { 18101 // We only are done when we receive all, we could check for gaps too. 18102 if atomic.AddInt32(&received, 1) >= total { 18103 done <- true 18104 } 18105 }) 18106 nc.Flush() 18107 18108 b.ResetTimer() 18109 o, err := mset.addConsumer(&ConsumerConfig{DeliverSubject: deliverTo, Durable: oname, AckPolicy: AckNone}) 18110 if err != nil { 18111 b.Fatalf("Expected no error with registered interest, got %v", err) 18112 } 18113 defer o.delete() 18114 <-done 18115 b.StopTimer() 18116 } 18117 18118 func benchJetStreamWorkersAndBatch(b *testing.B, numWorkers, batchSize int) { 18119 // Avoid running at too low of numbers since that chews up memory and GC. 18120 if b.N < numWorkers*batchSize { 18121 return 18122 } 18123 18124 s := RunBasicJetStreamServer(b) 18125 defer s.Shutdown() 18126 18127 mname := "MSET22" 18128 mset, err := s.GlobalAccount().addStream(&StreamConfig{Name: mname}) 18129 if err != nil { 18130 b.Fatalf("Unexpected error adding stream: %v", err) 18131 } 18132 defer mset.delete() 18133 18134 nc, err := nats.Connect(s.ClientURL(), nats.NoReconnect()) 18135 if err != nil { 18136 b.Fatalf("Failed to create client: %v", err) 18137 } 18138 defer nc.Close() 18139 18140 // Queue up messages. 18141 for i := 0; i < b.N; i++ { 18142 nc.Publish(mname, []byte("Hello World!")) 18143 } 18144 nc.Flush() 18145 18146 state := mset.state() 18147 if state.Msgs != uint64(b.N) { 18148 b.Fatalf("Expected %d messages, got %d", b.N, state.Msgs) 18149 } 18150 18151 // Create basic work queue mode consumer. 18152 oname := "WQ" 18153 o, err := mset.addConsumer(&ConsumerConfig{Durable: oname, AckPolicy: AckExplicit}) 18154 if err != nil { 18155 b.Fatalf("Expected no error with registered interest, got %v", err) 18156 } 18157 defer o.delete() 18158 18159 total := int32(b.N) 18160 received := int32(0) 18161 start := make(chan bool) 18162 done := make(chan bool) 18163 18164 batchSizeMsg := []byte(strconv.Itoa(batchSize)) 18165 reqNextMsgSubj := o.requestNextMsgSubject() 18166 18167 for i := 0; i < numWorkers; i++ { 18168 nc, err := nats.Connect(s.ClientURL(), nats.NoReconnect()) 18169 if err != nil { 18170 b.Fatalf("Failed to create client: %v", err) 18171 } 18172 defer nc.Close() 18173 18174 deliverTo := nats.NewInbox() 18175 nc.Subscribe(deliverTo, func(m *nats.Msg) { 18176 if atomic.AddInt32(&received, 1) >= total { 18177 done <- true 18178 } 18179 // Ack + Next request. 18180 nc.PublishRequest(m.Reply, deliverTo, AckNext) 18181 }) 18182 nc.Flush() 18183 go func() { 18184 <-start 18185 nc.PublishRequest(reqNextMsgSubj, deliverTo, batchSizeMsg) 18186 }() 18187 } 18188 18189 b.ResetTimer() 18190 close(start) 18191 <-done 18192 b.StopTimer() 18193 } 18194 18195 func Benchmark___JetStream1x1Worker(b *testing.B) { 18196 benchJetStreamWorkersAndBatch(b, 1, 1) 18197 } 18198 18199 func Benchmark__JetStream1x1kWorker(b *testing.B) { 18200 benchJetStreamWorkersAndBatch(b, 1, 1024) 18201 } 18202 18203 func Benchmark_JetStream10x1kWorker(b *testing.B) { 18204 benchJetStreamWorkersAndBatch(b, 10, 1024) 18205 } 18206 18207 func Benchmark_JetStream4x512Worker(b *testing.B) { 18208 benchJetStreamWorkersAndBatch(b, 4, 512) 18209 } 18210 18211 func TestJetStreamKVMemoryStorePerf(t *testing.T) { 18212 // Comment out to run, holding place for now. 18213 t.SkipNow() 18214 18215 s := RunBasicJetStreamServer(t) 18216 defer s.Shutdown() 18217 18218 nc, js := jsClientConnect(t, s) 18219 defer nc.Close() 18220 18221 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "TEST", History: 1, Storage: nats.MemoryStorage}) 18222 require_NoError(t, err) 18223 18224 start := time.Now() 18225 for i := 0; i < 100_000; i++ { 18226 _, err := kv.PutString(fmt.Sprintf("foo.%d", i), "HELLO") 18227 require_NoError(t, err) 18228 } 18229 fmt.Printf("Took %v for first run\n", time.Since(start)) 18230 18231 start = time.Now() 18232 for i := 0; i < 100_000; i++ { 18233 _, err := kv.PutString(fmt.Sprintf("foo.%d", i), "HELLO WORLD") 18234 require_NoError(t, err) 18235 } 18236 fmt.Printf("Took %v for second run\n", time.Since(start)) 18237 18238 start = time.Now() 18239 for i := 0; i < 100_000; i++ { 18240 _, err := kv.Get(fmt.Sprintf("foo.%d", i)) 18241 require_NoError(t, err) 18242 } 18243 fmt.Printf("Took %v for get\n", time.Since(start)) 18244 } 18245 18246 func TestJetStreamKVMemoryStoreDirectGetPerf(t *testing.T) { 18247 // Comment out to run, holding place for now. 18248 t.SkipNow() 18249 18250 s := RunBasicJetStreamServer(t) 18251 defer s.Shutdown() 18252 18253 nc, js := jsClientConnect(t, s) 18254 defer nc.Close() 18255 18256 cfg := &StreamConfig{ 18257 Name: "TEST", 18258 Storage: MemoryStorage, 18259 Subjects: []string{"foo.*"}, 18260 MaxMsgsPer: 1, 18261 AllowDirect: true, 18262 } 18263 addStream(t, nc, cfg) 18264 18265 start := time.Now() 18266 for i := 0; i < 100_000; i++ { 18267 _, err := js.Publish(fmt.Sprintf("foo.%d", i), []byte("HELLO")) 18268 require_NoError(t, err) 18269 } 18270 fmt.Printf("Took %v for put\n", time.Since(start)) 18271 18272 getSubj := fmt.Sprintf(JSDirectMsgGetT, "TEST") 18273 18274 const tmpl = "{\"last_by_subj\":%q}" 18275 18276 start = time.Now() 18277 for i := 0; i < 100_000; i++ { 18278 req := []byte(fmt.Sprintf(tmpl, fmt.Sprintf("foo.%d", i))) 18279 _, err := nc.Request(getSubj, req, time.Second) 18280 require_NoError(t, err) 18281 } 18282 fmt.Printf("Took %v for get\n", time.Since(start)) 18283 } 18284 18285 func TestJetStreamMultiplePullPerf(t *testing.T) { 18286 skip(t) 18287 18288 s := RunBasicJetStreamServer(t) 18289 defer s.Shutdown() 18290 18291 nc, js := jsClientConnect(t, s) 18292 defer nc.Close() 18293 18294 js.AddStream(&nats.StreamConfig{Name: "mp22", Storage: nats.FileStorage}) 18295 defer js.DeleteStream("mp22") 18296 18297 n, msg := 1_000_000, []byte("OK") 18298 for i := 0; i < n; i++ { 18299 js.PublishAsync("mp22", msg) 18300 } 18301 select { 18302 case <-js.PublishAsyncComplete(): 18303 case <-time.After(10 * time.Second): 18304 t.Fatalf("Did not receive completion signal") 18305 } 18306 18307 si, err := js.StreamInfo("mp22") 18308 require_NoError(t, err) 18309 18310 fmt.Printf("msgs: %d, total_bytes: %v\n", si.State.Msgs, friendlyBytes(int64(si.State.Bytes))) 18311 18312 // 10 pull subscribers each asking for 100 msgs. 18313 _, err = js.AddConsumer("mp22", &nats.ConsumerConfig{ 18314 Durable: "d", 18315 MaxAckPending: 8_000, 18316 AckPolicy: nats.AckExplicitPolicy, 18317 }) 18318 require_NoError(t, err) 18319 18320 startCh := make(chan bool) 18321 var wg sync.WaitGroup 18322 18323 np, bs := 10, 100 18324 18325 count := 0 18326 18327 for i := 0; i < np; i++ { 18328 nc, js := jsClientConnect(t, s) 18329 defer nc.Close() 18330 sub, err := js.PullSubscribe("mp22", "d") 18331 require_NoError(t, err) 18332 18333 wg.Add(1) 18334 go func(sub *nats.Subscription) { 18335 defer wg.Done() 18336 <-startCh 18337 for i := 0; i < n/(np*bs); i++ { 18338 msgs, err := sub.Fetch(bs) 18339 if err != nil { 18340 t.Logf("Got error on pull: %v", err) 18341 return 18342 } 18343 if len(msgs) != bs { 18344 t.Logf("Expected %d msgs, got %d", bs, len(msgs)) 18345 return 18346 } 18347 count += len(msgs) 18348 for _, m := range msgs { 18349 m.Ack() 18350 } 18351 } 18352 }(sub) 18353 } 18354 18355 start := time.Now() 18356 close(startCh) 18357 wg.Wait() 18358 18359 tt := time.Since(start) 18360 fmt.Printf("Took %v to receive %d msgs [%d]\n", tt, n, count) 18361 fmt.Printf("%.0f msgs/s\n", float64(n)/tt.Seconds()) 18362 fmt.Printf("%.0f mb/s\n\n", float64(si.State.Bytes/(1024*1024))/tt.Seconds()) 18363 } 18364 18365 func TestJetStreamMirrorUpdatesNotSupported(t *testing.T) { 18366 s := RunBasicJetStreamServer(t) 18367 defer s.Shutdown() 18368 18369 nc, js := jsClientConnect(t, s) 18370 defer nc.Close() 18371 18372 _, err := js.AddStream(&nats.StreamConfig{Name: "SOURCE"}) 18373 require_NoError(t, err) 18374 18375 cfg := &nats.StreamConfig{ 18376 Name: "M", 18377 Mirror: &nats.StreamSource{Name: "SOURCE"}, 18378 } 18379 _, err = js.AddStream(cfg) 18380 require_NoError(t, err) 18381 18382 cfg.Mirror = nil 18383 _, err = js.UpdateStream(cfg) 18384 require_Error(t, err, NewJSStreamMirrorNotUpdatableError()) 18385 } 18386 18387 func TestJetStreamMirrorFirstSeqNotSupported(t *testing.T) { 18388 s := RunBasicJetStreamServer(t) 18389 defer s.Shutdown() 18390 18391 _, err := s.gacc.addStream(&StreamConfig{Name: "SOURCE"}) 18392 require_NoError(t, err) 18393 18394 cfg := &StreamConfig{ 18395 Name: "M", 18396 Mirror: &StreamSource{Name: "SOURCE"}, 18397 FirstSeq: 123, 18398 } 18399 _, err = s.gacc.addStream(cfg) 18400 require_Error(t, err, NewJSMirrorWithFirstSeqError()) 18401 } 18402 18403 func TestJetStreamDirectGetBySubject(t *testing.T) { 18404 conf := createConfFile(t, []byte(fmt.Sprintf(` 18405 listen: 127.0.0.1:-1 18406 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 18407 18408 ONLYME = { 18409 publish = { allow = "$JS.API.DIRECT.GET.KV.vid.22.>"} 18410 } 18411 18412 accounts: { 18413 A: { 18414 jetstream: enabled 18415 users: [ 18416 { user: admin, password: s3cr3t }, 18417 { user: user, password: pwd, permissions: $ONLYME}, 18418 ] 18419 }, 18420 } 18421 `, t.TempDir()))) 18422 18423 s, _ := RunServerWithConfig(conf) 18424 defer s.Shutdown() 18425 18426 nc, js := jsClientConnect(t, s, nats.UserInfo("admin", "s3cr3t")) 18427 defer nc.Close() 18428 18429 // Do by hand for now. 18430 cfg := &StreamConfig{ 18431 Name: "KV", 18432 Storage: MemoryStorage, 18433 Subjects: []string{"vid.*.>"}, 18434 MaxMsgsPer: 1, 18435 AllowDirect: true, 18436 } 18437 addStream(t, nc, cfg) 18438 18439 // Add in mirror as well. 18440 cfg = &StreamConfig{ 18441 Name: "M", 18442 Storage: MemoryStorage, 18443 Mirror: &StreamSource{Name: "KV"}, 18444 MirrorDirect: true, 18445 } 18446 addStream(t, nc, cfg) 18447 18448 v22 := "vid.22.speed" 18449 v33 := "vid.33.speed" 18450 _, err := js.Publish(v22, []byte("100")) 18451 require_NoError(t, err) 18452 _, err = js.Publish(v33, []byte("55")) 18453 require_NoError(t, err) 18454 18455 // User the restricted user. 18456 nc, _ = jsClientConnect(t, s, nats.UserInfo("user", "pwd")) 18457 defer nc.Close() 18458 18459 errCh := make(chan error, 10) 18460 nc.SetErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, e error) { 18461 select { 18462 case errCh <- e: 18463 default: 18464 } 18465 }) 18466 18467 getSubj := fmt.Sprintf(JSDirectGetLastBySubjectT, "KV", v22) 18468 m, err := nc.Request(getSubj, nil, time.Second) 18469 require_NoError(t, err) 18470 require_True(t, string(m.Data) == "100") 18471 18472 // Now attempt to access vid 33 data.. 18473 getSubj = fmt.Sprintf(JSDirectGetLastBySubjectT, "KV", v33) 18474 _, err = nc.Request(getSubj, nil, 200*time.Millisecond) 18475 require_Error(t, err) // timeout here. 18476 18477 select { 18478 case e := <-errCh: 18479 if !strings.HasPrefix(e.Error(), "nats: Permissions Violation") { 18480 t.Fatalf("Expected a permissions violation but got %v", e) 18481 } 18482 case <-time.After(time.Second): 18483 t.Fatalf("Expected to get a permissions error, got none") 18484 } 18485 18486 // Now make sure mirrors are doing right thing with new way as well. 18487 var sawMirror bool 18488 getSubj = fmt.Sprintf(JSDirectGetLastBySubjectT, "KV", v22) 18489 for i := 0; i < 100; i++ { 18490 m, err := nc.Request(getSubj, nil, time.Second) 18491 require_NoError(t, err) 18492 if shdr := m.Header.Get(JSStream); shdr == "M" { 18493 sawMirror = true 18494 break 18495 } 18496 } 18497 if !sawMirror { 18498 t.Fatalf("Expected to see the mirror respond at least once") 18499 } 18500 } 18501 18502 func TestJetStreamProperErrorDueToOverlapSubjects(t *testing.T) { 18503 s := RunBasicJetStreamServer(t) 18504 defer s.Shutdown() 18505 18506 c := createJetStreamClusterExplicit(t, "R3S", 3) 18507 defer c.shutdown() 18508 18509 test := func(t *testing.T, s *Server) { 18510 nc, js := jsClientConnect(t, s) 18511 defer nc.Close() 18512 18513 _, err := js.AddStream(&nats.StreamConfig{ 18514 Name: "TEST", 18515 Subjects: []string{"foo.*"}, 18516 }) 18517 require_NoError(t, err) 18518 18519 // Now do this by end since we want to check the error returned. 18520 sc := &nats.StreamConfig{ 18521 Name: "TEST2", 18522 Subjects: []string{"foo.>"}, 18523 } 18524 req, _ := json.Marshal(sc) 18525 msg, err := nc.Request(fmt.Sprintf(JSApiStreamCreateT, sc.Name), req, time.Second) 18526 require_NoError(t, err) 18527 18528 var scResp JSApiStreamCreateResponse 18529 err = json.Unmarshal(msg.Data, &scResp) 18530 require_NoError(t, err) 18531 18532 if scResp.Error == nil || !IsNatsErr(scResp.Error, JSStreamSubjectOverlapErr) { 18533 t.Fatalf("Did not receive correct error: %+v", scResp) 18534 } 18535 } 18536 18537 t.Run("standalone", func(t *testing.T) { test(t, s) }) 18538 t.Run("clustered", func(t *testing.T) { test(t, c.randomServer()) }) 18539 } 18540 18541 func TestJetStreamServerCipherConvert(t *testing.T) { 18542 tmpl := ` 18543 server_name: S22 18544 listen: 127.0.0.1:-1 18545 jetstream: {key: s3cr3t, store_dir: '%s', cipher: %s} 18546 ` 18547 storeDir := t.TempDir() 18548 18549 // Create a stream and a consumer under one cipher, and restart the server with a new cipher. 18550 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, storeDir, "AES"))) 18551 18552 s, _ := RunServerWithConfig(conf) 18553 defer s.Shutdown() 18554 18555 // Client based API 18556 nc, js := jsClientConnect(t, s) 18557 defer nc.Close() 18558 18559 cfg := &nats.StreamConfig{ 18560 Name: "TEST", 18561 Subjects: []string{"foo"}, 18562 } 18563 if _, err := js.AddStream(cfg); err != nil { 18564 t.Fatalf("Unexpected error: %v", err) 18565 } 18566 18567 for i := 0; i < 1000; i++ { 18568 msg := []byte(fmt.Sprintf("TOP SECRET DOCUMENT #%d", i+1)) 18569 _, err := js.Publish("foo", msg) 18570 require_NoError(t, err) 18571 } 18572 18573 // Make sure consumers convert as well. 18574 sub, err := js.PullSubscribe("foo", "dlc") 18575 require_NoError(t, err) 18576 for _, m := range fetchMsgs(t, sub, 100, 5*time.Second) { 18577 m.AckSync() 18578 } 18579 18580 si, err := js.StreamInfo("TEST") 18581 require_NoError(t, err) 18582 18583 ci, err := js.ConsumerInfo("TEST", "dlc") 18584 require_NoError(t, err) 18585 18586 // Stop current 18587 s.Shutdown() 18588 18589 conf = createConfFile(t, []byte(fmt.Sprintf(tmpl, storeDir, "ChaCha"))) 18590 18591 s, _ = RunServerWithConfig(conf) 18592 defer s.Shutdown() 18593 18594 nc, js = jsClientConnect(t, s) 18595 defer nc.Close() 18596 18597 si2, err := js.StreamInfo("TEST") 18598 require_NoError(t, err) 18599 18600 if !reflect.DeepEqual(si, si2) { 18601 t.Fatalf("Stream infos did not match\n%+v\nvs\n%+v", si, si2) 18602 } 18603 18604 ci2, err := js.ConsumerInfo("TEST", "dlc") 18605 require_NoError(t, err) 18606 18607 // Consumer create times can be slightly off after restore from disk. 18608 now := time.Now() 18609 ci.Created, ci2.Created = now, now 18610 ci.Delivered.Last, ci2.Delivered.Last = nil, nil 18611 ci.AckFloor.Last, ci2.AckFloor.Last = nil, nil 18612 // Also clusters will be different. 18613 ci.Cluster, ci2.Cluster = nil, nil 18614 18615 if !reflect.DeepEqual(ci, ci2) { 18616 t.Fatalf("Consumer infos did not match\n%+v\nvs\n%+v", ci, ci2) 18617 } 18618 } 18619 18620 func TestJetStreamConsumerDeliverNewMaxRedeliveriesAndServerRestart(t *testing.T) { 18621 s := RunBasicJetStreamServer(t) 18622 defer s.Shutdown() 18623 18624 nc, js := jsClientConnect(t, s) 18625 defer nc.Close() 18626 18627 _, err := js.AddStream(&nats.StreamConfig{ 18628 Name: "TEST", 18629 Subjects: []string{"foo.*"}, 18630 }) 18631 require_NoError(t, err) 18632 18633 inbox := nats.NewInbox() 18634 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 18635 DeliverSubject: inbox, 18636 Durable: "dur", 18637 AckPolicy: nats.AckExplicitPolicy, 18638 DeliverPolicy: nats.DeliverNewPolicy, 18639 MaxDeliver: 3, 18640 AckWait: 250 * time.Millisecond, 18641 FilterSubject: "foo.bar", 18642 }) 18643 require_NoError(t, err) 18644 18645 sendStreamMsg(t, nc, "foo.bar", "msg") 18646 18647 sub := natsSubSync(t, nc, inbox) 18648 for i := 0; i < 3; i++ { 18649 natsNexMsg(t, sub, time.Second) 18650 } 18651 // Now check that there is no more redeliveries 18652 if msg, err := sub.NextMsg(300 * time.Millisecond); err != nats.ErrTimeout { 18653 t.Fatalf("Expected timeout, got msg=%+v err=%v", msg, err) 18654 } 18655 18656 // Give a chance to things to be persisted 18657 time.Sleep(300 * time.Millisecond) 18658 18659 // Check server restart 18660 nc.Close() 18661 sd := s.JetStreamConfig().StoreDir 18662 s.Shutdown() 18663 s = RunJetStreamServerOnPort(-1, sd) 18664 defer s.Shutdown() 18665 18666 nc, _ = jsClientConnect(t, s) 18667 defer nc.Close() 18668 18669 sub = natsSubSync(t, nc, inbox) 18670 // We should not have messages being redelivered. 18671 if msg, err := sub.NextMsg(300 * time.Millisecond); err != nats.ErrTimeout { 18672 t.Fatalf("Expected timeout, got msg=%+v err=%v", msg, err) 18673 } 18674 } 18675 18676 func TestJetStreamConsumerPendingLowerThanStreamFirstSeq(t *testing.T) { 18677 s := RunBasicJetStreamServer(t) 18678 defer s.Shutdown() 18679 18680 nc, js := jsClientConnect(t, s) 18681 defer nc.Close() 18682 18683 _, err := js.AddStream(&nats.StreamConfig{ 18684 Name: "TEST", 18685 Subjects: []string{"foo"}, 18686 }) 18687 require_NoError(t, err) 18688 18689 for i := 0; i < 100; i++ { 18690 sendStreamMsg(t, nc, "foo", "msg") 18691 } 18692 18693 inbox := nats.NewInbox() 18694 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 18695 DeliverSubject: inbox, 18696 Durable: "dur", 18697 AckPolicy: nats.AckExplicitPolicy, 18698 DeliverPolicy: nats.DeliverAllPolicy, 18699 }) 18700 require_NoError(t, err) 18701 18702 sub := natsSubSync(t, nc, inbox) 18703 for i := 0; i < 10; i++ { 18704 natsNexMsg(t, sub, time.Second) 18705 } 18706 18707 acc, err := s.lookupAccount(globalAccountName) 18708 require_NoError(t, err) 18709 mset, err := acc.lookupStream("TEST") 18710 require_NoError(t, err) 18711 o := mset.lookupConsumer("dur") 18712 require_True(t, o != nil) 18713 o.stop() 18714 mset.store.Compact(1_000_000) 18715 nc.Close() 18716 18717 sd := s.JetStreamConfig().StoreDir 18718 s.Shutdown() 18719 s = RunJetStreamServerOnPort(-1, sd) 18720 defer s.Shutdown() 18721 18722 nc, js = jsClientConnect(t, s) 18723 defer nc.Close() 18724 18725 si, err := js.StreamInfo("TEST") 18726 require_NoError(t, err) 18727 require_True(t, si.State.FirstSeq == 1_000_000) 18728 require_True(t, si.State.LastSeq == 999_999) 18729 18730 natsSubSync(t, nc, inbox) 18731 checkFor(t, 2*time.Second, 15*time.Millisecond, func() error { 18732 ci, err := js.ConsumerInfo("TEST", "dur") 18733 if err != nil { 18734 return err 18735 } 18736 if ci.NumAckPending != 0 { 18737 return fmt.Errorf("NumAckPending should be 0, got %v", ci.NumAckPending) 18738 } 18739 if ci.Delivered.Stream != 999_999 { 18740 return fmt.Errorf("Delivered.Stream should be 999,999, got %v", ci.Delivered.Stream) 18741 } 18742 return nil 18743 }) 18744 } 18745 18746 func TestJetStreamAllowDirectAfterUpdate(t *testing.T) { 18747 s := RunBasicJetStreamServer(t) 18748 defer s.Shutdown() 18749 18750 nc, js := jsClientConnect(t, s) 18751 defer nc.Close() 18752 18753 _, err := js.AddStream(&nats.StreamConfig{ 18754 Name: "TEST", 18755 Subjects: []string{"*"}, 18756 }) 18757 require_NoError(t, err) 18758 sendStreamMsg(t, nc, "foo", "msg") 18759 18760 si, err := js.UpdateStream(&nats.StreamConfig{ 18761 Name: "TEST", 18762 Subjects: []string{"*"}, 18763 AllowDirect: true, 18764 }) 18765 require_NoError(t, err) 18766 require_True(t, si.Config.AllowDirect) 18767 18768 _, err = js.GetLastMsg("TEST", "foo", nats.DirectGet(), nats.MaxWait(100*time.Millisecond)) 18769 require_NoError(t, err) 18770 18771 // Make sure turning off works too. 18772 si, err = js.UpdateStream(&nats.StreamConfig{ 18773 Name: "TEST", 18774 Subjects: []string{"*"}, 18775 AllowDirect: false, 18776 }) 18777 require_NoError(t, err) 18778 require_False(t, si.Config.AllowDirect) 18779 18780 _, err = js.GetLastMsg("TEST", "foo", nats.DirectGet(), nats.MaxWait(100*time.Millisecond)) 18781 require_Error(t, err) 18782 } 18783 18784 // Bug when stream's consumer config does not force filestore to track per subject information. 18785 func TestJetStreamConsumerEOFBugNewFileStore(t *testing.T) { 18786 s := RunBasicJetStreamServer(t) 18787 defer s.Shutdown() 18788 18789 nc, js := jsClientConnect(t, s) 18790 defer nc.Close() 18791 18792 _, err := js.AddStream(&nats.StreamConfig{ 18793 Name: "TEST", 18794 Subjects: []string{"foo.bar.*"}, 18795 }) 18796 require_NoError(t, err) 18797 18798 _, err = js.AddStream(&nats.StreamConfig{ 18799 Name: "M", 18800 Mirror: &nats.StreamSource{Name: "TEST"}, 18801 }) 18802 require_NoError(t, err) 18803 18804 dsubj := nats.NewInbox() 18805 sub, err := nc.SubscribeSync(dsubj) 18806 require_NoError(t, err) 18807 nc.Flush() 18808 18809 // Filter needs to be a wildcard. Need to bind to the 18810 _, err = js.AddConsumer("M", &nats.ConsumerConfig{DeliverSubject: dsubj, FilterSubject: "foo.>"}) 18811 require_NoError(t, err) 18812 18813 for i := 0; i < 100; i++ { 18814 _, err := js.PublishAsync("foo.bar.baz", []byte("OK")) 18815 require_NoError(t, err) 18816 } 18817 18818 for i := 0; i < 100; i++ { 18819 m, err := sub.NextMsg(time.Second) 18820 require_NoError(t, err) 18821 m.Respond(nil) 18822 } 18823 18824 // Now force an expiration. 18825 mset, err := s.GlobalAccount().lookupStream("M") 18826 require_NoError(t, err) 18827 mset.mu.RLock() 18828 store := mset.store.(*fileStore) 18829 mset.mu.RUnlock() 18830 store.mu.RLock() 18831 mb := store.blks[0] 18832 store.mu.RUnlock() 18833 mb.mu.Lock() 18834 mb.fss = nil 18835 mb.mu.Unlock() 18836 18837 // Now send another message. 18838 _, err = js.PublishAsync("foo.bar.baz", []byte("OK")) 18839 require_NoError(t, err) 18840 18841 // This will fail with the bug. 18842 _, err = sub.NextMsg(time.Second) 18843 require_NoError(t, err) 18844 } 18845 18846 func TestJetStreamSubjectBasedFilteredConsumers(t *testing.T) { 18847 conf := createConfFile(t, []byte(fmt.Sprintf(` 18848 listen: 127.0.0.1:-1 18849 jetstream: {max_mem_store: 64GB, max_file_store: 10TB, store_dir: %q} 18850 accounts: { 18851 A: { 18852 jetstream: enabled 18853 users: [ { 18854 user: u, 18855 password: p 18856 permissions { 18857 publish { 18858 allow: [ 18859 'ID.>', 18860 '$JS.API.INFO', 18861 '$JS.API.STREAM.>', 18862 '$JS.API.CONSUMER.INFO.>', 18863 '$JS.API.CONSUMER.CREATE.TEST.VIN-xxx.ID.foo.>', # Only allow ID.foo. 18864 ] 18865 deny: [ '$JS.API.CONSUMER.CREATE.*', '$JS.API.CONSUMER.DURABLE.CREATE.*.*'] 18866 } 18867 } 18868 } ] 18869 }, 18870 } 18871 `, t.TempDir()))) 18872 18873 s, _ := RunServerWithConfig(conf) 18874 defer s.Shutdown() 18875 18876 nc, js := jsClientConnect(t, s, nats.UserInfo("u", "p"), nats.ErrorHandler(noOpErrHandler)) 18877 defer nc.Close() 18878 18879 _, err := js.AddStream(&nats.StreamConfig{ 18880 Name: "TEST", 18881 Subjects: []string{"ID.*.*"}, 18882 }) 18883 require_NoError(t, err) 18884 18885 for i := 0; i < 100; i++ { 18886 js.Publish(fmt.Sprintf("ID.foo.%d", i*3), nil) 18887 js.Publish(fmt.Sprintf("ID.bar.%d", i*3+1), nil) 18888 js.Publish(fmt.Sprintf("ID.baz.%d", i*3+2), nil) 18889 } 18890 si, err := js.StreamInfo("TEST") 18891 require_NoError(t, err) 18892 require_True(t, si.State.Msgs == 300) 18893 18894 // Trying to create a consumer with non filtered API should fail. 18895 js, err = nc.JetStream(nats.MaxWait(200 * time.Millisecond)) 18896 require_NoError(t, err) 18897 18898 _, err = js.SubscribeSync("ID.foo.*") 18899 require_Error(t, err, nats.ErrTimeout, context.DeadlineExceeded) 18900 18901 _, err = js.SubscribeSync("ID.foo.*", nats.Durable("dlc")) 18902 require_Error(t, err, nats.ErrTimeout, context.DeadlineExceeded) 18903 18904 // Direct filtered should work. 18905 // Need to do by hand for now. 18906 ecSubj := fmt.Sprintf(JSApiConsumerCreateExT, "TEST", "VIN-xxx", "ID.foo.*") 18907 18908 crReq := CreateConsumerRequest{ 18909 Stream: "TEST", 18910 Config: ConsumerConfig{ 18911 DeliverPolicy: DeliverLast, 18912 FilterSubject: "ID.foo.*", 18913 AckPolicy: AckExplicit, 18914 }, 18915 } 18916 req, err := json.Marshal(crReq) 18917 require_NoError(t, err) 18918 18919 resp, err := nc.Request(ecSubj, req, 500*time.Millisecond) 18920 require_NoError(t, err) 18921 var ccResp JSApiConsumerCreateResponse 18922 err = json.Unmarshal(resp.Data, &ccResp) 18923 require_NoError(t, err) 18924 if ccResp.Error != nil { 18925 t.Fatalf("Unexpected error: %v", ccResp.Error) 18926 } 18927 cfg := ccResp.Config 18928 ci := ccResp.ConsumerInfo 18929 // Make sure we recognized as an ephemeral (since no durable was set) and that we have an InactiveThreshold. 18930 // Make sure we captured preferred ephemeral name. 18931 if ci.Name != "VIN-xxx" { 18932 t.Fatalf("Did not get correct name, expected %q got %q", "xxx", ci.Name) 18933 } 18934 if cfg.InactiveThreshold == 0 { 18935 t.Fatalf("Expected default inactive threshold to be set, got %v", cfg.InactiveThreshold) 18936 } 18937 18938 // Make sure we can not use different consumer name since locked above. 18939 ecSubj = fmt.Sprintf(JSApiConsumerCreateExT, "TEST", "VIN-zzz", "ID.foo.*") 18940 _, err = nc.Request(ecSubj, req, 500*time.Millisecond) 18941 require_Error(t, err, nats.ErrTimeout) 18942 18943 // Now check that we error when we mismatch filtersubject. 18944 crReq = CreateConsumerRequest{ 18945 Stream: "TEST", 18946 Config: ConsumerConfig{ 18947 DeliverPolicy: DeliverLast, 18948 FilterSubject: "ID.bar.*", 18949 AckPolicy: AckExplicit, 18950 }, 18951 } 18952 req, err = json.Marshal(crReq) 18953 require_NoError(t, err) 18954 18955 ecSubj = fmt.Sprintf(JSApiConsumerCreateExT, "TEST", "VIN-xxx", "ID.foo.*") 18956 resp, err = nc.Request(ecSubj, req, 500*time.Millisecond) 18957 require_NoError(t, err) 18958 err = json.Unmarshal(resp.Data, &ccResp) 18959 require_NoError(t, err) 18960 checkNatsError(t, ccResp.Error, JSConsumerCreateFilterSubjectMismatchErr) 18961 18962 // Now make sure if we change subject to match that we can not create a filtered consumer on ID.bar.> 18963 ecSubj = fmt.Sprintf(JSApiConsumerCreateExT, "TEST", "VIN-xxx", "ID.bar.*") 18964 _, err = nc.Request(ecSubj, req, 500*time.Millisecond) 18965 require_Error(t, err, nats.ErrTimeout) 18966 } 18967 18968 func TestJetStreamStreamSubjectsOverlap(t *testing.T) { 18969 s := RunBasicJetStreamServer(t) 18970 defer s.Shutdown() 18971 18972 nc, js := jsClientConnect(t, s) 18973 defer nc.Close() 18974 18975 _, err := js.AddStream(&nats.StreamConfig{ 18976 Name: "TEST", 18977 Subjects: []string{"foo.*", "foo.A"}, 18978 }) 18979 require_Error(t, err) 18980 require_True(t, strings.Contains(err.Error(), "overlaps")) 18981 18982 _, err = js.AddStream(&nats.StreamConfig{ 18983 Name: "TEST", 18984 Subjects: []string{"foo.*"}, 18985 }) 18986 require_NoError(t, err) 18987 18988 _, err = js.UpdateStream(&nats.StreamConfig{ 18989 Name: "TEST", 18990 Subjects: []string{"foo.*", "foo.A"}, 18991 }) 18992 require_Error(t, err) 18993 require_True(t, strings.Contains(err.Error(), "overlaps")) 18994 18995 _, err = js.UpdateStream(&nats.StreamConfig{ 18996 Name: "TEST", 18997 Subjects: []string{"foo.bar.*", "foo.*.bar"}, 18998 }) 18999 require_Error(t, err) 19000 require_True(t, strings.Contains(err.Error(), "overlaps")) 19001 } 19002 19003 func TestJetStreamStreamTransformOverlap(t *testing.T) { 19004 s := RunBasicJetStreamServer(t) 19005 defer s.Shutdown() 19006 19007 nc, js := jsClientConnect(t, s) 19008 defer nc.Close() 19009 19010 _, err := js.AddStream(&nats.StreamConfig{ 19011 Name: "TEST", 19012 Subjects: []string{"foo.>"}, 19013 }) 19014 require_NoError(t, err) 19015 19016 _, err = js.AddStream(&nats.StreamConfig{ 19017 Name: "MIRROR", 19018 Mirror: &nats.StreamSource{Name: "TEST", 19019 SubjectTransforms: []nats.SubjectTransformConfig{ 19020 { 19021 Source: "foo.*.bar", 19022 Destination: "baz", 19023 }, 19024 { 19025 Source: "foo.bar.*", 19026 Destination: "baz", 19027 }, 19028 }, 19029 }}) 19030 require_Error(t, err) 19031 require_True(t, strings.Contains(err.Error(), "overlap")) 19032 19033 } 19034 19035 func TestJetStreamSuppressAllowDirect(t *testing.T) { 19036 s := RunBasicJetStreamServer(t) 19037 defer s.Shutdown() 19038 19039 nc, js := jsClientConnect(t, s) 19040 defer nc.Close() 19041 19042 si, err := js.AddStream(&nats.StreamConfig{ 19043 Name: "TEST", 19044 Subjects: []string{"key.*"}, 19045 MaxMsgsPerSubject: 1, 19046 AllowDirect: true, 19047 }) 19048 require_NoError(t, err) 19049 require_True(t, si.Config.AllowDirect) 19050 19051 si, err = js.UpdateStream(&nats.StreamConfig{ 19052 Name: "TEST", 19053 Subjects: []string{"key.*"}, 19054 MaxMsgsPerSubject: 1, 19055 AllowDirect: false, 19056 }) 19057 require_NoError(t, err) 19058 require_False(t, si.Config.AllowDirect) 19059 19060 sendStreamMsg(t, nc, "key.22", "msg") 19061 19062 _, err = js.GetLastMsg("TEST", "foo", nats.DirectGet(), nats.MaxWait(100*time.Millisecond)) 19063 require_Error(t, err) 19064 } 19065 19066 func TestJetStreamPullConsumerNoAck(t *testing.T) { 19067 s := RunBasicJetStreamServer(t) 19068 defer s.Shutdown() 19069 19070 nc, js := jsClientConnect(t, s) 19071 defer nc.Close() 19072 19073 _, err := js.AddStream(&nats.StreamConfig{ 19074 Name: "TEST", 19075 Subjects: []string{"ORDERS.*"}, 19076 }) 19077 require_NoError(t, err) 19078 19079 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 19080 Durable: "dlc", 19081 AckPolicy: nats.AckNonePolicy, 19082 }) 19083 require_NoError(t, err) 19084 } 19085 19086 func TestJetStreamAccountPurge(t *testing.T) { 19087 sysKp, syspub := createKey(t) 19088 sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub) 19089 sysCreds := newUser(t, sysKp) 19090 accKp, accpub := createKey(t) 19091 accClaim := jwt.NewAccountClaims(accpub) 19092 accClaim.Limits.JetStreamLimits.DiskStorage = 1024 * 1024 * 5 19093 accClaim.Limits.JetStreamLimits.MemoryStorage = 1024 * 1024 * 5 19094 accJwt := encodeClaim(t, accClaim, accpub) 19095 accCreds := newUser(t, accKp) 19096 19097 storeDir := t.TempDir() 19098 19099 cfg := createConfFile(t, []byte(fmt.Sprintf(` 19100 host: 127.0.0.1 19101 port:-1 19102 server_name: S1 19103 operator: %s 19104 system_account: %s 19105 resolver: { 19106 type: full 19107 dir: '%s/jwt' 19108 } 19109 jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s/js'} 19110 `, ojwt, syspub, storeDir, storeDir))) 19111 defer os.Remove(cfg) 19112 19113 s, o := RunServerWithConfig(cfg) 19114 updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1) 19115 updateJwt(t, s.ClientURL(), sysCreds, accJwt, 1) 19116 defer s.Shutdown() 19117 19118 inspectDirs := func(t *testing.T, accTotal int) error { 19119 t.Helper() 19120 if accTotal == 0 { 19121 files, err := os.ReadDir(filepath.Join(o.StoreDir, "jetstream", accpub)) 19122 require_True(t, len(files) == accTotal || err != nil) 19123 } else { 19124 files, err := os.ReadDir(filepath.Join(o.StoreDir, "jetstream", accpub, "streams")) 19125 require_NoError(t, err) 19126 require_True(t, len(files) == accTotal) 19127 } 19128 return nil 19129 } 19130 19131 createTestData := func() { 19132 nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds)) 19133 defer nc.Close() 19134 js, err := nc.JetStream() 19135 require_NoError(t, err) 19136 _, err = js.AddStream(&nats.StreamConfig{ 19137 Name: "TEST1", 19138 Subjects: []string{"foo"}, 19139 }) 19140 require_NoError(t, err) 19141 _, err = js.AddConsumer("TEST1", 19142 &nats.ConsumerConfig{Durable: "DUR1", 19143 AckPolicy: nats.AckExplicitPolicy}) 19144 require_NoError(t, err) 19145 } 19146 19147 purge := func(t *testing.T) { 19148 t.Helper() 19149 var resp JSApiAccountPurgeResponse 19150 ncsys := natsConnect(t, s.ClientURL(), nats.UserCredentials(sysCreds)) 19151 defer ncsys.Close() 19152 m, err := ncsys.Request(fmt.Sprintf(JSApiAccountPurgeT, accpub), nil, 5*time.Second) 19153 require_NoError(t, err) 19154 err = json.Unmarshal(m.Data, &resp) 19155 require_NoError(t, err) 19156 require_True(t, resp.Initiated) 19157 } 19158 19159 createTestData() 19160 inspectDirs(t, 1) 19161 purge(t) 19162 inspectDirs(t, 0) 19163 createTestData() 19164 inspectDirs(t, 1) 19165 19166 s.Shutdown() 19167 require_NoError(t, os.Remove(storeDir+"/jwt/"+accpub+".jwt")) 19168 19169 s, o = RunServerWithConfig(o.ConfigFile) 19170 defer s.Shutdown() 19171 inspectDirs(t, 1) 19172 purge(t) 19173 inspectDirs(t, 0) 19174 } 19175 19176 func TestJetStreamPullConsumerLastPerSubjectRedeliveries(t *testing.T) { 19177 s := RunBasicJetStreamServer(t) 19178 defer s.Shutdown() 19179 19180 nc, js := jsClientConnect(t, s) 19181 defer nc.Close() 19182 19183 _, err := js.AddStream(&nats.StreamConfig{ 19184 Name: "TEST", 19185 Subjects: []string{"foo.>"}, 19186 }) 19187 require_NoError(t, err) 19188 19189 for i := 0; i < 20; i++ { 19190 sendStreamMsg(t, nc, fmt.Sprintf("foo.%v", i), "msg") 19191 } 19192 19193 // Create a pull sub with a maxackpending that is <= of the number of 19194 // messages in the stream and as much as we are going to Fetch() below. 19195 sub, err := js.PullSubscribe(">", "dur", 19196 nats.AckExplicit(), 19197 nats.BindStream("TEST"), 19198 nats.DeliverLastPerSubject(), 19199 nats.MaxAckPending(10), 19200 nats.MaxRequestBatch(10), 19201 nats.AckWait(250*time.Millisecond)) 19202 require_NoError(t, err) 19203 19204 // Fetch the max number of message we can get, and don't ack them. 19205 _, err = sub.Fetch(10, nats.MaxWait(time.Second)) 19206 require_NoError(t, err) 19207 19208 // Wait for more than redelivery time. 19209 time.Sleep(500 * time.Millisecond) 19210 19211 // Fetch again, make sure we can get those 10 messages. 19212 msgs, err := sub.Fetch(10, nats.MaxWait(time.Second)) 19213 require_NoError(t, err) 19214 require_True(t, len(msgs) == 10) 19215 // Make sure those were the first 10 messages 19216 for i, m := range msgs { 19217 if m.Subject != fmt.Sprintf("foo.%v", i) { 19218 t.Fatalf("Expected message for subject foo.%v, got %v", i, m.Subject) 19219 } 19220 m.Ack() 19221 } 19222 } 19223 19224 func TestJetStreamPullConsumersTimeoutHeaders(t *testing.T) { 19225 s := RunBasicJetStreamServer(t) 19226 defer s.Shutdown() 19227 19228 // Client for API requests. 19229 nc, js := jsClientConnect(t, s) 19230 defer nc.Close() 19231 19232 _, err := js.AddStream(&nats.StreamConfig{ 19233 Name: "TEST", 19234 Subjects: []string{"foo.>"}, 19235 }) 19236 require_NoError(t, err) 19237 19238 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 19239 Durable: "dlc", 19240 AckPolicy: nats.AckExplicitPolicy, 19241 }) 19242 require_NoError(t, err) 19243 19244 nc.Publish("foo.foo", []byte("foo")) 19245 nc.Publish("foo.bar", []byte("bar")) 19246 nc.Publish("foo.else", []byte("baz")) 19247 nc.Flush() 19248 19249 // We will do low level requests by hand for this test as to not depend on any client impl. 19250 rsubj := fmt.Sprintf(JSApiRequestNextT, "TEST", "dlc") 19251 19252 maxBytes := 1024 19253 batch := 50 19254 req := &JSApiConsumerGetNextRequest{Batch: batch, Expires: 100 * time.Millisecond, NoWait: false, MaxBytes: maxBytes} 19255 jreq, err := json.Marshal(req) 19256 require_NoError(t, err) 19257 // Create listener. 19258 reply, msgs := nats.NewInbox(), make(chan *nats.Msg, batch) 19259 sub, err := nc.ChanSubscribe(reply, msgs) 19260 require_NoError(t, err) 19261 defer sub.Unsubscribe() 19262 19263 // Send request. 19264 err = nc.PublishRequest(rsubj, reply, jreq) 19265 require_NoError(t, err) 19266 19267 bytesReceived := 0 19268 messagesReceived := 0 19269 19270 checkHeaders := func(expectedStatus, expectedDesc string, m *nats.Msg) { 19271 t.Helper() 19272 if value := m.Header.Get("Status"); value != expectedStatus { 19273 t.Fatalf("Expected status %q, got %q", expectedStatus, value) 19274 } 19275 if value := m.Header.Get("Description"); value != expectedDesc { 19276 t.Fatalf("Expected description %q, got %q", expectedDesc, value) 19277 } 19278 if value := m.Header.Get(JSPullRequestPendingMsgs); value != fmt.Sprint(batch-messagesReceived) { 19279 t.Fatalf("Expected %d messages, got %s", batch-messagesReceived, value) 19280 } 19281 if value := m.Header.Get(JSPullRequestPendingBytes); value != fmt.Sprint(maxBytes-bytesReceived) { 19282 t.Fatalf("Expected %d bytes, got %s", maxBytes-bytesReceived, value) 19283 } 19284 } 19285 19286 for done := false; !done; { 19287 select { 19288 case m := <-msgs: 19289 if len(m.Data) == 0 && m.Header != nil { 19290 checkHeaders("408", "Request Timeout", m) 19291 done = true 19292 } else { 19293 messagesReceived += 1 19294 bytesReceived += (len(m.Data) + len(m.Header) + len(m.Reply) + len(m.Subject)) 19295 } 19296 case <-time.After(100 + 250*time.Millisecond): 19297 t.Fatalf("Did not receive all the msgs in time") 19298 } 19299 } 19300 19301 // Now resend the request but then shutdown the server and 19302 // make sure we have the same info. 19303 err = nc.PublishRequest(rsubj, reply, jreq) 19304 require_NoError(t, err) 19305 natsFlush(t, nc) 19306 19307 s.Shutdown() 19308 19309 // It is possible that the client did not receive, so let's not fail 19310 // on that. But if the 409 indicating the server is shutdown 19311 // is received, then it should have the new headers. 19312 messagesReceived, bytesReceived = 0, 0 19313 select { 19314 case m := <-msgs: 19315 checkHeaders("409", "Server Shutdown", m) 19316 case <-time.After(500 * time.Millisecond): 19317 // we can't fail for that. 19318 t.Logf("Subscription did not receive the pull request response on server shutdown") 19319 } 19320 } 19321 19322 // For issue https://github.com/nats-io/nats-server/issues/3612 19323 // Do auto cleanup. 19324 func TestJetStreamDanglingMessageAutoCleanup(t *testing.T) { 19325 s := RunBasicJetStreamServer(t) 19326 defer s.Shutdown() 19327 19328 // Client for API requests. 19329 nc, js := jsClientConnect(t, s) 19330 defer nc.Close() 19331 19332 _, err := js.AddStream(&nats.StreamConfig{ 19333 Name: "TEST", 19334 Subjects: []string{"foo"}, 19335 Retention: nats.InterestPolicy, 19336 }) 19337 require_NoError(t, err) 19338 19339 sub, err := js.PullSubscribe("foo", "dlc", nats.MaxAckPending(10)) 19340 require_NoError(t, err) 19341 19342 // Send 100 msgs 19343 n := 100 19344 for i := 0; i < n; i++ { 19345 sendStreamMsg(t, nc, "foo", "msg") 19346 } 19347 19348 // Grab and ack 10 messages. 19349 for _, m := range fetchMsgs(t, sub, 10, time.Second) { 19350 m.AckSync() 19351 } 19352 19353 ci, err := sub.ConsumerInfo() 19354 require_NoError(t, err) 19355 require_True(t, ci.AckFloor.Stream == 10) 19356 19357 // Stop current 19358 sd := s.JetStreamConfig().StoreDir 19359 s.Shutdown() 19360 19361 // We will hand move the ackfloor to simulate dangling message condition. 19362 cstore := filepath.Join(sd, "$G", "streams", "TEST", "obs", "dlc", "o.dat") 19363 19364 buf, err := os.ReadFile(cstore) 19365 require_NoError(t, err) 19366 19367 state, err := decodeConsumerState(buf) 19368 require_NoError(t, err) 19369 19370 // Update from 10 for delivered and ack to 90. 19371 state.Delivered.Stream, state.Delivered.Consumer = 90, 90 19372 state.AckFloor.Stream, state.AckFloor.Consumer = 90, 90 19373 19374 err = os.WriteFile(cstore, encodeConsumerState(state), defaultFilePerms) 19375 require_NoError(t, err) 19376 19377 // Restart. 19378 s = RunJetStreamServerOnPort(-1, sd) 19379 defer s.Shutdown() 19380 19381 nc, js = jsClientConnect(t, s) 19382 defer nc.Close() 19383 19384 si, err := js.StreamInfo("TEST") 19385 require_NoError(t, err) 19386 19387 if si.State.Msgs != 10 { 19388 t.Fatalf("Expected auto-cleanup to have worked but got %d msgs vs 10", si.State.Msgs) 19389 } 19390 } 19391 19392 // Issue https://github.com/nats-io/nats-server/issues/3645 19393 func TestJetStreamMsgIDHeaderCollision(t *testing.T) { 19394 s := RunBasicJetStreamServer(t) 19395 defer s.Shutdown() 19396 19397 // Client for API requests. 19398 nc, js := jsClientConnect(t, s) 19399 defer nc.Close() 19400 19401 _, err := js.AddStream(&nats.StreamConfig{ 19402 Name: "TEST", 19403 Subjects: []string{"ORDERS.*"}, 19404 }) 19405 require_NoError(t, err) 19406 19407 m := nats.NewMsg("ORDERS.test") 19408 m.Header.Add(JSMsgId, "1") 19409 m.Data = []byte("ok") 19410 19411 _, err = js.PublishMsg(m) 19412 require_NoError(t, err) 19413 19414 m.Header = make(nats.Header) 19415 m.Header.Add("Orig-Nats-Msg-Id", "1") 19416 19417 _, err = js.PublishMsg(m) 19418 require_NoError(t, err) 19419 19420 m.Header = make(nats.Header) 19421 m.Header.Add("Original-Nats-Msg-Id", "1") 19422 19423 _, err = js.PublishMsg(m) 19424 require_NoError(t, err) 19425 19426 m.Header = make(nats.Header) 19427 m.Header.Add("Original-Nats-Msg-Id", "1") 19428 m.Header.Add("Really-Original-Nats-Msg-Id", "1") 19429 19430 _, err = js.PublishMsg(m) 19431 require_NoError(t, err) 19432 19433 m.Header = make(nats.Header) 19434 m.Header.Add("X", "Nats-Msg-Id:1") 19435 19436 _, err = js.PublishMsg(m) 19437 require_NoError(t, err) 19438 19439 si, err := js.StreamInfo("TEST") 19440 require_NoError(t, err) 19441 19442 require_True(t, si.State.Msgs == 5) 19443 } 19444 19445 // https://github.com/nats-io/nats-server/issues/3657 19446 func TestJetStreamServerCrashOnPullConsumerDeleteWithInactiveThresholdAfterAck(t *testing.T) { 19447 s := RunBasicJetStreamServer(t) 19448 defer s.Shutdown() 19449 19450 // Client for API requests. 19451 nc, js := jsClientConnect(t, s) 19452 defer nc.Close() 19453 19454 _, err := js.AddStream(&nats.StreamConfig{ 19455 Name: "TEST", 19456 Subjects: []string{"foo"}, 19457 }) 19458 require_NoError(t, err) 19459 19460 sendStreamMsg(t, nc, "foo", "msg") 19461 19462 sub, err := js.PullSubscribe("foo", "dlc", nats.InactiveThreshold(10*time.Second)) 19463 require_NoError(t, err) 19464 19465 msgs := fetchMsgs(t, sub, 1, time.Second) 19466 require_True(t, len(msgs) == 1) 19467 msgs[0].Ack() 19468 err = js.DeleteConsumer("TEST", "dlc") 19469 require_NoError(t, err) 19470 19471 // If server crashes this will fail. 19472 _, err = js.StreamInfo("TEST") 19473 require_NoError(t, err) 19474 } 19475 19476 func TestJetStreamConsumerMultipleSubjectsLast(t *testing.T) { 19477 s := RunBasicJetStreamServer(t) 19478 if config := s.JetStreamConfig(); config != nil { 19479 defer removeDir(t, config.StoreDir) 19480 } 19481 defer s.Shutdown() 19482 19483 durable := "durable" 19484 nc, js := jsClientConnect(t, s) 19485 defer nc.Close() 19486 acc := s.GlobalAccount() 19487 19488 mset, err := acc.addStream(&StreamConfig{ 19489 Subjects: []string{"events", "data", "other"}, 19490 Name: "name", 19491 }) 19492 if err != nil { 19493 t.Fatalf("error while creating stream") 19494 } 19495 19496 sendStreamMsg(t, nc, "events", "1") 19497 sendStreamMsg(t, nc, "data", "2") 19498 sendStreamMsg(t, nc, "other", "3") 19499 sendStreamMsg(t, nc, "events", "4") 19500 sendStreamMsg(t, nc, "data", "5") 19501 sendStreamMsg(t, nc, "data", "6") 19502 sendStreamMsg(t, nc, "other", "7") 19503 sendStreamMsg(t, nc, "other", "8") 19504 19505 // if they're not the same, expect error 19506 _, err = mset.addConsumer(&ConsumerConfig{ 19507 DeliverPolicy: DeliverLast, 19508 AckPolicy: AckExplicit, 19509 DeliverSubject: "deliver", 19510 FilterSubjects: []string{"events", "data"}, 19511 Durable: durable, 19512 }) 19513 require_NoError(t, err) 19514 19515 sub, err := js.SubscribeSync("", nats.Bind("name", durable)) 19516 require_NoError(t, err) 19517 19518 msg, err := sub.NextMsg(time.Millisecond * 500) 19519 require_NoError(t, err) 19520 19521 j, err := strconv.Atoi(string(msg.Data)) 19522 require_NoError(t, err) 19523 expectedStreamSeq := 6 19524 if j != expectedStreamSeq { 19525 t.Fatalf("wrong sequence, expected %v got %v", expectedStreamSeq, j) 19526 } 19527 19528 require_NoError(t, msg.AckSync()) 19529 19530 // check if we don't get more than we wanted 19531 msg, err = sub.NextMsg(time.Millisecond * 500) 19532 if msg != nil || err == nil { 19533 t.Fatalf("should not get more messages") 19534 } 19535 19536 info, err := js.ConsumerInfo("name", durable) 19537 require_NoError(t, err) 19538 19539 require_True(t, info.NumAckPending == 0) 19540 require_True(t, info.AckFloor.Stream == 8) 19541 require_True(t, info.AckFloor.Consumer == 1) 19542 require_True(t, info.NumPending == 0) 19543 } 19544 19545 func TestJetStreamConsumerMultipleSubjectsLastPerSubject(t *testing.T) { 19546 s := RunBasicJetStreamServer(t) 19547 if config := s.JetStreamConfig(); config != nil { 19548 defer removeDir(t, config.StoreDir) 19549 } 19550 defer s.Shutdown() 19551 19552 durable := "durable" 19553 nc, js := jsClientConnect(t, s) 19554 defer nc.Close() 19555 acc := s.GlobalAccount() 19556 19557 mset, err := acc.addStream(&StreamConfig{ 19558 Subjects: []string{"events.*", "data.>", "other"}, 19559 Name: "name", 19560 }) 19561 if err != nil { 19562 t.Fatalf("error while creating stream") 19563 } 19564 19565 sendStreamMsg(t, nc, "events.1", "bad") 19566 sendStreamMsg(t, nc, "events.1", "events.1") 19567 19568 sendStreamMsg(t, nc, "data.1", "bad") 19569 sendStreamMsg(t, nc, "data.1", "bad") 19570 sendStreamMsg(t, nc, "data.1", "bad") 19571 sendStreamMsg(t, nc, "data.1", "bad") 19572 sendStreamMsg(t, nc, "data.1", "data.1") 19573 19574 sendStreamMsg(t, nc, "events.2", "bad") 19575 sendStreamMsg(t, nc, "events.2", "bad") 19576 // this is last proper sequence, 19577 sendStreamMsg(t, nc, "events.2", "events.2") 19578 19579 sendStreamMsg(t, nc, "other", "bad") 19580 sendStreamMsg(t, nc, "other", "bad") 19581 19582 // if they're not the same, expect error 19583 _, err = mset.addConsumer(&ConsumerConfig{ 19584 DeliverPolicy: DeliverLastPerSubject, 19585 AckPolicy: AckExplicit, 19586 DeliverSubject: "deliver", 19587 FilterSubjects: []string{"events.*", "data.>"}, 19588 Durable: durable, 19589 }) 19590 require_NoError(t, err) 19591 19592 sub, err := js.SubscribeSync("", nats.Bind("name", durable)) 19593 require_NoError(t, err) 19594 19595 checkMessage := func(t *testing.T, subject string, payload string, ack bool) { 19596 msg, err := sub.NextMsg(time.Millisecond * 500) 19597 require_NoError(t, err) 19598 19599 if string(msg.Data) != payload { 19600 t.Fatalf("expected %v paylaod, got %v", payload, string(msg.Data)) 19601 } 19602 if subject != msg.Subject { 19603 t.Fatalf("expected %v subject, got %v", subject, msg.Subject) 19604 } 19605 if ack { 19606 msg.AckSync() 19607 } 19608 } 19609 19610 checkMessage(t, "events.1", "events.1", true) 19611 checkMessage(t, "data.1", "data.1", true) 19612 checkMessage(t, "events.2", "events.2", false) 19613 19614 info, err := js.ConsumerInfo("name", durable) 19615 require_NoError(t, err) 19616 19617 require_True(t, info.AckFloor.Consumer == 2) 19618 require_True(t, info.AckFloor.Stream == 9) 19619 require_True(t, info.Delivered.Stream == 12) 19620 require_True(t, info.Delivered.Consumer == 3) 19621 19622 require_NoError(t, err) 19623 19624 } 19625 func TestJetStreamConsumerMultipleSubjects(t *testing.T) { 19626 s := RunBasicJetStreamServer(t) 19627 if config := s.JetStreamConfig(); config != nil { 19628 defer removeDir(t, config.StoreDir) 19629 } 19630 defer s.Shutdown() 19631 19632 durable := "durable" 19633 nc, js := jsClientConnect(t, s) 19634 defer nc.Close() 19635 19636 mset, err := s.GlobalAccount().addStream(&StreamConfig{ 19637 Subjects: []string{"events.>", "data.>"}, 19638 Name: "name", 19639 }) 19640 require_NoError(t, err) 19641 19642 for i := 0; i < 20; i += 2 { 19643 sendStreamMsg(t, nc, "events.created", fmt.Sprintf("created %v", i)) 19644 sendStreamMsg(t, nc, "data.processed", fmt.Sprintf("processed %v", i+1)) 19645 } 19646 19647 _, err = mset.addConsumer(&ConsumerConfig{ 19648 Durable: durable, 19649 DeliverSubject: "deliver", 19650 FilterSubjects: []string{"events.created", "data.processed"}, 19651 AckPolicy: AckExplicit, 19652 }) 19653 require_NoError(t, err) 19654 19655 sub, err := js.SubscribeSync("", nats.Bind("name", durable)) 19656 require_NoError(t, err) 19657 19658 for i := 0; i < 20; i++ { 19659 msg, err := sub.NextMsg(time.Millisecond * 500) 19660 require_NoError(t, err) 19661 require_NoError(t, msg.AckSync()) 19662 } 19663 info, err := js.ConsumerInfo("name", durable) 19664 require_NoError(t, err) 19665 require_True(t, info.NumAckPending == 0) 19666 require_True(t, info.NumPending == 0) 19667 require_True(t, info.AckFloor.Consumer == 20) 19668 require_True(t, info.AckFloor.Stream == 20) 19669 19670 } 19671 19672 func TestJetStreamConsumerMultipleSubjectsWithEmpty(t *testing.T) { 19673 s := RunBasicJetStreamServer(t) 19674 if config := s.JetStreamConfig(); config != nil { 19675 defer removeDir(t, config.StoreDir) 19676 } 19677 defer s.Shutdown() 19678 19679 durable := "durable" 19680 nc, js := jsClientConnect(t, s) 19681 defer nc.Close() 19682 19683 _, err := js.AddStream(&nats.StreamConfig{ 19684 Subjects: []string{"events.>"}, 19685 Name: "name", 19686 }) 19687 require_NoError(t, err) 19688 19689 for i := 0; i < 10; i++ { 19690 sendStreamMsg(t, nc, "events.created", fmt.Sprintf("%v", i)) 19691 } 19692 19693 // if they're not the same, expect error 19694 _, err = js.AddConsumer("name", &nats.ConsumerConfig{ 19695 DeliverSubject: "deliver", 19696 FilterSubject: "", 19697 Durable: durable, 19698 AckPolicy: nats.AckExplicitPolicy}) 19699 require_NoError(t, err) 19700 19701 sub, err := js.SubscribeSync("", nats.Bind("name", durable)) 19702 require_NoError(t, err) 19703 19704 for i := 0; i < 9; i++ { 19705 msg, err := sub.NextMsg(time.Millisecond * 500) 19706 require_NoError(t, err) 19707 j, err := strconv.Atoi(string(msg.Data)) 19708 require_NoError(t, err) 19709 if j != i { 19710 t.Fatalf("wrong sequence, expected %v got %v", i, j) 19711 } 19712 require_NoError(t, msg.AckSync()) 19713 } 19714 19715 info, err := js.ConsumerInfo("name", durable) 19716 require_NoError(t, err) 19717 require_True(t, info.Delivered.Stream == 10) 19718 require_True(t, info.Delivered.Consumer == 10) 19719 require_True(t, info.AckFloor.Stream == 9) 19720 require_True(t, info.AckFloor.Consumer == 9) 19721 require_True(t, info.NumAckPending == 1) 19722 19723 resp := createConsumer(t, nc, "name", ConsumerConfig{ 19724 FilterSubjects: []string{""}, 19725 DeliverSubject: "multiple", 19726 Durable: "multiple", 19727 AckPolicy: AckExplicit, 19728 }) 19729 require_True(t, resp.Error.ErrCode == 10139) 19730 } 19731 19732 func SingleFilterConsumerCheck(t *testing.T) { 19733 s := RunBasicJetStreamServer(t) 19734 if config := s.JetStreamConfig(); config != nil { 19735 defer removeDir(t, config.StoreDir) 19736 } 19737 defer s.Shutdown() 19738 19739 durable := "durable" 19740 nc, _ := jsClientConnect(t, s) 19741 defer nc.Close() 19742 acc := s.GlobalAccount() 19743 19744 mset, err := acc.addStream(&StreamConfig{ 19745 Subjects: []string{"events.>"}, 19746 Name: "deliver", 19747 }) 19748 require_NoError(t, err) 19749 19750 // if they're not the same, expect error 19751 _, err = mset.addConsumer(&ConsumerConfig{ 19752 DeliverSubject: "deliver", 19753 FilterSubject: "SINGLE", 19754 Durable: durable, 19755 }) 19756 require_Error(t, err) 19757 } 19758 19759 // createConsumer is a temporary method until nats.go client supports multiple subjects. 19760 // it is used where lowe level call on mset is not enough, as we want to test error validation. 19761 func createConsumer(t *testing.T, nc *nats.Conn, stream string, config ConsumerConfig) JSApiConsumerCreateResponse { 19762 req, err := json.Marshal(&CreateConsumerRequest{Stream: stream, Config: config}) 19763 require_NoError(t, err) 19764 19765 resp, err := nc.Request(fmt.Sprintf("$JS.API.CONSUMER.DURABLE.CREATE.%s.%s", stream, config.Durable), req, time.Second*10) 19766 require_NoError(t, err) 19767 19768 var apiResp JSApiConsumerCreateResponse 19769 require_NoError(t, json.Unmarshal(resp.Data, &apiResp)) 19770 19771 return apiResp 19772 } 19773 19774 func TestJetStreamConsumerOverlappingSubjects(t *testing.T) { 19775 s := RunBasicJetStreamServer(t) 19776 if config := s.JetStreamConfig(); config != nil { 19777 defer removeDir(t, config.StoreDir) 19778 } 19779 defer s.Shutdown() 19780 19781 nc, _ := jsClientConnect(t, s) 19782 defer nc.Close() 19783 acc := s.GlobalAccount() 19784 19785 _, err := acc.addStream(&StreamConfig{ 19786 Subjects: []string{"events.>"}, 19787 Name: "deliver", 19788 }) 19789 require_NoError(t, err) 19790 19791 resp := createConsumer(t, nc, "deliver", ConsumerConfig{ 19792 FilterSubjects: []string{"events.one", "events.*"}, 19793 Durable: "name", 19794 }) 19795 19796 if resp.Error.ErrCode != 10138 { 19797 t.Fatalf("this should error as we have overlapping subjects, got %+v", resp.Error) 19798 } 19799 } 19800 19801 func TestJetStreamBothFiltersSet(t *testing.T) { 19802 s := RunBasicJetStreamServer(t) 19803 if config := s.JetStreamConfig(); config != nil { 19804 defer removeDir(t, config.StoreDir) 19805 } 19806 defer s.Shutdown() 19807 19808 nc, _ := jsClientConnect(t, s) 19809 defer nc.Close() 19810 acc := s.GlobalAccount() 19811 19812 _, err := acc.addStream(&StreamConfig{ 19813 Subjects: []string{"events.>"}, 19814 Name: "deliver", 19815 }) 19816 require_NoError(t, err) 19817 19818 resp := createConsumer(t, nc, "deliver", ConsumerConfig{ 19819 FilterSubjects: []string{"events.one", "events.two"}, 19820 FilterSubject: "events.three", 19821 Durable: "name", 19822 }) 19823 require_True(t, resp.Error.ErrCode == 10136) 19824 } 19825 19826 func TestJetStreamMultipleSubjectsPushBasic(t *testing.T) { 19827 s := RunBasicJetStreamServer(t) 19828 if config := s.JetStreamConfig(); config != nil { 19829 defer removeDir(t, config.StoreDir) 19830 } 19831 defer s.Shutdown() 19832 19833 nc, js := jsClientConnect(t, s) 19834 defer nc.Close() 19835 19836 mset, err := s.GlobalAccount().addStream(&StreamConfig{ 19837 Subjects: []string{"events", "data", "other"}, 19838 Name: "deliver", 19839 }) 19840 require_NoError(t, err) 19841 19842 _, err = mset.addConsumer(&ConsumerConfig{ 19843 FilterSubjects: []string{"events", "data"}, 19844 Durable: "name", 19845 DeliverSubject: "push", 19846 }) 19847 require_NoError(t, err) 19848 19849 sub, err := nc.SubscribeSync("push") 19850 require_NoError(t, err) 19851 19852 sendStreamMsg(t, nc, "other", "10") 19853 sendStreamMsg(t, nc, "events", "0") 19854 sendStreamMsg(t, nc, "data", "1") 19855 sendStreamMsg(t, nc, "events", "2") 19856 sendStreamMsg(t, nc, "events", "3") 19857 sendStreamMsg(t, nc, "other", "10") 19858 sendStreamMsg(t, nc, "data", "4") 19859 sendStreamMsg(t, nc, "data", "5") 19860 19861 for i := 0; i < 6; i++ { 19862 msg, err := sub.NextMsg(time.Second * 1) 19863 require_NoError(t, err) 19864 if fmt.Sprintf("%v", i) != string(msg.Data) { 19865 t.Fatalf("bad sequence. Expected %v, got %v", i, string(msg.Data)) 19866 } 19867 } 19868 info, err := js.ConsumerInfo("deliver", "name") 19869 require_NoError(t, err) 19870 require_True(t, info.AckFloor.Consumer == 6) 19871 require_True(t, info.AckFloor.Stream == 8) 19872 } 19873 func TestJetStreamMultipleSubjectsBasic(t *testing.T) { 19874 s := RunBasicJetStreamServer(t) 19875 if config := s.JetStreamConfig(); config != nil { 19876 defer removeDir(t, config.StoreDir) 19877 } 19878 defer s.Shutdown() 19879 19880 nc, js := jsClientConnect(t, s) 19881 defer nc.Close() 19882 acc := s.GlobalAccount() 19883 19884 mset, err := acc.addStream(&StreamConfig{ 19885 Subjects: []string{"events", "data", "other"}, 19886 Name: "deliver", 19887 }) 19888 require_NoError(t, err) 19889 19890 mset.addConsumer(&ConsumerConfig{ 19891 FilterSubjects: []string{"events", "data"}, 19892 Durable: "name", 19893 }) 19894 require_NoError(t, err) 19895 19896 sendStreamMsg(t, nc, "other", "10") 19897 sendStreamMsg(t, nc, "events", "0") 19898 sendStreamMsg(t, nc, "data", "1") 19899 sendStreamMsg(t, nc, "events", "2") 19900 sendStreamMsg(t, nc, "events", "3") 19901 sendStreamMsg(t, nc, "other", "10") 19902 sendStreamMsg(t, nc, "data", "4") 19903 sendStreamMsg(t, nc, "data", "5") 19904 19905 consumer, err := js.PullSubscribe("", "name", nats.Bind("deliver", "name")) 19906 require_NoError(t, err) 19907 19908 msg, err := consumer.Fetch(6) 19909 require_NoError(t, err) 19910 19911 for i, msg := range msg { 19912 if fmt.Sprintf("%v", i) != string(msg.Data) { 19913 t.Fatalf("bad sequence. Expected %v, got %v", i, string(msg.Data)) 19914 } 19915 } 19916 _, err = js.ConsumerInfo("deliver", "name") 19917 require_NoError(t, err) 19918 } 19919 19920 func TestJetStreamKVDelete(t *testing.T) { 19921 s := RunBasicJetStreamServer(t) 19922 if config := s.JetStreamConfig(); config != nil { 19923 defer removeDir(t, config.StoreDir) 19924 } 19925 defer s.Shutdown() 19926 19927 nc, js := jsClientConnect(t, s) 19928 defer nc.Close() 19929 19930 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{ 19931 Bucket: "deletion", 19932 History: 10, 19933 }) 19934 require_NoError(t, err) 19935 kv.Put("a", nil) 19936 kv.Put("a.a", nil) 19937 kv.Put("a.b", nil) 19938 kv.Put("a.b.c", nil) 19939 19940 keys, err := kv.Keys() 19941 require_NoError(t, err) 19942 require_True(t, len(keys) == 4) 19943 19944 info, err := js.AddConsumer("KV_deletion", &nats.ConsumerConfig{ 19945 Name: "keys", 19946 FilterSubject: "$KV.deletion.a.*", 19947 DeliverPolicy: nats.DeliverLastPerSubjectPolicy, 19948 DeliverSubject: "keys", 19949 MaxDeliver: 1, 19950 AckPolicy: nats.AckNonePolicy, 19951 MemoryStorage: true, 19952 FlowControl: true, 19953 Heartbeat: time.Second * 5, 19954 }) 19955 require_NoError(t, err) 19956 require_True(t, info.NumPending == 2) 19957 19958 sub, err := js.SubscribeSync("$KV.deletion.a.*", nats.Bind("KV_deletion", "keys")) 19959 require_NoError(t, err) 19960 19961 _, err = sub.NextMsg(time.Second * 1) 19962 require_NoError(t, err) 19963 _, err = sub.NextMsg(time.Second * 1) 19964 require_NoError(t, err) 19965 msg, err := sub.NextMsg(time.Second * 1) 19966 require_True(t, msg == nil) 19967 require_Error(t, err) 19968 19969 require_NoError(t, kv.Delete("a.a")) 19970 require_NoError(t, kv.Delete("a.b")) 19971 19972 watcher, err := kv.WatchAll() 19973 require_NoError(t, err) 19974 19975 updates := watcher.Updates() 19976 19977 keys = []string{} 19978 for v := range updates { 19979 if v == nil { 19980 break 19981 } 19982 if v.Operation() == nats.KeyValueDelete { 19983 keys = append(keys, v.Key()) 19984 } 19985 } 19986 require_True(t, len(keys) == 2) 19987 } 19988 19989 func TestJetStreamDeliverLastPerSubjectWithKV(t *testing.T) { 19990 s := RunBasicJetStreamServer(t) 19991 if config := s.JetStreamConfig(); config != nil { 19992 defer removeDir(t, config.StoreDir) 19993 } 19994 defer s.Shutdown() 19995 19996 nc, js := jsClientConnect(t, s) 19997 defer nc.Close() 19998 19999 _, err := js.AddStream(&nats.StreamConfig{ 20000 Name: "TEST", 20001 MaxMsgsPerSubject: 5, 20002 Subjects: []string{"kv.>"}, 20003 }) 20004 require_NoError(t, err) 20005 20006 sendStreamMsg(t, nc, "kv.a", "bad") 20007 sendStreamMsg(t, nc, "kv.a", "bad") 20008 sendStreamMsg(t, nc, "kv.a", "bad") 20009 sendStreamMsg(t, nc, "kv.a", "a") 20010 sendStreamMsg(t, nc, "kv.a.b", "bad") 20011 sendStreamMsg(t, nc, "kv.a.b", "bad") 20012 sendStreamMsg(t, nc, "kv.a.b", "a.b") 20013 sendStreamMsg(t, nc, "kv.a.b.c", "bad") 20014 sendStreamMsg(t, nc, "kv.a.b.c", "bad") 20015 sendStreamMsg(t, nc, "kv.a.b.c", "bad") 20016 sendStreamMsg(t, nc, "kv.a.b.c", "a.b.c") 20017 20018 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 20019 Name: "CONSUMER", 20020 FilterSubject: "kv.>", 20021 DeliverPolicy: nats.DeliverLastPerSubjectPolicy, 20022 DeliverSubject: "deliver", 20023 MaxDeliver: 1, 20024 AckPolicy: nats.AckNonePolicy, 20025 MemoryStorage: true, 20026 FlowControl: true, 20027 Heartbeat: time.Second * 5, 20028 }) 20029 require_NoError(t, err) 20030 20031 sub, err := js.SubscribeSync("kv.>", nats.Bind("TEST", "CONSUMER")) 20032 require_NoError(t, err) 20033 20034 for i := 1; i <= 3; i++ { 20035 _, err := sub.NextMsg(time.Second * 1) 20036 require_NoError(t, err) 20037 } 20038 20039 msg, err := sub.NextMsg(time.Second * 1) 20040 if err == nil || msg != nil { 20041 t.Fatalf("should not get any more messages") 20042 } 20043 } 20044 20045 func TestJetStreamConsumerMultipleSubjectsAck(t *testing.T) { 20046 s := RunBasicJetStreamServer(t) 20047 if config := s.JetStreamConfig(); config != nil { 20048 defer removeDir(t, config.StoreDir) 20049 } 20050 defer s.Shutdown() 20051 20052 nc, js := jsClientConnect(t, s) 20053 defer nc.Close() 20054 acc := s.GlobalAccount() 20055 20056 mset, err := acc.addStream(&StreamConfig{ 20057 Subjects: []string{"events", "data", "other"}, 20058 Name: "deliver", 20059 }) 20060 require_NoError(t, err) 20061 20062 _, err = mset.addConsumer(&ConsumerConfig{ 20063 FilterSubjects: []string{"events", "data"}, 20064 Durable: "name", 20065 AckPolicy: AckExplicit, 20066 Replicas: 1, 20067 }) 20068 require_NoError(t, err) 20069 20070 sendStreamMsg(t, nc, "events", "1") 20071 sendStreamMsg(t, nc, "data", "2") 20072 sendStreamMsg(t, nc, "data", "3") 20073 sendStreamMsg(t, nc, "data", "4") 20074 sendStreamMsg(t, nc, "events", "5") 20075 sendStreamMsg(t, nc, "data", "6") 20076 sendStreamMsg(t, nc, "data", "7") 20077 20078 consumer, err := js.PullSubscribe("", "name", nats.Bind("deliver", "name")) 20079 require_NoError(t, err) 20080 20081 msg, err := consumer.Fetch(3) 20082 require_NoError(t, err) 20083 20084 require_True(t, len(msg) == 3) 20085 20086 require_NoError(t, msg[0].AckSync()) 20087 require_NoError(t, msg[1].AckSync()) 20088 20089 info, err := js.ConsumerInfo("deliver", "name") 20090 require_NoError(t, err) 20091 20092 if info.AckFloor.Consumer != 2 { 20093 t.Fatalf("bad consumer sequence. expected %v, got %v", 2, info.AckFloor.Consumer) 20094 } 20095 if info.AckFloor.Stream != 2 { 20096 t.Fatalf("bad stream sequence. expected %v, got %v", 2, info.AckFloor.Stream) 20097 } 20098 if info.NumPending != 4 { 20099 t.Fatalf("bad num pending. Expected %v, got %v", 2, info.NumPending) 20100 } 20101 20102 } 20103 20104 func TestJetStreamConsumerMultipleSubjectAndNewAPI(t *testing.T) { 20105 s := RunBasicJetStreamServer(t) 20106 if config := s.JetStreamConfig(); config != nil { 20107 defer removeDir(t, config.StoreDir) 20108 } 20109 defer s.Shutdown() 20110 20111 nc, _ := jsClientConnect(t, s) 20112 defer nc.Close() 20113 acc := s.GlobalAccount() 20114 20115 _, err := acc.addStream(&StreamConfig{ 20116 Subjects: []string{"data", "events"}, 20117 Name: "deliver", 20118 }) 20119 if err != nil { 20120 t.Fatalf("error while creating stream") 20121 } 20122 20123 req, err := json.Marshal(&CreateConsumerRequest{Stream: "deliver", Config: ConsumerConfig{ 20124 FilterSubjects: []string{"events", "data"}, 20125 Name: "name", 20126 Durable: "name", 20127 }}) 20128 require_NoError(t, err) 20129 20130 resp, err := nc.Request(fmt.Sprintf("$JS.API.CONSUMER.CREATE.%s.%s.%s", "deliver", "name", "data.>"), req, time.Second*10) 20131 20132 var apiResp JSApiConsumerCreateResponse 20133 json.Unmarshal(resp.Data, &apiResp) 20134 require_NoError(t, err) 20135 20136 if apiResp.Error.ErrCode != 10137 { 20137 t.Fatal("this should error as multiple subject filters is incompatible with new API and didn't") 20138 } 20139 20140 } 20141 20142 func TestJetStreamConsumerMultipleSubjectsWithAddedMessages(t *testing.T) { 20143 s := RunBasicJetStreamServer(t) 20144 if config := s.JetStreamConfig(); config != nil { 20145 defer removeDir(t, config.StoreDir) 20146 } 20147 defer s.Shutdown() 20148 20149 durable := "durable" 20150 nc, js := jsClientConnect(t, s) 20151 defer nc.Close() 20152 acc := s.GlobalAccount() 20153 20154 mset, err := acc.addStream(&StreamConfig{ 20155 Subjects: []string{"events.>"}, 20156 Name: "deliver", 20157 }) 20158 require_NoError(t, err) 20159 20160 // if they're not the same, expect error 20161 _, err = mset.addConsumer(&ConsumerConfig{ 20162 DeliverSubject: "deliver", 20163 FilterSubjects: []string{"events.created", "events.processed"}, 20164 Durable: durable, 20165 AckPolicy: AckExplicit, 20166 }) 20167 20168 require_NoError(t, err) 20169 20170 sendStreamMsg(t, nc, "events.created", "0") 20171 sendStreamMsg(t, nc, "events.created", "1") 20172 sendStreamMsg(t, nc, "events.created", "2") 20173 sendStreamMsg(t, nc, "events.created", "3") 20174 sendStreamMsg(t, nc, "events.other", "BAD") 20175 sendStreamMsg(t, nc, "events.processed", "4") 20176 sendStreamMsg(t, nc, "events.processed", "5") 20177 sendStreamMsg(t, nc, "events.processed", "6") 20178 sendStreamMsg(t, nc, "events.other", "BAD") 20179 sendStreamMsg(t, nc, "events.processed", "7") 20180 sendStreamMsg(t, nc, "events.processed", "8") 20181 20182 sub, err := js.SubscribeSync("", nats.Bind("deliver", durable)) 20183 if err != nil { 20184 t.Fatalf("error while subscribing to Consumer: %v", err) 20185 } 20186 20187 for i := 0; i < 10; i++ { 20188 if i == 5 { 20189 sendStreamMsg(t, nc, "events.created", "9") 20190 } 20191 if i == 9 { 20192 sendStreamMsg(t, nc, "events.other", "BAD") 20193 sendStreamMsg(t, nc, "events.created", "11") 20194 } 20195 if i == 7 { 20196 sendStreamMsg(t, nc, "events.processed", "10") 20197 } 20198 20199 msg, err := sub.NextMsg(time.Second * 1) 20200 require_NoError(t, err) 20201 j, err := strconv.Atoi(string(msg.Data)) 20202 require_NoError(t, err) 20203 if j != i { 20204 t.Fatalf("wrong sequence, expected %v got %v", i, j) 20205 } 20206 if err := msg.AckSync(); err != nil { 20207 t.Fatalf("error while acking the message :%v", err) 20208 } 20209 20210 } 20211 20212 info, err := js.ConsumerInfo("deliver", durable) 20213 require_NoError(t, err) 20214 20215 require_True(t, info.Delivered.Consumer == 12) 20216 require_True(t, info.Delivered.Stream == 15) 20217 require_True(t, info.AckFloor.Stream == 12) 20218 require_True(t, info.AckFloor.Consumer == 10) 20219 } 20220 20221 func TestJetStreamConsumerThreeFilters(t *testing.T) { 20222 s := RunBasicJetStreamServer(t) 20223 defer s.Shutdown() 20224 20225 nc, js := jsClientConnect(t, s) 20226 defer nc.Close() 20227 20228 mset, err := s.GlobalAccount().addStream(&StreamConfig{ 20229 Name: "TEST", 20230 Subjects: []string{"events", "data", "other", "ignored"}, 20231 }) 20232 require_NoError(t, err) 20233 20234 sendStreamMsg(t, nc, "ignored", "100") 20235 sendStreamMsg(t, nc, "events", "0") 20236 sendStreamMsg(t, nc, "events", "1") 20237 20238 sendStreamMsg(t, nc, "data", "2") 20239 sendStreamMsg(t, nc, "ignored", "100") 20240 sendStreamMsg(t, nc, "data", "3") 20241 20242 sendStreamMsg(t, nc, "other", "4") 20243 sendStreamMsg(t, nc, "data", "5") 20244 sendStreamMsg(t, nc, "other", "6") 20245 sendStreamMsg(t, nc, "data", "7") 20246 sendStreamMsg(t, nc, "ignored", "100") 20247 20248 mset.addConsumer(&ConsumerConfig{ 20249 FilterSubjects: []string{"events", "data", "other"}, 20250 Durable: "multi", 20251 AckPolicy: AckExplicit, 20252 }) 20253 20254 consumer, err := js.PullSubscribe("", "multi", nats.Bind("TEST", "multi")) 20255 require_NoError(t, err) 20256 20257 msgs, err := consumer.Fetch(6) 20258 require_NoError(t, err) 20259 for i, msg := range msgs { 20260 require_Equal(t, string(msg.Data), fmt.Sprintf("%d", i)) 20261 require_NoError(t, msg.AckSync()) 20262 } 20263 20264 info, err := js.ConsumerInfo("TEST", "multi") 20265 require_NoError(t, err) 20266 require_True(t, info.Delivered.Stream == 8) 20267 require_True(t, info.Delivered.Consumer == 6) 20268 require_True(t, info.NumPending == 2) 20269 require_True(t, info.NumAckPending == 0) 20270 require_True(t, info.AckFloor.Consumer == 6) 20271 require_True(t, info.AckFloor.Stream == 8) 20272 } 20273 20274 func TestJetStreamConsumerUpdateFilterSubjects(t *testing.T) { 20275 s := RunBasicJetStreamServer(t) 20276 defer s.Shutdown() 20277 20278 nc, js := jsClientConnect(t, s) 20279 defer nc.Close() 20280 20281 mset, err := s.GlobalAccount().addStream(&StreamConfig{ 20282 Name: "TEST", 20283 Subjects: []string{"events", "data", "other"}, 20284 }) 20285 require_NoError(t, err) 20286 20287 sendStreamMsg(t, nc, "other", "100") 20288 sendStreamMsg(t, nc, "events", "0") 20289 sendStreamMsg(t, nc, "events", "1") 20290 sendStreamMsg(t, nc, "data", "2") 20291 sendStreamMsg(t, nc, "data", "3") 20292 sendStreamMsg(t, nc, "other", "4") 20293 sendStreamMsg(t, nc, "data", "5") 20294 20295 _, err = mset.addConsumer(&ConsumerConfig{ 20296 FilterSubjects: []string{"events", "data"}, 20297 Durable: "multi", 20298 AckPolicy: AckExplicit, 20299 }) 20300 require_NoError(t, err) 20301 20302 consumer, err := js.PullSubscribe("", "multi", nats.Bind("TEST", "multi")) 20303 require_NoError(t, err) 20304 20305 msgs, err := consumer.Fetch(3) 20306 require_NoError(t, err) 20307 for i, msg := range msgs { 20308 require_Equal(t, string(msg.Data), fmt.Sprintf("%d", i)) 20309 require_NoError(t, msg.AckSync()) 20310 } 20311 20312 _, err = mset.addConsumer(&ConsumerConfig{ 20313 FilterSubjects: []string{"events", "data", "other"}, 20314 Durable: "multi", 20315 AckPolicy: AckExplicit, 20316 }) 20317 require_NoError(t, err) 20318 20319 updatedConsumer, err := js.PullSubscribe("", "multi", nats.Bind("TEST", "multi")) 20320 require_NoError(t, err) 20321 20322 msgs, err = updatedConsumer.Fetch(3) 20323 require_NoError(t, err) 20324 for i, msg := range msgs { 20325 require_Equal(t, string(msg.Data), fmt.Sprintf("%d", i+3)) 20326 require_NoError(t, msg.AckSync()) 20327 } 20328 } 20329 func TestJetStreamStreamUpdateSubjectsOverlapOthers(t *testing.T) { 20330 s := RunBasicJetStreamServer(t) 20331 defer s.Shutdown() 20332 20333 nc, js := jsClientConnect(t, s) 20334 defer nc.Close() 20335 20336 _, err := js.AddStream(&nats.StreamConfig{ 20337 Name: "TEST", 20338 Subjects: []string{"TEST"}, 20339 }) 20340 require_NoError(t, err) 20341 20342 _, err = js.UpdateStream(&nats.StreamConfig{ 20343 Name: "TEST", 20344 Subjects: []string{"TEST", "foo.a"}, 20345 }) 20346 require_NoError(t, err) 20347 20348 _, err = js.AddStream(&nats.StreamConfig{ 20349 Name: "TEST2", 20350 Subjects: []string{"TEST2"}, 20351 }) 20352 require_NoError(t, err) 20353 20354 // we expect an error updating stream TEST2 with subject that overlaps that used by TEST 20355 // foo.a fails too, but foo.* also double-check for sophisticated overlap match 20356 _, err = js.UpdateStream(&nats.StreamConfig{ 20357 Name: "TEST2", 20358 Subjects: []string{"TEST2", "foo.*"}, 20359 }) 20360 require_Error(t, err) 20361 require_Contains(t, err.Error(), "overlap") 20362 } 20363 20364 func TestJetStreamMetaDataFailOnKernelFault(t *testing.T) { 20365 s := RunBasicJetStreamServer(t) 20366 defer s.Shutdown() 20367 20368 nc, js := jsClientConnect(t, s) 20369 defer nc.Close() 20370 20371 _, err := js.AddStream(&nats.StreamConfig{ 20372 Name: "TEST", 20373 Subjects: []string{"foo"}, 20374 }) 20375 require_NoError(t, err) 20376 20377 for i := 0; i < 10; i++ { 20378 sendStreamMsg(t, nc, "foo", "OK") 20379 } 20380 20381 sd := s.JetStreamConfig().StoreDir 20382 sdir := filepath.Join(sd, "$G", "streams", "TEST") 20383 s.Shutdown() 20384 20385 // Emulate if the kernel did not flush out to disk the meta information. 20386 // so we will zero out both meta.inf and meta.sum. 20387 err = os.WriteFile(filepath.Join(sdir, JetStreamMetaFile), nil, defaultFilePerms) 20388 require_NoError(t, err) 20389 20390 err = os.WriteFile(filepath.Join(sdir, JetStreamMetaFileSum), nil, defaultFilePerms) 20391 require_NoError(t, err) 20392 20393 // Restart. 20394 s = RunJetStreamServerOnPort(-1, sd) 20395 defer s.Shutdown() 20396 20397 nc, js = jsClientConnect(t, s) 20398 defer nc.Close() 20399 20400 // The stream will have not been recovered. So err is normal. 20401 _, err = js.StreamInfo("TEST") 20402 require_Error(t, err) 20403 20404 // Make sure we are signaled here from healthz 20405 hs := s.healthz(nil) 20406 const expected = "JetStream stream '$G > TEST' could not be recovered" 20407 if hs.Status != "unavailable" || hs.Error == _EMPTY_ { 20408 t.Fatalf("Expected healthz to return an error") 20409 } else if hs.Error != expected { 20410 t.Fatalf("Expected healthz error %q got %q", expected, hs.Error) 20411 } 20412 20413 // If we add it back, this should recover the msgs. 20414 _, err = js.AddStream(&nats.StreamConfig{ 20415 Name: "TEST", 20416 Subjects: []string{"foo"}, 20417 }) 20418 require_NoError(t, err) 20419 20420 // Make sure we recovered. 20421 si, err := js.StreamInfo("TEST") 20422 require_NoError(t, err) 20423 require_True(t, si.State.Msgs == 10) 20424 20425 // Now if we restart the server, meta should be correct, 20426 // and the stream should be restored. 20427 s.Shutdown() 20428 20429 s = RunJetStreamServerOnPort(-1, sd) 20430 defer s.Shutdown() 20431 20432 nc, js = jsClientConnect(t, s) 20433 defer nc.Close() 20434 20435 // Make sure we recovered the stream correctly after re-adding. 20436 si, err = js.StreamInfo("TEST") 20437 require_NoError(t, err) 20438 require_True(t, si.State.Msgs == 10) 20439 } 20440 20441 func TestJetstreamConsumerSingleTokenSubject(t *testing.T) { 20442 s := RunBasicJetStreamServer(t) 20443 defer s.Shutdown() 20444 20445 nc, js := jsClientConnect(t, s) 20446 defer nc.Close() 20447 20448 filterSubject := "foo" 20449 _, err := js.AddStream(&nats.StreamConfig{ 20450 Name: "TEST", 20451 Subjects: []string{filterSubject}, 20452 }) 20453 require_NoError(t, err) 20454 20455 req, err := json.Marshal(&CreateConsumerRequest{Stream: "TEST", Config: ConsumerConfig{ 20456 FilterSubject: filterSubject, 20457 Name: "name", 20458 }}) 20459 20460 if err != nil { 20461 t.Fatalf("failed to marshal consumer create request: %v", err) 20462 } 20463 20464 resp, err := nc.Request(fmt.Sprintf("$JS.API.CONSUMER.CREATE.%s.%s.%s", "TEST", "name", "not_filter_subject"), req, time.Second*10) 20465 20466 var apiResp ApiResponse 20467 json.Unmarshal(resp.Data, &apiResp) 20468 if err != nil { 20469 t.Fatalf("failed to unmarshal response: %v", err) 20470 } 20471 if apiResp.Error == nil { 20472 t.Fatalf("expected error, got nil") 20473 } 20474 if apiResp.Error.ErrCode != 10131 { 20475 t.Fatalf("expected error 10131, got %v", apiResp.Error) 20476 } 20477 } 20478 20479 // https://github.com/nats-io/nats-server/issues/3734 20480 func TestJetStreamMsgBlkFailOnKernelFault(t *testing.T) { 20481 s := RunBasicJetStreamServer(t) 20482 defer s.Shutdown() 20483 20484 nc, js := jsClientConnect(t, s) 20485 defer nc.Close() 20486 20487 _, err := js.AddStream(&nats.StreamConfig{ 20488 Name: "TEST", 20489 Subjects: []string{"foo"}, 20490 MaxBytes: 10 * 1024 * 1024, // 10MB 20491 }) 20492 require_NoError(t, err) 20493 20494 msgSize := 1024 * 1024 // 1MB 20495 msg := make([]byte, msgSize) 20496 crand.Read(msg) 20497 20498 for i := 0; i < 20; i++ { 20499 _, err := js.Publish("foo", msg) 20500 require_NoError(t, err) 20501 } 20502 20503 si, err := js.StreamInfo("TEST") 20504 require_NoError(t, err) 20505 require_True(t, si.State.Bytes < uint64(si.Config.MaxBytes)) 20506 20507 // Now emulate a kernel fault that fails to write the last blk properly. 20508 mset, err := s.GlobalAccount().lookupStream("TEST") 20509 require_NoError(t, err) 20510 20511 mset.mu.RLock() 20512 fs := mset.store.(*fileStore) 20513 fs.mu.RLock() 20514 require_True(t, len(fs.blks) > 2) 20515 // Here we do not grab the last one, which we handle correctly. We grab an interior one near the end. 20516 lmbf := fs.blks[len(fs.blks)-2].mfn 20517 fs.mu.RUnlock() 20518 mset.mu.RUnlock() 20519 20520 sd := s.JetStreamConfig().StoreDir 20521 s.Shutdown() 20522 20523 // Remove block. 20524 require_NoError(t, os.Remove(lmbf)) 20525 20526 s = RunJetStreamServerOnPort(-1, sd) 20527 defer s.Shutdown() 20528 20529 nc, js = jsClientConnect(t, s) 20530 defer nc.Close() 20531 20532 _, err = js.GetMsg("TEST", 17) 20533 require_Error(t, err, nats.ErrMsgNotFound) 20534 20535 si, err = js.StreamInfo("TEST") 20536 require_NoError(t, err) 20537 require_True(t, si.State.NumDeleted == 3) 20538 20539 // Test detailed version as well. 20540 si, err = js.StreamInfo("TEST", &nats.StreamInfoRequest{DeletedDetails: true}) 20541 require_NoError(t, err) 20542 require_True(t, si.State.NumDeleted == 3) 20543 if !reflect.DeepEqual(si.State.Deleted, []uint64{16, 17, 18}) { 20544 t.Fatalf("Expected deleted of %+v, got %+v", []uint64{16, 17, 18}, si.State.Deleted) 20545 } 20546 20547 for i := 0; i < 20; i++ { 20548 _, err := js.Publish("foo", msg) 20549 require_NoError(t, err) 20550 } 20551 20552 si, err = js.StreamInfo("TEST") 20553 require_NoError(t, err) 20554 if si.State.Bytes > uint64(si.Config.MaxBytes) { 20555 t.Fatalf("MaxBytes not enforced with empty interior msg blk, max %v, bytes %v", 20556 friendlyBytes(si.Config.MaxBytes), friendlyBytes(int64(si.State.Bytes))) 20557 } 20558 } 20559 20560 func TestJetStreamPullConsumerBatchCompleted(t *testing.T) { 20561 s := RunBasicJetStreamServer(t) 20562 defer s.Shutdown() 20563 20564 nc, js := jsClientConnect(t, s) 20565 defer nc.Close() 20566 20567 _, err := js.AddStream(&nats.StreamConfig{ 20568 Name: "TEST", 20569 Subjects: []string{"foo"}, 20570 }) 20571 require_NoError(t, err) 20572 20573 msgSize := 128 20574 msg := make([]byte, msgSize) 20575 crand.Read(msg) 20576 20577 for i := 0; i < 10; i++ { 20578 _, err := js.Publish("foo", msg) 20579 require_NoError(t, err) 20580 } 20581 20582 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 20583 Durable: "dur", 20584 AckPolicy: nats.AckExplicitPolicy, 20585 }) 20586 require_NoError(t, err) 20587 20588 req := JSApiConsumerGetNextRequest{Batch: 0, MaxBytes: 1024, Expires: 250 * time.Millisecond} 20589 20590 reqb, _ := json.Marshal(req) 20591 sub := natsSubSync(t, nc, nats.NewInbox()) 20592 err = nc.PublishRequest("$JS.API.CONSUMER.MSG.NEXT.TEST.dur", sub.Subject, reqb) 20593 require_NoError(t, err) 20594 20595 // Expect first message to arrive normally. 20596 _, err = sub.NextMsg(time.Second * 1) 20597 require_NoError(t, err) 20598 20599 // Second message should be info that batch is complete, but there were pending bytes. 20600 pullMsg, err := sub.NextMsg(time.Second * 1) 20601 require_NoError(t, err) 20602 20603 if v := pullMsg.Header.Get("Status"); v != "409" { 20604 t.Fatalf("Expected 409, got: %s", v) 20605 } 20606 if v := pullMsg.Header.Get("Description"); v != "Batch Completed" { 20607 t.Fatalf("Expected Batch Completed, got: %s", v) 20608 } 20609 } 20610 20611 func TestJetStreamConsumerAndStreamMetadata(t *testing.T) { 20612 s := RunBasicJetStreamServer(t) 20613 defer s.Shutdown() 20614 20615 metadata := map[string]string{"key": "value", "_nats_created_version": "2.9.11"} 20616 acc := s.GlobalAccount() 20617 20618 // Check stream's first. 20619 mset, err := acc.addStream(&StreamConfig{Name: "foo", Metadata: metadata}) 20620 if err != nil { 20621 t.Fatalf("Unexpected error adding stream: %v", err) 20622 } 20623 if cfg := mset.config(); !reflect.DeepEqual(metadata, cfg.Metadata) { 20624 t.Fatalf("Expected a metadata of %q, got %q", metadata, cfg.Metadata) 20625 } 20626 20627 // Now consumer 20628 o, err := mset.addConsumer(&ConsumerConfig{ 20629 Metadata: metadata, 20630 DeliverSubject: "to", 20631 AckPolicy: AckNone}) 20632 if err != nil { 20633 t.Fatalf("Unexpected error adding consumer: %v", err) 20634 } 20635 if cfg := o.config(); !reflect.DeepEqual(metadata, cfg.Metadata) { 20636 t.Fatalf("Expected a metadata of %q, got %q", metadata, cfg.Metadata) 20637 } 20638 20639 // Test max. 20640 data := make([]byte, JSMaxMetadataLen/100) 20641 crand.Read(data) 20642 bigValue := base64.StdEncoding.EncodeToString(data) 20643 20644 bigMetadata := make(map[string]string, 101) 20645 for i := 0; i < 101; i++ { 20646 bigMetadata[fmt.Sprintf("key%d", i)] = bigValue 20647 } 20648 20649 _, err = acc.addStream(&StreamConfig{Name: "bar", Metadata: bigMetadata}) 20650 if err == nil || !strings.Contains(err.Error(), "stream metadata exceeds") { 20651 t.Fatalf("Expected an error but got none") 20652 } 20653 20654 _, err = mset.addConsumer(&ConsumerConfig{ 20655 Metadata: bigMetadata, 20656 DeliverSubject: "to", 20657 AckPolicy: AckNone}) 20658 if err == nil || !strings.Contains(err.Error(), "consumer metadata exceeds") { 20659 t.Fatalf("Expected an error but got none") 20660 } 20661 } 20662 20663 func TestJetStreamConsumerPurge(t *testing.T) { 20664 s := RunBasicJetStreamServer(t) 20665 defer s.Shutdown() 20666 20667 nc, js := jsClientConnect(t, s) 20668 defer nc.Close() 20669 20670 _, err := js.AddStream(&nats.StreamConfig{ 20671 Name: "TEST", 20672 Subjects: []string{"test.>"}, 20673 }) 20674 require_NoError(t, err) 20675 20676 sendStreamMsg(t, nc, "test.1", "hello") 20677 sendStreamMsg(t, nc, "test.2", "hello") 20678 20679 sub, err := js.PullSubscribe("test.>", "consumer") 20680 require_NoError(t, err) 20681 20682 // Purge one of the subjects. 20683 err = js.PurgeStream("TEST", &nats.StreamPurgeRequest{Subject: "test.2"}) 20684 require_NoError(t, err) 20685 20686 info, err := js.ConsumerInfo("TEST", "consumer") 20687 require_NoError(t, err) 20688 require_True(t, info.NumPending == 1) 20689 20690 // Expect to get message from not purged subject. 20691 _, err = sub.Fetch(1) 20692 require_NoError(t, err) 20693 20694 _, err = js.AddStream(&nats.StreamConfig{ 20695 Name: "OTHER", 20696 Subjects: []string{"other.>"}, 20697 }) 20698 require_NoError(t, err) 20699 20700 // Publish two items to two subjects. 20701 sendStreamMsg(t, nc, "other.1", "hello") 20702 sendStreamMsg(t, nc, "other.2", "hello") 20703 20704 sub, err = js.PullSubscribe("other.>", "other_consumer") 20705 require_NoError(t, err) 20706 20707 // Purge whole stream. 20708 err = js.PurgeStream("OTHER", &nats.StreamPurgeRequest{}) 20709 require_NoError(t, err) 20710 20711 info, err = js.ConsumerInfo("OTHER", "other_consumer") 20712 require_NoError(t, err) 20713 require_True(t, info.NumPending == 0) 20714 20715 // This time expect error, as we purged whole stream, 20716 _, err = sub.Fetch(1) 20717 require_Error(t, err) 20718 20719 } 20720 20721 func TestJetStreamConsumerFilterUpdate(t *testing.T) { 20722 s := RunBasicJetStreamServer(t) 20723 defer s.Shutdown() 20724 20725 nc, js := jsClientConnect(t, s) 20726 defer nc.Close() 20727 20728 _, err := js.AddStream(&nats.StreamConfig{ 20729 Name: "TEST", 20730 Subjects: []string{"foo.>", "bar.>"}, 20731 }) 20732 require_NoError(t, err) 20733 20734 for i := 0; i < 3; i++ { 20735 sendStreamMsg(t, nc, "foo.data", "OK") 20736 } 20737 20738 sub, err := nc.SubscribeSync("deliver") 20739 require_NoError(t, err) 20740 20741 js.AddConsumer("TEST", &nats.ConsumerConfig{ 20742 Durable: "consumer", 20743 DeliverSubject: "deliver", 20744 FilterSubject: "foo.data", 20745 }) 20746 20747 _, err = sub.NextMsg(time.Second * 1) 20748 require_NoError(t, err) 20749 _, err = sub.NextMsg(time.Second * 1) 20750 require_NoError(t, err) 20751 _, err = sub.NextMsg(time.Second * 1) 20752 require_NoError(t, err) 20753 20754 _, err = js.UpdateConsumer("TEST", &nats.ConsumerConfig{ 20755 Durable: "consumer", 20756 DeliverSubject: "deliver", 20757 FilterSubject: "foo.>", 20758 }) 20759 require_NoError(t, err) 20760 20761 sendStreamMsg(t, nc, "foo.other", "data") 20762 20763 // This will timeout if filters were not properly updated. 20764 _, err = sub.NextMsg(time.Second * 1) 20765 require_NoError(t, err) 20766 20767 mset, err := s.GlobalAccount().lookupStream("TEST") 20768 require_NoError(t, err) 20769 20770 checkNumFilter := func(expected int) { 20771 t.Helper() 20772 mset.mu.RLock() 20773 nf := mset.numFilter 20774 mset.mu.RUnlock() 20775 if nf != expected { 20776 t.Fatalf("Expected stream's numFilter to be %d, got %d", expected, nf) 20777 } 20778 } 20779 20780 checkNumFilter(1) 20781 20782 // Update consumer once again, now not having any filters 20783 _, err = js.UpdateConsumer("TEST", &nats.ConsumerConfig{ 20784 Durable: "consumer", 20785 DeliverSubject: "deliver", 20786 FilterSubject: _EMPTY_, 20787 }) 20788 require_NoError(t, err) 20789 20790 // and expect that numFilter reports correctly. 20791 checkNumFilter(0) 20792 } 20793 20794 func TestJetStreamPurgeExAndAccounting(t *testing.T) { 20795 cases := []struct { 20796 name string 20797 cfg *nats.StreamConfig 20798 }{ 20799 {name: "MemoryStore", 20800 cfg: &nats.StreamConfig{ 20801 Name: "TEST", 20802 Storage: nats.MemoryStorage, 20803 Subjects: []string{"*"}, 20804 }}, 20805 {name: "FileStore", 20806 cfg: &nats.StreamConfig{ 20807 Name: "TEST", 20808 Storage: nats.FileStorage, 20809 Subjects: []string{"*"}, 20810 }}, 20811 } 20812 for _, c := range cases { 20813 s := RunBasicJetStreamServer(t) 20814 defer s.Shutdown() 20815 20816 // Client for API requests. 20817 nc, js := jsClientConnect(t, s) 20818 defer nc.Close() 20819 20820 _, err := js.AddStream(c.cfg) 20821 require_NoError(t, err) 20822 20823 msg := []byte("accounting") 20824 for i := 0; i < 100; i++ { 20825 _, err = js.Publish("foo", msg) 20826 require_NoError(t, err) 20827 _, err = js.Publish("bar", msg) 20828 require_NoError(t, err) 20829 } 20830 20831 info, err := js.AccountInfo() 20832 require_NoError(t, err) 20833 20834 err = js.PurgeStream("TEST", &nats.StreamPurgeRequest{Subject: "foo"}) 20835 require_NoError(t, err) 20836 20837 ninfo, err := js.AccountInfo() 20838 require_NoError(t, err) 20839 20840 // Make sure we did the proper accounting. 20841 if c.cfg.Storage == nats.MemoryStorage { 20842 if ninfo.Memory != info.Memory/2 { 20843 t.Fatalf("Accounting information incorrect for Memory: %d vs %d", 20844 ninfo.Memory, info.Memory/2) 20845 } 20846 } else { 20847 if ninfo.Store != info.Store/2 { 20848 t.Fatalf("Accounting information incorrect for FileStore: %d vs %d", 20849 ninfo.Store, info.Store/2) 20850 } 20851 } 20852 } 20853 } 20854 20855 func TestJetStreamRollup(t *testing.T) { 20856 s := RunBasicJetStreamServer(t) 20857 defer s.Shutdown() 20858 20859 nc, js := jsClientConnect(t, s) 20860 defer nc.Close() 20861 20862 const STREAM = "S" 20863 const SUBJ = "S.*" 20864 20865 js.AddStream(&nats.StreamConfig{ 20866 Name: STREAM, 20867 Subjects: []string{SUBJ}, 20868 AllowRollup: true, 20869 }) 20870 20871 for i := 1; i <= 10; i++ { 20872 sendStreamMsg(t, nc, "S.A", fmt.Sprintf("%v", i)) 20873 sendStreamMsg(t, nc, "S.B", fmt.Sprintf("%v", i)) 20874 } 20875 20876 sinfo, err := js.StreamInfo(STREAM) 20877 require_NoError(t, err) 20878 require_True(t, sinfo.State.Msgs == 20) 20879 20880 cinfo, err := js.AddConsumer(STREAM, &nats.ConsumerConfig{ 20881 Durable: "DUR-A", 20882 FilterSubject: "S.A", 20883 AckPolicy: nats.AckExplicitPolicy, 20884 }) 20885 require_NoError(t, err) 20886 require_True(t, cinfo.NumPending == 10) 20887 20888 m := nats.NewMsg("S.A") 20889 m.Header.Set(JSMsgRollup, JSMsgRollupSubject) 20890 20891 _, err = js.PublishMsg(m) 20892 require_NoError(t, err) 20893 20894 cinfo, err = js.ConsumerInfo("S", "DUR-A") 20895 require_NoError(t, err) 20896 require_True(t, cinfo.NumPending == 1) 20897 20898 sinfo, err = js.StreamInfo(STREAM) 20899 require_NoError(t, err) 20900 require_True(t, sinfo.State.Msgs == 11) 20901 20902 cinfo, err = js.AddConsumer(STREAM, &nats.ConsumerConfig{ 20903 Durable: "DUR-B", 20904 FilterSubject: "S.B", 20905 AckPolicy: nats.AckExplicitPolicy, 20906 }) 20907 require_NoError(t, err) 20908 require_True(t, cinfo.NumPending == 10) 20909 } 20910 20911 func TestJetStreamPartialPurgeWithAckPending(t *testing.T) { 20912 s := RunBasicJetStreamServer(t) 20913 defer s.Shutdown() 20914 20915 nc, js := jsClientConnect(t, s) 20916 defer nc.Close() 20917 20918 _, err := js.AddStream(&nats.StreamConfig{ 20919 Name: "TEST", 20920 Subjects: []string{"foo"}, 20921 }) 20922 require_NoError(t, err) 20923 20924 nmsgs := 100 20925 for i := 0; i < nmsgs; i++ { 20926 sendStreamMsg(t, nc, "foo", "OK") 20927 } 20928 sub, err := js.PullSubscribe("foo", "dlc", nats.AckWait(time.Second)) 20929 require_NoError(t, err) 20930 20931 // Queue up all for ack pending. 20932 _, err = sub.Fetch(nmsgs) 20933 require_NoError(t, err) 20934 20935 keep := nmsgs / 2 20936 require_NoError(t, js.PurgeStream("TEST", &nats.StreamPurgeRequest{Keep: uint64(keep)})) 20937 20938 // Should be able to be redelivered now. 20939 time.Sleep(2 * time.Second) 20940 20941 ci, err := js.ConsumerInfo("TEST", "dlc") 20942 require_NoError(t, err) 20943 // Make sure we calculated correctly. 20944 require_True(t, ci.AckFloor.Consumer == uint64(keep)) 20945 require_True(t, ci.AckFloor.Stream == uint64(keep)) 20946 require_True(t, ci.NumAckPending == keep) 20947 require_True(t, ci.NumPending == 0) 20948 20949 for i := 0; i < nmsgs; i++ { 20950 sendStreamMsg(t, nc, "foo", "OK") 20951 } 20952 20953 ci, err = js.ConsumerInfo("TEST", "dlc") 20954 require_NoError(t, err) 20955 // Make sure we calculated correctly. 20956 // Top 3 will be same. 20957 require_True(t, ci.AckFloor.Consumer == uint64(keep)) 20958 require_True(t, ci.AckFloor.Stream == uint64(keep)) 20959 require_True(t, ci.NumAckPending == keep) 20960 require_True(t, ci.NumPending == uint64(nmsgs)) 20961 require_True(t, ci.NumRedelivered == 0) 20962 20963 msgs, err := sub.Fetch(keep) 20964 require_NoError(t, err) 20965 require_True(t, len(msgs) == keep) 20966 20967 ci, err = js.ConsumerInfo("TEST", "dlc") 20968 require_NoError(t, err) 20969 // Make sure we calculated correctly. 20970 require_True(t, ci.Delivered.Consumer == uint64(nmsgs+keep)) 20971 require_True(t, ci.Delivered.Stream == uint64(nmsgs)) 20972 require_True(t, ci.AckFloor.Consumer == uint64(keep)) 20973 require_True(t, ci.AckFloor.Stream == uint64(keep)) 20974 require_True(t, ci.NumAckPending == keep) 20975 require_True(t, ci.NumPending == uint64(nmsgs)) 20976 require_True(t, ci.NumRedelivered == keep) 20977 20978 // Ack all. 20979 for _, m := range msgs { 20980 m.Ack() 20981 } 20982 nc.Flush() 20983 20984 ci, err = js.ConsumerInfo("TEST", "dlc") 20985 require_NoError(t, err) 20986 // Same for Delivered 20987 require_True(t, ci.Delivered.Consumer == uint64(nmsgs+keep)) 20988 require_True(t, ci.Delivered.Stream == uint64(nmsgs)) 20989 require_True(t, ci.AckFloor.Consumer == uint64(nmsgs+keep)) 20990 require_True(t, ci.AckFloor.Stream == uint64(nmsgs)) 20991 require_True(t, ci.NumAckPending == 0) 20992 require_True(t, ci.NumPending == uint64(nmsgs)) 20993 require_True(t, ci.NumRedelivered == 0) 20994 20995 msgs, err = sub.Fetch(nmsgs) 20996 require_NoError(t, err) 20997 require_True(t, len(msgs) == nmsgs) 20998 20999 // Ack all again 21000 for _, m := range msgs { 21001 m.Ack() 21002 } 21003 nc.Flush() 21004 21005 ci, err = js.ConsumerInfo("TEST", "dlc") 21006 require_NoError(t, err) 21007 // Make sure we calculated correctly. 21008 require_True(t, ci.Delivered.Consumer == uint64(nmsgs*2+keep)) 21009 require_True(t, ci.Delivered.Stream == uint64(nmsgs*2)) 21010 require_True(t, ci.AckFloor.Consumer == uint64(nmsgs*2+keep)) 21011 require_True(t, ci.AckFloor.Stream == uint64(nmsgs*2)) 21012 require_True(t, ci.NumAckPending == 0) 21013 require_True(t, ci.NumPending == 0) 21014 require_True(t, ci.NumRedelivered == 0) 21015 } 21016 21017 func TestJetStreamPurgeWithRedeliveredPending(t *testing.T) { 21018 s := RunBasicJetStreamServer(t) 21019 defer s.Shutdown() 21020 21021 nc, js := jsClientConnect(t, s) 21022 defer nc.Close() 21023 21024 _, err := js.AddStream(&nats.StreamConfig{ 21025 Name: "TEST", 21026 Subjects: []string{"foo"}, 21027 }) 21028 require_NoError(t, err) 21029 21030 nmsgs := 100 21031 for i := 0; i < nmsgs; i++ { 21032 sendStreamMsg(t, nc, "foo", "OK") 21033 } 21034 sub, err := js.PullSubscribe("foo", "dlc", nats.AckWait(time.Second)) 21035 require_NoError(t, err) 21036 21037 // Queue up all for ack pending. 21038 msgs, err := sub.Fetch(nmsgs) 21039 require_NoError(t, err) 21040 require_True(t, len(msgs) == nmsgs) 21041 21042 // Should be able to be redelivered now. 21043 time.Sleep(2 * time.Second) 21044 21045 // Queue up all for ack pending again. 21046 msgs, err = sub.Fetch(nmsgs) 21047 require_NoError(t, err) 21048 require_True(t, len(msgs) == nmsgs) 21049 21050 require_NoError(t, js.PurgeStream("TEST")) 21051 21052 ci, err := js.ConsumerInfo("TEST", "dlc") 21053 require_NoError(t, err) 21054 21055 require_True(t, ci.Delivered.Consumer == uint64(2*nmsgs)) 21056 require_True(t, ci.Delivered.Stream == uint64(nmsgs)) 21057 require_True(t, ci.AckFloor.Consumer == uint64(2*nmsgs)) 21058 require_True(t, ci.AckFloor.Stream == uint64(nmsgs)) 21059 require_True(t, ci.NumAckPending == 0) 21060 require_True(t, ci.NumPending == 0) 21061 require_True(t, ci.NumRedelivered == 0) 21062 } 21063 21064 func TestJetStreamConsumerAckFloorWithExpired(t *testing.T) { 21065 s := RunBasicJetStreamServer(t) 21066 defer s.Shutdown() 21067 21068 nc, js := jsClientConnect(t, s) 21069 defer nc.Close() 21070 21071 _, err := js.AddStream(&nats.StreamConfig{ 21072 Name: "TEST", 21073 Subjects: []string{"foo"}, 21074 MaxAge: 2 * time.Second, 21075 }) 21076 require_NoError(t, err) 21077 21078 nmsgs := 100 21079 for i := 0; i < nmsgs; i++ { 21080 sendStreamMsg(t, nc, "foo", "OK") 21081 } 21082 sub, err := js.PullSubscribe("foo", "dlc", nats.AckWait(time.Second)) 21083 require_NoError(t, err) 21084 21085 // Queue up all for ack pending. 21086 msgs, err := sub.Fetch(nmsgs) 21087 require_NoError(t, err) 21088 require_True(t, len(msgs) == nmsgs) 21089 21090 // Let all messages expire. 21091 time.Sleep(3 * time.Second) 21092 21093 si, err := js.StreamInfo("TEST") 21094 require_NoError(t, err) 21095 require_True(t, si.State.Msgs == 0) 21096 21097 ci, err := js.ConsumerInfo("TEST", "dlc") 21098 require_NoError(t, err) 21099 21100 require_True(t, ci.Delivered.Consumer == uint64(nmsgs)) 21101 require_True(t, ci.Delivered.Stream == uint64(nmsgs)) 21102 require_True(t, ci.AckFloor.Consumer == uint64(nmsgs)) 21103 require_True(t, ci.AckFloor.Stream == uint64(nmsgs)) 21104 require_True(t, ci.NumAckPending == 0) 21105 require_True(t, ci.NumPending == 0) 21106 require_True(t, ci.NumRedelivered == 0) 21107 } 21108 21109 func TestJetStreamConsumerIsFiltered(t *testing.T) { 21110 s := RunBasicJetStreamServer(t) 21111 defer s.Shutdown() 21112 acc := s.GlobalAccount() 21113 21114 tests := []struct { 21115 name string 21116 streamSubjects []string 21117 filters []string 21118 isFiltered bool 21119 }{ 21120 { 21121 name: "single_subject", 21122 streamSubjects: []string{"one"}, 21123 filters: []string{"one"}, 21124 isFiltered: false, 21125 }, 21126 { 21127 name: "single_subject_filtered", 21128 streamSubjects: []string{"one.>"}, 21129 filters: []string{"one.filter"}, 21130 isFiltered: true, 21131 }, 21132 { 21133 name: "multi_subject_non_filtered", 21134 streamSubjects: []string{"multi", "foo", "bar.>"}, 21135 filters: []string{"multi", "bar.>", "foo"}, 21136 isFiltered: false, 21137 }, 21138 { 21139 name: "multi_subject_filtered_wc", 21140 streamSubjects: []string{"events", "data"}, 21141 filters: []string{"data"}, 21142 isFiltered: true, 21143 }, 21144 { 21145 name: "multi_subject_filtered", 21146 streamSubjects: []string{"machines", "floors"}, 21147 filters: []string{"machines"}, 21148 isFiltered: true, 21149 }, 21150 } 21151 for _, test := range tests { 21152 t.Run(test.name, func(t *testing.T) { 21153 mset, err := acc.addStream(&StreamConfig{ 21154 Name: test.name, 21155 Subjects: test.streamSubjects, 21156 }) 21157 require_NoError(t, err) 21158 21159 o, err := mset.addConsumer(&ConsumerConfig{ 21160 FilterSubjects: test.filters, 21161 Durable: test.name, 21162 }) 21163 require_NoError(t, err) 21164 21165 require_True(t, o.isFiltered() == test.isFiltered) 21166 }) 21167 } 21168 } 21169 21170 func TestJetStreamConsumerWithFormattingSymbol(t *testing.T) { 21171 s := RunBasicJetStreamServer(t) 21172 defer s.Shutdown() 21173 21174 nc, js := jsClientConnect(t, s) 21175 defer nc.Close() 21176 21177 _, err := js.AddStream(&nats.StreamConfig{ 21178 Name: "Test%123", 21179 Subjects: []string{"foo"}, 21180 }) 21181 require_NoError(t, err) 21182 21183 for i := 0; i < 10; i++ { 21184 sendStreamMsg(t, nc, "foo", "OK") 21185 } 21186 21187 _, err = js.AddConsumer("Test%123", &nats.ConsumerConfig{ 21188 Durable: "Test%123", 21189 FilterSubject: "foo", 21190 DeliverSubject: "bar", 21191 }) 21192 require_NoError(t, err) 21193 21194 sub, err := js.SubscribeSync("foo", nats.Bind("Test%123", "Test%123")) 21195 require_NoError(t, err) 21196 21197 _, err = sub.NextMsg(time.Second * 5) 21198 require_NoError(t, err) 21199 } 21200 21201 func TestJetStreamStreamUpdateWithExternalSource(t *testing.T) { 21202 ho := DefaultTestOptions 21203 ho.Port = -1 21204 ho.LeafNode.Host = "127.0.0.1" 21205 ho.LeafNode.Port = -1 21206 ho.JetStream = true 21207 ho.JetStreamDomain = "hub" 21208 ho.StoreDir = t.TempDir() 21209 hs := RunServer(&ho) 21210 defer hs.Shutdown() 21211 21212 lu, err := url.Parse(fmt.Sprintf("nats://127.0.0.1:%d", ho.LeafNode.Port)) 21213 require_NoError(t, err) 21214 21215 lo1 := DefaultTestOptions 21216 lo1.Port = -1 21217 lo1.ServerName = "a-leaf" 21218 lo1.JetStream = true 21219 lo1.StoreDir = t.TempDir() 21220 lo1.JetStreamDomain = "a-leaf" 21221 lo1.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{lu}}} 21222 l1 := RunServer(&lo1) 21223 defer l1.Shutdown() 21224 21225 checkLeafNodeConnected(t, l1) 21226 21227 // Test sources with `External` provided 21228 ncl, jsl := jsClientConnect(t, l1) 21229 defer ncl.Close() 21230 21231 // Hub stream. 21232 _, err = jsl.AddStream(&nats.StreamConfig{Name: "stream", Subjects: []string{"leaf"}}) 21233 require_NoError(t, err) 21234 21235 nch, jsh := jsClientConnect(t, hs) 21236 defer nch.Close() 21237 21238 // Leaf stream. 21239 // Both streams uses the same name, as we're testing if overlap does not check against itself 21240 // if `External` stream has the same name. 21241 _, err = jsh.AddStream(&nats.StreamConfig{ 21242 Name: "stream", 21243 Subjects: []string{"hub"}, 21244 }) 21245 require_NoError(t, err) 21246 21247 // Add `Sources`. 21248 // This should not validate subjects overlap against itself. 21249 _, err = jsh.UpdateStream(&nats.StreamConfig{ 21250 Name: "stream", 21251 Subjects: []string{"hub"}, 21252 Sources: []*nats.StreamSource{ 21253 { 21254 Name: "stream", 21255 FilterSubject: "leaf", 21256 External: &nats.ExternalStream{ 21257 APIPrefix: "$JS.a-leaf.API", 21258 }, 21259 }, 21260 }, 21261 }) 21262 require_NoError(t, err) 21263 21264 // Specifying not existing FilterSubject should also be fine, as we do not validate `External` stream. 21265 _, err = jsh.UpdateStream(&nats.StreamConfig{ 21266 Name: "stream", 21267 Subjects: []string{"hub"}, 21268 Sources: []*nats.StreamSource{ 21269 { 21270 Name: "stream", 21271 FilterSubject: "foo", 21272 External: &nats.ExternalStream{ 21273 APIPrefix: "$JS.a-leaf.API", 21274 }, 21275 }, 21276 }, 21277 }) 21278 require_NoError(t, err) 21279 } 21280 21281 func TestJetStreamKVHistoryRegression(t *testing.T) { 21282 s := RunBasicJetStreamServer(t) 21283 defer s.Shutdown() 21284 21285 nc, js := jsClientConnect(t, s) 21286 defer nc.Close() 21287 21288 for _, storage := range []nats.StorageType{nats.FileStorage, nats.MemoryStorage} { 21289 t.Run(storage.String(), func(t *testing.T) { 21290 js.DeleteKeyValue("TEST") 21291 21292 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{ 21293 Bucket: "TEST", 21294 History: 4, 21295 Storage: storage, 21296 }) 21297 require_NoError(t, err) 21298 21299 r1, err := kv.Create("foo", []byte("a")) 21300 require_NoError(t, err) 21301 21302 _, err = kv.Update("foo", []byte("ab"), r1) 21303 require_NoError(t, err) 21304 21305 err = kv.Delete("foo") 21306 require_NoError(t, err) 21307 21308 _, err = kv.Create("foo", []byte("abc")) 21309 require_NoError(t, err) 21310 21311 err = kv.Delete("foo") 21312 require_NoError(t, err) 21313 21314 history, err := kv.History("foo") 21315 require_NoError(t, err) 21316 require_True(t, len(history) == 4) 21317 21318 _, err = kv.Update("foo", []byte("abcd"), history[len(history)-1].Revision()) 21319 require_NoError(t, err) 21320 21321 err = kv.Purge("foo") 21322 require_NoError(t, err) 21323 21324 _, err = kv.Create("foo", []byte("abcde")) 21325 require_NoError(t, err) 21326 21327 err = kv.Purge("foo") 21328 require_NoError(t, err) 21329 21330 history, err = kv.History("foo") 21331 require_NoError(t, err) 21332 require_True(t, len(history) == 1) 21333 }) 21334 } 21335 } 21336 21337 func TestJetStreamSnapshotRestoreStallAndHealthz(t *testing.T) { 21338 s := RunBasicJetStreamServer(t) 21339 defer s.Shutdown() 21340 21341 nc, js := jsClientConnect(t, s) 21342 defer nc.Close() 21343 21344 _, err := js.AddStream(&nats.StreamConfig{ 21345 Name: "ORDERS", 21346 Subjects: []string{"orders.*"}, 21347 }) 21348 require_NoError(t, err) 21349 21350 for i := 0; i < 1000; i++ { 21351 sendStreamMsg(t, nc, "orders.created", "new order") 21352 } 21353 21354 hs := s.healthz(nil) 21355 if hs.Status != "ok" || hs.Error != _EMPTY_ { 21356 t.Fatalf("Expected health to be ok, got %+v", hs) 21357 } 21358 21359 // Simulate the staging directory for restores. This is normally cleaned up 21360 // but since its at the root of the storage directory make sure healthz is not affected. 21361 snapDir := filepath.Join(s.getJetStream().config.StoreDir, snapStagingDir) 21362 require_NoError(t, os.MkdirAll(snapDir, defaultDirPerms)) 21363 21364 // Make sure healthz ok. 21365 hs = s.healthz(nil) 21366 if hs.Status != "ok" || hs.Error != _EMPTY_ { 21367 t.Fatalf("Expected health to be ok, got %+v", hs) 21368 } 21369 } 21370 21371 // https://github.com/nats-io/nats-server/pull/4163 21372 func TestJetStreamMaxBytesIgnored(t *testing.T) { 21373 s := RunBasicJetStreamServer(t) 21374 defer s.Shutdown() 21375 21376 nc, js := jsClientConnect(t, s) 21377 defer nc.Close() 21378 21379 _, err := js.AddStream(&nats.StreamConfig{ 21380 Name: "TEST", 21381 Subjects: []string{"*"}, 21382 MaxBytes: 10 * 1024 * 1024, 21383 }) 21384 require_NoError(t, err) 21385 21386 msg := bytes.Repeat([]byte("A"), 1024*1024) 21387 21388 for i := 0; i < 10; i++ { 21389 _, err := js.Publish("x", msg) 21390 require_NoError(t, err) 21391 } 21392 21393 si, err := js.StreamInfo("TEST") 21394 require_NoError(t, err) 21395 require_True(t, si.State.Msgs == 9) 21396 21397 // Stop current 21398 sd := s.JetStreamConfig().StoreDir 21399 s.Shutdown() 21400 21401 // We will truncate blk file. 21402 mdir := filepath.Join(sd, "$G", "streams", "TEST", "msgs") 21403 // Truncate blk 21404 err = os.WriteFile(filepath.Join(mdir, "1.blk"), nil, defaultFilePerms) 21405 require_NoError(t, err) 21406 21407 // Restart. 21408 s = RunJetStreamServerOnPort(-1, sd) 21409 defer s.Shutdown() 21410 21411 nc, js = jsClientConnect(t, s) 21412 defer nc.Close() 21413 21414 for i := 0; i < 10; i++ { 21415 _, err := js.Publish("x", msg) 21416 require_NoError(t, err) 21417 } 21418 21419 si, err = js.StreamInfo("TEST") 21420 require_NoError(t, err) 21421 require_True(t, si.State.Bytes <= 10*1024*1024) 21422 } 21423 21424 func TestJetStreamLastSequenceBySubjectConcurrent(t *testing.T) { 21425 for _, st := range []StorageType{FileStorage, MemoryStorage} { 21426 t.Run(st.String(), func(t *testing.T) { 21427 c := createJetStreamClusterExplicit(t, "JSC", 3) 21428 defer c.shutdown() 21429 21430 nc0, js0 := jsClientConnect(t, c.randomServer()) 21431 defer nc0.Close() 21432 21433 nc1, js1 := jsClientConnect(t, c.randomServer()) 21434 defer nc1.Close() 21435 21436 cfg := StreamConfig{ 21437 Name: "KV", 21438 Subjects: []string{"kv.>"}, 21439 Storage: st, 21440 Replicas: 3, 21441 } 21442 21443 req, err := json.Marshal(cfg) 21444 if err != nil { 21445 t.Fatalf("Unexpected error: %v", err) 21446 } 21447 // Do manually for now. 21448 m, err := nc0.Request(fmt.Sprintf(JSApiStreamCreateT, cfg.Name), req, time.Second) 21449 require_NoError(t, err) 21450 si, err := js0.StreamInfo("KV") 21451 if err != nil { 21452 t.Fatalf("Unexpected error: %v, respmsg: %q", err, string(m.Data)) 21453 } 21454 if si == nil || si.Config.Name != "KV" { 21455 t.Fatalf("StreamInfo is not correct %+v", si) 21456 } 21457 21458 pub := func(js nats.JetStreamContext, subj, data, seq string) { 21459 t.Helper() 21460 m := nats.NewMsg(subj) 21461 m.Data = []byte(data) 21462 m.Header.Set(JSExpectedLastSubjSeq, seq) 21463 js.PublishMsg(m) 21464 } 21465 21466 ready := make(chan struct{}) 21467 wg := &sync.WaitGroup{} 21468 wg.Add(2) 21469 21470 go func() { 21471 <-ready 21472 pub(js0, "kv.foo", "0-0", "0") 21473 pub(js0, "kv.foo", "0-1", "1") 21474 pub(js0, "kv.foo", "0-2", "2") 21475 wg.Done() 21476 }() 21477 21478 go func() { 21479 <-ready 21480 pub(js1, "kv.foo", "1-0", "0") 21481 pub(js1, "kv.foo", "1-1", "1") 21482 pub(js1, "kv.foo", "1-2", "2") 21483 wg.Done() 21484 }() 21485 21486 time.Sleep(50 * time.Millisecond) 21487 close(ready) 21488 wg.Wait() 21489 21490 // Read the messages. 21491 sub, err := js0.PullSubscribe(_EMPTY_, _EMPTY_, nats.BindStream("KV")) 21492 require_NoError(t, err) 21493 msgs, err := sub.Fetch(10) 21494 require_NoError(t, err) 21495 if len(msgs) != 3 { 21496 t.Errorf("Expected 3 messages, got %d", len(msgs)) 21497 } 21498 for i, m := range msgs { 21499 if m.Header.Get(JSExpectedLastSubjSeq) != fmt.Sprint(i) { 21500 t.Errorf("Expected %d for last sequence, got %q", i, m.Header.Get(JSExpectedLastSubjSeq)) 21501 } 21502 } 21503 }) 21504 } 21505 } 21506 21507 func TestJetStreamServerReencryption(t *testing.T) { 21508 storeDir := t.TempDir() 21509 21510 for i, algo := range []struct { 21511 from string 21512 to string 21513 }{ 21514 {"aes", "aes"}, 21515 {"aes", "chacha"}, 21516 {"chacha", "chacha"}, 21517 {"chacha", "aes"}, 21518 } { 21519 t.Run(fmt.Sprintf("%s_to_%s", algo.from, algo.to), func(t *testing.T) { 21520 streamName := fmt.Sprintf("TEST_%d", i) 21521 subjectName := fmt.Sprintf("foo_%d", i) 21522 expected := 30 21523 21524 checkStream := func(js nats.JetStreamContext) { 21525 si, err := js.StreamInfo(streamName) 21526 if err != nil { 21527 t.Fatal(err) 21528 } 21529 21530 if si.State.Msgs != uint64(expected) { 21531 t.Fatalf("Should be %d messages but got %d messages", expected, si.State.Msgs) 21532 } 21533 21534 sub, err := js.PullSubscribe(subjectName, "") 21535 if err != nil { 21536 t.Fatalf("Unexpected error: %v", err) 21537 } 21538 21539 c := 0 21540 for _, m := range fetchMsgs(t, sub, expected, 5*time.Second) { 21541 m.AckSync() 21542 c++ 21543 } 21544 if c != expected { 21545 t.Fatalf("Should have read back %d messages but got %d messages", expected, c) 21546 } 21547 } 21548 21549 // First off, we start up using the original encryption key and algorithm. 21550 // We'll create a stream and populate it with some messages. 21551 t.Run("setup", func(t *testing.T) { 21552 conf := createConfFile(t, []byte(fmt.Sprintf(` 21553 server_name: S22 21554 listen: 127.0.0.1:-1 21555 jetstream: { 21556 key: %q, 21557 cipher: %s, 21558 store_dir: %q 21559 } 21560 `, "firstencryptionkey", algo.from, storeDir))) 21561 21562 s, _ := RunServerWithConfig(conf) 21563 defer s.Shutdown() 21564 21565 nc, js := jsClientConnect(t, s) 21566 defer nc.Close() 21567 21568 cfg := &nats.StreamConfig{ 21569 Name: streamName, 21570 Subjects: []string{subjectName}, 21571 } 21572 if _, err := js.AddStream(cfg); err != nil { 21573 t.Fatalf("Unexpected error: %v", err) 21574 } 21575 21576 for i := 0; i < expected; i++ { 21577 if _, err := js.Publish(subjectName, []byte("ENCRYPTED PAYLOAD!!")); err != nil { 21578 t.Fatalf("Unexpected publish error: %v", err) 21579 } 21580 } 21581 21582 checkStream(js) 21583 }) 21584 21585 // Next up, we will restart the server, this time with both the new key 21586 // and algorithm and also the old key. At startup, the server will detect 21587 // the change in encryption key and/or algorithm and re-encrypt the stream. 21588 t.Run("reencrypt", func(t *testing.T) { 21589 conf := createConfFile(t, []byte(fmt.Sprintf(` 21590 server_name: S22 21591 listen: 127.0.0.1:-1 21592 jetstream: { 21593 key: %q, 21594 cipher: %s, 21595 prev_key: %q, 21596 store_dir: %q 21597 } 21598 `, "secondencryptionkey", algo.to, "firstencryptionkey", storeDir))) 21599 21600 s, _ := RunServerWithConfig(conf) 21601 defer s.Shutdown() 21602 21603 nc, js := jsClientConnect(t, s) 21604 defer nc.Close() 21605 21606 checkStream(js) 21607 }) 21608 21609 // Finally, we'll restart the server using only the new key and algorithm. 21610 // At this point everything should have been re-encrypted, so we should still 21611 // be able to access the stream. 21612 t.Run("restart", func(t *testing.T) { 21613 conf := createConfFile(t, []byte(fmt.Sprintf(` 21614 server_name: S22 21615 listen: 127.0.0.1:-1 21616 jetstream: { 21617 key: %q, 21618 cipher: %s, 21619 store_dir: %q 21620 } 21621 `, "secondencryptionkey", algo.to, storeDir))) 21622 21623 s, _ := RunServerWithConfig(conf) 21624 defer s.Shutdown() 21625 21626 nc, js := jsClientConnect(t, s) 21627 defer nc.Close() 21628 21629 checkStream(js) 21630 }) 21631 }) 21632 } 21633 } 21634 21635 func TestJetStreamLimitsToInterestPolicy(t *testing.T) { 21636 c := createJetStreamClusterExplicit(t, "JSC", 3) 21637 defer c.shutdown() 21638 21639 nc, js := jsClientConnect(t, c.leader()) 21640 defer nc.Close() 21641 21642 // This is the index of the consumer that we'll create as R1 21643 // instead of R3, just to prove that it blocks the stream 21644 // update from happening properly. 21645 singleReplica := 3 21646 21647 streamCfg := nats.StreamConfig{ 21648 Name: "TEST", 21649 Subjects: []string{"foo"}, 21650 Retention: nats.LimitsPolicy, 21651 Storage: nats.MemoryStorage, 21652 Replicas: 3, 21653 } 21654 21655 stream, err := js.AddStream(&streamCfg) 21656 require_NoError(t, err) 21657 21658 for i := 0; i < 10; i++ { 21659 replicas := streamCfg.Replicas 21660 if i == singleReplica { 21661 // Make one of the consumers R1 so that we can check 21662 // that the switch to interest-based retention is also 21663 // turning it into an R3 consumer. 21664 replicas = 1 21665 } 21666 cname := fmt.Sprintf("test_%d", i) 21667 _, err := js.AddConsumer("TEST", &nats.ConsumerConfig{ 21668 Name: cname, 21669 Durable: cname, 21670 AckPolicy: nats.AckAllPolicy, 21671 Replicas: replicas, 21672 }) 21673 require_NoError(t, err) 21674 } 21675 21676 for i := 0; i < 20; i++ { 21677 _, err := js.Publish("foo", []byte{1, 2, 3, 4, 5}) 21678 require_NoError(t, err) 21679 } 21680 21681 // Pull 10 or more messages from the stream. We will never pull 21682 // less than 10, which guarantees that the lowest ack floor of 21683 // all consumers should be 10. 21684 for i := 0; i < 10; i++ { 21685 cname := fmt.Sprintf("test_%d", i) 21686 count := 10 + i // At least 10 messages 21687 21688 sub, err := js.PullSubscribe("foo", cname) 21689 require_NoError(t, err) 21690 21691 msgs, err := sub.Fetch(count) 21692 require_NoError(t, err) 21693 require_Equal(t, len(msgs), count) 21694 require_NoError(t, msgs[len(msgs)-1].AckSync()) 21695 21696 // At this point the ack floor should match the count of 21697 // messages we received. 21698 info, err := js.ConsumerInfo("TEST", cname) 21699 require_NoError(t, err) 21700 require_Equal(t, info.AckFloor.Consumer, uint64(count)) 21701 } 21702 21703 // Try updating to interest-based. This should fail because 21704 // we have a consumer that is R1 on an R3 stream. 21705 streamCfg = stream.Config 21706 streamCfg.Retention = nats.InterestPolicy 21707 _, err = js.UpdateStream(&streamCfg) 21708 require_Error(t, err) 21709 21710 // Now we'll make the R1 consumer an R3. 21711 cname := fmt.Sprintf("test_%d", singleReplica) 21712 cinfo, err := js.ConsumerInfo("TEST", cname) 21713 require_NoError(t, err) 21714 21715 cinfo.Config.Replicas = streamCfg.Replicas 21716 _, _ = js.UpdateConsumer("TEST", &cinfo.Config) 21717 // TODO(nat): The jsConsumerCreateRequest update doesn't always 21718 // respond when there are no errors updating a consumer, so this 21719 // nearly always returns a timeout, despite actually doing what 21720 // it should. We'll make sure the replicas were updated by doing 21721 // another consumer info just to be sure. 21722 // require_NoError(t, err) 21723 c.waitOnAllCurrent() 21724 cinfo, err = js.ConsumerInfo("TEST", cname) 21725 require_NoError(t, err) 21726 require_Equal(t, cinfo.Config.Replicas, streamCfg.Replicas) 21727 require_Equal(t, len(cinfo.Cluster.Replicas), streamCfg.Replicas-1) 21728 21729 // This time it should succeed. 21730 _, err = js.UpdateStream(&streamCfg) 21731 require_NoError(t, err) 21732 21733 // We need to wait for all nodes to have applied the new stream 21734 // configuration. 21735 c.waitOnAllCurrent() 21736 21737 // Now we should only have 10 messages left in the stream, as 21738 // each consumer has acked at least the first 10 messages. 21739 info, err := js.StreamInfo("TEST") 21740 require_NoError(t, err) 21741 require_Equal(t, info.State.FirstSeq, 11) 21742 require_Equal(t, info.State.Msgs, 10) 21743 } 21744 21745 func TestJetStreamLimitsToInterestPolicyWhileAcking(t *testing.T) { 21746 for _, st := range []nats.StorageType{nats.FileStorage, nats.MemoryStorage} { 21747 t.Run(st.String(), func(t *testing.T) { 21748 c := createJetStreamClusterExplicit(t, "JSC", 3) 21749 defer c.shutdown() 21750 21751 nc, js := jsClientConnect(t, c.leader()) 21752 defer nc.Close() 21753 streamCfg := nats.StreamConfig{ 21754 Name: "TEST", 21755 Subjects: []string{"foo"}, 21756 Retention: nats.LimitsPolicy, 21757 Storage: st, 21758 Replicas: 3, 21759 } 21760 21761 stream, err := js.AddStream(&streamCfg) 21762 require_NoError(t, err) 21763 21764 wg := sync.WaitGroup{} 21765 ctx, cancel := context.WithCancel(context.Background()) 21766 payload := []byte(strings.Repeat("A", 128)) 21767 21768 wg.Add(1) 21769 go func() { 21770 defer wg.Done() 21771 for range time.NewTicker(10 * time.Millisecond).C { 21772 select { 21773 case <-ctx.Done(): 21774 return 21775 default: 21776 } 21777 js.Publish("foo", payload) 21778 } 21779 }() 21780 for i := 0; i < 5; i++ { 21781 cname := fmt.Sprintf("test_%d", i) 21782 sub, err := js.PullSubscribe("foo", cname) 21783 require_NoError(t, err) 21784 21785 wg.Add(1) 21786 go func() { 21787 defer wg.Done() 21788 for range time.NewTicker(10 * time.Millisecond).C { 21789 select { 21790 case <-ctx.Done(): 21791 return 21792 default: 21793 } 21794 21795 msgs, err := sub.Fetch(1) 21796 if err != nil && errors.Is(err, nats.ErrTimeout) { 21797 t.Logf("ERROR: %v", err) 21798 } 21799 for _, msg := range msgs { 21800 msg.Ack() 21801 } 21802 } 21803 }() 21804 } 21805 // Leave running for a few secs then do the change on a different connection. 21806 time.Sleep(5 * time.Second) 21807 nc2, js2 := jsClientConnect(t, c.leader()) 21808 defer nc2.Close() 21809 21810 // Try updating to interest-based and changing replicas too. 21811 streamCfg = stream.Config 21812 streamCfg.Retention = nats.InterestPolicy 21813 _, err = js2.UpdateStream(&streamCfg) 21814 require_NoError(t, err) 21815 21816 // We need to wait for all nodes to have applied the new stream 21817 // configuration. 21818 c.waitOnAllCurrent() 21819 21820 var retention nats.RetentionPolicy 21821 checkFor(t, 15*time.Second, 500*time.Millisecond, func() error { 21822 info, err := js2.StreamInfo("TEST", nats.MaxWait(500*time.Millisecond)) 21823 if err != nil { 21824 return err 21825 } 21826 retention = info.Config.Retention 21827 return nil 21828 }) 21829 require_Equal(t, retention, nats.InterestPolicy) 21830 21831 // Cancel and wait for goroutines underneath. 21832 cancel() 21833 wg.Wait() 21834 }) 21835 } 21836 } 21837 21838 func TestJetStreamUsageSyncDeadlock(t *testing.T) { 21839 s := RunBasicJetStreamServer(t) 21840 defer s.Shutdown() 21841 21842 nc, js := jsClientConnect(t, s) 21843 defer nc.Close() 21844 21845 _, err := js.AddStream(&nats.StreamConfig{ 21846 Name: "TEST", 21847 Subjects: []string{"*"}, 21848 }) 21849 require_NoError(t, err) 21850 21851 sendStreamMsg(t, nc, "foo", "hello") 21852 21853 // Now purposely mess up the usage that will force a sync. 21854 // Without the fix this will deadlock. 21855 jsa := s.getJetStream().lookupAccount(s.GlobalAccount()) 21856 jsa.usageMu.Lock() 21857 st, ok := jsa.usage[_EMPTY_] 21858 require_True(t, ok) 21859 st.local.store = -1000 21860 jsa.usageMu.Unlock() 21861 21862 sendStreamMsg(t, nc, "foo", "hello") 21863 } 21864 21865 // https://github.com/nats-io/nats.go/issues/1382 21866 // https://github.com/nats-io/nats-server/issues/4445 21867 func TestJetStreamChangeMaxMessagesPerSubject(t *testing.T) { 21868 s := RunBasicJetStreamServer(t) 21869 defer s.Shutdown() 21870 21871 nc, js := jsClientConnect(t, s) 21872 defer nc.Close() 21873 21874 _, err := js.AddStream(&nats.StreamConfig{ 21875 Name: "TEST", 21876 Subjects: []string{"one.>"}, 21877 MaxMsgsPerSubject: 5, 21878 }) 21879 require_NoError(t, err) 21880 21881 for i := 0; i < 10; i++ { 21882 sendStreamMsg(t, nc, "one.data", "data") 21883 } 21884 21885 expectMsgs := func(num int32) error { 21886 t.Helper() 21887 21888 var msgs atomic.Int32 21889 sub, err := js.Subscribe("one.>", func(msg *nats.Msg) { 21890 msgs.Add(1) 21891 msg.Ack() 21892 }) 21893 require_NoError(t, err) 21894 defer sub.Unsubscribe() 21895 21896 checkFor(t, 5*time.Second, 100*time.Millisecond, func() error { 21897 if nm := msgs.Load(); nm != num { 21898 return fmt.Errorf("expected to get %v messages, got %v instead", num, nm) 21899 } 21900 return nil 21901 }) 21902 return nil 21903 } 21904 21905 require_NoError(t, expectMsgs(5)) 21906 21907 js.UpdateStream(&nats.StreamConfig{ 21908 Name: "TEST", 21909 Subjects: []string{"one.>"}, 21910 MaxMsgsPerSubject: 3, 21911 }) 21912 21913 info, err := js.StreamInfo("TEST") 21914 require_NoError(t, err) 21915 require_True(t, info.Config.MaxMsgsPerSubject == 3) 21916 require_True(t, info.State.Msgs == 3) 21917 21918 require_NoError(t, expectMsgs(3)) 21919 21920 for i := 0; i < 10; i++ { 21921 sendStreamMsg(t, nc, "one.data", "data") 21922 } 21923 21924 require_NoError(t, expectMsgs(3)) 21925 } 21926 21927 func TestJetStreamConsumerDefaultsFromStream(t *testing.T) { 21928 s := RunBasicJetStreamServer(t) 21929 defer s.Shutdown() 21930 21931 acc := s.GlobalAccount() 21932 if _, err := acc.addStream(&StreamConfig{ 21933 Name: "test", 21934 Subjects: []string{"test.*"}, 21935 ConsumerLimits: StreamConsumerLimits{ 21936 MaxAckPending: 15, 21937 InactiveThreshold: time.Second, 21938 }, 21939 }); err != nil { 21940 t.Fatalf("Failed to add stream: %v", err) 21941 } 21942 21943 nc := clientConnectToServer(t, s) 21944 defer nc.Close() 21945 21946 js, err := nc.JetStream() 21947 if err != nil { 21948 t.Fatalf("Failed to connect to JetStream: %v", err) 21949 } 21950 21951 t.Run("InheritDefaultsFromStream", func(t *testing.T) { 21952 ci, err := js.AddConsumer("test", &nats.ConsumerConfig{ 21953 Name: "InheritDefaultsFromStream", 21954 AckPolicy: nats.AckExplicitPolicy, 21955 }) 21956 require_NoError(t, err) 21957 21958 switch { 21959 case ci.Config.InactiveThreshold != time.Second: 21960 t.Fatalf("InactiveThreshold should be 1s, got %s", ci.Config.InactiveThreshold) 21961 case ci.Config.MaxAckPending != 15: 21962 t.Fatalf("MaxAckPending should be 15, got %d", ci.Config.MaxAckPending) 21963 } 21964 }) 21965 21966 t.Run("CreateConsumerErrorOnExceedMaxAckPending", func(t *testing.T) { 21967 _, err := js.AddConsumer("test", &nats.ConsumerConfig{ 21968 Name: "CreateConsumerErrorOnExceedMaxAckPending", 21969 MaxAckPending: 30, 21970 }) 21971 switch e := err.(type) { 21972 case *nats.APIError: 21973 if ErrorIdentifier(e.ErrorCode) != JSConsumerMaxPendingAckExcessErrF { 21974 t.Fatalf("invalid error code, got %d, wanted %d", e.ErrorCode, JSConsumerMaxPendingAckExcessErrF) 21975 } 21976 default: 21977 t.Fatalf("should have returned API error, got %T", e) 21978 } 21979 }) 21980 21981 t.Run("CreateConsumerErrorOnExceedInactiveThreshold", func(t *testing.T) { 21982 _, err := js.AddConsumer("test", &nats.ConsumerConfig{ 21983 Name: "CreateConsumerErrorOnExceedInactiveThreshold", 21984 InactiveThreshold: time.Second * 2, 21985 }) 21986 switch e := err.(type) { 21987 case *nats.APIError: 21988 if ErrorIdentifier(e.ErrorCode) != JSConsumerInactiveThresholdExcess { 21989 t.Fatalf("invalid error code, got %d, wanted %d", e.ErrorCode, JSConsumerInactiveThresholdExcess) 21990 } 21991 default: 21992 t.Fatalf("should have returned API error, got %T", e) 21993 } 21994 }) 21995 21996 t.Run("UpdateStreamErrorOnViolateConsumerMaxAckPending", func(t *testing.T) { 21997 _, err := js.AddConsumer("test", &nats.ConsumerConfig{ 21998 Name: "UpdateStreamErrorOnViolateConsumerMaxAckPending", 21999 MaxAckPending: 15, 22000 }) 22001 require_NoError(t, err) 22002 22003 stream, err := acc.lookupStream("test") 22004 require_NoError(t, err) 22005 22006 err = stream.update(&StreamConfig{ 22007 Name: "test", 22008 Subjects: []string{"test.*"}, 22009 ConsumerLimits: StreamConsumerLimits{ 22010 MaxAckPending: 10, 22011 }, 22012 }) 22013 if err == nil { 22014 t.Fatalf("stream update should have errored but didn't") 22015 } 22016 }) 22017 22018 t.Run("UpdateStreamErrorOnViolateConsumerInactiveThreshold", func(t *testing.T) { 22019 _, err := js.AddConsumer("test", &nats.ConsumerConfig{ 22020 Name: "UpdateStreamErrorOnViolateConsumerInactiveThreshold", 22021 InactiveThreshold: time.Second, 22022 }) 22023 require_NoError(t, err) 22024 22025 stream, err := acc.lookupStream("test") 22026 require_NoError(t, err) 22027 22028 err = stream.update(&StreamConfig{ 22029 Name: "test", 22030 Subjects: []string{"test.*"}, 22031 ConsumerLimits: StreamConsumerLimits{ 22032 InactiveThreshold: time.Second / 2, 22033 }, 22034 }) 22035 if err == nil { 22036 t.Fatalf("stream update should have errored but didn't") 22037 } 22038 }) 22039 } 22040 22041 func TestJetStreamSyncInterval(t *testing.T) { 22042 sd := t.TempDir() 22043 tmpl := ` 22044 listen: 127.0.0.1:-1 22045 jetstream: { 22046 store_dir: %q 22047 %s 22048 }` 22049 22050 for _, test := range []struct { 22051 name string 22052 sync string 22053 expected time.Duration 22054 always bool 22055 }{ 22056 {"Default", _EMPTY_, defaultSyncInterval, false}, 22057 {"10s", "sync_interval: 10s", time.Duration(10 * time.Second), false}, 22058 {"Always", "sync_interval: always", defaultSyncInterval, true}, 22059 } { 22060 t.Run(test.name, func(t *testing.T) { 22061 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, sd, test.sync))) 22062 s, _ := RunServerWithConfig(conf) 22063 defer s.Shutdown() 22064 22065 opts := s.getOpts() 22066 require_True(t, opts.SyncInterval == test.expected) 22067 22068 nc, js := jsClientConnect(t, s) 22069 defer nc.Close() 22070 22071 _, err := js.AddStream(&nats.StreamConfig{ 22072 Name: "TEST", 22073 Subjects: []string{"test.>"}, 22074 }) 22075 require_NoError(t, err) 22076 22077 mset, err := s.GlobalAccount().lookupStream("TEST") 22078 require_NoError(t, err) 22079 fs := mset.store.(*fileStore) 22080 fs.mu.RLock() 22081 fsSync := fs.fcfg.SyncInterval 22082 syncAlways := fs.fcfg.SyncAlways 22083 fs.mu.RUnlock() 22084 require_True(t, fsSync == test.expected) 22085 require_True(t, syncAlways == test.always) 22086 }) 22087 } 22088 } 22089 22090 func TestJetStreamFilteredSubjectUsesNewConsumerCreateSubject(t *testing.T) { 22091 s := RunBasicJetStreamServer(t) 22092 defer s.Shutdown() 22093 22094 nc, _ := jsClientConnect(t, s) 22095 defer nc.Close() 22096 22097 extEndpoint := make(chan *nats.Msg, 1) 22098 normalEndpoint := make(chan *nats.Msg, 1) 22099 22100 _, err := nc.ChanSubscribe(JSApiConsumerCreateEx, extEndpoint) 22101 require_NoError(t, err) 22102 22103 _, err = nc.ChanSubscribe(JSApiConsumerCreate, normalEndpoint) 22104 require_NoError(t, err) 22105 22106 testStreamSource := func(name string, shouldBeExtended bool, ss StreamSource) { 22107 t.Run(name, func(t *testing.T) { 22108 req := StreamConfig{ 22109 Name: name, 22110 Storage: MemoryStorage, 22111 Subjects: []string{fmt.Sprintf("foo.%s", name)}, 22112 Sources: []*StreamSource{&ss}, 22113 } 22114 reqJson, err := json.Marshal(req) 22115 require_NoError(t, err) 22116 22117 _, err = nc.Request(fmt.Sprintf(JSApiStreamCreateT, name), reqJson, time.Second) 22118 require_NoError(t, err) 22119 22120 select { 22121 case <-time.After(time.Second * 5): 22122 t.Fatalf("Timed out waiting for receive consumer create") 22123 case <-extEndpoint: 22124 if !shouldBeExtended { 22125 t.Fatalf("Expected normal consumer create, got extended") 22126 } 22127 case <-normalEndpoint: 22128 if shouldBeExtended { 22129 t.Fatalf("Expected extended consumer create, got normal") 22130 } 22131 } 22132 }) 22133 } 22134 22135 testStreamSource("OneFilterSubject", true, StreamSource{ 22136 Name: "source", 22137 FilterSubject: "bar.>", 22138 }) 22139 22140 testStreamSource("OneTransform", true, StreamSource{ 22141 Name: "source", 22142 SubjectTransforms: []SubjectTransformConfig{ 22143 { 22144 Source: "bar.one.>", 22145 Destination: "bar.two.>", 22146 }, 22147 }, 22148 }) 22149 22150 testStreamSource("TwoTransforms", false, StreamSource{ 22151 Name: "source", 22152 SubjectTransforms: []SubjectTransformConfig{ 22153 { 22154 Source: "bar.one.>", 22155 Destination: "bar.two.>", 22156 }, 22157 { 22158 Source: "baz.one.>", 22159 Destination: "baz.two.>", 22160 }, 22161 }, 22162 }) 22163 } 22164 22165 // Make sure when we downgrade history to a smaller number that the account info 22166 // is properly updated and all keys are still accessible. 22167 // There was a bug calculating next first that was not taking into account the dbit slots. 22168 func TestJetStreamKVReductionInHistory(t *testing.T) { 22169 s := RunBasicJetStreamServer(t) 22170 defer s.Shutdown() 22171 22172 nc, js := jsClientConnect(t, s) 22173 defer nc.Close() 22174 22175 startHistory := 4 22176 kv, err := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "TEST", History: uint8(startHistory)}) 22177 require_NoError(t, err) 22178 22179 numKeys, msg := 1000, bytes.Repeat([]byte("ABC"), 330) // ~1000bytes 22180 for { 22181 key := fmt.Sprintf("%X", rand.Intn(numKeys)+1) 22182 _, err = kv.Put(key, msg) 22183 require_NoError(t, err) 22184 status, err := kv.Status() 22185 require_NoError(t, err) 22186 if status.Values() >= uint64(startHistory*numKeys) { 22187 break 22188 } 22189 } 22190 info, err := js.AccountInfo() 22191 require_NoError(t, err) 22192 22193 checkAllKeys := func() { 22194 t.Helper() 22195 // Make sure we can retrieve all of the keys. 22196 keys, err := kv.Keys() 22197 require_NoError(t, err) 22198 require_Equal(t, len(keys), numKeys) 22199 for _, key := range keys { 22200 _, err := kv.Get(key) 22201 require_NoError(t, err) 22202 } 22203 } 22204 22205 // Quick sanity check. 22206 checkAllKeys() 22207 22208 si, err := js.StreamInfo("KV_TEST") 22209 require_NoError(t, err) 22210 // Adjust down to history of 1. 22211 cfg := si.Config 22212 cfg.MaxMsgsPerSubject = 1 22213 _, err = js.UpdateStream(&cfg) 22214 require_NoError(t, err) 22215 // Make sure the accounting was updated. 22216 ninfo, err := js.AccountInfo() 22217 require_NoError(t, err) 22218 require_True(t, info.Store > ninfo.Store) 22219 22220 // Make sure all keys still accessible. 22221 checkAllKeys() 22222 } 22223 22224 // Server issue 4685 22225 func TestJetStreamConsumerPendingForKV(t *testing.T) { 22226 for _, st := range []nats.StorageType{nats.FileStorage, nats.MemoryStorage} { 22227 t.Run(st.String(), func(t *testing.T) { 22228 s := RunBasicJetStreamServer(t) 22229 defer s.Shutdown() 22230 22231 nc, js := jsClientConnect(t, s) 22232 defer nc.Close() 22233 22234 _, err := js.AddStream(&nats.StreamConfig{ 22235 Name: "TEST", 22236 Subjects: []string{"test.>"}, 22237 Storage: st, 22238 MaxMsgsPerSubject: 10, 22239 Discard: nats.DiscardNew, 22240 }) 22241 require_NoError(t, err) 22242 22243 _, err = js.Publish("test.1", []byte("x")) 22244 require_NoError(t, err) 22245 22246 var msg *nats.Msg 22247 22248 // this is the detail that triggers the off by one, remove this code and all tests pass 22249 msg = nats.NewMsg("test.1") 22250 msg.Data = []byte("y") 22251 msg.Header.Add(nats.ExpectedLastSeqHdr, "1") 22252 _, err = js.PublishMsg(msg) 22253 require_NoError(t, err) 22254 22255 _, err = js.Publish("test.2", []byte("x")) 22256 require_NoError(t, err) 22257 _, err = js.Publish("test.3", []byte("x")) 22258 require_NoError(t, err) 22259 _, err = js.Publish("test.4", []byte("x")) 22260 require_NoError(t, err) 22261 _, err = js.Publish("test.5", []byte("x")) 22262 require_NoError(t, err) 22263 22264 nfo, err := js.StreamInfo("TEST", &nats.StreamInfoRequest{SubjectsFilter: ">"}) 22265 require_NoError(t, err) 22266 22267 require_Equal(t, len(nfo.State.Subjects), 5) 22268 22269 sub, err := js.SubscribeSync("test.>", nats.DeliverLastPerSubject()) 22270 require_NoError(t, err) 22271 22272 msg, err = sub.NextMsg(time.Second) 22273 require_NoError(t, err) 22274 meta, err := msg.Metadata() 22275 require_NoError(t, err) 22276 require_Equal(t, meta.NumPending, 4) 22277 }) 22278 } 22279 } 22280 22281 func TestJetStreamDirectGetBatch(t *testing.T) { 22282 s := RunBasicJetStreamServer(t) 22283 defer s.Shutdown() 22284 22285 nc, js := jsClientConnect(t, s) 22286 defer nc.Close() 22287 22288 _, err := js.AddStream(&nats.StreamConfig{ 22289 Name: "TEST", 22290 Subjects: []string{"foo.*"}, 22291 }) 22292 require_NoError(t, err) 22293 22294 // Add in messages 22295 for i := 0; i < 333; i++ { 22296 js.PublishAsync("foo.foo", []byte("HELLO")) 22297 js.PublishAsync("foo.bar", []byte("WORLD")) 22298 js.PublishAsync("foo.baz", []byte("AGAIN")) 22299 } 22300 select { 22301 case <-js.PublishAsyncComplete(): 22302 case <-time.After(5 * time.Second): 22303 t.Fatalf("Did not receive completion signal") 22304 } 22305 22306 // DirectGet is required for batch. Make sure we error correctly if not enabled. 22307 mreq := &JSApiMsgGetRequest{Seq: 1, Batch: 10} 22308 req, _ := json.Marshal(mreq) 22309 rr, err := nc.Request("$JS.API.STREAM.MSG.GET.TEST", req, time.Second) 22310 require_NoError(t, err) 22311 var resp JSApiMsgGetResponse 22312 json.Unmarshal(rr.Data, &resp) 22313 require_True(t, resp.Error != nil) 22314 require_Equal(t, resp.Error.Code, NewJSBadRequestError().Code) 22315 22316 // Update stream to support direct. 22317 _, err = js.UpdateStream(&nats.StreamConfig{ 22318 Name: "TEST", 22319 Subjects: []string{"foo.*"}, 22320 AllowDirect: true, 22321 }) 22322 require_NoError(t, err) 22323 22324 // Direct subjects. 22325 sendRequest := func(mreq *JSApiMsgGetRequest) *nats.Subscription { 22326 t.Helper() 22327 req, _ := json.Marshal(mreq) 22328 // We will get multiple responses so can't do normal request. 22329 reply := nats.NewInbox() 22330 sub, err := nc.SubscribeSync(reply) 22331 require_NoError(t, err) 22332 err = nc.PublishRequest("$JS.API.DIRECT.GET.TEST", reply, req) 22333 require_NoError(t, err) 22334 return sub 22335 } 22336 22337 // Batch sizes greater than 1 will have a nil message as the end marker. 22338 checkResponses := func(sub *nats.Subscription, numPendingStart int, expected ...string) { 22339 t.Helper() 22340 defer sub.Unsubscribe() 22341 checkSubsPending(t, sub, len(expected)) 22342 np := numPendingStart 22343 for i := 0; i < len(expected); i++ { 22344 msg, err := sub.NextMsg(10 * time.Millisecond) 22345 require_NoError(t, err) 22346 // If expected is _EMPTY_ that signals we expect a EOB marker. 22347 if subj := expected[i]; subj != _EMPTY_ { 22348 // Make sure subject is correct. 22349 require_Equal(t, expected[i], msg.Header.Get(JSSubject)) 22350 // Should have Data field non-zero 22351 require_True(t, len(msg.Data) > 0) 22352 // Check we have NumPending and its correct. 22353 require_Equal(t, strconv.Itoa(np), msg.Header.Get(JSNumPending)) 22354 np-- 22355 22356 } else { 22357 // Check for properly formatted EOB marker. 22358 // Should have no body. 22359 require_Equal(t, len(msg.Data), 0) 22360 // We mark status as 204 - No Content 22361 require_Equal(t, msg.Header.Get("Status"), "204") 22362 // Check description is EOB 22363 require_Equal(t, msg.Header.Get("Description"), "EOB") 22364 // Check we have NumPending and its correct. 22365 require_Equal(t, strconv.Itoa(np), msg.Header.Get(JSNumPending)) 22366 } 22367 } 22368 } 22369 22370 // Run some simple tests. 22371 sub := sendRequest(&JSApiMsgGetRequest{Seq: 1, Batch: 2}) 22372 checkResponses(sub, 999, "foo.foo", "foo.bar", _EMPTY_) 22373 22374 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, Batch: 3}) 22375 checkResponses(sub, 999, "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 22376 22377 // Test NextFor works 22378 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, Batch: 3, NextFor: "foo.*"}) 22379 checkResponses(sub, 999, "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 22380 22381 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, Batch: 3, NextFor: "foo.baz"}) 22382 checkResponses(sub, 333, "foo.baz", "foo.baz", "foo.baz", _EMPTY_) 22383 22384 // Test stopping early by starting at 997 with only 3 messages. 22385 sub = sendRequest(&JSApiMsgGetRequest{Seq: 997, Batch: 10, NextFor: "foo.*"}) 22386 checkResponses(sub, 3, "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 22387 } 22388 22389 func TestJetStreamDirectGetBatchMaxBytes(t *testing.T) { 22390 s := RunBasicJetStreamServer(t) 22391 defer s.Shutdown() 22392 22393 nc, js := jsClientConnect(t, s) 22394 defer nc.Close() 22395 22396 _, err := js.AddStream(&nats.StreamConfig{ 22397 Name: "TEST", 22398 Subjects: []string{"foo.*"}, 22399 AllowDirect: true, 22400 Compression: nats.S2Compression, 22401 }) 22402 require_NoError(t, err) 22403 22404 msg := bytes.Repeat([]byte("Z"), 512*1024) 22405 // Add in messages 22406 for i := 0; i < 333; i++ { 22407 js.PublishAsync("foo.foo", msg) 22408 js.PublishAsync("foo.bar", msg) 22409 js.PublishAsync("foo.baz", msg) 22410 } 22411 select { 22412 case <-js.PublishAsyncComplete(): 22413 case <-time.After(5 * time.Second): 22414 t.Fatalf("Did not receive completion signal") 22415 } 22416 22417 sendRequestAndCheck := func(mreq *JSApiMsgGetRequest, numExpected int) { 22418 t.Helper() 22419 req, _ := json.Marshal(mreq) 22420 // We will get multiple responses so can't do normal request. 22421 reply := nats.NewInbox() 22422 sub, err := nc.SubscribeSync(reply) 22423 require_NoError(t, err) 22424 defer sub.Unsubscribe() 22425 err = nc.PublishRequest("$JS.API.DIRECT.GET.TEST", reply, req) 22426 require_NoError(t, err) 22427 // Make sure we get correct number of responses. 22428 checkSubsPending(t, sub, numExpected) 22429 } 22430 22431 // Total msg size being sent back to us. 22432 msgSize := len(msg) + len("foo.foo") 22433 // We should get 1 msg and 1 EOB 22434 sendRequestAndCheck(&JSApiMsgGetRequest{Seq: 1, Batch: 3, MaxBytes: msgSize}, 2) 22435 22436 // Test NextFor tracks as well. 22437 sendRequestAndCheck(&JSApiMsgGetRequest{Seq: 1, NextFor: "foo.bar", Batch: 3, MaxBytes: 2 * msgSize}, 3) 22438 22439 // Now test no MaxBytes to inherit server max_num_pending. 22440 expected := (int(s.getOpts().MaxPending) / msgSize) + 1 22441 sendRequestAndCheck(&JSApiMsgGetRequest{Seq: 1, Batch: 200}, expected+1) 22442 } 22443 22444 func TestJetStreamMsgGetAsOfTime(t *testing.T) { 22445 s := RunBasicJetStreamServer(t) 22446 defer s.Shutdown() 22447 22448 nc, js := jsClientConnect(t, s) 22449 defer nc.Close() 22450 22451 _, err := js.AddStream(&nats.StreamConfig{ 22452 Name: "TEST", 22453 Subjects: []string{"foo.*"}, 22454 AllowDirect: true, 22455 }) 22456 require_NoError(t, err) 22457 22458 sendRequestAndCheck := func(mreq *JSApiMsgGetRequest, seq uint64, eerr error) { 22459 t.Helper() 22460 req, _ := json.Marshal(mreq) 22461 rep, err := nc.Request(fmt.Sprintf(JSApiMsgGetT, "TEST"), req, time.Second) 22462 require_NoError(t, err) 22463 var mrep JSApiMsgGetResponse 22464 err = json.Unmarshal(rep.Data, &mrep) 22465 require_NoError(t, err) 22466 if eerr != nil { 22467 require_Error(t, mrep.ToError(), eerr) 22468 return 22469 } 22470 require_NoError(t, mrep.ToError()) 22471 require_Equal(t, seq, mrep.Message.Sequence) 22472 } 22473 t0 := time.Now() 22474 22475 // Check for conflicting options. 22476 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, LastFor: "foo.1"}, 0, NewJSBadRequestError()) 22477 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, Seq: 1}, 0, NewJSBadRequestError()) 22478 22479 // Nothing exists yet in the stream. 22480 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 0, NewJSNoMessageFoundError()) 22481 22482 _, err = js.Publish("foo.1", nil) 22483 require_NoError(t, err) 22484 22485 // Try again with t0 and now it will find the first message. 22486 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 1, nil) 22487 22488 t1 := time.Now() 22489 _, err = js.Publish("foo.2", nil) 22490 require_NoError(t, err) 22491 22492 // At t0, first message will still be returned first. 22493 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 1, nil) 22494 // Unless we combine with NextFor... 22495 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, NextFor: "foo.2"}, 2, nil) 22496 22497 // At t1 (after first message), the second message will be returned. 22498 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t1}, 2, nil) 22499 22500 t2 := time.Now() 22501 // t2 is later than the last message so nothing will be found. 22502 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t2}, 0, NewJSNoMessageFoundError()) 22503 } 22504 22505 func TestJetStreamMsgDirectGetAsOfTime(t *testing.T) { 22506 s := RunBasicJetStreamServer(t) 22507 defer s.Shutdown() 22508 22509 nc, js := jsClientConnect(t, s) 22510 defer nc.Close() 22511 22512 _, err := js.AddStream(&nats.StreamConfig{ 22513 Name: "TEST", 22514 Subjects: []string{"foo.*"}, 22515 AllowDirect: true, 22516 }) 22517 require_NoError(t, err) 22518 22519 sendRequestAndCheck := func(mreq *JSApiMsgGetRequest, seq uint64, eerr string) { 22520 t.Helper() 22521 req, _ := json.Marshal(mreq) 22522 rep, err := nc.Request(fmt.Sprintf(JSDirectMsgGetT, "TEST"), req, time.Second) 22523 require_NoError(t, err) 22524 if eerr != "" { 22525 require_Equal(t, rep.Header.Get("Description"), eerr) 22526 return 22527 } 22528 22529 mseq, err := strconv.ParseUint(rep.Header.Get("Nats-Sequence"), 10, 64) 22530 require_NoError(t, err) 22531 require_Equal(t, seq, mseq) 22532 } 22533 t0 := time.Now() 22534 22535 // Check for conflicting options. 22536 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, LastFor: "foo.1"}, 0, "Bad Request") 22537 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, Seq: 1}, 0, "Bad Request") 22538 22539 // Nothing exists yet in the stream. 22540 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 0, "Message Not Found") 22541 22542 _, err = js.Publish("foo.1", nil) 22543 require_NoError(t, err) 22544 22545 // Try again with t0 and now it will find the first message. 22546 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 1, "") 22547 22548 t1 := time.Now() 22549 _, err = js.Publish("foo.2", nil) 22550 require_NoError(t, err) 22551 22552 // At t0, first message will still be returned first. 22553 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0}, 1, "") 22554 // Unless we combine with NextFor.. 22555 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t0, NextFor: "foo.2"}, 2, "") 22556 22557 // At t1 (after first message), the second message will be returned. 22558 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t1}, 2, "") 22559 22560 t2 := time.Now() 22561 // t2 is later than the last message so nothing will be found. 22562 sendRequestAndCheck(&JSApiMsgGetRequest{StartTime: &t2}, 0, "Message Not Found") 22563 } 22564 22565 func TestJetStreamConsumerNakThenAckFloorMove(t *testing.T) { 22566 s := RunBasicJetStreamServer(t) 22567 defer s.Shutdown() 22568 22569 nc, js := jsClientConnect(t, s) 22570 defer nc.Close() 22571 22572 _, err := js.AddStream(&nats.StreamConfig{ 22573 Name: "TEST", 22574 Subjects: []string{"foo"}, 22575 }) 22576 require_NoError(t, err) 22577 22578 for i := 0; i < 11; i++ { 22579 js.Publish("foo", []byte("OK")) 22580 } 22581 22582 sub, err := js.PullSubscribe("foo", "dlc", nats.AckWait(100*time.Millisecond)) 22583 require_NoError(t, err) 22584 22585 msgs, err := sub.Fetch(11) 22586 require_NoError(t, err) 22587 22588 // Nak first one 22589 msgs[0].Nak() 22590 22591 // Ack 2-10 22592 for i := 1; i < 10; i++ { 22593 msgs[i].AckSync() 22594 } 22595 // Hold onto last. 22596 lastMsg := msgs[10] 22597 22598 ci, err := sub.ConsumerInfo() 22599 require_NoError(t, err) 22600 22601 require_Equal(t, ci.AckFloor.Consumer, 0) 22602 require_Equal(t, ci.AckFloor.Stream, 0) 22603 require_Equal(t, ci.NumAckPending, 2) 22604 22605 // Grab first messsage again and ack this time. 22606 msgs, err = sub.Fetch(1) 22607 require_NoError(t, err) 22608 msgs[0].AckSync() 22609 22610 ci, err = sub.ConsumerInfo() 22611 require_NoError(t, err) 22612 22613 require_Equal(t, ci.Delivered.Consumer, 12) 22614 require_Equal(t, ci.Delivered.Stream, 11) 22615 require_Equal(t, ci.AckFloor.Consumer, 10) 22616 require_Equal(t, ci.AckFloor.Stream, 10) 22617 require_Equal(t, ci.NumAckPending, 1) 22618 22619 // Make sure when we ack last one we collapse the AckFloor.Consumer 22620 // with the higher delivered due to re-deliveries. 22621 lastMsg.AckSync() 22622 ci, err = sub.ConsumerInfo() 22623 require_NoError(t, err) 22624 22625 require_Equal(t, ci.Delivered.Consumer, 12) 22626 require_Equal(t, ci.Delivered.Stream, 11) 22627 require_Equal(t, ci.AckFloor.Consumer, 12) 22628 require_Equal(t, ci.AckFloor.Stream, 11) 22629 require_Equal(t, ci.NumAckPending, 0) 22630 } 22631 22632 func TestJetStreamSubjectFilteredPurgeClearsPendingAcks(t *testing.T) { 22633 s := RunBasicJetStreamServer(t) 22634 defer s.Shutdown() 22635 22636 nc, js := jsClientConnect(t, s) 22637 defer nc.Close() 22638 22639 _, err := js.AddStream(&nats.StreamConfig{ 22640 Name: "TEST", 22641 Subjects: []string{"foo", "bar"}, 22642 }) 22643 require_NoError(t, err) 22644 22645 for i := 0; i < 5; i++ { 22646 js.Publish("foo", []byte("OK")) 22647 js.Publish("bar", []byte("OK")) 22648 } 22649 22650 // Note that there are no subject filters here, this is deliberate 22651 // as previously the purge with filter code was checking for them. 22652 // We want to prove that unfiltered consumers also get purged. 22653 ci, err := js.AddConsumer("TEST", &nats.ConsumerConfig{ 22654 Name: "my_consumer", 22655 AckPolicy: nats.AckExplicitPolicy, 22656 MaxAckPending: 10, 22657 }) 22658 require_NoError(t, err) 22659 require_Equal(t, ci.NumPending, 10) 22660 require_Equal(t, ci.NumAckPending, 0) 22661 22662 sub, err := js.PullSubscribe(">", "", nats.Bind("TEST", "my_consumer")) 22663 require_NoError(t, err) 22664 22665 msgs, err := sub.Fetch(10) 22666 require_NoError(t, err) 22667 require_Len(t, len(msgs), 10) 22668 22669 ci, err = js.ConsumerInfo("TEST", "my_consumer") 22670 require_NoError(t, err) 22671 require_Equal(t, ci.NumPending, 0) 22672 require_Equal(t, ci.NumAckPending, 10) 22673 22674 require_NoError(t, js.PurgeStream("TEST", &nats.StreamPurgeRequest{ 22675 Subject: "foo", 22676 })) 22677 22678 ci, err = js.ConsumerInfo("TEST", "my_consumer") 22679 require_NoError(t, err) 22680 require_Equal(t, ci.NumPending, 0) 22681 require_Equal(t, ci.NumAckPending, 5) 22682 22683 for i := 0; i < 5; i++ { 22684 js.Publish("foo", []byte("OK")) 22685 } 22686 msgs, err = sub.Fetch(5) 22687 require_NoError(t, err) 22688 require_Len(t, len(msgs), 5) 22689 22690 ci, err = js.ConsumerInfo("TEST", "my_consumer") 22691 require_NoError(t, err) 22692 require_Equal(t, ci.NumPending, 0) 22693 require_Equal(t, ci.NumAckPending, 10) 22694 } 22695 22696 // Helper function for TestJetStreamConsumerPause*, TestJetStreamClusterConsumerPause*, TestJetStreamSuperClusterConsumerPause* 22697 func jsTestPause_CreateOrUpdateConsumer(t *testing.T, nc *nats.Conn, action ConsumerAction, stream string, cc ConsumerConfig) *JSApiConsumerCreateResponse { 22698 t.Helper() 22699 j, err := json.Marshal(CreateConsumerRequest{ 22700 Stream: stream, 22701 Config: cc, 22702 Action: action, 22703 }) 22704 require_NoError(t, err) 22705 subj := fmt.Sprintf("$JS.API.CONSUMER.CREATE.%s.%s", stream, cc.Name) 22706 m, err := nc.Request(subj, j, time.Second*3) 22707 require_NoError(t, err) 22708 var res JSApiConsumerCreateResponse 22709 require_NoError(t, json.Unmarshal(m.Data, &res)) 22710 require_True(t, res.Config != nil) 22711 return &res 22712 } 22713 22714 // Helper function for TestJetStreamConsumerPause*, TestJetStreamClusterConsumerPause*, TestJetStreamSuperClusterConsumerPause* 22715 func jsTestPause_PauseConsumer(t *testing.T, nc *nats.Conn, stream, consumer string, deadline time.Time) time.Time { 22716 t.Helper() 22717 j, err := json.Marshal(JSApiConsumerPauseRequest{ 22718 PauseUntil: deadline, 22719 }) 22720 require_NoError(t, err) 22721 subj := fmt.Sprintf("$JS.API.CONSUMER.PAUSE.%s.%s", stream, consumer) 22722 msg, err := nc.Request(subj, j, time.Second) 22723 require_NoError(t, err) 22724 var res JSApiConsumerPauseResponse 22725 require_NoError(t, json.Unmarshal(msg.Data, &res)) 22726 return res.PauseUntil 22727 } 22728 22729 func TestJetStreamConsumerPauseViaConfig(t *testing.T) { 22730 s := RunBasicJetStreamServer(t) 22731 defer s.Shutdown() 22732 22733 nc, js := jsClientConnect(t, s) 22734 defer nc.Close() 22735 22736 _, err := js.AddStream(&nats.StreamConfig{ 22737 Name: "TEST", 22738 Subjects: []string{"foo"}, 22739 }) 22740 require_NoError(t, err) 22741 22742 t.Run("CreateShouldSucceed", func(t *testing.T) { 22743 deadline := time.Now().Add(time.Hour) 22744 ci := jsTestPause_CreateOrUpdateConsumer(t, nc, ActionCreate, "TEST", ConsumerConfig{ 22745 Name: "my_consumer_1", 22746 PauseUntil: &deadline, 22747 }) 22748 require_True(t, ci != nil) 22749 require_True(t, ci.Config != nil) 22750 require_True(t, ci.Config.PauseUntil != nil) 22751 require_True(t, ci.Config.PauseUntil.Equal(deadline)) 22752 }) 22753 22754 t.Run("UpdateShouldFail", func(t *testing.T) { 22755 deadline := time.Now().Add(time.Hour) 22756 ci := jsTestPause_CreateOrUpdateConsumer(t, nc, ActionCreate, "TEST", ConsumerConfig{ 22757 Name: "my_consumer_2", 22758 }) 22759 require_True(t, ci != nil) 22760 require_True(t, ci.Config != nil) 22761 require_True(t, ci.Config.PauseUntil == nil || ci.Config.PauseUntil.IsZero()) 22762 22763 var cc ConsumerConfig 22764 j, err := json.Marshal(ci.Config) 22765 require_NoError(t, err) 22766 require_NoError(t, json.Unmarshal(j, &cc)) 22767 22768 pauseUntil := time.Now().Add(time.Hour) 22769 cc.PauseUntil = &pauseUntil 22770 ci2 := jsTestPause_CreateOrUpdateConsumer(t, nc, ActionUpdate, "TEST", cc) 22771 require_False(t, ci2.Config.PauseUntil != nil && ci2.Config.PauseUntil.Equal(deadline)) 22772 require_True(t, ci2.Config.PauseUntil == nil || ci2.Config.PauseUntil.Equal(time.Time{})) 22773 }) 22774 } 22775 22776 func TestJetStreamConsumerPauseViaEndpoint(t *testing.T) { 22777 s := RunBasicJetStreamServer(t) 22778 defer s.Shutdown() 22779 22780 nc, js := jsClientConnect(t, s) 22781 defer nc.Close() 22782 22783 _, err := js.AddStream(&nats.StreamConfig{ 22784 Name: "TEST", 22785 Subjects: []string{"push", "pull"}, 22786 }) 22787 require_NoError(t, err) 22788 22789 t.Run("PullConsumer", func(t *testing.T) { 22790 _, err := js.AddConsumer("TEST", &nats.ConsumerConfig{ 22791 Name: "pull_consumer", 22792 }) 22793 require_NoError(t, err) 22794 22795 sub, err := js.PullSubscribe("pull", "", nats.Bind("TEST", "pull_consumer")) 22796 require_NoError(t, err) 22797 22798 // This should succeed as there's no pause, so it definitely 22799 // shouldn't take more than a second. 22800 for i := 0; i < 10; i++ { 22801 _, err = js.Publish("pull", []byte("OK")) 22802 require_NoError(t, err) 22803 } 22804 msgs, err := sub.Fetch(10, nats.MaxWait(time.Second)) 22805 require_NoError(t, err) 22806 require_Equal(t, len(msgs), 10) 22807 22808 // Now we'll pause the consumer for 3 seconds. 22809 deadline := time.Now().Add(time.Second * 3) 22810 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "pull_consumer", deadline).Equal(deadline)) 22811 22812 // This should fail as we'll wait for only half of the deadline. 22813 for i := 0; i < 10; i++ { 22814 _, err = js.Publish("pull", []byte("OK")) 22815 require_NoError(t, err) 22816 } 22817 _, err = sub.Fetch(10, nats.MaxWait(time.Until(deadline)/2)) 22818 require_Error(t, err, nats.ErrTimeout) 22819 22820 // This should succeed after a short wait, and when we're done, 22821 // we should be after the deadline. 22822 msgs, err = sub.Fetch(10) 22823 require_NoError(t, err) 22824 require_Equal(t, len(msgs), 10) 22825 require_True(t, time.Now().After(deadline)) 22826 22827 // This should succeed as there's no pause, so it definitely 22828 // shouldn't take more than a second. 22829 for i := 0; i < 10; i++ { 22830 _, err = js.Publish("pull", []byte("OK")) 22831 require_NoError(t, err) 22832 } 22833 msgs, err = sub.Fetch(10, nats.MaxWait(time.Second)) 22834 require_NoError(t, err) 22835 require_Equal(t, len(msgs), 10) 22836 22837 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "pull_consumer", time.Time{}).Equal(time.Time{})) 22838 22839 // This should succeed as there's no pause, so it definitely 22840 // shouldn't take more than a second. 22841 for i := 0; i < 10; i++ { 22842 _, err = js.Publish("pull", []byte("OK")) 22843 require_NoError(t, err) 22844 } 22845 msgs, err = sub.Fetch(10, nats.MaxWait(time.Second)) 22846 require_NoError(t, err) 22847 require_Equal(t, len(msgs), 10) 22848 }) 22849 22850 t.Run("PushConsumer", func(t *testing.T) { 22851 ch := make(chan *nats.Msg, 100) 22852 _, err = js.ChanSubscribe("push", ch, nats.BindStream("TEST"), nats.ConsumerName("push_consumer")) 22853 require_NoError(t, err) 22854 22855 // This should succeed as there's no pause, so it definitely 22856 // shouldn't take more than a second. 22857 for i := 0; i < 10; i++ { 22858 _, err = js.Publish("push", []byte("OK")) 22859 require_NoError(t, err) 22860 } 22861 for i := 0; i < 10; i++ { 22862 msg := require_ChanRead(t, ch, time.Second) 22863 require_NotEqual(t, msg, nil) 22864 } 22865 22866 // Now we'll pause the consumer for 3 seconds. 22867 deadline := time.Now().Add(time.Second * 3) 22868 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "push_consumer", deadline).Equal(deadline)) 22869 22870 // This should succeed after a short wait, and when we're done, 22871 // we should be after the deadline. 22872 for i := 0; i < 10; i++ { 22873 _, err = js.Publish("push", []byte("OK")) 22874 require_NoError(t, err) 22875 } 22876 for i := 0; i < 10; i++ { 22877 msg := require_ChanRead(t, ch, time.Second*5) 22878 require_NotEqual(t, msg, nil) 22879 require_True(t, time.Now().After(deadline)) 22880 } 22881 22882 // This should succeed as there's no pause, so it definitely 22883 // shouldn't take more than a second. 22884 for i := 0; i < 10; i++ { 22885 _, err = js.Publish("push", []byte("OK")) 22886 require_NoError(t, err) 22887 } 22888 for i := 0; i < 10; i++ { 22889 msg := require_ChanRead(t, ch, time.Second) 22890 require_NotEqual(t, msg, nil) 22891 } 22892 22893 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "push_consumer", time.Time{}).Equal(time.Time{})) 22894 22895 // This should succeed as there's no pause, so it definitely 22896 // shouldn't take more than a second. 22897 for i := 0; i < 10; i++ { 22898 _, err = js.Publish("push", []byte("OK")) 22899 require_NoError(t, err) 22900 } 22901 for i := 0; i < 10; i++ { 22902 msg := require_ChanRead(t, ch, time.Second) 22903 require_NotEqual(t, msg, nil) 22904 } 22905 }) 22906 } 22907 22908 func TestJetStreamConsumerPauseResumeViaEndpoint(t *testing.T) { 22909 s := RunBasicJetStreamServer(t) 22910 defer s.Shutdown() 22911 22912 nc, js := jsClientConnect(t, s) 22913 defer nc.Close() 22914 22915 _, err := js.AddStream(&nats.StreamConfig{ 22916 Name: "TEST", 22917 Subjects: []string{"TEST"}, 22918 }) 22919 require_NoError(t, err) 22920 22921 _, err = js.AddConsumer("TEST", &nats.ConsumerConfig{ 22922 Name: "CONSUMER", 22923 }) 22924 require_NoError(t, err) 22925 22926 getConsumerInfo := func() ConsumerInfo { 22927 var ci ConsumerInfo 22928 infoResp, err := nc.Request("$JS.API.CONSUMER.INFO.TEST.CONSUMER", nil, time.Second) 22929 require_NoError(t, err) 22930 err = json.Unmarshal(infoResp.Data, &ci) 22931 require_NoError(t, err) 22932 return ci 22933 } 22934 22935 // Ensure we are not paused 22936 require_False(t, getConsumerInfo().Paused) 22937 22938 // Now we'll pause the consumer for 30 seconds. 22939 deadline := time.Now().Add(time.Second * 30) 22940 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "CONSUMER", deadline).Equal(deadline)) 22941 22942 // Ensure the consumer reflects being paused 22943 require_True(t, getConsumerInfo().Paused) 22944 22945 subj := fmt.Sprintf("$JS.API.CONSUMER.PAUSE.%s.%s", "TEST", "CONSUMER") 22946 _, err = nc.Request(subj, nil, time.Second) 22947 require_NoError(t, err) 22948 22949 // Ensure the consumer reflects being resumed 22950 require_False(t, getConsumerInfo().Paused) 22951 } 22952 22953 func TestJetStreamConsumerPauseHeartbeats(t *testing.T) { 22954 s := RunBasicJetStreamServer(t) 22955 defer s.Shutdown() 22956 22957 nc, js := jsClientConnect(t, s) 22958 defer nc.Close() 22959 22960 _, err := js.AddStream(&nats.StreamConfig{ 22961 Name: "TEST", 22962 Subjects: []string{"foo"}, 22963 }) 22964 require_NoError(t, err) 22965 22966 deadline := time.Now().Add(time.Hour) 22967 dsubj := "deliver_subj" 22968 22969 ci := jsTestPause_CreateOrUpdateConsumer(t, nc, ActionCreate, "TEST", ConsumerConfig{ 22970 Name: "my_consumer", 22971 PauseUntil: &deadline, 22972 Heartbeat: time.Millisecond * 100, 22973 DeliverSubject: dsubj, 22974 }) 22975 require_True(t, ci.Config.PauseUntil.Equal(deadline)) 22976 22977 ch := make(chan *nats.Msg, 10) 22978 _, err = nc.ChanSubscribe(dsubj, ch) 22979 require_NoError(t, err) 22980 22981 for i := 0; i < 20; i++ { 22982 msg := require_ChanRead(t, ch, time.Millisecond*200) 22983 require_Equal(t, msg.Header.Get("Status"), "100") 22984 require_Equal(t, msg.Header.Get("Description"), "Idle Heartbeat") 22985 } 22986 } 22987 22988 func TestJetStreamConsumerPauseAdvisories(t *testing.T) { 22989 s := RunBasicJetStreamServer(t) 22990 defer s.Shutdown() 22991 22992 nc, js := jsClientConnect(t, s) 22993 defer nc.Close() 22994 22995 checkAdvisory := func(msg *nats.Msg, shouldBePaused bool, deadline time.Time) { 22996 t.Helper() 22997 var advisory JSConsumerPauseAdvisory 22998 require_NoError(t, json.Unmarshal(msg.Data, &advisory)) 22999 require_Equal(t, advisory.Stream, "TEST") 23000 require_Equal(t, advisory.Consumer, "my_consumer") 23001 require_Equal(t, advisory.Paused, shouldBePaused) 23002 require_True(t, advisory.PauseUntil.Equal(deadline)) 23003 } 23004 23005 _, err := js.AddStream(&nats.StreamConfig{ 23006 Name: "TEST", 23007 Subjects: []string{"foo"}, 23008 }) 23009 require_NoError(t, err) 23010 23011 ch := make(chan *nats.Msg, 10) 23012 _, err = nc.ChanSubscribe(JSAdvisoryConsumerPausePre+".TEST.my_consumer", ch) 23013 require_NoError(t, err) 23014 23015 deadline := time.Now().Add(time.Second) 23016 jsTestPause_CreateOrUpdateConsumer(t, nc, ActionCreate, "TEST", ConsumerConfig{ 23017 Name: "my_consumer", 23018 PauseUntil: &deadline, 23019 }) 23020 23021 // First advisory should tell us that the consumer was paused 23022 // on creation. 23023 msg := require_ChanRead(t, ch, time.Second*2) 23024 checkAdvisory(msg, true, deadline) 23025 23026 // The second one for the unpause. 23027 msg = require_ChanRead(t, ch, time.Second*2) 23028 checkAdvisory(msg, false, deadline) 23029 23030 // Now we'll pause the consumer using the API. 23031 deadline = time.Now().Add(time.Second) 23032 require_True(t, jsTestPause_PauseConsumer(t, nc, "TEST", "my_consumer", deadline).Equal(deadline)) 23033 23034 // Third advisory should tell us about the pause via the API. 23035 msg = require_ChanRead(t, ch, time.Second*2) 23036 checkAdvisory(msg, true, deadline) 23037 23038 // Finally that should unpause. 23039 msg = require_ChanRead(t, ch, time.Second*2) 23040 checkAdvisory(msg, false, deadline) 23041 } 23042 23043 func TestJetStreamConsumerSurvivesRestart(t *testing.T) { 23044 s := RunBasicJetStreamServer(t) 23045 defer s.Shutdown() 23046 23047 nc, js := jsClientConnect(t, s) 23048 defer nc.Close() 23049 23050 _, err := js.AddStream(&nats.StreamConfig{ 23051 Name: "TEST", 23052 Subjects: []string{"foo"}, 23053 }) 23054 require_NoError(t, err) 23055 23056 deadline := time.Now().Add(time.Hour) 23057 jsTestPause_CreateOrUpdateConsumer(t, nc, ActionCreate, "TEST", ConsumerConfig{ 23058 Name: "my_consumer", 23059 PauseUntil: &deadline, 23060 }) 23061 23062 sd := s.JetStreamConfig().StoreDir 23063 s.Shutdown() 23064 s = RunJetStreamServerOnPort(-1, sd) 23065 defer s.Shutdown() 23066 23067 stream, err := s.gacc.lookupStream("TEST") 23068 require_NoError(t, err) 23069 23070 consumer := stream.lookupConsumer("my_consumer") 23071 require_NotEqual(t, consumer, nil) 23072 23073 consumer.mu.RLock() 23074 timer := consumer.uptmr 23075 consumer.mu.RUnlock() 23076 require_True(t, timer != nil) 23077 } 23078 23079 func TestJetStreamDirectGetMulti(t *testing.T) { 23080 cases := []struct { 23081 name string 23082 cfg *nats.StreamConfig 23083 }{ 23084 {name: "MemoryStore", 23085 cfg: &nats.StreamConfig{ 23086 Name: "TEST", 23087 Subjects: []string{"foo.*"}, 23088 AllowDirect: true, 23089 Storage: nats.MemoryStorage, 23090 }}, 23091 {name: "FileStore", 23092 cfg: &nats.StreamConfig{ 23093 Name: "TEST", 23094 Subjects: []string{"foo.*"}, 23095 AllowDirect: true, 23096 }}, 23097 } 23098 for _, c := range cases { 23099 t.Run(c.name, func(t *testing.T) { 23100 23101 s := RunBasicJetStreamServer(t) 23102 defer s.Shutdown() 23103 23104 nc, js := jsClientConnect(t, s) 23105 defer nc.Close() 23106 23107 _, err := js.AddStream(c.cfg) 23108 require_NoError(t, err) 23109 23110 // Add in messages 23111 for i := 0; i < 33; i++ { 23112 js.PublishAsync("foo.foo", []byte(fmt.Sprintf("HELLO-%d", i))) 23113 js.PublishAsync("foo.bar", []byte(fmt.Sprintf("WORLD-%d", i))) 23114 js.PublishAsync("foo.baz", []byte(fmt.Sprintf("AGAIN-%d", i))) 23115 } 23116 select { 23117 case <-js.PublishAsyncComplete(): 23118 case <-time.After(5 * time.Second): 23119 t.Fatalf("Did not receive completion signal") 23120 } 23121 23122 // Direct subjects. 23123 sendRequest := func(mreq *JSApiMsgGetRequest) *nats.Subscription { 23124 t.Helper() 23125 req, _ := json.Marshal(mreq) 23126 // We will get multiple responses so can't do normal request. 23127 reply := nats.NewInbox() 23128 sub, err := nc.SubscribeSync(reply) 23129 require_NoError(t, err) 23130 err = nc.PublishRequest("$JS.API.DIRECT.GET.TEST", reply, req) 23131 require_NoError(t, err) 23132 return sub 23133 } 23134 23135 // Subject / Sequence pair 23136 type p struct { 23137 subj string 23138 seq int 23139 } 23140 var eob p 23141 23142 // Multi-Get will have a nil message as the end marker regardless. 23143 checkResponses := func(sub *nats.Subscription, numPendingStart int, expected ...p) { 23144 t.Helper() 23145 defer sub.Unsubscribe() 23146 checkSubsPending(t, sub, len(expected)) 23147 np := numPendingStart 23148 for i := 0; i < len(expected); i++ { 23149 msg, err := sub.NextMsg(10 * time.Millisecond) 23150 require_NoError(t, err) 23151 // If expected is _EMPTY_ that signals we expect a EOB marker. 23152 if subj := expected[i].subj; subj != _EMPTY_ { 23153 // Make sure subject is correct. 23154 require_Equal(t, subj, msg.Header.Get(JSSubject)) 23155 // Make sure sequence is correct. 23156 require_Equal(t, strconv.Itoa(expected[i].seq), msg.Header.Get(JSSequence)) 23157 // Should have Data field non-zero 23158 require_True(t, len(msg.Data) > 0) 23159 // Check we have NumPending and its correct. 23160 require_Equal(t, strconv.Itoa(np), msg.Header.Get(JSNumPending)) 23161 if np > 0 { 23162 np-- 23163 } 23164 } else { 23165 // Check for properly formatted EOB marker. 23166 // Should have no body. 23167 require_Equal(t, len(msg.Data), 0) 23168 // We mark status as 204 - No Content 23169 require_Equal(t, msg.Header.Get("Status"), "204") 23170 // Check description is EOB 23171 require_Equal(t, msg.Header.Get("Description"), "EOB") 23172 // Check we have NumPending and its correct. 23173 require_Equal(t, strconv.Itoa(np), msg.Header.Get(JSNumPending)) 23174 } 23175 } 23176 } 23177 23178 sub := sendRequest(&JSApiMsgGetRequest{MultiLastFor: []string{"foo.*"}}) 23179 checkResponses(sub, 2, p{"foo.foo", 97}, p{"foo.bar", 98}, p{"foo.baz", 99}, eob) 23180 // Check with UpToSeq 23181 sub = sendRequest(&JSApiMsgGetRequest{MultiLastFor: []string{"foo.*"}, UpToSeq: 3}) 23182 checkResponses(sub, 2, p{"foo.foo", 1}, p{"foo.bar", 2}, p{"foo.baz", 3}, eob) 23183 23184 // Test No Results. 23185 sub = sendRequest(&JSApiMsgGetRequest{MultiLastFor: []string{"bar.*"}}) 23186 checkSubsPending(t, sub, 1) 23187 msg, err := sub.NextMsg(10 * time.Millisecond) 23188 require_NoError(t, err) 23189 // Check for properly formatted No Results. 23190 // Should have no body. 23191 require_Equal(t, len(msg.Data), 0) 23192 // We mark status as 204 - No Content 23193 require_Equal(t, msg.Header.Get("Status"), "404") 23194 // Check description is No Results 23195 require_Equal(t, msg.Header.Get("Description"), "No Results") 23196 }) 23197 } 23198 } 23199 23200 func TestJetStreamDirectGetMultiUpToTime(t *testing.T) { 23201 s := RunBasicJetStreamServer(t) 23202 defer s.Shutdown() 23203 23204 nc, js := jsClientConnect(t, s) 23205 defer nc.Close() 23206 23207 _, err := js.AddStream(&nats.StreamConfig{ 23208 Name: "TEST", 23209 Subjects: []string{"foo.*"}, 23210 AllowDirect: true, 23211 }) 23212 require_NoError(t, err) 23213 23214 js.Publish("foo.foo", []byte("1")) 23215 js.Publish("foo.bar", []byte("1")) 23216 js.Publish("foo.baz", []byte("1")) 23217 start := time.Now() 23218 time.Sleep(time.Second) 23219 js.Publish("foo.foo", []byte("2")) 23220 js.Publish("foo.bar", []byte("2")) 23221 js.Publish("foo.baz", []byte("2")) 23222 mid := time.Now() 23223 time.Sleep(time.Second) 23224 js.Publish("foo.foo", []byte("3")) 23225 js.Publish("foo.bar", []byte("3")) 23226 js.Publish("foo.baz", []byte("3")) 23227 end := time.Now() 23228 23229 // Direct subjects. 23230 sendRequest := func(mreq *JSApiMsgGetRequest) *nats.Subscription { 23231 t.Helper() 23232 req, _ := json.Marshal(mreq) 23233 // We will get multiple responses so can't do normal request. 23234 reply := nats.NewInbox() 23235 sub, err := nc.SubscribeSync(reply) 23236 require_NoError(t, err) 23237 err = nc.PublishRequest("$JS.API.DIRECT.GET.TEST", reply, req) 23238 require_NoError(t, err) 23239 return sub 23240 } 23241 23242 checkResponses := func(sub *nats.Subscription, val string, expected ...string) { 23243 t.Helper() 23244 defer sub.Unsubscribe() 23245 checkSubsPending(t, sub, len(expected)) 23246 for i := 0; i < len(expected); i++ { 23247 msg, err := sub.NextMsg(10 * time.Millisecond) 23248 require_NoError(t, err) 23249 // If expected is _EMPTY_ that signals we expect a EOB marker. 23250 if subj := expected[i]; subj != _EMPTY_ { 23251 // Make sure subject is correct. 23252 require_Equal(t, subj, msg.Header.Get(JSSubject)) 23253 // Should have Data field non-zero 23254 require_True(t, len(msg.Data) > 0) 23255 // Make sure the value matches. 23256 require_Equal(t, string(msg.Data), val) 23257 } 23258 } 23259 } 23260 23261 // Make sure you can't set both. 23262 sub := sendRequest(&JSApiMsgGetRequest{Seq: 1, MultiLastFor: []string{"foo.*"}, UpToSeq: 3, UpToTime: &start}) 23263 checkSubsPending(t, sub, 1) 23264 msg, err := sub.NextMsg(10 * time.Millisecond) 23265 require_NoError(t, err) 23266 // Check for properly formatted No Results. 23267 // Should have no body. 23268 require_Equal(t, len(msg.Data), 0) 23269 // We mark status as 204 - No Content 23270 require_Equal(t, msg.Header.Get("Status"), "408") 23271 // Check description is No Results 23272 require_Equal(t, msg.Header.Get("Description"), "Bad Request") 23273 23274 // Valid responses. 23275 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, MultiLastFor: []string{"foo.*"}, UpToTime: &start}) 23276 checkResponses(sub, "1", "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 23277 23278 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, MultiLastFor: []string{"foo.*"}, UpToTime: &mid}) 23279 checkResponses(sub, "2", "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 23280 23281 sub = sendRequest(&JSApiMsgGetRequest{Seq: 1, MultiLastFor: []string{"foo.*"}, UpToTime: &end}) 23282 checkResponses(sub, "3", "foo.foo", "foo.bar", "foo.baz", _EMPTY_) 23283 } 23284 23285 func TestJetStreamDirectGetMultiMaxAllowed(t *testing.T) { 23286 s := RunBasicJetStreamServer(t) 23287 defer s.Shutdown() 23288 23289 nc, js := jsClientConnect(t, s) 23290 defer nc.Close() 23291 23292 _, err := js.AddStream(&nats.StreamConfig{ 23293 Name: "TEST", 23294 Subjects: []string{"foo.*"}, 23295 AllowDirect: true, 23296 }) 23297 require_NoError(t, err) 23298 23299 // from stream.go - const maxAllowedResponses = 1024, so max sure > 1024 23300 // Add in messages 23301 for i := 1; i <= 1025; i++ { 23302 js.PublishAsync(fmt.Sprintf("foo.%d", i), []byte("OK")) 23303 } 23304 select { 23305 case <-js.PublishAsyncComplete(): 23306 case <-time.After(5 * time.Second): 23307 t.Fatalf("Did not receive completion signal") 23308 } 23309 23310 req, _ := json.Marshal(&JSApiMsgGetRequest{Seq: 1, MultiLastFor: []string{"foo.*"}}) 23311 msg, err := nc.Request("$JS.API.DIRECT.GET.TEST", req, time.Second) 23312 require_NoError(t, err) 23313 23314 // Check for properly formatted Too Many Results error. 23315 // Should have no body. 23316 require_Equal(t, len(msg.Data), 0) 23317 // We mark status as 413 - Too Many Results 23318 require_Equal(t, msg.Header.Get("Status"), "413") 23319 // Check description is No Results 23320 require_Equal(t, msg.Header.Get("Description"), "Too Many Results") 23321 } 23322 23323 func TestJetStreamDirectGetMultiPaging(t *testing.T) { 23324 s := RunBasicJetStreamServer(t) 23325 defer s.Shutdown() 23326 23327 nc, js := jsClientConnect(t, s) 23328 defer nc.Close() 23329 23330 _, err := js.AddStream(&nats.StreamConfig{ 23331 Name: "TEST", 23332 Subjects: []string{"foo.*"}, 23333 AllowDirect: true, 23334 }) 23335 require_NoError(t, err) 23336 23337 // We will queue up 500 messages, each 512k big and request them for a multi-get. 23338 // This will not hit the max allowed limit of 1024, but will bump up against max bytes and only return partial results. 23339 // We want to make sure we can pick up where we left off. 23340 23341 // Add in messages 23342 data, sent := bytes.Repeat([]byte("Z"), 512*1024), 500 23343 for i := 1; i <= sent; i++ { 23344 js.PublishAsync(fmt.Sprintf("foo.%d", i), data) 23345 } 23346 select { 23347 case <-js.PublishAsyncComplete(): 23348 case <-time.After(5 * time.Second): 23349 t.Fatalf("Did not receive completion signal") 23350 } 23351 // Wait for all replicas to be correct. 23352 time.Sleep(time.Second) 23353 23354 // Direct subjects. 23355 sendRequest := func(mreq *JSApiMsgGetRequest) *nats.Subscription { 23356 t.Helper() 23357 req, _ := json.Marshal(mreq) 23358 // We will get multiple responses so can't do normal request. 23359 reply := nats.NewInbox() 23360 sub, err := nc.SubscribeSync(reply) 23361 require_NoError(t, err) 23362 err = nc.PublishRequest("$JS.API.DIRECT.GET.TEST", reply, req) 23363 require_NoError(t, err) 23364 return sub 23365 } 23366 23367 // Setup variables that control procesPartial 23368 start, seq, np, b, bsz := 1, 1, sent-1, 0, 128 23369 23370 processPartial := func(expected int) { 23371 t.Helper() 23372 sub := sendRequest(&JSApiMsgGetRequest{Seq: uint64(start), Batch: b, MultiLastFor: []string{"foo.*"}}) 23373 checkSubsPending(t, sub, expected) 23374 // Check partial. 23375 // We should receive seqs seq-(seq+bsz-1) 23376 for ; seq < start+(expected-1); seq++ { 23377 msg, err := sub.NextMsg(10 * time.Millisecond) 23378 require_NoError(t, err) 23379 // Make sure sequence is correct. 23380 require_Equal(t, strconv.Itoa(int(seq)), msg.Header.Get(JSSequence)) 23381 // Check we have NumPending and its correct. 23382 require_Equal(t, strconv.Itoa(int(np)), msg.Header.Get(JSNumPending)) 23383 if np > 0 { 23384 np-- 23385 } 23386 } 23387 // Now check EOB 23388 msg, err := sub.NextMsg(10 * time.Millisecond) 23389 require_NoError(t, err) 23390 // We mark status as 204 - No Content 23391 require_Equal(t, msg.Header.Get("Status"), "204") 23392 // Check description is EOB 23393 require_Equal(t, msg.Header.Get("Description"), "EOB") 23394 // Check we have NumPending and its correct. 23395 require_Equal(t, strconv.Itoa(np), msg.Header.Get(JSNumPending)) 23396 // Check we have LastSequence and its correct. 23397 require_Equal(t, strconv.Itoa(seq-1), msg.Header.Get(JSLastSequence)) 23398 // Check we have UpToSequence and its correct. 23399 require_Equal(t, strconv.Itoa(sent), msg.Header.Get(JSUpToSequence)) 23400 // Update start 23401 start = seq 23402 } 23403 23404 processPartial(bsz + 1) // 128 + EOB 23405 processPartial(bsz + 1) // 128 + EOB 23406 processPartial(bsz + 1) // 128 + EOB 23407 // Last one will be a partial block. 23408 processPartial(116 + 1) 23409 23410 // Now reset and test that batch is honored as well. 23411 start, seq, np, b = 1, 1, sent-1, 100 23412 for i := 0; i < 5; i++ { 23413 processPartial(b + 1) // 100 + EOB 23414 } 23415 }