Skip to content

Commit

Permalink
storage: move TestTruncateLog
Browse files Browse the repository at this point in the history
Release note: None
  • Loading branch information
tbg committed Feb 27, 2019
1 parent 423c352 commit aa0943d
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 107 deletions.
108 changes: 108 additions & 0 deletions pkg/storage/raft_log_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package storage
import (
"context"
"fmt"
"math"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -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")
}
}
107 changes: 0 additions & 107 deletions pkg/storage/replica_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit aa0943d

Please sign in to comment.