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

     1  package v2
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/url"
     7  	"testing"
     8  
     9  	"github.com/coreos/etcd/server"
    10  	"github.com/coreos/etcd/tests"
    11  	"github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert"
    12  )
    13  
    14  // Ensures that a key is deleted.
    15  //
    16  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
    17  //   $ curl -X DELETE localhost:4001/v2/keys/foo/bar
    18  //
    19  func TestV2DeleteKey(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(), "/v2/keys/foo/bar"), v)
    24  		tests.ReadBody(resp)
    25  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), url.Values{})
    26  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    27  		body := tests.ReadBody(resp)
    28  		assert.Nil(t, err, "")
    29  		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo/bar","value":"XXX","modifiedIndex":2,"createdIndex":2}}`, "")
    30  	})
    31  }
    32  
    33  // Ensures that an empty directory is deleted when dir is set.
    34  //
    35  //   $ curl -X PUT localhost:4001/v2/keys/foo?dir=true
    36  //   $ curl -X DELETE localhost:4001/v2/keys/foo ->fail
    37  //   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true
    38  //
    39  func TestV2DeleteEmptyDirectory(t *testing.T) {
    40  	tests.RunServer(func(s *server.Server) {
    41  		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
    42  		tests.ReadBody(resp)
    43  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), url.Values{})
    44  		assert.Equal(t, resp.StatusCode, http.StatusForbidden)
    45  		bodyJson := tests.ReadBodyJSON(resp)
    46  		assert.Equal(t, bodyJson["errorCode"], 102, "")
    47  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
    48  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    49  		body := tests.ReadBody(resp)
    50  		assert.Nil(t, err, "")
    51  		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
    52  	})
    53  }
    54  
    55  // Ensures that a not-empty directory is deleted when dir is set.
    56  //
    57  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar?dir=true
    58  //   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true ->fail
    59  //   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true&recursive=true
    60  //
    61  func TestV2DeleteNonEmptyDirectory(t *testing.T) {
    62  	tests.RunServer(func(s *server.Server) {
    63  		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?dir=true"), url.Values{})
    64  		tests.ReadBody(resp)
    65  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
    66  		assert.Equal(t, resp.StatusCode, http.StatusForbidden)
    67  		bodyJson := tests.ReadBodyJSON(resp)
    68  		assert.Equal(t, bodyJson["errorCode"], 108, "")
    69  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true&recursive=true"), url.Values{})
    70  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    71  		body := tests.ReadBody(resp)
    72  		assert.Nil(t, err, "")
    73  		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
    74  	})
    75  }
    76  
    77  // Ensures that a directory is deleted when recursive is set.
    78  //
    79  //   $ curl -X PUT localhost:4001/v2/keys/foo?dir=true
    80  //   $ curl -X DELETE localhost:4001/v2/keys/foo?recursive=true
    81  //
    82  func TestV2DeleteDirectoryRecursiveImpliesDir(t *testing.T) {
    83  	tests.RunServer(func(s *server.Server) {
    84  		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
    85  		tests.ReadBody(resp)
    86  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?recursive=true"), url.Values{})
    87  		assert.Equal(t, resp.StatusCode, http.StatusOK)
    88  		body := tests.ReadBody(resp)
    89  		assert.Nil(t, err, "")
    90  		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
    91  	})
    92  }
    93  
    94  // Ensures that a key is deleted if the previous index matches
    95  //
    96  //   $ curl -X PUT localhost:4001/v2/keys/foo -d value=XXX
    97  //   $ curl -X DELETE localhost:4001/v2/keys/foo?prevIndex=2
    98  //
    99  func TestV2DeleteKeyCADOnIndexSuccess(t *testing.T) {
   100  	tests.RunServer(func(s *server.Server) {
   101  		v := url.Values{}
   102  		v.Set("value", "XXX")
   103  		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), v)
   104  		tests.ReadBody(resp)
   105  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?prevIndex=2"), url.Values{})
   106  		assert.Nil(t, err, "")
   107  		body := tests.ReadBodyJSON(resp)
   108  		assert.Equal(t, body["action"], "compareAndDelete", "")
   109  
   110  		node := body["node"].(map[string]interface{})
   111  		assert.Equal(t, node["key"], "/foo", "")
   112  		assert.Equal(t, node["modifiedIndex"], 3, "")
   113  	})
   114  }
   115  
   116  // Ensures that a key is not deleted if the previous index does not match
   117  //
   118  //   $ curl -X PUT localhost:4001/v2/keys/foo -d value=XXX
   119  //   $ curl -X DELETE localhost:4001/v2/keys/foo?prevIndex=100
   120  //
   121  func TestV2DeleteKeyCADOnIndexFail(t *testing.T) {
   122  	tests.RunServer(func(s *server.Server) {
   123  		v := url.Values{}
   124  		v.Set("value", "XXX")
   125  		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), v)
   126  		tests.ReadBody(resp)
   127  		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?prevIndex=100"), url.Values{})
   128  		assert.Nil(t, err, "")
   129  		body := tests.ReadBodyJSON(resp)
   130  		assert.Equal(t, body["errorCode"], 101)
   131  	})
   132  }
   133  
   134  // Ensures that an error is thrown if an invalid previous index is provided.
   135  //
   136  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
   137  //   $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex=bad_index
   138  //
   139  func TestV2DeleteKeyCADWithInvalidIndex(t *testing.T) {
   140  	tests.RunServer(func(s *server.Server) {
   141  		v := url.Values{}
   142  		v.Set("value", "XXX")
   143  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
   144  		tests.ReadBody(resp)
   145  		resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevIndex=bad_index"), v)
   146  		body := tests.ReadBodyJSON(resp)
   147  		assert.Equal(t, body["errorCode"], 203)
   148  	})
   149  }
   150  
   151  // Ensures that a key is deleted only if the previous value matches.
   152  //
   153  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
   154  //   $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=XXX
   155  //
   156  func TestV2DeleteKeyCADOnValueSuccess(t *testing.T) {
   157  	tests.RunServer(func(s *server.Server) {
   158  		v := url.Values{}
   159  		v.Set("value", "XXX")
   160  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
   161  		tests.ReadBody(resp)
   162  		resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue=XXX"), v)
   163  		body := tests.ReadBodyJSON(resp)
   164  		assert.Equal(t, body["action"], "compareAndDelete", "")
   165  
   166  		node := body["node"].(map[string]interface{})
   167  		assert.Equal(t, node["modifiedIndex"], 3, "")
   168  	})
   169  }
   170  
   171  // Ensures that a key is not deleted if the previous value does not match.
   172  //
   173  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
   174  //   $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=YYY
   175  //
   176  func TestV2DeleteKeyCADOnValueFail(t *testing.T) {
   177  	tests.RunServer(func(s *server.Server) {
   178  		v := url.Values{}
   179  		v.Set("value", "XXX")
   180  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
   181  		tests.ReadBody(resp)
   182  		resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue=YYY"), v)
   183  		body := tests.ReadBodyJSON(resp)
   184  		assert.Equal(t, body["errorCode"], 101)
   185  	})
   186  }
   187  
   188  // Ensures that an error is thrown if an invalid previous value is provided.
   189  //
   190  //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
   191  //   $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex=
   192  //
   193  func TestV2DeleteKeyCADWithInvalidValue(t *testing.T) {
   194  	tests.RunServer(func(s *server.Server) {
   195  		v := url.Values{}
   196  		v.Set("value", "XXX")
   197  		resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
   198  		tests.ReadBody(resp)
   199  		resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue="), v)
   200  		body := tests.ReadBodyJSON(resp)
   201  		assert.Equal(t, body["errorCode"], 201)
   202  	})
   203  }