diff --git a/src/db/boltstore/bolt_store.go b/src/db/boltstore/bolt_store.go index f31eec5..aa2a98a 100644 --- a/src/db/boltstore/bolt_store.go +++ b/src/db/boltstore/bolt_store.go @@ -1,6 +1,7 @@ package boltstore import ( + "bytes" "encoding/json" "errors" "fmt" @@ -289,48 +290,45 @@ func (bs *BoltStore) DelInfos(userID uint64, itemPath string, isDir bool) error return bs.boltdb.Update(func(tx *bolt.Tx) error { var err error - // delete file info fileInfoBucket := tx.Bucket([]byte(db.InfoNs)) if fileInfoBucket == nil { return db.ErrBucketNotFound } - fileInfoBytes := fileInfoBucket.Get([]byte(itemPath)) - if fileInfoBytes == nil { - if !isDir { - return db.ErrKeyNotFound - } - } else { + // delete children + prefixBytes := []byte(itemPath) + cur := fileInfoBucket.Cursor() + usedSpaceDecr := int64(0) + for k, v := cur.Seek(prefixBytes); k != nil && bytes.HasPrefix(k, prefixBytes); k, v = cur.Next() { fileInfo := &db.FileInfo{} - err = json.Unmarshal(fileInfoBytes, fileInfo) + err = json.Unmarshal(v, fileInfo) if err != nil { return err } - err = fileInfoBucket.Delete([]byte(itemPath)) + usedSpaceDecr += fileInfo.Size + childPath := string(k) + err = fileInfoBucket.Delete([]byte(childPath)) if err != nil { return err } - - // decr used space - userInfo, err := bs.getUserInfo(tx, userID) - if err != nil { - return err - } - - userInfo.UsedSpace -= fileInfo.Size - err = bs.setUserInfo(tx, userID, userInfo) - if err != nil { - return err + if fileInfo.IsDir { + err = bs.delShareID(tx, childPath) + if err != nil { + return err + } } } - // delete share id - if isDir { - err = bs.delShareID(tx, itemPath) - if err != nil { - return err - } + // decr used space + userInfo, err := bs.getUserInfo(tx, userID) + if err != nil { + return err + } + userInfo.UsedSpace -= usedSpaceDecr + err = bs.setUserInfo(tx, userID, userInfo) + if err != nil { + return err } return nil diff --git a/src/server/server_space_limit_test.go b/src/server/server_space_limit_test.go index ddb8ca4..18fa065 100644 --- a/src/server/server_space_limit_test.go +++ b/src/server/server_space_limit_test.go @@ -3,6 +3,7 @@ package server import ( "fmt" "os" + "path/filepath" "testing" "github.com/ihexxa/quickshare/src/client" @@ -148,6 +149,77 @@ func TestSpaceLimit(t *testing.T) { } }) + t.Run("usedSpace keeps correct in operations: Mkdir-Create-UploadChunk-AddSharing-Move-IsSharing-List", func(t *testing.T) { + srcDir := "qs/files/folder/move/src" + dstDir := "qs/files/folder/move/dst" + filesCl := client.NewFilesClient(addr, token) + + getUsedSpace := func() int64 { + resp, selfResp, errs := usersCl.Self(token) + if len(errs) > 0 { + t.Fatal(errs) + } else if resp.StatusCode != 200 { + t.Fatal("failed to get self") + } + + return selfResp.UsedSpace + } + + initUsedSpace := getUsedSpace() + + for _, dirPath := range []string{srcDir, dstDir} { + res, _, errs := filesCl.Mkdir(dirPath) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { + t.Fatal(res.StatusCode) + } + } + if getUsedSpace() != initUsedSpace { + t.Fatal("incorrect used space") + } + + expectedUsedSpace := initUsedSpace + files := map[string]string{ + "f1.md": "111", + "f2.md": "22222", + } + for fileName, content := range files { + oldPath := filepath.Join(srcDir, fileName) + assertUploadOK(t, oldPath, content, addr, token) + expectedUsedSpace += int64(len(content)) + } + if getUsedSpace() != expectedUsedSpace { + t.Fatal("used space incorrect") + } + + for fileName := range files { + oldPath := filepath.Join(srcDir, fileName) + newPath := filepath.Join(dstDir, fileName) + res, _, errs := filesCl.Move(oldPath, newPath) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { + t.Fatal(res.StatusCode) + } + + if getUsedSpace() != expectedUsedSpace { + t.Fatal("used space incorrect") + } + } + + res, _, errs := filesCl.Delete(dstDir) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { + t.Fatal(res.StatusCode) + } + + if getUsedSpace() != initUsedSpace { + t.Fatal("used space incorrect") + } + }) + resp, _, errs = usersCl.Logout(token) if len(errs) > 0 { t.Fatal(errs) diff --git a/src/server/testdata/test_quickshare.db b/src/server/testdata/test_quickshare.db index 20304f1..4487f1f 100644 Binary files a/src/server/testdata/test_quickshare.db and b/src/server/testdata/test_quickshare.db differ