mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
199 lines
4.2 KiB
Go
199 lines
4.2 KiB
Go
package raft
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// TestCompactionSideEffects ensures that all the log related funcationality works correctly after
|
|
// a compaction.
|
|
func TestCompactionSideEffects(t *testing.T) {
|
|
lastIndex := 1000
|
|
log := newLog()
|
|
|
|
for i := 0; i < lastIndex; i++ {
|
|
log.append(i, Entry{Term: i + 1})
|
|
}
|
|
|
|
log.compact(500)
|
|
|
|
if log.lastIndex() != lastIndex {
|
|
t.Errorf("lastIndex = %d, want %d", log.lastIndex(), lastIndex)
|
|
}
|
|
|
|
for i := log.offset; i <= log.lastIndex(); i++ {
|
|
if log.term(i) != i {
|
|
t.Errorf("term(%d) = %d, want %d", i, log.term(i), i)
|
|
}
|
|
}
|
|
|
|
for i := log.offset; i <= log.lastIndex(); i++ {
|
|
if !log.matchTerm(i, i) {
|
|
t.Errorf("matchTerm(%d) = false, want true", i)
|
|
}
|
|
}
|
|
|
|
prev := log.lastIndex()
|
|
log.append(log.lastIndex(), Entry{Term: log.lastIndex() + 1})
|
|
if log.lastIndex() != prev+1 {
|
|
t.Errorf("lastIndex = %d, want = %d", log.lastIndex(), prev+1)
|
|
}
|
|
|
|
ents := log.entries(log.lastIndex())
|
|
if len(ents) != 1 {
|
|
t.Errorf("len(entries) = %d, want = %d", len(ents), 1)
|
|
}
|
|
}
|
|
|
|
//TestCompaction ensures that the number of log entreis is correct after compactions.
|
|
func TestCompaction(t *testing.T) {
|
|
tests := []struct {
|
|
app int
|
|
compact []int
|
|
wleft []int
|
|
wallow bool
|
|
}{
|
|
// out of upper bound
|
|
{1000, []int{1001}, []int{-1}, false},
|
|
{1000, []int{300, 500, 800, 900}, []int{701, 501, 201, 101}, true},
|
|
// out of lower bound
|
|
{1000, []int{300, 299}, []int{701, -1}, false},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
if tt.wallow == true {
|
|
t.Errorf("%d: allow = %v, want %v", i, false, true)
|
|
}
|
|
}
|
|
}()
|
|
|
|
log := newLog()
|
|
for i := 0; i < tt.app; i++ {
|
|
log.append(i, Entry{})
|
|
}
|
|
|
|
for j := 0; j < len(tt.compact); j++ {
|
|
log.compact(tt.compact[j])
|
|
if len(log.ents) != tt.wleft[j] {
|
|
t.Errorf("#%d.%d len = %d, want %d", i, j, len(log.ents), tt.wleft[j])
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
|
|
func TestLogRestore(t *testing.T) {
|
|
log := newLog()
|
|
for i := 0; i < 100; i++ {
|
|
log.append(i, Entry{Term: i + 1})
|
|
}
|
|
|
|
index := 1000
|
|
term := 1000
|
|
log.restore(index, term)
|
|
|
|
// only has the guard entry
|
|
if len(log.ents) != 1 {
|
|
t.Errorf("len = %d, want 0", len(log.ents))
|
|
}
|
|
if log.offset != index {
|
|
t.Errorf("offset = %d, want %d", log.offset, index)
|
|
}
|
|
if log.applied != index {
|
|
t.Errorf("applied = %d, want %d", log.applied, index)
|
|
}
|
|
if log.committed != index {
|
|
t.Errorf("comitted = %d, want %d", log.committed, index)
|
|
}
|
|
if log.term(index) != term {
|
|
t.Errorf("term = %d, want %d", log.term(index), term)
|
|
}
|
|
}
|
|
|
|
func TestIsOutOfBounds(t *testing.T) {
|
|
offset := 100
|
|
num := 100
|
|
l := &log{offset: offset, ents: make([]Entry, num)}
|
|
|
|
tests := []struct {
|
|
index int
|
|
w bool
|
|
}{
|
|
{offset - 1, true},
|
|
{offset, false},
|
|
{offset + num/2, false},
|
|
{offset + num - 1, false},
|
|
{offset + num, true},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
g := l.isOutOfBounds(tt.index)
|
|
if g != tt.w {
|
|
t.Errorf("#%d: isOutOfBounds = %v, want %v", i, g, tt.w)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAt(t *testing.T) {
|
|
offset := 100
|
|
num := 100
|
|
|
|
l := &log{offset: offset}
|
|
for i := 0; i < num; i++ {
|
|
l.ents = append(l.ents, Entry{Term: i})
|
|
}
|
|
|
|
tests := []struct {
|
|
index int
|
|
w *Entry
|
|
}{
|
|
{offset - 1, nil},
|
|
{offset, &Entry{Term: 0}},
|
|
{offset + num/2, &Entry{Term: num / 2}},
|
|
{offset + num - 1, &Entry{Term: num - 1}},
|
|
{offset + num, nil},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
g := l.at(tt.index)
|
|
if !reflect.DeepEqual(g, tt.w) {
|
|
t.Errorf("#%d: at = %v, want %v", i, g, tt.w)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSlice(t *testing.T) {
|
|
offset := 100
|
|
num := 100
|
|
|
|
l := &log{offset: offset}
|
|
for i := 0; i < num; i++ {
|
|
l.ents = append(l.ents, Entry{Term: i})
|
|
}
|
|
|
|
tests := []struct {
|
|
from int
|
|
to int
|
|
w []Entry
|
|
}{
|
|
{offset - 1, offset + 1, nil},
|
|
{offset, offset + 1, []Entry{{Term: 0}}},
|
|
{offset + num/2, offset + num/2 + 1, []Entry{{Term: num / 2}}},
|
|
{offset + num - 1, offset + num, []Entry{{Term: num - 1}}},
|
|
{offset + num, offset + num + 1, nil},
|
|
|
|
{offset + num/2, offset + num/2, nil},
|
|
{offset + num/2, offset + num/2 - 1, nil},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
g := l.slice(tt.from, tt.to)
|
|
if !reflect.DeepEqual(g, tt.w) {
|
|
t.Errorf("#%d: from %d to %d = %v, want %v", i, tt.from, tt.to, g, tt.w)
|
|
}
|
|
}
|
|
}
|