Merge pull request #1063 from coreos/node_run_test

raft: test node block proposal
This commit is contained in:
Xiang Li
2014-09-14 22:46:50 -07:00
2 changed files with 82 additions and 1 deletions

View File

@@ -34,7 +34,7 @@ type Ready struct {
}
func isStateEqual(a, b pb.State) bool {
return a.Term == b.Term && a.Vote == b.Vote && a.LastIndex == b.LastIndex
return a.Term == b.Term && a.Vote == b.Vote && a.Commit == b.Commit && a.LastIndex == b.LastIndex
}
func IsEmptyState(st pb.State) bool {

View File

@@ -2,6 +2,7 @@ package raft
import (
"reflect"
"runtime"
"testing"
"time"
@@ -81,6 +82,58 @@ func TestNodeStepUnblock(t *testing.T) {
}
}
// TestBlockProposal ensures that node will block proposal when it does not
// know who is the current leader; node will accept proposal when it knows
// who is the current leader.
func TestBlockProposal(t *testing.T) {
n := newNode()
r := newRaft(1, []int64{1}, 10, 1)
go n.run(r)
defer n.Stop()
errc := make(chan error, 1)
go func() {
errc <- n.Propose(context.TODO(), []byte("somedata"))
}()
forceGosched()
select {
case err := <-errc:
t.Errorf("err = %v, want blocking", err)
default:
}
n.Campaign(context.TODO())
forceGosched()
select {
case err := <-errc:
if err != nil {
t.Errorf("err = %v, want %v", err, nil)
}
default:
t.Errorf("blocking proposal, want unblocking")
}
}
func TestReadyContainUpdates(t *testing.T) {
tests := []struct {
rd Ready
wcontain bool
}{
{Ready{}, false},
{Ready{State: raftpb.State{Vote: 1}}, true},
{Ready{Entries: make([]raftpb.Entry, 1, 1)}, true},
{Ready{CommittedEntries: make([]raftpb.Entry, 1, 1)}, true},
{Ready{Messages: make([]raftpb.Message, 1, 1)}, true},
}
for i, tt := range tests {
if tt.rd.containsUpdates() != tt.wcontain {
t.Errorf("#%d: containUpdates = %v, want %v", i, tt.rd.containsUpdates(), tt.wcontain)
}
}
}
func TestNode(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -140,3 +193,31 @@ func TestNodeRestart(t *testing.T) {
default:
}
}
func TestIsStateEqual(t *testing.T) {
tests := []struct {
st raftpb.State
we bool
}{
{emptyState, true},
{raftpb.State{Vote: 1}, false},
{raftpb.State{Commit: 1}, false},
{raftpb.State{Term: 1}, false},
{raftpb.State{LastIndex: 1}, false},
}
for i, tt := range tests {
if isStateEqual(tt.st, emptyState) != tt.we {
t.Errorf("#%d, equal = %v, want %v", i, isStateEqual(tt.st, emptyState), tt.we)
}
}
}
// WARNING: This is a hack.
// Remove this when we are able to block/check the status of the go-routines.
func forceGosched() {
// possibility enough to sched upto 10 go routines.
for i := 0; i < 10000; i++ {
runtime.Gosched()
}
}