coreos/etcd — pull request #159 by hayesgm (2013-09-06 04:20:38+00:00)
Title: Blank prevValue should be TestAndSet with blank prevValue, not Set

When calling `test-and-set` with a blank `prevValue`, currently this is interpreted as a `set` (since the code checks `len(prevValue)` to differentiate `set` from `test-and-set`). This makes it difficult to run: "set a key value if key is blank or undefined." This case is extremely useful in building a simple distributed lock with timeouts.

This patch will check for the presence of `prevValue` and, if present, call `TestAndSet` instead of `Set`. This could affect current usage if clients are posting blank `prevValue` and expecting a `set` command, but I wouldn't imagine that was ever expected behavior.

## Pre-patch

> curl -L http://localhost:4001/v1/keys/mylock -d prevValue= -d value=1 -d ttl=20
{"action":"SET","key":"/mylock","value":"1","newKey":true,"expiration":"2013-09-05T21:17:31.463080924-07:00","ttl":19,"index":3}

> curl -L http://localhost:4001/v1/keys/mylock -d prevValue= -d value=1 -d ttl=20
{"action":"SET","key":"/mylock","prevValue":"1","value":"1","expiration":"2013-09-05T21:17:40.547865333-07:00","ttl":19,"index":13}

## Post-patch

> curl -L http://localhost:4001/v1/keys/mylock -d prevValue= -d value=1 -d ttl=20
{"action":"SET","key":"/mylock","value":"1","newKey":true,"expiration":"2013-09-05T21:18:17.516966308-07:00","ttl":19,"index":6}

> curl -L http://localhost:4001/v1/keys/mylock -d prevValue= -d value=1 -d ttl=20
{"errorCode":101,"message":"The given PrevValue is not equal to the value of the key","cause":"TestAndSet: 1!="}