get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/filestore_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  	"archive/tar"
    18  	"bytes"
    19  	"crypto/hmac"
    20  	crand "crypto/rand"
    21  	"crypto/sha256"
    22  	"encoding/hex"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"math/bits"
    28  	"math/rand"
    29  	"os"
    30  	"path/filepath"
    31  	"reflect"
    32  	"strings"
    33  	"sync"
    34  	"testing"
    35  	"time"
    36  
    37  	"github.com/klauspost/compress/s2"
    38  )
    39  
    40  func testFileStoreAllPermutations(t *testing.T, fn func(t *testing.T, fcfg FileStoreConfig)) {
    41  	for _, fcfg := range []FileStoreConfig{
    42  		{Cipher: NoCipher, Compression: NoCompression},
    43  		{Cipher: NoCipher, Compression: S2Compression},
    44  		{Cipher: AES, Compression: NoCompression},
    45  		{Cipher: AES, Compression: S2Compression},
    46  		{Cipher: ChaCha, Compression: NoCompression},
    47  		{Cipher: ChaCha, Compression: S2Compression},
    48  	} {
    49  		subtestName := fmt.Sprintf("%s-%s", fcfg.Cipher, fcfg.Compression)
    50  		t.Run(subtestName, func(t *testing.T) {
    51  			fcfg.StoreDir = t.TempDir()
    52  			fn(t, fcfg)
    53  			time.Sleep(100 * time.Millisecond)
    54  		})
    55  	}
    56  }
    57  
    58  func prf(fcfg *FileStoreConfig) func(context []byte) ([]byte, error) {
    59  	if fcfg.Cipher == NoCipher {
    60  		return nil
    61  	}
    62  	return func(context []byte) ([]byte, error) {
    63  		h := hmac.New(sha256.New, []byte("dlc22"))
    64  		if _, err := h.Write(context); err != nil {
    65  			return nil, err
    66  		}
    67  		return h.Sum(nil), nil
    68  	}
    69  }
    70  
    71  func TestFileStoreBasics(t *testing.T) {
    72  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
    73  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
    74  		require_NoError(t, err)
    75  		defer fs.Stop()
    76  
    77  		subj, msg := "foo", []byte("Hello World")
    78  		now := time.Now().UnixNano()
    79  		for i := 1; i <= 5; i++ {
    80  			if seq, ts, err := fs.StoreMsg(subj, nil, msg); err != nil {
    81  				t.Fatalf("Error storing msg: %v", err)
    82  			} else if seq != uint64(i) {
    83  				t.Fatalf("Expected sequence to be %d, got %d", i, seq)
    84  			} else if ts < now || ts > now+int64(time.Millisecond) {
    85  				t.Fatalf("Expected timestamp to be current, got %v", ts-now)
    86  			}
    87  		}
    88  
    89  		state := fs.State()
    90  		if state.Msgs != 5 {
    91  			t.Fatalf("Expected 5 msgs, got %d", state.Msgs)
    92  		}
    93  		expectedSize := 5 * fileStoreMsgSize(subj, nil, msg)
    94  		if state.Bytes != expectedSize {
    95  			t.Fatalf("Expected %d bytes, got %d", expectedSize, state.Bytes)
    96  		}
    97  
    98  		var smv StoreMsg
    99  		sm, err := fs.LoadMsg(2, &smv)
   100  		if err != nil {
   101  			t.Fatalf("Unexpected error looking up msg: %v", err)
   102  		}
   103  		if sm.subj != subj {
   104  			t.Fatalf("Subjects don't match, original %q vs %q", subj, sm.subj)
   105  		}
   106  		if !bytes.Equal(sm.msg, msg) {
   107  			t.Fatalf("Msgs don't match, original %q vs %q", msg, sm.msg)
   108  		}
   109  		_, err = fs.LoadMsg(3, nil)
   110  		if err != nil {
   111  			t.Fatalf("Unexpected error looking up msg: %v", err)
   112  		}
   113  
   114  		remove := func(seq, expectedMsgs uint64) {
   115  			t.Helper()
   116  			removed, err := fs.RemoveMsg(seq)
   117  			if err != nil {
   118  				t.Fatalf("Got an error on remove of %d: %v", seq, err)
   119  			}
   120  			if !removed {
   121  				t.Fatalf("Expected remove to return true for %d", seq)
   122  			}
   123  			if state := fs.State(); state.Msgs != expectedMsgs {
   124  				t.Fatalf("Expected %d msgs, got %d", expectedMsgs, state.Msgs)
   125  			}
   126  		}
   127  
   128  		// Remove first
   129  		remove(1, 4)
   130  		// Remove last
   131  		remove(5, 3)
   132  		// Remove a middle
   133  		remove(3, 2)
   134  	})
   135  }
   136  
   137  func TestFileStoreMsgHeaders(t *testing.T) {
   138  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   139  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   140  		require_NoError(t, err)
   141  		defer fs.Stop()
   142  
   143  		subj, hdr, msg := "foo", []byte("name:derek"), []byte("Hello World")
   144  		elen := 22 + len(subj) + 4 + len(hdr) + len(msg) + 8
   145  		if sz := int(fileStoreMsgSize(subj, hdr, msg)); sz != elen {
   146  			t.Fatalf("Wrong size for stored msg with header")
   147  		}
   148  		fs.StoreMsg(subj, hdr, msg)
   149  		var smv StoreMsg
   150  		sm, err := fs.LoadMsg(1, &smv)
   151  		if err != nil {
   152  			t.Fatalf("Unexpected error looking up msg: %v", err)
   153  		}
   154  		if !bytes.Equal(msg, sm.msg) {
   155  			t.Fatalf("Expected same msg, got %q vs %q", sm.msg, msg)
   156  		}
   157  		if !bytes.Equal(hdr, sm.hdr) {
   158  			t.Fatalf("Expected same hdr, got %q vs %q", sm.hdr, hdr)
   159  		}
   160  		if removed, _ := fs.EraseMsg(1); !removed {
   161  			t.Fatalf("Expected erase msg to return success")
   162  		}
   163  	})
   164  }
   165  
   166  func TestFileStoreBasicWriteMsgsAndRestore(t *testing.T) {
   167  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   168  		if _, err := newFileStore(fcfg, StreamConfig{Storage: MemoryStorage}); err == nil {
   169  			t.Fatalf("Expected an error with wrong type")
   170  		}
   171  		if _, err := newFileStore(fcfg, StreamConfig{Storage: FileStorage}); err == nil {
   172  			t.Fatalf("Expected an error with no name")
   173  		}
   174  
   175  		created := time.Now()
   176  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   177  		require_NoError(t, err)
   178  		defer fs.Stop()
   179  
   180  		subj := "foo"
   181  
   182  		// Write 100 msgs
   183  		toStore := uint64(100)
   184  		for i := uint64(1); i <= toStore; i++ {
   185  			msg := []byte(fmt.Sprintf("[%08d] Hello World!", i))
   186  			if seq, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   187  				t.Fatalf("Error storing msg: %v", err)
   188  			} else if seq != uint64(i) {
   189  				t.Fatalf("Expected sequence to be %d, got %d", i, seq)
   190  			}
   191  		}
   192  		state := fs.State()
   193  		if state.Msgs != toStore {
   194  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   195  		}
   196  		msg22 := []byte(fmt.Sprintf("[%08d] Hello World!", 22))
   197  		expectedSize := toStore * fileStoreMsgSize(subj, nil, msg22)
   198  
   199  		if state.Bytes != expectedSize {
   200  			t.Fatalf("Expected %d bytes, got %d", expectedSize, state.Bytes)
   201  		}
   202  		// Stop will flush to disk.
   203  		fs.Stop()
   204  
   205  		// Make sure Store call after does not work.
   206  		if _, _, err := fs.StoreMsg(subj, nil, []byte("no work")); err == nil {
   207  			t.Fatalf("Expected an error for StoreMsg call after Stop, got none")
   208  		}
   209  
   210  		// Restart
   211  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   212  		require_NoError(t, err)
   213  		defer fs.Stop()
   214  
   215  		state = fs.State()
   216  		if state.Msgs != toStore {
   217  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   218  		}
   219  		if state.Bytes != expectedSize {
   220  			t.Fatalf("Expected %d bytes, got %d", expectedSize, state.Bytes)
   221  		}
   222  
   223  		// Now write 100 more msgs
   224  		for i := uint64(101); i <= toStore*2; i++ {
   225  			msg := []byte(fmt.Sprintf("[%08d] Hello World!", i))
   226  			if seq, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   227  				t.Fatalf("Error storing msg: %v", err)
   228  			} else if seq != uint64(i) {
   229  				t.Fatalf("Expected sequence to be %d, got %d", i, seq)
   230  			}
   231  		}
   232  		state = fs.State()
   233  		if state.Msgs != toStore*2 {
   234  			t.Fatalf("Expected %d msgs, got %d", toStore*2, state.Msgs)
   235  		}
   236  
   237  		// Now cycle again and make sure that last batch was stored.
   238  		// Stop will flush to disk.
   239  		fs.Stop()
   240  
   241  		// Restart
   242  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   243  		require_NoError(t, err)
   244  		defer fs.Stop()
   245  
   246  		state = fs.State()
   247  		if state.Msgs != toStore*2 {
   248  			t.Fatalf("Expected %d msgs, got %d", toStore*2, state.Msgs)
   249  		}
   250  		if state.Bytes != expectedSize*2 {
   251  			t.Fatalf("Expected %d bytes, got %d", expectedSize*2, state.Bytes)
   252  		}
   253  
   254  		fs.Purge()
   255  		fs.Stop()
   256  
   257  		// Restart
   258  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   259  		require_NoError(t, err)
   260  		defer fs.Stop()
   261  
   262  		state = fs.State()
   263  		if state.Msgs != 0 {
   264  			t.Fatalf("Expected %d msgs, got %d", 0, state.Msgs)
   265  		}
   266  		if state.Bytes != 0 {
   267  			t.Fatalf("Expected %d bytes, got %d", 0, state.Bytes)
   268  		}
   269  
   270  		seq, _, err := fs.StoreMsg(subj, nil, []byte("Hello"))
   271  		if err != nil {
   272  			t.Fatalf("Unexpected error: %v", err)
   273  		}
   274  		fs.RemoveMsg(seq)
   275  
   276  		fs.Stop()
   277  
   278  		// Restart
   279  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   280  		require_NoError(t, err)
   281  		defer fs.Stop()
   282  
   283  		state = fs.State()
   284  		require_Equal(t, state.FirstSeq, seq+1)
   285  	})
   286  }
   287  
   288  func TestFileStoreSelectNextFirst(t *testing.T) {
   289  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   290  		fcfg.BlockSize = 256
   291  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   292  		require_NoError(t, err)
   293  		defer fs.Stop()
   294  
   295  		numMsgs := 10
   296  		subj, msg := "zzz", []byte("Hello World")
   297  		for i := 0; i < numMsgs; i++ {
   298  			fs.StoreMsg(subj, nil, msg)
   299  		}
   300  		if state := fs.State(); state.Msgs != uint64(numMsgs) {
   301  			t.Fatalf("Expected %d msgs, got %d", numMsgs, state.Msgs)
   302  		}
   303  
   304  		// Note the 256 block size is tied to the msg size below to give us 5 messages per block.
   305  		if fmb := fs.selectMsgBlock(1); fmb.msgs != 5 {
   306  			t.Fatalf("Expected 5 messages per block, but got %d", fmb.msgs)
   307  		}
   308  
   309  		// Delete 2-7, this will cross message blocks.
   310  		for i := 2; i <= 7; i++ {
   311  			fs.RemoveMsg(uint64(i))
   312  		}
   313  
   314  		if state := fs.State(); state.Msgs != 4 || state.FirstSeq != 1 {
   315  			t.Fatalf("Expected 4 msgs, first seq of 11, got msgs of %d and first seq of %d", state.Msgs, state.FirstSeq)
   316  		}
   317  		// Now close the gap which will force the system to jump underlying message blocks to find the right sequence.
   318  		fs.RemoveMsg(1)
   319  		if state := fs.State(); state.Msgs != 3 || state.FirstSeq != 8 {
   320  			t.Fatalf("Expected 3 msgs, first seq of 8, got msgs of %d and first seq of %d", state.Msgs, state.FirstSeq)
   321  		}
   322  	})
   323  }
   324  
   325  func TestFileStoreSkipMsg(t *testing.T) {
   326  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   327  		fcfg.BlockSize = 256
   328  		created := time.Now()
   329  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   330  		require_NoError(t, err)
   331  		defer fs.Stop()
   332  
   333  		numSkips := 10
   334  		for i := 0; i < numSkips; i++ {
   335  			fs.SkipMsg()
   336  		}
   337  		state := fs.State()
   338  		if state.Msgs != 0 {
   339  			t.Fatalf("Expected %d msgs, got %d", 0, state.Msgs)
   340  		}
   341  		if state.FirstSeq != uint64(numSkips+1) || state.LastSeq != uint64(numSkips) {
   342  			t.Fatalf("Expected first to be %d and last to be %d. got first %d and last %d", numSkips+1, numSkips, state.FirstSeq, state.LastSeq)
   343  		}
   344  
   345  		fs.StoreMsg("zzz", nil, []byte("Hello World!"))
   346  		fs.SkipMsg()
   347  		fs.SkipMsg()
   348  		fs.StoreMsg("zzz", nil, []byte("Hello World!"))
   349  		fs.SkipMsg()
   350  
   351  		state = fs.State()
   352  		if state.Msgs != 2 {
   353  			t.Fatalf("Expected %d msgs, got %d", 2, state.Msgs)
   354  		}
   355  		if state.FirstSeq != uint64(numSkips+1) || state.LastSeq != uint64(numSkips+5) {
   356  			t.Fatalf("Expected first to be %d and last to be %d. got first %d and last %d", numSkips+1, numSkips+5, state.FirstSeq, state.LastSeq)
   357  		}
   358  
   359  		// Make sure we recover same state.
   360  		fs.Stop()
   361  
   362  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   363  		require_NoError(t, err)
   364  		defer fs.Stop()
   365  
   366  		state = fs.State()
   367  		if state.Msgs != 2 {
   368  			t.Fatalf("Expected %d msgs, got %d", 2, state.Msgs)
   369  		}
   370  		if state.FirstSeq != uint64(numSkips+1) || state.LastSeq != uint64(numSkips+5) {
   371  			t.Fatalf("Expected first to be %d and last to be %d. got first %d and last %d", numSkips+1, numSkips+5, state.FirstSeq, state.LastSeq)
   372  		}
   373  
   374  		var smv StoreMsg
   375  		sm, err := fs.LoadMsg(11, &smv)
   376  		if err != nil {
   377  			t.Fatalf("Unexpected error looking up seq 11: %v", err)
   378  		}
   379  		if sm.subj != "zzz" || string(sm.msg) != "Hello World!" {
   380  			t.Fatalf("Message did not match")
   381  		}
   382  
   383  		fs.SkipMsg()
   384  		nseq, _, err := fs.StoreMsg("AAA", nil, []byte("Skip?"))
   385  		if err != nil {
   386  			t.Fatalf("Unexpected error looking up seq 11: %v", err)
   387  		}
   388  		if nseq != 17 {
   389  			t.Fatalf("Expected seq of %d but got %d", 17, nseq)
   390  		}
   391  
   392  		// Make sure we recover same state.
   393  		fs.Stop()
   394  
   395  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   396  		require_NoError(t, err)
   397  		defer fs.Stop()
   398  
   399  		sm, err = fs.LoadMsg(nseq, &smv)
   400  		if err != nil {
   401  			t.Fatalf("Unexpected error looking up seq %d: %v", nseq, err)
   402  		}
   403  		if sm.subj != "AAA" || string(sm.msg) != "Skip?" {
   404  			t.Fatalf("Message did not match")
   405  		}
   406  	})
   407  }
   408  
   409  func TestFileStoreWriteExpireWrite(t *testing.T) {
   410  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   411  		cexp := 10 * time.Millisecond
   412  		fcfg.CacheExpire = cexp
   413  		created := time.Now()
   414  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   415  		require_NoError(t, err)
   416  		defer fs.Stop()
   417  
   418  		toSend := 10
   419  		for i := 0; i < toSend; i++ {
   420  			fs.StoreMsg("zzz", nil, []byte("Hello World!"))
   421  		}
   422  
   423  		// Wait for write cache portion to go to zero.
   424  		checkFor(t, time.Second, 20*time.Millisecond, func() error {
   425  			if csz := fs.cacheSize(); csz != 0 {
   426  				return fmt.Errorf("cache size not 0, got %s", friendlyBytes(int64(csz)))
   427  			}
   428  			return nil
   429  		})
   430  
   431  		for i := 0; i < toSend; i++ {
   432  			fs.StoreMsg("zzz", nil, []byte("Hello World! - 22"))
   433  		}
   434  
   435  		if state := fs.State(); state.Msgs != uint64(toSend*2) {
   436  			t.Fatalf("Expected %d msgs, got %d", toSend*2, state.Msgs)
   437  		}
   438  
   439  		// Make sure we recover same state.
   440  		fs.Stop()
   441  
   442  		fcfg.CacheExpire = 0
   443  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   444  		require_NoError(t, err)
   445  		defer fs.Stop()
   446  
   447  		if state := fs.State(); state.Msgs != uint64(toSend*2) {
   448  			t.Fatalf("Expected %d msgs, got %d", toSend*2, state.Msgs)
   449  		}
   450  
   451  		// Now load them in and check.
   452  		var smv StoreMsg
   453  		for i := 1; i <= toSend*2; i++ {
   454  			sm, err := fs.LoadMsg(uint64(i), &smv)
   455  			if err != nil {
   456  				t.Fatalf("Unexpected error looking up seq %d: %v", i, err)
   457  			}
   458  			str := "Hello World!"
   459  			if i > toSend {
   460  				str = "Hello World! - 22"
   461  			}
   462  			if sm.subj != "zzz" || string(sm.msg) != str {
   463  				t.Fatalf("Message did not match")
   464  			}
   465  		}
   466  	})
   467  }
   468  
   469  func TestFileStoreMsgLimit(t *testing.T) {
   470  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   471  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxMsgs: 10}, time.Now(), prf(&fcfg), nil)
   472  		require_NoError(t, err)
   473  		defer fs.Stop()
   474  
   475  		subj, msg := "foo", []byte("Hello World")
   476  		for i := 0; i < 10; i++ {
   477  			fs.StoreMsg(subj, nil, msg)
   478  		}
   479  		state := fs.State()
   480  		if state.Msgs != 10 {
   481  			t.Fatalf("Expected %d msgs, got %d", 10, state.Msgs)
   482  		}
   483  		if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   484  			t.Fatalf("Error storing msg: %v", err)
   485  		}
   486  		state = fs.State()
   487  		if state.Msgs != 10 {
   488  			t.Fatalf("Expected %d msgs, got %d", 10, state.Msgs)
   489  		}
   490  		if state.LastSeq != 11 {
   491  			t.Fatalf("Expected the last sequence to be 11 now, but got %d", state.LastSeq)
   492  		}
   493  		if state.FirstSeq != 2 {
   494  			t.Fatalf("Expected the first sequence to be 2 now, but got %d", state.FirstSeq)
   495  		}
   496  		// Make sure we can not lookup seq 1.
   497  		if _, err := fs.LoadMsg(1, nil); err == nil {
   498  			t.Fatalf("Expected error looking up seq 1 but got none")
   499  		}
   500  	})
   501  }
   502  
   503  func TestFileStoreMsgLimitBug(t *testing.T) {
   504  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   505  		created := time.Now()
   506  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxMsgs: 1}, created, prf(&fcfg), nil)
   507  		require_NoError(t, err)
   508  		defer fs.Stop()
   509  
   510  		subj, msg := "foo", []byte("Hello World")
   511  		fs.StoreMsg(subj, nil, msg)
   512  		fs.StoreMsg(subj, nil, msg)
   513  		fs.Stop()
   514  
   515  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxMsgs: 1}, created, prf(&fcfg), nil)
   516  		require_NoError(t, err)
   517  		defer fs.Stop()
   518  		fs.StoreMsg(subj, nil, msg)
   519  	})
   520  }
   521  
   522  func TestFileStoreBytesLimit(t *testing.T) {
   523  	subj, msg := "foo", make([]byte, 512)
   524  	storedMsgSize := fileStoreMsgSize(subj, nil, msg)
   525  
   526  	toStore := uint64(1024)
   527  	maxBytes := storedMsgSize * toStore
   528  
   529  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   530  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxBytes: int64(maxBytes)}, time.Now(), prf(&fcfg), nil)
   531  		require_NoError(t, err)
   532  		defer fs.Stop()
   533  
   534  		for i := uint64(0); i < toStore; i++ {
   535  			fs.StoreMsg(subj, nil, msg)
   536  		}
   537  		state := fs.State()
   538  		if state.Msgs != toStore {
   539  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   540  		}
   541  		if state.Bytes != storedMsgSize*toStore {
   542  			t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes)
   543  		}
   544  
   545  		// Now send 10 more and check that bytes limit enforced.
   546  		for i := 0; i < 10; i++ {
   547  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   548  				t.Fatalf("Error storing msg: %v", err)
   549  			}
   550  		}
   551  		state = fs.State()
   552  		if state.Msgs != toStore {
   553  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   554  		}
   555  		if state.Bytes != storedMsgSize*toStore {
   556  			t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes)
   557  		}
   558  		if state.FirstSeq != 11 {
   559  			t.Fatalf("Expected first sequence to be 11, got %d", state.FirstSeq)
   560  		}
   561  		if state.LastSeq != toStore+10 {
   562  			t.Fatalf("Expected last sequence to be %d, got %d", toStore+10, state.LastSeq)
   563  		}
   564  	})
   565  }
   566  
   567  // https://github.com/nats-io/nats-server/issues/4771
   568  func TestFileStoreBytesLimitWithDiscardNew(t *testing.T) {
   569  	subj, msg := "tiny", make([]byte, 7)
   570  	storedMsgSize := fileStoreMsgSize(subj, nil, msg)
   571  
   572  	toStore := uint64(2)
   573  	maxBytes := 100
   574  
   575  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   576  		cfg := StreamConfig{Name: "zzz", Storage: FileStorage, MaxBytes: int64(maxBytes), Discard: DiscardNew}
   577  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
   578  		require_NoError(t, err)
   579  		defer fs.Stop()
   580  
   581  		for i := 0; i < 10; i++ {
   582  			_, _, err := fs.StoreMsg(subj, nil, msg)
   583  			if i < int(toStore) {
   584  				if err != nil {
   585  					t.Fatalf("Error storing msg: %v", err)
   586  				}
   587  			} else if !errors.Is(err, ErrMaxBytes) {
   588  				t.Fatalf("Storing msg should result in: %v", ErrMaxBytes)
   589  			}
   590  		}
   591  		state := fs.State()
   592  		if state.Msgs != toStore {
   593  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   594  		}
   595  		if state.Bytes != storedMsgSize*toStore {
   596  			t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes)
   597  		}
   598  	})
   599  }
   600  
   601  func TestFileStoreAgeLimit(t *testing.T) {
   602  	maxAge := 1 * time.Second
   603  
   604  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   605  		if fcfg.Compression != NoCompression {
   606  			// TODO(nat): This test fails at the moment with compression enabled
   607  			// because it takes longer to compress the blocks, by which time the
   608  			// messages have expired. Need to think about a balanced age so that
   609  			// the test doesn't take too long in non-compressed cases.
   610  			t.SkipNow()
   611  		}
   612  
   613  		fcfg.BlockSize = 256
   614  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxAge: maxAge}, time.Now(), prf(&fcfg), nil)
   615  		require_NoError(t, err)
   616  		defer fs.Stop()
   617  
   618  		// Store some messages. Does not really matter how many.
   619  		subj, msg := "foo", []byte("Hello World")
   620  		toStore := 500
   621  		for i := 0; i < toStore; i++ {
   622  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   623  				t.Fatalf("Unexpected error: %v", err)
   624  			}
   625  		}
   626  		state := fs.State()
   627  		if state.Msgs != uint64(toStore) {
   628  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   629  		}
   630  		checkExpired := func(t *testing.T) {
   631  			t.Helper()
   632  			checkFor(t, 5*time.Second, maxAge, func() error {
   633  				state = fs.State()
   634  				if state.Msgs != 0 {
   635  					return fmt.Errorf("Expected no msgs, got %d", state.Msgs)
   636  				}
   637  				if state.Bytes != 0 {
   638  					return fmt.Errorf("Expected no bytes, got %d", state.Bytes)
   639  				}
   640  				return nil
   641  			})
   642  		}
   643  		// Let them expire
   644  		checkExpired(t)
   645  
   646  		// Now add some more and make sure that timer will fire again.
   647  		for i := 0; i < toStore; i++ {
   648  			fs.StoreMsg(subj, nil, msg)
   649  		}
   650  		state = fs.State()
   651  		if state.Msgs != uint64(toStore) {
   652  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   653  		}
   654  		fs.RemoveMsg(502)
   655  		fs.RemoveMsg(602)
   656  		fs.RemoveMsg(702)
   657  		fs.RemoveMsg(802)
   658  		// We will measure the time to make sure expires works with interior deletes.
   659  		start := time.Now()
   660  		checkExpired(t)
   661  		if elapsed := time.Since(start); elapsed > 5*time.Second {
   662  			t.Fatalf("Took too long to expire: %v", elapsed)
   663  		}
   664  	})
   665  }
   666  
   667  func TestFileStoreTimeStamps(t *testing.T) {
   668  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   669  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   670  		require_NoError(t, err)
   671  		defer fs.Stop()
   672  
   673  		last := time.Now().UnixNano()
   674  		subj, msg := "foo", []byte("Hello World")
   675  		for i := 0; i < 10; i++ {
   676  			time.Sleep(5 * time.Millisecond)
   677  			fs.StoreMsg(subj, nil, msg)
   678  		}
   679  		var smv StoreMsg
   680  		for seq := uint64(1); seq <= 10; seq++ {
   681  			sm, err := fs.LoadMsg(seq, &smv)
   682  			if err != nil {
   683  				t.Fatalf("Unexpected error looking up msg [%d]: %v", seq, err)
   684  			}
   685  			// These should be different
   686  			if sm.ts <= last {
   687  				t.Fatalf("Expected different timestamps, got last %v vs %v", last, sm.ts)
   688  			}
   689  			last = sm.ts
   690  		}
   691  	})
   692  }
   693  
   694  func TestFileStorePurge(t *testing.T) {
   695  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   696  		blkSize := uint64(64 * 1024)
   697  		fcfg.BlockSize = blkSize
   698  		created := time.Now()
   699  
   700  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   701  		require_NoError(t, err)
   702  		defer fs.Stop()
   703  
   704  		subj, msg := "foo", make([]byte, 8*1024)
   705  		storedMsgSize := fileStoreMsgSize(subj, nil, msg)
   706  
   707  		toStore := uint64(1024)
   708  		for i := uint64(0); i < toStore; i++ {
   709  			fs.StoreMsg(subj, nil, msg)
   710  		}
   711  		state := fs.State()
   712  		if state.Msgs != toStore {
   713  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   714  		}
   715  		if state.Bytes != storedMsgSize*toStore {
   716  			t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes)
   717  		}
   718  
   719  		expectedBlocks := int(storedMsgSize * toStore / blkSize)
   720  		if numBlocks := fs.numMsgBlocks(); numBlocks <= expectedBlocks {
   721  			t.Fatalf("Expected to have more then %d msg blocks, got %d", blkSize, numBlocks)
   722  		}
   723  
   724  		fs.Purge()
   725  
   726  		if numBlocks := fs.numMsgBlocks(); numBlocks != 1 {
   727  			t.Fatalf("Expected to have exactly 1 empty msg block, got %d", numBlocks)
   728  		}
   729  
   730  		checkPurgeState := func(stored uint64) {
   731  			t.Helper()
   732  			state = fs.State()
   733  			if state.Msgs != 0 {
   734  				t.Fatalf("Expected 0 msgs after purge, got %d", state.Msgs)
   735  			}
   736  			if state.Bytes != 0 {
   737  				t.Fatalf("Expected 0 bytes after purge, got %d", state.Bytes)
   738  			}
   739  			if state.LastSeq != stored {
   740  				t.Fatalf("Expected LastSeq to be %d., got %d", toStore, state.LastSeq)
   741  			}
   742  			if state.FirstSeq != stored+1 {
   743  				t.Fatalf("Expected FirstSeq to be %d., got %d", toStore+1, state.FirstSeq)
   744  			}
   745  		}
   746  		checkPurgeState(toStore)
   747  
   748  		// Make sure we recover same state.
   749  		fs.Stop()
   750  
   751  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   752  		require_NoError(t, err)
   753  		defer fs.Stop()
   754  
   755  		if numBlocks := fs.numMsgBlocks(); numBlocks != 1 {
   756  			t.Fatalf("Expected to have exactly 1 empty msg block, got %d", numBlocks)
   757  		}
   758  
   759  		checkPurgeState(toStore)
   760  
   761  		// Now make sure we clean up any dangling purged messages.
   762  		for i := uint64(0); i < toStore; i++ {
   763  			fs.StoreMsg(subj, nil, msg)
   764  		}
   765  		state = fs.State()
   766  		if state.Msgs != toStore {
   767  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
   768  		}
   769  		if state.Bytes != storedMsgSize*toStore {
   770  			t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, state.Bytes)
   771  		}
   772  
   773  		// We will simulate crashing before the purge directory is cleared.
   774  		mdir := filepath.Join(fs.fcfg.StoreDir, msgDir)
   775  		pdir := filepath.Join(fs.fcfg.StoreDir, "ptest")
   776  		os.Rename(mdir, pdir)
   777  		os.MkdirAll(mdir, 0755)
   778  
   779  		fs.Purge()
   780  		checkPurgeState(toStore * 2)
   781  
   782  		// Make sure we recover same state.
   783  		fs.Stop()
   784  
   785  		purgeDir := filepath.Join(fs.fcfg.StoreDir, purgeDir)
   786  		os.Rename(pdir, purgeDir)
   787  
   788  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   789  		require_NoError(t, err)
   790  		defer fs.Stop()
   791  
   792  		if numBlocks := fs.numMsgBlocks(); numBlocks != 1 {
   793  			t.Fatalf("Expected to have exactly 1 empty msg block, got %d", numBlocks)
   794  		}
   795  
   796  		checkPurgeState(toStore * 2)
   797  
   798  		checkFor(t, 2*time.Second, 100*time.Millisecond, func() error {
   799  			if _, err := os.Stat(purgeDir); err == nil {
   800  				return fmt.Errorf("purge directory still present")
   801  			}
   802  			return nil
   803  		})
   804  	})
   805  }
   806  
   807  func TestFileStoreCompact(t *testing.T) {
   808  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   809  		fcfg.BlockSize = 350
   810  		created := time.Now()
   811  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   812  		require_NoError(t, err)
   813  		defer fs.Stop()
   814  
   815  		subj, msg := "foo", []byte("Hello World")
   816  		for i := 0; i < 10; i++ {
   817  			fs.StoreMsg(subj, nil, msg)
   818  		}
   819  		if state := fs.State(); state.Msgs != 10 {
   820  			t.Fatalf("Expected 10 msgs, got %d", state.Msgs)
   821  		}
   822  		n, err := fs.Compact(6)
   823  		if err != nil {
   824  			t.Fatalf("Unexpected error: %v", err)
   825  		}
   826  		if n != 5 {
   827  			t.Fatalf("Expected to have purged 5 msgs, got %d", n)
   828  		}
   829  		state := fs.State()
   830  		if state.Msgs != 5 {
   831  			t.Fatalf("Expected 5 msgs, got %d", state.Msgs)
   832  		}
   833  		if state.FirstSeq != 6 {
   834  			t.Fatalf("Expected first seq of 6, got %d", state.FirstSeq)
   835  		}
   836  		// Now test that compact will also reset first if seq > last
   837  		n, err = fs.Compact(100)
   838  		if err != nil {
   839  			t.Fatalf("Unexpected error: %v", err)
   840  		}
   841  		if n != 5 {
   842  			t.Fatalf("Expected to have purged 5 msgs, got %d", n)
   843  		}
   844  		if state = fs.State(); state.FirstSeq != 100 {
   845  			t.Fatalf("Expected first seq of 100, got %d", state.FirstSeq)
   846  		}
   847  
   848  		fs.Stop()
   849  
   850  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
   851  		require_NoError(t, err)
   852  		defer fs.Stop()
   853  
   854  		if state = fs.State(); state.FirstSeq != 100 {
   855  			t.Fatalf("Expected first seq of 100, got %d", state.FirstSeq)
   856  		}
   857  	})
   858  }
   859  
   860  func TestFileStoreCompactLastPlusOne(t *testing.T) {
   861  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   862  		fcfg.BlockSize = 8192
   863  		fcfg.AsyncFlush = true
   864  
   865  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   866  		require_NoError(t, err)
   867  		defer fs.Stop()
   868  
   869  		subj, msg := "foo", make([]byte, 10_000)
   870  		for i := 0; i < 10_000; i++ {
   871  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
   872  				t.Fatalf("Unexpected error: %v", err)
   873  			}
   874  		}
   875  
   876  		// The performance of this test is quite terrible with compression
   877  		// if we have AsyncFlush = false, so we'll batch flushes instead.
   878  		fs.mu.Lock()
   879  		fs.checkAndFlushAllBlocks()
   880  		fs.mu.Unlock()
   881  
   882  		if state := fs.State(); state.Msgs != 10_000 {
   883  			t.Fatalf("Expected 1000000 msgs, got %d", state.Msgs)
   884  		}
   885  		if _, err := fs.Compact(10_001); err != nil {
   886  			t.Fatalf("Unexpected error: %v", err)
   887  		}
   888  		state := fs.State()
   889  		if state.Msgs != 0 {
   890  			t.Fatalf("Expected no message but got %d", state.Msgs)
   891  		}
   892  
   893  		fs.StoreMsg(subj, nil, msg)
   894  		state = fs.State()
   895  		if state.Msgs != 1 {
   896  			t.Fatalf("Expected one message but got %d", state.Msgs)
   897  		}
   898  	})
   899  }
   900  
   901  func TestFileStoreCompactMsgCountBug(t *testing.T) {
   902  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   903  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   904  		require_NoError(t, err)
   905  		defer fs.Stop()
   906  
   907  		subj, msg := "foo", []byte("Hello World")
   908  		for i := 0; i < 10; i++ {
   909  			fs.StoreMsg(subj, nil, msg)
   910  		}
   911  		if state := fs.State(); state.Msgs != 10 {
   912  			t.Fatalf("Expected 10 msgs, got %d", state.Msgs)
   913  		}
   914  		// Now delete 2,3,4.
   915  		fs.EraseMsg(2)
   916  		fs.EraseMsg(3)
   917  		fs.EraseMsg(4)
   918  
   919  		// Also delete 7,8, and 9.
   920  		fs.RemoveMsg(7)
   921  		fs.RemoveMsg(8)
   922  		fs.RemoveMsg(9)
   923  
   924  		n, err := fs.Compact(6)
   925  		if err != nil {
   926  			t.Fatalf("Unexpected error: %v", err)
   927  		}
   928  		// 1 & 5
   929  		if n != 2 {
   930  			t.Fatalf("Expected to have deleted 2 msgs, got %d", n)
   931  		}
   932  		if state := fs.State(); state.Msgs != 2 {
   933  			t.Fatalf("Expected to have 2 remaining, got %d", state.Msgs)
   934  		}
   935  	})
   936  }
   937  
   938  func TestFileStoreCompactPerf(t *testing.T) {
   939  	t.SkipNow()
   940  
   941  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   942  		fcfg.BlockSize = 8192
   943  		fcfg.AsyncFlush = true
   944  
   945  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
   946  		require_NoError(t, err)
   947  		defer fs.Stop()
   948  
   949  		subj, msg := "foo", []byte("Hello World")
   950  		for i := 0; i < 100_000; i++ {
   951  			fs.StoreMsg(subj, nil, msg)
   952  		}
   953  		if state := fs.State(); state.Msgs != 100_000 {
   954  			t.Fatalf("Expected 1000000 msgs, got %d", state.Msgs)
   955  		}
   956  		start := time.Now()
   957  		n, err := fs.Compact(90_001)
   958  		if err != nil {
   959  			t.Fatalf("Unexpected error: %v", err)
   960  		}
   961  		t.Logf("Took %v to compact\n", time.Since(start))
   962  
   963  		if n != 90_000 {
   964  			t.Fatalf("Expected to have purged 90_000 msgs, got %d", n)
   965  		}
   966  		state := fs.State()
   967  		if state.Msgs != 10_000 {
   968  			t.Fatalf("Expected 10_000 msgs, got %d", state.Msgs)
   969  		}
   970  		if state.FirstSeq != 90_001 {
   971  			t.Fatalf("Expected first seq of 90_001, got %d", state.FirstSeq)
   972  		}
   973  	})
   974  }
   975  
   976  func TestFileStoreStreamTruncate(t *testing.T) {
   977  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
   978  		fcfg.BlockSize = 350
   979  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
   980  		created := time.Now()
   981  
   982  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
   983  		require_NoError(t, err)
   984  		defer fs.Stop()
   985  
   986  		tseq := uint64(50)
   987  
   988  		subj, toStore := "foo", uint64(100)
   989  		for i := uint64(1); i < tseq; i++ {
   990  			_, _, err := fs.StoreMsg(subj, nil, []byte("ok"))
   991  			require_NoError(t, err)
   992  		}
   993  		subj = "bar"
   994  		for i := tseq; i <= toStore; i++ {
   995  			_, _, err := fs.StoreMsg(subj, nil, []byte("ok"))
   996  			require_NoError(t, err)
   997  		}
   998  
   999  		if state := fs.State(); state.Msgs != toStore {
  1000  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1001  		}
  1002  
  1003  		// Check that sequence has to be interior.
  1004  		if err := fs.Truncate(toStore + 1); err != ErrInvalidSequence {
  1005  			t.Fatalf("Expected err of '%v', got '%v'", ErrInvalidSequence, err)
  1006  		}
  1007  
  1008  		if err := fs.Truncate(tseq); err != nil {
  1009  			t.Fatalf("Unexpected error: %v", err)
  1010  		}
  1011  		if state := fs.State(); state.Msgs != tseq {
  1012  			t.Fatalf("Expected %d msgs, got %d", tseq, state.Msgs)
  1013  		}
  1014  
  1015  		// Now make sure we report properly if we have some deleted interior messages.
  1016  		fs.RemoveMsg(10)
  1017  		fs.RemoveMsg(20)
  1018  		fs.RemoveMsg(30)
  1019  		fs.RemoveMsg(40)
  1020  
  1021  		tseq = uint64(25)
  1022  		if err := fs.Truncate(tseq); err != nil {
  1023  			t.Fatalf("Unexpected error: %v", err)
  1024  		}
  1025  		state := fs.State()
  1026  		if state.Msgs != tseq-2 {
  1027  			t.Fatalf("Expected %d msgs, got %d", tseq-2, state.Msgs)
  1028  		}
  1029  		expected := []uint64{10, 20}
  1030  		if !reflect.DeepEqual(state.Deleted, expected) {
  1031  			t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted)
  1032  		}
  1033  
  1034  		before := state
  1035  
  1036  		// Make sure we can recover same state.
  1037  		fs.Stop()
  1038  
  1039  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1040  		require_NoError(t, err)
  1041  		defer fs.Stop()
  1042  
  1043  		if state := fs.State(); !reflect.DeepEqual(state, before) {
  1044  			t.Fatalf("Expected state of %+v, got %+v", before, state)
  1045  		}
  1046  
  1047  		mb := fs.getFirstBlock()
  1048  		require_True(t, mb != nil)
  1049  		require_NoError(t, mb.loadMsgs())
  1050  	})
  1051  }
  1052  
  1053  func TestFileStoreRemovePartialRecovery(t *testing.T) {
  1054  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1055  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  1056  		created := time.Now()
  1057  
  1058  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1059  		require_NoError(t, err)
  1060  		defer fs.Stop()
  1061  
  1062  		subj, msg := "foo", []byte("Hello World")
  1063  		toStore := 100
  1064  		for i := 0; i < toStore; i++ {
  1065  			fs.StoreMsg(subj, nil, msg)
  1066  		}
  1067  		state := fs.State()
  1068  		if state.Msgs != uint64(toStore) {
  1069  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1070  		}
  1071  
  1072  		// Remove half
  1073  		for i := 1; i <= toStore/2; i++ {
  1074  			fs.RemoveMsg(uint64(i))
  1075  		}
  1076  
  1077  		state = fs.State()
  1078  		if state.Msgs != uint64(toStore/2) {
  1079  			t.Fatalf("Expected %d msgs, got %d", toStore/2, state.Msgs)
  1080  		}
  1081  
  1082  		// Make sure we recover same state.
  1083  		fs.Stop()
  1084  
  1085  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1086  		require_NoError(t, err)
  1087  		defer fs.Stop()
  1088  
  1089  		state2 := fs.State()
  1090  		if !reflect.DeepEqual(state2, state) {
  1091  			t.Fatalf("Expected recovered state to be the same, got %+v vs %+v\n", state2, state)
  1092  		}
  1093  	})
  1094  }
  1095  
  1096  func TestFileStoreRemoveOutOfOrderRecovery(t *testing.T) {
  1097  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1098  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  1099  		created := time.Now()
  1100  
  1101  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1102  		require_NoError(t, err)
  1103  		defer fs.Stop()
  1104  
  1105  		subj, msg := "foo", []byte("Hello World")
  1106  		toStore := 100
  1107  		for i := 0; i < toStore; i++ {
  1108  			fs.StoreMsg(subj, nil, msg)
  1109  		}
  1110  		state := fs.State()
  1111  		if state.Msgs != uint64(toStore) {
  1112  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1113  		}
  1114  
  1115  		// Remove evens
  1116  		for i := 2; i <= toStore; i += 2 {
  1117  			if removed, _ := fs.RemoveMsg(uint64(i)); !removed {
  1118  				t.Fatalf("Expected remove to return true")
  1119  			}
  1120  		}
  1121  
  1122  		state = fs.State()
  1123  		if state.Msgs != uint64(toStore/2) {
  1124  			t.Fatalf("Expected %d msgs, got %d", toStore/2, state.Msgs)
  1125  		}
  1126  
  1127  		var smv StoreMsg
  1128  		if _, err := fs.LoadMsg(1, &smv); err != nil {
  1129  			t.Fatalf("Expected to retrieve seq 1")
  1130  		}
  1131  		for i := 2; i <= toStore; i += 2 {
  1132  			if _, err := fs.LoadMsg(uint64(i), &smv); err == nil {
  1133  				t.Fatalf("Expected error looking up seq %d that should be deleted", i)
  1134  			}
  1135  		}
  1136  
  1137  		// Make sure we recover same state.
  1138  		fs.Stop()
  1139  
  1140  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1141  		require_NoError(t, err)
  1142  		defer fs.Stop()
  1143  
  1144  		state2 := fs.State()
  1145  		if !reflect.DeepEqual(state2, state) {
  1146  			t.Fatalf("Expected recovered states to be the same, got %+v vs %+v\n", state, state2)
  1147  		}
  1148  
  1149  		if _, err := fs.LoadMsg(1, &smv); err != nil {
  1150  			t.Fatalf("Expected to retrieve seq 1")
  1151  		}
  1152  		for i := 2; i <= toStore; i += 2 {
  1153  			if _, err := fs.LoadMsg(uint64(i), nil); err == nil {
  1154  				t.Fatalf("Expected error looking up seq %d that should be deleted", i)
  1155  			}
  1156  		}
  1157  	})
  1158  }
  1159  
  1160  func TestFileStoreAgeLimitRecovery(t *testing.T) {
  1161  	maxAge := 1 * time.Second
  1162  
  1163  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1164  		fcfg.CacheExpire = 1 * time.Millisecond
  1165  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage, MaxAge: maxAge}
  1166  		created := time.Now()
  1167  
  1168  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1169  		require_NoError(t, err)
  1170  		defer fs.Stop()
  1171  
  1172  		// Store some messages. Does not really matter how many.
  1173  		subj, msg := "foo", []byte("Hello World")
  1174  		toStore := 100
  1175  		for i := 0; i < toStore; i++ {
  1176  			fs.StoreMsg(subj, nil, msg)
  1177  		}
  1178  		state := fs.State()
  1179  		if state.Msgs != uint64(toStore) {
  1180  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1181  		}
  1182  		fs.Stop()
  1183  
  1184  		time.Sleep(maxAge)
  1185  
  1186  		fcfg.CacheExpire = 0
  1187  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  1188  		require_NoError(t, err)
  1189  		defer fs.Stop()
  1190  
  1191  		// Make sure they expire.
  1192  		checkFor(t, time.Second, 2*maxAge, func() error {
  1193  			t.Helper()
  1194  			state = fs.State()
  1195  			if state.Msgs != 0 {
  1196  				return fmt.Errorf("Expected no msgs, got %d", state.Msgs)
  1197  			}
  1198  			if state.Bytes != 0 {
  1199  				return fmt.Errorf("Expected no bytes, got %d", state.Bytes)
  1200  			}
  1201  			return nil
  1202  		})
  1203  	})
  1204  }
  1205  
  1206  func TestFileStoreBitRot(t *testing.T) {
  1207  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1208  		created := time.Now()
  1209  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1210  		require_NoError(t, err)
  1211  		defer fs.Stop()
  1212  
  1213  		// Store some messages. Does not really matter how many.
  1214  		subj, msg := "foo", []byte("Hello World")
  1215  		toStore := 100
  1216  		for i := 0; i < toStore; i++ {
  1217  			fs.StoreMsg(subj, nil, msg)
  1218  		}
  1219  		state := fs.State()
  1220  		if state.Msgs != uint64(toStore) {
  1221  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1222  		}
  1223  
  1224  		if ld := fs.checkMsgs(); ld != nil && len(ld.Msgs) > 0 {
  1225  			t.Fatalf("Expected to have no corrupt msgs, got %d", len(ld.Msgs))
  1226  		}
  1227  
  1228  		for i := 0; i < 10; i++ {
  1229  			// Now twiddle some bits.
  1230  			fs.mu.Lock()
  1231  			lmb := fs.lmb
  1232  			contents, err := os.ReadFile(lmb.mfn)
  1233  			require_NoError(t, err)
  1234  			require_True(t, len(contents) > 0)
  1235  
  1236  			var index int
  1237  			for {
  1238  				index = rand.Intn(len(contents))
  1239  				// Reverse one byte anywhere.
  1240  				b := contents[index]
  1241  				contents[index] = bits.Reverse8(b)
  1242  				if b != contents[index] {
  1243  					break
  1244  				}
  1245  			}
  1246  			os.WriteFile(lmb.mfn, contents, 0644)
  1247  			fs.mu.Unlock()
  1248  
  1249  			ld := fs.checkMsgs()
  1250  			if len(ld.Msgs) > 0 {
  1251  				break
  1252  			}
  1253  			// If our bitrot caused us to not be able to recover any messages we can break as well.
  1254  			if state := fs.State(); state.Msgs == 0 {
  1255  				break
  1256  			}
  1257  			// Fail the test if we have tried the 10 times and still did not
  1258  			// get any corruption report.
  1259  			if i == 9 {
  1260  				t.Fatalf("Expected to have corrupt msgs got none: changed [%d]", index)
  1261  			}
  1262  		}
  1263  
  1264  		// Make sure we can restore.
  1265  		fs.Stop()
  1266  
  1267  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1268  		require_NoError(t, err)
  1269  		defer fs.Stop()
  1270  
  1271  		// checkMsgs will repair the underlying store, so checkMsgs should be clean now.
  1272  		if ld := fs.checkMsgs(); ld != nil {
  1273  			// If we have no msgs left this will report the head msgs as lost again.
  1274  			if state := fs.State(); state.Msgs > 0 {
  1275  				t.Fatalf("Expected no errors restoring checked and fixed filestore, got %+v", ld)
  1276  			}
  1277  		}
  1278  	})
  1279  }
  1280  
  1281  func TestFileStoreEraseMsg(t *testing.T) {
  1282  	// Just do no encryption, etc.
  1283  	fcfg := FileStoreConfig{StoreDir: t.TempDir()}
  1284  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage})
  1285  	require_NoError(t, err)
  1286  	defer fs.Stop()
  1287  
  1288  	subj, msg := "foo", []byte("Hello World")
  1289  	fs.StoreMsg(subj, nil, msg)
  1290  	fs.StoreMsg(subj, nil, msg) // To keep block from being deleted.
  1291  	var smv StoreMsg
  1292  	sm, err := fs.LoadMsg(1, &smv)
  1293  	if err != nil {
  1294  		t.Fatalf("Unexpected error looking up msg: %v", err)
  1295  	}
  1296  	if !bytes.Equal(msg, sm.msg) {
  1297  		t.Fatalf("Expected same msg, got %q vs %q", sm.msg, msg)
  1298  	}
  1299  	if removed, _ := fs.EraseMsg(1); !removed {
  1300  		t.Fatalf("Expected erase msg to return success")
  1301  	}
  1302  	if sm2, _ := fs.msgForSeq(1, nil); sm2 != nil {
  1303  		t.Fatalf("Expected msg to be erased")
  1304  	}
  1305  	fs.checkAndFlushAllBlocks()
  1306  
  1307  	// Now look on disk as well.
  1308  	rl := fileStoreMsgSize(subj, nil, msg)
  1309  	buf := make([]byte, rl)
  1310  	fp, err := os.Open(filepath.Join(fcfg.StoreDir, msgDir, fmt.Sprintf(blkScan, 1)))
  1311  	if err != nil {
  1312  		t.Fatalf("Error opening msg block file: %v", err)
  1313  	}
  1314  	defer fp.Close()
  1315  
  1316  	fp.ReadAt(buf, 0)
  1317  	fs.mu.RLock()
  1318  	mb := fs.blks[0]
  1319  	fs.mu.RUnlock()
  1320  	mb.mu.Lock()
  1321  	sm, err = mb.msgFromBuf(buf, nil, nil)
  1322  	mb.mu.Unlock()
  1323  	if err != nil {
  1324  		t.Fatalf("error reading message from block: %v", err)
  1325  	}
  1326  	if sm.subj == subj {
  1327  		t.Fatalf("Expected the subjects to be different")
  1328  	}
  1329  	if sm.seq != 0 && sm.seq&ebit == 0 {
  1330  		t.Fatalf("Expected seq to be 0, marking as deleted, got %d", sm.seq)
  1331  	}
  1332  	if sm.ts != 0 {
  1333  		t.Fatalf("Expected timestamp to be 0, got %d", sm.ts)
  1334  	}
  1335  	if bytes.Equal(sm.msg, msg) {
  1336  		t.Fatalf("Expected message body to be randomized")
  1337  	}
  1338  }
  1339  
  1340  func TestFileStoreEraseAndNoIndexRecovery(t *testing.T) {
  1341  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1342  		created := time.Now()
  1343  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1344  		require_NoError(t, err)
  1345  		defer fs.Stop()
  1346  
  1347  		subj, msg := "foo", []byte("Hello World")
  1348  		toStore := 100
  1349  		for i := 0; i < toStore; i++ {
  1350  			fs.StoreMsg(subj, nil, msg)
  1351  		}
  1352  		state := fs.State()
  1353  		if state.Msgs != uint64(toStore) {
  1354  			t.Fatalf("Expected %d msgs, got %d", toStore, state.Msgs)
  1355  		}
  1356  
  1357  		// Erase the even messages.
  1358  		for i := 2; i <= toStore; i += 2 {
  1359  			if removed, _ := fs.EraseMsg(uint64(i)); !removed {
  1360  				t.Fatalf("Expected erase msg to return true")
  1361  			}
  1362  		}
  1363  		state = fs.State()
  1364  		if state.Msgs != uint64(toStore/2) {
  1365  			t.Fatalf("Expected %d msgs, got %d", toStore/2, state.Msgs)
  1366  		}
  1367  
  1368  		// Stop and remove the optional index file.
  1369  		fs.Stop()
  1370  		ifn := filepath.Join(fcfg.StoreDir, msgDir, fmt.Sprintf(indexScan, 1))
  1371  		os.Remove(ifn)
  1372  
  1373  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1374  		require_NoError(t, err)
  1375  		defer fs.Stop()
  1376  
  1377  		state = fs.State()
  1378  		if state.Msgs != uint64(toStore/2) {
  1379  			t.Fatalf("Expected %d msgs, got %d", toStore/2, state.Msgs)
  1380  		}
  1381  
  1382  		for i := 2; i <= toStore; i += 2 {
  1383  			if _, err := fs.LoadMsg(uint64(i), nil); err == nil {
  1384  				t.Fatalf("Expected error looking up seq %d that should be erased", i)
  1385  			}
  1386  		}
  1387  	})
  1388  }
  1389  
  1390  func TestFileStoreMeta(t *testing.T) {
  1391  	// Just do no encryption, etc.
  1392  	fcfg := FileStoreConfig{StoreDir: t.TempDir()}
  1393  	mconfig := StreamConfig{Name: "ZZ-22-33", Storage: FileStorage, Subjects: []string{"foo.*"}, Replicas: 22}
  1394  	fs, err := newFileStore(fcfg, mconfig)
  1395  	require_NoError(t, err)
  1396  	defer fs.Stop()
  1397  
  1398  	metafile := filepath.Join(fcfg.StoreDir, JetStreamMetaFile)
  1399  	metasum := filepath.Join(fcfg.StoreDir, JetStreamMetaFileSum)
  1400  
  1401  	// Test to make sure meta file and checksum are present.
  1402  	if _, err := os.Stat(metafile); os.IsNotExist(err) {
  1403  		t.Fatalf("Expected metafile %q to exist", metafile)
  1404  	}
  1405  	if _, err := os.Stat(metasum); os.IsNotExist(err) {
  1406  		t.Fatalf("Expected metafile's checksum %q to exist", metasum)
  1407  	}
  1408  
  1409  	buf, err := os.ReadFile(metafile)
  1410  	if err != nil {
  1411  		t.Fatalf("Error reading metafile: %v", err)
  1412  	}
  1413  	var mconfig2 StreamConfig
  1414  	if err := json.Unmarshal(buf, &mconfig2); err != nil {
  1415  		t.Fatalf("Error unmarshalling: %v", err)
  1416  	}
  1417  	if !reflect.DeepEqual(mconfig, mconfig2) {
  1418  		t.Fatalf("Stream configs not equal, got %+v vs %+v", mconfig2, mconfig)
  1419  	}
  1420  	checksum, err := os.ReadFile(metasum)
  1421  	if err != nil {
  1422  		t.Fatalf("Error reading metafile checksum: %v", err)
  1423  	}
  1424  
  1425  	fs.mu.Lock()
  1426  	fs.hh.Reset()
  1427  	fs.hh.Write(buf)
  1428  	mychecksum := hex.EncodeToString(fs.hh.Sum(nil))
  1429  	fs.mu.Unlock()
  1430  
  1431  	if mychecksum != string(checksum) {
  1432  		t.Fatalf("Checksums do not match, got %q vs %q", mychecksum, checksum)
  1433  	}
  1434  
  1435  	// Now create a consumer. Same deal for them.
  1436  	oconfig := ConsumerConfig{
  1437  		DeliverSubject: "d",
  1438  		FilterSubject:  "foo",
  1439  		AckPolicy:      AckAll,
  1440  	}
  1441  	oname := "obs22"
  1442  	obs, err := fs.ConsumerStore(oname, &oconfig)
  1443  	if err != nil {
  1444  		t.Fatalf("Unexpected error: %v", err)
  1445  	}
  1446  
  1447  	ometafile := filepath.Join(fcfg.StoreDir, consumerDir, oname, JetStreamMetaFile)
  1448  	ometasum := filepath.Join(fcfg.StoreDir, consumerDir, oname, JetStreamMetaFileSum)
  1449  
  1450  	// Test to make sure meta file and checksum are present.
  1451  	if _, err := os.Stat(ometafile); os.IsNotExist(err) {
  1452  		t.Fatalf("Expected consumer metafile %q to exist", ometafile)
  1453  	}
  1454  	if _, err := os.Stat(ometasum); os.IsNotExist(err) {
  1455  		t.Fatalf("Expected consumer metafile's checksum %q to exist", ometasum)
  1456  	}
  1457  
  1458  	buf, err = os.ReadFile(ometafile)
  1459  	if err != nil {
  1460  		t.Fatalf("Error reading consumer metafile: %v", err)
  1461  	}
  1462  
  1463  	var oconfig2 ConsumerConfig
  1464  	if err := json.Unmarshal(buf, &oconfig2); err != nil {
  1465  		t.Fatalf("Error unmarshalling: %v", err)
  1466  	}
  1467  	// Since we set name we will get that back now.
  1468  	oconfig.Name = oname
  1469  	if !reflect.DeepEqual(oconfig2, oconfig) {
  1470  		t.Fatalf("Consumer configs not equal, got %+v vs %+v", oconfig2, oconfig)
  1471  	}
  1472  	checksum, err = os.ReadFile(ometasum)
  1473  
  1474  	if err != nil {
  1475  		t.Fatalf("Error reading consumer metafile checksum: %v", err)
  1476  	}
  1477  
  1478  	hh := obs.(*consumerFileStore).hh
  1479  	hh.Reset()
  1480  	hh.Write(buf)
  1481  	mychecksum = hex.EncodeToString(hh.Sum(nil))
  1482  	if mychecksum != string(checksum) {
  1483  		t.Fatalf("Checksums do not match, got %q vs %q", mychecksum, checksum)
  1484  	}
  1485  }
  1486  
  1487  func TestFileStoreWriteAndReadSameBlock(t *testing.T) {
  1488  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1489  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1490  		require_NoError(t, err)
  1491  		defer fs.Stop()
  1492  
  1493  		subj, msg := "foo", []byte("Hello World!")
  1494  
  1495  		for i := uint64(1); i <= 10; i++ {
  1496  			fs.StoreMsg(subj, nil, msg)
  1497  			if _, err := fs.LoadMsg(i, nil); err != nil {
  1498  				t.Fatalf("Error loading %d: %v", i, err)
  1499  			}
  1500  		}
  1501  	})
  1502  }
  1503  
  1504  func TestFileStoreAndRetrieveMultiBlock(t *testing.T) {
  1505  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1506  		subj, msg := "foo", []byte("Hello World!")
  1507  		storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  1508  
  1509  		fcfg.BlockSize = 4 * storedMsgSize
  1510  		created := time.Now()
  1511  
  1512  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1513  		require_NoError(t, err)
  1514  		defer fs.Stop()
  1515  
  1516  		for i := 0; i < 20; i++ {
  1517  			fs.StoreMsg(subj, nil, msg)
  1518  		}
  1519  		state := fs.State()
  1520  		if state.Msgs != 20 {
  1521  			t.Fatalf("Expected 20 msgs, got %d", state.Msgs)
  1522  		}
  1523  		fs.Stop()
  1524  
  1525  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  1526  		require_NoError(t, err)
  1527  		defer fs.Stop()
  1528  
  1529  		var smv StoreMsg
  1530  		for i := uint64(1); i <= 20; i++ {
  1531  			if _, err := fs.LoadMsg(i, &smv); err != nil {
  1532  				t.Fatalf("Error loading %d: %v", i, err)
  1533  			}
  1534  		}
  1535  	})
  1536  }
  1537  
  1538  func TestFileStoreCollapseDmap(t *testing.T) {
  1539  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1540  		subj, msg := "foo", []byte("Hello World!")
  1541  		storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  1542  
  1543  		fcfg.BlockSize = 4 * storedMsgSize
  1544  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1545  		require_NoError(t, err)
  1546  		defer fs.Stop()
  1547  
  1548  		for i := 0; i < 10; i++ {
  1549  			fs.StoreMsg(subj, nil, msg)
  1550  		}
  1551  		state := fs.State()
  1552  		if state.Msgs != 10 {
  1553  			t.Fatalf("Expected 10 msgs, got %d", state.Msgs)
  1554  		}
  1555  
  1556  		checkDmapTotal := func(total int) {
  1557  			t.Helper()
  1558  			if nde := fs.dmapEntries(); nde != total {
  1559  				t.Fatalf("Expecting only %d entries, got %d", total, nde)
  1560  			}
  1561  		}
  1562  
  1563  		checkFirstSeq := func(seq uint64) {
  1564  			t.Helper()
  1565  			state := fs.State()
  1566  			if state.FirstSeq != seq {
  1567  				t.Fatalf("Expected first seq to be %d, got %d", seq, state.FirstSeq)
  1568  			}
  1569  		}
  1570  
  1571  		// Now remove some out of order, forming gaps and entries in dmaps.
  1572  		fs.RemoveMsg(2)
  1573  		checkFirstSeq(1)
  1574  		fs.RemoveMsg(4)
  1575  		checkFirstSeq(1)
  1576  		fs.RemoveMsg(8)
  1577  		checkFirstSeq(1)
  1578  
  1579  		state = fs.State()
  1580  		if state.Msgs != 7 {
  1581  			t.Fatalf("Expected 7 msgs, got %d", state.Msgs)
  1582  		}
  1583  
  1584  		checkDmapTotal(3)
  1585  
  1586  		// Close gaps..
  1587  		fs.RemoveMsg(1)
  1588  		checkDmapTotal(2)
  1589  		checkFirstSeq(3)
  1590  
  1591  		fs.RemoveMsg(3)
  1592  		checkDmapTotal(1)
  1593  		checkFirstSeq(5)
  1594  
  1595  		fs.RemoveMsg(5)
  1596  		checkDmapTotal(1)
  1597  		checkFirstSeq(6)
  1598  
  1599  		fs.RemoveMsg(7)
  1600  		checkDmapTotal(2)
  1601  
  1602  		fs.RemoveMsg(6)
  1603  		checkDmapTotal(0)
  1604  	})
  1605  }
  1606  
  1607  func TestFileStoreReadCache(t *testing.T) {
  1608  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1609  		fcfg.CacheExpire = 100 * time.Millisecond
  1610  
  1611  		subj, msg := "foo.bar", make([]byte, 1024)
  1612  		storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  1613  
  1614  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1615  		require_NoError(t, err)
  1616  		defer fs.Stop()
  1617  
  1618  		toStore := 500
  1619  		totalBytes := uint64(toStore) * storedMsgSize
  1620  
  1621  		for i := 0; i < toStore; i++ {
  1622  			fs.StoreMsg(subj, nil, msg)
  1623  		}
  1624  
  1625  		// Wait for cache to go to zero.
  1626  		checkFor(t, time.Second, 10*time.Millisecond, func() error {
  1627  			if csz := fs.cacheSize(); csz != 0 {
  1628  				return fmt.Errorf("cache size not 0, got %s", friendlyBytes(int64(csz)))
  1629  			}
  1630  			return nil
  1631  		})
  1632  
  1633  		fs.LoadMsg(1, nil)
  1634  		if csz := fs.cacheSize(); csz != totalBytes {
  1635  			t.Fatalf("Expected all messages to be cached, got %d vs %d", csz, totalBytes)
  1636  		}
  1637  		// Should expire and be removed.
  1638  		checkFor(t, time.Second, 10*time.Millisecond, func() error {
  1639  			if csz := fs.cacheSize(); csz != 0 {
  1640  				return fmt.Errorf("cache size not 0, got %s", friendlyBytes(int64(csz)))
  1641  			}
  1642  			return nil
  1643  		})
  1644  		if cls := fs.cacheLoads(); cls != 1 {
  1645  			t.Fatalf("Expected only 1 cache load, got %d", cls)
  1646  		}
  1647  		// Now make sure we do not reload cache if there is activity.
  1648  		fs.LoadMsg(1, nil)
  1649  		timeout := time.Now().Add(250 * time.Millisecond)
  1650  		for time.Now().Before(timeout) {
  1651  			if cls := fs.cacheLoads(); cls != 2 {
  1652  				t.Fatalf("cache loads not 2, got %d", cls)
  1653  			}
  1654  			time.Sleep(5 * time.Millisecond)
  1655  			fs.LoadMsg(1, nil) // register activity.
  1656  		}
  1657  	})
  1658  }
  1659  
  1660  func TestFileStorePartialCacheExpiration(t *testing.T) {
  1661  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1662  		cexp := 10 * time.Millisecond
  1663  		fcfg.CacheExpire = cexp
  1664  
  1665  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1666  		require_NoError(t, err)
  1667  		defer fs.Stop()
  1668  
  1669  		fs.StoreMsg("foo", nil, []byte("msg1"))
  1670  
  1671  		// Should expire and be removed.
  1672  		time.Sleep(2 * cexp)
  1673  		fs.StoreMsg("bar", nil, []byte("msg2"))
  1674  
  1675  		// Again wait for cache to expire.
  1676  		time.Sleep(2 * cexp)
  1677  		if _, err := fs.LoadMsg(1, nil); err != nil {
  1678  			t.Fatalf("Error loading message 1: %v", err)
  1679  		}
  1680  	})
  1681  }
  1682  
  1683  func TestFileStorePartialIndexes(t *testing.T) {
  1684  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1685  		cexp := 10 * time.Millisecond
  1686  		fcfg.CacheExpire = cexp
  1687  
  1688  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1689  		require_NoError(t, err)
  1690  		defer fs.Stop()
  1691  
  1692  		toSend := 5
  1693  		for i := 0; i < toSend; i++ {
  1694  			fs.StoreMsg("foo", nil, []byte("ok-1"))
  1695  		}
  1696  
  1697  		// Now wait til the cache expires, including the index.
  1698  		fs.mu.Lock()
  1699  		mb := fs.blks[0]
  1700  		fs.mu.Unlock()
  1701  
  1702  		// Force idx to expire by resetting last remove ts.
  1703  		mb.mu.Lock()
  1704  		mb.llts = mb.llts - int64(defaultCacheBufferExpiration*2)
  1705  		mb.mu.Unlock()
  1706  
  1707  		checkFor(t, time.Second, 10*time.Millisecond, func() error {
  1708  			mb.mu.Lock()
  1709  			defer mb.mu.Unlock()
  1710  			if mb.cache == nil || len(mb.cache.idx) == 0 {
  1711  				return nil
  1712  			}
  1713  			return fmt.Errorf("Index not empty")
  1714  		})
  1715  
  1716  		// Create a partial cache by adding more msgs.
  1717  		for i := 0; i < toSend; i++ {
  1718  			fs.StoreMsg("foo", nil, []byte("ok-2"))
  1719  		}
  1720  		// If we now load in a message in second half if we do not
  1721  		// detect idx is a partial correctly this will panic.
  1722  		if _, err := fs.LoadMsg(8, nil); err != nil {
  1723  			t.Fatalf("Error loading %d: %v", 1, err)
  1724  		}
  1725  	})
  1726  }
  1727  
  1728  func TestFileStoreSnapshot(t *testing.T) {
  1729  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1730  		subj, msg := "foo", []byte("Hello Snappy!")
  1731  		scfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  1732  
  1733  		fs, err := newFileStoreWithCreated(fcfg, scfg, time.Now(), prf(&fcfg), nil)
  1734  		require_NoError(t, err)
  1735  		defer fs.Stop()
  1736  
  1737  		toSend := 2233
  1738  		for i := 0; i < toSend; i++ {
  1739  			fs.StoreMsg(subj, nil, msg)
  1740  		}
  1741  
  1742  		// Create a few consumers.
  1743  		o1, err := fs.ConsumerStore("o22", &ConsumerConfig{})
  1744  		if err != nil {
  1745  			t.Fatalf("Unexpected error: %v", err)
  1746  		}
  1747  		o2, err := fs.ConsumerStore("o33", &ConsumerConfig{})
  1748  		if err != nil {
  1749  			t.Fatalf("Unexpected error: %v", err)
  1750  		}
  1751  		state := &ConsumerState{}
  1752  		state.Delivered.Consumer = 100
  1753  		state.Delivered.Stream = 100
  1754  		state.AckFloor.Consumer = 22
  1755  		state.AckFloor.Stream = 22
  1756  
  1757  		if err := o1.Update(state); err != nil {
  1758  			t.Fatalf("Unexpected error updating state: %v", err)
  1759  		}
  1760  		state.AckFloor.Consumer = 33
  1761  		state.AckFloor.Stream = 33
  1762  
  1763  		if err := o2.Update(state); err != nil {
  1764  			t.Fatalf("Unexpected error updating state: %v", err)
  1765  		}
  1766  
  1767  		snapshot := func() []byte {
  1768  			t.Helper()
  1769  			r, err := fs.Snapshot(5*time.Second, true, true)
  1770  			if err != nil {
  1771  				t.Fatalf("Error creating snapshot")
  1772  			}
  1773  			snapshot, err := io.ReadAll(r.Reader)
  1774  			if err != nil {
  1775  				t.Fatalf("Error reading snapshot")
  1776  			}
  1777  			return snapshot
  1778  		}
  1779  
  1780  		// This will unzip the snapshot and create a new filestore that will recover the state.
  1781  		// We will compare the states for this vs the original one.
  1782  		verifySnapshot := func(snap []byte) {
  1783  			t.Helper()
  1784  			r := bytes.NewReader(snap)
  1785  			tr := tar.NewReader(s2.NewReader(r))
  1786  
  1787  			rstoreDir := t.TempDir()
  1788  
  1789  			for {
  1790  				hdr, err := tr.Next()
  1791  				if err == io.EOF {
  1792  					break // End of archive
  1793  				}
  1794  				if err != nil {
  1795  					t.Fatalf("Error getting next entry from snapshot: %v", err)
  1796  				}
  1797  				fpath := filepath.Join(rstoreDir, filepath.Clean(hdr.Name))
  1798  				pdir := filepath.Dir(fpath)
  1799  				os.MkdirAll(pdir, 0755)
  1800  				fd, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0600)
  1801  				if err != nil {
  1802  					t.Fatalf("Error opening file[%s]: %v", fpath, err)
  1803  				}
  1804  				if _, err := io.Copy(fd, tr); err != nil {
  1805  					t.Fatalf("Error writing file[%s]: %v", fpath, err)
  1806  				}
  1807  				fd.Close()
  1808  			}
  1809  
  1810  			fcfg.StoreDir = rstoreDir
  1811  			fsr, err := newFileStoreWithCreated(fcfg, scfg, time.Now(), prf(&fcfg), nil)
  1812  			require_NoError(t, err)
  1813  			defer fsr.Stop()
  1814  			state := fs.State()
  1815  			rstate := fsr.State()
  1816  
  1817  			// FIXME(dlc)
  1818  			// Right now the upper layers in JetStream recover the consumers and do not expect
  1819  			// the lower layers to do that. So for now blank that out of our original state.
  1820  			// Will have more exhaustive tests in jetstream_test.go.
  1821  			state.Consumers = 0
  1822  
  1823  			// Just check the state.
  1824  			if !reflect.DeepEqual(rstate, state) {
  1825  				t.Fatalf("Restored state does not match:\n%+v\n\n%+v", rstate, state)
  1826  			}
  1827  		}
  1828  
  1829  		// Simple case first.
  1830  		snap := snapshot()
  1831  		verifySnapshot(snap)
  1832  
  1833  		// Remove first 100 messages.
  1834  		for i := 1; i <= 100; i++ {
  1835  			fs.RemoveMsg(uint64(i))
  1836  		}
  1837  
  1838  		snap = snapshot()
  1839  		verifySnapshot(snap)
  1840  
  1841  		// Now sporadic messages inside the stream.
  1842  		total := int64(toSend - 100)
  1843  		// Delete 50 random messages.
  1844  		for i := 0; i < 50; i++ {
  1845  			seq := uint64(rand.Int63n(total) + 101)
  1846  			fs.RemoveMsg(seq)
  1847  		}
  1848  
  1849  		snap = snapshot()
  1850  		verifySnapshot(snap)
  1851  
  1852  		// Make sure compaction works with snapshots.
  1853  		fs.mu.RLock()
  1854  		for _, mb := range fs.blks {
  1855  			// Should not call compact on last msg block.
  1856  			if mb != fs.lmb {
  1857  				mb.mu.Lock()
  1858  				mb.compact()
  1859  				mb.mu.Unlock()
  1860  			}
  1861  		}
  1862  		fs.mu.RUnlock()
  1863  
  1864  		snap = snapshot()
  1865  		verifySnapshot(snap)
  1866  
  1867  		// Now check to make sure that we get the correct error when trying to delete or erase
  1868  		// a message when a snapshot is in progress and that closing the reader releases that condition.
  1869  		sr, err := fs.Snapshot(5*time.Second, false, true)
  1870  		if err != nil {
  1871  			t.Fatalf("Error creating snapshot")
  1872  		}
  1873  		if _, err := fs.RemoveMsg(122); err != ErrStoreSnapshotInProgress {
  1874  			t.Fatalf("Did not get the correct error on remove during snapshot: %v", err)
  1875  		}
  1876  		if _, err := fs.EraseMsg(122); err != ErrStoreSnapshotInProgress {
  1877  			t.Fatalf("Did not get the correct error on remove during snapshot: %v", err)
  1878  		}
  1879  
  1880  		// Now make sure we can do these when we close the reader and release the snapshot condition.
  1881  		sr.Reader.Close()
  1882  		checkFor(t, time.Second, 10*time.Millisecond, func() error {
  1883  			if _, err := fs.RemoveMsg(122); err != nil {
  1884  				return fmt.Errorf("Got an error on remove after snapshot: %v", err)
  1885  			}
  1886  			return nil
  1887  		})
  1888  
  1889  		// Make sure if we do not read properly then it will close the writer and report an error.
  1890  		sr, err = fs.Snapshot(25*time.Millisecond, false, false)
  1891  		if err != nil {
  1892  			t.Fatalf("Error creating snapshot")
  1893  		}
  1894  
  1895  		// Cause snapshot to timeout.
  1896  		time.Sleep(50 * time.Millisecond)
  1897  		// Read should fail
  1898  		var buf [32]byte
  1899  		if _, err := sr.Reader.Read(buf[:]); err != io.EOF {
  1900  			t.Fatalf("Expected read to produce an error, got none")
  1901  		}
  1902  	})
  1903  }
  1904  
  1905  func TestFileStoreConsumer(t *testing.T) {
  1906  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  1907  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  1908  		require_NoError(t, err)
  1909  		defer fs.Stop()
  1910  
  1911  		o, err := fs.ConsumerStore("obs22", &ConsumerConfig{})
  1912  		if err != nil {
  1913  			t.Fatalf("Unexpected error: %v", err)
  1914  		}
  1915  		if state, err := o.State(); err != nil || state.Delivered.Consumer != 0 {
  1916  			t.Fatalf("Unexpected state or error: %v", err)
  1917  		}
  1918  
  1919  		state := &ConsumerState{}
  1920  
  1921  		updateAndCheck := func() {
  1922  			t.Helper()
  1923  			if err := o.Update(state); err != nil {
  1924  				t.Fatalf("Unexpected error updating state: %v", err)
  1925  			}
  1926  			s2, err := o.State()
  1927  			if err != nil {
  1928  				t.Fatalf("Unexpected error getting state: %v", err)
  1929  			}
  1930  			if !reflect.DeepEqual(state, s2) {
  1931  				t.Fatalf("State is not the same: wanted %+v got %+v", state, s2)
  1932  			}
  1933  		}
  1934  
  1935  		shouldFail := func() {
  1936  			t.Helper()
  1937  			if err := o.Update(state); err == nil {
  1938  				t.Fatalf("Expected an error and got none")
  1939  			}
  1940  		}
  1941  
  1942  		state.Delivered.Consumer = 1
  1943  		state.Delivered.Stream = 22
  1944  		updateAndCheck()
  1945  
  1946  		state.Delivered.Consumer = 100
  1947  		state.Delivered.Stream = 122
  1948  		state.AckFloor.Consumer = 50
  1949  		state.AckFloor.Stream = 123
  1950  		// This should fail, bad state.
  1951  		shouldFail()
  1952  		// So should this.
  1953  		state.AckFloor.Consumer = 200
  1954  		state.AckFloor.Stream = 100
  1955  		shouldFail()
  1956  
  1957  		// Should succeed
  1958  		state.AckFloor.Consumer = 50
  1959  		state.AckFloor.Stream = 72
  1960  		updateAndCheck()
  1961  
  1962  		tn := time.Now().UnixNano()
  1963  
  1964  		// We should sanity check pending here as well, so will check if a pending value is below
  1965  		// ack floor or above delivered.
  1966  		state.Pending = map[uint64]*Pending{70: {70, tn}}
  1967  		shouldFail()
  1968  		state.Pending = map[uint64]*Pending{140: {140, tn}}
  1969  		shouldFail()
  1970  		state.Pending = map[uint64]*Pending{72: {72, tn}} // exact on floor should fail
  1971  		shouldFail()
  1972  
  1973  		// Put timestamps a second apart.
  1974  		// We will downsample to second resolution to save space. So setup our times
  1975  		// to reflect that.
  1976  		ago := time.Now().Add(-30 * time.Second).Truncate(time.Second)
  1977  		nt := func() *Pending {
  1978  			ago = ago.Add(time.Second)
  1979  			return &Pending{0, ago.UnixNano()}
  1980  		}
  1981  		// Should succeed.
  1982  		state.Pending = map[uint64]*Pending{75: nt(), 80: nt(), 83: nt(), 90: nt(), 111: nt()}
  1983  		updateAndCheck()
  1984  
  1985  		// Now do redlivery, but first with no pending.
  1986  		state.Pending = nil
  1987  		state.Redelivered = map[uint64]uint64{22: 3, 44: 8}
  1988  		updateAndCheck()
  1989  
  1990  		// All together.
  1991  		state.Pending = map[uint64]*Pending{75: nt(), 80: nt(), 83: nt(), 90: nt(), 111: nt()}
  1992  		updateAndCheck()
  1993  
  1994  		// Large one
  1995  		state.Delivered.Consumer = 10000
  1996  		state.Delivered.Stream = 10000
  1997  		state.AckFloor.Consumer = 100
  1998  		state.AckFloor.Stream = 100
  1999  		// Generate 8k pending.
  2000  		state.Pending = make(map[uint64]*Pending)
  2001  		for len(state.Pending) < 8192 {
  2002  			seq := uint64(rand.Intn(9890) + 101)
  2003  			if _, ok := state.Pending[seq]; !ok {
  2004  				state.Pending[seq] = nt()
  2005  			}
  2006  		}
  2007  		updateAndCheck()
  2008  
  2009  		state.Pending = nil
  2010  		state.AckFloor.Consumer = 10000
  2011  		state.AckFloor.Stream = 10000
  2012  		updateAndCheck()
  2013  	})
  2014  }
  2015  
  2016  func TestFileStoreConsumerEncodeDecodeRedelivered(t *testing.T) {
  2017  	state := &ConsumerState{}
  2018  
  2019  	state.Delivered.Consumer = 100
  2020  	state.Delivered.Stream = 100
  2021  	state.AckFloor.Consumer = 50
  2022  	state.AckFloor.Stream = 50
  2023  
  2024  	state.Redelivered = map[uint64]uint64{122: 3, 144: 8}
  2025  	buf := encodeConsumerState(state)
  2026  
  2027  	rstate, err := decodeConsumerState(buf)
  2028  	if err != nil {
  2029  		t.Fatalf("Unexpected error: %v", err)
  2030  	}
  2031  	if !reflect.DeepEqual(state, rstate) {
  2032  		t.Fatalf("States do not match: %+v vs %+v", state, rstate)
  2033  	}
  2034  }
  2035  
  2036  func TestFileStoreConsumerEncodeDecodePendingBelowStreamAckFloor(t *testing.T) {
  2037  	state := &ConsumerState{}
  2038  
  2039  	state.Delivered.Consumer = 1192
  2040  	state.Delivered.Stream = 10185
  2041  	state.AckFloor.Consumer = 1189
  2042  	state.AckFloor.Stream = 10815
  2043  
  2044  	now := time.Now().Round(time.Second).Add(-10 * time.Second).UnixNano()
  2045  	state.Pending = map[uint64]*Pending{
  2046  		10782: {1190, now},
  2047  		10810: {1191, now + int64(time.Second)},
  2048  		10815: {1192, now + int64(2*time.Second)},
  2049  	}
  2050  	buf := encodeConsumerState(state)
  2051  
  2052  	rstate, err := decodeConsumerState(buf)
  2053  	if err != nil {
  2054  		t.Fatalf("Unexpected error: %v", err)
  2055  	}
  2056  	if len(rstate.Pending) != 3 {
  2057  		t.Fatalf("Invalid pending: %v", rstate.Pending)
  2058  	}
  2059  	for k, v := range state.Pending {
  2060  		rv, ok := rstate.Pending[k]
  2061  		if !ok {
  2062  			t.Fatalf("Did not find sseq=%v", k)
  2063  		}
  2064  		if !reflect.DeepEqual(v, rv) {
  2065  			t.Fatalf("Pending for sseq=%v should be %+v, got %+v", k, v, rv)
  2066  		}
  2067  	}
  2068  	state.Pending, rstate.Pending = nil, nil
  2069  	if !reflect.DeepEqual(*state, *rstate) {
  2070  		t.Fatalf("States do not match: %+v vs %+v", state, rstate)
  2071  	}
  2072  }
  2073  
  2074  func TestFileStoreWriteFailures(t *testing.T) {
  2075  	// This test should be run inside an environment where this directory
  2076  	// has a limited size.
  2077  	// E.g. Docker
  2078  	// docker run -ti --tmpfs /jswf_test:rw,size=32k --rm -v ~/Development/go/src:/go/src -w /go/src/github.com/nats-io/nats-server/ golang:1.21 /bin/bash
  2079  	tdir := filepath.Join("/", "jswf_test")
  2080  	if stat, err := os.Stat(tdir); err != nil || !stat.IsDir() {
  2081  		t.SkipNow()
  2082  	}
  2083  
  2084  	storeDir := filepath.Join(tdir, JetStreamStoreDir)
  2085  	os.MkdirAll(storeDir, 0755)
  2086  
  2087  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2088  		fcfg.StoreDir = storeDir
  2089  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  2090  		created := time.Now()
  2091  
  2092  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  2093  		require_NoError(t, err)
  2094  		defer fs.Stop()
  2095  
  2096  		subj, msg := "foo", []byte("Hello Write Failures!")
  2097  
  2098  		var lseq uint64
  2099  		// msz about will be ~54 bytes, so if limit is 32k trying to send 1000 will fail at some point.
  2100  		for i := 1; i <= 1000; i++ {
  2101  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2102  				lseq = uint64(i)
  2103  				break
  2104  			}
  2105  		}
  2106  		if lseq == 0 {
  2107  			t.Fatalf("Expected to get a failure but did not")
  2108  		}
  2109  
  2110  		state := fs.State()
  2111  
  2112  		if state.LastSeq != lseq-1 {
  2113  			t.Fatalf("Expected last seq to be %d, got %d\n", lseq-1, state.LastSeq)
  2114  		}
  2115  		if state.Msgs != lseq-1 {
  2116  			t.Fatalf("Expected total msgs to be %d, got %d\n", lseq-1, state.Msgs)
  2117  		}
  2118  		if _, err := fs.LoadMsg(lseq, nil); err == nil {
  2119  			t.Fatalf("Expected error loading seq that failed, got none")
  2120  		}
  2121  		// Loading should still work.
  2122  		if _, err := fs.LoadMsg(1, nil); err != nil {
  2123  			t.Fatalf("Unexpected error: %v", err)
  2124  		}
  2125  
  2126  		// Make sure we recover same state.
  2127  		fs.Stop()
  2128  
  2129  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  2130  		require_NoError(t, err)
  2131  		defer fs.Stop()
  2132  
  2133  		state2 := fs.State()
  2134  
  2135  		// Ignore lost state.
  2136  		state.Lost, state2.Lost = nil, nil
  2137  		if !reflect.DeepEqual(state2, state) {
  2138  			t.Fatalf("Expected recovered state to be the same\n%+v\nvs\n%+v\n", state2, state)
  2139  		}
  2140  
  2141  		// We should still fail here.
  2142  		for i := 1; i <= 100; i++ {
  2143  			_, _, err = fs.StoreMsg(subj, nil, msg)
  2144  			if err != nil {
  2145  				break
  2146  			}
  2147  		}
  2148  		require_Error(t, err)
  2149  
  2150  		lseq = fs.State().LastSeq + 1
  2151  
  2152  		// Purge should help.
  2153  		if _, err := fs.Purge(); err != nil {
  2154  			t.Fatalf("Unexpected error: %v", err)
  2155  		}
  2156  		// Wait for purge to complete its out of band processing.
  2157  		time.Sleep(50 * time.Millisecond)
  2158  
  2159  		// Check we will fail again in same spot.
  2160  		for i := 1; i <= 1000; i++ {
  2161  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2162  				if i != int(lseq) {
  2163  					t.Fatalf("Expected to fail after purge about the same spot, wanted %d got %d", lseq, i)
  2164  				}
  2165  				break
  2166  			}
  2167  		}
  2168  	})
  2169  }
  2170  
  2171  func TestFileStorePerf(t *testing.T) {
  2172  	// Comment out to run, holding place for now.
  2173  	t.SkipNow()
  2174  
  2175  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2176  		fcfg.AsyncFlush = true
  2177  
  2178  		subj, msg := "foo", make([]byte, 1024-33)
  2179  		for i := 0; i < len(msg); i++ {
  2180  			msg[i] = 'D'
  2181  		}
  2182  		storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  2183  
  2184  		// 5GB
  2185  		toStore := 5 * 1024 * 1024 * 1024 / storedMsgSize
  2186  
  2187  		fmt.Printf("storing %d msgs of %s each, totalling %s\n",
  2188  			toStore,
  2189  			friendlyBytes(int64(storedMsgSize)),
  2190  			friendlyBytes(int64(toStore*storedMsgSize)),
  2191  		)
  2192  
  2193  		created := time.Now()
  2194  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  2195  		require_NoError(t, err)
  2196  		defer fs.Stop()
  2197  
  2198  		start := time.Now()
  2199  		for i := 0; i < int(toStore); i++ {
  2200  			fs.StoreMsg(subj, nil, msg)
  2201  		}
  2202  		fs.Stop()
  2203  
  2204  		tt := time.Since(start)
  2205  		fmt.Printf("time to store is %v\n", tt)
  2206  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2207  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2208  
  2209  		fmt.Printf("Filesystem cache flush, paused 5 seconds.\n\n")
  2210  		time.Sleep(5 * time.Second)
  2211  
  2212  		fmt.Printf("Restoring..\n")
  2213  		start = time.Now()
  2214  		fcfg.AsyncFlush = false
  2215  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  2216  		require_NoError(t, err)
  2217  		defer fs.Stop()
  2218  
  2219  		fmt.Printf("time to restore is %v\n\n", time.Since(start))
  2220  
  2221  		fmt.Printf("LOAD: reading %d msgs of %s each, totalling %s\n",
  2222  			toStore,
  2223  			friendlyBytes(int64(storedMsgSize)),
  2224  			friendlyBytes(int64(toStore*storedMsgSize)),
  2225  		)
  2226  
  2227  		var smv StoreMsg
  2228  		start = time.Now()
  2229  		for i := uint64(1); i <= toStore; i++ {
  2230  			if _, err := fs.LoadMsg(i, &smv); err != nil {
  2231  				t.Fatalf("Error loading %d: %v", i, err)
  2232  			}
  2233  		}
  2234  
  2235  		tt = time.Since(start)
  2236  		fmt.Printf("time to read all back messages is %v\n", tt)
  2237  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2238  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2239  
  2240  		// Do again to test skip for hash..
  2241  		fmt.Printf("\nSKIP CHECKSUM: reading %d msgs of %s each, totalling %s\n",
  2242  			toStore,
  2243  			friendlyBytes(int64(storedMsgSize)),
  2244  			friendlyBytes(int64(toStore*storedMsgSize)),
  2245  		)
  2246  
  2247  		start = time.Now()
  2248  		for i := uint64(1); i <= toStore; i++ {
  2249  			if _, err := fs.LoadMsg(i, &smv); err != nil {
  2250  				t.Fatalf("Error loading %d: %v", i, err)
  2251  			}
  2252  		}
  2253  
  2254  		tt = time.Since(start)
  2255  		fmt.Printf("time to read all back messages is %v\n", tt)
  2256  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2257  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2258  
  2259  		fs.Stop()
  2260  
  2261  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  2262  		require_NoError(t, err)
  2263  		defer fs.Stop()
  2264  
  2265  		fmt.Printf("\nremoving [in order] %d msgs of %s each, totalling %s\n",
  2266  			toStore,
  2267  			friendlyBytes(int64(storedMsgSize)),
  2268  			friendlyBytes(int64(toStore*storedMsgSize)),
  2269  		)
  2270  
  2271  		start = time.Now()
  2272  		// For reverse order.
  2273  		//for i := toStore; i > 0; i-- {
  2274  		for i := uint64(1); i <= toStore; i++ {
  2275  			fs.RemoveMsg(i)
  2276  		}
  2277  		fs.Stop()
  2278  
  2279  		tt = time.Since(start)
  2280  		fmt.Printf("time to remove all messages is %v\n", tt)
  2281  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2282  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2283  
  2284  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  2285  		require_NoError(t, err)
  2286  		defer fs.Stop()
  2287  
  2288  		state := fs.State()
  2289  		if state.Msgs != 0 {
  2290  			t.Fatalf("Expected no msgs, got %d", state.Msgs)
  2291  		}
  2292  		if state.Bytes != 0 {
  2293  			t.Fatalf("Expected no bytes, got %d", state.Bytes)
  2294  		}
  2295  	})
  2296  }
  2297  
  2298  func TestFileStoreReadBackMsgPerf(t *testing.T) {
  2299  	// Comment out to run, holding place for now.
  2300  	t.SkipNow()
  2301  
  2302  	subj := "foo"
  2303  	msg := []byte("ABCDEFGH") // Smaller shows problems more.
  2304  
  2305  	storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  2306  
  2307  	// Make sure we store 2 blocks.
  2308  	toStore := defaultLargeBlockSize * 2 / storedMsgSize
  2309  
  2310  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2311  		fmt.Printf("storing %d msgs of %s each, totalling %s\n",
  2312  			toStore,
  2313  			friendlyBytes(int64(storedMsgSize)),
  2314  			friendlyBytes(int64(toStore*storedMsgSize)),
  2315  		)
  2316  
  2317  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2318  		require_NoError(t, err)
  2319  		defer fs.Stop()
  2320  
  2321  		start := time.Now()
  2322  		for i := 0; i < int(toStore); i++ {
  2323  			fs.StoreMsg(subj, nil, msg)
  2324  		}
  2325  
  2326  		tt := time.Since(start)
  2327  		fmt.Printf("time to store is %v\n", tt)
  2328  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2329  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2330  
  2331  		// We should not have cached here with no reads.
  2332  		// Pick something towards end of the block.
  2333  		index := defaultLargeBlockSize/storedMsgSize - 22
  2334  		start = time.Now()
  2335  		fs.LoadMsg(index, nil)
  2336  		fmt.Printf("Time to load first msg [%d] = %v\n", index, time.Since(start))
  2337  
  2338  		start = time.Now()
  2339  		fs.LoadMsg(index+2, nil)
  2340  		fmt.Printf("Time to load second msg [%d] = %v\n", index+2, time.Since(start))
  2341  	})
  2342  }
  2343  
  2344  // This test is testing an upper level stream with a message or byte limit.
  2345  // Even though this is 1, any limit would trigger same behavior once the limit was reached
  2346  // and we were adding and removing.
  2347  func TestFileStoreStoreLimitRemovePerf(t *testing.T) {
  2348  	// Comment out to run, holding place for now.
  2349  	t.SkipNow()
  2350  
  2351  	subj, msg := "foo", make([]byte, 1024-33)
  2352  	for i := 0; i < len(msg); i++ {
  2353  		msg[i] = 'D'
  2354  	}
  2355  	storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  2356  
  2357  	// 1GB
  2358  	toStore := 1 * 1024 * 1024 * 1024 / storedMsgSize
  2359  
  2360  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2361  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2362  		require_NoError(t, err)
  2363  		defer fs.Stop()
  2364  
  2365  		fs.RegisterStorageUpdates(func(md, bd int64, seq uint64, subj string) {})
  2366  
  2367  		fmt.Printf("storing and removing (limit 1) %d msgs of %s each, totalling %s\n",
  2368  			toStore,
  2369  			friendlyBytes(int64(storedMsgSize)),
  2370  			friendlyBytes(int64(toStore*storedMsgSize)),
  2371  		)
  2372  
  2373  		start := time.Now()
  2374  		for i := 0; i < int(toStore); i++ {
  2375  			seq, _, err := fs.StoreMsg(subj, nil, msg)
  2376  			if err != nil {
  2377  				t.Fatalf("Unexpected error storing message: %v", err)
  2378  			}
  2379  			if i > 0 {
  2380  				fs.RemoveMsg(seq - 1)
  2381  			}
  2382  		}
  2383  		fs.Stop()
  2384  
  2385  		tt := time.Since(start)
  2386  		fmt.Printf("time to store and remove all messages is %v\n", tt)
  2387  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2388  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2389  	})
  2390  }
  2391  
  2392  func TestFileStorePubPerfWithSmallBlkSize(t *testing.T) {
  2393  	// Comment out to run, holding place for now.
  2394  	t.SkipNow()
  2395  
  2396  	subj, msg := "foo", make([]byte, 1024-33)
  2397  	for i := 0; i < len(msg); i++ {
  2398  		msg[i] = 'D'
  2399  	}
  2400  	storedMsgSize := fileStoreMsgSize(subj, nil, msg)
  2401  
  2402  	// 1GB
  2403  	toStore := 1 * 1024 * 1024 * 1024 / storedMsgSize
  2404  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2405  		fmt.Printf("storing %d msgs of %s each, totalling %s\n",
  2406  			toStore,
  2407  			friendlyBytes(int64(storedMsgSize)),
  2408  			friendlyBytes(int64(toStore*storedMsgSize)),
  2409  		)
  2410  
  2411  		fcfg.BlockSize = FileStoreMinBlkSize
  2412  
  2413  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2414  		require_NoError(t, err)
  2415  		defer fs.Stop()
  2416  
  2417  		start := time.Now()
  2418  		for i := 0; i < int(toStore); i++ {
  2419  			fs.StoreMsg(subj, nil, msg)
  2420  		}
  2421  		fs.Stop()
  2422  
  2423  		tt := time.Since(start)
  2424  		fmt.Printf("time to store is %v\n", tt)
  2425  		fmt.Printf("%.0f msgs/sec\n", float64(toStore)/tt.Seconds())
  2426  		fmt.Printf("%s per sec\n", friendlyBytes(int64(float64(toStore*storedMsgSize)/tt.Seconds())))
  2427  	})
  2428  }
  2429  
  2430  // Saw this manifest from a restart test with max delivered set for JetStream.
  2431  func TestFileStoreConsumerRedeliveredLost(t *testing.T) {
  2432  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2433  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2434  		require_NoError(t, err)
  2435  		defer fs.Stop()
  2436  
  2437  		cfg := &ConsumerConfig{AckPolicy: AckExplicit}
  2438  		o, err := fs.ConsumerStore("o22", cfg)
  2439  		if err != nil {
  2440  			t.Fatalf("Unexpected error: %v", err)
  2441  		}
  2442  
  2443  		restartConsumer := func() {
  2444  			t.Helper()
  2445  			o.Stop()
  2446  			time.Sleep(20 * time.Millisecond) // Wait for all things to settle.
  2447  			o, err = fs.ConsumerStore("o22", cfg)
  2448  			if err != nil {
  2449  				t.Fatalf("Unexpected error: %v", err)
  2450  			}
  2451  			// Make sure we recovered Redelivered.
  2452  			state, err := o.State()
  2453  			if err != nil {
  2454  				t.Fatalf("Unexpected error: %v", err)
  2455  			}
  2456  			if state == nil {
  2457  				t.Fatalf("Did not recover state")
  2458  			}
  2459  			if len(state.Redelivered) == 0 {
  2460  				t.Fatalf("Did not recover redelivered")
  2461  			}
  2462  		}
  2463  
  2464  		ts := time.Now().UnixNano()
  2465  		o.UpdateDelivered(1, 1, 1, ts)
  2466  		o.UpdateDelivered(2, 1, 2, ts)
  2467  		o.UpdateDelivered(3, 1, 3, ts)
  2468  		o.UpdateDelivered(4, 1, 4, ts)
  2469  		o.UpdateDelivered(5, 2, 1, ts)
  2470  
  2471  		restartConsumer()
  2472  
  2473  		o.UpdateDelivered(6, 2, 2, ts)
  2474  		o.UpdateDelivered(7, 3, 1, ts)
  2475  
  2476  		restartConsumer()
  2477  		if state, _ := o.State(); len(state.Pending) != 3 {
  2478  			t.Fatalf("Did not recover pending correctly")
  2479  		}
  2480  
  2481  		o.UpdateAcks(7, 3)
  2482  		o.UpdateAcks(6, 2)
  2483  
  2484  		restartConsumer()
  2485  		o.UpdateAcks(4, 1)
  2486  
  2487  		state, _ := o.State()
  2488  		if len(state.Pending) != 0 {
  2489  			t.Fatalf("Did not clear pending correctly")
  2490  		}
  2491  		if len(state.Redelivered) != 0 {
  2492  			t.Fatalf("Did not clear redelivered correctly")
  2493  		}
  2494  	})
  2495  }
  2496  
  2497  func TestFileStoreConsumerFlusher(t *testing.T) {
  2498  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2499  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2500  		require_NoError(t, err)
  2501  		defer fs.Stop()
  2502  
  2503  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{})
  2504  		if err != nil {
  2505  			t.Fatalf("Unexpected error: %v", err)
  2506  		}
  2507  		// Get the underlying impl.
  2508  		oc := o.(*consumerFileStore)
  2509  		// Wait for flusher to be running.
  2510  		checkFor(t, time.Second, 20*time.Millisecond, func() error {
  2511  			if !oc.inFlusher() {
  2512  				return fmt.Errorf("Flusher not running")
  2513  			}
  2514  			return nil
  2515  		})
  2516  		// Stop and make sure the flusher goes away
  2517  		o.Stop()
  2518  		// Wait for flusher to stop.
  2519  		checkFor(t, time.Second, 20*time.Millisecond, func() error {
  2520  			if oc.inFlusher() {
  2521  				return fmt.Errorf("Flusher still running")
  2522  			}
  2523  			return nil
  2524  		})
  2525  	})
  2526  }
  2527  
  2528  func TestFileStoreConsumerDeliveredUpdates(t *testing.T) {
  2529  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2530  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2531  		require_NoError(t, err)
  2532  		defer fs.Stop()
  2533  
  2534  		// Simple consumer, no ack policy configured.
  2535  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{})
  2536  		if err != nil {
  2537  			t.Fatalf("Unexpected error: %v", err)
  2538  		}
  2539  		defer o.Stop()
  2540  
  2541  		testDelivered := func(dseq, sseq uint64) {
  2542  			t.Helper()
  2543  			ts := time.Now().UnixNano()
  2544  			if err := o.UpdateDelivered(dseq, sseq, 1, ts); err != nil {
  2545  				t.Fatalf("Unexpected error: %v", err)
  2546  			}
  2547  			state, err := o.State()
  2548  			if err != nil {
  2549  				t.Fatalf("Error getting state: %v", err)
  2550  			}
  2551  			if state == nil {
  2552  				t.Fatalf("No state available")
  2553  			}
  2554  			expected := SequencePair{dseq, sseq}
  2555  			if state.Delivered != expected {
  2556  				t.Fatalf("Unexpected state, wanted %+v, got %+v", expected, state.Delivered)
  2557  			}
  2558  			if state.AckFloor != expected {
  2559  				t.Fatalf("Unexpected ack floor state, wanted %+v, got %+v", expected, state.AckFloor)
  2560  			}
  2561  			if len(state.Pending) != 0 {
  2562  				t.Fatalf("Did not expect any pending, got %d pending", len(state.Pending))
  2563  			}
  2564  		}
  2565  
  2566  		testDelivered(1, 100)
  2567  		testDelivered(2, 110)
  2568  		testDelivered(5, 130)
  2569  
  2570  		// If we try to do an ack this should err since we are not configured with ack policy.
  2571  		if err := o.UpdateAcks(1, 100); err != ErrNoAckPolicy {
  2572  			t.Fatalf("Expected a no ack policy error on update acks, got %v", err)
  2573  		}
  2574  		// Also if we do an update with a delivery count of anything but 1 here should also give same error.
  2575  		ts := time.Now().UnixNano()
  2576  		if err := o.UpdateDelivered(5, 130, 2, ts); err != ErrNoAckPolicy {
  2577  			t.Fatalf("Expected a no ack policy error on update delivered with dc > 1, got %v", err)
  2578  		}
  2579  	})
  2580  }
  2581  
  2582  func TestFileStoreConsumerDeliveredAndAckUpdates(t *testing.T) {
  2583  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2584  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2585  		require_NoError(t, err)
  2586  		defer fs.Stop()
  2587  
  2588  		// Simple consumer, no ack policy configured.
  2589  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{AckPolicy: AckExplicit})
  2590  		if err != nil {
  2591  			t.Fatalf("Unexpected error: %v", err)
  2592  		}
  2593  		defer o.Stop()
  2594  
  2595  		// Track pending.
  2596  		var pending int
  2597  
  2598  		testDelivered := func(dseq, sseq uint64) {
  2599  			t.Helper()
  2600  			ts := time.Now().Round(time.Second).UnixNano()
  2601  			if err := o.UpdateDelivered(dseq, sseq, 1, ts); err != nil {
  2602  				t.Fatalf("Unexpected error: %v", err)
  2603  			}
  2604  			pending++
  2605  			state, err := o.State()
  2606  			if err != nil {
  2607  				t.Fatalf("Error getting state: %v", err)
  2608  			}
  2609  			if state == nil {
  2610  				t.Fatalf("No state available")
  2611  			}
  2612  			expected := SequencePair{dseq, sseq}
  2613  			if state.Delivered != expected {
  2614  				t.Fatalf("Unexpected delivered state, wanted %+v, got %+v", expected, state.Delivered)
  2615  			}
  2616  			if len(state.Pending) != pending {
  2617  				t.Fatalf("Expected %d pending, got %d pending", pending, len(state.Pending))
  2618  			}
  2619  		}
  2620  
  2621  		testDelivered(1, 100)
  2622  		testDelivered(2, 110)
  2623  		testDelivered(3, 130)
  2624  		testDelivered(4, 150)
  2625  		testDelivered(5, 165)
  2626  
  2627  		testBadAck := func(dseq, sseq uint64) {
  2628  			t.Helper()
  2629  			if err := o.UpdateAcks(dseq, sseq); err == nil {
  2630  				t.Fatalf("Expected error but got none")
  2631  			}
  2632  		}
  2633  		testBadAck(3, 101)
  2634  		testBadAck(1, 1)
  2635  
  2636  		testAck := func(dseq, sseq, dflr, sflr uint64) {
  2637  			t.Helper()
  2638  			if err := o.UpdateAcks(dseq, sseq); err != nil {
  2639  				t.Fatalf("Unexpected error: %v", err)
  2640  			}
  2641  			pending--
  2642  			state, err := o.State()
  2643  			if err != nil {
  2644  				t.Fatalf("Error getting state: %v", err)
  2645  			}
  2646  			if state == nil {
  2647  				t.Fatalf("No state available")
  2648  			}
  2649  			if len(state.Pending) != pending {
  2650  				t.Fatalf("Expected %d pending, got %d pending", pending, len(state.Pending))
  2651  			}
  2652  			eflr := SequencePair{dflr, sflr}
  2653  			if state.AckFloor != eflr {
  2654  				t.Fatalf("Unexpected ack floor state, wanted %+v, got %+v", eflr, state.AckFloor)
  2655  			}
  2656  		}
  2657  
  2658  		testAck(1, 100, 1, 109)
  2659  		testAck(3, 130, 1, 109)
  2660  		testAck(2, 110, 3, 149) // We do not track explicit state on previous stream floors, so we take last known -1
  2661  		testAck(5, 165, 3, 149)
  2662  		testAck(4, 150, 5, 165)
  2663  
  2664  		testDelivered(6, 170)
  2665  		testDelivered(7, 171)
  2666  		testDelivered(8, 172)
  2667  		testDelivered(9, 173)
  2668  		testDelivered(10, 200)
  2669  
  2670  		testAck(7, 171, 5, 165)
  2671  		testAck(8, 172, 5, 165)
  2672  
  2673  		state, err := o.State()
  2674  		if err != nil {
  2675  			t.Fatalf("Unexpected error getting state: %v", err)
  2676  		}
  2677  		o.Stop()
  2678  
  2679  		o, err = fs.ConsumerStore("o22", &ConsumerConfig{AckPolicy: AckExplicit})
  2680  		if err != nil {
  2681  			t.Fatalf("Unexpected error: %v", err)
  2682  		}
  2683  		defer o.Stop()
  2684  
  2685  		nstate, err := o.State()
  2686  		if err != nil {
  2687  			t.Fatalf("Unexpected error getting state: %v", err)
  2688  		}
  2689  		if !reflect.DeepEqual(nstate, state) {
  2690  			t.Fatalf("States don't match! NEW %+v OLD %+v", nstate, state)
  2691  		}
  2692  	})
  2693  }
  2694  
  2695  func TestFileStoreStreamStateDeleted(t *testing.T) {
  2696  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2697  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2698  		require_NoError(t, err)
  2699  		defer fs.Stop()
  2700  
  2701  		subj, toStore := "foo", uint64(10)
  2702  		for i := uint64(1); i <= toStore; i++ {
  2703  			msg := []byte(fmt.Sprintf("[%08d] Hello World!", i))
  2704  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2705  				t.Fatalf("Error storing msg: %v", err)
  2706  			}
  2707  		}
  2708  		state := fs.State()
  2709  		if len(state.Deleted) != 0 {
  2710  			t.Fatalf("Expected deleted to be empty")
  2711  		}
  2712  		// Now remove some interior messages.
  2713  		var expected []uint64
  2714  		for seq := uint64(2); seq < toStore; seq += 2 {
  2715  			fs.RemoveMsg(seq)
  2716  			expected = append(expected, seq)
  2717  		}
  2718  		state = fs.State()
  2719  		if !reflect.DeepEqual(state.Deleted, expected) {
  2720  			t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted)
  2721  		}
  2722  		// Now fill the gap by deleting 1 and 3
  2723  		fs.RemoveMsg(1)
  2724  		fs.RemoveMsg(3)
  2725  		expected = expected[2:]
  2726  		state = fs.State()
  2727  		if !reflect.DeepEqual(state.Deleted, expected) {
  2728  			t.Fatalf("Expected deleted to be %+v, got %+v\n", expected, state.Deleted)
  2729  		}
  2730  		if state.FirstSeq != 5 {
  2731  			t.Fatalf("Expected first seq to be 5, got %d", state.FirstSeq)
  2732  		}
  2733  		fs.Purge()
  2734  		if state = fs.State(); len(state.Deleted) != 0 {
  2735  			t.Fatalf("Expected no deleted after purge, got %+v\n", state.Deleted)
  2736  		}
  2737  	})
  2738  }
  2739  
  2740  // We have reports that sometimes under load a stream could complain about a storage directory
  2741  // not being empty.
  2742  func TestFileStoreStreamDeleteDirNotEmpty(t *testing.T) {
  2743  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2744  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2745  		require_NoError(t, err)
  2746  		defer fs.Stop()
  2747  
  2748  		subj, toStore := "foo", uint64(10)
  2749  		for i := uint64(1); i <= toStore; i++ {
  2750  			msg := []byte(fmt.Sprintf("[%08d] Hello World!", i))
  2751  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2752  				t.Fatalf("Error storing msg: %v", err)
  2753  			}
  2754  		}
  2755  
  2756  		ready := make(chan bool)
  2757  		go func() {
  2758  			g := filepath.Join(fcfg.StoreDir, "g")
  2759  			ready <- true
  2760  			for i := 0; i < 100; i++ {
  2761  				os.WriteFile(g, []byte("OK"), defaultFilePerms)
  2762  			}
  2763  		}()
  2764  
  2765  		<-ready
  2766  		if err := fs.Delete(); err != nil {
  2767  			t.Fatalf("Delete returned an error: %v", err)
  2768  		}
  2769  	})
  2770  }
  2771  
  2772  func TestFileStoreConsumerPerf(t *testing.T) {
  2773  	// Comment out to run, holding place for now.
  2774  	t.SkipNow()
  2775  
  2776  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2777  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2778  		require_NoError(t, err)
  2779  		defer fs.Stop()
  2780  
  2781  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{AckPolicy: AckExplicit})
  2782  		if err != nil {
  2783  			t.Fatalf("Unexpected error: %v", err)
  2784  		}
  2785  		// Get the underlying impl.
  2786  		oc := o.(*consumerFileStore)
  2787  		// Wait for flusher to br running
  2788  		checkFor(t, time.Second, 20*time.Millisecond, func() error {
  2789  			if !oc.inFlusher() {
  2790  				return fmt.Errorf("not in flusher")
  2791  			}
  2792  			return nil
  2793  		})
  2794  
  2795  		// Stop flusher for this benchmark since we will invoke directly.
  2796  		oc.mu.Lock()
  2797  		qch := oc.qch
  2798  		oc.qch = nil
  2799  		oc.mu.Unlock()
  2800  		close(qch)
  2801  
  2802  		checkFor(t, time.Second, 20*time.Millisecond, func() error {
  2803  			if oc.inFlusher() {
  2804  				return fmt.Errorf("still in flusher")
  2805  			}
  2806  			return nil
  2807  		})
  2808  
  2809  		toStore := uint64(1_000_000)
  2810  
  2811  		start := time.Now()
  2812  
  2813  		ts := start.UnixNano()
  2814  
  2815  		for i := uint64(1); i <= toStore; i++ {
  2816  			if err := o.UpdateDelivered(i, i, 1, ts); err != nil {
  2817  				t.Fatalf("Unexpected error: %v", err)
  2818  			}
  2819  		}
  2820  		tt := time.Since(start)
  2821  		fmt.Printf("time to update %d is %v\n", toStore, tt)
  2822  		fmt.Printf("%.0f updates/sec\n", float64(toStore)/tt.Seconds())
  2823  
  2824  		start = time.Now()
  2825  		oc.mu.Lock()
  2826  		buf, err := oc.encodeState()
  2827  		oc.mu.Unlock()
  2828  		if err != nil {
  2829  			t.Fatalf("Error encoding state: %v", err)
  2830  		}
  2831  		fmt.Printf("time to encode %d bytes is %v\n", len(buf), time.Since(start))
  2832  		start = time.Now()
  2833  		oc.writeState(buf)
  2834  		fmt.Printf("time to write is %v\n", time.Since(start))
  2835  	})
  2836  }
  2837  
  2838  // Reported by Ivan.
  2839  func TestFileStoreStreamDeleteCacheBug(t *testing.T) {
  2840  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2841  		fcfg.CacheExpire = 50 * time.Millisecond
  2842  
  2843  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  2844  		require_NoError(t, err)
  2845  		defer fs.Stop()
  2846  
  2847  		subj, msg := "foo", []byte("Hello World")
  2848  
  2849  		if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2850  			t.Fatalf("Unexpected error: %v", err)
  2851  		}
  2852  		if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  2853  			t.Fatalf("Unexpected error: %v", err)
  2854  		}
  2855  		if _, err := fs.EraseMsg(1); err != nil {
  2856  			t.Fatalf("Got an error on remove of %d: %v", 1, err)
  2857  		}
  2858  		time.Sleep(100 * time.Millisecond)
  2859  		if _, err := fs.LoadMsg(2, nil); err != nil {
  2860  			t.Fatalf("Unexpected error looking up msg: %v", err)
  2861  		}
  2862  	})
  2863  }
  2864  
  2865  // rip
  2866  func TestFileStoreStreamFailToRollBug(t *testing.T) {
  2867  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2868  		fcfg.BlockSize = 512
  2869  
  2870  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage, MaxBytes: 300}, time.Now(), prf(&fcfg), nil)
  2871  		require_NoError(t, err)
  2872  		defer fs.Stop()
  2873  
  2874  		// Make sure we properly roll underlying blocks.
  2875  		n, msg := 200, bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  2876  		for i := 0; i < n; i++ {
  2877  			if _, _, err := fs.StoreMsg("zzz", nil, msg); err != nil {
  2878  				t.Fatalf("Unexpected error: %v", err)
  2879  			}
  2880  		}
  2881  
  2882  		// Grab some info for introspection.
  2883  		fs.mu.RLock()
  2884  		numBlks := len(fs.blks)
  2885  		var index uint32
  2886  		var blkSize int64
  2887  		if numBlks > 0 {
  2888  			mb := fs.blks[0]
  2889  			mb.mu.RLock()
  2890  			index = mb.index
  2891  			if fi, _ := os.Stat(mb.mfn); fi != nil {
  2892  				blkSize = fi.Size()
  2893  			}
  2894  			mb.mu.RUnlock()
  2895  		}
  2896  		fs.mu.RUnlock()
  2897  
  2898  		if numBlks != 1 {
  2899  			t.Fatalf("Expected only one block, got %d", numBlks)
  2900  		}
  2901  		if index < 60 {
  2902  			t.Fatalf("Expected a block index > 60, got %d", index)
  2903  		}
  2904  		if blkSize > 512 {
  2905  			t.Fatalf("Expected block to be <= 512, got %d", blkSize)
  2906  		}
  2907  	})
  2908  }
  2909  
  2910  // We had a case where a consumer state had a redelivered record that had seq of 0.
  2911  // This was causing the server to panic.
  2912  func TestFileStoreBadConsumerState(t *testing.T) {
  2913  	bs := []byte("\x16\x02\x01\x01\x03\x02\x01\x98\xf4\x8a\x8a\f\x01\x03\x86\xfa\n\x01\x00\x01")
  2914  	if cs, err := decodeConsumerState(bs); err != nil || cs == nil {
  2915  		t.Fatalf("Expected to not throw error, got %v and %+v", err, cs)
  2916  	}
  2917  }
  2918  
  2919  func TestFileStoreExpireMsgsOnStart(t *testing.T) {
  2920  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  2921  		fcfg.BlockSize = 8 * 1024
  2922  		ttl := 250 * time.Millisecond
  2923  		cfg := StreamConfig{Name: "ORDERS", Subjects: []string{"orders.*"}, Storage: FileStorage, MaxAge: ttl}
  2924  		var fs *fileStore
  2925  
  2926  		startFS := func() *fileStore {
  2927  			t.Helper()
  2928  			fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  2929  			require_NoError(t, err)
  2930  			return fs
  2931  		}
  2932  
  2933  		newFS := func() *fileStore {
  2934  			t.Helper()
  2935  			if fs != nil {
  2936  				fs.Stop()
  2937  				fs = nil
  2938  			}
  2939  			removeDir(t, fcfg.StoreDir)
  2940  			return startFS()
  2941  		}
  2942  
  2943  		restartFS := func(delay time.Duration) *fileStore {
  2944  			if fs != nil {
  2945  				fs.Stop()
  2946  				fs = nil
  2947  				time.Sleep(delay)
  2948  			}
  2949  			fs = startFS()
  2950  			return fs
  2951  		}
  2952  
  2953  		fs = newFS()
  2954  		defer fs.Stop()
  2955  
  2956  		msg := bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  2957  		loadMsgs := func(n int) {
  2958  			t.Helper()
  2959  			for i := 1; i <= n; i++ {
  2960  				if _, _, err := fs.StoreMsg(fmt.Sprintf("orders.%d", i%10), nil, msg); err != nil {
  2961  					t.Fatalf("Unexpected error: %v", err)
  2962  				}
  2963  			}
  2964  		}
  2965  
  2966  		checkState := func(msgs, first, last uint64) {
  2967  			t.Helper()
  2968  			if fs == nil {
  2969  				t.Fatalf("No fs")
  2970  				return
  2971  			}
  2972  			state := fs.State()
  2973  			if state.Msgs != msgs {
  2974  				t.Fatalf("Expected %d msgs, got %d", msgs, state.Msgs)
  2975  			}
  2976  			if state.FirstSeq != first {
  2977  				t.Fatalf("Expected %d as first, got %d", first, state.FirstSeq)
  2978  			}
  2979  			if state.LastSeq != last {
  2980  				t.Fatalf("Expected %d as last, got %d", last, state.LastSeq)
  2981  			}
  2982  		}
  2983  
  2984  		checkNumBlks := func(expected int) {
  2985  			t.Helper()
  2986  			fs.mu.RLock()
  2987  			n := len(fs.blks)
  2988  			fs.mu.RUnlock()
  2989  			if n != expected {
  2990  				t.Fatalf("Expected %d msg blks, got %d", expected, n)
  2991  			}
  2992  		}
  2993  
  2994  		// Check the filtered subject state and make sure that is tracked properly.
  2995  		checkFiltered := func(subject string, ss SimpleState) {
  2996  			t.Helper()
  2997  			fss := fs.FilteredState(1, subject)
  2998  			if fss != ss {
  2999  				t.Fatalf("Expected FilteredState of %+v, got %+v", ss, fss)
  3000  			}
  3001  		}
  3002  
  3003  		// Make sure state on disk matches (e.g. writeIndexInfo properly called)
  3004  		checkBlkState := func(index int) {
  3005  			t.Helper()
  3006  			fs.mu.RLock()
  3007  			if index >= len(fs.blks) {
  3008  				t.Fatalf("Out of range, wanted %d but only %d blks", index, len(fs.blks))
  3009  			}
  3010  			fs.mu.RUnlock()
  3011  		}
  3012  
  3013  		lastSeqForBlk := func(index int) uint64 {
  3014  			t.Helper()
  3015  			fs.mu.RLock()
  3016  			defer fs.mu.RUnlock()
  3017  			if len(fs.blks) == 0 {
  3018  				t.Fatalf("No blocks?")
  3019  			}
  3020  			mb := fs.blks[0]
  3021  			mb.mu.RLock()
  3022  			defer mb.mu.RUnlock()
  3023  			return mb.last.seq
  3024  		}
  3025  
  3026  		// Actual testing here.
  3027  
  3028  		loadMsgs(500)
  3029  		restartFS(ttl + 100*time.Millisecond)
  3030  		checkState(0, 501, 500)
  3031  		// We actually hold onto the last one now to remember our starting sequence.
  3032  		checkNumBlks(1)
  3033  
  3034  		// Now check partial expires and the fss tracking state.
  3035  		// Small numbers is to keep them in one block.
  3036  		fs = newFS()
  3037  		loadMsgs(10)
  3038  		time.Sleep(100 * time.Millisecond)
  3039  		loadMsgs(10)
  3040  		checkFiltered("orders.*", SimpleState{Msgs: 20, First: 1, Last: 20})
  3041  
  3042  		restartFS(ttl - 100*time.Millisecond + 25*time.Millisecond) // Just want half
  3043  		checkState(10, 11, 20)
  3044  		checkNumBlks(1)
  3045  		checkFiltered("orders.*", SimpleState{Msgs: 10, First: 11, Last: 20})
  3046  		checkFiltered("orders.5", SimpleState{Msgs: 1, First: 15, Last: 15})
  3047  		checkBlkState(0)
  3048  
  3049  		fs = newFS()
  3050  		loadMsgs(5)
  3051  		time.Sleep(100 * time.Millisecond)
  3052  		loadMsgs(15)
  3053  		restartFS(ttl - 100*time.Millisecond + 25*time.Millisecond) // Just want half
  3054  		checkState(15, 6, 20)
  3055  		checkFiltered("orders.*", SimpleState{Msgs: 15, First: 6, Last: 20})
  3056  		checkFiltered("orders.5", SimpleState{Msgs: 2, First: 10, Last: 20})
  3057  
  3058  		// Now we want to test that if the end of a msg block is all deletes msgs that we do the right thing.
  3059  		fs = newFS()
  3060  		loadMsgs(150)
  3061  		time.Sleep(100 * time.Millisecond)
  3062  		loadMsgs(100)
  3063  
  3064  		checkNumBlks(5)
  3065  
  3066  		// Now delete 10 messages from the end of the first block which we will expire on restart.
  3067  		// We will expire up to seq 100, so delete 91-100.
  3068  		lseq := lastSeqForBlk(0)
  3069  		for seq := lseq; seq > lseq-10; seq-- {
  3070  			removed, err := fs.RemoveMsg(seq)
  3071  			if err != nil || !removed {
  3072  				t.Fatalf("Error removing message: %v", err)
  3073  			}
  3074  		}
  3075  		restartFS(ttl - 100*time.Millisecond + 25*time.Millisecond) // Just want half
  3076  		checkState(100, 151, 250)
  3077  		checkNumBlks(3) // We should only have 3 blks left.
  3078  		checkBlkState(0)
  3079  
  3080  		// Now make sure that we properly clean up any internal dmap entries (sparse) when expiring.
  3081  		fs = newFS()
  3082  		loadMsgs(10)
  3083  		// Remove some in sparse fashion, adding to dmap.
  3084  		fs.RemoveMsg(2)
  3085  		fs.RemoveMsg(4)
  3086  		fs.RemoveMsg(6)
  3087  		time.Sleep(100 * time.Millisecond)
  3088  		loadMsgs(10)
  3089  		restartFS(ttl - 100*time.Millisecond + 25*time.Millisecond) // Just want half
  3090  		checkState(10, 11, 20)
  3091  		checkNumBlks(1)
  3092  		checkBlkState(0)
  3093  
  3094  		// Make sure expiring a block with tail deleted messages removes the message block etc.
  3095  		fs = newFS()
  3096  		loadMsgs(7)
  3097  		time.Sleep(100 * time.Millisecond)
  3098  		loadMsgs(3)
  3099  		fs.RemoveMsg(8)
  3100  		fs.RemoveMsg(9)
  3101  		fs.RemoveMsg(10)
  3102  		restartFS(ttl - 100*time.Millisecond + 25*time.Millisecond)
  3103  		checkState(0, 11, 10)
  3104  
  3105  		fs.Stop()
  3106  		// Not for start per se but since we have all the test tooling here check that Compact() does right thing as well.
  3107  		fs = newFS()
  3108  		defer fs.Stop()
  3109  		loadMsgs(100)
  3110  		checkFiltered("orders.*", SimpleState{Msgs: 100, First: 1, Last: 100})
  3111  		checkFiltered("orders.5", SimpleState{Msgs: 10, First: 5, Last: 95})
  3112  		// Check that Compact keeps fss updated, does dmap etc.
  3113  		fs.Compact(51)
  3114  		checkFiltered("orders.*", SimpleState{Msgs: 50, First: 51, Last: 100})
  3115  		checkFiltered("orders.5", SimpleState{Msgs: 5, First: 55, Last: 95})
  3116  		checkBlkState(0)
  3117  	})
  3118  }
  3119  
  3120  func TestFileStoreSparseCompaction(t *testing.T) {
  3121  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3122  		fcfg.BlockSize = 1024 * 1024
  3123  		cfg := StreamConfig{Name: "KV", Subjects: []string{"kv.>"}, Storage: FileStorage}
  3124  
  3125  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3126  		require_NoError(t, err)
  3127  		defer fs.Stop()
  3128  
  3129  		msg := bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  3130  		loadMsgs := func(n int) {
  3131  			t.Helper()
  3132  			for i := 1; i <= n; i++ {
  3133  				if _, _, err := fs.StoreMsg(fmt.Sprintf("kv.%d", i%10), nil, msg); err != nil {
  3134  					t.Fatalf("Unexpected error: %v", err)
  3135  				}
  3136  			}
  3137  		}
  3138  
  3139  		checkState := func(msgs, first, last uint64) {
  3140  			t.Helper()
  3141  			if fs == nil {
  3142  				t.Fatalf("No fs")
  3143  				return
  3144  			}
  3145  			state := fs.State()
  3146  			if state.Msgs != msgs {
  3147  				t.Fatalf("Expected %d msgs, got %d", msgs, state.Msgs)
  3148  			}
  3149  			if state.FirstSeq != first {
  3150  				t.Fatalf("Expected %d as first, got %d", first, state.FirstSeq)
  3151  			}
  3152  			if state.LastSeq != last {
  3153  				t.Fatalf("Expected %d as last, got %d", last, state.LastSeq)
  3154  			}
  3155  		}
  3156  
  3157  		deleteMsgs := func(seqs ...uint64) {
  3158  			t.Helper()
  3159  			for _, seq := range seqs {
  3160  				removed, err := fs.RemoveMsg(seq)
  3161  				if err != nil || !removed {
  3162  					t.Fatalf("Got an error on remove of %d: %v", seq, err)
  3163  				}
  3164  			}
  3165  		}
  3166  
  3167  		eraseMsgs := func(seqs ...uint64) {
  3168  			t.Helper()
  3169  			for _, seq := range seqs {
  3170  				removed, err := fs.EraseMsg(seq)
  3171  				if err != nil || !removed {
  3172  					t.Fatalf("Got an error on erase of %d: %v", seq, err)
  3173  				}
  3174  			}
  3175  		}
  3176  
  3177  		compact := func() {
  3178  			t.Helper()
  3179  			var ssb, ssa StreamState
  3180  			fs.FastState(&ssb)
  3181  			tb, ub, _ := fs.Utilization()
  3182  
  3183  			fs.mu.RLock()
  3184  			if len(fs.blks) == 0 {
  3185  				t.Fatalf("No blocks?")
  3186  			}
  3187  			mb := fs.blks[0]
  3188  			fs.mu.RUnlock()
  3189  
  3190  			mb.mu.Lock()
  3191  			mb.compact()
  3192  			mb.mu.Unlock()
  3193  
  3194  			fs.FastState(&ssa)
  3195  			if !reflect.DeepEqual(ssb, ssa) {
  3196  				t.Fatalf("States do not match; %+v vs %+v", ssb, ssa)
  3197  			}
  3198  			ta, ua, _ := fs.Utilization()
  3199  			if ub != ua {
  3200  				t.Fatalf("Expected used to be the same, got %d vs %d", ub, ua)
  3201  			}
  3202  			if ta >= tb {
  3203  				t.Fatalf("Expected total after to be less then before, got %d vs %d", tb, ta)
  3204  			}
  3205  		}
  3206  
  3207  		// Actual testing here.
  3208  		loadMsgs(1000)
  3209  		checkState(1000, 1, 1000)
  3210  
  3211  		// Now delete a few messages.
  3212  		deleteMsgs(1)
  3213  		compact()
  3214  
  3215  		deleteMsgs(1000, 999, 998, 997)
  3216  		compact()
  3217  
  3218  		eraseMsgs(500, 502, 504, 506, 508, 510)
  3219  		compact()
  3220  	})
  3221  }
  3222  
  3223  func TestFileStoreSparseCompactionWithInteriorDeletes(t *testing.T) {
  3224  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3225  		cfg := StreamConfig{Name: "KV", Subjects: []string{"kv.>"}, Storage: FileStorage}
  3226  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3227  		require_NoError(t, err)
  3228  		defer fs.Stop()
  3229  
  3230  		for i := 1; i <= 1000; i++ {
  3231  			if _, _, err := fs.StoreMsg(fmt.Sprintf("kv.%d", i%10), nil, []byte("OK")); err != nil {
  3232  				t.Fatalf("Unexpected error: %v", err)
  3233  			}
  3234  		}
  3235  
  3236  		// Now do interior deletes.
  3237  		for _, seq := range []uint64{500, 600, 700, 800} {
  3238  			removed, err := fs.RemoveMsg(seq)
  3239  			if err != nil || !removed {
  3240  				t.Fatalf("Got an error on remove of %d: %v", seq, err)
  3241  			}
  3242  		}
  3243  
  3244  		_, err = fs.LoadMsg(900, nil)
  3245  		if err != nil {
  3246  			t.Fatalf("Unexpected error: %v", err)
  3247  		}
  3248  
  3249  		// Do compact by hand, make sure we can still access msgs past the interior deletes.
  3250  		fs.mu.RLock()
  3251  		lmb := fs.lmb
  3252  		lmb.dirtyCloseWithRemove(false)
  3253  		lmb.compact()
  3254  		fs.mu.RUnlock()
  3255  
  3256  		if _, err = fs.LoadMsg(900, nil); err != nil {
  3257  			t.Fatalf("Unexpected error: %v", err)
  3258  		}
  3259  	})
  3260  }
  3261  
  3262  // When messages span multiple blocks and we want to purge but keep some amount, say 1, we would remove all.
  3263  // This is because we would not break out of iterator across more message blocks.
  3264  // Issue #2622
  3265  func TestFileStorePurgeExKeepOneBug(t *testing.T) {
  3266  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3267  		fcfg.BlockSize = 128
  3268  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  3269  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3270  		require_NoError(t, err)
  3271  		defer fs.Stop()
  3272  
  3273  		fill := bytes.Repeat([]byte("X"), 128)
  3274  
  3275  		fs.StoreMsg("A", nil, []byte("META"))
  3276  		fs.StoreMsg("B", nil, fill)
  3277  		fs.StoreMsg("A", nil, []byte("META"))
  3278  		fs.StoreMsg("B", nil, fill)
  3279  
  3280  		if fss := fs.FilteredState(1, "A"); fss.Msgs != 2 {
  3281  			t.Fatalf("Expected to find 2 `A` msgs, got %d", fss.Msgs)
  3282  		}
  3283  
  3284  		n, err := fs.PurgeEx("A", 0, 1)
  3285  		if err != nil {
  3286  			t.Fatalf("Unexpected error: %v", err)
  3287  		}
  3288  		if n != 1 {
  3289  			t.Fatalf("Expected PurgeEx to remove 1 `A` msgs, got %d", n)
  3290  		}
  3291  		if fss := fs.FilteredState(1, "A"); fss.Msgs != 1 {
  3292  			t.Fatalf("Expected to find 1 `A` msgs, got %d", fss.Msgs)
  3293  		}
  3294  	})
  3295  }
  3296  
  3297  func TestFileStoreFilteredPendingBug(t *testing.T) {
  3298  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3299  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  3300  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3301  		require_NoError(t, err)
  3302  		defer fs.Stop()
  3303  
  3304  		fs.StoreMsg("foo", nil, []byte("msg"))
  3305  		fs.StoreMsg("bar", nil, []byte("msg"))
  3306  		fs.StoreMsg("baz", nil, []byte("msg"))
  3307  
  3308  		fs.mu.Lock()
  3309  		mb := fs.lmb
  3310  		fs.mu.Unlock()
  3311  
  3312  		total, f, l := mb.filteredPending("foo", false, 3)
  3313  		if total != 0 {
  3314  			t.Fatalf("Expected total of 0 but got %d", total)
  3315  		}
  3316  		if f != 0 || l != 0 {
  3317  			t.Fatalf("Expected first and last to be 0 as well, but got %d %d", f, l)
  3318  		}
  3319  	})
  3320  }
  3321  
  3322  // Test to optimize the selectMsgBlock with lots of blocks.
  3323  func TestFileStoreFetchPerf(t *testing.T) {
  3324  	// Comment out to run.
  3325  	t.SkipNow()
  3326  
  3327  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3328  		fcfg.BlockSize = 8192
  3329  		fcfg.AsyncFlush = true
  3330  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  3331  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3332  		require_NoError(t, err)
  3333  		defer fs.Stop()
  3334  
  3335  		// Will create 25k msg blocks.
  3336  		n, subj, msg := 100_000, "zzz", bytes.Repeat([]byte("ABC"), 600)
  3337  		for i := 0; i < n; i++ {
  3338  			if _, _, err := fs.StoreMsg(subj, nil, msg); err != nil {
  3339  				t.Fatalf("Unexpected error: %v", err)
  3340  			}
  3341  		}
  3342  
  3343  		// Time how long it takes us to load all messages.
  3344  		var smv StoreMsg
  3345  		now := time.Now()
  3346  		for i := 0; i < n; i++ {
  3347  			_, err := fs.LoadMsg(uint64(i), &smv)
  3348  			if err != nil {
  3349  				t.Fatalf("Unexpected error looking up seq %d: %v", i, err)
  3350  			}
  3351  		}
  3352  		fmt.Printf("Elapsed to load all messages is %v\n", time.Since(now))
  3353  	})
  3354  }
  3355  
  3356  // For things like raft log when we compact and have a message block that could reclaim > 50% of space for block we want to do that.
  3357  // https://github.com/nats-io/nats-server/issues/2936
  3358  func TestFileStoreCompactReclaimHeadSpace(t *testing.T) {
  3359  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3360  		fcfg.BlockSize = 4 * 1024 * 1024
  3361  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  3362  		created := time.Now()
  3363  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  3364  		require_NoError(t, err)
  3365  		defer fs.Stop()
  3366  
  3367  		// Create random bytes for payload to test for corruption vs repeated.
  3368  		msg := make([]byte, 64*1024)
  3369  		crand.Read(msg)
  3370  
  3371  		// This gives us ~63 msgs in first and ~37 in second.
  3372  		n, subj := 100, "z"
  3373  		for i := 0; i < n; i++ {
  3374  			_, _, err := fs.StoreMsg(subj, nil, msg)
  3375  			require_NoError(t, err)
  3376  		}
  3377  
  3378  		checkNumBlocks := func(n int) {
  3379  			t.Helper()
  3380  			fs.mu.RLock()
  3381  			defer fs.mu.RUnlock()
  3382  			if len(fs.blks) != n {
  3383  				t.Fatalf("Expected to have %d blocks, got %d", n, len(fs.blks))
  3384  			}
  3385  		}
  3386  
  3387  		getBlock := func(index int) *msgBlock {
  3388  			t.Helper()
  3389  			fs.mu.RLock()
  3390  			defer fs.mu.RUnlock()
  3391  			return fs.blks[index]
  3392  		}
  3393  
  3394  		// Check that we did right thing and actually reclaimed since > 50%
  3395  		checkBlock := func(mb *msgBlock) {
  3396  			t.Helper()
  3397  
  3398  			mb.mu.RLock()
  3399  			nbytes, rbytes, mfn := mb.bytes, mb.rbytes, mb.mfn
  3400  			fseq, lseq := mb.first.seq, mb.last.seq
  3401  			mb.mu.RUnlock()
  3402  
  3403  			// Check that sizes match as long as we are not doing compression.
  3404  			if fcfg.Compression == NoCompression {
  3405  				// Check rbytes then the actual file as well.
  3406  				if nbytes != rbytes {
  3407  					t.Fatalf("Expected to reclaim and have bytes == rbytes, got %d vs %d", nbytes, rbytes)
  3408  				}
  3409  				file, err := os.Open(mfn)
  3410  				require_NoError(t, err)
  3411  				defer file.Close()
  3412  				fi, err := file.Stat()
  3413  				require_NoError(t, err)
  3414  				if rbytes != uint64(fi.Size()) {
  3415  					t.Fatalf("Expected to rbytes == fi.Size, got %d vs %d", rbytes, fi.Size())
  3416  				}
  3417  			}
  3418  
  3419  			// Make sure we can pull messages and that they are ok.
  3420  			var smv StoreMsg
  3421  			sm, err := fs.LoadMsg(fseq, &smv)
  3422  			require_NoError(t, err)
  3423  			if !bytes.Equal(sm.msg, msg) {
  3424  				t.Fatalf("Msgs don't match, original %q vs %q", msg, sm.msg)
  3425  			}
  3426  			sm, err = fs.LoadMsg(lseq, &smv)
  3427  			require_NoError(t, err)
  3428  			if !bytes.Equal(sm.msg, msg) {
  3429  				t.Fatalf("Msgs don't match, original %q vs %q", msg, sm.msg)
  3430  			}
  3431  		}
  3432  
  3433  		checkNumBlocks(2)
  3434  		_, err = fs.Compact(33)
  3435  		require_NoError(t, err)
  3436  
  3437  		checkNumBlocks(2)
  3438  		checkBlock(getBlock(0))
  3439  		checkBlock(getBlock(1))
  3440  
  3441  		_, err = fs.Compact(85)
  3442  		require_NoError(t, err)
  3443  
  3444  		checkNumBlocks(1)
  3445  		checkBlock(getBlock(0))
  3446  
  3447  		// Make sure we can write.
  3448  		_, _, err = fs.StoreMsg(subj, nil, msg)
  3449  		require_NoError(t, err)
  3450  
  3451  		checkNumBlocks(1)
  3452  		checkBlock(getBlock(0))
  3453  
  3454  		// Stop and start again.
  3455  		fs.Stop()
  3456  
  3457  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  3458  		require_NoError(t, err)
  3459  		defer fs.Stop()
  3460  
  3461  		checkNumBlocks(1)
  3462  		checkBlock(getBlock(0))
  3463  
  3464  		// Make sure we can write.
  3465  		_, _, err = fs.StoreMsg(subj, nil, msg)
  3466  		require_NoError(t, err)
  3467  	})
  3468  }
  3469  
  3470  func TestFileStoreRememberLastMsgTime(t *testing.T) {
  3471  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3472  		var fs *fileStore
  3473  		cfg := StreamConfig{Name: "TEST", Storage: FileStorage, MaxAge: 1 * time.Second}
  3474  
  3475  		getFS := func() *fileStore {
  3476  			t.Helper()
  3477  			fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3478  			require_NoError(t, err)
  3479  			return fs
  3480  		}
  3481  		restartFS := func() {
  3482  			t.Helper()
  3483  			fs.Stop()
  3484  			fs = getFS()
  3485  		}
  3486  
  3487  		msg := bytes.Repeat([]byte("X"), 2*1024*1024)
  3488  
  3489  		// Get first one.
  3490  		fs = getFS()
  3491  		defer fs.Stop()
  3492  
  3493  		seq, ts, err := fs.StoreMsg("foo", nil, msg)
  3494  		require_NoError(t, err)
  3495  		// We will test that last msg time survives from delete, purge and expires after restart.
  3496  		removed, err := fs.RemoveMsg(seq)
  3497  		require_NoError(t, err)
  3498  		require_True(t, removed)
  3499  
  3500  		lt := time.Unix(0, ts).UTC()
  3501  		require_True(t, lt == fs.State().LastTime)
  3502  
  3503  		// Restart
  3504  		restartFS()
  3505  
  3506  		// Test that last time survived.
  3507  		require_True(t, lt == fs.State().LastTime)
  3508  
  3509  		seq, ts, err = fs.StoreMsg("foo", nil, msg)
  3510  		require_NoError(t, err)
  3511  
  3512  		var smv StoreMsg
  3513  		_, err = fs.LoadMsg(seq, &smv)
  3514  		require_NoError(t, err)
  3515  
  3516  		fs.Purge()
  3517  
  3518  		// Restart
  3519  		restartFS()
  3520  
  3521  		lt = time.Unix(0, ts).UTC()
  3522  		require_True(t, lt == fs.State().LastTime)
  3523  
  3524  		_, _, err = fs.StoreMsg("foo", nil, msg)
  3525  		require_NoError(t, err)
  3526  		seq, ts, err = fs.StoreMsg("foo", nil, msg)
  3527  		require_NoError(t, err)
  3528  
  3529  		require_True(t, seq == 4)
  3530  
  3531  		// Wait til messages expire.
  3532  		checkFor(t, 5*time.Second, time.Second, func() error {
  3533  			state := fs.State()
  3534  			if state.Msgs == 0 {
  3535  				return nil
  3536  			}
  3537  			return fmt.Errorf("Still has %d msgs", state.Msgs)
  3538  		})
  3539  
  3540  		// Restart
  3541  		restartFS()
  3542  
  3543  		lt = time.Unix(0, ts).UTC()
  3544  		require_True(t, lt == fs.State().LastTime)
  3545  
  3546  		// Now make sure we retain the true last seq.
  3547  		_, _, err = fs.StoreMsg("foo", nil, msg)
  3548  		require_NoError(t, err)
  3549  		seq, ts, err = fs.StoreMsg("foo", nil, msg)
  3550  		require_NoError(t, err)
  3551  
  3552  		require_True(t, seq == 6)
  3553  		removed, err = fs.RemoveMsg(seq)
  3554  		require_NoError(t, err)
  3555  		require_True(t, removed)
  3556  
  3557  		removed, err = fs.RemoveMsg(seq - 1)
  3558  		require_NoError(t, err)
  3559  		require_True(t, removed)
  3560  
  3561  		// Restart
  3562  		restartFS()
  3563  
  3564  		lt = time.Unix(0, ts).UTC()
  3565  		require_True(t, lt == fs.State().LastTime)
  3566  		require_True(t, seq == 6)
  3567  	})
  3568  }
  3569  
  3570  func (fs *fileStore) getFirstBlock() *msgBlock {
  3571  	fs.mu.RLock()
  3572  	defer fs.mu.RUnlock()
  3573  	if len(fs.blks) == 0 {
  3574  		return nil
  3575  	}
  3576  	return fs.blks[0]
  3577  }
  3578  
  3579  func TestFileStoreRebuildStateDmapAccountingBug(t *testing.T) {
  3580  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3581  		fcfg.BlockSize = 1024 * 1024
  3582  
  3583  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  3584  		require_NoError(t, err)
  3585  		defer fs.Stop()
  3586  
  3587  		for i := 0; i < 100; i++ {
  3588  			_, _, err = fs.StoreMsg("foo", nil, nil)
  3589  			require_NoError(t, err)
  3590  		}
  3591  		// Delete 2-40.
  3592  		for i := 2; i <= 40; i++ {
  3593  			_, err := fs.RemoveMsg(uint64(i))
  3594  			require_NoError(t, err)
  3595  		}
  3596  
  3597  		mb := fs.getFirstBlock()
  3598  		require_True(t, mb != nil)
  3599  
  3600  		check := func() {
  3601  			t.Helper()
  3602  			mb.mu.RLock()
  3603  			defer mb.mu.RUnlock()
  3604  			dmapLen := uint64(mb.dmap.Size())
  3605  			if mb.msgs != (mb.last.seq-mb.first.seq+1)-dmapLen {
  3606  				t.Fatalf("Consistency check failed: %d != %d -> last %d first %d len(dmap) %d",
  3607  					mb.msgs, (mb.last.seq-mb.first.seq+1)-dmapLen, mb.last.seq, mb.first.seq, dmapLen)
  3608  			}
  3609  		}
  3610  
  3611  		check()
  3612  
  3613  		mb.mu.Lock()
  3614  		mb.compact()
  3615  		mb.mu.Unlock()
  3616  
  3617  		// Now delete first.
  3618  		_, err = fs.RemoveMsg(1)
  3619  		require_NoError(t, err)
  3620  
  3621  		mb.mu.Lock()
  3622  		_, _, err = mb.rebuildStateLocked()
  3623  		mb.mu.Unlock()
  3624  		require_NoError(t, err)
  3625  
  3626  		check()
  3627  	})
  3628  }
  3629  
  3630  func TestFileStorePurgeExWithSubject(t *testing.T) {
  3631  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3632  		fcfg.BlockSize = 1000
  3633  		cfg := StreamConfig{Name: "TEST", Subjects: []string{"foo.>"}, Storage: FileStorage}
  3634  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3635  		require_NoError(t, err)
  3636  		defer fs.Stop()
  3637  
  3638  		payload := make([]byte, 20)
  3639  		total := 200
  3640  		for i := 0; i < total; i++ {
  3641  			_, _, err = fs.StoreMsg("foo.1", nil, payload)
  3642  			require_NoError(t, err)
  3643  		}
  3644  		_, _, err = fs.StoreMsg("foo.2", nil, []byte("xxxxxx"))
  3645  		require_NoError(t, err)
  3646  
  3647  		// This should purge all.
  3648  		p, err := fs.PurgeEx("foo.1", 1, 0)
  3649  		require_NoError(t, err)
  3650  		require_True(t, int(p) == total)
  3651  		require_True(t, int(p) == total)
  3652  		require_True(t, fs.State().Msgs == 1)
  3653  		require_True(t, fs.State().FirstSeq == 201)
  3654  	})
  3655  }
  3656  
  3657  // When the N.idx file is shorter than the previous write we could fail to recover the idx properly.
  3658  // For instance, with encryption and an expiring stream that has no messages, when a restart happens the decrypt will fail
  3659  // since their are extra bytes, and this could lead to a stream sequence reset to zero.
  3660  //
  3661  // NOTE: We do not use idx files anymore, but keeping test.
  3662  func TestFileStoreShortIndexWriteBug(t *testing.T) {
  3663  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3664  		// Encrypted mode shows, but could effect non-encrypted mode.
  3665  		cfg := StreamConfig{Name: "TEST", Storage: FileStorage, MaxAge: time.Second}
  3666  		created := time.Now()
  3667  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  3668  		require_NoError(t, err)
  3669  		defer fs.Stop()
  3670  
  3671  		for i := 0; i < 100; i++ {
  3672  			_, _, err = fs.StoreMsg("foo", nil, nil)
  3673  			require_NoError(t, err)
  3674  		}
  3675  		// Wait til messages all go away.
  3676  		checkFor(t, 5*time.Second, 200*time.Millisecond, func() error {
  3677  			if state := fs.State(); state.Msgs != 0 {
  3678  				return fmt.Errorf("Expected no msgs, got %d", state.Msgs)
  3679  			}
  3680  			return nil
  3681  		})
  3682  
  3683  		if state := fs.State(); state.FirstSeq != 101 {
  3684  			t.Fatalf("Expected first sequence of 101 vs %d", state.FirstSeq)
  3685  		}
  3686  
  3687  		// Now restart..
  3688  		fs.Stop()
  3689  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  3690  		require_NoError(t, err)
  3691  		defer fs.Stop()
  3692  
  3693  		if state := fs.State(); state.FirstSeq != 101 || state.LastSeq != 100 {
  3694  			t.Fatalf("Expected first sequence of 101 vs %d", state.FirstSeq)
  3695  		}
  3696  	})
  3697  }
  3698  
  3699  func TestFileStoreDoubleCompactWithWriteInBetweenEncryptedBug(t *testing.T) {
  3700  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3701  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  3702  		require_NoError(t, err)
  3703  		defer fs.Stop()
  3704  
  3705  		subj, msg := "foo", []byte("ouch")
  3706  		for i := 0; i < 5; i++ {
  3707  			fs.StoreMsg(subj, nil, msg)
  3708  		}
  3709  		_, err = fs.Compact(5)
  3710  		require_NoError(t, err)
  3711  
  3712  		if state := fs.State(); state.LastSeq != 5 {
  3713  			t.Fatalf("Expected last sequence to be 5 but got %d", state.LastSeq)
  3714  		}
  3715  		for i := 0; i < 5; i++ {
  3716  			fs.StoreMsg(subj, nil, msg)
  3717  		}
  3718  		_, err = fs.Compact(10)
  3719  		require_NoError(t, err)
  3720  
  3721  		if state := fs.State(); state.LastSeq != 10 {
  3722  			t.Fatalf("Expected last sequence to be 10 but got %d", state.LastSeq)
  3723  		}
  3724  	})
  3725  }
  3726  
  3727  // When we kept the empty block for tracking sequence, we needed to reset the bek
  3728  // counter when encrypted for subsequent writes to be correct. The bek in place could
  3729  // possibly still have a non-zero counter from previous writes.
  3730  // Happens when all messages expire and the are flushed and then subsequent writes occur.
  3731  func TestFileStoreEncryptedKeepIndexNeedBekResetBug(t *testing.T) {
  3732  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3733  		ttl := 1 * time.Second
  3734  		cfg := StreamConfig{Name: "zzz", Storage: FileStorage, MaxAge: ttl}
  3735  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3736  		require_NoError(t, err)
  3737  		defer fs.Stop()
  3738  
  3739  		subj, msg := "foo", []byte("ouch")
  3740  		for i := 0; i < 5; i++ {
  3741  			fs.StoreMsg(subj, nil, msg)
  3742  		}
  3743  
  3744  		// Want to go to 0.
  3745  		// This will leave the marker.
  3746  		checkFor(t, 5*time.Second, ttl, func() error {
  3747  			if state := fs.State(); state.Msgs != 0 {
  3748  				return fmt.Errorf("Expected no msgs, got %d", state.Msgs)
  3749  			}
  3750  			return nil
  3751  		})
  3752  
  3753  		// Now write additional messages.
  3754  		for i := 0; i < 5; i++ {
  3755  			fs.StoreMsg(subj, nil, msg)
  3756  		}
  3757  
  3758  		// Make sure the buffer is cleared.
  3759  		fs.mu.RLock()
  3760  		mb := fs.lmb
  3761  		fs.mu.RUnlock()
  3762  		mb.mu.Lock()
  3763  		mb.clearCacheAndOffset()
  3764  		mb.mu.Unlock()
  3765  
  3766  		// Now make sure we can read.
  3767  		var smv StoreMsg
  3768  		_, err = fs.LoadMsg(10, &smv)
  3769  		require_NoError(t, err)
  3770  	})
  3771  }
  3772  
  3773  func (fs *fileStore) reportMeta() (hasPSIM, hasAnyFSS bool) {
  3774  	fs.mu.RLock()
  3775  	defer fs.mu.RUnlock()
  3776  
  3777  	hasPSIM = fs.psim != nil
  3778  	for _, mb := range fs.blks {
  3779  		mb.mu.RLock()
  3780  		hasAnyFSS = hasAnyFSS || mb.fss != nil
  3781  		mb.mu.RUnlock()
  3782  		if hasAnyFSS {
  3783  			break
  3784  		}
  3785  	}
  3786  	return hasPSIM, hasAnyFSS
  3787  }
  3788  
  3789  func TestFileStoreExpireSubjectMeta(t *testing.T) {
  3790  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3791  		fcfg.BlockSize = 1024
  3792  		fcfg.CacheExpire = time.Second
  3793  		fcfg.SyncInterval = time.Second
  3794  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"kv.>"}, Storage: FileStorage, MaxMsgsPer: 1}
  3795  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3796  		require_NoError(t, err)
  3797  		defer fs.Stop()
  3798  
  3799  		ns := 100
  3800  		for i := 1; i <= ns; i++ {
  3801  			subj := fmt.Sprintf("kv.%d", i)
  3802  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3803  			require_NoError(t, err)
  3804  		}
  3805  
  3806  		// Test that on restart we do not have extensize metadata but do have correct number of subjects/keys.
  3807  		// Only thing really needed for store state / stream info.
  3808  		fs.Stop()
  3809  		fs, err = newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3810  		require_NoError(t, err)
  3811  		defer fs.Stop()
  3812  
  3813  		var ss StreamState
  3814  		fs.FastState(&ss)
  3815  		if ss.NumSubjects != ns {
  3816  			t.Fatalf("Expected NumSubjects of %d, got %d", ns, ss.NumSubjects)
  3817  		}
  3818  
  3819  		// Make sure we clear mb fss meta
  3820  		checkFor(t, 10*time.Second, 500*time.Millisecond, func() error {
  3821  			if _, hasAnyFSS := fs.reportMeta(); hasAnyFSS {
  3822  				return fmt.Errorf("Still have mb fss state")
  3823  			}
  3824  			return nil
  3825  		})
  3826  
  3827  		// LoadLast, which is what KV uses, should load meta and succeed.
  3828  		_, err = fs.LoadLastMsg("kv.22", nil)
  3829  		require_NoError(t, err)
  3830  		// Make sure we clear mb fss meta
  3831  		checkFor(t, 10*time.Second, 500*time.Millisecond, func() error {
  3832  			if _, hasAnyFSS := fs.reportMeta(); hasAnyFSS {
  3833  				return fmt.Errorf("Still have mb fss state")
  3834  			}
  3835  			return nil
  3836  		})
  3837  	})
  3838  }
  3839  
  3840  func TestFileStoreMaxMsgsPerSubject(t *testing.T) {
  3841  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3842  		fcfg.BlockSize = 128
  3843  		fcfg.CacheExpire = time.Second
  3844  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"kv.>"}, Storage: FileStorage, MaxMsgsPer: 1}
  3845  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3846  		require_NoError(t, err)
  3847  		defer fs.Stop()
  3848  
  3849  		ns := 100
  3850  		for i := 1; i <= ns; i++ {
  3851  			subj := fmt.Sprintf("kv.%d", i)
  3852  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3853  			require_NoError(t, err)
  3854  		}
  3855  
  3856  		for i := 1; i <= ns; i++ {
  3857  			subj := fmt.Sprintf("kv.%d", i)
  3858  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3859  			require_NoError(t, err)
  3860  		}
  3861  
  3862  		if state := fs.State(); state.Msgs != 100 || state.FirstSeq != 101 || state.LastSeq != 200 || len(state.Deleted) != 0 {
  3863  			t.Fatalf("Bad state: %+v", state)
  3864  		}
  3865  
  3866  		if nb := fs.numMsgBlocks(); nb != 34 {
  3867  			t.Fatalf("Expected 34 blocks, got %d", nb)
  3868  		}
  3869  	})
  3870  }
  3871  
  3872  // Testing the case in https://github.com/nats-io/nats-server/issues/4247
  3873  func TestFileStoreMaxMsgsAndMaxMsgsPerSubject(t *testing.T) {
  3874  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3875  		fcfg.BlockSize = 128
  3876  		fcfg.CacheExpire = time.Second
  3877  		cfg := StreamConfig{
  3878  			Name:     "zzz",
  3879  			Subjects: []string{"kv.>"},
  3880  			Storage:  FileStorage,
  3881  			Discard:  DiscardNew, MaxMsgs: 100, // Total stream policy
  3882  			DiscardNewPer: true, MaxMsgsPer: 1, // Per-subject policy
  3883  		}
  3884  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3885  		require_NoError(t, err)
  3886  		defer fs.Stop()
  3887  
  3888  		for i := 1; i <= 101; i++ {
  3889  			subj := fmt.Sprintf("kv.%d", i)
  3890  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3891  			if i == 101 {
  3892  				// The 101th iteration should fail because MaxMsgs is set to
  3893  				// 100 and the policy is DiscardNew.
  3894  				require_Error(t, err)
  3895  			} else {
  3896  				require_NoError(t, err)
  3897  			}
  3898  		}
  3899  
  3900  		for i := 1; i <= 100; i++ {
  3901  			subj := fmt.Sprintf("kv.%d", i)
  3902  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3903  			// All of these iterations should fail because MaxMsgsPer is set
  3904  			// to 1 and DiscardNewPer is set to true, forcing us to reject
  3905  			// cases where there is already a message on this subject.
  3906  			require_Error(t, err)
  3907  		}
  3908  
  3909  		if state := fs.State(); state.Msgs != 100 || state.FirstSeq != 1 || state.LastSeq != 100 || len(state.Deleted) != 0 {
  3910  			// There should be 100 messages exactly, as the 101st subject
  3911  			// should have been rejected in the first loop, and any duplicates
  3912  			// on the other subjects should have been rejected in the second loop.
  3913  			t.Fatalf("Bad state: %+v", state)
  3914  		}
  3915  	})
  3916  }
  3917  
  3918  func TestFileStoreSubjectStateCacheExpiration(t *testing.T) {
  3919  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3920  		fcfg.BlockSize = 32
  3921  		fcfg.CacheExpire = time.Second
  3922  		fcfg.SyncInterval = time.Second
  3923  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"kv.>"}, Storage: FileStorage, MaxMsgsPer: 2}
  3924  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  3925  		require_NoError(t, err)
  3926  		defer fs.Stop()
  3927  
  3928  		for i := 1; i <= 100; i++ {
  3929  			subj := fmt.Sprintf("kv.foo.%d", i)
  3930  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3931  			require_NoError(t, err)
  3932  		}
  3933  		for i := 1; i <= 100; i++ {
  3934  			subj := fmt.Sprintf("kv.bar.%d", i)
  3935  			_, _, err := fs.StoreMsg(subj, nil, []byte("value"))
  3936  			require_NoError(t, err)
  3937  		}
  3938  
  3939  		// Make sure we clear mb fss meta before asking for SubjectState.
  3940  		checkFor(t, 10*time.Second, 500*time.Millisecond, func() error {
  3941  			if _, hasAnyFSS := fs.reportMeta(); hasAnyFSS {
  3942  				return fmt.Errorf("Still have mb fss state")
  3943  			}
  3944  			return nil
  3945  		})
  3946  
  3947  		if fss := fs.SubjectsState("kv.bar.>"); len(fss) != 100 {
  3948  			t.Fatalf("Expected 100 entries but got %d", len(fss))
  3949  		}
  3950  
  3951  		fss := fs.SubjectsState("kv.bar.99")
  3952  		if len(fss) != 1 {
  3953  			t.Fatalf("Expected 1 entry but got %d", len(fss))
  3954  		}
  3955  		expected := SimpleState{Msgs: 1, First: 199, Last: 199}
  3956  		if ss := fss["kv.bar.99"]; ss != expected {
  3957  			t.Fatalf("Bad subject state, expected %+v but got %+v", expected, ss)
  3958  		}
  3959  
  3960  		// Now add one to end and check as well for non-wildcard.
  3961  		_, _, err = fs.StoreMsg("kv.foo.1", nil, []byte("value22"))
  3962  		require_NoError(t, err)
  3963  
  3964  		if state := fs.State(); state.Msgs != 201 {
  3965  			t.Fatalf("Expected 201 msgs but got %+v", state)
  3966  		}
  3967  
  3968  		fss = fs.SubjectsState("kv.foo.1")
  3969  		if len(fss) != 1 {
  3970  			t.Fatalf("Expected 1 entry but got %d", len(fss))
  3971  		}
  3972  		expected = SimpleState{Msgs: 2, First: 1, Last: 201}
  3973  		if ss := fss["kv.foo.1"]; ss != expected {
  3974  			t.Fatalf("Bad subject state, expected %+v but got %+v", expected, ss)
  3975  		}
  3976  	})
  3977  }
  3978  
  3979  func TestFileStoreEncrypted(t *testing.T) {
  3980  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  3981  		created := time.Now()
  3982  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  3983  		require_NoError(t, err)
  3984  		defer fs.Stop()
  3985  
  3986  		subj, msg := "foo", []byte("aes ftw")
  3987  		for i := 0; i < 50; i++ {
  3988  			fs.StoreMsg(subj, nil, msg)
  3989  		}
  3990  
  3991  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{})
  3992  		require_NoError(t, err)
  3993  
  3994  		state := &ConsumerState{}
  3995  		state.Delivered.Consumer = 22
  3996  		state.Delivered.Stream = 22
  3997  		state.AckFloor.Consumer = 11
  3998  		state.AckFloor.Stream = 11
  3999  		err = o.Update(state)
  4000  		require_NoError(t, err)
  4001  
  4002  		fs.Stop()
  4003  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  4004  		require_NoError(t, err)
  4005  		defer fs.Stop()
  4006  
  4007  		// Now make sure we can read.
  4008  		var smv StoreMsg
  4009  		sm, err := fs.LoadMsg(10, &smv)
  4010  		require_NoError(t, err)
  4011  		require_True(t, string(sm.msg) == "aes ftw")
  4012  
  4013  		o, err = fs.ConsumerStore("o22", &ConsumerConfig{})
  4014  		require_NoError(t, err)
  4015  		rstate, err := o.State()
  4016  		require_NoError(t, err)
  4017  
  4018  		if rstate.Delivered != state.Delivered || rstate.AckFloor != state.AckFloor {
  4019  			t.Fatalf("Bad recovered consumer state, expected %+v got %+v", state, rstate)
  4020  		}
  4021  	})
  4022  }
  4023  
  4024  // Make sure we do not go through block loads when we know no subjects will exists, e.g. raft.
  4025  func TestFileStoreNoFSSWhenNoSubjects(t *testing.T) {
  4026  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4027  		created := time.Now()
  4028  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  4029  		require_NoError(t, err)
  4030  		defer fs.Stop()
  4031  
  4032  		n, msg := 100, []byte("raft state")
  4033  		for i := 0; i < n; i++ {
  4034  			_, _, err := fs.StoreMsg(_EMPTY_, nil, msg)
  4035  			require_NoError(t, err)
  4036  		}
  4037  
  4038  		state := fs.State()
  4039  		require_True(t, state.Msgs == uint64(n))
  4040  
  4041  		fs.Stop()
  4042  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, created, prf(&fcfg), nil)
  4043  		require_NoError(t, err)
  4044  		defer fs.Stop()
  4045  
  4046  		// Make sure we did not load the block trying to generate fss.
  4047  		fs.mu.RLock()
  4048  		mb := fs.blks[0]
  4049  		fs.mu.RUnlock()
  4050  
  4051  		mb.mu.Lock()
  4052  		defer mb.mu.Unlock()
  4053  
  4054  		if mb.cloads > 0 {
  4055  			t.Fatalf("Expected no cache loads but got %d", mb.cloads)
  4056  		}
  4057  		if mb.fss != nil {
  4058  			t.Fatalf("Expected fss to be nil")
  4059  		}
  4060  	})
  4061  }
  4062  
  4063  func TestFileStoreNoFSSBugAfterRemoveFirst(t *testing.T) {
  4064  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4065  		fcfg.BlockSize = 8 * 1024 * 1024
  4066  		fcfg.CacheExpire = 200 * time.Millisecond
  4067  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo.bar.*"}, Storage: FileStorage}
  4068  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4069  		require_NoError(t, err)
  4070  		defer fs.Stop()
  4071  
  4072  		n, msg := 100, bytes.Repeat([]byte("ZZZ"), 33) // ~100bytes
  4073  		for i := 0; i < n; i++ {
  4074  			subj := fmt.Sprintf("foo.bar.%d", i)
  4075  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4076  			require_NoError(t, err)
  4077  		}
  4078  
  4079  		state := fs.State()
  4080  		require_True(t, state.Msgs == uint64(n))
  4081  
  4082  		// Let fss expire.
  4083  		time.Sleep(250 * time.Millisecond)
  4084  
  4085  		_, err = fs.RemoveMsg(1)
  4086  		require_NoError(t, err)
  4087  
  4088  		sm, _, err := fs.LoadNextMsg("foo.>", true, 1, nil)
  4089  		require_NoError(t, err)
  4090  		require_True(t, sm.subj == "foo.bar.1")
  4091  
  4092  		// Make sure mb.fss does not have the entry for foo.bar.0
  4093  		fs.mu.Lock()
  4094  		mb := fs.blks[0]
  4095  		fs.mu.Unlock()
  4096  		mb.mu.RLock()
  4097  		ss := mb.fss["foo.bar.0"]
  4098  		mb.mu.RUnlock()
  4099  
  4100  		if ss != nil {
  4101  			t.Fatalf("Expected no state for %q, but got %+v\n", "foo.bar.0", ss)
  4102  		}
  4103  	})
  4104  }
  4105  
  4106  // NOTE: We do not use fss files anymore, but leaving test in place.
  4107  func TestFileStoreNoFSSAfterRecover(t *testing.T) {
  4108  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4109  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4110  		created := time.Now()
  4111  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4112  		require_NoError(t, err)
  4113  		defer fs.Stop()
  4114  
  4115  		n, msg := 100, []byte("no fss for you!")
  4116  		for i := 0; i < n; i++ {
  4117  			_, _, err := fs.StoreMsg(_EMPTY_, nil, msg)
  4118  			require_NoError(t, err)
  4119  		}
  4120  
  4121  		state := fs.State()
  4122  		require_True(t, state.Msgs == uint64(n))
  4123  
  4124  		fs.Stop()
  4125  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4126  		require_NoError(t, err)
  4127  		defer fs.Stop()
  4128  
  4129  		// Make sure we did not load the block trying to generate fss.
  4130  		fs.mu.RLock()
  4131  		mb := fs.blks[0]
  4132  		fs.mu.RUnlock()
  4133  
  4134  		mb.mu.Lock()
  4135  		defer mb.mu.Unlock()
  4136  
  4137  		if mb.fss != nil {
  4138  			t.Fatalf("Expected no fss post recover")
  4139  		}
  4140  	})
  4141  }
  4142  
  4143  func TestFileStoreFSSCloseAndKeepOnExpireOnRecoverBug(t *testing.T) {
  4144  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4145  		ttl := 100 * time.Millisecond
  4146  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage, MaxAge: ttl}
  4147  		created := time.Now()
  4148  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4149  		require_NoError(t, err)
  4150  		defer fs.Stop()
  4151  
  4152  		_, _, err = fs.StoreMsg("foo", nil, nil)
  4153  		require_NoError(t, err)
  4154  
  4155  		fs.Stop()
  4156  		time.Sleep(2 * ttl)
  4157  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4158  		require_NoError(t, err)
  4159  		defer fs.Stop()
  4160  
  4161  		if state := fs.State(); state.NumSubjects != 0 {
  4162  			t.Fatalf("Expected no subjects with no messages, got %d", state.NumSubjects)
  4163  		}
  4164  	})
  4165  }
  4166  
  4167  func TestFileStoreExpireOnRecoverSubjectAccounting(t *testing.T) {
  4168  	const msgLen = 19
  4169  	msg := bytes.Repeat([]byte("A"), msgLen)
  4170  
  4171  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4172  		fcfg.BlockSize = 100
  4173  		ttl := 200 * time.Millisecond
  4174  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxAge: ttl}
  4175  		created := time.Now()
  4176  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4177  		require_NoError(t, err)
  4178  		defer fs.Stop()
  4179  
  4180  		// These are in first block.
  4181  		fs.StoreMsg("A", nil, msg)
  4182  		fs.StoreMsg("B", nil, msg)
  4183  		time.Sleep(ttl / 2)
  4184  		// This one in 2nd block.
  4185  		fs.StoreMsg("C", nil, msg)
  4186  
  4187  		fs.Stop()
  4188  		time.Sleep(ttl/2 + 10*time.Millisecond)
  4189  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4190  		require_NoError(t, err)
  4191  		defer fs.Stop()
  4192  
  4193  		// Make sure we take into account PSIM when throwing a whole block away.
  4194  		if state := fs.State(); state.NumSubjects != 1 {
  4195  			t.Fatalf("Expected 1 subject, got %d", state.NumSubjects)
  4196  		}
  4197  	})
  4198  }
  4199  
  4200  func TestFileStoreFSSExpireNumPendingBug(t *testing.T) {
  4201  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4202  		cexp := 100 * time.Millisecond
  4203  		fcfg.CacheExpire = cexp
  4204  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"KV.>"}, MaxMsgsPer: 1, Storage: FileStorage}
  4205  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4206  		require_NoError(t, err)
  4207  		defer fs.Stop()
  4208  
  4209  		// Let FSS meta expire.
  4210  		time.Sleep(2 * cexp)
  4211  
  4212  		_, _, err = fs.StoreMsg("KV.X", nil, []byte("Y"))
  4213  		require_NoError(t, err)
  4214  
  4215  		if fss := fs.FilteredState(1, "KV.X"); fss.Msgs != 1 {
  4216  			t.Fatalf("Expected only 1 msg, got %d", fss.Msgs)
  4217  		}
  4218  	})
  4219  }
  4220  
  4221  // https://github.com/nats-io/nats-server/issues/3484
  4222  func TestFileStoreFilteredFirstMatchingBug(t *testing.T) {
  4223  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4224  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo.>"}, Storage: FileStorage}
  4225  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4226  		require_NoError(t, err)
  4227  		defer fs.Stop()
  4228  
  4229  		_, _, err = fs.StoreMsg("foo.foo", nil, []byte("A"))
  4230  		require_NoError(t, err)
  4231  
  4232  		_, _, err = fs.StoreMsg("foo.foo", nil, []byte("B"))
  4233  		require_NoError(t, err)
  4234  
  4235  		_, _, err = fs.StoreMsg("foo.foo", nil, []byte("C"))
  4236  		require_NoError(t, err)
  4237  
  4238  		fs.mu.RLock()
  4239  		mb := fs.lmb
  4240  		fs.mu.RUnlock()
  4241  
  4242  		mb.mu.Lock()
  4243  		// Simulate swapping out the fss state and reading it back in with only one subject
  4244  		// present in the block.
  4245  		if mb.fss != nil {
  4246  			mb.fss = nil
  4247  		}
  4248  		// Now load info back in.
  4249  		mb.generatePerSubjectInfo()
  4250  		mb.mu.Unlock()
  4251  
  4252  		// Now add in a different subject.
  4253  		_, _, err = fs.StoreMsg("foo.bar", nil, []byte("X"))
  4254  		require_NoError(t, err)
  4255  
  4256  		// Now see if a filtered load would incorrectly succeed.
  4257  		sm, _, err := fs.LoadNextMsg("foo.foo", false, 4, nil)
  4258  		if err == nil || sm != nil {
  4259  			t.Fatalf("Loaded filtered message with wrong subject, wanted %q got %q", "foo.foo", sm.subj)
  4260  		}
  4261  	})
  4262  }
  4263  
  4264  func TestFileStoreOutOfSpaceRebuildState(t *testing.T) {
  4265  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4266  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  4267  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4268  		require_NoError(t, err)
  4269  		defer fs.Stop()
  4270  
  4271  		_, _, err = fs.StoreMsg("foo", nil, []byte("A"))
  4272  		require_NoError(t, err)
  4273  
  4274  		_, _, err = fs.StoreMsg("bar", nil, []byte("B"))
  4275  		require_NoError(t, err)
  4276  
  4277  		// Grab state.
  4278  		state := fs.State()
  4279  		ss := fs.SubjectsState(">")
  4280  
  4281  		// Set mock out of space error to trip.
  4282  		fs.mu.RLock()
  4283  		mb := fs.lmb
  4284  		fs.mu.RUnlock()
  4285  
  4286  		mb.mu.Lock()
  4287  		mb.mockWriteErr = true
  4288  		mb.mu.Unlock()
  4289  
  4290  		_, _, err = fs.StoreMsg("baz", nil, []byte("C"))
  4291  		require_Error(t, err, errors.New("mock write error"))
  4292  
  4293  		nstate := fs.State()
  4294  		nss := fs.SubjectsState(">")
  4295  
  4296  		if !reflect.DeepEqual(state, nstate) {
  4297  			t.Fatalf("State expected to be\n  %+v\nvs\n  %+v", state, nstate)
  4298  		}
  4299  
  4300  		if !reflect.DeepEqual(ss, nss) {
  4301  			t.Fatalf("Subject state expected to be\n  %+v\nvs\n  %+v", ss, nss)
  4302  		}
  4303  	})
  4304  }
  4305  
  4306  func TestFileStoreRebuildStateProperlyWithMaxMsgsPerSubject(t *testing.T) {
  4307  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4308  		fcfg.BlockSize = 4096
  4309  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo", "bar", "baz"}, Storage: FileStorage, MaxMsgsPer: 1}
  4310  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4311  		require_NoError(t, err)
  4312  		defer fs.Stop()
  4313  
  4314  		// Send one to baz at beginning.
  4315  		_, _, err = fs.StoreMsg("baz", nil, nil)
  4316  		require_NoError(t, err)
  4317  
  4318  		ns := 1000
  4319  		for i := 1; i <= ns; i++ {
  4320  			_, _, err := fs.StoreMsg("foo", nil, nil)
  4321  			require_NoError(t, err)
  4322  			_, _, err = fs.StoreMsg("bar", nil, nil)
  4323  			require_NoError(t, err)
  4324  		}
  4325  
  4326  		var ss StreamState
  4327  		fs.FastState(&ss)
  4328  		if ss.NumSubjects != 3 {
  4329  			t.Fatalf("Expected NumSubjects of 3, got %d", ss.NumSubjects)
  4330  		}
  4331  		if ss.Msgs != 3 {
  4332  			t.Fatalf("Expected NumMsgs of 3, got %d", ss.Msgs)
  4333  		}
  4334  	})
  4335  }
  4336  
  4337  func TestFileStoreUpdateMaxMsgsPerSubject(t *testing.T) {
  4338  	cfg := StreamConfig{
  4339  		Name:       "TEST",
  4340  		Storage:    FileStorage,
  4341  		Subjects:   []string{"foo"},
  4342  		MaxMsgsPer: 10,
  4343  	}
  4344  
  4345  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4346  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4347  		require_NoError(t, err)
  4348  		defer fs.Stop()
  4349  
  4350  		// Make sure this is honored on an update.
  4351  		cfg.MaxMsgsPer = 50
  4352  		err = fs.UpdateConfig(&cfg)
  4353  		require_NoError(t, err)
  4354  
  4355  		numStored := 22
  4356  		for i := 0; i < numStored; i++ {
  4357  			_, _, err = fs.StoreMsg("foo", nil, nil)
  4358  			require_NoError(t, err)
  4359  		}
  4360  
  4361  		ss := fs.SubjectsState("foo")["foo"]
  4362  		if ss.Msgs != uint64(numStored) {
  4363  			t.Fatalf("Expected to have %d stored, got %d", numStored, ss.Msgs)
  4364  		}
  4365  
  4366  		// Now make sure we trunk if setting to lower value.
  4367  		cfg.MaxMsgsPer = 10
  4368  		err = fs.UpdateConfig(&cfg)
  4369  		require_NoError(t, err)
  4370  
  4371  		ss = fs.SubjectsState("foo")["foo"]
  4372  		if ss.Msgs != 10 {
  4373  			t.Fatalf("Expected to have %d stored, got %d", 10, ss.Msgs)
  4374  		}
  4375  	})
  4376  }
  4377  
  4378  func TestFileStoreBadFirstAndFailedExpireAfterRestart(t *testing.T) {
  4379  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4380  		fcfg.BlockSize = 256
  4381  		ttl := time.Second
  4382  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage, MaxAge: ttl}
  4383  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4384  		require_NoError(t, err)
  4385  		defer fs.Stop()
  4386  
  4387  		// With block size of 256 and subject and message below, seq 8 starts new block.
  4388  		// Will double check and fail test if not the case since test depends on this.
  4389  		subj, msg := "foo", []byte("ZZ")
  4390  		// These are all instant and will expire after 1 sec.
  4391  		start := time.Now()
  4392  		for i := 0; i < 7; i++ {
  4393  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4394  			require_NoError(t, err)
  4395  		}
  4396  
  4397  		// Put two more after a delay.
  4398  		time.Sleep(1500 * time.Millisecond)
  4399  		seq, _, err := fs.StoreMsg(subj, nil, msg)
  4400  		require_NoError(t, err)
  4401  		_, _, err = fs.StoreMsg(subj, nil, msg)
  4402  		require_NoError(t, err)
  4403  
  4404  		// Make sure that sequence 8 is first in second block, and break test if that is not true.
  4405  		fs.mu.RLock()
  4406  		lmb := fs.lmb
  4407  		fs.mu.RUnlock()
  4408  		lmb.mu.RLock()
  4409  		first := lmb.first.seq
  4410  		lmb.mu.RUnlock()
  4411  		require_True(t, first == 8)
  4412  
  4413  		// Instantly remove first one from second block.
  4414  		// On restart this will trigger expire on recover which will set fs.FirstSeq to the deleted one.
  4415  		fs.RemoveMsg(seq)
  4416  
  4417  		// Stop the filstore and wait til first block expires.
  4418  		fs.Stop()
  4419  		time.Sleep(ttl - time.Since(start) + (time.Second))
  4420  		fs, err = newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4421  		require_NoError(t, err)
  4422  		defer fs.Stop()
  4423  
  4424  		// Check that state is correct for first message which should be 9 and have a proper timestamp.
  4425  		var state StreamState
  4426  		fs.FastState(&state)
  4427  		ts := state.FirstTime
  4428  		require_True(t, state.Msgs == 1)
  4429  		require_True(t, state.FirstSeq == 9)
  4430  		require_True(t, !state.FirstTime.IsZero())
  4431  
  4432  		// Wait and make sure expire timer is still working properly.
  4433  		time.Sleep(2 * ttl)
  4434  		fs.FastState(&state)
  4435  		require_Equal(t, state.Msgs, 0)
  4436  		require_Equal(t, state.FirstSeq, 10)
  4437  		require_Equal(t, state.LastSeq, 9)
  4438  		require_Equal(t, state.LastTime, ts)
  4439  	})
  4440  }
  4441  
  4442  func TestFileStoreCompactAllWithDanglingLMB(t *testing.T) {
  4443  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4444  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4445  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4446  		require_NoError(t, err)
  4447  		defer fs.Stop()
  4448  
  4449  		subj, msg := "foo", []byte("ZZ")
  4450  		for i := 0; i < 100; i++ {
  4451  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4452  			require_NoError(t, err)
  4453  		}
  4454  
  4455  		fs.RemoveMsg(100)
  4456  		purged, err := fs.Compact(100)
  4457  		require_NoError(t, err)
  4458  		require_True(t, purged == 99)
  4459  
  4460  		_, _, err = fs.StoreMsg(subj, nil, msg)
  4461  		require_NoError(t, err)
  4462  	})
  4463  }
  4464  
  4465  func TestFileStoreStateWithBlkFirstDeleted(t *testing.T) {
  4466  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4467  		fcfg.BlockSize = 4096
  4468  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4469  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4470  		require_NoError(t, err)
  4471  		defer fs.Stop()
  4472  
  4473  		subj, msg := "foo", []byte("Hello World")
  4474  		toStore := 500
  4475  		for i := 0; i < toStore; i++ {
  4476  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4477  			require_NoError(t, err)
  4478  		}
  4479  
  4480  		// Delete some messages from the beginning of an interior block.
  4481  		fs.mu.RLock()
  4482  		require_True(t, len(fs.blks) > 2)
  4483  		fseq := fs.blks[1].first.seq
  4484  		fs.mu.RUnlock()
  4485  
  4486  		// Now start from first seq of second blk and delete 10 msgs
  4487  		for seq := fseq; seq < fseq+10; seq++ {
  4488  			removed, err := fs.RemoveMsg(seq)
  4489  			require_NoError(t, err)
  4490  			require_True(t, removed)
  4491  		}
  4492  
  4493  		// This bug was in normal detailed state. But check fast state too.
  4494  		var fstate StreamState
  4495  		fs.FastState(&fstate)
  4496  		require_True(t, fstate.NumDeleted == 10)
  4497  		state := fs.State()
  4498  		require_True(t, state.NumDeleted == 10)
  4499  	})
  4500  }
  4501  
  4502  func TestFileStoreMsgBlkFailOnKernelFaultLostDataReporting(t *testing.T) {
  4503  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4504  		fcfg.BlockSize = 4096
  4505  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4506  		created := time.Now()
  4507  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4508  		require_NoError(t, err)
  4509  		defer fs.Stop()
  4510  
  4511  		subj, msg := "foo", []byte("Hello World")
  4512  		toStore := 500
  4513  		for i := 0; i < toStore; i++ {
  4514  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4515  			require_NoError(t, err)
  4516  		}
  4517  
  4518  		// We want to make sure all of the scenarios report lost data properly.
  4519  		// Will run 3 scenarios, 1st block, last block, interior block.
  4520  		// The new system does not detect byzantine behavior by default on creating the store.
  4521  		// A LoadMsg() of checkMsgs() call will be needed now.
  4522  
  4523  		// First block
  4524  		fs.mu.RLock()
  4525  		require_True(t, len(fs.blks) > 0)
  4526  		mfn := fs.blks[0].mfn
  4527  		fs.mu.RUnlock()
  4528  
  4529  		fs.Stop()
  4530  
  4531  		require_NoError(t, os.Remove(mfn))
  4532  
  4533  		// Restart.
  4534  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4535  		require_NoError(t, err)
  4536  		defer fs.Stop()
  4537  
  4538  		_, err = fs.LoadMsg(1, nil)
  4539  		require_Error(t, err, errNoBlkData)
  4540  
  4541  		// Load will rebuild fs itself async..
  4542  		checkFor(t, time.Second, 50*time.Millisecond, func() error {
  4543  			if state := fs.State(); state.Lost != nil {
  4544  				return nil
  4545  			}
  4546  			return errors.New("no ld yet")
  4547  		})
  4548  
  4549  		state := fs.State()
  4550  		require_True(t, state.FirstSeq == 94)
  4551  		require_True(t, state.Lost != nil)
  4552  		require_True(t, len(state.Lost.Msgs) == 93)
  4553  
  4554  		// Last block
  4555  		fs.mu.RLock()
  4556  		require_True(t, len(fs.blks) > 0)
  4557  		require_True(t, fs.lmb != nil)
  4558  		mfn = fs.lmb.mfn
  4559  		fs.mu.RUnlock()
  4560  
  4561  		fs.Stop()
  4562  
  4563  		require_NoError(t, os.Remove(mfn))
  4564  
  4565  		// Restart.
  4566  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4567  		require_NoError(t, err)
  4568  		defer fs.Stop()
  4569  
  4570  		state = fs.State()
  4571  		require_True(t, state.FirstSeq == 94)
  4572  		require_True(t, state.LastSeq == 500)   // Make sure we do not lose last seq.
  4573  		require_True(t, state.NumDeleted == 35) // These are interiors
  4574  		require_True(t, state.Lost != nil)
  4575  		require_True(t, len(state.Lost.Msgs) == 35)
  4576  
  4577  		// Interior block.
  4578  		fs.mu.RLock()
  4579  		require_True(t, len(fs.blks) > 3)
  4580  		mfn = fs.blks[len(fs.blks)-3].mfn
  4581  		fs.mu.RUnlock()
  4582  
  4583  		fs.Stop()
  4584  
  4585  		require_NoError(t, os.Remove(mfn))
  4586  
  4587  		// Restart.
  4588  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  4589  		require_NoError(t, err)
  4590  		defer fs.Stop()
  4591  
  4592  		// Need checkMsgs to catch interior one.
  4593  		require_True(t, fs.checkMsgs() != nil)
  4594  
  4595  		state = fs.State()
  4596  		require_True(t, state.FirstSeq == 94)
  4597  		require_True(t, state.LastSeq == 500) // Make sure we do not lose last seq.
  4598  		require_True(t, state.NumDeleted == 128)
  4599  		require_True(t, state.Lost != nil)
  4600  		require_True(t, len(state.Lost.Msgs) == 93)
  4601  	})
  4602  }
  4603  
  4604  func TestFileStoreAllFilteredStateWithDeleted(t *testing.T) {
  4605  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4606  		fcfg.BlockSize = 1024
  4607  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4608  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4609  		require_NoError(t, err)
  4610  		defer fs.Stop()
  4611  
  4612  		subj, msg := "foo", []byte("Hello World")
  4613  		for i := 0; i < 100; i++ {
  4614  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4615  			require_NoError(t, err)
  4616  		}
  4617  
  4618  		remove := func(seqs ...uint64) {
  4619  			for _, seq := range seqs {
  4620  				ok, err := fs.RemoveMsg(seq)
  4621  				require_NoError(t, err)
  4622  				require_True(t, ok)
  4623  			}
  4624  		}
  4625  
  4626  		checkFilteredState := func(start, msgs, first, last int) {
  4627  			fss := fs.FilteredState(uint64(start), _EMPTY_)
  4628  			if fss.Msgs != uint64(msgs) {
  4629  				t.Fatalf("Expected %d msgs, got %d", msgs, fss.Msgs)
  4630  			}
  4631  			if fss.First != uint64(first) {
  4632  				t.Fatalf("Expected %d to be first, got %d", first, fss.First)
  4633  			}
  4634  			if fss.Last != uint64(last) {
  4635  				t.Fatalf("Expected %d to be last, got %d", last, fss.Last)
  4636  			}
  4637  		}
  4638  
  4639  		checkFilteredState(1, 100, 1, 100)
  4640  		remove(2)
  4641  		checkFilteredState(2, 98, 3, 100)
  4642  		remove(3, 4, 5)
  4643  		checkFilteredState(2, 95, 6, 100)
  4644  		checkFilteredState(6, 95, 6, 100)
  4645  		remove(8, 10, 12, 14, 16, 18)
  4646  		checkFilteredState(7, 88, 7, 100)
  4647  
  4648  		// Now check when purged that we return first and last sequences properly.
  4649  		fs.Purge()
  4650  		checkFilteredState(0, 0, 101, 100)
  4651  	})
  4652  }
  4653  
  4654  func TestFileStoreStreamTruncateResetMultiBlock(t *testing.T) {
  4655  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4656  		fcfg.BlockSize = 128
  4657  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage}
  4658  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4659  		require_NoError(t, err)
  4660  		defer fs.Stop()
  4661  
  4662  		subj, msg := "foo", []byte("Hello World")
  4663  		for i := 0; i < 1000; i++ {
  4664  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4665  			require_NoError(t, err)
  4666  		}
  4667  		fs.syncBlocks()
  4668  		require_True(t, fs.numMsgBlocks() == 500)
  4669  
  4670  		// Reset everything
  4671  		require_NoError(t, fs.Truncate(0))
  4672  		require_True(t, fs.numMsgBlocks() == 0)
  4673  
  4674  		state := fs.State()
  4675  		require_Equal(t, state.Msgs, 0)
  4676  		require_Equal(t, state.Bytes, 0)
  4677  		require_Equal(t, state.FirstSeq, 0)
  4678  		require_Equal(t, state.LastSeq, 0)
  4679  		require_Equal(t, state.NumSubjects, 0)
  4680  		require_Equal(t, state.NumDeleted, 0)
  4681  
  4682  		for i := 0; i < 1000; i++ {
  4683  			_, _, err := fs.StoreMsg(subj, nil, msg)
  4684  			require_NoError(t, err)
  4685  		}
  4686  		fs.syncBlocks()
  4687  
  4688  		state = fs.State()
  4689  		require_Equal(t, state.Msgs, 1000)
  4690  		require_Equal(t, state.Bytes, 44000)
  4691  		require_Equal(t, state.FirstSeq, 1)
  4692  		require_Equal(t, state.LastSeq, 1000)
  4693  		require_Equal(t, state.NumSubjects, 1)
  4694  		require_Equal(t, state.NumDeleted, 0)
  4695  	})
  4696  }
  4697  
  4698  func TestFileStoreStreamCompactMultiBlockSubjectInfo(t *testing.T) {
  4699  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4700  		fcfg.BlockSize = 128
  4701  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage}
  4702  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4703  		require_NoError(t, err)
  4704  		defer fs.Stop()
  4705  
  4706  		for i := 0; i < 1000; i++ {
  4707  			subj := fmt.Sprintf("foo.%d", i)
  4708  			_, _, err := fs.StoreMsg(subj, nil, []byte("Hello World"))
  4709  			require_NoError(t, err)
  4710  		}
  4711  		require_True(t, fs.numMsgBlocks() == 500)
  4712  
  4713  		// Compact such that we know we throw blocks away from the beginning.
  4714  		deleted, err := fs.Compact(501)
  4715  		require_NoError(t, err)
  4716  		require_True(t, deleted == 500)
  4717  		require_True(t, fs.numMsgBlocks() == 250)
  4718  
  4719  		// Make sure we adjusted for subjects etc.
  4720  		state := fs.State()
  4721  		require_True(t, state.NumSubjects == 500)
  4722  	})
  4723  }
  4724  
  4725  func TestFileStoreSubjectsTotals(t *testing.T) {
  4726  	// No need for all permutations here.
  4727  	storeDir := t.TempDir()
  4728  	fcfg := FileStoreConfig{StoreDir: storeDir}
  4729  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"*.*"}, Storage: FileStorage})
  4730  	require_NoError(t, err)
  4731  	defer fs.Stop()
  4732  
  4733  	fmap := make(map[int]int)
  4734  	bmap := make(map[int]int)
  4735  
  4736  	var m map[int]int
  4737  	var ft string
  4738  
  4739  	for i := 0; i < 10_000; i++ {
  4740  		// Flip coin for prefix
  4741  		if rand.Intn(2) == 0 {
  4742  			ft, m = "foo", fmap
  4743  		} else {
  4744  			ft, m = "bar", bmap
  4745  		}
  4746  		dt := rand.Intn(100)
  4747  		subj := fmt.Sprintf("%s.%d", ft, dt)
  4748  		m[dt]++
  4749  
  4750  		_, _, err := fs.StoreMsg(subj, nil, []byte("Hello World"))
  4751  		require_NoError(t, err)
  4752  	}
  4753  
  4754  	// Now test SubjectsTotal
  4755  	for dt, total := range fmap {
  4756  		subj := fmt.Sprintf("foo.%d", dt)
  4757  		m := fs.SubjectsTotals(subj)
  4758  		if m[subj] != uint64(total) {
  4759  			t.Fatalf("Expected %q to have %d total, got %d", subj, total, m[subj])
  4760  		}
  4761  	}
  4762  
  4763  	// Check fmap.
  4764  	if st := fs.SubjectsTotals("foo.*"); len(st) != len(fmap) {
  4765  		t.Fatalf("Expected %d subjects for %q, got %d", len(fmap), "foo.*", len(st))
  4766  	} else {
  4767  		expected := 0
  4768  		for _, n := range fmap {
  4769  			expected += n
  4770  		}
  4771  		received := uint64(0)
  4772  		for _, n := range st {
  4773  			received += n
  4774  		}
  4775  		if received != uint64(expected) {
  4776  			t.Fatalf("Expected %d total but got %d", expected, received)
  4777  		}
  4778  	}
  4779  
  4780  	// Check bmap.
  4781  	if st := fs.SubjectsTotals("bar.*"); len(st) != len(bmap) {
  4782  		t.Fatalf("Expected %d subjects for %q, got %d", len(bmap), "bar.*", len(st))
  4783  	} else {
  4784  		expected := 0
  4785  		for _, n := range bmap {
  4786  			expected += n
  4787  		}
  4788  		received := uint64(0)
  4789  		for _, n := range st {
  4790  			received += n
  4791  		}
  4792  		if received != uint64(expected) {
  4793  			t.Fatalf("Expected %d total but got %d", expected, received)
  4794  		}
  4795  	}
  4796  
  4797  	// All with pwc match.
  4798  	if st, expected := fs.SubjectsTotals("*.*"), len(bmap)+len(fmap); len(st) != expected {
  4799  		t.Fatalf("Expected %d subjects for %q, got %d", expected, "*.*", len(st))
  4800  	}
  4801  }
  4802  
  4803  func TestFileStoreConsumerStoreEncodeAfterRestart(t *testing.T) {
  4804  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4805  		fs, err := newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  4806  		require_NoError(t, err)
  4807  		defer fs.Stop()
  4808  
  4809  		o, err := fs.ConsumerStore("o22", &ConsumerConfig{AckPolicy: AckExplicit})
  4810  		require_NoError(t, err)
  4811  
  4812  		state := &ConsumerState{}
  4813  		state.Delivered.Consumer = 22
  4814  		state.Delivered.Stream = 22
  4815  		state.AckFloor.Consumer = 11
  4816  		state.AckFloor.Stream = 11
  4817  		err = o.Update(state)
  4818  		require_NoError(t, err)
  4819  
  4820  		fs.Stop()
  4821  
  4822  		fs, err = newFileStoreWithCreated(fcfg, StreamConfig{Name: "zzz", Storage: FileStorage}, time.Now(), prf(&fcfg), nil)
  4823  		require_NoError(t, err)
  4824  		defer fs.Stop()
  4825  
  4826  		o, err = fs.ConsumerStore("o22", &ConsumerConfig{AckPolicy: AckExplicit})
  4827  		require_NoError(t, err)
  4828  
  4829  		if o.(*consumerFileStore).state.Delivered != state.Delivered {
  4830  			t.Fatalf("Consumer state is wrong %+v vs %+v", o.(*consumerFileStore).state, state)
  4831  		}
  4832  		if o.(*consumerFileStore).state.AckFloor != state.AckFloor {
  4833  			t.Fatalf("Consumer state is wrong %+v vs %+v", o.(*consumerFileStore).state, state)
  4834  		}
  4835  	})
  4836  }
  4837  
  4838  func TestFileStoreNumPendingLargeNumBlks(t *testing.T) {
  4839  	// No need for all permutations here.
  4840  	storeDir := t.TempDir()
  4841  	fcfg := FileStoreConfig{
  4842  		StoreDir:  storeDir,
  4843  		BlockSize: 128, // Small on purpose to create alot of blks.
  4844  	}
  4845  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"zzz"}, Storage: FileStorage})
  4846  	require_NoError(t, err)
  4847  	defer fs.Stop()
  4848  
  4849  	subj, msg := "zzz", bytes.Repeat([]byte("X"), 100)
  4850  	numMsgs := 10_000
  4851  
  4852  	for i := 0; i < numMsgs; i++ {
  4853  		fs.StoreMsg(subj, nil, msg)
  4854  	}
  4855  
  4856  	start := time.Now()
  4857  	total, _ := fs.NumPending(4000, "zzz", false)
  4858  	require_LessThan(t, time.Since(start), 15*time.Millisecond)
  4859  	require_Equal(t, total, 6001)
  4860  
  4861  	start = time.Now()
  4862  	total, _ = fs.NumPending(6000, "zzz", false)
  4863  	require_LessThan(t, time.Since(start), 25*time.Millisecond)
  4864  	require_Equal(t, total, 4001)
  4865  
  4866  	// Now delete a message in first half and second half.
  4867  	fs.RemoveMsg(1000)
  4868  	fs.RemoveMsg(9000)
  4869  
  4870  	start = time.Now()
  4871  	total, _ = fs.NumPending(4000, "zzz", false)
  4872  	require_LessThan(t, time.Since(start), 50*time.Millisecond)
  4873  	require_Equal(t, total, 6000)
  4874  
  4875  	start = time.Now()
  4876  	total, _ = fs.NumPending(6000, "zzz", false)
  4877  	require_LessThan(t, time.Since(start), 50*time.Millisecond)
  4878  	require_Equal(t, total, 4000)
  4879  }
  4880  
  4881  func TestFileStoreSkipMsgAndNumBlocks(t *testing.T) {
  4882  	// No need for all permutations here.
  4883  	storeDir := t.TempDir()
  4884  	fcfg := FileStoreConfig{
  4885  		StoreDir:  storeDir,
  4886  		BlockSize: 128, // Small on purpose to create alot of blks.
  4887  	}
  4888  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"zzz"}, Storage: FileStorage})
  4889  	require_NoError(t, err)
  4890  	defer fs.Stop()
  4891  
  4892  	subj, msg := "zzz", bytes.Repeat([]byte("X"), 100)
  4893  	numMsgs := 10_000
  4894  
  4895  	fs.StoreMsg(subj, nil, msg)
  4896  	for i := 0; i < numMsgs; i++ {
  4897  		fs.SkipMsg()
  4898  	}
  4899  	fs.StoreMsg(subj, nil, msg)
  4900  	require_True(t, fs.numMsgBlocks() == 2)
  4901  }
  4902  
  4903  func TestFileStoreRestoreEncryptedWithNoKeyFuncFails(t *testing.T) {
  4904  	// No need for all permutations here.
  4905  	fcfg := FileStoreConfig{StoreDir: t.TempDir(), Cipher: AES}
  4906  	cfg := StreamConfig{Name: "zzz", Subjects: []string{"zzz"}, Storage: FileStorage}
  4907  	fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4908  	require_NoError(t, err)
  4909  	defer fs.Stop()
  4910  
  4911  	subj, msg := "zzz", bytes.Repeat([]byte("X"), 100)
  4912  	numMsgs := 100
  4913  	for i := 0; i < numMsgs; i++ {
  4914  		fs.StoreMsg(subj, nil, msg)
  4915  	}
  4916  
  4917  	fs.Stop()
  4918  
  4919  	// Make sure if we try to restore with no prf (key) that it fails.
  4920  	_, err = newFileStoreWithCreated(fcfg, cfg, time.Now(), nil, nil)
  4921  	require_Error(t, err, errNoMainKey)
  4922  }
  4923  
  4924  func TestFileStoreInitialFirstSeq(t *testing.T) {
  4925  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  4926  		cfg := StreamConfig{Name: "zzz", Storage: FileStorage, FirstSeq: 1000}
  4927  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  4928  		require_NoError(t, err)
  4929  		defer fs.Stop()
  4930  
  4931  		seq, _, err := fs.StoreMsg("A", nil, []byte("OK"))
  4932  		require_NoError(t, err)
  4933  		if seq != 1000 {
  4934  			t.Fatalf("Message should have been sequence 1000 but was %d", seq)
  4935  		}
  4936  
  4937  		seq, _, err = fs.StoreMsg("B", nil, []byte("OK"))
  4938  		require_NoError(t, err)
  4939  		if seq != 1001 {
  4940  			t.Fatalf("Message should have been sequence 1001 but was %d", seq)
  4941  		}
  4942  
  4943  		var state StreamState
  4944  		fs.FastState(&state)
  4945  		switch {
  4946  		case state.Msgs != 2:
  4947  			t.Fatalf("Expected 2 messages, got %d", state.Msgs)
  4948  		case state.FirstSeq != 1000:
  4949  			t.Fatalf("Expected first seq 1000, got %d", state.FirstSeq)
  4950  		case state.LastSeq != 1001:
  4951  			t.Fatalf("Expected last seq 1001, got %d", state.LastSeq)
  4952  		}
  4953  	})
  4954  }
  4955  
  4956  func TestFileStoreRecaluclateFirstForSubjBug(t *testing.T) {
  4957  	fs, err := newFileStore(FileStoreConfig{StoreDir: t.TempDir()}, StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  4958  	require_NoError(t, err)
  4959  	defer fs.Stop()
  4960  
  4961  	fs.StoreMsg("foo", nil, nil) // 1
  4962  	fs.StoreMsg("bar", nil, nil) // 2
  4963  	fs.StoreMsg("foo", nil, nil) // 3
  4964  
  4965  	// Now remove first 2..
  4966  	fs.RemoveMsg(1)
  4967  	fs.RemoveMsg(2)
  4968  
  4969  	// Now grab first (and only) block.
  4970  	fs.mu.RLock()
  4971  	mb := fs.blks[0]
  4972  	fs.mu.RUnlock()
  4973  
  4974  	// Since we lazy update the first, simulate that we have not updated it as of yet.
  4975  	ss := &SimpleState{Msgs: 1, First: 1, Last: 3, firstNeedsUpdate: true}
  4976  
  4977  	mb.mu.Lock()
  4978  	defer mb.mu.Unlock()
  4979  
  4980  	// Flush the cache.
  4981  	mb.clearCacheAndOffset()
  4982  	// Now call with start sequence of 1, the old one
  4983  	// This will panic without the fix.
  4984  	mb.recalculateFirstForSubj("foo", 1, ss)
  4985  	// Make sure it was update properly.
  4986  	require_True(t, *ss == SimpleState{Msgs: 1, First: 3, Last: 3, firstNeedsUpdate: false})
  4987  }
  4988  
  4989  func TestFileStoreKeepWithDeletedMsgsBug(t *testing.T) {
  4990  	fs, err := newFileStore(FileStoreConfig{StoreDir: t.TempDir()}, StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  4991  	require_NoError(t, err)
  4992  	defer fs.Stop()
  4993  
  4994  	msg := bytes.Repeat([]byte("A"), 19)
  4995  	for i := 0; i < 5; i++ {
  4996  		fs.StoreMsg("A", nil, msg)
  4997  		fs.StoreMsg("B", nil, msg)
  4998  	}
  4999  
  5000  	n, err := fs.PurgeEx("A", 0, 0)
  5001  	require_NoError(t, err)
  5002  	require_True(t, n == 5)
  5003  
  5004  	// Purge with keep.
  5005  	n, err = fs.PurgeEx(_EMPTY_, 0, 2)
  5006  	require_NoError(t, err)
  5007  	require_True(t, n == 3)
  5008  }
  5009  
  5010  func TestFileStoreRestartWithExpireAndLockingBug(t *testing.T) {
  5011  	sd := t.TempDir()
  5012  	scfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  5013  	fs, err := newFileStore(FileStoreConfig{StoreDir: sd}, scfg)
  5014  	require_NoError(t, err)
  5015  	defer fs.Stop()
  5016  
  5017  	// 20 total
  5018  	msg := []byte("HELLO WORLD")
  5019  	for i := 0; i < 10; i++ {
  5020  		fs.StoreMsg("A", nil, msg)
  5021  		fs.StoreMsg("B", nil, msg)
  5022  	}
  5023  	fs.Stop()
  5024  
  5025  	// Now change config underneath of so we will do expires at startup.
  5026  	scfg.MaxMsgs = 15
  5027  	scfg.MaxMsgsPer = 2
  5028  	newCfg := FileStreamInfo{Created: fs.cfg.Created, StreamConfig: scfg}
  5029  
  5030  	// Replace
  5031  	fs.cfg = newCfg
  5032  	require_NoError(t, fs.writeStreamMeta())
  5033  
  5034  	fs, err = newFileStore(FileStoreConfig{StoreDir: sd}, scfg)
  5035  	require_NoError(t, err)
  5036  	defer fs.Stop()
  5037  }
  5038  
  5039  // Test that loads from lmb under lots of writes do not return errPartialCache.
  5040  func TestFileStoreErrPartialLoad(t *testing.T) {
  5041  	fs, err := newFileStore(FileStoreConfig{StoreDir: t.TempDir()}, StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  5042  	require_NoError(t, err)
  5043  	defer fs.Stop()
  5044  
  5045  	put := func(num int) {
  5046  		for i := 0; i < num; i++ {
  5047  			fs.StoreMsg("Z", nil, []byte("ZZZZZZZZZZZZZ"))
  5048  		}
  5049  	}
  5050  
  5051  	put(100)
  5052  
  5053  	// Dump cache of lmb.
  5054  	clearCache := func() {
  5055  		fs.mu.RLock()
  5056  		lmb := fs.lmb
  5057  		fs.mu.RUnlock()
  5058  		lmb.mu.Lock()
  5059  		lmb.clearCache()
  5060  		lmb.mu.Unlock()
  5061  	}
  5062  	clearCache()
  5063  
  5064  	qch := make(chan struct{})
  5065  	defer close(qch)
  5066  
  5067  	for i := 0; i < 10; i++ {
  5068  		go func() {
  5069  			for {
  5070  				select {
  5071  				case <-qch:
  5072  					return
  5073  				default:
  5074  					put(5)
  5075  				}
  5076  			}
  5077  		}()
  5078  	}
  5079  
  5080  	time.Sleep(100 * time.Millisecond)
  5081  
  5082  	var smv StoreMsg
  5083  	for i := 0; i < 10_000; i++ {
  5084  		fs.mu.RLock()
  5085  		lmb := fs.lmb
  5086  		fs.mu.RUnlock()
  5087  		lmb.mu.Lock()
  5088  		first, last := fs.lmb.first.seq, fs.lmb.last.seq
  5089  		if i%100 == 0 {
  5090  			lmb.clearCache()
  5091  		}
  5092  		lmb.mu.Unlock()
  5093  
  5094  		if spread := int(last - first); spread > 0 {
  5095  			seq := first + uint64(rand.Intn(spread))
  5096  			_, err = fs.LoadMsg(seq, &smv)
  5097  			require_NoError(t, err)
  5098  		}
  5099  	}
  5100  }
  5101  
  5102  func TestFileStoreErrPartialLoadOnSyncClose(t *testing.T) {
  5103  	fs, err := newFileStore(
  5104  		FileStoreConfig{StoreDir: t.TempDir(), BlockSize: 500},
  5105  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage},
  5106  	)
  5107  	require_NoError(t, err)
  5108  	defer fs.Stop()
  5109  
  5110  	// This yields an internal record length of 50 bytes. So 10 msgs per blk.
  5111  	msgLen := 19
  5112  	msg := bytes.Repeat([]byte("A"), msgLen)
  5113  
  5114  	// Load up half the block.
  5115  	for _, subj := range []string{"A", "B", "C", "D", "E"} {
  5116  		fs.StoreMsg(subj, nil, msg)
  5117  	}
  5118  
  5119  	// Now simulate the sync timer closing the last block.
  5120  	fs.mu.RLock()
  5121  	lmb := fs.lmb
  5122  	fs.mu.RUnlock()
  5123  	require_True(t, lmb != nil)
  5124  
  5125  	lmb.mu.Lock()
  5126  	lmb.expireCacheLocked()
  5127  	lmb.dirtyCloseWithRemove(false)
  5128  	lmb.mu.Unlock()
  5129  
  5130  	fs.StoreMsg("Z", nil, msg)
  5131  	_, err = fs.LoadMsg(1, nil)
  5132  	require_NoError(t, err)
  5133  }
  5134  
  5135  func TestFileStoreSyncIntervals(t *testing.T) {
  5136  	fcfg := FileStoreConfig{StoreDir: t.TempDir(), SyncInterval: 250 * time.Millisecond}
  5137  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  5138  	require_NoError(t, err)
  5139  	defer fs.Stop()
  5140  
  5141  	checkSyncFlag := func(expected bool) {
  5142  		fs.mu.RLock()
  5143  		lmb := fs.lmb
  5144  		fs.mu.RUnlock()
  5145  		lmb.mu.RLock()
  5146  		syncNeeded := lmb.needSync
  5147  		lmb.mu.RUnlock()
  5148  		if syncNeeded != expected {
  5149  			t.Fatalf("Expected needSync to be %v", expected)
  5150  		}
  5151  	}
  5152  
  5153  	checkSyncFlag(false)
  5154  	fs.StoreMsg("Z", nil, []byte("hello"))
  5155  	checkSyncFlag(true)
  5156  	time.Sleep(400 * time.Millisecond)
  5157  	checkSyncFlag(false)
  5158  	fs.Stop()
  5159  
  5160  	// Now check always
  5161  	fcfg.SyncInterval = 10 * time.Second
  5162  	fcfg.SyncAlways = true
  5163  	fs, err = newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  5164  	require_NoError(t, err)
  5165  	defer fs.Stop()
  5166  
  5167  	checkSyncFlag(false)
  5168  	fs.StoreMsg("Z", nil, []byte("hello"))
  5169  	checkSyncFlag(false)
  5170  }
  5171  
  5172  // https://github.com/nats-io/nats-server/issues/4529
  5173  // Run this wuth --race and you will see the unlocked access that probably caused this.
  5174  func TestFileStoreRecalcFirstSequenceBug(t *testing.T) {
  5175  	fcfg := FileStoreConfig{StoreDir: t.TempDir()}
  5176  	fs, err := newFileStore(fcfg, StreamConfig{Name: "zzz", Subjects: []string{"*"}, MaxMsgsPer: 2, Storage: FileStorage})
  5177  	require_NoError(t, err)
  5178  	defer fs.Stop()
  5179  
  5180  	msg := bytes.Repeat([]byte("A"), 22)
  5181  
  5182  	for _, subj := range []string{"A", "A", "B", "B"} {
  5183  		fs.StoreMsg(subj, nil, msg)
  5184  	}
  5185  	// Make sure the buffer is cleared.
  5186  	clearLMBCache := func() {
  5187  		fs.mu.RLock()
  5188  		mb := fs.lmb
  5189  		fs.mu.RUnlock()
  5190  		mb.mu.Lock()
  5191  		mb.clearCacheAndOffset()
  5192  		mb.mu.Unlock()
  5193  	}
  5194  
  5195  	clearLMBCache()
  5196  
  5197  	// Do first here.
  5198  	fs.StoreMsg("A", nil, msg)
  5199  
  5200  	var wg sync.WaitGroup
  5201  	start := make(chan bool)
  5202  
  5203  	wg.Add(1)
  5204  	go func() {
  5205  		defer wg.Done()
  5206  		<-start
  5207  		for i := 0; i < 1_000; i++ {
  5208  			fs.LoadLastMsg("A", nil)
  5209  			clearLMBCache()
  5210  		}
  5211  	}()
  5212  
  5213  	wg.Add(1)
  5214  	go func() {
  5215  		defer wg.Done()
  5216  		<-start
  5217  		for i := 0; i < 1_000; i++ {
  5218  			fs.StoreMsg("A", nil, msg)
  5219  		}
  5220  	}()
  5221  
  5222  	close(start)
  5223  	wg.Wait()
  5224  }
  5225  
  5226  ///////////////////////////////////////////////////////////////////////////
  5227  // New WAL based architecture tests
  5228  ///////////////////////////////////////////////////////////////////////////
  5229  
  5230  func TestFileStoreFullStateBasics(t *testing.T) {
  5231  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5232  		fcfg.BlockSize = 100
  5233  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  5234  		created := time.Now()
  5235  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5236  		require_NoError(t, err)
  5237  		defer fs.Stop()
  5238  
  5239  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5240  		subj, msgLen, recLen := "A", 19, uint64(50)
  5241  		msgA := bytes.Repeat([]byte("A"), msgLen)
  5242  		msgZ := bytes.Repeat([]byte("Z"), msgLen)
  5243  
  5244  		// Send 2 msgs and stop, check for presence of our full state file.
  5245  		fs.StoreMsg(subj, nil, msgA)
  5246  		fs.StoreMsg(subj, nil, msgZ)
  5247  		require_True(t, fs.numMsgBlocks() == 1)
  5248  
  5249  		// Make sure there is a full state file after we do a stop.
  5250  		fs.Stop()
  5251  
  5252  		sfile := filepath.Join(fcfg.StoreDir, msgDir, streamStreamStateFile)
  5253  		if _, err := os.Stat(sfile); err != nil {
  5254  			t.Fatalf("Expected stream state file but got %v", err)
  5255  		}
  5256  
  5257  		// Read it in and make sure len > 0.
  5258  		buf, err := os.ReadFile(sfile)
  5259  		require_NoError(t, err)
  5260  		require_True(t, len(buf) > 0)
  5261  
  5262  		// Now make sure we recover properly.
  5263  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5264  		require_NoError(t, err)
  5265  		defer fs.Stop()
  5266  
  5267  		// Make sure there are no old idx or fss files.
  5268  		matches, err := filepath.Glob(filepath.Join(fcfg.StoreDir, msgDir, "%d.fss"))
  5269  		require_NoError(t, err)
  5270  		require_True(t, len(matches) == 0)
  5271  		matches, err = filepath.Glob(filepath.Join(fcfg.StoreDir, msgDir, "%d.idx"))
  5272  		require_NoError(t, err)
  5273  		require_True(t, len(matches) == 0)
  5274  
  5275  		state := fs.State()
  5276  		require_Equal(t, state.Msgs, 2)
  5277  		require_Equal(t, state.FirstSeq, 1)
  5278  		require_Equal(t, state.LastSeq, 2)
  5279  
  5280  		// Now make sure we can read in values.
  5281  		var smv StoreMsg
  5282  		sm, err := fs.LoadMsg(1, &smv)
  5283  		require_NoError(t, err)
  5284  		require_True(t, bytes.Equal(sm.msg, msgA))
  5285  
  5286  		sm, err = fs.LoadMsg(2, &smv)
  5287  		require_NoError(t, err)
  5288  		require_True(t, bytes.Equal(sm.msg, msgZ))
  5289  
  5290  		// Now add in 1 more here to split the lmb.
  5291  		fs.StoreMsg(subj, nil, msgZ)
  5292  
  5293  		// Now stop the filestore and replace the old stream state and make sure we recover correctly.
  5294  		fs.Stop()
  5295  
  5296  		// Regrab the stream state
  5297  		buf, err = os.ReadFile(sfile)
  5298  		require_NoError(t, err)
  5299  
  5300  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5301  		require_NoError(t, err)
  5302  		defer fs.Stop()
  5303  
  5304  		// Add in one more.
  5305  		fs.StoreMsg(subj, nil, msgZ)
  5306  		fs.Stop()
  5307  
  5308  		// Put old stream state back with only 3.
  5309  		err = os.WriteFile(sfile, buf, defaultFilePerms)
  5310  		require_NoError(t, err)
  5311  
  5312  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5313  		require_NoError(t, err)
  5314  		defer fs.Stop()
  5315  
  5316  		state = fs.State()
  5317  		require_Equal(t, state.Msgs, 4)
  5318  		require_Equal(t, state.Bytes, 4*recLen)
  5319  		require_Equal(t, state.FirstSeq, 1)
  5320  		require_Equal(t, state.LastSeq, 4)
  5321  		require_Equal(t, fs.numMsgBlocks(), 2)
  5322  
  5323  		// Make sure we are tracking subjects correctly.
  5324  		fs.mu.RLock()
  5325  		info, _ := fs.psim.Find(stringToBytes(subj))
  5326  		psi := *info
  5327  		fs.mu.RUnlock()
  5328  
  5329  		require_Equal(t, psi.total, 4)
  5330  		require_Equal(t, psi.fblk, 1)
  5331  		require_Equal(t, psi.lblk, 2)
  5332  
  5333  		// Store 1 more
  5334  		fs.StoreMsg(subj, nil, msgA)
  5335  		fs.Stop()
  5336  		// Put old stream state back with only 3.
  5337  		err = os.WriteFile(sfile, buf, defaultFilePerms)
  5338  		require_NoError(t, err)
  5339  
  5340  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5341  		require_NoError(t, err)
  5342  		defer fs.Stop()
  5343  
  5344  		state = fs.State()
  5345  		require_Equal(t, state.Msgs, 5)
  5346  		require_Equal(t, state.FirstSeq, 1)
  5347  		require_Equal(t, state.LastSeq, 5)
  5348  		require_Equal(t, fs.numMsgBlocks(), 3)
  5349  		// Make sure we are tracking subjects correctly.
  5350  		fs.mu.RLock()
  5351  		info, _ = fs.psim.Find(stringToBytes(subj))
  5352  		psi = *info
  5353  		fs.mu.RUnlock()
  5354  		require_Equal(t, psi.total, 5)
  5355  		require_Equal(t, psi.fblk, 1)
  5356  		require_Equal(t, psi.lblk, 3)
  5357  	})
  5358  }
  5359  
  5360  func TestFileStoreFullStatePurge(t *testing.T) {
  5361  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5362  		fcfg.BlockSize = 132 // Leave room for tombstones.
  5363  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  5364  		created := time.Now()
  5365  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5366  		require_NoError(t, err)
  5367  		defer fs.Stop()
  5368  
  5369  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5370  		subj, msg := "A", bytes.Repeat([]byte("A"), 19)
  5371  
  5372  		// Should be 2 per block, so 5 blocks.
  5373  		for i := 0; i < 10; i++ {
  5374  			fs.StoreMsg(subj, nil, msg)
  5375  		}
  5376  		n, err := fs.Purge()
  5377  		require_NoError(t, err)
  5378  		require_Equal(t, n, 10)
  5379  		state := fs.State()
  5380  		fs.Stop()
  5381  
  5382  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5383  		require_NoError(t, err)
  5384  		defer fs.Stop()
  5385  
  5386  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5387  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5388  				state, newState)
  5389  		}
  5390  
  5391  		// Add in more 10 more total, some B some C.
  5392  		for i := 0; i < 5; i++ {
  5393  			fs.StoreMsg("B", nil, msg)
  5394  			fs.StoreMsg("C", nil, msg)
  5395  		}
  5396  
  5397  		n, err = fs.PurgeEx("B", 0, 0)
  5398  		require_NoError(t, err)
  5399  		require_Equal(t, n, 5)
  5400  
  5401  		state = fs.State()
  5402  		fs.Stop()
  5403  
  5404  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5405  		require_NoError(t, err)
  5406  		defer fs.Stop()
  5407  
  5408  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5409  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5410  				state, newState)
  5411  		}
  5412  
  5413  		// Purge with keep.
  5414  		n, err = fs.PurgeEx(_EMPTY_, 0, 2)
  5415  		require_NoError(t, err)
  5416  		require_Equal(t, n, 3)
  5417  
  5418  		state = fs.State()
  5419  
  5420  		// Do some quick checks here, keep had a bug.
  5421  		require_Equal(t, state.Msgs, 2)
  5422  		require_Equal(t, state.FirstSeq, 18)
  5423  		require_Equal(t, state.LastSeq, 20)
  5424  
  5425  		fs.Stop()
  5426  
  5427  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5428  		require_NoError(t, err)
  5429  		defer fs.Stop()
  5430  
  5431  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5432  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5433  				state, newState)
  5434  		}
  5435  
  5436  		// Make sure we can survive a purge with no full stream state and have the correct first sequence.
  5437  		// This used to be provided by the idx file and is now tombstones and the full stream state snapshot.
  5438  		n, err = fs.Purge()
  5439  		require_NoError(t, err)
  5440  		require_Equal(t, n, 2)
  5441  		state = fs.State()
  5442  		fs.Stop()
  5443  
  5444  		sfile := filepath.Join(fcfg.StoreDir, msgDir, streamStreamStateFile)
  5445  		os.Remove(sfile)
  5446  
  5447  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5448  		require_NoError(t, err)
  5449  		defer fs.Stop()
  5450  
  5451  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5452  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5453  				state, newState)
  5454  		}
  5455  	})
  5456  }
  5457  
  5458  func TestFileStoreFullStateTestUserRemoveWAL(t *testing.T) {
  5459  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5460  		fcfg.BlockSize = 132 // Leave room for tombstones.
  5461  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  5462  		created := time.Now()
  5463  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5464  		require_NoError(t, err)
  5465  		defer fs.Stop()
  5466  
  5467  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5468  		msgLen := 19
  5469  		msgA := bytes.Repeat([]byte("A"), msgLen)
  5470  		msgZ := bytes.Repeat([]byte("Z"), msgLen)
  5471  
  5472  		// Store 2 msgs and delete first.
  5473  		fs.StoreMsg("A", nil, msgA)
  5474  		fs.StoreMsg("Z", nil, msgZ)
  5475  		fs.RemoveMsg(1)
  5476  
  5477  		// Check we can load things properly since the block will have a tombstone now for seq 1.
  5478  		sm, err := fs.LoadMsg(2, nil)
  5479  		require_NoError(t, err)
  5480  		require_True(t, bytes.Equal(sm.msg, msgZ))
  5481  
  5482  		require_Equal(t, fs.numMsgBlocks(), 1)
  5483  		state := fs.State()
  5484  		fs.Stop()
  5485  
  5486  		// Grab the state from this stop.
  5487  		sfile := filepath.Join(fcfg.StoreDir, msgDir, streamStreamStateFile)
  5488  		buf, err := os.ReadFile(sfile)
  5489  		require_NoError(t, err)
  5490  
  5491  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5492  		require_NoError(t, err)
  5493  		defer fs.Stop()
  5494  
  5495  		// Check we can load things properly since the block will have a tombstone now for seq 1.
  5496  		_, err = fs.LoadMsg(2, nil)
  5497  		require_NoError(t, err)
  5498  		_, err = fs.LoadMsg(1, nil)
  5499  		require_Error(t, err, ErrStoreMsgNotFound)
  5500  
  5501  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5502  			t.Fatalf("Restore state does not match:\n%+v\n%+v",
  5503  				state, newState)
  5504  		}
  5505  		require_True(t, !state.FirstTime.IsZero())
  5506  
  5507  		// Store 2 more msgs and delete 2 & 4.
  5508  		fs.StoreMsg("A", nil, msgA)
  5509  		fs.StoreMsg("Z", nil, msgZ)
  5510  		fs.RemoveMsg(2)
  5511  		fs.RemoveMsg(4)
  5512  
  5513  		state = fs.State()
  5514  		require_Equal(t, len(state.Deleted), state.NumDeleted)
  5515  		fs.Stop()
  5516  
  5517  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5518  		require_NoError(t, err)
  5519  		defer fs.Stop()
  5520  
  5521  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5522  			t.Fatalf("Restore state does not match:\n%+v\n%+v",
  5523  				state, newState)
  5524  		}
  5525  		require_True(t, !state.FirstTime.IsZero())
  5526  
  5527  		// Now close again and put back old stream state.
  5528  		// This will test that we can remember user deletes by placing tombstones in the lmb/wal.
  5529  		fs.Stop()
  5530  		err = os.WriteFile(sfile, buf, defaultFilePerms)
  5531  		require_NoError(t, err)
  5532  
  5533  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5534  		require_NoError(t, err)
  5535  		defer fs.Stop()
  5536  
  5537  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5538  			t.Fatalf("Restore state does not match:\n%+v\n%+v",
  5539  				state, newState)
  5540  		}
  5541  		require_True(t, !state.FirstTime.IsZero())
  5542  	})
  5543  }
  5544  
  5545  func TestFileStoreFullStateTestSysRemovals(t *testing.T) {
  5546  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5547  		fcfg.BlockSize = 100
  5548  		cfg := StreamConfig{
  5549  			Name:       "zzz",
  5550  			Subjects:   []string{"*"},
  5551  			MaxMsgs:    10,
  5552  			MaxMsgsPer: 1,
  5553  			Storage:    FileStorage,
  5554  		}
  5555  		created := time.Now()
  5556  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5557  		require_NoError(t, err)
  5558  		defer fs.Stop()
  5559  
  5560  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5561  		msgLen := 19
  5562  		msg := bytes.Repeat([]byte("A"), msgLen)
  5563  
  5564  		for _, subj := range []string{"A", "B", "A", "B"} {
  5565  			fs.StoreMsg(subj, nil, msg)
  5566  		}
  5567  
  5568  		state := fs.State()
  5569  		require_Equal(t, state.Msgs, 2)
  5570  		require_Equal(t, state.FirstSeq, 3)
  5571  		require_Equal(t, state.LastSeq, 4)
  5572  		fs.Stop()
  5573  
  5574  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5575  		require_NoError(t, err)
  5576  		defer fs.Stop()
  5577  
  5578  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5579  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5580  				state, newState)
  5581  		}
  5582  
  5583  		for _, subj := range []string{"C", "D", "E", "F", "G", "H", "I", "J"} {
  5584  			fs.StoreMsg(subj, nil, msg)
  5585  		}
  5586  
  5587  		state = fs.State()
  5588  		require_Equal(t, state.Msgs, 10)
  5589  		require_Equal(t, state.FirstSeq, 3)
  5590  		require_Equal(t, state.LastSeq, 12)
  5591  		fs.Stop()
  5592  
  5593  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5594  		require_NoError(t, err)
  5595  		defer fs.Stop()
  5596  
  5597  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5598  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5599  				state, newState)
  5600  		}
  5601  
  5602  		// Goes over limit
  5603  		fs.StoreMsg("ZZZ", nil, msg)
  5604  
  5605  		state = fs.State()
  5606  		require_Equal(t, state.Msgs, 10)
  5607  		require_Equal(t, state.FirstSeq, 4)
  5608  		require_Equal(t, state.LastSeq, 13)
  5609  		fs.Stop()
  5610  
  5611  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5612  		require_NoError(t, err)
  5613  		defer fs.Stop()
  5614  
  5615  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5616  			t.Fatalf("Restore state after purge does not match:\n%+v\n%+v",
  5617  				state, newState)
  5618  		}
  5619  	})
  5620  }
  5621  
  5622  func TestFileStoreSelectBlockWithFirstSeqRemovals(t *testing.T) {
  5623  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5624  		fcfg.BlockSize = 100
  5625  		cfg := StreamConfig{
  5626  			Name:       "zzz",
  5627  			Subjects:   []string{"*"},
  5628  			MaxMsgsPer: 1,
  5629  			Storage:    FileStorage,
  5630  		}
  5631  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  5632  		require_NoError(t, err)
  5633  		defer fs.Stop()
  5634  
  5635  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5636  		msgLen := 19
  5637  		msg := bytes.Repeat([]byte("A"), msgLen)
  5638  
  5639  		subjects := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+@$^"
  5640  		// We need over 32 blocks to kick in binary search. So 32*2+1 (65) msgs to get 33 blocks.
  5641  		for i := 0; i < 32*2+1; i++ {
  5642  			subj := string(subjects[i])
  5643  			fs.StoreMsg(subj, nil, msg)
  5644  		}
  5645  		require_Equal(t, fs.numMsgBlocks(), 33)
  5646  
  5647  		// Now we want to delete the first msg of each block to move the first sequence.
  5648  		// Want to do this via system removes, not user initiated moves.
  5649  		for i := 0; i < len(subjects); i += 2 {
  5650  			subj := string(subjects[i])
  5651  			fs.StoreMsg(subj, nil, msg)
  5652  		}
  5653  
  5654  		var ss StreamState
  5655  		fs.FastState(&ss)
  5656  
  5657  		// We want to make sure that select always returns an index and a non-nil mb.
  5658  		for seq := ss.FirstSeq; seq <= ss.LastSeq; seq++ {
  5659  			fs.mu.RLock()
  5660  			index, mb := fs.selectMsgBlockWithIndex(seq)
  5661  			fs.mu.RUnlock()
  5662  			require_True(t, index >= 0)
  5663  			require_True(t, mb != nil)
  5664  			require_Equal(t, (seq-1)/2, uint64(index))
  5665  		}
  5666  	})
  5667  }
  5668  
  5669  func TestFileStoreMsgBlockHolesAndIndexing(t *testing.T) {
  5670  	fs, err := newFileStore(
  5671  		FileStoreConfig{StoreDir: t.TempDir()},
  5672  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxMsgsPer: 1},
  5673  	)
  5674  	require_NoError(t, err)
  5675  	defer fs.Stop()
  5676  
  5677  	// Grab the message block by hand and manipulate at that level.
  5678  	mb := fs.getFirstBlock()
  5679  	writeMsg := func(subj string, seq uint64) {
  5680  		rl := fileStoreMsgSize(subj, nil, []byte(subj))
  5681  		require_NoError(t, mb.writeMsgRecord(rl, seq, subj, nil, []byte(subj), time.Now().UnixNano(), true))
  5682  		fs.rebuildState(nil)
  5683  	}
  5684  	readMsg := func(seq uint64, expectedSubj string) {
  5685  		// Clear cache so we load back in from disk and need to properly process any holes.
  5686  		ld, tombs, err := mb.rebuildState()
  5687  		require_NoError(t, err)
  5688  		require_Equal(t, ld, nil)
  5689  		require_Equal(t, len(tombs), 0)
  5690  		fs.rebuildState(nil)
  5691  		sm, _, err := mb.fetchMsg(seq, nil)
  5692  		require_NoError(t, err)
  5693  		require_Equal(t, sm.subj, expectedSubj)
  5694  		require_True(t, bytes.Equal(sm.buf[:len(expectedSubj)], []byte(expectedSubj)))
  5695  	}
  5696  
  5697  	writeMsg("A", 2)
  5698  	require_Equal(t, mb.first.seq, 2)
  5699  	require_Equal(t, mb.last.seq, 2)
  5700  
  5701  	writeMsg("B", 4)
  5702  	require_Equal(t, mb.first.seq, 2)
  5703  	require_Equal(t, mb.last.seq, 4)
  5704  
  5705  	writeMsg("C", 12)
  5706  
  5707  	readMsg(4, "B")
  5708  	require_True(t, mb.dmap.Exists(3))
  5709  
  5710  	readMsg(12, "C")
  5711  	readMsg(2, "A")
  5712  
  5713  	// Check that we get deleted for the right ones etc.
  5714  	checkDeleted := func(seq uint64) {
  5715  		_, _, err = mb.fetchMsg(seq, nil)
  5716  		require_Error(t, err, ErrStoreMsgNotFound, errDeletedMsg)
  5717  		mb.mu.RLock()
  5718  		shouldExist, exists := seq >= mb.first.seq, mb.dmap.Exists(seq)
  5719  		mb.mu.RUnlock()
  5720  		if shouldExist {
  5721  			require_True(t, exists)
  5722  		}
  5723  	}
  5724  	checkDeleted(1)
  5725  	checkDeleted(3)
  5726  	for seq := 5; seq < 12; seq++ {
  5727  		checkDeleted(uint64(seq))
  5728  	}
  5729  }
  5730  
  5731  func TestFileStoreMsgBlockCompactionAndHoles(t *testing.T) {
  5732  	fs, err := newFileStore(
  5733  		FileStoreConfig{StoreDir: t.TempDir()},
  5734  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxMsgsPer: 1},
  5735  	)
  5736  	require_NoError(t, err)
  5737  	defer fs.Stop()
  5738  
  5739  	msg := bytes.Repeat([]byte("Z"), 1024)
  5740  	for _, subj := range []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"} {
  5741  		fs.StoreMsg(subj, nil, msg)
  5742  	}
  5743  	// Leave first one but delete the rest.
  5744  	for seq := uint64(2); seq < 10; seq++ {
  5745  		fs.RemoveMsg(seq)
  5746  	}
  5747  	require_Equal(t, fs.numMsgBlocks(), 1)
  5748  	mb := fs.getFirstBlock()
  5749  	require_NotNil(t, mb)
  5750  
  5751  	_, ub, _ := fs.Utilization()
  5752  
  5753  	// Do compaction, should remove all excess now.
  5754  	mb.mu.Lock()
  5755  	mb.compact()
  5756  	mb.mu.Unlock()
  5757  
  5758  	ta, ua, _ := fs.Utilization()
  5759  	require_Equal(t, ub, ua)
  5760  	require_Equal(t, ta, ua)
  5761  }
  5762  
  5763  func TestFileStoreRemoveLastNoDoubleTombstones(t *testing.T) {
  5764  	fs, err := newFileStore(
  5765  		FileStoreConfig{StoreDir: t.TempDir()},
  5766  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxMsgsPer: 1},
  5767  	)
  5768  	require_NoError(t, err)
  5769  	defer fs.Stop()
  5770  
  5771  	fs.StoreMsg("A", nil, []byte("hello"))
  5772  	fs.mu.Lock()
  5773  	fs.removeMsgViaLimits(1)
  5774  	fs.mu.Unlock()
  5775  
  5776  	require_Equal(t, fs.numMsgBlocks(), 1)
  5777  	mb := fs.getFirstBlock()
  5778  	require_NotNil(t, mb)
  5779  	mb.loadMsgs()
  5780  	rbytes, _, err := fs.Utilization()
  5781  	require_NoError(t, err)
  5782  	require_Equal(t, rbytes, emptyRecordLen)
  5783  }
  5784  
  5785  func TestFileStoreFullStateMultiBlockPastWAL(t *testing.T) {
  5786  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5787  		fcfg.BlockSize = 100
  5788  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage}
  5789  		created := time.Now()
  5790  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5791  		require_NoError(t, err)
  5792  		defer fs.Stop()
  5793  
  5794  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5795  		msgLen := 19
  5796  		msgA := bytes.Repeat([]byte("A"), msgLen)
  5797  		msgZ := bytes.Repeat([]byte("Z"), msgLen)
  5798  
  5799  		// Store 2 msgs
  5800  		fs.StoreMsg("A", nil, msgA)
  5801  		fs.StoreMsg("B", nil, msgZ)
  5802  		require_Equal(t, fs.numMsgBlocks(), 1)
  5803  		fs.Stop()
  5804  
  5805  		// Grab the state from this stop.
  5806  		sfile := filepath.Join(fcfg.StoreDir, msgDir, streamStreamStateFile)
  5807  		buf, err := os.ReadFile(sfile)
  5808  		require_NoError(t, err)
  5809  
  5810  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5811  		require_NoError(t, err)
  5812  		defer fs.Stop()
  5813  
  5814  		// Store 6 more msgs.
  5815  		fs.StoreMsg("C", nil, msgA)
  5816  		fs.StoreMsg("D", nil, msgZ)
  5817  		fs.StoreMsg("E", nil, msgA)
  5818  		fs.StoreMsg("F", nil, msgZ)
  5819  		fs.StoreMsg("G", nil, msgA)
  5820  		fs.StoreMsg("H", nil, msgZ)
  5821  		require_Equal(t, fs.numMsgBlocks(), 4)
  5822  		state := fs.State()
  5823  		fs.Stop()
  5824  
  5825  		// Put back old stream state.
  5826  		// This will test that we properly walk multiple blocks past where we snapshotted state.
  5827  		err = os.WriteFile(sfile, buf, defaultFilePerms)
  5828  		require_NoError(t, err)
  5829  
  5830  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5831  		require_NoError(t, err)
  5832  		defer fs.Stop()
  5833  
  5834  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5835  			t.Fatalf("Restore state does not match:\n%+v\n%+v",
  5836  				state, newState)
  5837  		}
  5838  		require_True(t, !state.FirstTime.IsZero())
  5839  	})
  5840  }
  5841  
  5842  // This tests we can successfully recover without having to rebuild the whole stream from a mid block index.db marker
  5843  // when they updated block has a removed entry.
  5844  // TODO(dlc) - This test will force a rebuild atm, leaving here for later.
  5845  func TestFileStoreFullStateMidBlockPastWAL(t *testing.T) {
  5846  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5847  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxMsgsPer: 1}
  5848  		created := time.Now()
  5849  		fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5850  		require_NoError(t, err)
  5851  		defer fs.Stop()
  5852  
  5853  		// This yields an internal record length of 50 bytes. So 2 msgs per blk.
  5854  		msg := bytes.Repeat([]byte("Z"), 19)
  5855  
  5856  		// Store 5 msgs
  5857  		fs.StoreMsg("A", nil, msg)
  5858  		fs.StoreMsg("B", nil, msg)
  5859  		fs.StoreMsg("C", nil, msg)
  5860  		fs.StoreMsg("D", nil, msg)
  5861  		fs.StoreMsg("E", nil, msg)
  5862  		require_Equal(t, fs.numMsgBlocks(), 1)
  5863  		fs.Stop()
  5864  
  5865  		// Grab the state from this stop.
  5866  		sfile := filepath.Join(fcfg.StoreDir, msgDir, streamStreamStateFile)
  5867  		buf, err := os.ReadFile(sfile)
  5868  		require_NoError(t, err)
  5869  
  5870  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5871  		require_NoError(t, err)
  5872  		defer fs.Stop()
  5873  
  5874  		// Store 5 more messages, then remove seq 2, "B".
  5875  		fs.StoreMsg("F", nil, msg)
  5876  		fs.StoreMsg("G", nil, msg)
  5877  		fs.StoreMsg("H", nil, msg)
  5878  		fs.StoreMsg("I", nil, msg)
  5879  		fs.StoreMsg("J", nil, msg)
  5880  		fs.RemoveMsg(2)
  5881  
  5882  		require_Equal(t, fs.numMsgBlocks(), 1)
  5883  		state := fs.State()
  5884  		fs.Stop()
  5885  
  5886  		// Put back old stream state.
  5887  		// This will test that we properly walk multiple blocks past where we snapshotted state.
  5888  		err = os.WriteFile(sfile, buf, defaultFilePerms)
  5889  		require_NoError(t, err)
  5890  
  5891  		fs, err = newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil)
  5892  		require_NoError(t, err)
  5893  		defer fs.Stop()
  5894  
  5895  		if newState := fs.State(); !reflect.DeepEqual(state, newState) {
  5896  			t.Fatalf("Restore state does not match:\n%+v\n%+v",
  5897  				state, newState)
  5898  		}
  5899  	})
  5900  }
  5901  
  5902  func TestFileStoreCompactingBlocksOnSync(t *testing.T) {
  5903  	testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) {
  5904  		fcfg.BlockSize = 1000 // 20 msgs per block.
  5905  		fcfg.SyncInterval = 100 * time.Millisecond
  5906  		cfg := StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage, MaxMsgsPer: 1}
  5907  		fs, err := newFileStoreWithCreated(fcfg, cfg, time.Now(), prf(&fcfg), nil)
  5908  		require_NoError(t, err)
  5909  		defer fs.Stop()
  5910  
  5911  		// This yields an internal record length of 50 bytes. So 20 msgs per blk.
  5912  		msg := bytes.Repeat([]byte("Z"), 19)
  5913  		subjects := "ABCDEFGHIJKLMNOPQRST"
  5914  		for _, subj := range subjects {
  5915  			fs.StoreMsg(string(subj), nil, msg)
  5916  		}
  5917  		require_Equal(t, fs.numMsgBlocks(), 1)
  5918  		total, reported, err := fs.Utilization()
  5919  		require_NoError(t, err)
  5920  
  5921  		require_Equal(t, total, reported)
  5922  
  5923  		// Now start removing, since we are small this should not kick in any inline logic.
  5924  		// Remove all interior messages, leave 1 and 20. So write B-S
  5925  		for i := 1; i < 19; i++ {
  5926  			fs.StoreMsg(string(subjects[i]), nil, msg)
  5927  		}
  5928  		require_Equal(t, fs.numMsgBlocks(), 2)
  5929  
  5930  		blkUtil := func() (uint64, uint64) {
  5931  			fs.mu.RLock()
  5932  			fmb := fs.blks[0]
  5933  			fs.mu.RUnlock()
  5934  			fmb.mu.RLock()
  5935  			defer fmb.mu.RUnlock()
  5936  			return fmb.rbytes, fmb.bytes
  5937  		}
  5938  
  5939  		total, reported = blkUtil()
  5940  		require_Equal(t, reported, 100)
  5941  		// Raw bytes will be 1000, but due to compression could be less.
  5942  		if fcfg.Compression != NoCompression {
  5943  			require_True(t, total > reported)
  5944  		} else {
  5945  			require_Equal(t, total, 1000)
  5946  		}
  5947  
  5948  		// Make sure the sync interval when kicked in compacts down to rbytes == 100.
  5949  		checkFor(t, time.Second, 100*time.Millisecond, func() error {
  5950  			if total, reported := blkUtil(); total <= reported {
  5951  				return nil
  5952  			}
  5953  			return fmt.Errorf("Not compacted yet, raw %v vs reported %v",
  5954  				friendlyBytes(total), friendlyBytes(reported))
  5955  		})
  5956  	})
  5957  }
  5958  
  5959  // Make sure a call to Compact() updates PSIM correctly.
  5960  func TestFileStoreCompactAndPSIMWhenDeletingBlocks(t *testing.T) {
  5961  	fs, err := newFileStore(
  5962  		FileStoreConfig{StoreDir: t.TempDir(), BlockSize: 512},
  5963  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  5964  	require_NoError(t, err)
  5965  	defer fs.Stop()
  5966  
  5967  	subj, msg := "A", bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  5968  
  5969  	// Add in 10 As
  5970  	for i := 0; i < 10; i++ {
  5971  		fs.StoreMsg(subj, nil, msg)
  5972  	}
  5973  	require_Equal(t, fs.numMsgBlocks(), 4)
  5974  
  5975  	// Should leave 1.
  5976  	n, err := fs.Compact(10)
  5977  	require_NoError(t, err)
  5978  	require_Equal(t, n, 9)
  5979  	require_Equal(t, fs.numMsgBlocks(), 1)
  5980  
  5981  	fs.mu.RLock()
  5982  	info, _ := fs.psim.Find(stringToBytes(subj))
  5983  	psi := *info
  5984  	fs.mu.RUnlock()
  5985  
  5986  	require_Equal(t, psi.total, 1)
  5987  	require_Equal(t, psi.fblk, psi.lblk)
  5988  }
  5989  
  5990  func TestFileStoreTrackSubjLenForPSIM(t *testing.T) {
  5991  	sd := t.TempDir()
  5992  	fs, err := newFileStore(
  5993  		FileStoreConfig{StoreDir: sd},
  5994  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  5995  	require_NoError(t, err)
  5996  	defer fs.Stop()
  5997  
  5998  	// Place 1000 msgs with varying subjects.
  5999  	// Make sure we track the subject length properly.
  6000  	smap := make(map[string]int, 1000)
  6001  	buf := make([]byte, 10)
  6002  	for i := 0; i < 1000; i++ {
  6003  		var b strings.Builder
  6004  		// 1-6 tokens.
  6005  		numTokens := rand.Intn(6) + 1
  6006  		for i := 0; i < numTokens; i++ {
  6007  			tlen := rand.Intn(4) + 2
  6008  			tok := buf[:tlen]
  6009  			crand.Read(tok)
  6010  			b.WriteString(hex.EncodeToString(tok))
  6011  			if i != numTokens-1 {
  6012  				b.WriteString(".")
  6013  			}
  6014  		}
  6015  		subj := b.String()
  6016  		// Avoid dupes since will cause check to fail after we delete messages.
  6017  		if _, ok := smap[subj]; ok {
  6018  			continue
  6019  		}
  6020  		smap[subj] = len(subj)
  6021  		fs.StoreMsg(subj, nil, nil)
  6022  	}
  6023  
  6024  	check := func() {
  6025  		t.Helper()
  6026  		var total int
  6027  		for _, slen := range smap {
  6028  			total += slen
  6029  		}
  6030  		fs.mu.RLock()
  6031  		tsl := fs.tsl
  6032  		fs.mu.RUnlock()
  6033  		require_Equal(t, tsl, total)
  6034  	}
  6035  
  6036  	check()
  6037  
  6038  	// Delete ~half
  6039  	var smv StoreMsg
  6040  	for i := 0; i < 500; i++ {
  6041  		seq := uint64(rand.Intn(1000) + 1)
  6042  		sm, err := fs.LoadMsg(seq, &smv)
  6043  		if err != nil {
  6044  			continue
  6045  		}
  6046  		fs.RemoveMsg(seq)
  6047  		delete(smap, sm.subj)
  6048  	}
  6049  
  6050  	check()
  6051  
  6052  	// Make sure we can recover same after restart.
  6053  	fs.Stop()
  6054  	fs, err = newFileStore(
  6055  		FileStoreConfig{StoreDir: sd},
  6056  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  6057  	require_NoError(t, err)
  6058  	defer fs.Stop()
  6059  
  6060  	check()
  6061  
  6062  	// Drain the rest through purge.
  6063  	fs.Purge()
  6064  	smap = nil
  6065  	check()
  6066  }
  6067  
  6068  // This was used to make sure our estimate was correct, but not needed normally.
  6069  func TestFileStoreLargeFullStatePSIM(t *testing.T) {
  6070  	t.Skip()
  6071  
  6072  	sd := t.TempDir()
  6073  	fs, err := newFileStore(
  6074  		FileStoreConfig{StoreDir: sd},
  6075  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  6076  	require_NoError(t, err)
  6077  	defer fs.Stop()
  6078  
  6079  	buf := make([]byte, 20)
  6080  	for i := 0; i < 100_000; i++ {
  6081  		var b strings.Builder
  6082  		// 1-6 tokens.
  6083  		numTokens := rand.Intn(6) + 1
  6084  		for i := 0; i < numTokens; i++ {
  6085  			tlen := rand.Intn(8) + 2
  6086  			tok := buf[:tlen]
  6087  			crand.Read(tok)
  6088  			b.WriteString(hex.EncodeToString(tok))
  6089  			if i != numTokens-1 {
  6090  				b.WriteString(".")
  6091  			}
  6092  		}
  6093  		subj := b.String()
  6094  		fs.StoreMsg(subj, nil, nil)
  6095  	}
  6096  	fs.Stop()
  6097  }
  6098  
  6099  func TestFileStoreLargeFullStateMetaCleanup(t *testing.T) {
  6100  	sd := t.TempDir()
  6101  	fs, err := newFileStore(
  6102  		FileStoreConfig{StoreDir: sd},
  6103  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  6104  	require_NoError(t, err)
  6105  	defer fs.Stop()
  6106  
  6107  	subj, msg := "foo.bar.baz", bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  6108  	for i := 0; i < 1000; i++ {
  6109  		fs.StoreMsg(subj, nil, nil)
  6110  	}
  6111  	fs.Stop()
  6112  
  6113  	mdir := filepath.Join(sd, msgDir)
  6114  	idxFile := filepath.Join(mdir, "1.idx")
  6115  	fssFile := filepath.Join(mdir, "1.fss")
  6116  	require_NoError(t, os.WriteFile(idxFile, msg, defaultFilePerms))
  6117  	require_NoError(t, os.WriteFile(fssFile, msg, defaultFilePerms))
  6118  
  6119  	fs, err = newFileStore(
  6120  		FileStoreConfig{StoreDir: sd},
  6121  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  6122  	require_NoError(t, err)
  6123  	defer fs.Stop()
  6124  
  6125  	checkFor(t, time.Second, 50*time.Millisecond, func() error {
  6126  		if _, err := os.Stat(idxFile); err == nil {
  6127  			return errors.New("idx file still exists")
  6128  		}
  6129  		if _, err := os.Stat(fssFile); err == nil {
  6130  			return errors.New("fss file still exists")
  6131  		}
  6132  		return nil
  6133  	})
  6134  }
  6135  
  6136  func TestFileStoreIndexDBExistsAfterShutdown(t *testing.T) {
  6137  	sd := t.TempDir()
  6138  	fs, err := newFileStore(
  6139  		FileStoreConfig{StoreDir: sd},
  6140  		StreamConfig{Name: "zzz", Subjects: []string{">"}, Storage: FileStorage})
  6141  	require_NoError(t, err)
  6142  	defer fs.Stop()
  6143  
  6144  	subj := "foo.bar.baz"
  6145  	for i := 0; i < 1000; i++ {
  6146  		fs.StoreMsg(subj, nil, nil)
  6147  	}
  6148  
  6149  	idxFile := filepath.Join(sd, msgDir, streamStreamStateFile)
  6150  
  6151  	fs.mu.Lock()
  6152  	fs.dirty = 1
  6153  	if err := os.Remove(idxFile); err != nil && !errors.Is(err, os.ErrNotExist) {
  6154  		t.Fatal(err)
  6155  	}
  6156  	fs.mu.Unlock()
  6157  
  6158  	fs.Stop()
  6159  
  6160  	checkFor(t, time.Second, 50*time.Millisecond, func() error {
  6161  		if _, err := os.Stat(idxFile); err != nil {
  6162  			return fmt.Errorf("%q doesn't exist", idxFile)
  6163  		}
  6164  		return nil
  6165  	})
  6166  }
  6167  
  6168  // https://github.com/nats-io/nats-server/issues/4842
  6169  func TestFileStoreSubjectCorruption(t *testing.T) {
  6170  	sd, blkSize := t.TempDir(), uint64(2*1024*1024)
  6171  	fs, err := newFileStore(
  6172  		FileStoreConfig{StoreDir: sd, BlockSize: blkSize},
  6173  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6174  	require_NoError(t, err)
  6175  	defer fs.Stop()
  6176  
  6177  	numSubjects := 100
  6178  	msgs := [][]byte{bytes.Repeat([]byte("ABC"), 333), bytes.Repeat([]byte("ABC"), 888), bytes.Repeat([]byte("ABC"), 555)}
  6179  	for i := 0; i < 10_000; i++ {
  6180  		subj := fmt.Sprintf("foo.%d", rand.Intn(numSubjects)+1)
  6181  		msg := msgs[rand.Intn(len(msgs))]
  6182  		fs.StoreMsg(subj, nil, msg)
  6183  	}
  6184  	fs.Stop()
  6185  
  6186  	require_NoError(t, os.Remove(filepath.Join(sd, msgDir, streamStreamStateFile)))
  6187  
  6188  	fs, err = newFileStore(
  6189  		FileStoreConfig{StoreDir: sd, BlockSize: blkSize},
  6190  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6191  	require_NoError(t, err)
  6192  	defer fs.Stop()
  6193  
  6194  	for subj := range fs.SubjectsTotals(">") {
  6195  		var n int
  6196  		_, err := fmt.Sscanf(subj, "foo.%d", &n)
  6197  		require_NoError(t, err)
  6198  	}
  6199  }
  6200  
  6201  // Since 2.10 we no longer have fss, and the approach for calculating NumPending would branch
  6202  // based on the old fss metadata being present. This meant that calculating NumPending in >= 2.10.x
  6203  // would load all blocks to complete. This test makes sure we do not do that anymore.
  6204  func TestFileStoreNumPendingLastBySubject(t *testing.T) {
  6205  	sd, blkSize := t.TempDir(), uint64(1024)
  6206  	fs, err := newFileStore(
  6207  		FileStoreConfig{StoreDir: sd, BlockSize: blkSize},
  6208  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*.*"}, Storage: FileStorage})
  6209  	require_NoError(t, err)
  6210  	defer fs.Stop()
  6211  
  6212  	numSubjects := 20
  6213  	msg := bytes.Repeat([]byte("ABC"), 25)
  6214  	for i := 1; i <= 1000; i++ {
  6215  		subj := fmt.Sprintf("foo.%d.%d", rand.Intn(numSubjects)+1, i)
  6216  		fs.StoreMsg(subj, nil, msg)
  6217  	}
  6218  	// Each block has ~8 msgs.
  6219  	require_True(t, fs.numMsgBlocks() > 100)
  6220  
  6221  	calcCacheLoads := func() (cloads uint64) {
  6222  		fs.mu.RLock()
  6223  		defer fs.mu.RUnlock()
  6224  		for _, mb := range fs.blks {
  6225  			mb.mu.RLock()
  6226  			cloads += mb.cloads
  6227  			mb.mu.RUnlock()
  6228  		}
  6229  		return cloads
  6230  	}
  6231  
  6232  	total, _ := fs.NumPending(0, "foo.*.*", true)
  6233  	require_Equal(t, total, 1000)
  6234  	// Make sure no blocks were loaded to calculate this as a new consumer.
  6235  	require_Equal(t, calcCacheLoads(), 0)
  6236  
  6237  	checkResult := func(sseq, np uint64, filter string) {
  6238  		t.Helper()
  6239  		var checkTotal uint64
  6240  		var smv StoreMsg
  6241  		for seq := sseq; seq <= 1000; seq++ {
  6242  			sm, err := fs.LoadMsg(seq, &smv)
  6243  			require_NoError(t, err)
  6244  			if subjectIsSubsetMatch(sm.subj, filter) {
  6245  				checkTotal++
  6246  			}
  6247  		}
  6248  		require_Equal(t, np, checkTotal)
  6249  	}
  6250  
  6251  	// Make sure partials work properly.
  6252  	for _, filter := range []string{"foo.10.*", "*.22.*", "*.*.222", "foo.5.999", "*.2.*"} {
  6253  		sseq := uint64(rand.Intn(250) + 200) // Between 200-450
  6254  		total, _ = fs.NumPending(sseq, filter, true)
  6255  		checkResult(sseq, total, filter)
  6256  	}
  6257  }
  6258  
  6259  // We had a bug that could cause internal memory corruption of the psim keys in memory
  6260  // which could have been written to disk via index.db.
  6261  func TestFileStoreCorruptPSIMOnDisk(t *testing.T) {
  6262  	sd := t.TempDir()
  6263  	fs, err := newFileStore(
  6264  		FileStoreConfig{StoreDir: sd},
  6265  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6266  	require_NoError(t, err)
  6267  	defer fs.Stop()
  6268  
  6269  	fs.StoreMsg("foo.bar", nil, []byte("ABC"))
  6270  	fs.StoreMsg("foo.baz", nil, []byte("XYZ"))
  6271  
  6272  	// Force bad subject.
  6273  	fs.mu.Lock()
  6274  	psi, _ := fs.psim.Find(stringToBytes("foo.bar"))
  6275  	bad := make([]byte, 7)
  6276  	crand.Read(bad)
  6277  	fs.psim.Insert(bad, *psi)
  6278  	fs.psim.Delete(stringToBytes("foo.bar"))
  6279  	fs.dirty++
  6280  	fs.mu.Unlock()
  6281  
  6282  	// Restart
  6283  	fs.Stop()
  6284  	fs, err = newFileStore(
  6285  		FileStoreConfig{StoreDir: sd},
  6286  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6287  	require_NoError(t, err)
  6288  	defer fs.Stop()
  6289  
  6290  	sm, err := fs.LoadLastMsg("foo.bar", nil)
  6291  	require_NoError(t, err)
  6292  	require_True(t, bytes.Equal(sm.msg, []byte("ABC")))
  6293  
  6294  	sm, err = fs.LoadLastMsg("foo.baz", nil)
  6295  	require_NoError(t, err)
  6296  	require_True(t, bytes.Equal(sm.msg, []byte("XYZ")))
  6297  }
  6298  
  6299  func TestFileStorePurgeExBufPool(t *testing.T) {
  6300  	sd := t.TempDir()
  6301  	fs, err := newFileStore(
  6302  		FileStoreConfig{StoreDir: sd, BlockSize: 1024},
  6303  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6304  	require_NoError(t, err)
  6305  	defer fs.Stop()
  6306  
  6307  	msg := bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  6308  	for i := 0; i < 1000; i++ {
  6309  		fs.StoreMsg("foo.foo", nil, msg)
  6310  		fs.StoreMsg("foo.bar", nil, msg)
  6311  	}
  6312  
  6313  	p, err := fs.PurgeEx("foo.bar", 1, 0)
  6314  	require_NoError(t, err)
  6315  	require_Equal(t, p, 1000)
  6316  
  6317  	// Now make sure we do not have all of the msg blocks cache's loaded.
  6318  	var loaded int
  6319  	fs.mu.RLock()
  6320  	for _, mb := range fs.blks {
  6321  		mb.mu.RLock()
  6322  		if mb.cacheAlreadyLoaded() {
  6323  			loaded++
  6324  		}
  6325  		mb.mu.RUnlock()
  6326  	}
  6327  	fs.mu.RUnlock()
  6328  	require_Equal(t, loaded, 1)
  6329  }
  6330  
  6331  func TestFileStoreFSSMeta(t *testing.T) {
  6332  	sd := t.TempDir()
  6333  	fs, err := newFileStore(
  6334  		FileStoreConfig{StoreDir: sd, BlockSize: 100, CacheExpire: 200 * time.Millisecond, SyncInterval: time.Second},
  6335  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  6336  	require_NoError(t, err)
  6337  	defer fs.Stop()
  6338  
  6339  	// This yields an internal record length of 50 bytes. So 2 msgs per blk with subject len of 1, e.g. "A" or "Z".
  6340  	msg := bytes.Repeat([]byte("Z"), 19)
  6341  
  6342  	// Should leave us with |A-Z| |Z-Z| |Z-Z| |Z-A|
  6343  	fs.StoreMsg("A", nil, msg)
  6344  	for i := 0; i < 6; i++ {
  6345  		fs.StoreMsg("Z", nil, msg)
  6346  	}
  6347  	fs.StoreMsg("A", nil, msg)
  6348  
  6349  	// Let cache's expire before PurgeEx which will load them back in.
  6350  	time.Sleep(250 * time.Millisecond)
  6351  
  6352  	p, err := fs.PurgeEx("A", 1, 0)
  6353  	require_NoError(t, err)
  6354  	require_Equal(t, p, 2)
  6355  
  6356  	// Make sure cache is not loaded but fss state still is.
  6357  	var stillHasCache, noFSS bool
  6358  	fs.mu.RLock()
  6359  	for _, mb := range fs.blks {
  6360  		mb.mu.RLock()
  6361  		stillHasCache = stillHasCache || mb.cacheAlreadyLoaded()
  6362  		noFSS = noFSS || mb.fssNotLoaded()
  6363  		mb.mu.RUnlock()
  6364  	}
  6365  	fs.mu.RUnlock()
  6366  
  6367  	require_False(t, stillHasCache)
  6368  	require_False(t, noFSS)
  6369  
  6370  	// Let fss expire via syncInterval.
  6371  	time.Sleep(time.Second)
  6372  
  6373  	fs.mu.RLock()
  6374  	for _, mb := range fs.blks {
  6375  		mb.mu.RLock()
  6376  		noFSS = noFSS || mb.fssNotLoaded()
  6377  		mb.mu.RUnlock()
  6378  	}
  6379  	fs.mu.RUnlock()
  6380  
  6381  	require_True(t, noFSS)
  6382  }
  6383  
  6384  func TestFileStoreExpireCacheOnLinearWalk(t *testing.T) {
  6385  	sd := t.TempDir()
  6386  	expire := 250 * time.Millisecond
  6387  	fs, err := newFileStore(
  6388  		FileStoreConfig{StoreDir: sd, CacheExpire: expire},
  6389  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  6390  	require_NoError(t, err)
  6391  	defer fs.Stop()
  6392  
  6393  	// This yields an internal record length of 50 bytes.
  6394  	subj, msg := "Z", bytes.Repeat([]byte("Z"), 19)
  6395  
  6396  	// Store 10 messages, so 5 blocks.
  6397  	for i := 0; i < 10; i++ {
  6398  		fs.StoreMsg(subj, nil, msg)
  6399  	}
  6400  	// Let them all expire. This way we load as we walk and can test that we expire all blocks without
  6401  	// needing to worry about last write times blocking forced expiration.
  6402  	time.Sleep(expire)
  6403  
  6404  	checkNoCache := func() {
  6405  		t.Helper()
  6406  		fs.mu.RLock()
  6407  		var stillHasCache bool
  6408  		for _, mb := range fs.blks {
  6409  			mb.mu.RLock()
  6410  			stillHasCache = stillHasCache || mb.cacheAlreadyLoaded()
  6411  			mb.mu.RUnlock()
  6412  		}
  6413  		fs.mu.RUnlock()
  6414  		require_False(t, stillHasCache)
  6415  	}
  6416  
  6417  	// Walk forward.
  6418  	var smv StoreMsg
  6419  	for seq := uint64(1); seq <= 10; seq++ {
  6420  		_, err := fs.LoadMsg(seq, &smv)
  6421  		require_NoError(t, err)
  6422  	}
  6423  	checkNoCache()
  6424  
  6425  	// No test walking backwards. We have this scenario when we search for starting points for sourced streams.
  6426  	// Noticed some memory bloat when we have to search many blocks looking for a source that may be closer to the
  6427  	// beginning of the stream (infrequently updated sourced stream).
  6428  	for seq := uint64(10); seq >= 1; seq-- {
  6429  		_, err := fs.LoadMsg(seq, &smv)
  6430  		require_NoError(t, err)
  6431  	}
  6432  	checkNoCache()
  6433  
  6434  	// Now make sure still expires properly on linear scans with deleted msgs.
  6435  	// We want to make sure we track linear updates even if message deleted.
  6436  	_, err = fs.RemoveMsg(2)
  6437  	require_NoError(t, err)
  6438  	_, err = fs.RemoveMsg(9)
  6439  	require_NoError(t, err)
  6440  
  6441  	// Walk forward.
  6442  	for seq := uint64(1); seq <= 10; seq++ {
  6443  		_, err := fs.LoadMsg(seq, &smv)
  6444  		if seq == 2 || seq == 9 {
  6445  			require_Error(t, err, errDeletedMsg)
  6446  		} else {
  6447  			require_NoError(t, err)
  6448  		}
  6449  	}
  6450  	checkNoCache()
  6451  }
  6452  
  6453  func TestFileStoreSkipMsgs(t *testing.T) {
  6454  	fs, err := newFileStore(
  6455  		FileStoreConfig{StoreDir: t.TempDir(), BlockSize: 1024},
  6456  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  6457  	require_NoError(t, err)
  6458  	defer fs.Stop()
  6459  
  6460  	// Test on empty FS first.
  6461  	// Make sure wrong starting sequence fails.
  6462  	err = fs.SkipMsgs(10, 100)
  6463  	require_Error(t, err, ErrSequenceMismatch)
  6464  
  6465  	err = fs.SkipMsgs(1, 100)
  6466  	require_NoError(t, err)
  6467  
  6468  	state := fs.State()
  6469  	require_Equal(t, state.FirstSeq, 101)
  6470  	require_Equal(t, state.LastSeq, 100)
  6471  	require_Equal(t, fs.numMsgBlocks(), 1)
  6472  
  6473  	// Now add alot.
  6474  	err = fs.SkipMsgs(101, 100_000)
  6475  	require_NoError(t, err)
  6476  	state = fs.State()
  6477  	require_Equal(t, state.FirstSeq, 100_101)
  6478  	require_Equal(t, state.LastSeq, 100_100)
  6479  	require_Equal(t, fs.numMsgBlocks(), 1)
  6480  
  6481  	// Now add in a message, and then skip to check dmap.
  6482  	fs, err = newFileStore(
  6483  		FileStoreConfig{StoreDir: t.TempDir(), BlockSize: 1024},
  6484  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  6485  	require_NoError(t, err)
  6486  	defer fs.Stop()
  6487  
  6488  	fs.StoreMsg("foo", nil, nil)
  6489  	err = fs.SkipMsgs(2, 10)
  6490  	require_NoError(t, err)
  6491  	state = fs.State()
  6492  	require_Equal(t, state.FirstSeq, 1)
  6493  	require_Equal(t, state.LastSeq, 11)
  6494  	require_Equal(t, state.Msgs, 1)
  6495  	require_Equal(t, state.NumDeleted, 10)
  6496  	require_Equal(t, len(state.Deleted), 10)
  6497  
  6498  	// Check Fast State too.
  6499  	state.Deleted = nil
  6500  	fs.FastState(&state)
  6501  	require_Equal(t, state.FirstSeq, 1)
  6502  	require_Equal(t, state.LastSeq, 11)
  6503  	require_Equal(t, state.Msgs, 1)
  6504  	require_Equal(t, state.NumDeleted, 10)
  6505  }
  6506  
  6507  func TestFileStoreOptimizeFirstLoadNextMsgWithSequenceZero(t *testing.T) {
  6508  	sd := t.TempDir()
  6509  	fs, err := newFileStore(
  6510  		FileStoreConfig{StoreDir: sd, BlockSize: 4096},
  6511  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6512  	require_NoError(t, err)
  6513  	defer fs.Stop()
  6514  
  6515  	msg := bytes.Repeat([]byte("ZZZ"), 33) // ~100bytes
  6516  
  6517  	for i := 0; i < 5000; i++ {
  6518  		fs.StoreMsg("foo.A", nil, msg)
  6519  	}
  6520  	// This will create alot of blocks, ~167.
  6521  	// Just used to check that we do not load these in when searching.
  6522  	// Now add in 10 for foo.bar at the end.
  6523  	for i := 0; i < 10; i++ {
  6524  		fs.StoreMsg("foo.B", nil, msg)
  6525  	}
  6526  	// The bug would not be visible on running server per se since we would have had fss loaded
  6527  	// and that sticks around a bit longer, we would use that to skip over the early blocks. So stop
  6528  	// and restart the filestore.
  6529  	fs.Stop()
  6530  	fs, err = newFileStore(
  6531  		FileStoreConfig{StoreDir: sd, BlockSize: 4096},
  6532  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6533  	require_NoError(t, err)
  6534  	defer fs.Stop()
  6535  
  6536  	// Now fetch the next message for foo.B but set starting sequence to 0.
  6537  	_, nseq, err := fs.LoadNextMsg("foo.B", false, 0, nil)
  6538  	require_NoError(t, err)
  6539  	require_Equal(t, nseq, 5001)
  6540  	// Now check how many blks are loaded, should be only 1.
  6541  	require_Equal(t, fs.cacheLoads(), 1)
  6542  }
  6543  
  6544  func TestFileStoreWriteFullStateHighSubjectCardinality(t *testing.T) {
  6545  	t.Skip()
  6546  
  6547  	sd := t.TempDir()
  6548  	fs, err := newFileStore(
  6549  		FileStoreConfig{StoreDir: sd, BlockSize: 4096},
  6550  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6551  	require_NoError(t, err)
  6552  	defer fs.Stop()
  6553  
  6554  	msg := []byte{1, 2, 3}
  6555  
  6556  	for i := 0; i < 1_000_000; i++ {
  6557  		subj := fmt.Sprintf("subj_%d", i)
  6558  		_, _, err := fs.StoreMsg(subj, nil, msg)
  6559  		require_NoError(t, err)
  6560  	}
  6561  
  6562  	start := time.Now()
  6563  	require_NoError(t, fs.writeFullState())
  6564  	t.Logf("Took %s to writeFullState", time.Since(start))
  6565  }
  6566  
  6567  func TestFileStoreEraseMsgWithDbitSlots(t *testing.T) {
  6568  	fs, err := newFileStore(
  6569  		FileStoreConfig{StoreDir: t.TempDir()},
  6570  		StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage})
  6571  	require_NoError(t, err)
  6572  	defer fs.Stop()
  6573  
  6574  	fs.StoreMsg("foo", nil, []byte("abd"))
  6575  	for i := 0; i < 10; i++ {
  6576  		fs.SkipMsg()
  6577  	}
  6578  	fs.StoreMsg("foo", nil, []byte("abd"))
  6579  	// Now grab that first block and compact away the skips which will
  6580  	// introduce dbits into our idx.
  6581  	fs.mu.RLock()
  6582  	mb := fs.blks[0]
  6583  	fs.mu.RUnlock()
  6584  	// Compact.
  6585  	mb.mu.Lock()
  6586  	mb.compact()
  6587  	mb.mu.Unlock()
  6588  
  6589  	removed, err := fs.EraseMsg(1)
  6590  	require_NoError(t, err)
  6591  	require_True(t, removed)
  6592  }
  6593  
  6594  func TestFileStoreEraseMsgWithAllTrailingDbitSlots(t *testing.T) {
  6595  	fs, err := newFileStore(
  6596  		FileStoreConfig{StoreDir: t.TempDir()},
  6597  		StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage})
  6598  	require_NoError(t, err)
  6599  	defer fs.Stop()
  6600  
  6601  	fs.StoreMsg("foo", nil, []byte("abc"))
  6602  	fs.StoreMsg("foo", nil, []byte("abcdefg"))
  6603  
  6604  	for i := 0; i < 10; i++ {
  6605  		fs.SkipMsg()
  6606  	}
  6607  	// Now grab that first block and compact away the skips which will
  6608  	// introduce dbits into our idx.
  6609  	fs.mu.RLock()
  6610  	mb := fs.blks[0]
  6611  	fs.mu.RUnlock()
  6612  	// Compact.
  6613  	mb.mu.Lock()
  6614  	mb.compact()
  6615  	mb.mu.Unlock()
  6616  
  6617  	removed, err := fs.EraseMsg(2)
  6618  	require_NoError(t, err)
  6619  	require_True(t, removed)
  6620  }
  6621  
  6622  func TestFileStoreMultiLastSeqs(t *testing.T) {
  6623  	fs, err := newFileStore(
  6624  		FileStoreConfig{StoreDir: t.TempDir(), BlockSize: 256}, // Make block size small to test multiblock selections with maxSeq
  6625  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6626  	require_NoError(t, err)
  6627  	defer fs.Stop()
  6628  
  6629  	msg := []byte("abc")
  6630  	for i := 0; i < 33; i++ {
  6631  		fs.StoreMsg("foo.foo", nil, msg)
  6632  		fs.StoreMsg("foo.bar", nil, msg)
  6633  		fs.StoreMsg("foo.baz", nil, msg)
  6634  	}
  6635  	for i := 0; i < 33; i++ {
  6636  		fs.StoreMsg("bar.foo", nil, msg)
  6637  		fs.StoreMsg("bar.bar", nil, msg)
  6638  		fs.StoreMsg("bar.baz", nil, msg)
  6639  	}
  6640  
  6641  	checkResults := func(seqs, expected []uint64) {
  6642  		t.Helper()
  6643  		if len(seqs) != len(expected) {
  6644  			t.Fatalf("Expected %+v got %+v", expected, seqs)
  6645  		}
  6646  		for i := range seqs {
  6647  			if seqs[i] != expected[i] {
  6648  				t.Fatalf("Expected %+v got %+v", expected, seqs)
  6649  			}
  6650  		}
  6651  	}
  6652  
  6653  	// UpTo sequence 3. Tests block split.
  6654  	seqs, err := fs.MultiLastSeqs([]string{"foo.*"}, 3, -1)
  6655  	require_NoError(t, err)
  6656  	checkResults(seqs, []uint64{1, 2, 3})
  6657  	// Up to last sequence of the stream.
  6658  	seqs, err = fs.MultiLastSeqs([]string{"foo.*"}, 0, -1)
  6659  	require_NoError(t, err)
  6660  	checkResults(seqs, []uint64{97, 98, 99})
  6661  	// Check for bar.* at the end.
  6662  	seqs, err = fs.MultiLastSeqs([]string{"bar.*"}, 0, -1)
  6663  	require_NoError(t, err)
  6664  	checkResults(seqs, []uint64{196, 197, 198})
  6665  	// This should find nothing.
  6666  	seqs, err = fs.MultiLastSeqs([]string{"bar.*"}, 99, -1)
  6667  	require_NoError(t, err)
  6668  	checkResults(seqs, nil)
  6669  
  6670  	// Do multiple subjects explicitly.
  6671  	seqs, err = fs.MultiLastSeqs([]string{"foo.foo", "foo.bar", "foo.baz"}, 3, -1)
  6672  	require_NoError(t, err)
  6673  	checkResults(seqs, []uint64{1, 2, 3})
  6674  	seqs, err = fs.MultiLastSeqs([]string{"foo.foo", "foo.bar", "foo.baz"}, 0, -1)
  6675  	require_NoError(t, err)
  6676  	checkResults(seqs, []uint64{97, 98, 99})
  6677  	seqs, err = fs.MultiLastSeqs([]string{"bar.foo", "bar.bar", "bar.baz"}, 0, -1)
  6678  	require_NoError(t, err)
  6679  	checkResults(seqs, []uint64{196, 197, 198})
  6680  	seqs, err = fs.MultiLastSeqs([]string{"bar.foo", "bar.bar", "bar.baz"}, 99, -1)
  6681  	require_NoError(t, err)
  6682  	checkResults(seqs, nil)
  6683  
  6684  	// Check single works
  6685  	seqs, err = fs.MultiLastSeqs([]string{"foo.foo"}, 3, -1)
  6686  	require_NoError(t, err)
  6687  	checkResults(seqs, []uint64{1})
  6688  
  6689  	// Now test that we properly de-duplicate between filters.
  6690  	seqs, err = fs.MultiLastSeqs([]string{"foo.*", "foo.bar"}, 3, -1)
  6691  	require_NoError(t, err)
  6692  	checkResults(seqs, []uint64{1, 2, 3})
  6693  	seqs, err = fs.MultiLastSeqs([]string{"bar.>", "bar.bar", "bar.baz"}, 0, -1)
  6694  	require_NoError(t, err)
  6695  	checkResults(seqs, []uint64{196, 197, 198})
  6696  
  6697  	// All
  6698  	seqs, err = fs.MultiLastSeqs([]string{">"}, 0, -1)
  6699  	require_NoError(t, err)
  6700  	checkResults(seqs, []uint64{97, 98, 99, 196, 197, 198})
  6701  	seqs, err = fs.MultiLastSeqs([]string{">"}, 99, -1)
  6702  	require_NoError(t, err)
  6703  	checkResults(seqs, []uint64{97, 98, 99})
  6704  }
  6705  
  6706  func TestFileStoreMultiLastSeqsMaxAllowed(t *testing.T) {
  6707  	fs, err := newFileStore(
  6708  		FileStoreConfig{StoreDir: t.TempDir()},
  6709  		StreamConfig{Name: "zzz", Subjects: []string{"foo.*"}, Storage: FileStorage})
  6710  	require_NoError(t, err)
  6711  	defer fs.Stop()
  6712  
  6713  	msg := []byte("abc")
  6714  	for i := 1; i <= 100; i++ {
  6715  		fs.StoreMsg(fmt.Sprintf("foo.%d", i), nil, msg)
  6716  	}
  6717  	// Test that if we specify maxAllowed that we get the correct error.
  6718  	seqs, err := fs.MultiLastSeqs([]string{"foo.*"}, 0, 10)
  6719  	require_True(t, seqs == nil)
  6720  	require_Error(t, err, ErrTooManyResults)
  6721  }
  6722  
  6723  ///////////////////////////////////////////////////////////////////////////
  6724  // Benchmarks
  6725  ///////////////////////////////////////////////////////////////////////////
  6726  
  6727  func Benchmark_FileStoreSelectMsgBlock(b *testing.B) {
  6728  	// We use small block size to create lots of blocks for this test.
  6729  	fs, err := newFileStore(
  6730  		FileStoreConfig{StoreDir: b.TempDir(), BlockSize: 128},
  6731  		StreamConfig{Name: "zzz", Subjects: []string{"*"}, Storage: FileStorage})
  6732  	if err != nil {
  6733  		b.Fatalf("Unexpected error: %v", err)
  6734  	}
  6735  	defer fs.Stop()
  6736  
  6737  	subj, msg := "A", bytes.Repeat([]byte("ABC"), 33) // ~100bytes
  6738  
  6739  	// Add in a bunch of blocks.
  6740  	for i := 0; i < 1000; i++ {
  6741  		fs.StoreMsg(subj, nil, msg)
  6742  	}
  6743  	if fs.numMsgBlocks() < 1000 {
  6744  		b.Fatalf("Expected at least 1000 blocks, got %d", fs.numMsgBlocks())
  6745  	}
  6746  
  6747  	fs.mu.RLock()
  6748  	defer fs.mu.RUnlock()
  6749  
  6750  	b.ResetTimer()
  6751  	for i := 0; i < b.N; i++ {
  6752  		_, mb := fs.selectMsgBlockWithIndex(1)
  6753  		if mb == nil {
  6754  			b.Fatalf("Expected a non-nil mb")
  6755  		}
  6756  	}
  6757  	b.StopTimer()
  6758  }