github.com/matrixorigin/matrixone@v0.7.0/pkg/logservice/truncation_test.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package logservice 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 pb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestTruncationExportSnapshot(t *testing.T) { 28 fn := func(t *testing.T, s *Service) { 29 ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) 30 defer cancel() 31 32 dnID := uint64(100) 33 req := pb.Request{ 34 Method: pb.CONNECT_RO, 35 LogRequest: pb.LogRequest{ 36 ShardID: 1, 37 DNID: dnID, 38 }, 39 } 40 resp := s.handleConnect(ctx, req) 41 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 42 43 for i := 0; i < 10; i++ { 44 data := make([]byte, 8) 45 cmd := getTestAppendCmd(dnID, data) 46 req = pb.Request{ 47 Method: pb.APPEND, 48 LogRequest: pb.LogRequest{ 49 ShardID: 1, 50 }, 51 } 52 resp = s.handleAppend(ctx, req, cmd) 53 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 54 assert.Equal(t, uint64(4+i), resp.LogResponse.Lsn) // applied index is 4+i 55 } 56 57 req = pb.Request{ 58 Method: pb.TRUNCATE, 59 LogRequest: pb.LogRequest{ 60 ShardID: 1, 61 Lsn: 4, 62 }, 63 } 64 resp = s.handleTruncate(ctx, req) 65 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 66 assert.Equal(t, uint64(0), resp.LogResponse.Lsn) 67 68 req = pb.Request{ 69 Method: pb.GET_TRUNCATE, 70 LogRequest: pb.LogRequest{ 71 ShardID: 1, 72 }, 73 } 74 resp = s.handleGetTruncatedIndex(ctx, req) 75 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 76 assert.Equal(t, uint64(4), resp.LogResponse.Lsn) 77 78 err := s.store.processShardTruncateLog(ctx, 1) 79 assert.NoError(t, err) 80 assert.Equal(t, 1, s.store.snapshotMgr.Count(1, 1)) 81 82 err = s.store.processShardTruncateLog(ctx, 1) 83 // truncate lsn not advanced, no error is returned. 84 assert.NoError(t, err) 85 } 86 runServiceTest(t, false, true, fn) 87 } 88 89 func TestTruncationImportSnapshot(t *testing.T) { 90 fn := func(t *testing.T, s *Service) { 91 ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) 92 defer cancel() 93 94 dnID := uint64(100) 95 req := pb.Request{ 96 Method: pb.CONNECT_RO, 97 LogRequest: pb.LogRequest{ 98 ShardID: 1, 99 DNID: dnID, 100 }, 101 } 102 resp := s.handleConnect(ctx, req) 103 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 104 105 for i := 0; i < 10; i++ { 106 data := make([]byte, 8) 107 cmd := getTestAppendCmd(dnID, data) 108 req = pb.Request{ 109 Method: pb.APPEND, 110 LogRequest: pb.LogRequest{ 111 ShardID: 1, 112 }, 113 } 114 resp = s.handleAppend(ctx, req, cmd) 115 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 116 assert.Equal(t, uint64(4+i), resp.LogResponse.Lsn) // applied index is 4+i 117 } 118 119 req = pb.Request{ 120 Method: pb.TRUNCATE, 121 LogRequest: pb.LogRequest{ 122 ShardID: 1, 123 Lsn: 4, 124 }, 125 } 126 resp = s.handleTruncate(ctx, req) 127 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 128 assert.Equal(t, uint64(0), resp.LogResponse.Lsn) 129 130 req = pb.Request{ 131 Method: pb.GET_TRUNCATE, 132 LogRequest: pb.LogRequest{ 133 ShardID: 1, 134 }, 135 } 136 resp = s.handleGetTruncatedIndex(ctx, req) 137 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 138 assert.Equal(t, uint64(4), resp.LogResponse.Lsn) 139 140 // after this, snapshot index 14 is exported. 141 err := s.store.processShardTruncateLog(ctx, 1) 142 assert.NoError(t, err) 143 assert.Equal(t, 1, s.store.snapshotMgr.Count(1, 1)) 144 145 _, idx := s.store.snapshotMgr.EvalImportSnapshot(1, 1, 6) 146 assert.Equal(t, uint64(0), idx) 147 148 err = s.store.processShardTruncateLog(ctx, 1) 149 assert.NoError(t, err) 150 assert.Equal(t, 1, s.store.snapshotMgr.Count(1, 1)) 151 152 req = pb.Request{ 153 Method: pb.TRUNCATE, 154 LogRequest: pb.LogRequest{ 155 ShardID: 1, 156 Lsn: 10, 157 }, 158 } 159 resp = s.handleTruncate(ctx, req) 160 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 161 assert.Equal(t, uint64(0), resp.LogResponse.Lsn) 162 163 _, idx = s.store.snapshotMgr.EvalImportSnapshot(1, 1, 10) 164 assert.Equal(t, uint64(0), idx) 165 // index already advance to 15 because of truncate op. 166 err = s.store.processShardTruncateLog(ctx, 1) 167 assert.NoError(t, err) 168 assert.Equal(t, 2, s.store.snapshotMgr.Count(1, 1)) 169 170 for i := 0; i < 10; i++ { 171 data := make([]byte, 8) 172 cmd := getTestAppendCmd(dnID, data) 173 req = pb.Request{ 174 Method: pb.APPEND, 175 LogRequest: pb.LogRequest{ 176 ShardID: 1, 177 }, 178 } 179 resp = s.handleAppend(ctx, req, cmd) 180 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 181 assert.Equal(t, uint64(16+i), resp.LogResponse.Lsn) // applied index is 16+i 182 } 183 184 req = pb.Request{ 185 Method: pb.TRUNCATE, 186 LogRequest: pb.LogRequest{ 187 ShardID: 1, 188 Lsn: 15, 189 }, 190 } 191 resp = s.handleTruncate(ctx, req) 192 assert.Equal(t, uint32(moerr.Ok), resp.ErrorCode) 193 assert.Equal(t, uint64(0), resp.LogResponse.Lsn) 194 195 _, idx = s.store.snapshotMgr.EvalImportSnapshot(1, 1, 14) 196 assert.Equal(t, uint64(14), idx) 197 err = s.store.processShardTruncateLog(ctx, 1) 198 assert.NoError(t, err) 199 assert.Equal(t, 0, s.store.snapshotMgr.Count(1, 1)) 200 } 201 runServiceTest(t, false, true, fn) 202 }