feat: raft/log_test se testify packages in tests

Signed-off-by: jianfei.zhang <jianfei.zhang@daocloud.io>
This commit is contained in:
jianfei.zhang 2022-11-14 11:43:16 +08:00
parent 970ecfcddb
commit cadf9de3f8

View File

@ -15,9 +15,11 @@
package raft package raft
import ( import (
"reflect" "fmt"
"testing" "testing"
"github.com/stretchr/testify/require"
pb "go.etcd.io/etcd/raft/v3/raftpb" pb "go.etcd.io/etcd/raft/v3/raftpb"
) )
@ -45,13 +47,11 @@ func TestFindConflict(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
raftLog := newLog(NewMemoryStorage(), raftLogger) t.Run(fmt.Sprint(i), func(t *testing.T) {
raftLog.append(previousEnts...) raftLog := newLog(NewMemoryStorage(), raftLogger)
raftLog.append(previousEnts...)
gconflict := raftLog.findConflict(tt.ents) require.Equal(t, tt.wconflict, raftLog.findConflict(tt.ents))
if gconflict != tt.wconflict { })
t.Errorf("#%d: conflict = %d, want %d", i, gconflict, tt.wconflict)
}
} }
} }
@ -79,10 +79,9 @@ func TestIsUpToDate(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
gUpToDate := raftLog.isUpToDate(tt.lastIndex, tt.term) t.Run(fmt.Sprint(i), func(t *testing.T) {
if gUpToDate != tt.wUpToDate { require.Equal(t, tt.wUpToDate, raftLog.isUpToDate(tt.lastIndex, tt.term))
t.Errorf("#%d: uptodate = %v, want %v", i, gUpToDate, tt.wUpToDate) })
}
} }
} }
@ -123,24 +122,16 @@ func TestAppend(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
storage := NewMemoryStorage() t.Run(fmt.Sprint(i), func(t *testing.T) {
storage.Append(previousEnts) storage := NewMemoryStorage()
raftLog := newLog(storage, raftLogger) storage.Append(previousEnts)
raftLog := newLog(storage, raftLogger)
index := raftLog.append(tt.ents...) require.Equal(t, tt.windex, raftLog.append(tt.ents...))
if index != tt.windex { g, err := raftLog.entries(1, noLimit)
t.Errorf("#%d: lastIndex = %d, want %d", i, index, tt.windex) require.NoError(t, err)
} require.Equal(t, tt.wents, g)
g, err := raftLog.entries(1, noLimit) require.Equal(t, tt.wunstable, raftLog.unstable.offset)
if err != nil { })
t.Fatalf("#%d: unexpected error %v", i, err)
}
if !reflect.DeepEqual(g, tt.wents) {
t.Errorf("#%d: logEnts = %+v, want %+v", i, g, tt.wents)
}
if goff := raftLog.unstable.offset; goff != tt.wunstable {
t.Errorf("#%d: unstable = %d, want %d", i, goff, tt.wunstable)
}
} }
} }
@ -241,36 +232,23 @@ func TestLogMaybeAppend(t *testing.T) {
raftLog := newLog(NewMemoryStorage(), raftLogger) raftLog := newLog(NewMemoryStorage(), raftLogger)
raftLog.append(previousEnts...) raftLog.append(previousEnts...)
raftLog.committed = commit raftLog.committed = commit
func() {
t.Run(fmt.Sprint(i), func(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
if !tt.wpanic { require.True(t, tt.wpanic)
t.Errorf("%d: panic = %v, want %v", i, true, tt.wpanic)
}
} }
}() }()
glasti, gappend := raftLog.maybeAppend(tt.index, tt.logTerm, tt.committed, tt.ents...) glasti, gappend := raftLog.maybeAppend(tt.index, tt.logTerm, tt.committed, tt.ents...)
gcommit := raftLog.committed require.Equal(t, tt.wlasti, glasti)
require.Equal(t, tt.wappend, gappend)
if glasti != tt.wlasti { require.Equal(t, tt.wcommit, raftLog.committed)
t.Errorf("#%d: lastindex = %d, want %d", i, glasti, tt.wlasti)
}
if gappend != tt.wappend {
t.Errorf("#%d: append = %v, want %v", i, gappend, tt.wappend)
}
if gcommit != tt.wcommit {
t.Errorf("#%d: committed = %d, want %d", i, gcommit, tt.wcommit)
}
if gappend && len(tt.ents) != 0 { if gappend && len(tt.ents) != 0 {
gents, err := raftLog.slice(raftLog.lastIndex()-uint64(len(tt.ents))+1, raftLog.lastIndex()+1, noLimit) gents, err := raftLog.slice(raftLog.lastIndex()-uint64(len(tt.ents))+1, raftLog.lastIndex()+1, noLimit)
if err != nil { require.NoError(t, err)
t.Fatalf("unexpected error %v", err) require.Equal(t, tt.ents, gents)
}
if !reflect.DeepEqual(tt.ents, gents) {
t.Errorf("#%d: appended entries = %v, want %v", i, gents, tt.ents)
}
} }
}() })
} }
} }
@ -291,52 +269,32 @@ func TestCompactionSideEffects(t *testing.T) {
raftLog.append(pb.Entry{Term: i + 1, Index: i + 1}) raftLog.append(pb.Entry{Term: i + 1, Index: i + 1})
} }
ok := raftLog.maybeCommit(lastIndex, lastTerm) require.True(t, raftLog.maybeCommit(lastIndex, lastTerm))
if !ok {
t.Fatalf("maybeCommit returned false")
}
raftLog.appliedTo(raftLog.committed) raftLog.appliedTo(raftLog.committed)
offset := uint64(500) offset := uint64(500)
storage.Compact(offset) storage.Compact(offset)
require.Equal(t, lastIndex, raftLog.lastIndex())
if raftLog.lastIndex() != lastIndex { for j := offset; j <= raftLog.lastIndex(); j++ {
t.Errorf("lastIndex = %d, want %d", raftLog.lastIndex(), lastIndex) require.Equal(t, j, mustTerm(raftLog.term(j)))
} }
for j := offset; j <= raftLog.lastIndex(); j++ { for j := offset; j <= raftLog.lastIndex(); j++ {
if mustTerm(raftLog.term(j)) != j { require.True(t, raftLog.matchTerm(j, j))
t.Errorf("term(%d) = %d, want %d", j, mustTerm(raftLog.term(j)), j)
}
}
for j := offset; j <= raftLog.lastIndex(); j++ {
if !raftLog.matchTerm(j, j) {
t.Errorf("matchTerm(%d) = false, want true", j)
}
} }
unstableEnts := raftLog.unstableEntries() unstableEnts := raftLog.unstableEntries()
if g := len(unstableEnts); g != 250 { require.Equal(t, 250, len(unstableEnts))
t.Errorf("len(unstableEntries) = %d, want = %d", g, 250) require.Equal(t, uint64(751), unstableEnts[0].Index)
}
if unstableEnts[0].Index != 751 {
t.Errorf("Index = %d, want = %d", unstableEnts[0].Index, 751)
}
prev := raftLog.lastIndex() prev := raftLog.lastIndex()
raftLog.append(pb.Entry{Index: raftLog.lastIndex() + 1, Term: raftLog.lastIndex() + 1}) raftLog.append(pb.Entry{Index: raftLog.lastIndex() + 1, Term: raftLog.lastIndex() + 1})
if raftLog.lastIndex() != prev+1 { require.Equal(t, prev+1, raftLog.lastIndex())
t.Errorf("lastIndex = %d, want = %d", raftLog.lastIndex(), prev+1)
}
ents, err := raftLog.entries(raftLog.lastIndex(), noLimit) ents, err := raftLog.entries(raftLog.lastIndex(), noLimit)
if err != nil { require.NoError(t, err)
t.Fatalf("unexpected error %v", err) require.Equal(t, 1, len(ents))
}
if len(ents) != 1 {
t.Errorf("len(entries) = %d, want = %d", len(ents), 1)
}
} }
func TestHasNextCommittedEnts(t *testing.T) { func TestHasNextCommittedEnts(t *testing.T) {
@ -361,22 +319,21 @@ func TestHasNextCommittedEnts(t *testing.T) {
{applied: 3, snap: true, whasNext: false}, {applied: 3, snap: true, whasNext: false},
} }
for i, tt := range tests { for i, tt := range tests {
storage := NewMemoryStorage() t.Run(fmt.Sprint(i), func(t *testing.T) {
storage.ApplySnapshot(snap) storage := NewMemoryStorage()
raftLog := newLog(storage, raftLogger) require.NoError(t, storage.ApplySnapshot(snap))
raftLog.append(ents...)
raftLog.maybeCommit(5, 1)
raftLog.appliedTo(tt.applied)
if tt.snap {
newSnap := snap
newSnap.Metadata.Index++
raftLog.restore(newSnap)
}
hasNext := raftLog.hasNextCommittedEnts() raftLog := newLog(storage, raftLogger)
if hasNext != tt.whasNext { raftLog.append(ents...)
t.Errorf("#%d: hasNext = %v, want %v", i, hasNext, tt.whasNext) raftLog.maybeCommit(5, 1)
} raftLog.appliedTo(tt.applied)
if tt.snap {
newSnap := snap
newSnap.Metadata.Index++
raftLog.restore(newSnap)
}
require.Equal(t, tt.whasNext, raftLog.hasNextCommittedEnts())
})
} }
} }
@ -402,22 +359,22 @@ func TestNextCommittedEnts(t *testing.T) {
{applied: 3, snap: true, wents: nil}, {applied: 3, snap: true, wents: nil},
} }
for i, tt := range tests { for i, tt := range tests {
storage := NewMemoryStorage() t.Run(fmt.Sprint(i), func(t *testing.T) {
storage.ApplySnapshot(snap) storage := NewMemoryStorage()
raftLog := newLog(storage, raftLogger) require.NoError(t, storage.ApplySnapshot(snap))
raftLog.append(ents...)
raftLog.maybeCommit(5, 1) raftLog := newLog(storage, raftLogger)
raftLog.appliedTo(tt.applied) raftLog.append(ents...)
if tt.snap { raftLog.maybeCommit(5, 1)
newSnap := snap raftLog.appliedTo(tt.applied)
newSnap.Metadata.Index++ if tt.snap {
raftLog.restore(newSnap) newSnap := snap
} newSnap.Metadata.Index++
raftLog.restore(newSnap)
}
require.Equal(t, tt.wents, raftLog.nextCommittedEnts())
})
nents := raftLog.nextCommittedEnts()
if !reflect.DeepEqual(nents, tt.wents) {
t.Errorf("#%d: nents = %+v, want %+v", i, nents, tt.wents)
}
} }
} }
@ -434,25 +391,22 @@ func TestUnstableEnts(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
// append stable entries to storage t.Run(fmt.Sprint(i), func(t *testing.T) {
storage := NewMemoryStorage() // append stable entries to storage
storage.Append(previousEnts[:tt.unstable-1]) storage := NewMemoryStorage()
require.NoError(t, storage.Append(previousEnts[:tt.unstable-1]))
// append unstable entries to raftlog // append unstable entries to raftlog
raftLog := newLog(storage, raftLogger) raftLog := newLog(storage, raftLogger)
raftLog.append(previousEnts[tt.unstable-1:]...) raftLog.append(previousEnts[tt.unstable-1:]...)
ents := raftLog.unstableEntries() ents := raftLog.unstableEntries()
if l := len(ents); l > 0 { if l := len(ents); l > 0 {
raftLog.stableTo(ents[l-1].Index, ents[l-1].Term) raftLog.stableTo(ents[l-1].Index, ents[l-1].Term)
} }
if !reflect.DeepEqual(ents, tt.wents) { require.Equal(t, tt.wents, ents)
t.Errorf("#%d: unstableEnts = %+v, want %+v", i, ents, tt.wents) require.Equal(t, previousEnts[len(previousEnts)-1].Index+1, raftLog.unstable.offset)
} })
w := previousEnts[len(previousEnts)-1].Index + 1
if g := raftLog.unstable.offset; g != w {
t.Errorf("#%d: unstable = %d, want %d", i, g, w)
}
} }
} }
@ -469,22 +423,18 @@ func TestCommitTo(t *testing.T) {
{4, 0, true}, // commit out of range -> panic {4, 0, true}, // commit out of range -> panic
} }
for i, tt := range tests { for i, tt := range tests {
func() { t.Run(fmt.Sprint(i), func(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
if !tt.wpanic { require.True(t, tt.wpanic)
t.Errorf("%d: panic = %v, want %v", i, true, tt.wpanic)
}
} }
}() }()
raftLog := newLog(NewMemoryStorage(), raftLogger) raftLog := newLog(NewMemoryStorage(), raftLogger)
raftLog.append(previousEnts...) raftLog.append(previousEnts...)
raftLog.committed = commit raftLog.committed = commit
raftLog.commitTo(tt.commit) raftLog.commitTo(tt.commit)
if raftLog.committed != tt.wcommit { require.Equal(t, tt.wcommit, raftLog.committed)
t.Errorf("#%d: committed = %d, want %d", i, raftLog.committed, tt.wcommit) })
}
}()
} }
} }
@ -500,12 +450,12 @@ func TestStableTo(t *testing.T) {
{3, 1, 1}, // bad index {3, 1, 1}, // bad index
} }
for i, tt := range tests { for i, tt := range tests {
raftLog := newLog(NewMemoryStorage(), raftLogger) t.Run(fmt.Sprint(i), func(t *testing.T) {
raftLog.append([]pb.Entry{{Index: 1, Term: 1}, {Index: 2, Term: 2}}...) raftLog := newLog(NewMemoryStorage(), raftLogger)
raftLog.stableTo(tt.stablei, tt.stablet) raftLog.append([]pb.Entry{{Index: 1, Term: 1}, {Index: 2, Term: 2}}...)
if raftLog.unstable.offset != tt.wunstable { raftLog.stableTo(tt.stablei, tt.stablet)
t.Errorf("#%d: unstable = %d, want %d", i, raftLog.unstable.offset, tt.wunstable) require.Equal(t, tt.wunstable, raftLog.unstable.offset)
} })
} }
} }
@ -535,14 +485,15 @@ func TestStableToWithSnap(t *testing.T) {
{snapi - 1, snapt + 1, []pb.Entry{{Index: snapi + 1, Term: snapt}}, snapi + 1}, {snapi - 1, snapt + 1, []pb.Entry{{Index: snapi + 1, Term: snapt}}, snapi + 1},
} }
for i, tt := range tests { for i, tt := range tests {
s := NewMemoryStorage() t.Run(fmt.Sprint(i), func(t *testing.T) {
s.ApplySnapshot(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: snapi, Term: snapt}}) s := NewMemoryStorage()
raftLog := newLog(s, raftLogger) require.NoError(t, s.ApplySnapshot(pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: snapi, Term: snapt}}))
raftLog.append(tt.newEnts...) raftLog := newLog(s, raftLogger)
raftLog.stableTo(tt.stablei, tt.stablet) raftLog.append(tt.newEnts...)
if raftLog.unstable.offset != tt.wunstable { raftLog.stableTo(tt.stablei, tt.stablet)
t.Errorf("#%d: unstable = %d, want %d", i, raftLog.unstable.offset, tt.wunstable) require.Equal(t, tt.wunstable, raftLog.unstable.offset)
} })
} }
} }
@ -562,36 +513,30 @@ func TestCompaction(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
func() { t.Run(fmt.Sprint(i), func(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
if tt.wallow { require.False(t, tt.wallow)
t.Errorf("%d: allow = %v, want %v: %v", i, false, true, r)
}
} }
}() }()
storage := NewMemoryStorage() storage := NewMemoryStorage()
for i := uint64(1); i <= tt.lastIndex; i++ { for i := uint64(1); i <= tt.lastIndex; i++ {
storage.Append([]pb.Entry{{Index: i}}) storage.Append([]pb.Entry{{Index: i}})
} }
raftLog := newLog(storage, raftLogger) raftLog := newLog(storage, raftLogger)
raftLog.maybeCommit(tt.lastIndex, 0) raftLog.maybeCommit(tt.lastIndex, 0)
raftLog.appliedTo(raftLog.committed)
raftLog.appliedTo(raftLog.committed)
for j := 0; j < len(tt.compact); j++ { for j := 0; j < len(tt.compact); j++ {
err := storage.Compact(tt.compact[j]) err := storage.Compact(tt.compact[j])
if err != nil { if err != nil {
if tt.wallow { require.False(t, tt.wallow)
t.Errorf("#%d.%d allow = %t, want %t", i, j, false, tt.wallow)
}
continue continue
} }
if len(raftLog.allEntries()) != tt.wleft[j] { require.Equal(t, tt.wleft[j], len(raftLog.allEntries()))
t.Errorf("#%d.%d len = %d, want %d", i, j, len(raftLog.allEntries()), tt.wleft[j])
}
} }
}()
})
} }
} }
@ -603,21 +548,11 @@ func TestLogRestore(t *testing.T) {
storage.ApplySnapshot(pb.Snapshot{Metadata: snap}) storage.ApplySnapshot(pb.Snapshot{Metadata: snap})
raftLog := newLog(storage, raftLogger) raftLog := newLog(storage, raftLogger)
if len(raftLog.allEntries()) != 0 { require.Zero(t, len(raftLog.allEntries()))
t.Errorf("len = %d, want 0", len(raftLog.allEntries())) require.Equal(t, index+1, raftLog.firstIndex())
} require.Equal(t, index, raftLog.committed)
if raftLog.firstIndex() != index+1 { require.Equal(t, index+1, raftLog.unstable.offset)
t.Errorf("firstIndex = %d, want %d", raftLog.firstIndex(), index+1) require.Equal(t, term, mustTerm(raftLog.term(index)))
}
if raftLog.committed != index {
t.Errorf("committed = %d, want %d", raftLog.committed, index)
}
if raftLog.unstable.offset != index+1 {
t.Errorf("unstable = %d, want %d", raftLog.unstable.offset, index+1)
}
if mustTerm(raftLog.term(index)) != term {
t.Errorf("term = %d, want %d", mustTerm(raftLog.term(index)), term)
}
} }
func TestIsOutOfBounds(t *testing.T) { func TestIsOutOfBounds(t *testing.T) {
@ -679,25 +614,17 @@ func TestIsOutOfBounds(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
func() { t.Run(fmt.Sprint(i), func(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
if !tt.wpanic { require.True(t, tt.wpanic)
t.Errorf("%d: panic = %v, want %v: %v", i, true, false, r)
}
} }
}() }()
err := l.mustCheckOutOfBounds(tt.lo, tt.hi) err := l.mustCheckOutOfBounds(tt.lo, tt.hi)
if tt.wpanic { require.False(t, tt.wpanic)
t.Errorf("#%d: panic = %v, want %v", i, false, true) require.False(t, tt.wErrCompacted && err != ErrCompacted)
} require.False(t, !tt.wErrCompacted && err != nil)
if tt.wErrCompacted && err != ErrCompacted { })
t.Errorf("#%d: err = %v, want %v", i, err, ErrCompacted)
}
if !tt.wErrCompacted && err != nil {
t.Errorf("#%d: unexpected err %v", i, err)
}
}()
} }
} }
@ -725,10 +652,9 @@ func TestTerm(t *testing.T) {
} }
for j, tt := range tests { for j, tt := range tests {
term := mustTerm(l.term(tt.index)) t.Run(fmt.Sprint(j), func(t *testing.T) {
if term != tt.w { require.Equal(t, tt.w, mustTerm(l.term(tt.index)))
t.Errorf("#%d: at = %d, want %d", j, term, tt.w) })
}
} }
} }
@ -755,10 +681,9 @@ func TestTermWithUnstableSnapshot(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
term := mustTerm(l.term(tt.index)) t.Run(fmt.Sprint(i), func(t *testing.T) {
if term != tt.w { require.Equal(t, tt.w, mustTerm(l.term(tt.index)))
t.Errorf("#%d: at = %d, want %d", i, term, tt.w) })
}
} }
} }
@ -807,25 +732,17 @@ func TestSlice(t *testing.T) {
} }
for j, tt := range tests { for j, tt := range tests {
func() { t.Run(fmt.Sprint(j), func(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
if !tt.wpanic { require.True(t, tt.wpanic)
t.Errorf("%d: panic = %v, want %v: %v", j, true, false, r)
}
} }
}() }()
g, err := l.slice(tt.from, tt.to, tt.limit) g, err := l.slice(tt.from, tt.to, tt.limit)
if tt.from <= offset && err != ErrCompacted { require.False(t, tt.from <= offset && err != ErrCompacted)
t.Fatalf("#%d: err = %v, want %v", j, err, ErrCompacted) require.False(t, tt.from > offset && err != nil)
} require.Equal(t, tt.w, g)
if tt.from > offset && err != nil { })
t.Fatalf("#%d: unexpected error %v", j, err)
}
if !reflect.DeepEqual(g, tt.w) {
t.Errorf("#%d: from %d to %d = %v, want %v", j, tt.from, tt.to, g, tt.w)
}
}()
} }
} }