github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/v2/tests/get_handler_test.go (about) 1 package v2 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 value can be retrieve for a given key. 16 // 17 // $ curl localhost:4001/v2/keys/foo/bar -> fail 18 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 19 // $ curl localhost:4001/v2/keys/foo/bar 20 // 21 func TestV2GetKey(t *testing.T) { 22 tests.RunServer(func(s *server.Server) { 23 v := url.Values{} 24 v.Set("value", "XXX") 25 fullURL := fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar") 26 resp, _ := tests.Get(fullURL) 27 assert.Equal(t, resp.StatusCode, http.StatusNotFound) 28 29 resp, _ = tests.PutForm(fullURL, v) 30 tests.ReadBody(resp) 31 32 resp, _ = tests.Get(fullURL) 33 assert.Equal(t, resp.StatusCode, http.StatusOK) 34 body := tests.ReadBodyJSON(resp) 35 assert.Equal(t, body["action"], "get", "") 36 node := body["node"].(map[string]interface{}) 37 assert.Equal(t, node["key"], "/foo/bar", "") 38 assert.Equal(t, node["value"], "XXX", "") 39 assert.Equal(t, node["modifiedIndex"], 2, "") 40 }) 41 } 42 43 // Ensures that a directory of values can be recursively retrieved for a given key. 44 // 45 // $ curl -X PUT localhost:4001/v2/keys/foo/x -d value=XXX 46 // $ curl -X PUT localhost:4001/v2/keys/foo/y/z -d value=YYY 47 // $ curl localhost:4001/v2/keys/foo -d recursive=true 48 // 49 func TestV2GetKeyRecursively(t *testing.T) { 50 tests.RunServer(func(s *server.Server) { 51 v := url.Values{} 52 v.Set("value", "XXX") 53 v.Set("ttl", "10") 54 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/x"), v) 55 tests.ReadBody(resp) 56 57 v.Set("value", "YYY") 58 resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/y/z"), v) 59 tests.ReadBody(resp) 60 61 resp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?recursive=true")) 62 assert.Equal(t, resp.StatusCode, http.StatusOK) 63 body := tests.ReadBodyJSON(resp) 64 assert.Equal(t, body["action"], "get", "") 65 node := body["node"].(map[string]interface{}) 66 assert.Equal(t, node["key"], "/foo", "") 67 assert.Equal(t, node["dir"], true, "") 68 assert.Equal(t, node["modifiedIndex"], 2, "") 69 assert.Equal(t, len(node["nodes"].([]interface{})), 2, "") 70 71 node0 := node["nodes"].([]interface{})[0].(map[string]interface{}) 72 assert.Equal(t, node0["key"], "/foo/x", "") 73 assert.Equal(t, node0["value"], "XXX", "") 74 assert.Equal(t, node0["ttl"], 10, "") 75 76 node1 := node["nodes"].([]interface{})[1].(map[string]interface{}) 77 assert.Equal(t, node1["key"], "/foo/y", "") 78 assert.Equal(t, node1["dir"], true, "") 79 80 node2 := node1["nodes"].([]interface{})[0].(map[string]interface{}) 81 assert.Equal(t, node2["key"], "/foo/y/z", "") 82 assert.Equal(t, node2["value"], "YYY", "") 83 }) 84 } 85 86 // Ensures that a watcher can wait for a value to be set and return it to the client. 87 // 88 // $ curl localhost:4001/v2/keys/foo/bar?wait=true 89 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 90 // 91 func TestV2WatchKey(t *testing.T) { 92 tests.RunServer(func(s *server.Server) { 93 var watchResp *http.Response 94 c := make(chan bool) 95 go func() { 96 watchResp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true")) 97 c <- true 98 }() 99 100 // Make sure response didn't fire early. 101 time.Sleep(1 * time.Millisecond) 102 103 // Set a value. 104 v := url.Values{} 105 v.Set("value", "XXX") 106 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 107 tests.ReadBody(resp) 108 109 // A response should follow from the GET above. 110 time.Sleep(1 * time.Millisecond) 111 112 select { 113 case <-c: 114 115 default: 116 t.Fatal("cannot get watch result") 117 } 118 119 body := tests.ReadBodyJSON(watchResp) 120 assert.NotNil(t, body, "") 121 assert.Equal(t, body["action"], "set", "") 122 123 node := body["node"].(map[string]interface{}) 124 assert.Equal(t, node["key"], "/foo/bar", "") 125 assert.Equal(t, node["value"], "XXX", "") 126 assert.Equal(t, node["modifiedIndex"], 2, "") 127 }) 128 } 129 130 // Ensures that a watcher can wait for a value to be set after a given index. 131 // 132 // $ curl localhost:4001/v2/keys/foo/bar?wait=true&waitIndex=4 133 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 134 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=YYY 135 // 136 func TestV2WatchKeyWithIndex(t *testing.T) { 137 tests.RunServer(func(s *server.Server) { 138 var body map[string]interface{} 139 c := make(chan bool) 140 go func() { 141 resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true&waitIndex=3")) 142 body = tests.ReadBodyJSON(resp) 143 c <- true 144 }() 145 146 // Make sure response didn't fire early. 147 time.Sleep(1 * time.Millisecond) 148 assert.Nil(t, body, "") 149 150 // Set a value (before given index). 151 v := url.Values{} 152 v.Set("value", "XXX") 153 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 154 tests.ReadBody(resp) 155 156 // Make sure response didn't fire early. 157 time.Sleep(1 * time.Millisecond) 158 assert.Nil(t, body, "") 159 160 // Set a value (before given index). 161 v.Set("value", "YYY") 162 resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 163 tests.ReadBody(resp) 164 165 // A response should follow from the GET above. 166 time.Sleep(1 * time.Millisecond) 167 168 select { 169 case <-c: 170 171 default: 172 t.Fatal("cannot get watch result") 173 } 174 175 assert.NotNil(t, body, "") 176 assert.Equal(t, body["action"], "set", "") 177 178 node := body["node"].(map[string]interface{}) 179 assert.Equal(t, node["key"], "/foo/bar", "") 180 assert.Equal(t, node["value"], "YYY", "") 181 assert.Equal(t, node["modifiedIndex"], 3, "") 182 }) 183 } 184 185 // Ensures that a watcher can wait for a value to be set after a given index. 186 // 187 // $ curl localhost:4001/v2/keys/keyindir/bar?wait=true 188 // $ curl -X PUT localhost:4001/v2/keys/keyindir -d dir=true -d ttl=1 189 // $ curl -X PUT localhost:4001/v2/keys/keyindir/bar -d value=YYY 190 // 191 func TestV2WatchKeyInDir(t *testing.T) { 192 tests.RunServer(func(s *server.Server) { 193 var body map[string]interface{} 194 c := make(chan bool) 195 196 // Set a value (before given index). 197 v := url.Values{} 198 v.Set("dir", "true") 199 v.Set("ttl", "1") 200 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir"), v) 201 tests.ReadBody(resp) 202 203 // Set a value (before given index). 204 v = url.Values{} 205 v.Set("value", "XXX") 206 resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir/bar"), v) 207 tests.ReadBody(resp) 208 209 go func() { 210 resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir/bar?wait=true")) 211 body = tests.ReadBodyJSON(resp) 212 c <- true 213 }() 214 215 // wait for expiration, we do have a up to 500 millisecond delay 216 time.Sleep(2000 * time.Millisecond) 217 218 select { 219 case <-c: 220 221 default: 222 t.Fatal("cannot get watch result") 223 } 224 225 assert.NotNil(t, body, "") 226 assert.Equal(t, body["action"], "expire", "") 227 228 node := body["node"].(map[string]interface{}) 229 assert.Equal(t, node["key"], "/keyindir", "") 230 }) 231 } 232 233 // Ensures that HEAD could work. 234 // 235 // $ curl -I localhost:4001/v2/keys/foo/bar -> fail 236 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 237 // $ curl -I localhost:4001/v2/keys/foo/bar 238 // 239 func TestV2HeadKey(t *testing.T) { 240 tests.RunServer(func(s *server.Server) { 241 v := url.Values{} 242 v.Set("value", "XXX") 243 fullURL := fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar") 244 resp, _ := tests.Head(fullURL) 245 assert.Equal(t, resp.StatusCode, http.StatusNotFound) 246 assert.Equal(t, resp.ContentLength, -1) 247 248 resp, _ = tests.PutForm(fullURL, v) 249 tests.ReadBody(resp) 250 251 resp, _ = tests.Head(fullURL) 252 assert.Equal(t, resp.StatusCode, http.StatusOK) 253 assert.Equal(t, resp.ContentLength, -1) 254 }) 255 }