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 }