github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/integration/commitlog_bootstrap_with_snapshots_test.go (about)

     1  // +build integration
     2  
     3  // Copyright (c) 2017 Uber Technologies, Inc.
     4  //
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  //
    12  // The above copyright notice and this permission notice shall be included in
    13  // all copies or substantial portions of the Software.
    14  //
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    21  // THE SOFTWARE.
    22  
    23  package integration
    24  
    25  import (
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/m3db/m3/src/dbnode/integration/generate"
    30  	"github.com/m3db/m3/src/dbnode/namespace"
    31  	"github.com/m3db/m3/src/dbnode/retention"
    32  
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  func TestCommitLogBootstrapWithSnapshots(t *testing.T) {
    37  	testCommitLogBootstrapWithSnapshots(t, nil, nil)
    38  }
    39  
    40  func TestProtoCommitLogBootstrapWithSnapshots(t *testing.T) {
    41  	testCommitLogBootstrapWithSnapshots(t, setProtoTestOptions, setProtoTestInputConfig)
    42  }
    43  
    44  func testCommitLogBootstrapWithSnapshots(t *testing.T, setTestOpts setTestOptions, updateInputConfig generate.UpdateBlockConfig) {
    45  	if testing.Short() {
    46  		t.SkipNow() // Just skip if we're doing a short run
    47  	}
    48  
    49  	// Test setup
    50  	var (
    51  		ropts     = retention.NewOptions().SetRetentionPeriod(12 * time.Hour)
    52  		blockSize = ropts.BlockSize()
    53  	)
    54  	ns1, err := namespace.NewMetadata(testNamespaces[0], namespace.NewOptions().
    55  		SetRetentionOptions(ropts).
    56  		SetColdWritesEnabled(true))
    57  	require.NoError(t, err)
    58  	ns2, err := namespace.NewMetadata(testNamespaces[1], namespace.NewOptions().
    59  		SetRetentionOptions(ropts).
    60  		SetColdWritesEnabled(true))
    61  	require.NoError(t, err)
    62  	opts := NewTestOptions(t).
    63  		SetNamespaces([]namespace.Metadata{ns1, ns2})
    64  
    65  	if setTestOpts != nil {
    66  		opts = setTestOpts(t, opts)
    67  		ns1 = opts.Namespaces()[0]
    68  		ns2 = opts.Namespaces()[1]
    69  	}
    70  
    71  	setup, err := NewTestSetup(t, opts, nil)
    72  	require.NoError(t, err)
    73  	defer setup.Close()
    74  
    75  	commitLogOpts := setup.StorageOpts().CommitLogOptions().
    76  		SetFlushInterval(defaultIntegrationTestFlushInterval)
    77  	setup.SetStorageOpts(setup.StorageOpts().SetCommitLogOptions(commitLogOpts))
    78  
    79  	log := setup.StorageOpts().InstrumentOptions().Logger()
    80  	log.Info("commit log bootstrap test")
    81  
    82  	// Write test data
    83  	log.Info("generating data")
    84  	var (
    85  		now        = setup.NowFn()().Truncate(blockSize)
    86  		seriesMaps = generateSeriesMaps(
    87  			100,
    88  			updateInputConfig,
    89  			now.Add(-4*blockSize),
    90  			now.Add(-3*blockSize),
    91  			now.Add(-2*blockSize),
    92  			now.Add(-blockSize),
    93  		)
    94  	)
    95  	log.Info("writing data")
    96  
    97  	var (
    98  		snapshotInterval            = 10 * time.Second
    99  		numDatapointsNotInSnapshots = 0
   100  		pred                        = func(dp generate.TestValue) bool {
   101  			blockStart := dp.TimestampNanos.Truncate(blockSize)
   102  			if dp.TimestampNanos.Before(blockStart.Add(snapshotInterval)) {
   103  				return true
   104  			}
   105  
   106  			numDatapointsNotInSnapshots++
   107  			return false
   108  		}
   109  	)
   110  
   111  	writeSnapshotsWithPredicate(
   112  		t, setup, commitLogOpts, seriesMaps, 0, ns1, nil, pred, snapshotInterval)
   113  
   114  	numDatapointsNotInCommitLogs := 0
   115  	writeCommitLogDataWithPredicate(t, setup, commitLogOpts, seriesMaps, ns1, func(dp generate.TestValue) bool {
   116  		blockStart := dp.TimestampNanos.Truncate(blockSize)
   117  		if dp.TimestampNanos.Equal(blockStart.Add(snapshotInterval)) ||
   118  			dp.TimestampNanos.After(blockStart.Add(snapshotInterval)) {
   119  			return true
   120  		}
   121  
   122  		numDatapointsNotInCommitLogs++
   123  		return false
   124  	})
   125  
   126  	// Make sure we actually excluded some datapoints from the snapshot and commitlog files
   127  	require.True(t, numDatapointsNotInSnapshots > 0)
   128  	require.True(t, numDatapointsNotInCommitLogs > 0)
   129  
   130  	log.Info("finished writing data")
   131  
   132  	// Setup bootstrapper after writing data so filesystem inspection can find it.
   133  	setupCommitLogBootstrapperWithFSInspection(t, setup, commitLogOpts)
   134  
   135  	setup.SetNowFn(now)
   136  	// Start the server with filesystem bootstrapper
   137  	require.NoError(t, setup.StartServer())
   138  	log.Debug("server is now up")
   139  
   140  	// Stop the server
   141  	defer func() {
   142  		require.NoError(t, setup.StopServer())
   143  		log.Debug("server is now down")
   144  	}()
   145  
   146  	// Verify in-memory data match what we expect - all writes from seriesMaps
   147  	// should be present
   148  	metadatasByShard := testSetupMetadatas(t, setup, testNamespaces[0], now.Add(-4*blockSize), now)
   149  	observedSeriesMaps := testSetupToSeriesMaps(t, setup, ns1, metadatasByShard)
   150  	verifySeriesMapsEqual(t, seriesMaps, observedSeriesMaps)
   151  
   152  	// Verify in-memory data match what we expect - no writes should be present
   153  	// because we didn't issue any writes for this namespaces
   154  	emptySeriesMaps := make(generate.SeriesBlocksByStart)
   155  	metadatasByShard2 := testSetupMetadatas(t, setup, testNamespaces[1], now.Add(-4*blockSize), now)
   156  	observedSeriesMaps2 := testSetupToSeriesMaps(t, setup, ns2, metadatasByShard2)
   157  	verifySeriesMapsEqual(t, emptySeriesMaps, observedSeriesMaps2)
   158  
   159  }