github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/dirtree/dirtree_test.go (about) 1 package dirtree 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/rclone/rclone/fstest/mockdir" 8 "github.com/rclone/rclone/fstest/mockobject" 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestNew(t *testing.T) { 14 dt := New() 15 assert.Equal(t, "", dt.String()) 16 } 17 18 func TestParentDir(t *testing.T) { 19 assert.Equal(t, "root/parent", parentDir("root/parent/file")) 20 assert.Equal(t, "parent", parentDir("parent/file")) 21 assert.Equal(t, "", parentDir("parent")) 22 assert.Equal(t, "", parentDir("")) 23 } 24 25 func TestDirTreeAdd(t *testing.T) { 26 dt := New() 27 o := mockobject.New("potato") 28 dt.Add(o) 29 assert.Equal(t, `/ 30 potato 31 `, dt.String()) 32 o = mockobject.New("dir/subdir/sausage") 33 dt.Add(o) 34 assert.Equal(t, `/ 35 potato 36 dir/subdir/ 37 sausage 38 `, dt.String()) 39 } 40 41 func TestDirTreeAddDir(t *testing.T) { 42 dt := New() 43 d := mockdir.New("potato") 44 dt.Add(d) 45 assert.Equal(t, `/ 46 potato/ 47 `, dt.String()) 48 d = mockdir.New("dir/subdir/sausage") 49 dt.AddDir(d) 50 assert.Equal(t, `/ 51 potato/ 52 dir/subdir/ 53 sausage/ 54 dir/subdir/sausage/ 55 `, dt.String()) 56 d = mockdir.New("") 57 dt.AddDir(d) 58 assert.Equal(t, `/ 59 potato/ 60 dir/subdir/ 61 sausage/ 62 dir/subdir/sausage/ 63 `, dt.String()) 64 } 65 66 func TestDirTreeAddEntry(t *testing.T) { 67 dt := New() 68 69 d := mockdir.New("dir/subdir/sausagedir") 70 dt.AddEntry(d) 71 o := mockobject.New("dir/subdir2/sausage2") 72 dt.AddEntry(o) 73 74 assert.Equal(t, `/ 75 dir/ 76 dir/ 77 subdir/ 78 subdir2/ 79 dir/subdir/ 80 sausagedir/ 81 dir/subdir/sausagedir/ 82 dir/subdir2/ 83 sausage2 84 `, dt.String()) 85 } 86 87 func TestDirTreeFind(t *testing.T) { 88 dt := New() 89 90 parent, foundObj := dt.Find("dir/subdir/sausage") 91 assert.Equal(t, "dir/subdir", parent) 92 assert.Nil(t, foundObj) 93 94 o := mockobject.New("dir/subdir/sausage") 95 dt.Add(o) 96 97 parent, foundObj = dt.Find("dir/subdir/sausage") 98 assert.Equal(t, "dir/subdir", parent) 99 assert.Equal(t, o, foundObj) 100 } 101 102 func TestDirTreeCheckParent(t *testing.T) { 103 dt := New() 104 105 o := mockobject.New("dir/subdir/sausage") 106 dt.Add(o) 107 108 assert.Equal(t, `dir/subdir/ 109 sausage 110 `, dt.String()) 111 112 dt.checkParent("", "dir/subdir", nil) 113 114 assert.Equal(t, `/ 115 dir/ 116 dir/ 117 subdir/ 118 dir/subdir/ 119 sausage 120 `, dt.String()) 121 122 } 123 124 func TestDirTreeCheckParents(t *testing.T) { 125 dt := New() 126 127 dt.Add(mockobject.New("dir/subdir/sausage")) 128 dt.Add(mockobject.New("dir/subdir2/sausage2")) 129 130 dt.CheckParents("") 131 dt.Sort() // sort since the exact order of adding parents is not defined 132 133 assert.Equal(t, `/ 134 dir/ 135 dir/ 136 subdir/ 137 subdir2/ 138 dir/subdir/ 139 sausage 140 dir/subdir2/ 141 sausage2 142 `, dt.String()) 143 } 144 145 func TestDirTreeSort(t *testing.T) { 146 dt := New() 147 148 dt.Add(mockobject.New("dir/subdir/B")) 149 dt.Add(mockobject.New("dir/subdir/A")) 150 151 assert.Equal(t, `dir/subdir/ 152 B 153 A 154 `, dt.String()) 155 156 dt.Sort() 157 158 assert.Equal(t, `dir/subdir/ 159 A 160 B 161 `, dt.String()) 162 } 163 164 func TestDirTreeDirs(t *testing.T) { 165 dt := New() 166 167 dt.Add(mockobject.New("dir/subdir/sausage")) 168 dt.Add(mockobject.New("dir/subdir2/sausage2")) 169 170 dt.CheckParents("") 171 172 assert.Equal(t, []string{ 173 "", 174 "dir", 175 "dir/subdir", 176 "dir/subdir2", 177 }, dt.Dirs()) 178 } 179 180 func TestDirTreePrune(t *testing.T) { 181 dt := New() 182 183 dt.Add(mockobject.New("file")) 184 dt.Add(mockobject.New("dir/subdir/sausage")) 185 dt.Add(mockobject.New("dir/subdir2/sausage2")) 186 dt.Add(mockobject.New("dir/file")) 187 dt.Add(mockobject.New("dir2/file")) 188 189 dt.CheckParents("") 190 191 err := dt.Prune(map[string]bool{ 192 "dir": true, 193 }) 194 require.NoError(t, err) 195 196 assert.Equal(t, `/ 197 file 198 dir2/ 199 dir2/ 200 file 201 `, dt.String()) 202 203 } 204 205 func BenchmarkCheckParents(b *testing.B) { 206 for _, N := range []int{1e2, 1e3, 1e4, 1e5, 1e6} { 207 b.Run(fmt.Sprintf("%d", N), func(b *testing.B) { 208 b.StopTimer() 209 dt := New() 210 for i := 0; i < N; i++ { 211 remote := fmt.Sprintf("dir%09d/file%09d.txt", i, 1) 212 o := mockobject.New(remote) 213 dt.Add(o) 214 } 215 b.StartTimer() 216 for n := 0; n < b.N; n++ { 217 dt.CheckParents("") 218 } 219 }) 220 } 221 }