mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-06-25 22:51:34 +00:00
* Initial commit for fileserver written in golang. [gofileserver] Fix some syntaxt errors. Add fs backend and objstore test (#352) * Add fs backend and objstore test * modify test case and optimize fs backend * Modify function name and first write temporary files * Don't need to reopen the temp files Add comment for objstore (#354) * Add comment for objstore * Modify comment Add commitmgr and test case (#356) * Add commitmgr and test case * Redefine the interface * Modify comment and interface * Modify parameter and del unused method * Add comment for FromData and ToData Add blockmgr and test case (#357) * Add blockmgr and test case * Modify comment and interface Add fsmgr and test case (#358) * Add fsmgr and test case * Add save interface and error details * Modify errors and comments Add searpc package and test case (#360) * Add searpc package * Add searpc test case * Add return error and add Request struct * Modify returned error * Modify comments add checkPerm (#369) Add file and block download (#363) * Add file and block download * Modify init and use aes algorithm * Get block by offset and add stat method * Modify objID's type * Fix reset pos after add start * Add http error handing and record log when failed to read block or write block to response * Modify http return code and value names * Modify http return code and add log info * Block read add comment and only repeat once load ccnetdb and support sqlite (#371) Add zip download (#372) * Add zip download * Modify pack dir and log info * Modify http return code and use Deflate zip compression methods add /repo/<repo-id>/permission-check (#375) add /<repo-id>/commit/HEAD (#377) add /repo/<repo-id>/commit/<id> (#379) add /repo/<repo-id>/block/<id> (#380) add /repo/<repo-id>/fs-id-list (#383) add /repo/head-commits-multi (#388) Add file upload api (#378) * Add file upload api * Upload api implements post multi files and create relative path * Modify handle error and save files directly * Fix rebase conflict * index block use channel and optimize mkdir with parents * Handle jobs and results in a loop * Mkdir with parents use postMultiFiles and use pointer of SeafDirent * Del diff_simple size_sched virtual_repo * Need to check the path with and without slash * Modify merge trees and add merge test case * Del postFile and don't close results channel * Close the file and remove multipart temp file * Modify merge test case and compare the first name of path * Use pointer of Entries for SeafDir * Add test cases for different situations add /repo/<repo-id>/pack-fs (#389) add POST /<repo-id>/check-fs and /<repo-id>/check-blocks (#396) Merge compute repo (#397) * Add update repo size and merge virtual repo * Eliminate lint warnings * Uncomment merge virtual repo and compute repo size * Need init the dents * Use interface{} param and modify removeElems * Move update dir to file.go and modify logs * Del sync pkg add PUT /<repo-id>/commit/<commit-id> (#400) add PUT /<repo-id>/block/<id> (#401) add POST /<repo-id>/recv-fs (#398) add PUT /<repo-id>/commit/HEAD (#402) Add http return code (#403) Add file update API (#399) * Add file update API * Add GetObjIDByPath and fix change size error * Add traffic statistics for update api add diffTrees unit test (#391) add GET /accessible-repos (#406) add GET /<repo-id>/block-map/<file-id> (#405) Add test update repo size and merge virtual repo (#409) * Update dir need update repo size * Add test update repo size and merge virtual repo * Add delay for test ajax * Add delay before get repo size and modify comment Use go fileserver for unit test (#410) * Use go fileserver for unit test * Blocking scheduling update repo size * Add delay because of sqlite doesn't support concurrency * Post use multipart form encode * Del mysql database when test finished * Fix merge virtual repo failed when use sqlite3 Add upload block API (#412) fixed error Add quota-check API (#426) use diff package * Use central conf for go fileserver (#428) * Use central conf for go fileserver * Fix log error * use store id and remove share get repo owner (#430) * Fix permission error (#432) Co-authored-by: feiniks <36756310+feiniks@users.noreply.github.com> Co-authored-by: Xiangyue Cai <caixiangyue007@gmail.com>
282 lines
6.3 KiB
Go
282 lines
6.3 KiB
Go
package diff
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"github.com/haiwen/seafile-server/fileserver/fsmgr"
|
|
)
|
|
|
|
const (
|
|
emptySHA1 = "0000000000000000000000000000000000000000"
|
|
diffTestSeafileConfPath = "/tmp/conf"
|
|
diffTestSeafileDataDir = "/tmp/conf/seafile-data"
|
|
diffTestRepoID = "0d18a711-c988-4f7b-960c-211b34705ce3"
|
|
)
|
|
|
|
var diffTestTree1 string
|
|
var diffTestTree2 string
|
|
var diffTestTree3 string
|
|
var diffTestTree4 string
|
|
var diffTestFileID string
|
|
var diffTestDirID1 string
|
|
var diffTestDirID2 string
|
|
|
|
/*
|
|
test directory structure:
|
|
|
|
tree1
|
|
|--
|
|
|
|
tree2
|
|
|--file
|
|
|
|
tree3
|
|
|--dir
|
|
|
|
tree4
|
|
|--dir
|
|
|-- file
|
|
|
|
*/
|
|
|
|
func TestDiffTrees(t *testing.T) {
|
|
fsmgr.Init(diffTestSeafileConfPath, diffTestSeafileDataDir)
|
|
|
|
err := diffTestCreateTestDir()
|
|
if err != nil {
|
|
fmt.Printf("failed to create test dir: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
t.Run("test1", testDiffTrees1)
|
|
t.Run("test2", testDiffTrees2)
|
|
t.Run("test3", testDiffTrees3)
|
|
t.Run("test4", testDiffTrees4)
|
|
t.Run("test5", testDiffTrees5)
|
|
|
|
err = diffTestDelFile()
|
|
if err != nil {
|
|
fmt.Printf("failed to remove test file : %v", err)
|
|
}
|
|
}
|
|
|
|
func diffTestCreateTestDir() error {
|
|
modeDir := uint32(syscall.S_IFDIR | 0644)
|
|
modeFile := uint32(syscall.S_IFREG | 0644)
|
|
|
|
dir1, err := diffTestCreateSeafdir(nil)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get seafdir: %v", err)
|
|
return err
|
|
}
|
|
diffTestTree1 = dir1
|
|
file1, err := fsmgr.NewSeafile(1, 1, nil)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to new seafile: %v", err)
|
|
return err
|
|
}
|
|
diffTestFileID = file1.FileID
|
|
err = fsmgr.SaveSeafile(diffTestRepoID, file1)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to save seafile: %v", err)
|
|
return err
|
|
}
|
|
dent1 := fsmgr.SeafDirent{ID: file1.FileID, Name: "file", Mode: modeFile, Size: 1}
|
|
dir2, err := diffTestCreateSeafdir([]*fsmgr.SeafDirent{&dent1})
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get seafdir: %v", err)
|
|
return err
|
|
}
|
|
diffTestTree2 = dir2
|
|
|
|
dent2 := fsmgr.SeafDirent{ID: dir1, Name: "dir", Mode: modeDir}
|
|
diffTestDirID1 = dir1
|
|
dir3, err := diffTestCreateSeafdir([]*fsmgr.SeafDirent{&dent2})
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get seafdir: %v", err)
|
|
return err
|
|
}
|
|
diffTestTree3 = dir3
|
|
|
|
dent3 := fsmgr.SeafDirent{ID: dir2, Name: "dir", Mode: modeDir}
|
|
diffTestDirID2 = dir2
|
|
dir4, err := diffTestCreateSeafdir([]*fsmgr.SeafDirent{&dent3})
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get seafdir: %v", err)
|
|
return err
|
|
}
|
|
diffTestTree4 = dir4
|
|
|
|
return nil
|
|
}
|
|
|
|
func testDiffTrees1(t *testing.T) {
|
|
var results []interface{}
|
|
opt := &DiffOptions{
|
|
FileCB: diffTestFileCB,
|
|
DirCB: diffTestDirCB,
|
|
RepoID: diffTestRepoID}
|
|
opt.Data = &results
|
|
DiffTrees([]string{diffTestTree2, diffTestTree1}, opt)
|
|
if len(results) != 1 {
|
|
t.Errorf("data length is %d not 1", len(results))
|
|
}
|
|
var ret = make([]string, len(results))
|
|
for k, v := range results {
|
|
ret[k] = fmt.Sprintf("%s", v)
|
|
}
|
|
if ret[0] != diffTestFileID {
|
|
t.Errorf("result %s != %s", ret[0], diffTestFileID)
|
|
}
|
|
}
|
|
|
|
func testDiffTrees2(t *testing.T) {
|
|
var results []interface{}
|
|
opt := &DiffOptions{
|
|
FileCB: diffTestFileCB,
|
|
DirCB: diffTestDirCB,
|
|
RepoID: diffTestRepoID}
|
|
opt.Data = &results
|
|
DiffTrees([]string{diffTestTree3, diffTestTree1}, opt)
|
|
if len(results) != 1 {
|
|
t.Errorf("data length is %d not 1", len(results))
|
|
}
|
|
var ret = make([]string, len(results))
|
|
for k, v := range results {
|
|
ret[k] = fmt.Sprintf("%s", v)
|
|
}
|
|
if ret[0] != diffTestDirID1 {
|
|
t.Errorf("result %s != %s", ret[0], diffTestDirID1)
|
|
}
|
|
|
|
}
|
|
|
|
func testDiffTrees3(t *testing.T) {
|
|
var results []interface{}
|
|
opt := &DiffOptions{
|
|
FileCB: diffTestFileCB,
|
|
DirCB: diffTestDirCB,
|
|
RepoID: diffTestRepoID}
|
|
opt.Data = &results
|
|
DiffTrees([]string{diffTestTree4, diffTestTree1}, opt)
|
|
if len(results) != 2 {
|
|
t.Errorf("data length is %d not 1", len(results))
|
|
}
|
|
|
|
var ret = make([]string, len(results))
|
|
for k, v := range results {
|
|
ret[k] = fmt.Sprintf("%s", v)
|
|
}
|
|
if ret[0] != diffTestDirID2 {
|
|
t.Errorf("result %s != %s", ret[0], diffTestDirID2)
|
|
}
|
|
if ret[1] != diffTestFileID {
|
|
t.Errorf("result %s != %s", ret[1], diffTestFileID)
|
|
}
|
|
}
|
|
|
|
func testDiffTrees4(t *testing.T) {
|
|
var results []interface{}
|
|
opt := &DiffOptions{
|
|
FileCB: diffTestFileCB,
|
|
DirCB: diffTestDirCB,
|
|
RepoID: diffTestRepoID}
|
|
opt.Data = &results
|
|
DiffTrees([]string{diffTestTree4, diffTestTree3}, opt)
|
|
if len(results) != 2 {
|
|
t.Errorf("data length is %d not 1", len(results))
|
|
}
|
|
|
|
var ret = make([]string, len(results))
|
|
for k, v := range results {
|
|
ret[k] = fmt.Sprintf("%s", v)
|
|
}
|
|
if ret[0] != diffTestDirID2 {
|
|
t.Errorf("result %s != %s", ret[0], diffTestDirID2)
|
|
}
|
|
if ret[1] != diffTestFileID {
|
|
t.Errorf("result %s != %s", ret[1], diffTestFileID)
|
|
}
|
|
}
|
|
|
|
func testDiffTrees5(t *testing.T) {
|
|
var results []interface{}
|
|
opt := &DiffOptions{
|
|
FileCB: diffTestFileCB,
|
|
DirCB: diffTestDirCB,
|
|
RepoID: diffTestRepoID}
|
|
opt.Data = &results
|
|
DiffTrees([]string{diffTestTree3, diffTestTree2}, opt)
|
|
if len(results) != 1 {
|
|
t.Errorf("data length is %d not 1", len(results))
|
|
}
|
|
var ret = make([]string, len(results))
|
|
for k, v := range results {
|
|
ret[k] = fmt.Sprintf("%s", v)
|
|
}
|
|
if ret[0] != diffTestDirID1 {
|
|
t.Errorf("result %s != %s", ret[0], diffTestDirID1)
|
|
}
|
|
}
|
|
|
|
func diffTestCreateSeafdir(dents []*fsmgr.SeafDirent) (string, error) {
|
|
seafdir, err := fsmgr.NewSeafdir(1, dents)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
err = fsmgr.SaveSeafdir(diffTestRepoID, seafdir)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return seafdir.DirID, nil
|
|
}
|
|
|
|
func diffTestDelFile() error {
|
|
err := os.RemoveAll(diffTestSeafileConfPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func diffTestFileCB(baseDir string, files []*fsmgr.SeafDirent, data interface{}) error {
|
|
file1 := files[0]
|
|
file2 := files[1]
|
|
results, ok := data.(*[]interface{})
|
|
if !ok {
|
|
err := fmt.Errorf("failed to assert results")
|
|
return err
|
|
}
|
|
|
|
if file1 != nil &&
|
|
(file2 == nil || file1.ID != file2.ID) &&
|
|
file1.ID != emptySHA1 {
|
|
*results = append(*results, file1.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func diffTestDirCB(baseDir string, dirs []*fsmgr.SeafDirent, data interface{}, recurse *bool) error {
|
|
dir1 := dirs[0]
|
|
dir2 := dirs[1]
|
|
results, ok := data.(*[]interface{})
|
|
if !ok {
|
|
err := fmt.Errorf("failed to assert results")
|
|
return err
|
|
}
|
|
|
|
if dir1 != nil &&
|
|
(dir2 == nil || dir1.ID != dir2.ID) &&
|
|
dir1.ID != emptySHA1 {
|
|
*results = append(*results, dir1.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|