2019-06-27 22:54:43 +08:00
|
|
|
package dirtree
|
|
|
|
|
|
|
|
import (
|
2023-06-30 00:38:18 +08:00
|
|
|
"fmt"
|
2019-06-27 22:54:43 +08:00
|
|
|
"testing"
|
|
|
|
|
2019-07-29 01:47:38 +08:00
|
|
|
"github.com/rclone/rclone/fstest/mockdir"
|
|
|
|
"github.com/rclone/rclone/fstest/mockobject"
|
2019-06-27 22:54:43 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestNew(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
assert.Equal(t, "", dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParentDir(t *testing.T) {
|
|
|
|
assert.Equal(t, "root/parent", parentDir("root/parent/file"))
|
|
|
|
assert.Equal(t, "parent", parentDir("parent/file"))
|
|
|
|
assert.Equal(t, "", parentDir("parent"))
|
|
|
|
assert.Equal(t, "", parentDir(""))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeAdd(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
o := mockobject.New("potato")
|
|
|
|
dt.Add(o)
|
|
|
|
assert.Equal(t, `/
|
|
|
|
potato
|
|
|
|
`, dt.String())
|
|
|
|
o = mockobject.New("dir/subdir/sausage")
|
|
|
|
dt.Add(o)
|
|
|
|
assert.Equal(t, `/
|
|
|
|
potato
|
|
|
|
dir/subdir/
|
|
|
|
sausage
|
|
|
|
`, dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeAddDir(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
d := mockdir.New("potato")
|
|
|
|
dt.Add(d)
|
|
|
|
assert.Equal(t, `/
|
|
|
|
potato/
|
|
|
|
`, dt.String())
|
|
|
|
d = mockdir.New("dir/subdir/sausage")
|
|
|
|
dt.AddDir(d)
|
|
|
|
assert.Equal(t, `/
|
|
|
|
potato/
|
|
|
|
dir/subdir/
|
|
|
|
sausage/
|
|
|
|
dir/subdir/sausage/
|
2022-06-09 19:45:24 +08:00
|
|
|
`, dt.String())
|
|
|
|
d = mockdir.New("")
|
|
|
|
dt.AddDir(d)
|
|
|
|
assert.Equal(t, `/
|
|
|
|
potato/
|
|
|
|
dir/subdir/
|
|
|
|
sausage/
|
|
|
|
dir/subdir/sausage/
|
2019-06-27 22:54:43 +08:00
|
|
|
`, dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeAddEntry(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
d := mockdir.New("dir/subdir/sausagedir")
|
|
|
|
dt.AddEntry(d)
|
|
|
|
o := mockobject.New("dir/subdir2/sausage2")
|
|
|
|
dt.AddEntry(o)
|
|
|
|
|
|
|
|
assert.Equal(t, `/
|
|
|
|
dir/
|
|
|
|
dir/
|
|
|
|
subdir/
|
|
|
|
subdir2/
|
|
|
|
dir/subdir/
|
|
|
|
sausagedir/
|
|
|
|
dir/subdir/sausagedir/
|
|
|
|
dir/subdir2/
|
|
|
|
sausage2
|
|
|
|
`, dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeFind(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
parent, foundObj := dt.Find("dir/subdir/sausage")
|
|
|
|
assert.Equal(t, "dir/subdir", parent)
|
|
|
|
assert.Nil(t, foundObj)
|
|
|
|
|
|
|
|
o := mockobject.New("dir/subdir/sausage")
|
|
|
|
dt.Add(o)
|
|
|
|
|
|
|
|
parent, foundObj = dt.Find("dir/subdir/sausage")
|
|
|
|
assert.Equal(t, "dir/subdir", parent)
|
|
|
|
assert.Equal(t, o, foundObj)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeCheckParent(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
o := mockobject.New("dir/subdir/sausage")
|
|
|
|
dt.Add(o)
|
|
|
|
|
|
|
|
assert.Equal(t, `dir/subdir/
|
|
|
|
sausage
|
|
|
|
`, dt.String())
|
|
|
|
|
2023-06-30 00:38:18 +08:00
|
|
|
dt.checkParent("", "dir/subdir", nil)
|
2019-06-27 22:54:43 +08:00
|
|
|
|
|
|
|
assert.Equal(t, `/
|
|
|
|
dir/
|
|
|
|
dir/
|
|
|
|
subdir/
|
|
|
|
dir/subdir/
|
|
|
|
sausage
|
|
|
|
`, dt.String())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeCheckParents(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
dt.Add(mockobject.New("dir/subdir/sausage"))
|
|
|
|
dt.Add(mockobject.New("dir/subdir2/sausage2"))
|
|
|
|
|
|
|
|
dt.CheckParents("")
|
2019-07-02 23:29:40 +08:00
|
|
|
dt.Sort() // sort since the exact order of adding parents is not defined
|
2019-06-27 22:54:43 +08:00
|
|
|
|
|
|
|
assert.Equal(t, `/
|
|
|
|
dir/
|
|
|
|
dir/
|
|
|
|
subdir/
|
|
|
|
subdir2/
|
|
|
|
dir/subdir/
|
|
|
|
sausage
|
|
|
|
dir/subdir2/
|
|
|
|
sausage2
|
|
|
|
`, dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeSort(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
dt.Add(mockobject.New("dir/subdir/B"))
|
|
|
|
dt.Add(mockobject.New("dir/subdir/A"))
|
|
|
|
|
|
|
|
assert.Equal(t, `dir/subdir/
|
|
|
|
B
|
|
|
|
A
|
|
|
|
`, dt.String())
|
|
|
|
|
|
|
|
dt.Sort()
|
|
|
|
|
|
|
|
assert.Equal(t, `dir/subdir/
|
|
|
|
A
|
|
|
|
B
|
|
|
|
`, dt.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreeDirs(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
dt.Add(mockobject.New("dir/subdir/sausage"))
|
|
|
|
dt.Add(mockobject.New("dir/subdir2/sausage2"))
|
|
|
|
|
|
|
|
dt.CheckParents("")
|
|
|
|
|
|
|
|
assert.Equal(t, []string{
|
|
|
|
"",
|
|
|
|
"dir",
|
|
|
|
"dir/subdir",
|
|
|
|
"dir/subdir2",
|
|
|
|
}, dt.Dirs())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDirTreePrune(t *testing.T) {
|
|
|
|
dt := New()
|
|
|
|
|
|
|
|
dt.Add(mockobject.New("file"))
|
|
|
|
dt.Add(mockobject.New("dir/subdir/sausage"))
|
|
|
|
dt.Add(mockobject.New("dir/subdir2/sausage2"))
|
|
|
|
dt.Add(mockobject.New("dir/file"))
|
|
|
|
dt.Add(mockobject.New("dir2/file"))
|
|
|
|
|
|
|
|
dt.CheckParents("")
|
|
|
|
|
|
|
|
err := dt.Prune(map[string]bool{
|
|
|
|
"dir": true,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, `/
|
|
|
|
file
|
|
|
|
dir2/
|
|
|
|
dir2/
|
|
|
|
file
|
|
|
|
`, dt.String())
|
|
|
|
|
|
|
|
}
|
2023-06-30 00:38:18 +08:00
|
|
|
|
|
|
|
func BenchmarkCheckParents(b *testing.B) {
|
|
|
|
for _, N := range []int{1e2, 1e3, 1e4, 1e5, 1e6} {
|
|
|
|
b.Run(fmt.Sprintf("%d", N), func(b *testing.B) {
|
|
|
|
b.StopTimer()
|
|
|
|
dt := New()
|
|
|
|
for i := 0; i < N; i++ {
|
|
|
|
remote := fmt.Sprintf("dir%09d/file%09d.txt", i, 1)
|
|
|
|
o := mockobject.New(remote)
|
|
|
|
dt.Add(o)
|
|
|
|
}
|
|
|
|
b.StartTimer()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
dt.CheckParents("")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|