Browse Source

tests add tests for dir flag

Xiang Li 12 years ago
parent
commit
d646d7c16a
4 changed files with 182 additions and 12 deletions
  1. 56 0
      server/v2/tests/delete_handler_test.go
  2. 13 0
      server/v2/tests/put_handler_test.go
  3. 5 0
      store/store.go
  4. 108 12
      store/store_test.go

+ 56 - 0
server/v2/tests/delete_handler_test.go

@@ -27,3 +27,59 @@ func TestV2DeleteKey(t *testing.T) {
 		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","prevValue":"XXX","modifiedIndex":3,"createdIndex":2}}`, "")
 		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","prevValue":"XXX","modifiedIndex":3,"createdIndex":2}}`, "")
 	})
 	})
 }
 }
+
+// Ensures that an empty directory is deleted when dir is set.
+//
+//   $ curl -X PUT localhost:4001/v2/keys/foo?dir=true
+//   $ curl -X PUT localhost:4001/v2/keys/foo ->fail
+//   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true
+//
+func TestV2DeleteEmptyDirectory(t *testing.T) {
+	tests.RunServer(func(s *server.Server) {
+		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
+		tests.ReadBody(resp)
+		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo"), url.Values{})
+		bodyJson := tests.ReadBodyJSON(resp)
+		assert.Equal(t, bodyJson["errorCode"], 102, "")
+		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
+		body := tests.ReadBody(resp)
+		assert.Nil(t, err, "")
+		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "")
+	})
+}
+
+// Ensures that a not-empty directory is deleted when dir is set.
+//
+//   $ curl -X PUT localhost:4001/v2/keys/foo/bar?dir=true
+//   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true ->fail
+//   $ curl -X DELETE localhost:4001/v2/keys/foo?dir=true&recursive=true
+//
+func TestV2DeleteNonEmptyDirectory(t *testing.T) {
+	tests.RunServer(func(s *server.Server) {
+		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?dir=true"), url.Values{})
+		tests.ReadBody(resp)
+		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
+		bodyJson := tests.ReadBodyJSON(resp)
+		assert.Equal(t, bodyJson["errorCode"], 108, "")
+		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true&recursive=true"), url.Values{})
+		body := tests.ReadBody(resp)
+		assert.Nil(t, err, "")
+		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "")
+	})
+}
+
+// Ensures that a directory is deleted when recursive is set.
+//
+//   $ curl -X PUT localhost:4001/v2/keys/foo?dir=true
+//   $ curl -X DELETE localhost:4001/v2/keys/foo?recursive=true
+//
+func TestV2DeleteDirectoryRecursiveImpliesDir(t *testing.T) {
+	tests.RunServer(func(s *server.Server) {
+		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
+		tests.ReadBody(resp)
+		resp, err = tests.DeleteForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?recursive=true"), url.Values{})
+		body := tests.ReadBody(resp)
+		assert.Nil(t, err, "")
+		assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "")
+	})
+}

+ 13 - 0
server/v2/tests/put_handler_test.go

@@ -26,6 +26,19 @@ func TestV2SetKey(t *testing.T) {
 	})
 	})
 }
 }
 
 
