get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/memstore_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 package server 15 16 import ( 17 "bytes" 18 "errors" 19 "fmt" 20 "math/rand" 21 "reflect" 22 "testing" 23 "time" 24 ) 25 26 func TestMemStoreBasics(t *testing.T) { 27 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 28 require_NoError(t, err) 29 defer ms.Stop() 30 31 subj, msg := "foo", []byte("Hello World") 32 now := time.Now().UnixNano() 33 if seq, ts, err := ms.StoreMsg(subj, nil, msg); err != nil { 34 t.Fatalf("Error storing msg: %v", err) 35 } else if seq != 1 { 36 t.Fatalf("Expected sequence to be 1, got %d", seq) 37 } else if ts < now || ts > now+int64(time.Millisecond) { 38 t.Fatalf("Expected timestamp to be current, got %v", ts-now) 39 } 40 41 state := ms.State() 42 if state.Msgs != 1 { 43 t.Fatalf("Expected 1 msg, got %d", state.Msgs) 44 } 45 expectedSize := memStoreMsgSize(subj, nil, msg) 46 if state.Bytes != expectedSize { 47 t.Fatalf("Expected %d bytes, got %d", expectedSize, state.Bytes) 48 } 49 sm, err := ms.LoadMsg(1, nil) 50 if err != nil { 51 t.Fatalf("Unexpected error looking up msg: %v", err) 52 } 53 if sm.subj != subj { 54 t.Fatalf("Subjects don't match, original %q vs %q", subj, sm.subj) 55 } 56 if !bytes.Equal(sm.msg, msg) { 57 t.Fatalf("Msgs don't match, original %q vs %q", msg, sm.msg) 58 } 59 } 60 61 func TestMemStoreMsgLimit(t *testing.T) { 62 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage, MaxMsgs: 10}) 63 require_NoError(t, err) 64 defer ms.Stop() 65 66 subj, msg := "foo", []byte("Hello World") 67 for i := 0; i < 10; i++ { 68 ms.StoreMsg(subj, nil, msg) 69 } 70 state := ms.State() 71 if state.Msgs != 10 { 72 t.Fatalf("Expected %d msgs, got %d", 10, state.Msgs) 73 } 74 if _, _, err := ms.StoreMsg(subj, nil, msg); err != nil { 75 t.Fatalf("Error storing msg: %v", err) 76 } 77 state = ms.State() 78 if state.Msgs != 10 { 79 t.Fatalf("Expected %d msgs, got %d", 10, state.Msgs) 80 } 81 if state.LastSeq != 11 { 82 t.Fatalf("Expected the last sequence to be 11 now, but got %d", state.LastSeq) 83 } 84 if state.FirstSeq != 2 { 85 t.Fatalf("Expected the first sequence to be 2 now, but got %d", state.FirstSeq) 86 } 87 // Make sure we can not lookup seq 1. 88 if _, err := ms.LoadMsg(1, nil); err == nil { 89 t.Fatalf("Expected error looking up seq 1 but got none") 90 } 91 } 92 93 func TestMemStoreBytesLimit(t *testing.T) { 94 subj, msg := "foo", make([]byte, 512) 95 storedMsgSize := memStoreMsgSize(subj, nil, msg) 96 97 toStore := uint64(1024) 98 maxBytes := storedMsgSize * toStore 99 100 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage, MaxBytes: int64(maxBytes)}) 101 require_NoError(t, err) 102 defer ms.Stop() 103 104 for i := uint64(0); i < toStore; i++ { 105 ms.StoreMsg(subj, nil, msg) 106 } 107 state := ms.State() 108 if state.Msgs != toStore { 109 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 110 } 111 if state.Bytes != storedMsgSize*toStore { 112 t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes) 113 } 114 115 // Now send 10 more and check that bytes limit enforced. 116 for i := 0; i < 10; i++ { 117 if _, _, err := ms.StoreMsg(subj, nil, msg); err != nil { 118 t.Fatalf("Error storing msg: %v", err) 119 } 120 } 121 state = ms.State() 122 if state.Msgs != toStore { 123 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 124 } 125 if state.Bytes != storedMsgSize*toStore { 126 t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes) 127 } 128 if state.FirstSeq != 11 { 129 t.Fatalf("Expected first sequence to be 11, got %d", state.FirstSeq) 130 } 131 if state.LastSeq != toStore+10 { 132 t.Fatalf("Expected last sequence to be %d, got %d", toStore+10, state.LastSeq) 133 } 134 } 135 136 // https://github.com/nats-io/nats-server/issues/4771 137 func TestMemStoreBytesLimitWithDiscardNew(t *testing.T) { 138 subj, msg := "tiny", make([]byte, 7) 139 storedMsgSize := memStoreMsgSize(subj, nil, msg) 140 141 toStore := uint64(3) 142 maxBytes := 100 143 144 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage, MaxBytes: int64(maxBytes), Discard: DiscardNew}) 145 require_NoError(t, err) 146 defer ms.Stop() 147 148 // Now send 10 messages and check that bytes limit enforced. 149 for i := 0; i < 10; i++ { 150 _, _, err := ms.StoreMsg(subj, nil, msg) 151 if i < int(toStore) { 152 if err != nil { 153 t.Fatalf("Error storing msg: %v", err) 154 } 155 } else if !errors.Is(err, ErrMaxBytes) { 156 t.Fatalf("Storing msg should result in: %v", ErrMaxBytes) 157 } 158 } 159 state := ms.State() 160 if state.Msgs != toStore { 161 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 162 } 163 if state.Bytes != storedMsgSize*toStore { 164 t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes) 165 } 166 } 167 168 func TestMemStoreAgeLimit(t *testing.T) { 169 maxAge := 10 * time.Millisecond 170 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage, MaxAge: maxAge}) 171 require_NoError(t, err) 172 defer ms.Stop() 173 174 // Store some messages. Does not really matter how many. 175 subj, msg := "foo", []byte("Hello World") 176 toStore := 100 177 for i := 0; i < toStore; i++ { 178 ms.StoreMsg(subj, nil, msg) 179 } 180 state := ms.State() 181 if state.Msgs != uint64(toStore) { 182 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 183 } 184 checkExpired := func(t *testing.T) { 185 t.Helper() 186 checkFor(t, time.Second, maxAge, func() error { 187 state = ms.State() 188 if state.Msgs != 0 { 189 return fmt.Errorf("Expected no msgs, got %d", state.Msgs) 190 } 191 if state.Bytes != 0 { 192 return fmt.Errorf("Expected no bytes, got %d", state.Bytes) 193 } 194 return nil 195 }) 196 } 197 // Let them expire 198 checkExpired(t) 199 // Now add some more and make sure that timer will fire again. 200 for i := 0; i < toStore; i++ { 201 ms.StoreMsg(subj, nil, msg) 202 } 203 state = ms.State() 204 if state.Msgs != uint64(toStore) { 205 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 206 } 207 checkExpired(t) 208 } 209 210 func TestMemStoreTimeStamps(t *testing.T) { 211 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 212 require_NoError(t, err) 213 defer ms.Stop() 214 215 last := time.Now().UnixNano() 216 subj, msg := "foo", []byte("Hello World") 217 for i := 0; i < 10; i++ { 218 time.Sleep(5 * time.Microsecond) 219 ms.StoreMsg(subj, nil, msg) 220 } 221 var smv StoreMsg 222 for seq := uint64(1); seq <= 10; seq++ { 223 sm, err := ms.LoadMsg(seq, &smv) 224 if err != nil { 225 t.Fatalf("Unexpected error looking up msg: %v", err) 226 } 227 // These should be different 228 if sm.ts <= last { 229 t.Fatalf("Expected different timestamps, got %v", sm.ts) 230 } 231 last = sm.ts 232 } 233 } 234 235 func TestMemStorePurge(t *testing.T) { 236 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 237 require_NoError(t, err) 238 defer ms.Stop() 239 240 subj, msg := "foo", []byte("Hello World") 241 for i := 0; i < 10; i++ { 242 ms.StoreMsg(subj, nil, msg) 243 } 244 if state := ms.State(); state.Msgs != 10 { 245 t.Fatalf("Expected 10 msgs, got %d", state.Msgs) 246 } 247 ms.Purge() 248 if state := ms.State(); state.Msgs != 0 { 249 t.Fatalf("Expected no msgs, got %d", state.Msgs) 250 } 251 } 252 253 func TestMemStoreCompact(t *testing.T) { 254 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 255 require_NoError(t, err) 256 defer ms.Stop() 257 258 subj, msg := "foo", []byte("Hello World") 259 for i := 0; i < 10; i++ { 260 ms.StoreMsg(subj, nil, msg) 261 } 262 if state := ms.State(); state.Msgs != 10 { 263 t.Fatalf("Expected 10 msgs, got %d", state.Msgs) 264 } 265 n, err := ms.Compact(6) 266 if err != nil { 267 t.Fatalf("Unexpected error: %v", err) 268 } 269 if n != 5 { 270 t.Fatalf("Expected to have purged 5 msgs, got %d", n) 271 } 272 state := ms.State() 273 if state.Msgs != 5 { 274 t.Fatalf("Expected 5 msgs, got %d", state.Msgs) 275 } 276 if state.FirstSeq != 6 { 277 t.Fatalf("Expected first seq of 6, got %d", state.FirstSeq) 278 } 279 // Now test that compact will also reset first if seq > last 280 n, err = ms.Compact(100) 281 if err != nil { 282 t.Fatalf("Unexpected error: %v", err) 283 } 284 if n != 5 { 285 t.Fatalf("Expected to have purged 5 msgs, got %d", n) 286 } 287 if state = ms.State(); state.FirstSeq != 100 { 288 t.Fatalf("Expected first seq of 100, got %d", state.FirstSeq) 289 } 290 } 291 292 func TestMemStoreEraseMsg(t *testing.T) { 293 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 294 require_NoError(t, err) 295 defer ms.Stop() 296 297 subj, msg := "foo", []byte("Hello World") 298 ms.StoreMsg(subj, nil, msg) 299 sm, err := ms.LoadMsg(1, nil) 300 if err != nil { 301 t.Fatalf("Unexpected error looking up msg: %v", err) 302 } 303 if !bytes.Equal(msg, sm.msg) { 304 t.Fatalf("Expected same msg, got %q vs %q", sm.msg, msg) 305 } 306 if removed, _ := ms.EraseMsg(1); !removed { 307 t.Fatalf("Expected erase msg to return success") 308 } 309 } 310 311 func TestMemStoreMsgHeaders(t *testing.T) { 312 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 313 require_NoError(t, err) 314 defer ms.Stop() 315 316 subj, hdr, msg := "foo", []byte("name:derek"), []byte("Hello World") 317 if sz := int(memStoreMsgSize(subj, hdr, msg)); sz != (len(subj) + len(hdr) + len(msg) + 16) { 318 t.Fatalf("Wrong size for stored msg with header") 319 } 320 ms.StoreMsg(subj, hdr, msg) 321 sm, err := ms.LoadMsg(1, nil) 322 if err != nil { 323 t.Fatalf("Unexpected error looking up msg: %v", err) 324 } 325 if !bytes.Equal(msg, sm.msg) { 326 t.Fatalf("Expected same msg, got %q vs %q", sm.msg, msg) 327 } 328 if !bytes.Equal(hdr, sm.hdr) { 329 t.Fatalf("Expected same hdr, got %q vs %q", sm.hdr, hdr) 330 } 331 if removed, _ := ms.EraseMsg(1); !removed { 332 t.Fatalf("Expected erase msg to return success") 333 } 334 } 335 336 func TestMemStoreStreamStateDeleted(t *testing.T) { 337 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 338 require_NoError(t, err) 339 defer ms.Stop() 340 341 subj, toStore := "foo", uint64(10) 342 for i := uint64(1); i <= toStore; i++ { 343 msg := []byte(fmt.Sprintf("[%08d] Hello World!", i)) 344 if _, _, err := ms.StoreMsg(subj, nil, msg); err != nil { 345 t.Fatalf("Error storing msg: %v", err) 346 } 347 } 348 state := ms.State() 349 if len(state.Deleted) != 0 { 350 t.Fatalf("Expected deleted to be empty") 351 } 352 // Now remove some interior messages. 353 var expected []uint64 354 for seq := uint64(2); seq < toStore; seq += 2 { 355 ms.RemoveMsg(seq) 356 expected = append(expected, seq) 357 } 358 state = ms.State() 359 if !reflect.DeepEqual(state.Deleted, expected) { 360 t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted) 361 } 362 // Now fill the gap by deleting 1 and 3 363 ms.RemoveMsg(1) 364 ms.RemoveMsg(3) 365 expected = expected[2:] 366 state = ms.State() 367 if !reflect.DeepEqual(state.Deleted, expected) { 368 t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted) 369 } 370 if state.FirstSeq != 5 { 371 t.Fatalf("Expected first seq to be 5, got %d", state.FirstSeq) 372 } 373 ms.Purge() 374 if state = ms.State(); len(state.Deleted) != 0 { 375 t.Fatalf("Expected no deleted after purge, got %+v\n", state.Deleted) 376 } 377 } 378 379 func TestMemStoreStreamTruncate(t *testing.T) { 380 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 381 require_NoError(t, err) 382 defer ms.Stop() 383 384 tseq := uint64(50) 385 386 subj, toStore := "foo", uint64(100) 387 for i := uint64(1); i < tseq; i++ { 388 _, _, err := ms.StoreMsg(subj, nil, []byte("ok")) 389 require_NoError(t, err) 390 } 391 subj = "bar" 392 for i := tseq; i <= toStore; i++ { 393 _, _, err := ms.StoreMsg(subj, nil, []byte("ok")) 394 require_NoError(t, err) 395 } 396 397 if state := ms.State(); state.Msgs != toStore { 398 t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs) 399 } 400 401 // Check that sequence has to be interior. 402 if err := ms.Truncate(toStore + 1); err != ErrInvalidSequence { 403 t.Fatalf("Expected err of '%v', got '%v'", ErrInvalidSequence, err) 404 } 405 406 if err := ms.Truncate(tseq); err != nil { 407 t.Fatalf("Unexpected error: %v", err) 408 } 409 if state := ms.State(); state.Msgs != tseq { 410 t.Fatalf("Expected %d msgs, got %d", tseq, state.Msgs) 411 } 412 413 // Now make sure we report properly if we have some deleted interior messages. 414 ms.RemoveMsg(10) 415 ms.RemoveMsg(20) 416 ms.RemoveMsg(30) 417 ms.RemoveMsg(40) 418 419 tseq = uint64(25) 420 if err := ms.Truncate(tseq); err != nil { 421 t.Fatalf("Unexpected error: %v", err) 422 } 423 state := ms.State() 424 if state.Msgs != tseq-2 { 425 t.Fatalf("Expected %d msgs, got %d", tseq-2, state.Msgs) 426 } 427 if state.NumSubjects != 1 { 428 t.Fatalf("Expected only 1 subject, got %d", state.NumSubjects) 429 } 430 expected := []uint64{10, 20} 431 if !reflect.DeepEqual(state.Deleted, expected) { 432 t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted) 433 } 434 } 435 436 func TestMemStorePurgeExWithSubject(t *testing.T) { 437 ms, err := newMemStore(&StreamConfig{Storage: MemoryStorage}) 438 require_NoError(t, err) 439 defer ms.Stop() 440 441 for i := 0; i < 100; i++ { 442 _, _, err = ms.StoreMsg("foo", nil, nil) 443 require_NoError(t, err) 444 } 445 446 // This should purge all. 447 ms.PurgeEx("foo", 1, 0) 448 require_True(t, ms.State().Msgs == 0) 449 } 450 451 func TestMemStoreUpdateMaxMsgsPerSubject(t *testing.T) { 452 cfg := &StreamConfig{ 453 Name: "TEST", 454 Storage: MemoryStorage, 455 Subjects: []string{"foo"}, 456 MaxMsgsPer: 10, 457 } 458 ms, err := newMemStore(cfg) 459 require_NoError(t, err) 460 defer ms.Stop() 461 462 // Make sure this is honored on an update. 463 cfg.MaxMsgsPer = 50 464 err = ms.UpdateConfig(cfg) 465 require_NoError(t, err) 466 467 numStored := 22 468 for i := 0; i < numStored; i++ { 469 _, _, err = ms.StoreMsg("foo", nil, nil) 470 require_NoError(t, err) 471 } 472 473 ss := ms.SubjectsState("foo")["foo"] 474 if ss.Msgs != uint64(numStored) { 475 t.Fatalf("Expected to have %d stored, got %d", numStored, ss.Msgs) 476 } 477 478 // Now make sure we trunk if setting to lower value. 479 cfg.MaxMsgsPer = 10 480 err = ms.UpdateConfig(cfg) 481 require_NoError(t, err) 482 483 ss = ms.SubjectsState("foo")["foo"] 484 if ss.Msgs != 10 { 485 t.Fatalf("Expected to have %d stored, got %d", 10, ss.Msgs) 486 } 487 } 488 489 func TestMemStoreStreamTruncateReset(t *testing.T) { 490 cfg := &StreamConfig{ 491 Name: "TEST", 492 Storage: MemoryStorage, 493 Subjects: []string{"foo"}, 494 } 495 ms, err := newMemStore(cfg) 496 require_NoError(t, err) 497 defer ms.Stop() 498 499 subj, msg := "foo", []byte("Hello World") 500 for i := 0; i < 1000; i++ { 501 _, _, err := ms.StoreMsg(subj, nil, msg) 502 require_NoError(t, err) 503 } 504 505 // Reset everything 506 require_NoError(t, ms.Truncate(0)) 507 508 state := ms.State() 509 require_True(t, state.Msgs == 0) 510 require_True(t, state.Bytes == 0) 511 require_True(t, state.FirstSeq == 0) 512 require_True(t, state.LastSeq == 0) 513 require_True(t, state.NumSubjects == 0) 514 require_True(t, state.NumDeleted == 0) 515 516 for i := 0; i < 1000; i++ { 517 _, _, err := ms.StoreMsg(subj, nil, msg) 518 require_NoError(t, err) 519 } 520 521 state = ms.State() 522 require_True(t, state.Msgs == 1000) 523 require_True(t, state.Bytes == 30000) 524 require_True(t, state.FirstSeq == 1) 525 require_True(t, state.LastSeq == 1000) 526 require_True(t, state.NumSubjects == 1) 527 require_True(t, state.NumDeleted == 0) 528 } 529 530 func TestMemStoreStreamCompactMultiBlockSubjectInfo(t *testing.T) { 531 cfg := &StreamConfig{ 532 Name: "TEST", 533 Storage: MemoryStorage, 534 Subjects: []string{"foo.*"}, 535 } 536 ms, err := newMemStore(cfg) 537 require_NoError(t, err) 538 defer ms.Stop() 539 540 for i := 0; i < 1000; i++ { 541 subj := fmt.Sprintf("foo.%d", i) 542 _, _, err := ms.StoreMsg(subj, nil, []byte("Hello World")) 543 require_NoError(t, err) 544 } 545 546 // Compact such that we know we throw blocks away from the beginning. 547 deleted, err := ms.Compact(501) 548 require_NoError(t, err) 549 require_True(t, deleted == 500) 550 551 // Make sure we adjusted for subjects etc. 552 state := ms.State() 553 require_True(t, state.NumSubjects == 500) 554 } 555 556 func TestMemStoreSubjectsTotals(t *testing.T) { 557 cfg := &StreamConfig{ 558 Name: "TEST", 559 Storage: MemoryStorage, 560 Subjects: []string{"*.*"}, 561 } 562 ms, err := newMemStore(cfg) 563 require_NoError(t, err) 564 defer ms.Stop() 565 566 fmap := make(map[int]int) 567 bmap := make(map[int]int) 568 569 var m map[int]int 570 var ft string 571 572 for i := 0; i < 10_000; i++ { 573 // Flip coin for prefix 574 if rand.Intn(2) == 0 { 575 ft, m = "foo", fmap 576 } else { 577 ft, m = "bar", bmap 578 } 579 dt := rand.Intn(100) 580 subj := fmt.Sprintf("%s.%d", ft, dt) 581 m[dt]++ 582 583 _, _, err := ms.StoreMsg(subj, nil, []byte("Hello World")) 584 require_NoError(t, err) 585 } 586 587 // Now test SubjectsTotal 588 for dt, total := range fmap { 589 subj := fmt.Sprintf("foo.%d", dt) 590 m := ms.SubjectsTotals(subj) 591 if m[subj] != uint64(total) { 592 t.Fatalf("Expected %q to have %d total, got %d", subj, total, m[subj]) 593 } 594 } 595 596 // Check fmap. 597 if st := ms.SubjectsTotals("foo.*"); len(st) != len(fmap) { 598 t.Fatalf("Expected %d subjects for %q, got %d", len(fmap), "foo.*", len(st)) 599 } else { 600 expected := 0 601 for _, n := range fmap { 602 expected += n 603 } 604 received := uint64(0) 605 for _, n := range st { 606 received += n 607 } 608 if received != uint64(expected) { 609 t.Fatalf("Expected %d total but got %d", expected, received) 610 } 611 } 612 613 // Check bmap. 614 if st := ms.SubjectsTotals("bar.*"); len(st) != len(bmap) { 615 t.Fatalf("Expected %d subjects for %q, got %d", len(bmap), "bar.*", len(st)) 616 } else { 617 expected := 0 618 for _, n := range bmap { 619 expected += n 620 } 621 received := uint64(0) 622 for _, n := range st { 623 received += n 624 } 625 if received != uint64(expected) { 626 t.Fatalf("Expected %d total but got %d", expected, received) 627 } 628 } 629 630 // All with pwc match. 631 if st, expected := ms.SubjectsTotals("*.*"), len(bmap)+len(fmap); len(st) != expected { 632 t.Fatalf("Expected %d subjects for %q, got %d", expected, "*.*", len(st)) 633 } 634 } 635 636 func TestMemStoreNumPending(t *testing.T) { 637 cfg := &StreamConfig{ 638 Name: "TEST", 639 Storage: MemoryStorage, 640 Subjects: []string{"*.*.*.*"}, 641 } 642 ms, err := newMemStore(cfg) 643 require_NoError(t, err) 644 defer ms.Stop() 645 646 tokens := []string{"foo", "bar", "baz"} 647 genSubj := func() string { 648 return fmt.Sprintf("%s.%s.%s.%s", 649 tokens[rand.Intn(len(tokens))], 650 tokens[rand.Intn(len(tokens))], 651 tokens[rand.Intn(len(tokens))], 652 tokens[rand.Intn(len(tokens))], 653 ) 654 } 655 656 for i := 0; i < 50_000; i++ { 657 subj := genSubj() 658 _, _, err := ms.StoreMsg(subj, nil, []byte("Hello World")) 659 require_NoError(t, err) 660 } 661 662 state := ms.State() 663 664 // Scan one by one for sanity check against other calculations. 665 sanityCheck := func(sseq uint64, filter string) SimpleState { 666 t.Helper() 667 var ss SimpleState 668 var smv StoreMsg 669 // For here we know 0 is invalid, set to 1. 670 if sseq == 0 { 671 sseq = 1 672 } 673 for seq := sseq; seq <= state.LastSeq; seq++ { 674 sm, err := ms.LoadMsg(seq, &smv) 675 if err != nil { 676 t.Logf("Encountered error %v loading sequence: %d", err, seq) 677 continue 678 } 679 if subjectIsSubsetMatch(sm.subj, filter) { 680 ss.Msgs++ 681 ss.Last = seq 682 if ss.First == 0 || seq < ss.First { 683 ss.First = seq 684 } 685 } 686 } 687 return ss 688 } 689 690 check := func(sseq uint64, filter string) { 691 t.Helper() 692 np, lvs := ms.NumPending(sseq, filter, false) 693 ss := ms.FilteredState(sseq, filter) 694 sss := sanityCheck(sseq, filter) 695 if lvs != state.LastSeq { 696 t.Fatalf("Expected NumPending to return valid through last of %d but got %d", state.LastSeq, lvs) 697 } 698 if ss.Msgs != np { 699 t.Fatalf("NumPending of %d did not match ss.Msgs of %d", np, ss.Msgs) 700 } 701 if ss != sss { 702 t.Fatalf("Failed sanity check, expected %+v got %+v", sss, ss) 703 } 704 } 705 706 sanityCheckLastOnly := func(sseq uint64, filter string) SimpleState { 707 t.Helper() 708 var ss SimpleState 709 var smv StoreMsg 710 // For here we know 0 is invalid, set to 1. 711 if sseq == 0 { 712 sseq = 1 713 } 714 seen := make(map[string]bool) 715 for seq := state.LastSeq; seq >= sseq; seq-- { 716 sm, err := ms.LoadMsg(seq, &smv) 717 if err != nil { 718 t.Logf("Encountered error %v loading sequence: %d", err, seq) 719 continue 720 } 721 if !seen[sm.subj] && subjectIsSubsetMatch(sm.subj, filter) { 722 ss.Msgs++ 723 if ss.Last == 0 { 724 ss.Last = seq 725 } 726 if ss.First == 0 || seq < ss.First { 727 ss.First = seq 728 } 729 seen[sm.subj] = true 730 } 731 } 732 return ss 733 } 734 735 checkLastOnly := func(sseq uint64, filter string) { 736 t.Helper() 737 np, lvs := ms.NumPending(sseq, filter, true) 738 ss := sanityCheckLastOnly(sseq, filter) 739 if lvs != state.LastSeq { 740 t.Fatalf("Expected NumPending to return valid through last of %d but got %d", state.LastSeq, lvs) 741 } 742 if ss.Msgs != np { 743 t.Fatalf("NumPending of %d did not match ss.Msgs of %d", np, ss.Msgs) 744 } 745 } 746 747 startSeqs := []uint64{0, 1, 2, 200, 444, 555, 2222, 8888, 12_345, 28_222, 33_456, 44_400, 49_999} 748 checkSubs := []string{"foo.>", "*.bar.>", "foo.bar.*.baz", "*.bar.>", "*.foo.bar.*", "foo.foo.bar.baz"} 749 750 for _, filter := range checkSubs { 751 for _, start := range startSeqs { 752 check(start, filter) 753 checkLastOnly(start, filter) 754 } 755 } 756 } 757 758 func TestMemStoreInitialFirstSeq(t *testing.T) { 759 cfg := &StreamConfig{ 760 Name: "zzz", 761 Storage: MemoryStorage, 762 FirstSeq: 1000, 763 } 764 ms, err := newMemStore(cfg) 765 require_NoError(t, err) 766 defer ms.Stop() 767 768 seq, _, err := ms.StoreMsg("A", nil, []byte("OK")) 769 require_NoError(t, err) 770 if seq != 1000 { 771 t.Fatalf("Message should have been sequence 1000 but was %d", seq) 772 } 773 774 seq, _, err = ms.StoreMsg("B", nil, []byte("OK")) 775 require_NoError(t, err) 776 if seq != 1001 { 777 t.Fatalf("Message should have been sequence 1001 but was %d", seq) 778 } 779 780 var state StreamState 781 ms.FastState(&state) 782 switch { 783 case state.Msgs != 2: 784 t.Fatalf("Expected 2 messages, got %d", state.Msgs) 785 case state.FirstSeq != 1000: 786 t.Fatalf("Expected first seq 1000, got %d", state.FirstSeq) 787 case state.LastSeq != 1001: 788 t.Fatalf("Expected last seq 1001, got %d", state.LastSeq) 789 } 790 } 791 792 func TestMemStoreDeleteBlocks(t *testing.T) { 793 cfg := &StreamConfig{ 794 Name: "zzz", 795 Subjects: []string{"*"}, 796 Storage: MemoryStorage, 797 } 798 ms, err := newMemStore(cfg) 799 require_NoError(t, err) 800 defer ms.Stop() 801 802 // Put in 10_000 msgs. 803 total := 10_000 804 for i := 0; i < total; i++ { 805 _, _, err := ms.StoreMsg("A", nil, []byte("OK")) 806 require_NoError(t, err) 807 } 808 809 // Now pick 5k random sequences. 810 delete := 5000 811 deleteMap := make(map[int]struct{}, delete) 812 for len(deleteMap) < delete { 813 deleteMap[rand.Intn(total)+1] = struct{}{} 814 } 815 // Now remove? 816 for seq := range deleteMap { 817 ms.RemoveMsg(uint64(seq)) 818 } 819 820 var state StreamState 821 ms.FastState(&state) 822 823 // For now we just track via one dmap. 824 ms.mu.RLock() 825 dmap := ms.dmap.Clone() 826 ms.mu.RUnlock() 827 828 require_True(t, dmap.Size() == state.NumDeleted) 829 } 830 831 // https://github.com/nats-io/nats-server/issues/4850 832 func TestMemStoreGetSeqFromTimeWithLastDeleted(t *testing.T) { 833 cfg := &StreamConfig{ 834 Name: "zzz", 835 Subjects: []string{"*"}, 836 Storage: MemoryStorage, 837 } 838 ms, err := newMemStore(cfg) 839 require_NoError(t, err) 840 defer ms.Stop() 841 842 // Put in 1000 msgs. 843 total := 1000 844 var st time.Time 845 for i := 1; i <= total; i++ { 846 _, _, err := ms.StoreMsg("A", nil, []byte("OK")) 847 require_NoError(t, err) 848 if i == total/2 { 849 time.Sleep(100 * time.Millisecond) 850 st = time.Now() 851 } 852 } 853 // Delete last 100 854 for seq := total - 100; seq <= total; seq++ { 855 ms.RemoveMsg(uint64(seq)) 856 } 857 858 // Make sure this does not panic with last sequence no longer accessible. 859 seq := ms.GetSeqFromTime(st) 860 // Make sure we get the right value. 861 require_Equal(t, seq, 501) 862 } 863 864 func TestMemStoreSkipMsgs(t *testing.T) { 865 cfg := &StreamConfig{ 866 Name: "zzz", 867 Subjects: []string{"*"}, 868 Storage: MemoryStorage, 869 } 870 ms, err := newMemStore(cfg) 871 require_NoError(t, err) 872 defer ms.Stop() 873 874 // Test on empty FS first. 875 // Make sure wrong starting sequence fails. 876 err = ms.SkipMsgs(10, 100) 877 require_Error(t, err, ErrSequenceMismatch) 878 879 err = ms.SkipMsgs(1, 100) 880 require_NoError(t, err) 881 882 state := ms.State() 883 require_Equal(t, state.FirstSeq, 101) 884 require_Equal(t, state.LastSeq, 100) 885 886 // Now add alot. 887 err = ms.SkipMsgs(101, 100_000) 888 require_NoError(t, err) 889 state = ms.State() 890 require_Equal(t, state.FirstSeq, 100_101) 891 require_Equal(t, state.LastSeq, 100_100) 892 893 // Now add in a message, and then skip to check dmap. 894 ms, err = newMemStore(cfg) 895 require_NoError(t, err) 896 ms.StoreMsg("foo", nil, nil) 897 898 err = ms.SkipMsgs(2, 10) 899 require_NoError(t, err) 900 state = ms.State() 901 require_Equal(t, state.FirstSeq, 1) 902 require_Equal(t, state.LastSeq, 11) 903 require_Equal(t, state.Msgs, 1) 904 require_Equal(t, state.NumDeleted, 10) 905 require_Equal(t, len(state.Deleted), 10) 906 907 // Check Fast State too. 908 state.Deleted = nil 909 ms.FastState(&state) 910 require_Equal(t, state.FirstSeq, 1) 911 require_Equal(t, state.LastSeq, 11) 912 require_Equal(t, state.Msgs, 1) 913 require_Equal(t, state.NumDeleted, 10) 914 } 915 916 func TestMemStoreMultiLastSeqs(t *testing.T) { 917 cfg := &StreamConfig{ 918 Name: "zzz", 919 Subjects: []string{"foo.*"}, 920 Storage: MemoryStorage, 921 } 922 ms, err := newMemStore(cfg) 923 require_NoError(t, err) 924 defer ms.Stop() 925 926 msg := []byte("abc") 927 for i := 0; i < 33; i++ { 928 ms.StoreMsg("foo.foo", nil, msg) 929 ms.StoreMsg("foo.bar", nil, msg) 930 ms.StoreMsg("foo.baz", nil, msg) 931 } 932 for i := 0; i < 33; i++ { 933 ms.StoreMsg("bar.foo", nil, msg) 934 ms.StoreMsg("bar.bar", nil, msg) 935 ms.StoreMsg("bar.baz", nil, msg) 936 } 937 938 checkResults := func(seqs, expected []uint64) { 939 t.Helper() 940 if len(seqs) != len(expected) { 941 t.Fatalf("Expected %+v got %+v", expected, seqs) 942 } 943 for i := range seqs { 944 if seqs[i] != expected[i] { 945 t.Fatalf("Expected %+v got %+v", expected, seqs) 946 } 947 } 948 } 949 950 // UpTo sequence 3. Tests block split. 951 seqs, err := ms.MultiLastSeqs([]string{"foo.*"}, 3, -1) 952 require_NoError(t, err) 953 checkResults(seqs, []uint64{1, 2, 3}) 954 // Up to last sequence of the stream. 955 seqs, err = ms.MultiLastSeqs([]string{"foo.*"}, 0, -1) 956 require_NoError(t, err) 957 checkResults(seqs, []uint64{97, 98, 99}) 958 // Check for bar.* at the end. 959 seqs, err = ms.MultiLastSeqs([]string{"bar.*"}, 0, -1) 960 require_NoError(t, err) 961 checkResults(seqs, []uint64{196, 197, 198}) 962 // This should find nothing. 963 seqs, err = ms.MultiLastSeqs([]string{"bar.*"}, 99, -1) 964 require_NoError(t, err) 965 checkResults(seqs, nil) 966 967 // Do multiple subjects explicitly. 968 seqs, err = ms.MultiLastSeqs([]string{"foo.foo", "foo.bar", "foo.baz"}, 3, -1) 969 require_NoError(t, err) 970 checkResults(seqs, []uint64{1, 2, 3}) 971 seqs, err = ms.MultiLastSeqs([]string{"foo.foo", "foo.bar", "foo.baz"}, 0, -1) 972 require_NoError(t, err) 973 checkResults(seqs, []uint64{97, 98, 99}) 974 seqs, err = ms.MultiLastSeqs([]string{"bar.foo", "bar.bar", "bar.baz"}, 0, -1) 975 require_NoError(t, err) 976 checkResults(seqs, []uint64{196, 197, 198}) 977 seqs, err = ms.MultiLastSeqs([]string{"bar.foo", "bar.bar", "bar.baz"}, 99, -1) 978 require_NoError(t, err) 979 checkResults(seqs, nil) 980 981 // Check single works 982 seqs, err = ms.MultiLastSeqs([]string{"foo.foo"}, 3, -1) 983 require_NoError(t, err) 984 checkResults(seqs, []uint64{1}) 985 986 // Now test that we properly de-duplicate between filters. 987 seqs, err = ms.MultiLastSeqs([]string{"foo.*", "foo.bar"}, 3, -1) 988 require_NoError(t, err) 989 checkResults(seqs, []uint64{1, 2, 3}) 990 seqs, err = ms.MultiLastSeqs([]string{"bar.>", "bar.bar", "bar.baz"}, 0, -1) 991 require_NoError(t, err) 992 checkResults(seqs, []uint64{196, 197, 198}) 993 994 // All 995 seqs, err = ms.MultiLastSeqs([]string{">"}, 0, -1) 996 require_NoError(t, err) 997 checkResults(seqs, []uint64{97, 98, 99, 196, 197, 198}) 998 seqs, err = ms.MultiLastSeqs([]string{">"}, 99, -1) 999 require_NoError(t, err) 1000 checkResults(seqs, []uint64{97, 98, 99}) 1001 } 1002 1003 func TestMemStoreMultiLastSeqsMaxAllowed(t *testing.T) { 1004 cfg := &StreamConfig{ 1005 Name: "zzz", 1006 Subjects: []string{"foo.*"}, 1007 Storage: MemoryStorage, 1008 } 1009 ms, err := newMemStore(cfg) 1010 require_NoError(t, err) 1011 defer ms.Stop() 1012 1013 msg := []byte("abc") 1014 for i := 1; i <= 100; i++ { 1015 ms.StoreMsg(fmt.Sprintf("foo.%d", i), nil, msg) 1016 } 1017 // Test that if we specify maxAllowed that we get the correct error. 1018 seqs, err := ms.MultiLastSeqs([]string{"foo.*"}, 0, 10) 1019 require_True(t, seqs == nil) 1020 require_Error(t, err, ErrTooManyResults) 1021 }