github.com/pbberlin/tools@v0.0.0-20160910141205-7aa5421c2169/os/fsi/tests/dirwalk_test_core.go (about) 1 package tests 2 3 import ( 4 "bytes" 5 "os" 6 "strings" 7 8 "appengine/datastore" 9 10 "github.com/pbberlin/tools/os/fsi" 11 "github.com/pbberlin/tools/os/fsi/common" 12 "github.com/pbberlin/tools/os/fsi/dsfs" 13 14 pth "path" 15 ) 16 17 const relPsep = "" 18 const relOpt = "" 19 20 var rel = "." 21 22 func CreateSys(fs fsi.FileSystem) (*bytes.Buffer, string) { 23 24 bb := new(bytes.Buffer) 25 wpf(bb, "--------create-dirs---------\n") 26 27 fc1 := func(p []string) { 28 path := pth.Join(p...) 29 err := fs.MkdirAll(relOpt+path, os.ModePerm) 30 if err != nil { 31 wpf(bb, "MkdirAll failed %v\n", err) 32 } 33 } 34 35 fc1([]string{"ch1"}) 36 fc1([]string{"ch1", "ch2"}) 37 fc1([]string{"ch1", "ch2", "ch3"}) 38 fc1([]string{"ch1", "ch2", "ch3", "ch4"}) 39 fc1([]string{"ch1", "ch2a"}) 40 fc1([]string{"ch1A"}) 41 fc1([]string{"ch1B"}) 42 fc1([]string{"d1", "d2", "d3_secretdir", "neverwalked"}) 43 fc1([]string{"d1", "d2", "d3a", "willwalk"}) 44 45 wpf(bb, "\n--------retrieve-dirs---------\n") 46 47 // retrieval 48 gotByPath := 0 49 wntByPath := 5 50 fc2 := func(p []string) { 51 path := pth.Join(p...) 52 wpf(bb, "searching... %q\n", path) 53 f, err := fs.Lstat(relOpt + path) 54 if err != nil { 55 wpf(bb, " nothing retrieved - err %v\n", err) 56 } else { 57 wpf(bb, " fnd %v \n", pth.Join(path, f.Name())) 58 gotByPath++ 59 } 60 } 61 fc2([]string{"ch1"}) 62 fc2([]string{"ch1", "ch2"}) 63 fc2([]string{"ch1", "non-exist-dir"}) 64 fc2([]string{"ch1", "ch2", "ch3"}) 65 fc2([]string{"ch1A"}) 66 fc2([]string{rel}) 67 68 wpf(bb, "\nfnd %v of %v dirs \n", gotByPath, wntByPath) 69 70 wpf(bb, "\n-------create and save some files----\n") 71 72 fc4a := func(name, content string) { 73 err := fs.WriteFile(relOpt+name, []byte(content), os.ModePerm) 74 if err != nil { 75 wpf(bb, "WriteFile %v failed %v\n", name, err) 76 } 77 } 78 fc4b := func(name, content string) { 79 f, err := fs.Create(relOpt + name) 80 if err != nil { 81 wpf(bb, "Create %v failed %v\n", name, err) 82 } 83 if err != nil { 84 return 85 } 86 _, err = f.WriteString(content) 87 if err != nil { 88 wpf(bb, "WriteString %v failed %v\n", name, err) 89 } 90 err = f.Close() 91 if err != nil { 92 wpf(bb, "Sync %v failed %v\n", name, err) 93 } 94 } 95 96 fc4a("ch1/ch2/file_1", "content 1") 97 fc4b("ch1/ch2/file_2", "content 2") 98 fc4a("ch1/ch2/ch3/file3", "another content") 99 fc4b(relPsep+"file4", "chq content 2") 100 101 // fsc, ok := memfs.Unwrap(fs) 102 // if ok { 103 // fsc.Dump() 104 // } 105 // return bb, "" 106 107 wpf(bb, "\n-------retrieve files again----\n\n") 108 109 gotNumFiles := 0 110 wntNumFiles := 4 111 gotSizeFiles := 0 112 wntSizeFiles := 9 + 9 + 15 + 13 113 114 fc5 := func(path string) { 115 files, err := fs.ReadDir(relOpt + path) 116 if err != nil { 117 wpf(bb, "filesByPath %v failed %v\n", path, err) 118 } 119 wpf(bb, " srch %-20q yielded %v dirs+files\n", relOpt+path, len(files)) 120 121 for k, v := range files { 122 if v.IsDir() { 123 wpf(bb, " skip dir %v \n", v.Name()) 124 continue 125 } 126 data, err := fs.ReadFile(pth.Join(path, v.Name())) 127 if err != nil { 128 wpf(bb, "could not get content of %v => %v\n", pth.Join(path, v.Name()), err) 129 } 130 wpf(bb, " %v - %v %s\n", k, pth.Join(path, v.Name()), data) 131 gotNumFiles++ 132 gotSizeFiles += len(data) 133 } 134 } 135 136 fc5("ch1/ch2") 137 fc5("ch1/ch2/ch3") 138 fc5(rel) 139 140 wpf(bb, "\n") 141 142 wpf(bb, "fnd %2v of %2v fils \n", gotNumFiles, wntNumFiles) 143 wpf(bb, "fnd %2v of %2v fsize \n", gotSizeFiles, wntSizeFiles) 144 wpf(bb, "\n") 145 146 testRes := "" 147 if gotNumFiles != wntNumFiles { 148 testRes += spf("Create files num : wnt %2v - got %v\n", wntNumFiles, gotNumFiles) 149 } 150 if gotSizeFiles != wntSizeFiles { 151 testRes += spf("Create files size: wnt %2v - got %v\n", wntSizeFiles, gotSizeFiles) 152 } 153 return bb, testRes 154 } 155 156 func RetrieveByReadDir(fs fsi.FileSystem) (*bytes.Buffer, string) { 157 158 bb := new(bytes.Buffer) 159 wpf(bb, "--------retrieve by readDir---------\n\n") 160 161 wnt1 := []int{2, 3, 2, 5} 162 wnt2 := []int{2, 2, 5} 163 got := []int{} 164 165 fc3 := func(path string) { 166 wpf(bb, "searching %q\n", path) 167 children, err := fs.ReadDir(path) 168 if err != nil { 169 wpf(bb, " nothing retrieved - err %v\n", err) 170 } else { 171 for k, v := range children { 172 wpf(bb, " child #%-2v %-24v\n", k, pth.Join(path, v.Name())) 173 } 174 got = append(got, len(children)) 175 } 176 wpf(bb, "\n") 177 } 178 179 fc3(`ch1/ch2/ch3`) 180 fc3(`ch1/ch2`) 181 fc3(`ch1`) 182 fc3(rel) 183 184 testRes := "" 185 if spf("%+v", wnt1) != spf("%+v", got) && 186 spf("%+v", wnt2) != spf("%+v", got) { 187 testRes = spf("ReadDir: wnt %v or %v - got %v", wnt1, wnt2, got) 188 } 189 return bb, testRes 190 191 } 192 193 func RetrieveByQuery(fs fsi.FileSystem) (*bytes.Buffer, string) { 194 195 bb := new(bytes.Buffer) 196 197 wnt1 := []int{1, 1, 2, 1, 4, 2, 4, 13} 198 wnt2 := []int{2, 2, 4, 11} 199 got := []int{} 200 201 fsConcrete, ok := dsfs.Unwrap(fs) 202 if !ok { 203 wpf(bb, "--------retrieve by query UNSUPPORTED---------\n\n") 204 return bb, "" 205 } 206 207 wpf(bb, "--------retrieve by query---------\n\n") 208 209 fc3 := func(path string, direct bool) { 210 mode := "direct" 211 if !direct { 212 mode = "all" 213 } 214 wpf(bb, "searching %-6v %q\n", mode, path) 215 children, err := fsConcrete.SubtreeByPath(path, direct) 216 if err != nil { 217 wpf(bb, " nothing retrieved - err %v\n", err) 218 } else { 219 for k, v := range children { 220 wpf(bb, " child #%-2v %-5v ... %-24v\n", k, path, v.Name()) 221 } 222 got = append(got, len(children)) 223 } 224 wpf(bb, "\n") 225 } 226 227 fc3(`ch1/ch2/ch3`, false) 228 fc3(`ch1/ch2/ch3`, true) 229 230 fc3(`ch1/ch2`, false) 231 fc3(`ch1/ch2`, true) 232 233 fc3(`ch1`, false) 234 fc3(`ch1`, true) 235 236 fc3(``, true) 237 fc3(``, false) 238 239 testRes := "" 240 if spf("%+v", wnt1) != spf("%+v", got) && 241 spf("%+v", wnt2) != spf("%+v", got) { 242 testRes = spf("IdxQuery: wnt %v or %v - got %v", wnt1, wnt2, got) 243 } 244 return bb, testRes 245 246 } 247 248 func WalkDirs(fs fsi.FileSystem) (*bytes.Buffer, string) { 249 250 bb := new(bytes.Buffer) 251 wpf(bb, "-------filewalk----\n\n") 252 253 wnt := []int{16, 6, 3} 254 wnt2 := []int{13, 3, 0} 255 got := []int{} 256 257 cntr := 0 258 walkFunc := func(path string, f os.FileInfo, err error) error { 259 if err != nil { 260 wpf(bb, "error on visiting %q => %v \n", path, err) 261 if err == datastore.ErrNoSuchEntity || err == os.ErrNotExist { 262 return nil // dont break the walk on this, it's just a stale directory 263 } 264 return err // this would break the walk on any error; notably dir-index entries, that have been deleted since. 265 } 266 if strings.HasSuffix(path, "_secretdir") { 267 return common.SkipDir // do not delve deeper 268 } 269 if err == os.ErrInvalid { 270 return err // calling off the walk 271 } 272 tp := "file" 273 if f != nil { 274 if f.IsDir() { 275 tp = "dir " 276 } 277 } 278 wpf(bb, "Visited: %s %s \n", tp, path) 279 cntr++ 280 // if cntr > 100 { 281 // return fmt.Errorf("too many walk recursions%v", cntr) 282 // } 283 return nil 284 } 285 286 var err error 287 288 cntr = 0 289 err = common.Walk(fs, rel, walkFunc) 290 wpf(bb, "fs.Walk() returned %v\n\n", err) 291 got = append(got, cntr) 292 293 cntr = 0 294 err = common.Walk(fs, "ch1/ch2", walkFunc) 295 wpf(bb, "fs.Walk() returned %v\n\n", err) 296 got = append(got, cntr) 297 298 cntr = 0 299 err = common.Walk(fs, "ch1/ch2/ch3", walkFunc) 300 wpf(bb, "fs.Walk() returned %v\n\n", err) 301 got = append(got, cntr) 302 303 testRes := "" 304 if spf("%+v", wnt) != spf("%+v", got) && 305 spf("%+v", wnt2) != spf("%+v", got) { 306 testRes = spf("WalkDir: wnt %v or %v - got %v", wnt, wnt2, got) 307 } 308 309 return bb, testRes 310 } 311 312 func RemoveSubtree(fs fsi.FileSystem) (*bytes.Buffer, string) { 313 314 bb := new(bytes.Buffer) 315 316 wpf(bb, "-------removedir----\n\n") 317 err := fs.RemoveAll("ch1/ch2/ch3") 318 wpf(bb, "fs.RemoveAll() returned %v\n\n", err) 319 320 testRes := "" 321 if err != nil { 322 testRes = spf("RemoveTree: %v", err) 323 } 324 return bb, testRes 325 }