diff --git a/raft/log_unstable_test.go b/raft/log_unstable_test.go new file mode 100644 index 000000000..97685892c --- /dev/null +++ b/raft/log_unstable_test.go @@ -0,0 +1,189 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package raft + +import ( + "testing" + + pb "github.com/coreos/etcd/raft/raftpb" +) + +func TestUnstableMaybeFirstIndex(t *testing.T) { + tests := []struct { + entries []pb.Entry + offset uint64 + snap *pb.Snapshot + + wok bool + windex uint64 + }{ + // no snapshot + { + []pb.Entry{{Index: 5, Term: 1}}, 5, nil, + false, 0, + }, + { + []pb.Entry{}, 0, nil, + false, 0, + }, + // has snapshot + { + []pb.Entry{{Index: 5, Term: 1}}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + true, 5, + }, + { + []pb.Entry{}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + true, 5, + }, + } + + for i, tt := range tests { + u := unstable{ + entries: tt.entries, + offset: tt.offset, + snapshot: tt.snap, + } + index, ok := u.maybeFirstIndex() + if ok != tt.wok { + t.Errorf("#%d: ok = %t, want %t", i, ok, tt.wok) + } + if index != tt.windex { + t.Errorf("#%d: index = %d, want %d", i, index, tt.windex) + } + } +} + +func TestMaybeLastIndex(t *testing.T) { + tests := []struct { + entries []pb.Entry + offset uint64 + snap *pb.Snapshot + + wok bool + windex uint64 + }{ + // last in entries + { + []pb.Entry{{Index: 5, Term: 1}}, 5, nil, + true, 5, + }, + { + []pb.Entry{{Index: 5, Term: 1}}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + true, 5, + }, + // last in snapshot + { + []pb.Entry{}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + true, 4, + }, + // empty unstable + { + []pb.Entry{}, 0, nil, + false, 0, + }, + } + + for i, tt := range tests { + u := unstable{ + entries: tt.entries, + offset: tt.offset, + snapshot: tt.snap, + } + index, ok := u.maybeLastIndex() + if ok != tt.wok { + t.Errorf("#%d: ok = %t, want %t", i, ok, tt.wok) + } + if index != tt.windex { + t.Errorf("#%d: index = %d, want %d", i, index, tt.windex) + } + } +} + +func TestUnstableMaybeTerm(t *testing.T) { + tests := []struct { + entries []pb.Entry + offset uint64 + snap *pb.Snapshot + index uint64 + + wok bool + wterm uint64 + }{ + // term from entries + { + []pb.Entry{{Index: 5, Term: 1}}, 5, nil, + 5, + true, 1, + }, + { + []pb.Entry{{Index: 5, Term: 1}}, 5, nil, + 6, + false, 0, + }, + { + []pb.Entry{{Index: 5, Term: 1}}, 5, nil, + 4, + false, 0, + }, + { + []pb.Entry{{Index: 5, Term: 1}}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + 5, + true, 1, + }, + { + []pb.Entry{{Index: 5, Term: 1}}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + 6, + false, 0, + }, + // term from snapshot + { + []pb.Entry{{Index: 5, Term: 1}}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + 4, + true, 1, + }, + { + []pb.Entry{}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + 5, + false, 0, + }, + { + []pb.Entry{}, 5, &pb.Snapshot{Metadata: pb.SnapshotMetadata{Index: 4, Term: 1}}, + 4, + true, 1, + }, + { + []pb.Entry{}, 0, nil, + 5, + false, 0, + }, + } + + for i, tt := range tests { + u := unstable{ + entries: tt.entries, + offset: tt.offset, + snapshot: tt.snap, + } + term, ok := u.maybeTerm(tt.index) + if ok != tt.wok { + t.Errorf("#%d: ok = %t, want %t", i, ok, tt.wok) + } + if term != tt.wterm { + t.Errorf("#%d: term = %d, want %d", i, term, tt.wterm) + } + } +}