diff --git a/etcdserver/server.go b/etcdserver/server.go index f1d64a1b4..5d1082516 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -723,7 +723,11 @@ func (s *EtcdServer) applyRequest(r pb.Request) Response { switch { case existsSet: if exists { - return f(s.store.Update(r.Path, r.Val, expr)) + if r.PrevIndex == 0 && r.PrevValue == "" { + return f(s.store.Update(r.Path, r.Val, expr)) + } else { + return f(s.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, expr)) + } } return f(s.store.Create(r.Path, r.Dir, r.Val, false, expr)) case r.PrevIndex > 0 || r.PrevValue != "": diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index 29dd90350..7318b6a25 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -235,20 +235,18 @@ func TestApplyRequest(t *testing.T) { }, }, }, - // PUT with PrevExist=true *and* PrevIndex set ==> Update - // TODO(jonboulle): is this expected?! + // PUT with PrevExist=true *and* PrevIndex set ==> CompareAndSwap { pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(true), PrevIndex: 1}, Response{Event: &store.Event{}}, []testutil.Action{ { - Name: "Update", - Params: []interface{}{"", "", time.Time{}}, + Name: "CompareAndSwap", + Params: []interface{}{"", "", uint64(1), "", time.Time{}}, }, }, }, // PUT with PrevExist=false *and* PrevIndex set ==> Create - // TODO(jonboulle): is this expected?! { pb.Request{Method: "PUT", ID: 1, PrevExist: pbutil.Boolp(false), PrevIndex: 1}, Response{Event: &store.Event{}},