mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #1063 from coreos/node_run_test
raft: test node block proposal
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user