From aa0943d16eccf5f193dd6fa8734c20fe6f6699f6 Mon Sep 17 00:00:00 2001 From: Tobias Schottdorf Date: Thu, 21 Feb 2019 20:27:43 +0100 Subject: [PATCH] storage: move TestTruncateLog Release note: None --- pkg/storage/raft_log_queue_test.go | 108 +++++++++++++++++++++++++++++ pkg/storage/replica_test.go | 107 ---------------------------- 2 files changed, 108 insertions(+), 107 deletions(-) diff --git a/pkg/storage/raft_log_queue_test.go b/pkg/storage/raft_log_queue_test.go index 2c83a39ce56d..9c2ca5191032 100644 --- a/pkg/storage/raft_log_queue_test.go +++ b/pkg/storage/raft_log_queue_test.go @@ -17,6 +17,7 @@ package storage import ( "context" "fmt" + "math" "strings" "testing" "time" @@ -675,3 +676,110 @@ func TestSnapshotLogTruncationConstraints(t *testing.T) { assert.Equal(t, r.mu.snapshotLogTruncationConstraints, map[uuid.UUID]snapTruncationInfo(nil)) } + +// TestTruncateLog verifies that the TruncateLog command removes a +// prefix of the raft logs (modifying FirstIndex() and making them +// inaccessible via Entries()). +func TestTruncateLog(t *testing.T) { + defer leaktest.AfterTest(t)() + tc := testContext{} + stopper := stop.NewStopper() + defer stopper.Stop(context.TODO()) + tc.Start(t, stopper) + tc.repl.store.SetRaftLogQueueActive(false) + + // Populate the log with 10 entries. Save the LastIndex after each write. + var indexes []uint64 + for i := 0; i < 10; i++ { + args := incrementArgs([]byte("a"), int64(i)) + + if _, pErr := tc.SendWrapped(&args); pErr != nil { + t.Fatal(pErr) + } + idx, err := tc.repl.GetLastIndex() + if err != nil { + t.Fatal(err) + } + indexes = append(indexes, idx) + } + + rangeID := tc.repl.RangeID + + // Discard the first half of the log. + truncateArgs := truncateLogArgs(indexes[5], rangeID) + if _, pErr := tc.SendWrappedWith(roachpb.Header{RangeID: 1}, &truncateArgs); pErr != nil { + t.Fatal(pErr) + } + + // FirstIndex has changed. + firstIndex, err := tc.repl.GetFirstIndex() + if err != nil { + t.Fatal(err) + } + if firstIndex != indexes[5] { + t.Errorf("expected firstIndex == %d, got %d", indexes[5], firstIndex) + } + + // We can still get what remains of the log. + tc.repl.mu.Lock() + entries, err := tc.repl.raftEntriesLocked(indexes[5], indexes[9], math.MaxUint64) + tc.repl.mu.Unlock() + if err != nil { + t.Fatal(err) + } + if len(entries) != int(indexes[9]-indexes[5]) { + t.Errorf("expected %d entries, got %d", indexes[9]-indexes[5], len(entries)) + } + + // But any range that includes the truncated entries returns an error. + tc.repl.mu.Lock() + _, err = tc.repl.raftEntriesLocked(indexes[4], indexes[9], math.MaxUint64) + tc.repl.mu.Unlock() + if err != raft.ErrCompacted { + t.Errorf("expected ErrCompacted, got %s", err) + } + + // The term of the last truncated entry is still available. + tc.repl.mu.Lock() + term, err := tc.repl.raftTermRLocked(indexes[4]) + tc.repl.mu.Unlock() + if err != nil { + t.Fatal(err) + } + if term == 0 { + t.Errorf("invalid term 0 for truncated entry") + } + + // The terms of older entries are gone. + tc.repl.mu.Lock() + _, err = tc.repl.raftTermRLocked(indexes[3]) + tc.repl.mu.Unlock() + if err != raft.ErrCompacted { + t.Errorf("expected ErrCompacted, got %s", err) + } + + // Truncating logs that have already been truncated should not return an + // error. + truncateArgs = truncateLogArgs(indexes[3], rangeID) + if _, pErr := tc.SendWrapped(&truncateArgs); pErr != nil { + t.Fatal(pErr) + } + + // Truncating logs that have the wrong rangeID included should not return + // an error but should not truncate any logs. + truncateArgs = truncateLogArgs(indexes[9], rangeID+1) + if _, pErr := tc.SendWrapped(&truncateArgs); pErr != nil { + t.Fatal(pErr) + } + + tc.repl.mu.Lock() + // The term of the last truncated entry is still available. + term, err = tc.repl.raftTermRLocked(indexes[4]) + tc.repl.mu.Unlock() + if err != nil { + t.Fatal(err) + } + if term == 0 { + t.Errorf("invalid term 0 for truncated entry") + } +} diff --git a/pkg/storage/replica_test.go b/pkg/storage/replica_test.go index 4e1421be21ed..4dca107ae969 100644 --- a/pkg/storage/replica_test.go +++ b/pkg/storage/replica_test.go @@ -5663,113 +5663,6 @@ func TestMerge(t *testing.T) { } } -// TestTruncateLog verifies that the TruncateLog command removes a -// prefix of the raft logs (modifying FirstIndex() and making them -// inaccessible via Entries()). -func TestTruncateLog(t *testing.T) { - defer leaktest.AfterTest(t)() - tc := testContext{} - stopper := stop.NewStopper() - defer stopper.Stop(context.TODO()) - tc.Start(t, stopper) - tc.repl.store.SetRaftLogQueueActive(false) - - // Populate the log with 10 entries. Save the LastIndex after each write. - var indexes []uint64 - for i := 0; i < 10; i++ { - args := incrementArgs([]byte("a"), int64(i)) - - if _, pErr := tc.SendWrapped(&args); pErr != nil { - t.Fatal(pErr) - } - idx, err := tc.repl.GetLastIndex() - if err != nil { - t.Fatal(err) - } - indexes = append(indexes, idx) - } - - rangeID := tc.repl.RangeID - - // Discard the first half of the log. - truncateArgs := truncateLogArgs(indexes[5], rangeID) - if _, pErr := tc.SendWrappedWith(roachpb.Header{RangeID: 1}, &truncateArgs); pErr != nil { - t.Fatal(pErr) - } - - // FirstIndex has changed. - firstIndex, err := tc.repl.GetFirstIndex() - if err != nil { - t.Fatal(err) - } - if firstIndex != indexes[5] { - t.Errorf("expected firstIndex == %d, got %d", indexes[5], firstIndex) - } - - // We can still get what remains of the log. - tc.repl.mu.Lock() - entries, err := tc.repl.raftEntriesLocked(indexes[5], indexes[9], math.MaxUint64) - tc.repl.mu.Unlock() - if err != nil { - t.Fatal(err) - } - if len(entries) != int(indexes[9]-indexes[5]) { - t.Errorf("expected %d entries, got %d", indexes[9]-indexes[5], len(entries)) - } - - // But any range that includes the truncated entries returns an error. - tc.repl.mu.Lock() - _, err = tc.repl.raftEntriesLocked(indexes[4], indexes[9], math.MaxUint64) - tc.repl.mu.Unlock() - if err != raft.ErrCompacted { - t.Errorf("expected ErrCompacted, got %s", err) - } - - // The term of the last truncated entry is still available. - tc.repl.mu.Lock() - term, err := tc.repl.raftTermRLocked(indexes[4]) - tc.repl.mu.Unlock() - if err != nil { - t.Fatal(err) - } - if term == 0 { - t.Errorf("invalid term 0 for truncated entry") - } - - // The terms of older entries are gone. - tc.repl.mu.Lock() - _, err = tc.repl.raftTermRLocked(indexes[3]) - tc.repl.mu.Unlock() - if err != raft.ErrCompacted { - t.Errorf("expected ErrCompacted, got %s", err) - } - - // Truncating logs that have already been truncated should not return an - // error. - truncateArgs = truncateLogArgs(indexes[3], rangeID) - if _, pErr := tc.SendWrapped(&truncateArgs); pErr != nil { - t.Fatal(pErr) - } - - // Truncating logs that have the wrong rangeID included should not return - // an error but should not truncate any logs. - truncateArgs = truncateLogArgs(indexes[9], rangeID+1) - if _, pErr := tc.SendWrapped(&truncateArgs); pErr != nil { - t.Fatal(pErr) - } - - tc.repl.mu.Lock() - // The term of the last truncated entry is still available. - term, err = tc.repl.raftTermRLocked(indexes[4]) - tc.repl.mu.Unlock() - if err != nil { - t.Fatal(err) - } - if term == 0 { - t.Errorf("invalid term 0 for truncated entry") - } -} - // TestConditionFailedError tests that a ConditionFailedError correctly // bubbles up from MVCC to Range. func TestConditionFailedError(t *testing.T) {