delete_handler_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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=1
  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. fmt.Println(resp)
  94. body := tests.ReadBodyJSON(resp)
  95. assert.Equal(t, body["action"], "compareAndDelete", "")
  96. node := body["node"].(map[string]interface{})
  97. assert.Equal(t, node["key"], "/foo", "")
  98. assert.Equal(t, node["modifiedIndex"], 3, "")
  99. })
  100. }
  101. // Ensures that a key is not deleted if the previous index does not match
  102. //
  103. // $ curl -X PUT localhost:4001/v2/keys/foo -d value=XXX
  104. // $ curl -X DELETE localhost:4001/v2/keys/foo?prevIndex=100
  105. //
  106. func TestV2DeleteKeyCADOnIndexFail(t *testing.T) {
  107. tests.RunServer(func(s *server.Server) {
  108. v := url.Values{}
  109. v.Set("value", "XXX")
  110. resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), v)
  111. tests.ReadBody(resp)
  112. resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?prevIndex=100"), url.Values{})
  113. assert.Nil(t, err, "")
  114. body := tests.ReadBodyJSON(resp)
  115. assert.Equal(t, body["errorCode"], 101)
  116. })
  117. }
  118. // Ensures that an error is thrown if an invalid previous index is provided.
  119. //
  120. // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
  121. // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex=bad_index
  122. //
  123. func TestV2DeleteKeyCADWithInvalidIndex(t *testing.T) {
  124. tests.RunServer(func(s *server.Server) {
  125. v := url.Values{}
  126. v.Set("value", "XXX")
  127. resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
  128. tests.ReadBody(resp)
  129. resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevIndex=bad_index"), v)
  130. body := tests.ReadBodyJSON(resp)
  131. assert.Equal(t, body["errorCode"], 203)
  132. })
  133. }
  134. // Ensures that a key is deleted only if the previous value matches.
  135. //
  136. // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
  137. // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=XXX
  138. //
  139. func TestV2DeleteKeyCADOnValueSuccess(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?prevValue=XXX"), v)
  146. body := tests.ReadBodyJSON(resp)
  147. assert.Equal(t, body["action"], "compareAndDelete", "")
  148. node := body["node"].(map[string]interface{})
  149. assert.Equal(t, node["modifiedIndex"], 3, "")
  150. })
  151. }
  152. // Ensures that a key is not deleted if the previous value does not match.
  153. //
  154. // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
  155. // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevValue=YYY
  156. //
  157. func TestV2DeleteKeyCADOnValueFail(t *testing.T) {
  158. tests.RunServer(func(s *server.Server) {
  159. v := url.Values{}
  160. v.Set("value", "XXX")
  161. resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
  162. tests.ReadBody(resp)
  163. resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue=YYY"), v)
  164. body := tests.ReadBodyJSON(resp)
  165. assert.Equal(t, body["errorCode"], 101)
  166. })
  167. }
  168. // Ensures that an error is thrown if an invalid previous value is provided.
  169. //
  170. // $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
  171. // $ curl -X DELETE localhost:4001/v2/keys/foo/bar?prevIndex=
  172. //
  173. func TestV2DeleteKeyCADWithInvalidValue(t *testing.T) {
  174. tests.RunServer(func(s *server.Server) {
  175. v := url.Values{}
  176. v.Set("value", "XXX")
  177. resp, _ := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar"), v)
  178. tests.ReadBody(resp)
  179. resp, _ = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?prevValue="), v)
  180. body := tests.ReadBodyJSON(resp)
  181. assert.Equal(t, body["errorCode"], 201)
  182. })
  183. }