diff --git a/consul/state_store.go b/consul/state_store.go index e2d0ece8f9..c65152cf69 100644 --- a/consul/state_store.go +++ b/consul/state_store.go @@ -1329,7 +1329,10 @@ func (s *StateStore) KVSDeleteCheckAndSet(index uint64, key string, casIndex uin } // Do the actual delete - return true, s.kvsDeleteWithIndex(index, "id", key) + if err := s.kvsDeleteWithIndexTxn(index, tx, "id", key); err != nil { + return false, err + } + return true, tx.Commit() } // KVSDeleteTree is used to delete all keys with a given prefix diff --git a/consul/state_store_test.go b/consul/state_store_test.go index b456c19e97..589f7b3781 100644 --- a/consul/state_store_test.go +++ b/consul/state_store_test.go @@ -1569,6 +1569,56 @@ func TestKVSDelete(t *testing.T) { } } +func TestKVSDeleteCheckAndSet(t *testing.T) { + store, err := testStateStore() + if err != nil { + t.Fatalf("err: %v", err) + } + defer store.Close() + + // CAS should fail, no entry + ok, err := store.KVSDeleteCheckAndSet(1000, "/foo", 100) + if err != nil { + t.Fatalf("err: %v", err) + } + if ok { + t.Fatalf("unexpected commit") + } + + // CAS should work, no entry + ok, err = store.KVSDeleteCheckAndSet(1000, "/foo", 0) + if err != nil { + t.Fatalf("err: %v", err) + } + if !ok { + t.Fatalf("unexpected failure") + } + + // Make an entry + d := &structs.DirEntry{Key: "/foo"} + if err := store.KVSSet(1000, d); err != nil { + t.Fatalf("err: %v", err) + } + + // Constrain on a wrong modify time + ok, err = store.KVSDeleteCheckAndSet(1001, "/foo", 42) + if err != nil { + t.Fatalf("err: %v", err) + } + if ok { + t.Fatalf("unexpected commit") + } + + // Constrain on a correct modify time + ok, err = store.KVSDeleteCheckAndSet(1002, "/foo", 1000) + if err != nil { + t.Fatalf("err: %v", err) + } + if !ok { + t.Fatalf("expected commit") + } +} + func TestKVSCheckAndSet(t *testing.T) { store, err := testStateStore() if err != nil {