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  }