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  }