github.com/macb/etcd@v0.3.1-0.20140227003422-a60481c6b1a0/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 body map[string]interface{} 94 c := make(chan bool) 95 go func() { 96 resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true")) 97 body = tests.ReadBodyJSON(resp) 98 c <- true 99 }() 100 101 // Make sure response didn't fire early. 102 time.Sleep(1 * time.Millisecond) 103 assert.Nil(t, body, "") 104 105 // Set a value. 106 v := url.Values{} 107 v.Set("value", "XXX") 108 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 109 tests.ReadBody(resp) 110 111 // A response should follow from the GET above. 112 time.Sleep(1 * time.Millisecond) 113 114 select { 115 case <-c: 116 117 default: 118 t.Fatal("cannot get watch result") 119 } 120 121 assert.NotNil(t, body, "") 122 assert.Equal(t, body["action"], "set", "") 123 124 node := body["node"].(map[string]interface{}) 125 assert.Equal(t, node["key"], "/foo/bar", "") 126 assert.Equal(t, node["value"], "XXX", "") 127 assert.Equal(t, node["modifiedIndex"], 2, "") 128 }) 129 } 130 131 // Ensures that a watcher can wait for a value to be set after a given index. 132 // 133 // $ curl localhost:4001/v2/keys/foo/bar?wait=true&waitIndex=4 134 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX 135 // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=YYY 136 // 137 func TestV2WatchKeyWithIndex(t *testing.T) { 138 tests.RunServer(func(s *server.Server) { 139 var body map[string]interface{} 140 c := make(chan bool) 141 go func() { 142 resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true&waitIndex=3")) 143 body = tests.ReadBodyJSON(resp) 144 c <- true 145 }() 146 147 // Make sure response didn't fire early. 148 time.Sleep(1 * time.Millisecond) 149 assert.Nil(t, body, "") 150 151 // Set a value (before given index). 152 v := url.Values{} 153 v.Set("value", "XXX") 154 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 155 tests.ReadBody(resp) 156 157 // Make sure response didn't fire early. 158 time.Sleep(1 * time.Millisecond) 159 assert.Nil(t, body, "") 160 161 // Set a value (before given index). 162 v.Set("value", "YYY") 163 resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v) 164 tests.ReadBody(resp) 165 166 // A response should follow from the GET above. 167 time.Sleep(1 * time.Millisecond) 168 169 select { 170 case <-c: 171 172 default: 173 t.Fatal("cannot get watch result") 174 } 175 176 assert.NotNil(t, body, "") 177 assert.Equal(t, body["action"], "set", "") 178 179 node := body["node"].(map[string]interface{}) 180 assert.Equal(t, node["key"], "/foo/bar", "") 181 assert.Equal(t, node["value"], "YYY", "") 182 assert.Equal(t, node["modifiedIndex"], 3, "") 183 }) 184 } 185 186 // Ensures that a watcher can wait for a value to be set after a given index. 187 // 188 // $ curl localhost:4001/v2/keys/keyindir/bar?wait=true 189 // $ curl -X PUT localhost:4001/v2/keys/keyindir -d dir=true -d ttl=1 190 // $ curl -X PUT localhost:4001/v2/keys/keyindir/bar -d value=YYY 191 // 192 func TestV2WatchKeyInDir(t *testing.T) { 193 tests.RunServer(func(s *server.Server) { 194 var body map[string]interface{} 195 c := make(chan bool) 196 197 // Set a value (before given index). 198 v := url.Values{} 199 v.Set("dir", "true") 200 v.Set("ttl", "1") 201 resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir"), v) 202 tests.ReadBody(resp) 203 204 // Set a value (before given index). 205 v = url.Values{} 206 v.Set("value", "XXX") 207 resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir/bar"), v) 208 tests.ReadBody(resp) 209 210 go func() { 211 resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/keyindir/bar?wait=true")) 212 body = tests.ReadBodyJSON(resp) 213 c <- true 214 }() 215 216 // wait for expiration, we do have a up to 500 millisecond delay 217 time.Sleep(2000 * time.Millisecond) 218 219 select { 220 case <-c: 221 222 default: 223 t.Fatal("cannot get watch result") 224 } 225 226 assert.NotNil(t, body, "") 227 assert.Equal(t, body["action"], "expire", "") 228 229 node := body["node"].(map[string]interface{}) 230 assert.Equal(t, node["key"], "/keyindir", "") 231 }) 232 }