etcd/server/v1/tests/get_handler_test.go
Yicheng Qin df2b565397 fix(test/server): avoid watch test timeout by moving json decode
These tests were timing out because the combination of the GET and JSON
decode was taking longer than the timeout. Pull the JSON decode out of
the go routine that is being timed.
2014-03-18 08:49:14 -07:00

179 lines
4.9 KiB
Go

package v1
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"testing"
"time"
"github.com/coreos/etcd/server"
"github.com/coreos/etcd/tests"
"github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert"
)
// Ensures that a value can be retrieve for a given key.
//
// $ curl localhost:4001/v1/keys/foo/bar -> fail
// $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
// $ curl localhost:4001/v1/keys/foo/bar
//
func TestV1GetKey(t *testing.T) {
tests.RunServer(func(s *server.Server) {
v := url.Values{}
v.Set("value", "XXX")
fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar")
resp, _ := tests.Get(fullURL)
assert.Equal(t, resp.StatusCode, http.StatusNotFound)
resp, _ = tests.PutForm(fullURL, v)
tests.ReadBody(resp)
resp, _ = tests.Get(fullURL)
assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["action"], "get", "")
assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "XXX", "")
assert.Equal(t, body["index"], 2, "")
})
}
// Ensures that a directory of values can be retrieved for a given key.
//
// $ curl -X PUT localhost:4001/v1/keys/foo/x -d value=XXX
// $ curl -X PUT localhost:4001/v1/keys/foo/y/z -d value=YYY
// $ curl localhost:4001/v1/keys/foo
//
func TestV1GetKeyDir(t *testing.T) {
tests.RunServer(func(s *server.Server) {
v := url.Values{}
v.Set("value", "XXX")
resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/x"), v)
tests.ReadBody(resp)
v.Set("value", "YYY")
resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/y/z"), v)
tests.ReadBody(resp)
resp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo"))
assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBody(resp)
nodes := make([]interface{}, 0)
if err := json.Unmarshal(body, &nodes); err != nil {
panic(fmt.Sprintf("HTTP body JSON parse error: %v", err))
}
assert.Equal(t, len(nodes), 2, "")
node0 := nodes[0].(map[string]interface{})
assert.Equal(t, node0["action"], "get", "")
assert.Equal(t, node0["key"], "/foo/x", "")
assert.Equal(t, node0["value"], "XXX", "")
node1 := nodes[1].(map[string]interface{})
assert.Equal(t, node1["action"], "get", "")
assert.Equal(t, node1["key"], "/foo/y", "")
assert.Equal(t, node1["dir"], true, "")
})
}
// Ensures that a watcher can wait for a value to be set and return it to the client.
//
// $ curl localhost:4001/v1/watch/foo/bar
// $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
//
func TestV1WatchKey(t *testing.T) {
tests.RunServer(func(s *server.Server) {
var watchResp *http.Response
c := make(chan bool)
go func() {
watchResp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v1/watch/foo/bar"))
c <- true
}()
// Make sure response didn't fire early.
time.Sleep(1 * time.Millisecond)
// Set a value.
v := url.Values{}
v.Set("value", "XXX")
resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
tests.ReadBody(resp)
// A response should follow from the GET above.
time.Sleep(1 * time.Millisecond)
select {
case <-c:
default:
t.Fatal("cannot get watch result")
}
body := tests.ReadBodyJSON(watchResp)
assert.NotNil(t, body, "")
assert.Equal(t, body["action"], "set", "")
assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "XXX", "")
assert.Equal(t, body["index"], 2, "")
})
}
// Ensures that a watcher can wait for a value to be set after a given index.
//
// $ curl -X POST localhost:4001/v1/watch/foo/bar -d index=4
// $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
// $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=YYY
//
func TestV1WatchKeyWithIndex(t *testing.T) {
tests.RunServer(func(s *server.Server) {
var body map[string]interface{}
c := make(chan bool)
go func() {
v := url.Values{}
v.Set("index", "3")
resp, _ := tests.PostForm(fmt.Sprintf("%s%s", s.URL(), "/v1/watch/foo/bar"), v)
body = tests.ReadBodyJSON(resp)
c <- true
}()
// Make sure response didn't fire early.
time.Sleep(1 * time.Millisecond)
assert.Nil(t, body, "")
// Set a value (before given index).
v := url.Values{}
v.Set("value", "XXX")
resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
tests.ReadBody(resp)
// Make sure response didn't fire early.
time.Sleep(1 * time.Millisecond)
assert.Nil(t, body, "")
// Set a value (before given index).
v.Set("value", "YYY")
resp, _ = tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
tests.ReadBody(resp)
// A response should follow from the GET above.
time.Sleep(1 * time.Millisecond)
select {
case <-c:
default:
t.Fatal("cannot get watch result")
}
assert.NotNil(t, body, "")
assert.Equal(t, body["action"], "set", "")
assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "YYY", "")
assert.Equal(t, body["index"], 3, "")
})
}