github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/v1/tests/put_handler_test.go (about) 1 package v1 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "testing" 8 "time" 9 10 "github.com/coreos/etcd/server" 11 "github.com/coreos/etcd/tests" 12 "github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert" 13 ) 14 15 // Ensures that a key is set to a given value. 16 // 17 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX 18 // 19 func TestV1SetKey(t *testing.T) { 20 tests.RunServer(func(s *server.Server) { 21 v := url.Values{} 22 v.Set("value", "XXX") 23 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v) 24 assert.Equal(t, resp.StatusCode, http.StatusOK) 25 body := tests.ReadBody(resp) 26 assert.Nil(t, err, "") 27 28 assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","newKey":true,"index":2}`, "") 29 }) 30 } 31 32 // Ensures that a time-to-live is added to a key. 33 // 34 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d ttl=20 35 // 36 func TestV1SetKeyWithTTL(t *testing.T) { 37 tests.RunServer(func(s *server.Server) { 38 t0 := time.Now() 39 v := url.Values{} 40 v.Set("value", "XXX") 41 v.Set("ttl", "20") 42 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v) 43 assert.Equal(t, resp.StatusCode, http.StatusOK) 44 body := tests.ReadBodyJSON(resp) 45 assert.Equal(t, body["ttl"], 20, "") 46 47 // Make sure the expiration date is correct. 48 expiration, _ := time.Parse(time.RFC3339Nano, body["expiration"].(string)) 49 assert.Equal(t, expiration.Sub(t0)/time.Second, 20, "") 50 }) 51 } 52 53 // Ensures that an invalid time-to-live is returned as an error. 54 // 55 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d ttl=bad_ttl 56 // 57 func TestV1SetKeyWithBadTTL(t *testing.T) { 58 tests.RunServer(func(s *server.Server) { 59 v := url.Values{} 60 v.Set("value", "XXX") 61 v.Set("ttl", "bad_ttl") 62 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v) 63 assert.Equal(t, resp.StatusCode, http.StatusBadRequest) 64 body := tests.ReadBodyJSON(resp) 65 assert.Equal(t, body["errorCode"], 202, "") 66 assert.Equal(t, body["message"], "The given TTL in POST form is not a number", "") 67 assert.Equal(t, body["cause"], "Set", "") 68 }) 69 } 70 71 // Ensures that a key is conditionally set if it previously did not exist. 72 // 73 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue= 74 // 75 func TestV1CreateKeySuccess(t *testing.T) { 76 tests.RunServer(func(s *server.Server) { 77 v := url.Values{} 78 v.Set("value", "XXX") 79 v.Set("prevValue", "") 80 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v) 81 assert.Equal(t, resp.StatusCode, http.StatusOK) 82 body := tests.ReadBodyJSON(resp) 83 assert.Equal(t, body["value"], "XXX", "") 84 }) 85 } 86 87 // Ensures that a key is not conditionally set because it previously existed. 88 // 89 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue= 90 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue= -> fail 91 // 92 func TestV1CreateKeyFail(t *testing.T) { 93 tests.RunServer(func(s *server.Server) { 94 v := url.Values{} 95 v.Set("value", "XXX") 96 v.Set("prevValue", "") 97 fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar") 98 resp, _ := tests.PutForm(fullURL, v) 99 assert.Equal(t, resp.StatusCode, http.StatusOK) 100 tests.ReadBody(resp) 101 resp, _ = tests.PutForm(fullURL, v) 102 assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed) 103 body := tests.ReadBodyJSON(resp) 104 assert.Equal(t, body["errorCode"], 105, "") 105 assert.Equal(t, body["message"], "Key already exists", "") 106 assert.Equal(t, body["cause"], "/foo/bar", "") 107 }) 108 } 109 110 // Ensures that a key is set only if the previous value matches. 111 // 112 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX 113 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=YYY -d prevValue=XXX 114 // 115 func TestV1SetKeyCASOnValueSuccess(t *testing.T) { 116 tests.RunServer(func(s *server.Server) { 117 v := url.Values{} 118 v.Set("value", "XXX") 119 fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar") 120 resp, _ := tests.PutForm(fullURL, v) 121 assert.Equal(t, resp.StatusCode, http.StatusOK) 122 tests.ReadBody(resp) 123 v.Set("value", "YYY") 124 v.Set("prevValue", "XXX") 125 resp, _ = tests.PutForm(fullURL, v) 126 assert.Equal(t, resp.StatusCode, http.StatusOK) 127 body := tests.ReadBodyJSON(resp) 128 assert.Equal(t, body["action"], "testAndSet", "") 129 assert.Equal(t, body["value"], "YYY", "") 130 assert.Equal(t, body["index"], 3, "") 131 }) 132 } 133 134 // Ensures that a key is not set if the previous value does not match. 135 // 136 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX 137 // $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=YYY -d prevValue=AAA 138 // 139 func TestV1SetKeyCASOnValueFail(t *testing.T) { 140 tests.RunServer(func(s *server.Server) { 141 v := url.Values{} 142 v.Set("value", "XXX") 143 fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar") 144 resp, _ := tests.PutForm(fullURL, v) 145 assert.Equal(t, resp.StatusCode, http.StatusOK) 146 tests.ReadBody(resp) 147 v.Set("value", "YYY") 148 v.Set("prevValue", "AAA") 149 resp, _ = tests.PutForm(fullURL, v) 150 assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed) 151 body := tests.ReadBodyJSON(resp) 152 assert.Equal(t, body["errorCode"], 101, "") 153 assert.Equal(t, body["message"], "Compare failed", "") 154 assert.Equal(t, body["cause"], "[AAA != XXX]", "") 155 assert.Equal(t, body["index"], 2, "") 156 }) 157 }