+// Ensures that a directory is created
+//
+//   $ curl -X PUT localhost:4001/v2/keys/foo/bar?dir=true
+//
+func TestV2SetDirectory(t *testing.T) {
+	tests.RunServer(func(s *server.Server) {
+		resp, err := tests.PutForm(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo?dir=true"), url.Values{})
+		body := tests.ReadBody(resp)
+		assert.Nil(t, err, "")
+		assert.Equal(t, string(body), `{"action":"set","node":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
+	})
+}
+
 // Ensures that a time-to-live is added to a key.
 // Ensures that a time-to-live is added to a key.
 //
 //
 //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX -d ttl=20
 //   $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX -d ttl=20

+ 5 - 0
store/store.go

@@ -252,6 +252,11 @@ func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) {
 	s.worldLock.Lock()
 	s.worldLock.Lock()
 	defer s.worldLock.Unlock()
 	defer s.worldLock.Unlock()
 
 
+	// recursive implies dir
+	if recursive == true {
+		dir = true
+	}
+
 	nextIndex := s.CurrentIndex + 1
 	nextIndex := s.CurrentIndex + 1
 
 
 	n, err := s.internalGet(nodePath)
 	n, err := s.internalGet(nodePath)

+ 108 - 12
store/store_test.go

@@ -84,9 +84,53 @@ func TestStoreGetSorted(t *testing.T) {
 	assert.Equal(t, e.Node.Nodes[2].Key, "/foo/z", "")
 	assert.Equal(t, e.Node.Nodes[2].Key, "/foo/z", "")
 }
 }
 
 
+func TestSet(t *testing.T) {
+	s := newStore()
+
+	// Set /foo=""
+	e, err := s.Set("/foo", false, "", Permanent)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "set", "")
+	assert.Equal(t, e.Node.Key, "/foo", "")
+	assert.False(t, e.Node.Dir, "")
+	assert.Equal(t, e.Node.PrevValue, "", "")
+	assert.Equal(t, e.Node.Value, "", "")
+	assert.Nil(t, e.Node.Nodes, "")
+	assert.Nil(t, e.Node.Expiration, "")
+	assert.Equal(t, e.Node.TTL, 0, "")
+	assert.Equal(t, e.Node.ModifiedIndex, uint64(1), "")
+
+	// Set /foo="bar"
+	e, err = s.Set("/foo", false, "bar", Permanent)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "set", "")
+	assert.Equal(t, e.Node.Key, "/foo", "")
+	assert.False(t, e.Node.Dir, "")
+	assert.Equal(t, e.Node.PrevValue, "", "")
+	assert.Equal(t, e.Node.Value, "bar", "")
+	assert.Nil(t, e.Node.Nodes, "")
+	assert.Nil(t, e.Node.Expiration, "")
+	assert.Equal(t, e.Node.TTL, 0, "")
+	assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
+
+	// Set /dir as a directory
+	e, err = s.Set("/dir", true, "", Permanent)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "set", "")
+	assert.Equal(t, e.Node.Key, "/dir", "")
+	assert.True(t, e.Node.Dir, "")
+	assert.Equal(t, e.Node.PrevValue, "", "")
+	assert.Equal(t, e.Node.Value, "", "")
+	assert.Nil(t, e.Node.Nodes, "")
+	assert.Nil(t, e.Node.Expiration, "")
+	assert.Equal(t, e.Node.TTL, 0, "")
+	assert.Equal(t, e.Node.ModifiedIndex, uint64(3), "")
+}
+
 // Ensure that the store can create a new key if it doesn't already exist.
 // Ensure that the store can create a new key if it doesn't already exist.
 func TestStoreCreateValue(t *testing.T) {
 func TestStoreCreateValue(t *testing.T) {
 	s := newStore()
 	s := newStore()
+	// Create /foo=bar
 	e, err := s.Create("/foo", false, "bar", false, Permanent)
 	e, err := s.Create("/foo", false, "bar", false, Permanent)
 	assert.Nil(t, err, "")
 	assert.Nil(t, err, "")
 	assert.Equal(t, e.Action, "create", "")
 	assert.Equal(t, e.Action, "create", "")
@@ -98,6 +142,20 @@ func TestStoreCreateValue(t *testing.T) {
 	assert.Nil(t, e.Node.Expiration, "")
 	assert.Nil(t, e.Node.Expiration, "")
 	assert.Equal(t, e.Node.TTL, 0, "")
 	assert.Equal(t, e.Node.TTL, 0, "")
 	assert.Equal(t, e.Node.ModifiedIndex, uint64(1), "")
 	assert.Equal(t, e.Node.ModifiedIndex, uint64(1), "")
+
+	// Create /empty=""
+	e, err = s.Create("/empty", false, "", false, Permanent)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "create", "")
+	assert.Equal(t, e.Node.Key, "/empty", "")
+	assert.False(t, e.Node.Dir, "")
+	assert.Equal(t, e.Node.PrevValue, "", "")
+	assert.Equal(t, e.Node.Value, "", "")
+	assert.Nil(t, e.Node.Nodes, "")
+	assert.Nil(t, e.Node.Expiration, "")
+	assert.Equal(t, e.Node.TTL, 0, "")
+	assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
+
 }
 }
 
 
 // Ensure that the store can create a new directory if it doesn't already exist.
 // Ensure that the store can create a new directory if it doesn't already exist.
@@ -113,7 +171,10 @@ func TestStoreCreateDirectory(t *testing.T) {
 // Ensure that the store fails to create a key if it already exists.
 // Ensure that the store fails to create a key if it already exists.
 func TestStoreCreateFailsIfExists(t *testing.T) {
 func TestStoreCreateFailsIfExists(t *testing.T) {
 	s := newStore()
 	s := newStore()
+	// create /foo as dir
 	s.Create("/foo", true, "", false, Permanent)
 	s.Create("/foo", true, "", false, Permanent)
+
+	// create /foo as dir again
 	e, _err := s.Create("/foo", true, "", false, Permanent)
 	e, _err := s.Create("/foo", true, "", false, Permanent)
 	err := _err.(*etcdErr.Error)
 	err := _err.(*etcdErr.Error)
 	assert.Equal(t, err.ErrorCode, etcdErr.EcodeNodeExist, "")
 	assert.Equal(t, err.ErrorCode, etcdErr.EcodeNodeExist, "")
@@ -126,7 +187,9 @@ func TestStoreCreateFailsIfExists(t *testing.T) {
 // Ensure that the store can update a key if it already exists.
 // Ensure that the store can update a key if it already exists.
 func TestStoreUpdateValue(t *testing.T) {
 func TestStoreUpdateValue(t *testing.T) {
 	s := newStore()
 	s := newStore()
+	// create /foo=bar
 	s.Create("/foo", false, "bar", false, Permanent)
 	s.Create("/foo", false, "bar", false, Permanent)
+	// update /foo="bzr"
 	e, err := s.Update("/foo", "baz", Permanent)
 	e, err := s.Update("/foo", "baz", Permanent)
 	assert.Nil(t, err, "")
 	assert.Nil(t, err, "")
 	assert.Equal(t, e.Action, "update", "")
 	assert.Equal(t, e.Action, "update", "")
@@ -138,6 +201,19 @@ func TestStoreUpdateValue(t *testing.T) {
 	assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
 	assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
 	e, _ = s.Get("/foo", false, false)
 	e, _ = s.Get("/foo", false, false)
 	assert.Equal(t, e.Node.Value, "baz", "")
 	assert.Equal(t, e.Node.Value, "baz", "")
+
+	// update /foo=""
+	e, err = s.Update("/foo", "", Permanent)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "update", "")
+	assert.Equal(t, e.Node.Key, "/foo", "")
+	assert.False(t, e.Node.Dir, "")
+	assert.Equal(t, e.Node.PrevValue, "baz", "")
+	assert.Equal(t, e.Node.Value, "", "")
+	assert.Equal(t, e.Node.TTL, 0, "")
+	assert.Equal(t, e.Node.ModifiedIndex, uint64(3), "")
+	e, _ = s.Get("/foo", false, false)
+	assert.Equal(t, e.Node.Value, "", "")
 }
 }
 
 
 // Ensure that the store cannot update a directory.
 // Ensure that the store cannot update a directory.
@@ -207,10 +283,41 @@ func TestStoreDeleteValue(t *testing.T) {
 // Ensure that the store can delete a directory if recursive is specified.
 // Ensure that the store can delete a directory if recursive is specified.
 func TestStoreDeleteDiretory(t *testing.T) {
 func TestStoreDeleteDiretory(t *testing.T) {
 	s := newStore()
 	s := newStore()
+	// create directory /foo
 	s.Create("/foo", true, "", false, Permanent)
 	s.Create("/foo", true, "", false, Permanent)
-	e, err := s.Delete("/foo", true, true)
+	// delete /foo with dir = true and recursive = false
+	// this should success, since the directory is empty
+	e, err := s.Delete("/foo", true, false)
 	assert.Nil(t, err, "")
 	assert.Nil(t, err, "")
 	assert.Equal(t, e.Action, "delete", "")
 	assert.Equal(t, e.Action, "delete", "")
+
+	// create directory /foo and directory /foo/bar
+	s.Create("/foo/bar", true, "", false, Permanent)
+	// delete /foo with dir = true and recursive = false
+	// this should fail, since the directory is not empty
+	_, err = s.Delete("/foo", true, false)
+	assert.NotNil(t, err, "")
+
+	// delete /foo with dir=false and recursive = true
+	// this should success, since recursive implies dir=true
+	// and recursively delete should be able to delete all
+	// items under the given directory
+	e, err = s.Delete("/foo", false, true)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.Action, "delete", "")
+
+}
+
+// Ensure that the store cannot delete a directory if both of recursive
+// and dir are not specified.
+func TestStoreDeleteDiretoryFailsIfNonRecursiveAndDir(t *testing.T) {
+	s := newStore()
+	s.Create("/foo", true, "", false, Permanent)
+	e, _err := s.Delete("/foo", false, false)
+	err := _err.(*etcdErr.Error)
+	assert.Equal(t, err.ErrorCode, etcdErr.EcodeNotFile, "")
+	assert.Equal(t, err.Message, "Not a file", "")
+	assert.Nil(t, e, "")
 }
 }
 
 
 func TestRootRdOnly(t *testing.T) {
 func TestRootRdOnly(t *testing.T) {
@@ -233,17 +340,6 @@ func TestRootRdOnly(t *testing.T) {
 
 
 }
 }
 
 
-// Ensure that the store cannot delete a directory if recursive is not specified.
-func TestStoreDeleteDiretoryFailsIfNonRecursive(t *testing.T) {
-	s := newStore()
-	s.Create("/foo", true, "", false, Permanent)
-	e, _err := s.Delete("/foo", false, false)
-	err := _err.(*etcdErr.Error)
-	assert.Equal(t, err.ErrorCode, etcdErr.EcodeNotFile, "")
-	assert.Equal(t, err.Message, "Not a file", "")
-	assert.Nil(t, e, "")
-}
-
 // Ensure that the store can conditionally update a key if it has a previous value.
 // Ensure that the store can conditionally update a key if it has a previous value.
 func TestStoreCompareAndSwapPrevValue(t *testing.T) {
 func TestStoreCompareAndSwapPrevValue(t *testing.T) {
 	s := newStore()
 	s := newStore()