github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/v2/tests/delete_handler_test.go (about) 1 package v2 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "testing" 8 9 "github.com/coreos/etcd/server" 10 "github.com/coreos/etcd/tests" 11 "github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert" 12 ) 13 14 // Ensures that a key is deleted. 15 // 16 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 17 // $ curl -X DELETE localhost:4001/v2/keys/foo/bar 18 // 19 func TestV2DeleteKey(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(), "/v2/keys/foo/bar"), v) 24 tests.ReadBody(resp) 25 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), url.Values{}) 26 assert.Equal(t, resp.StatusCode, http.StatusOK) 27 body := tests.ReadBody(resp) 28 assert.Nil(t, err, "") 29 assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo/bar","value":"XXX","modifiedIndex":2,"createdIndex":2}}`, "") 30 }) 31 } 32 33 // Ensures that an empty directory is deleted when dir is set. 34 // 35 // $ curl -X PUT localhost:4001/v2/keys/foo?dir=true 36 // $ curl -X DELETE localhost:4001/v2/keys/foo ->fail 37 // $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true 38 // 39 func TestV2DeleteEmptyDirectory(t *testing.T) { 40 tests.RunServer(func(s *server.Server) { 41 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{}) 42 tests.ReadBody(resp) 43 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), url.Values{}) 44 assert.Equal(t, resp.StatusCode, http.StatusForbidden) 45 bodyJson := tests.ReadBodyJSON(resp) 46 assert.Equal(t, bodyJson["errorCode"], 102, "") 47 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{}) 48 assert.Equal(t, resp.StatusCode, http.StatusOK) 49 body := tests.ReadBody(resp) 50 assert.Nil(t, err, "") 51 assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "") 52 }) 53 } 54 55 // Ensures that a not-empty directory is deleted when dir is set. 56 // 57 // $ curl -X PUT localhost:4001/v2/keys/foo/bar?dir=true 58 // $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true ->fail 59 // $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true&recursive=true 60 // 61 func TestV2DeleteNonEmptyDirectory(t *testing.T) { 62 tests.RunServer(func(s *server.Server) { 63 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?dir=true"), url.Values{}) 64 tests.ReadBody(resp) 65 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{}) 66 assert.Equal(t, resp.StatusCode, http.StatusForbidden) 67 bodyJson := tests.ReadBodyJSON(resp) 68 assert.Equal(t, bodyJson["errorCode"], 108, "") 69 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true&recursive=true"), url.Values{}) 70 assert.Equal(t, resp.StatusCode, http.StatusOK) 71 body := tests.ReadBody(resp) 72 assert.Nil(t, err, "") 73 assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "") 74 }) 75 } 76 77 // Ensures that a directory is deleted when recursive is set. 78 // 79 // $ curl -X PUT localhost:4001/v2/keys/foo?dir=true 80 // $ curl -X DELETE localhost:4001/v2/keys/foo?recursive=true 81 // 82 func TestV2DeleteDirectoryRecursiveImpliesDir(t *testing.T) { 83 tests.RunServer(func(s *server.Server) { 84 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{}) 85 tests.ReadBody(resp) 86 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?recursive=true"), url.Values{}) 87 assert.Equal(t, resp.StatusCode, http.StatusOK) 88 body := tests.ReadBody(resp) 89 assert.Nil(t, err, "") 90 assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "") 91 }) 92 } 93 94 // Ensures that a key is deleted if the previous index matches 95 // 96 // $ curl -X PUT localhost:4001/v2/keys/foo -d value=XXX 97 // $ curl -X DELETE localhost:4001/v2/keys/foo?prevIndex=2 98 // 99 func TestV2DeleteKeyCADOnIndexSuccess(t *testing.T) { 100 tests.RunServer(func(s *server.Server) { 101 v := url.Values{} 102 v.Set("value", "XXX") 103 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), v) 104 tests.ReadBody(resp) 105 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?prevIndex=2"), url.Values{}) 106 assert.Nil(t, err, "") 107 body := tests.ReadBodyJSON(resp) 108 assert.Equal(t, body["action"], "compareAndDelete", "") 109 110 node := body["node"].(map[string]interface{}) 111 assert.Equal(t, node["key"], "/foo", "") 112 assert.Equal(t, node["modifiedIndex"], 3, "") 113 }) 114 } 115 116 // Ensures that a key is not deleted if the previous index does not match 117 // 118 // $ curl -X PUT localhost:4001/v2/keys/foo -d value=XXX 119 // $ curl -X DELETE localhost:4001/v2/keys/foo?prevIndex=100 120 // 121 func TestV2DeleteKeyCADOnIndexFail(t *testing.T) { 122 tests.RunServer(func(s *server.Server) { 123 v := url.Values{} 124 v.Set("value", "XXX") 125 resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), v) 126 tests.ReadBody(resp) 127 resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?prevIndex=100"), url.Values{}) 128 assert.Nil(t, err, "") 129 body := tests.ReadBodyJSON(resp) 130 assert.Equal(t, body["errorCode"], 101) 131 }) 132 } 133 134 // Ensures that an error is thrown if an invalid previous index is provided. 135 // 136 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 137 // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex=bad_index 138 // 139 func TestV2DeleteKeyCADWithInvalidIndex(t *testing.T) { 140 tests.RunServer(func(s *server.Server) { 141 v := url.Values{} 142 v.Set("value", "XXX") 143 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 144 tests.ReadBody(resp) 145 resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevIndex=bad_index"), v) 146 body := tests.ReadBodyJSON(resp) 147 assert.Equal(t, body["errorCode"], 203) 148 }) 149 } 150 151 // Ensures that a key is deleted only if the previous value matches. 152 // 153 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 154 // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=XXX 155 // 156 func TestV2DeleteKeyCADOnValueSuccess(t *testing.T) { 157 tests.RunServer(func(s *server.Server) { 158 v := url.Values{} 159 v.Set("value", "XXX") 160 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 161 tests.ReadBody(resp) 162 resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue=XXX"), v) 163 body := tests.ReadBodyJSON(resp) 164 assert.Equal(t, body["action"], "compareAndDelete", "") 165 166 node := body["node"].(map[string]interface{}) 167 assert.Equal(t, node["modifiedIndex"], 3, "") 168 }) 169 } 170 171 // Ensures that a key is not deleted if the previous value does not match. 172 // 173 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 174 // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=YYY 175 // 176 func TestV2DeleteKeyCADOnValueFail(t *testing.T) { 177 tests.RunServer(func(s *server.Server) { 178 v := url.Values{} 179 v.Set("value", "XXX") 180 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 181 tests.ReadBody(resp) 182 resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue=YYY"), v) 183 body := tests.ReadBodyJSON(resp) 184 assert.Equal(t, body["errorCode"], 101) 185 }) 186 } 187 188 // Ensures that an error is thrown if an invalid previous value is provided. 189 // 190 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 191 // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex= 192 // 193 func TestV2DeleteKeyCADWithInvalidValue(t *testing.T) { 194 tests.RunServer(func(s *server.Server) { 195 v := url.Values{} 196 v.Set("value", "XXX") 197 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 198 tests.ReadBody(resp) 199 resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue="), v) 200 body := tests.ReadBodyJSON(resp) 201 assert.Equal(t, body["errorCode"], 201) 202 }) 203 }