mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
commit
5bb43b5276
@ -23,6 +23,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/etcd/pkg/testutil"
|
||||
"github.com/coreos/etcd/pkg/types"
|
||||
"github.com/coreos/etcd/raft/raftpb"
|
||||
"github.com/coreos/etcd/store"
|
||||
@ -535,10 +536,10 @@ func TestClusterAddMember(t *testing.T) {
|
||||
c.SetStore(st)
|
||||
c.AddMember(newTestMember(1, nil, "node1", nil))
|
||||
|
||||
wactions := []action{
|
||||
wactions := []testutil.Action{
|
||||
{
|
||||
name: "Create",
|
||||
params: []interface{}{
|
||||
Name: "Create",
|
||||
Params: []interface{}{
|
||||
path.Join(storeMembersPrefix, "1", "raftAttributes"),
|
||||
false,
|
||||
`{"peerURLs":null}`,
|
||||
@ -623,9 +624,9 @@ func TestClusterRemoveMember(t *testing.T) {
|
||||
c.SetStore(st)
|
||||
c.RemoveMember(1)
|
||||
|
||||
wactions := []action{
|
||||
{name: "Delete", params: []interface{}{memberStoreKey(1), true, true}},
|
||||
{name: "Create", params: []interface{}{removedMemberStoreKey(1), false, "", false, store.Permanent}},
|
||||
wactions := []testutil.Action{
|
||||
{Name: "Delete", Params: []interface{}{memberStoreKey(1), true, true}},
|
||||
{Name: "Create", Params: []interface{}{removedMemberStoreKey(1), false, "", false, store.Permanent}},
|
||||
}
|
||||
if !reflect.DeepEqual(st.Action(), wactions) {
|
||||
t.Errorf("actions = %v, want %v", st.Action(), wactions)
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -49,35 +48,35 @@ func TestDoLocalAction(t *testing.T) {
|
||||
|
||||
wresp Response
|
||||
werr error
|
||||
wactions []action
|
||||
wactions []testutil.Action
|
||||
}{
|
||||
{
|
||||
pb.Request{Method: "GET", ID: 1, Wait: true},
|
||||
Response{Watcher: &stubWatcher{}}, nil, []action{action{name: "Watch"}},
|
||||
Response{Watcher: &nopWatcher{}}, nil, []testutil.Action{{Name: "Watch"}},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "GET", ID: 1},
|
||||
Response{Event: &store.Event{}}, nil,
|
||||
[]action{
|
||||
action{
|
||||
name: "Get",
|
||||
params: []interface{}{"", false, false},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Get",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "HEAD", ID: 1},
|
||||
Response{Event: &store.Event{}}, nil,
|
||||
[]action{
|
||||
action{
|
||||
name: "Get",
|
||||
params: []interface{}{"", false, false},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Get",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "BADMETHOD", ID: 1},
|
||||
Response{}, ErrUnknownMethod, []action{},
|
||||
Response{}, ErrUnknownMethod, []testutil.Action{},
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
@ -108,19 +107,29 @@ func TestDoBadLocalAction(t *testing.T) {
|
||||
tests := []struct {
|
||||
req pb.Request
|
||||
|
||||
wactions []action
|
||||
wactions []testutil.Action
|
||||
}{
|
||||
{
|
||||
pb.Request{Method: "GET", ID: 1, Wait: true},
|
||||
[]action{action{name: "Watch"}},
|
||||
[]testutil.Action{{Name: "Watch"}},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "GET", ID: 1},
|
||||
[]action{action{name: "Get"}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Get",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "HEAD", ID: 1},
|
||||
[]action{action{name: "Get"}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Get",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
@ -149,16 +158,16 @@ func TestApplyRequest(t *testing.T) {
|
||||
req pb.Request
|
||||
|
||||
wresp Response
|
||||
wactions []action
|
||||
wactions []testutil.Action
|
||||
}{
|
||||
// POST ==> Create
|
||||
{
|
||||
pb.Request{Method: "POST", ID: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Create",
|
||||
params: []interface{}{"", false, "", true, time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Create",
|
||||
Params: []interface{}{"", false, "", true, time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -166,10 +175,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "POST", ID: 1, Expiration: 1337},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Create",
|
||||
params: []interface{}{"", false, "", true, time.Unix(0, 1337)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Create",
|
||||
Params: []interface{}{"", false, "", true, time.Unix(0, 1337)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -177,10 +186,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "POST", ID: 1, Dir: true},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Create",
|
||||
params: []interface{}{"", true, "", true, time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Create",
|
||||
Params: []interface{}{"", true, "", true, time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -188,10 +197,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Set",
|
||||
params: []interface{}{"", false, "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Set",
|
||||
Params: []interface{}{"", false, "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -199,10 +208,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, Dir: true},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Set",
|
||||
params: []interface{}{"", true, "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Set",
|
||||
Params: []interface{}{"", true, "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -210,10 +219,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(true)},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Update",
|
||||
params: []interface{}{"", "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Update",
|
||||
Params: []interface{}{"", "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -221,10 +230,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(false)},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Create",
|
||||
params: []interface{}{"", false, "", false, time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Create",
|
||||
Params: []interface{}{"", false, "", false, time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -233,10 +242,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(true), PrevIndex: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Update",
|
||||
params: []interface{}{"", "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Update",
|
||||
Params: []interface{}{"", "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -245,10 +254,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(false), PrevIndex: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Create",
|
||||
params: []interface{}{"", false, "", false, time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Create",
|
||||
Params: []interface{}{"", false, "", false, time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -256,10 +265,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevIndex: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndSwap",
|
||||
params: []interface{}{"", "", uint64(1), "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndSwap",
|
||||
Params: []interface{}{"", "", uint64(1), "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -267,10 +276,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevValue: "bar"},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndSwap",
|
||||
params: []interface{}{"", "bar", uint64(0), "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndSwap",
|
||||
Params: []interface{}{"", "bar", uint64(0), "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -278,10 +287,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "PUT", ID: 1, PrevIndex: 1, PrevValue: "bar"},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndSwap",
|
||||
params: []interface{}{"", "bar", uint64(1), "", time.Time{}},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndSwap",
|
||||
Params: []interface{}{"", "bar", uint64(1), "", time.Time{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -289,10 +298,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "DELETE", ID: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Delete",
|
||||
params: []interface{}{"", false, false},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Delete",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -300,10 +309,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "DELETE", ID: 1, PrevIndex: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndDelete",
|
||||
params: []interface{}{"", "", uint64(1)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndDelete",
|
||||
Params: []interface{}{"", "", uint64(1)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -311,10 +320,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "DELETE", ID: 1, PrevValue: "bar"},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndDelete",
|
||||
params: []interface{}{"", "bar", uint64(0)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndDelete",
|
||||
Params: []interface{}{"", "bar", uint64(0)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -322,10 +331,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "DELETE", ID: 1, PrevIndex: 5, PrevValue: "bar"},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "CompareAndDelete",
|
||||
params: []interface{}{"", "bar", uint64(5)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "CompareAndDelete",
|
||||
Params: []interface{}{"", "bar", uint64(5)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -333,10 +342,10 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "QGET", ID: 1},
|
||||
Response{Event: &store.Event{}},
|
||||
[]action{
|
||||
action{
|
||||
name: "Get",
|
||||
params: []interface{}{"", false, false},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "Get",
|
||||
Params: []interface{}{"", false, false},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -344,20 +353,20 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "SYNC", ID: 1},
|
||||
Response{},
|
||||
[]action{
|
||||
action{
|
||||
name: "DeleteExpiredKeys",
|
||||
params: []interface{}{time.Unix(0, 0)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "DeleteExpiredKeys",
|
||||
Params: []interface{}{time.Unix(0, 0)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
pb.Request{Method: "SYNC", ID: 1, Time: 12345},
|
||||
Response{},
|
||||
[]action{
|
||||
action{
|
||||
name: "DeleteExpiredKeys",
|
||||
params: []interface{}{time.Unix(0, 12345)},
|
||||
[]testutil.Action{
|
||||
{
|
||||
Name: "DeleteExpiredKeys",
|
||||
Params: []interface{}{time.Unix(0, 12345)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -365,7 +374,7 @@ func TestApplyRequest(t *testing.T) {
|
||||
{
|
||||
pb.Request{Method: "BADMETHOD", ID: 1},
|
||||
Response{err: ErrUnknownMethod},
|
||||
[]action{},
|
||||
[]testutil.Action{},
|
||||
},
|
||||
}
|
||||
|
||||
@ -455,10 +464,10 @@ func TestApplyConfChangeError(t *testing.T) {
|
||||
t.Errorf("#%d: applyConfChange error = %v, want %v", i, err, tt.werr)
|
||||
}
|
||||
cc := raftpb.ConfChange{Type: tt.cc.Type, NodeID: raft.None}
|
||||
w := []action{
|
||||
w := []testutil.Action{
|
||||
{
|
||||
name: "ApplyConfChange",
|
||||
params: []interface{}{cc},
|
||||
Name: "ApplyConfChange",
|
||||
Params: []interface{}{cc},
|
||||
},
|
||||
}
|
||||
if g := n.Action(); !reflect.DeepEqual(g, w) {
|
||||
@ -552,7 +561,7 @@ func TestDoProposalCancelled(t *testing.T) {
|
||||
if err != ErrCanceled {
|
||||
t.Fatalf("err = %v, want %v", err, ErrCanceled)
|
||||
}
|
||||
w := []action{action{name: "Register"}, action{name: "Trigger"}}
|
||||
w := []testutil.Action{{Name: "Register"}, {Name: "Trigger"}}
|
||||
if !reflect.DeepEqual(wait.action, w) {
|
||||
t.Errorf("wait.action = %+v, want %+v", wait.action, w)
|
||||
}
|
||||
@ -604,10 +613,10 @@ func TestSync(t *testing.T) {
|
||||
if len(action) != 1 {
|
||||
t.Fatalf("len(action) = %d, want 1", len(action))
|
||||
}
|
||||
if action[0].name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].name)
|
||||
if action[0].Name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].Name)
|
||||
}
|
||||
data := action[0].params[0].([]byte)
|
||||
data := action[0].Params[0].([]byte)
|
||||
var r pb.Request
|
||||
if err := r.Unmarshal(data); err != nil {
|
||||
t.Fatalf("unmarshal request error: %v", err)
|
||||
@ -634,7 +643,7 @@ func TestSyncTimeout(t *testing.T) {
|
||||
|
||||
// give time for goroutine in sync to cancel
|
||||
testutil.ForceGosched()
|
||||
w := []action{action{name: "Propose blocked"}}
|
||||
w := []testutil.Action{{Name: "Propose blocked"}}
|
||||
if g := n.Action(); !reflect.DeepEqual(g, w) {
|
||||
t.Errorf("action = %v, want %v", g, w)
|
||||
}
|
||||
@ -671,10 +680,10 @@ func TestSyncTrigger(t *testing.T) {
|
||||
if len(action) != 1 {
|
||||
t.Fatalf("len(action) = %d, want 1", len(action))
|
||||
}
|
||||
if action[0].name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].name)
|
||||
if action[0].Name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].Name)
|
||||
}
|
||||
data := action[0].params[0].([]byte)
|
||||
data := action[0].Params[0].([]byte)
|
||||
var req pb.Request
|
||||
if err := req.Unmarshal(data); err != nil {
|
||||
t.Fatalf("error unmarshalling data: %v", err)
|
||||
@ -701,17 +710,17 @@ func TestSnapshot(t *testing.T) {
|
||||
if len(gaction) != 1 {
|
||||
t.Fatalf("len(action) = %d, want 1", len(gaction))
|
||||
}
|
||||
if !reflect.DeepEqual(gaction[0], action{name: "Save"}) {
|
||||
if !reflect.DeepEqual(gaction[0], testutil.Action{Name: "Save"}) {
|
||||
t.Errorf("action = %s, want Save", gaction[0])
|
||||
}
|
||||
gaction = p.Action()
|
||||
if len(gaction) != 2 {
|
||||
t.Fatalf("len(action) = %d, want 2", len(gaction))
|
||||
}
|
||||
if !reflect.DeepEqual(gaction[0], action{name: "Cut"}) {
|
||||
if !reflect.DeepEqual(gaction[0], testutil.Action{Name: "Cut"}) {
|
||||
t.Errorf("action = %s, want Cut", gaction[0])
|
||||
}
|
||||
if !reflect.DeepEqual(gaction[1], action{name: "SaveSnap"}) {
|
||||
if !reflect.DeepEqual(gaction[1], testutil.Action{Name: "SaveSnap"}) {
|
||||
t.Errorf("action = %s, want SaveSnap", gaction[1])
|
||||
}
|
||||
}
|
||||
@ -743,7 +752,7 @@ func TestTriggerSnap(t *testing.T) {
|
||||
if len(gaction) != wcnt {
|
||||
t.Fatalf("len(action) = %d, want %d", len(gaction), wcnt)
|
||||
}
|
||||
if !reflect.DeepEqual(gaction[wcnt-1], action{name: "SaveSnap"}) {
|
||||
if !reflect.DeepEqual(gaction[wcnt-1], testutil.Action{Name: "SaveSnap"}) {
|
||||
t.Errorf("action = %s, want SaveSnap", gaction[wcnt-1])
|
||||
}
|
||||
}
|
||||
@ -771,11 +780,11 @@ func TestRecvSnapshot(t *testing.T) {
|
||||
testutil.ForceGosched()
|
||||
s.Stop()
|
||||
|
||||
wactions := []action{action{name: "Recovery"}}
|
||||
wactions := []testutil.Action{{Name: "Recovery"}}
|
||||
if g := st.Action(); !reflect.DeepEqual(g, wactions) {
|
||||
t.Errorf("store action = %v, want %v", g, wactions)
|
||||
}
|
||||
wactions = []action{action{name: "SaveSnap"}, action{name: "Save"}}
|
||||
wactions = []testutil.Action{{Name: "SaveSnap"}, {Name: "Save"}}
|
||||
if g := p.Action(); !reflect.DeepEqual(g, wactions) {
|
||||
t.Errorf("storage action = %v, want %v", g, wactions)
|
||||
}
|
||||
@ -847,11 +856,11 @@ func TestApplySnapshotAndCommittedEntries(t *testing.T) {
|
||||
if len(actions) != 2 {
|
||||
t.Fatalf("len(action) = %d, want 2", len(actions))
|
||||
}
|
||||
if actions[0].name != "Recovery" {
|
||||
t.Errorf("actions[0] = %s, want %s", actions[0].name, "Recovery")
|
||||
if actions[0].Name != "Recovery" {
|
||||
t.Errorf("actions[0] = %s, want %s", actions[0].Name, "Recovery")
|
||||
}
|
||||
if actions[1].name != "Get" {
|
||||
t.Errorf("actions[1] = %s, want %s", actions[1].name, "Get")
|
||||
if actions[1].Name != "Get" {
|
||||
t.Errorf("actions[1] = %s, want %s", actions[1].Name, "Get")
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,11 +871,12 @@ func TestAddMember(t *testing.T) {
|
||||
SoftState: &raft.SoftState{RaftState: raft.StateLeader},
|
||||
}
|
||||
cl := newTestCluster(nil)
|
||||
cl.SetStore(store.New())
|
||||
st := store.New()
|
||||
cl.SetStore(st)
|
||||
s := &EtcdServer{
|
||||
node: n,
|
||||
raftStorage: raft.NewMemoryStorage(),
|
||||
store: &storeRecorder{},
|
||||
store: st,
|
||||
transport: &nopTransporter{},
|
||||
storage: &storageRecorder{},
|
||||
Cluster: cl,
|
||||
@ -881,7 +891,7 @@ func TestAddMember(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("AddMember error: %v", err)
|
||||
}
|
||||
wactions := []action{action{name: "ProposeConfChange:ConfChangeAddNode"}, action{name: "ApplyConfChange:ConfChangeAddNode"}}
|
||||
wactions := []testutil.Action{{Name: "ProposeConfChange:ConfChangeAddNode"}, {Name: "ApplyConfChange:ConfChangeAddNode"}}
|
||||
if !reflect.DeepEqual(gaction, wactions) {
|
||||
t.Errorf("action = %v, want %v", gaction, wactions)
|
||||
}
|
||||
@ -897,12 +907,13 @@ func TestRemoveMember(t *testing.T) {
|
||||
SoftState: &raft.SoftState{RaftState: raft.StateLeader},
|
||||
}
|
||||
cl := newTestCluster(nil)
|
||||
st := store.New()
|
||||
cl.SetStore(store.New())
|
||||
cl.AddMember(&Member{ID: 1234})
|
||||
s := &EtcdServer{
|
||||
node: n,
|
||||
raftStorage: raft.NewMemoryStorage(),
|
||||
store: &storeRecorder{},
|
||||
store: st,
|
||||
transport: &nopTransporter{},
|
||||
storage: &storageRecorder{},
|
||||
Cluster: cl,
|
||||
@ -916,7 +927,7 @@ func TestRemoveMember(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("RemoveMember error: %v", err)
|
||||
}
|
||||
wactions := []action{action{name: "ProposeConfChange:ConfChangeRemoveNode"}, action{name: "ApplyConfChange:ConfChangeRemoveNode"}}
|
||||
wactions := []testutil.Action{{Name: "ProposeConfChange:ConfChangeRemoveNode"}, {Name: "ApplyConfChange:ConfChangeRemoveNode"}}
|
||||
if !reflect.DeepEqual(gaction, wactions) {
|
||||
t.Errorf("action = %v, want %v", gaction, wactions)
|
||||
}
|
||||
@ -932,12 +943,13 @@ func TestUpdateMember(t *testing.T) {
|
||||
SoftState: &raft.SoftState{RaftState: raft.StateLeader},
|
||||
}
|
||||
cl := newTestCluster(nil)
|
||||
cl.SetStore(store.New())
|
||||
st := store.New()
|
||||
cl.SetStore(st)
|
||||
cl.AddMember(&Member{ID: 1234})
|
||||
s := &EtcdServer{
|
||||
node: n,
|
||||
raftStorage: raft.NewMemoryStorage(),
|
||||
store: &storeRecorder{},
|
||||
store: st,
|
||||
transport: &nopTransporter{},
|
||||
storage: &storageRecorder{},
|
||||
Cluster: cl,
|
||||
@ -952,7 +964,7 @@ func TestUpdateMember(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("UpdateMember error: %v", err)
|
||||
}
|
||||
wactions := []action{action{name: "ProposeConfChange:ConfChangeUpdateNode"}, action{name: "ApplyConfChange:ConfChangeUpdateNode"}}
|
||||
wactions := []testutil.Action{{Name: "ProposeConfChange:ConfChangeUpdateNode"}, {Name: "ApplyConfChange:ConfChangeUpdateNode"}}
|
||||
if !reflect.DeepEqual(gaction, wactions) {
|
||||
t.Errorf("action = %v, want %v", gaction, wactions)
|
||||
}
|
||||
@ -983,10 +995,10 @@ func TestPublish(t *testing.T) {
|
||||
if len(action) != 1 {
|
||||
t.Fatalf("len(action) = %d, want 1", len(action))
|
||||
}
|
||||
if action[0].name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].name)
|
||||
if action[0].Name != "Propose" {
|
||||
t.Fatalf("action = %s, want Propose", action[0].Name)
|
||||
}
|
||||
data := action[0].params[0].([]byte)
|
||||
data := action[0].Params[0].([]byte)
|
||||
var r pb.Request
|
||||
if err := r.Unmarshal(data); err != nil {
|
||||
t.Fatalf("unmarshal request error: %v", err)
|
||||
@ -1108,135 +1120,114 @@ func TestGetOtherPeerURLs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type action struct {
|
||||
name string
|
||||
params []interface{}
|
||||
}
|
||||
|
||||
type recorder struct {
|
||||
sync.Mutex
|
||||
actions []action
|
||||
}
|
||||
|
||||
func (r *recorder) record(a action) {
|
||||
r.Lock()
|
||||
r.actions = append(r.actions, a)
|
||||
r.Unlock()
|
||||
}
|
||||
func (r *recorder) Action() []action {
|
||||
r.Lock()
|
||||
cpy := make([]action, len(r.actions))
|
||||
copy(cpy, r.actions)
|
||||
r.Unlock()
|
||||
return cpy
|
||||
}
|
||||
|
||||
type storeRecorder struct {
|
||||
recorder
|
||||
}
|
||||
// storeRecorder records all the methods it receives.
|
||||
// storeRecorder DOES NOT work as a actual store.
|
||||
// It always returns invaild empty response and no error.
|
||||
type storeRecorder struct{ testutil.Recorder }
|
||||
|
||||
func (s *storeRecorder) Version() int { return 0 }
|
||||
func (s *storeRecorder) Index() uint64 { return 0 }
|
||||
func (s *storeRecorder) Get(path string, recursive, sorted bool) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "Get",
|
||||
params: []interface{}{path, recursive, sorted},
|
||||
s.Record(testutil.Action{
|
||||
Name: "Get",
|
||||
Params: []interface{}{path, recursive, sorted},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Set(path string, dir bool, val string, expr time.Time) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "Set",
|
||||
params: []interface{}{path, dir, val, expr},
|
||||
s.Record(testutil.Action{
|
||||
Name: "Set",
|
||||
Params: []interface{}{path, dir, val, expr},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Update(path, val string, expr time.Time) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "Update",
|
||||
params: []interface{}{path, val, expr},
|
||||
s.Record(testutil.Action{
|
||||
Name: "Update",
|
||||
Params: []interface{}{path, val, expr},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Create(path string, dir bool, val string, uniq bool, exp time.Time) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "Create",
|
||||
params: []interface{}{path, dir, val, uniq, exp},
|
||||
s.Record(testutil.Action{
|
||||
Name: "Create",
|
||||
Params: []interface{}{path, dir, val, uniq, exp},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) CompareAndSwap(path, prevVal string, prevIdx uint64, val string, expr time.Time) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "CompareAndSwap",
|
||||
params: []interface{}{path, prevVal, prevIdx, val, expr},
|
||||
s.Record(testutil.Action{
|
||||
Name: "CompareAndSwap",
|
||||
Params: []interface{}{path, prevVal, prevIdx, val, expr},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Delete(path string, dir, recursive bool) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "Delete",
|
||||
params: []interface{}{path, dir, recursive},
|
||||
s.Record(testutil.Action{
|
||||
Name: "Delete",
|
||||
Params: []interface{}{path, dir, recursive},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) CompareAndDelete(path, prevVal string, prevIdx uint64) (*store.Event, error) {
|
||||
s.record(action{
|
||||
name: "CompareAndDelete",
|
||||
params: []interface{}{path, prevVal, prevIdx},
|
||||
s.Record(testutil.Action{
|
||||
Name: "CompareAndDelete",
|
||||
Params: []interface{}{path, prevVal, prevIdx},
|
||||
})
|
||||
return &store.Event{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Watch(_ string, _, _ bool, _ uint64) (store.Watcher, error) {
|
||||
s.record(action{name: "Watch"})
|
||||
return &stubWatcher{}, nil
|
||||
s.Record(testutil.Action{Name: "Watch"})
|
||||
return &nopWatcher{}, nil
|
||||
}
|
||||
func (s *storeRecorder) Save() ([]byte, error) {
|
||||
s.record(action{name: "Save"})
|
||||
s.Record(testutil.Action{Name: "Save"})
|
||||
return nil, nil
|
||||
}
|
||||
func (s *storeRecorder) Recovery(b []byte) error {
|
||||
s.record(action{name: "Recovery"})
|
||||
s.Record(testutil.Action{Name: "Recovery"})
|
||||
return nil
|
||||
}
|
||||
func (s *storeRecorder) JsonStats() []byte { return nil }
|
||||
func (s *storeRecorder) DeleteExpiredKeys(cutoff time.Time) {
|
||||
s.record(action{
|
||||
name: "DeleteExpiredKeys",
|
||||
params: []interface{}{cutoff},
|
||||
s.Record(testutil.Action{
|
||||
Name: "DeleteExpiredKeys",
|
||||
Params: []interface{}{cutoff},
|
||||
})
|
||||
}
|
||||
|
||||
type stubWatcher struct{}
|
||||
type nopWatcher struct{}
|
||||
|
||||
func (w *stubWatcher) EventChan() chan *store.Event { return nil }
|
||||
func (w *stubWatcher) StartIndex() uint64 { return 0 }
|
||||
func (w *stubWatcher) Remove() {}
|
||||
func (w *nopWatcher) EventChan() chan *store.Event { return nil }
|
||||
func (w *nopWatcher) StartIndex() uint64 { return 0 }
|
||||
func (w *nopWatcher) Remove() {}
|
||||
|
||||
// errStoreRecorder returns an store error on Get, Watch request
|
||||
// errStoreRecorder is a storeRecorder, but returns the given error on
|
||||
// Get, Watch methods.
|
||||
type errStoreRecorder struct {
|
||||
storeRecorder
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *errStoreRecorder) Get(_ string, _, _ bool) (*store.Event, error) {
|
||||
s.record(action{name: "Get"})
|
||||
func (s *errStoreRecorder) Get(path string, recursive, sorted bool) (*store.Event, error) {
|
||||
s.storeRecorder.Get(path, recursive, sorted)
|
||||
return nil, s.err
|
||||
}
|
||||
func (s *errStoreRecorder) Watch(_ string, _, _ bool, _ uint64) (store.Watcher, error) {
|
||||
s.record(action{name: "Watch"})
|
||||
func (s *errStoreRecorder) Watch(path string, recursive, sorted bool, index uint64) (store.Watcher, error) {
|
||||
s.storeRecorder.Watch(path, recursive, sorted, index)
|
||||
return nil, s.err
|
||||
}
|
||||
|
||||
type waitRecorder struct {
|
||||
action []action
|
||||
action []testutil.Action
|
||||
}
|
||||
|
||||
func (w *waitRecorder) Register(id uint64) <-chan interface{} {
|
||||
w.action = append(w.action, action{name: "Register"})
|
||||
w.action = append(w.action, testutil.Action{Name: "Register"})
|
||||
return nil
|
||||
}
|
||||
func (w *waitRecorder) Trigger(id uint64, x interface{}) {
|
||||
w.action = append(w.action, action{name: "Trigger"})
|
||||
w.action = append(w.action, testutil.Action{Name: "Trigger"})
|
||||
}
|
||||
|
||||
type waitWithResponse struct {
|
||||
@ -1248,58 +1239,54 @@ func (w *waitWithResponse) Register(id uint64) <-chan interface{} {
|
||||
}
|
||||
func (w *waitWithResponse) Trigger(id uint64, x interface{}) {}
|
||||
|
||||
type storageRecorder struct {
|
||||
recorder
|
||||
}
|
||||
type storageRecorder struct{ testutil.Recorder }
|
||||
|
||||
func (p *storageRecorder) Save(st raftpb.HardState, ents []raftpb.Entry) error {
|
||||
p.record(action{name: "Save"})
|
||||
p.Record(testutil.Action{Name: "Save"})
|
||||
return nil
|
||||
}
|
||||
func (p *storageRecorder) Cut() error {
|
||||
p.record(action{name: "Cut"})
|
||||
p.Record(testutil.Action{Name: "Cut"})
|
||||
return nil
|
||||
}
|
||||
func (p *storageRecorder) SaveSnap(st raftpb.Snapshot) error {
|
||||
if !raft.IsEmptySnap(st) {
|
||||
p.record(action{name: "SaveSnap"})
|
||||
p.Record(testutil.Action{Name: "SaveSnap"})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (p *storageRecorder) Close() error { return nil }
|
||||
|
||||
type nodeRecorder struct {
|
||||
recorder
|
||||
}
|
||||
type nodeRecorder struct{ testutil.Recorder }
|
||||
|
||||
func (n *nodeRecorder) Tick() { n.record(action{name: "Tick"}) }
|
||||
func (n *nodeRecorder) Tick() { n.Record(testutil.Action{Name: "Tick"}) }
|
||||
func (n *nodeRecorder) Campaign(ctx context.Context) error {
|
||||
n.record(action{name: "Campaign"})
|
||||
n.Record(testutil.Action{Name: "Campaign"})
|
||||
return nil
|
||||
}
|
||||
func (n *nodeRecorder) Propose(ctx context.Context, data []byte) error {
|
||||
n.record(action{name: "Propose", params: []interface{}{data}})
|
||||
n.Record(testutil.Action{Name: "Propose", Params: []interface{}{data}})
|
||||
return nil
|
||||
}
|
||||
func (n *nodeRecorder) ProposeConfChange(ctx context.Context, conf raftpb.ConfChange) error {
|
||||
n.record(action{name: "ProposeConfChange"})
|
||||
n.Record(testutil.Action{Name: "ProposeConfChange"})
|
||||
return nil
|
||||
}
|
||||
func (n *nodeRecorder) Step(ctx context.Context, msg raftpb.Message) error {
|
||||
n.record(action{name: "Step"})
|
||||
n.Record(testutil.Action{Name: "Step"})
|
||||
return nil
|
||||
}
|
||||
func (n *nodeRecorder) Ready() <-chan raft.Ready { return nil }
|
||||
func (n *nodeRecorder) Advance() {}
|
||||
func (n *nodeRecorder) ApplyConfChange(conf raftpb.ConfChange) *raftpb.ConfState {
|
||||
n.record(action{name: "ApplyConfChange", params: []interface{}{conf}})
|
||||
n.Record(testutil.Action{Name: "ApplyConfChange", Params: []interface{}{conf}})
|
||||
return &raftpb.ConfState{}
|
||||
}
|
||||
func (n *nodeRecorder) Stop() {
|
||||
n.record(action{name: "Stop"})
|
||||
n.Record(testutil.Action{Name: "Stop"})
|
||||
}
|
||||
func (n *nodeRecorder) Compact(index uint64, nodes []uint64, d []byte) {
|
||||
n.record(action{name: "Compact"})
|
||||
n.Record(testutil.Action{Name: "Compact"})
|
||||
}
|
||||
|
||||
type nodeProposalBlockerRecorder struct {
|
||||
@ -1308,7 +1295,7 @@ type nodeProposalBlockerRecorder struct {
|
||||
|
||||
func (n *nodeProposalBlockerRecorder) Propose(ctx context.Context, data []byte) error {
|
||||
<-ctx.Done()
|
||||
n.record(action{name: "Propose blocked"})
|
||||
n.Record(testutil.Action{Name: "Propose blocked"})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1329,14 +1316,14 @@ func (n *nodeConfChangeCommitterRecorder) ProposeConfChange(ctx context.Context,
|
||||
}
|
||||
n.index++
|
||||
n.readyc <- raft.Ready{CommittedEntries: []raftpb.Entry{{Index: n.index, Type: raftpb.EntryConfChange, Data: data}}}
|
||||
n.record(action{name: "ProposeConfChange:" + conf.Type.String()})
|
||||
n.Record(testutil.Action{Name: "ProposeConfChange:" + conf.Type.String()})
|
||||
return nil
|
||||
}
|
||||
func (n *nodeConfChangeCommitterRecorder) Ready() <-chan raft.Ready {
|
||||
return n.readyc
|
||||
}
|
||||
func (n *nodeConfChangeCommitterRecorder) ApplyConfChange(conf raftpb.ConfChange) *raftpb.ConfState {
|
||||
n.record(action{name: "ApplyConfChange:" + conf.Type.String()})
|
||||
n.Record(testutil.Action{Name: "ApplyConfChange:" + conf.Type.String()})
|
||||
return &raftpb.ConfState{}
|
||||
}
|
||||
|
||||
|
42
pkg/testutil/recorder.go
Normal file
42
pkg/testutil/recorder.go
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2015 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 testutil
|
||||
|
||||
import "sync"
|
||||
|
||||
type Action struct {
|
||||
Name string
|
||||
Params []interface{}
|
||||
}
|
||||
|
||||
type Recorder struct {
|
||||
sync.Mutex
|
||||
actions []Action
|
||||
}
|
||||
|
||||
func (r *Recorder) Record(a Action) {
|
||||
r.Lock()
|
||||
r.actions = append(r.actions, a)
|
||||
r.Unlock()
|
||||
}
|
||||
func (r *Recorder) Action() []Action {
|
||||
r.Lock()
|
||||
cpy := make([]Action, len(r.actions))
|
||||
copy(cpy, r.actions)
|
||||
r.Unlock()
|
||||
return cpy
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user