mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #1620 from yichengq/204
etcdserver: not record attributes when add member
This commit is contained in:
commit
1e1535e6f9
@ -327,7 +327,8 @@ func (c *Cluster) ValidateConfigurationChange(cc raftpb.ConfChange) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMember puts a new Member into the store.
|
// AddMember adds a new Member into the cluster, and saves the given member's
|
||||||
|
// raftAttributes into the store. The given member should have empty attributes.
|
||||||
// A Member with a matching id must not exist.
|
// A Member with a matching id must not exist.
|
||||||
func (c *Cluster) AddMember(m *Member) {
|
func (c *Cluster) AddMember(m *Member) {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@ -340,14 +341,6 @@ func (c *Cluster) AddMember(m *Member) {
|
|||||||
if _, err := c.store.Create(p, false, string(b), false, store.Permanent); err != nil {
|
if _, err := c.store.Create(p, false, string(b), false, store.Permanent); err != nil {
|
||||||
log.Panicf("create raftAttributes should never fail: %v", err)
|
log.Panicf("create raftAttributes should never fail: %v", err)
|
||||||
}
|
}
|
||||||
b, err = json.Marshal(m.Attributes)
|
|
||||||
if err != nil {
|
|
||||||
log.Panicf("marshal attributes should never fail: %v", err)
|
|
||||||
}
|
|
||||||
p = path.Join(memberStoreKey(m.ID), attributesSuffix)
|
|
||||||
if _, err := c.store.Create(p, false, string(b), false, store.Permanent); err != nil {
|
|
||||||
log.Panicf("create attributes should never fail: %v", err)
|
|
||||||
}
|
|
||||||
c.members[m.ID] = m
|
c.members[m.ID] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,20 +383,26 @@ func (c *Cluster) UpdateMember(nm *Member) {
|
|||||||
// the child nodes of the given node should be sorted by key.
|
// the child nodes of the given node should be sorted by key.
|
||||||
func nodeToMember(n *store.NodeExtern) (*Member, error) {
|
func nodeToMember(n *store.NodeExtern) (*Member, error) {
|
||||||
m := &Member{ID: mustParseMemberIDFromKey(n.Key)}
|
m := &Member{ID: mustParseMemberIDFromKey(n.Key)}
|
||||||
if len(n.Nodes) != 2 {
|
attrs := make(map[string][]byte)
|
||||||
return m, fmt.Errorf("len(nodes) = %d, want 2", len(n.Nodes))
|
raftAttrKey := path.Join(n.Key, raftAttributesSuffix)
|
||||||
|
attrKey := path.Join(n.Key, attributesSuffix)
|
||||||
|
for _, nn := range n.Nodes {
|
||||||
|
if nn.Key != raftAttrKey && nn.Key != attrKey {
|
||||||
|
return nil, fmt.Errorf("unknown key %q", nn.Key)
|
||||||
|
}
|
||||||
|
attrs[nn.Key] = []byte(*nn.Value)
|
||||||
}
|
}
|
||||||
if w := path.Join(n.Key, attributesSuffix); n.Nodes[0].Key != w {
|
if data := attrs[raftAttrKey]; data != nil {
|
||||||
return m, fmt.Errorf("key = %v, want %v", n.Nodes[0].Key, w)
|
if err := json.Unmarshal(data, &m.RaftAttributes); err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshal raftAttributes error: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("raftAttributes key doesn't exist")
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal([]byte(*n.Nodes[0].Value), &m.Attributes); err != nil {
|
if data := attrs[attrKey]; data != nil {
|
||||||
return m, fmt.Errorf("unmarshal attributes error: %v", err)
|
if err := json.Unmarshal(data, &m.Attributes); err != nil {
|
||||||
}
|
return m, fmt.Errorf("unmarshal attributes error: %v", err)
|
||||||
if w := path.Join(n.Key, raftAttributesSuffix); n.Nodes[1].Key != w {
|
}
|
||||||
return m, fmt.Errorf("key = %v, want %v", n.Nodes[1].Key, w)
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal([]byte(*n.Nodes[1].Value), &m.RaftAttributes); err != nil {
|
|
||||||
return m, fmt.Errorf("unmarshal raftAttributes error: %v", err)
|
|
||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
@ -82,20 +82,21 @@ func TestClusterFromStore(t *testing.T) {
|
|||||||
mems []*Member
|
mems []*Member
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
[]*Member{newTestMember(1, nil, "node1", nil)},
|
[]*Member{newTestMember(1, nil, "", nil)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]*Member{
|
[]*Member{
|
||||||
newTestMember(1, nil, "node1", nil),
|
newTestMember(1, nil, "", nil),
|
||||||
newTestMember(2, nil, "node2", nil),
|
newTestMember(2, nil, "", nil),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
hc := newTestCluster(nil)
|
hc := newTestCluster(nil)
|
||||||
|
hc.SetStore(store.New())
|
||||||
for _, m := range tt.mems {
|
for _, m := range tt.mems {
|
||||||
hc.AddMember(m)
|
hc.AddMember(m)
|
||||||
}
|
}
|
||||||
@ -500,22 +501,22 @@ func TestNodeToMemberBad(t *testing.T) {
|
|||||||
{Key: "/1234/strange"},
|
{Key: "/1234/strange"},
|
||||||
}},
|
}},
|
||||||
{Key: "/1234", Nodes: []*store.NodeExtern{
|
{Key: "/1234", Nodes: []*store.NodeExtern{
|
||||||
{Key: "/1234/dynamic", Value: stringp("garbage")},
|
{Key: "/1234/raftAttributes", Value: stringp("garbage")},
|
||||||
}},
|
}},
|
||||||
{Key: "/1234", Nodes: []*store.NodeExtern{
|
{Key: "/1234", Nodes: []*store.NodeExtern{
|
||||||
{Key: "/1234/dynamic", Value: stringp(`{"peerURLs":null}`)},
|
{Key: "/1234/attributes", Value: stringp(`{"name":"node1","clientURLs":null}`)},
|
||||||
}},
|
}},
|
||||||
{Key: "/1234", Nodes: []*store.NodeExtern{
|
{Key: "/1234", Nodes: []*store.NodeExtern{
|
||||||
{Key: "/1234/dynamic", Value: stringp(`{"peerURLs":null}`)},
|
{Key: "/1234/raftAttributes", Value: stringp(`{"peerURLs":null}`)},
|
||||||
{Key: "/1234/strange"},
|
{Key: "/1234/strange"},
|
||||||
}},
|
}},
|
||||||
{Key: "/1234", Nodes: []*store.NodeExtern{
|
{Key: "/1234", Nodes: []*store.NodeExtern{
|
||||||
{Key: "/1234/dynamic", Value: stringp(`{"peerURLs":null}`)},
|
{Key: "/1234/raftAttributes", Value: stringp(`{"peerURLs":null}`)},
|
||||||
{Key: "/1234/static", Value: stringp("garbage")},
|
{Key: "/1234/attributes", Value: stringp("garbage")},
|
||||||
}},
|
}},
|
||||||
{Key: "/1234", Nodes: []*store.NodeExtern{
|
{Key: "/1234", Nodes: []*store.NodeExtern{
|
||||||
{Key: "/1234/dynamic", Value: stringp(`{"peerURLs":null}`)},
|
{Key: "/1234/raftAttributes", Value: stringp(`{"peerURLs":null}`)},
|
||||||
{Key: "/1234/static", Value: stringp(`{"name":"node1","clientURLs":null}`)},
|
{Key: "/1234/attributes", Value: stringp(`{"name":"node1","clientURLs":null}`)},
|
||||||
{Key: "/1234/strange"},
|
{Key: "/1234/strange"},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
@ -543,16 +544,6 @@ func TestClusterAddMember(t *testing.T) {
|
|||||||
store.Permanent,
|
store.Permanent,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Create",
|
|
||||||
params: []interface{}{
|
|
||||||
path.Join(storeMembersPrefix, "1", "attributes"),
|
|
||||||
false,
|
|
||||||
`{"name":"node1"}`,
|
|
||||||
false,
|
|
||||||
store.Permanent,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
if g := st.Action(); !reflect.DeepEqual(g, wactions) {
|
if g := st.Action(); !reflect.DeepEqual(g, wactions) {
|
||||||
t.Errorf("actions = %v, want %v", g, wactions)
|
t.Errorf("actions = %v, want %v", g, wactions)
|
||||||
@ -656,9 +647,8 @@ func TestNodeToMember(t *testing.T) {
|
|||||||
|
|
||||||
func newTestCluster(membs []*Member) *Cluster {
|
func newTestCluster(membs []*Member) *Cluster {
|
||||||
c := &Cluster{members: make(map[types.ID]*Member), removed: make(map[types.ID]bool)}
|
c := &Cluster{members: make(map[types.ID]*Member), removed: make(map[types.ID]bool)}
|
||||||
c.store = store.New()
|
for _, m := range membs {
|
||||||
for i := range membs {
|
c.members[m.ID] = m
|
||||||
c.AddMember(membs[i])
|
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -554,8 +554,8 @@ func testServer(t *testing.T, ns uint64) {
|
|||||||
|
|
||||||
g, w := resp.Event.Node, &store.NodeExtern{
|
g, w := resp.Event.Node, &store.NodeExtern{
|
||||||
Key: "/foo",
|
Key: "/foo",
|
||||||
ModifiedIndex: uint64(i) + 2*ns,
|
ModifiedIndex: uint64(i) + ns,
|
||||||
CreatedIndex: uint64(i) + 2*ns,
|
CreatedIndex: uint64(i) + ns,
|
||||||
Value: stringp("bar"),
|
Value: stringp("bar"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,7 +993,9 @@ func TestRemoveMember(t *testing.T) {
|
|||||||
Nodes: []uint64{1234, 2345, 3456},
|
Nodes: []uint64{1234, 2345, 3456},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cl := newTestCluster([]*Member{{ID: 1234}})
|
cl := newTestCluster(nil)
|
||||||
|
cl.SetStore(store.New())
|
||||||
|
cl.AddMember(&Member{ID: 1234})
|
||||||
s := &EtcdServer{
|
s := &EtcdServer{
|
||||||
node: n,
|
node: n,
|
||||||
store: &storeRecorder{},
|
store: &storeRecorder{},
|
||||||
@ -1027,7 +1029,9 @@ func TestUpdateMember(t *testing.T) {
|
|||||||
Nodes: []uint64{1234, 2345, 3456},
|
Nodes: []uint64{1234, 2345, 3456},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cl := newTestCluster([]*Member{{ID: 1234}})
|
cl := newTestCluster(nil)
|
||||||
|
cl.SetStore(store.New())
|
||||||
|
cl.AddMember(&Member{ID: 1234})
|
||||||
s := &EtcdServer{
|
s := &EtcdServer{
|
||||||
node: n,
|
node: n,
|
||||||
store: &storeRecorder{},
|
store: &storeRecorder{},
|
||||||
|
@ -55,19 +55,19 @@ func TestV2Set(t *testing.T) {
|
|||||||
"/v2/keys/foo/bar",
|
"/v2/keys/foo/bar",
|
||||||
v,
|
v,
|
||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
`{"action":"set","node":{"key":"/foo/bar","value":"bar","modifiedIndex":4,"createdIndex":4}}`,
|
`{"action":"set","node":{"key":"/foo/bar","value":"bar","modifiedIndex":3,"createdIndex":3}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"/v2/keys/foodir?dir=true",
|
"/v2/keys/foodir?dir=true",
|
||||||
url.Values{},
|
url.Values{},
|
||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
`{"action":"set","node":{"key":"/foodir","dir":true,"modifiedIndex":5,"createdIndex":5}}`,
|
`{"action":"set","node":{"key":"/foodir","dir":true,"modifiedIndex":4,"createdIndex":4}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"/v2/keys/fooempty",
|
"/v2/keys/fooempty",
|
||||||
url.Values(map[string][]string{"value": {""}}),
|
url.Values(map[string][]string{"value": {""}}),
|
||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
`{"action":"set","node":{"key":"/fooempty","value":"","modifiedIndex":6,"createdIndex":6}}`,
|
`{"action":"set","node":{"key":"/fooempty","value":"","modifiedIndex":5,"createdIndex":5}}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,12 +216,12 @@ func TestV2CAS(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"/v2/keys/cas/foo",
|
"/v2/keys/cas/foo",
|
||||||
url.Values(map[string][]string{"value": {"YYY"}, "prevIndex": {"4"}}),
|
url.Values(map[string][]string{"value": {"YYY"}, "prevIndex": {"3"}}),
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"value": "YYY",
|
"value": "YYY",
|
||||||
"modifiedIndex": float64(5),
|
"modifiedIndex": float64(4),
|
||||||
},
|
},
|
||||||
"action": "compareAndSwap",
|
"action": "compareAndSwap",
|
||||||
},
|
},
|
||||||
@ -233,8 +233,8 @@ func TestV2CAS(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"errorCode": float64(101),
|
"errorCode": float64(101),
|
||||||
"message": "Compare failed",
|
"message": "Compare failed",
|
||||||
"cause": "[10 != 5]",
|
"cause": "[10 != 4]",
|
||||||
"index": float64(5),
|
"index": float64(4),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -283,7 +283,7 @@ func TestV2CAS(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"errorCode": float64(101),
|
"errorCode": float64(101),
|
||||||
"message": "Compare failed",
|
"message": "Compare failed",
|
||||||
"cause": "[bad_value != ZZZ] [100 != 6]",
|
"cause": "[bad_value != ZZZ] [100 != 5]",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -293,12 +293,12 @@ func TestV2CAS(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"errorCode": float64(101),
|
"errorCode": float64(101),
|
||||||
"message": "Compare failed",
|
"message": "Compare failed",
|
||||||
"cause": "[100 != 6]",
|
"cause": "[100 != 5]",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"/v2/keys/cas/foo",
|
"/v2/keys/cas/foo",
|
||||||
url.Values(map[string][]string{"value": {"XXX"}, "prevValue": {"bad_value"}, "prevIndex": {"6"}}),
|
url.Values(map[string][]string{"value": {"XXX"}, "prevValue": {"bad_value"}, "prevIndex": {"5"}}),
|
||||||
http.StatusPreconditionFailed,
|
http.StatusPreconditionFailed,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"errorCode": float64(101),
|
"errorCode": float64(101),
|
||||||
@ -448,7 +448,7 @@ func TestV2CAD(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"errorCode": float64(101),
|
"errorCode": float64(101),
|
||||||
"message": "Compare failed",
|
"message": "Compare failed",
|
||||||
"cause": "[100 != 4]",
|
"cause": "[100 != 3]",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -460,12 +460,12 @@ func TestV2CAD(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"/v2/keys/foo?prevIndex=4",
|
"/v2/keys/foo?prevIndex=3",
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foo",
|
"key": "/foo",
|
||||||
"modifiedIndex": float64(6),
|
"modifiedIndex": float64(5),
|
||||||
},
|
},
|
||||||
"action": "compareAndDelete",
|
"action": "compareAndDelete",
|
||||||
},
|
},
|
||||||
@ -493,7 +493,7 @@ func TestV2CAD(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foovalue",
|
"key": "/foovalue",
|
||||||
"modifiedIndex": float64(7),
|
"modifiedIndex": float64(6),
|
||||||
},
|
},
|
||||||
"action": "compareAndDelete",
|
"action": "compareAndDelete",
|
||||||
},
|
},
|
||||||
@ -531,7 +531,7 @@ func TestV2Unique(t *testing.T) {
|
|||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foo/4",
|
"key": "/foo/3",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
},
|
},
|
||||||
"action": "create",
|
"action": "create",
|
||||||
@ -543,7 +543,7 @@ func TestV2Unique(t *testing.T) {
|
|||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foo/5",
|
"key": "/foo/4",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
},
|
},
|
||||||
"action": "create",
|
"action": "create",
|
||||||
@ -555,7 +555,7 @@ func TestV2Unique(t *testing.T) {
|
|||||||
http.StatusCreated,
|
http.StatusCreated,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/bar/6",
|
"key": "/bar/5",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
},
|
},
|
||||||
"action": "create",
|
"action": "create",
|
||||||
@ -617,8 +617,8 @@ func TestV2Get(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"dir": true,
|
"dir": true,
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -636,14 +636,14 @@ func TestV2Get(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"dir": true,
|
"dir": true,
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
"nodes": []interface{}{
|
"nodes": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar/zar",
|
"key": "/foo/bar/zar",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -711,8 +711,8 @@ func TestV2QuorumGet(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"dir": true,
|
"dir": true,
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -730,14 +730,14 @@ func TestV2QuorumGet(t *testing.T) {
|
|||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"dir": true,
|
"dir": true,
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
"nodes": []interface{}{
|
"nodes": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": "/foo/bar/zar",
|
"key": "/foo/bar/zar",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
"createdIndex": float64(4),
|
"createdIndex": float64(3),
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -797,7 +797,7 @@ func TestV2Watch(t *testing.T) {
|
|||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
"modifiedIndex": float64(4),
|
"modifiedIndex": float64(3),
|
||||||
},
|
},
|
||||||
"action": "set",
|
"action": "set",
|
||||||
}
|
}
|
||||||
@ -818,7 +818,7 @@ func TestV2WatchWithIndex(t *testing.T) {
|
|||||||
var body map[string]interface{}
|
var body map[string]interface{}
|
||||||
c := make(chan bool, 1)
|
c := make(chan bool, 1)
|
||||||
go func() {
|
go func() {
|
||||||
resp, _ := tc.Get(fmt.Sprintf("%s%s", u, "/v2/keys/foo/bar?wait=true&waitIndex=5"))
|
resp, _ := tc.Get(fmt.Sprintf("%s%s", u, "/v2/keys/foo/bar?wait=true&waitIndex=4"))
|
||||||
body = tc.ReadBodyJSON(resp)
|
body = tc.ReadBodyJSON(resp)
|
||||||
c <- true
|
c <- true
|
||||||
}()
|
}()
|
||||||
@ -855,7 +855,7 @@ func TestV2WatchWithIndex(t *testing.T) {
|
|||||||
"node": map[string]interface{}{
|
"node": map[string]interface{}{
|
||||||
"key": "/foo/bar",
|
"key": "/foo/bar",
|
||||||
"value": "XXX",
|
"value": "XXX",
|
||||||
"modifiedIndex": float64(5),
|
"modifiedIndex": float64(4),
|
||||||
},
|
},
|
||||||
"action": "set",
|
"action": "set",
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user