github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/v1/tests/put_handler_test.go (about)

     1  package v1
     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 key is set to a given value.
    16  //
    17  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
    18  //
    19  func TestV1SetKey(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(), "/v1/keys/foo/bar"), v)
    24  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    25  		body := tests.ReadBody(resp)
    26  		assert.Nil(t, err, "")
    27  
    28  		assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","newKey":true,"index":2}`, "")
    29  	})
    30  }
    31  
    32  // Ensures that a time-to-live is added to a key.
    33  //
    34  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d ttl=20
    35  //
    36  func TestV1SetKeyWithTTL(t *testing.T) {
    37  	tests.RunServer(func(s *server.Server) {
    38  		t0 := time.Now()
    39  		v := url.Values{}
    40  		v.Set("value", "XXX")
    41  		v.Set("ttl", "20")
    42  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
    43  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    44  		body := tests.ReadBodyJSON(resp)
    45  		assert.Equal(t, body["ttl"], 20, "")
    46  
    47  		// Make sure the expiration date is correct.
    48  		expiration, _ := time.Parse(time.RFC3339Nano, body["expiration"].(string))
    49  		assert.Equal(t, expiration.Sub(t0)/time.Second, 20, "")
    50  	})
    51  }
    52  
    53  // Ensures that an invalid time-to-live is returned as an error.
    54  //
    55  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d ttl=bad_ttl
    56  //
    57  func TestV1SetKeyWithBadTTL(t *testing.T) {
    58  	tests.RunServer(func(s *server.Server) {
    59  		v := url.Values{}
    60  		v.Set("value", "XXX")
    61  		v.Set("ttl", "bad_ttl")
    62  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
    63  		assert.Equal(t, resp.StatusCode, http.StatusBadRequest)
    64  		body := tests.ReadBodyJSON(resp)
    65  		assert.Equal(t, body["errorCode"], 202, "")
    66  		assert.Equal(t, body["message"], "The given TTL in POST form is not a number", "")
    67  		assert.Equal(t, body["cause"], "Set", "")
    68  	})
    69  }
    70  
    71  // Ensures that a key is conditionally set if it previously did not exist.
    72  //
    73  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue=
    74  //
    75  func TestV1CreateKeySuccess(t *testing.T) {
    76  	tests.RunServer(func(s *server.Server) {
    77  		v := url.Values{}
    78  		v.Set("value", "XXX")
    79  		v.Set("prevValue", "")
    80  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar"), v)
    81  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    82  		body := tests.ReadBodyJSON(resp)
    83  		assert.Equal(t, body["value"], "XXX", "")
    84  	})
    85  }
    86  
    87  // Ensures that a key is not conditionally set because it previously existed.
    88  //
    89  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue=
    90  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX -d prevValue= -> fail
    91  //
    92  func TestV1CreateKeyFail(t *testing.T) {
    93  	tests.RunServer(func(s *server.Server) {
    94  		v := url.Values{}
    95  		v.Set("value", "XXX")
    96  		v.Set("prevValue", "")
    97  		fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar")
    98  		resp, _ := tests.PutForm(fullURL, v)
    99  		assert.Equal(t, resp.StatusCode, http.StatusOK)
   100  		tests.ReadBody(resp)
   101  		resp, _ = tests.PutForm(fullURL, v)
   102  		assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed)
   103  		body := tests.ReadBodyJSON(resp)
   104  		assert.Equal(t, body["errorCode"], 105, "")
   105  		assert.Equal(t, body["message"], "Key already exists", "")
   106  		assert.Equal(t, body["cause"], "/foo/bar", "")
   107  	})
   108  }
   109  
   110  // Ensures that a key is set only if the previous value matches.
   111  //
   112  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
   113  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=YYY -d prevValue=XXX
   114  //
   115  func TestV1SetKeyCASOnValueSuccess(t *testing.T) {
   116  	tests.RunServer(func(s *server.Server) {
   117  		v := url.Values{}
   118  		v.Set("value", "XXX")
   119  		fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar")
   120  		resp, _ := tests.PutForm(fullURL, v)
   121  		assert.Equal(t, resp.StatusCode, http.StatusOK)
   122  		tests.ReadBody(resp)
   123  		v.Set("value", "YYY")
   124  		v.Set("prevValue", "XXX")
   125  		resp, _ = tests.PutForm(fullURL, v)
   126  		assert.Equal(t, resp.StatusCode, http.StatusOK)
   127  		body := tests.ReadBodyJSON(resp)
   128  		assert.Equal(t, body["action"], "testAndSet", "")
   129  		assert.Equal(t, body["value"], "YYY", "")
   130  		assert.Equal(t, body["index"], 3, "")
   131  	})
   132  }
   133  
   134  // Ensures that a key is not set if the previous value does not match.
   135  //
   136  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=XXX
   137  //   $ curl -X PUT localhost:4001/v1/keys/foo/bar -d value=YYY -d prevValue=AAA
   138  //
   139  func TestV1SetKeyCASOnValueFail(t *testing.T) {
   140  	tests.RunServer(func(s *server.Server) {
   141  		v := url.Values{}
   142  		v.Set("value", "XXX")
   143  		fullURL := fmt.Sprintf("%s%s", s.URL(), "/v1/keys/foo/bar")
   144  		resp, _ := tests.PutForm(fullURL, v)
   145  		assert.Equal(t, resp.StatusCode, http.StatusOK)
   146  		tests.ReadBody(resp)
   147  		v.Set("value", "YYY")
   148  		v.Set("prevValue", "AAA")
   149  		resp, _ = tests.PutForm(fullURL, v)
   150  		assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed)
   151  		body := tests.ReadBodyJSON(resp)
   152  		assert.Equal(t, body["errorCode"], 101, "")
   153  		assert.Equal(t, body["message"], "Compare failed", "")
   154  		assert.Equal(t, body["cause"], "[AAA != XXX]", "")
   155  		assert.Equal(t, body["index"], 2, "")
   156  	})
   157  }