delete_handler_test.go 7.4 KB

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