github.com/3JoB/vfs@v1.0.0/filesystem_test.go (about) 1 package vfs 2 3 import ( 4 "errors" 5 "os" 6 "testing" 7 ) 8 9 type openFS struct { 10 Filesystem 11 fn func(name string, flag int, perm os.FileMode) (File, error) 12 } 13 14 func (fs openFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { 15 return fs.fn(name, flag, perm) 16 } 17 18 func TestCreate(t *testing.T) { 19 fs := openFS{ 20 Filesystem: Dummy(errors.New("Not implemented")), 21 fn: func(name string, flag int, perm os.FileMode) (File, error) { 22 if name != "name" { 23 t.Errorf("Invalid name: %s", name) 24 } 25 if flag != os.O_RDWR|os.O_CREATE|os.O_TRUNC { 26 t.Errorf("Invalid flag: %d", flag) 27 } 28 if perm != 0666 { 29 t.Errorf("Invalid perm: %d", perm) 30 } 31 return nil, nil 32 }, 33 } 34 _, err := Create(fs, "name") 35 if err != nil { 36 t.Fatalf("OpenFile not called") 37 } 38 } 39 40 func TestOpen(t *testing.T) { 41 fs := openFS{ 42 Filesystem: Dummy(errors.New("Not implemented")), 43 fn: func(name string, flag int, perm os.FileMode) (File, error) { 44 if name != "name" { 45 t.Errorf("Invalid name: %s", name) 46 } 47 if flag != os.O_RDONLY { 48 t.Errorf("Invalid flag: %d", flag) 49 } 50 if perm != 0 { 51 t.Errorf("Invalid perm: %d", perm) 52 } 53 return nil, nil 54 }, 55 } 56 _, err := Open(fs, "name") 57 if err != nil { 58 t.Fatalf("OpenFile not called") 59 } 60 } 61 62 type mkdirFS struct { 63 Filesystem 64 dirs map[string]os.FileInfo 65 perm os.FileMode 66 } 67 68 func (fs *mkdirFS) Mkdir(name string, perm os.FileMode) error { 69 if _, ok := fs.dirs[name]; ok { 70 return os.ErrExist 71 } 72 fs.perm = perm 73 fs.dirs[name] = DumFileInfo{ 74 IName: name, 75 IDir: true, 76 IMode: perm, 77 } 78 return nil 79 } 80 81 func (fs mkdirFS) Stat(name string) (os.FileInfo, error) { 82 return fs.Lstat(name) 83 } 84 85 func (fs mkdirFS) Lstat(name string) (os.FileInfo, error) { 86 if fi, ok := fs.dirs[name]; ok { 87 return fi, nil 88 } 89 return nil, os.ErrNotExist 90 } 91 92 func TestMkdirAll(t *testing.T) { 93 fs := &mkdirFS{ 94 Filesystem: Dummy(errors.New("Not implemented")), 95 dirs: make(map[string]os.FileInfo), 96 } 97 err := MkdirAll(fs, "/usr/src/linux", 0777) 98 if err != nil { 99 t.Fatalf("Mkdir failed") 100 } 101 if fs.perm != 0777 { 102 t.Errorf("Wrong perm: %d", fs.perm) 103 } 104 if _, ok := fs.dirs["/usr"]; !ok { 105 t.Errorf("Dir not created: /usr") 106 } 107 if _, ok := fs.dirs["/usr/src"]; !ok { 108 t.Errorf("Dir not created: /usr/src") 109 } 110 if _, ok := fs.dirs["/usr/src/linux"]; !ok { 111 t.Errorf("Dir not created: /usr/src/linux") 112 } 113 } 114 115 func TestMkdirAllExists(t *testing.T) { 116 fs := &mkdirFS{ 117 Filesystem: Dummy(errors.New("Not implemented")), 118 dirs: make(map[string]os.FileInfo), 119 } 120 // Make dir 121 fs.dirs["/usr/src/linux"] = DumFileInfo{IName: "linux", IDir: true} 122 123 err := MkdirAll(fs, "/usr/src/linux", 0777) 124 if err != nil { 125 t.Fatalf("Mkdir failed") 126 } 127 } 128 129 func TestMkdirAllFirstExists(t *testing.T) { 130 fs := &mkdirFS{ 131 Filesystem: Dummy(errors.New("Not implemented")), 132 dirs: make(map[string]os.FileInfo), 133 } 134 // Make dir 135 fs.dirs["/usr"] = DumFileInfo{IName: "usr", IDir: true} 136 137 err := MkdirAll(fs, "/usr/src/linux/", 0777) 138 if err != nil { 139 t.Fatalf("Mkdir failed") 140 } 141 142 if _, ok := fs.dirs["/usr/src"]; !ok { 143 t.Errorf("Dir not created: /usr/src") 144 } 145 if _, ok := fs.dirs["/usr/src/linux/"]; !ok { 146 t.Errorf("Dir not created: /usr/src/linux") 147 } 148 } 149 150 func TestMkdirAllFirstExistsNoFile(t *testing.T) { 151 fs := &mkdirFS{ 152 Filesystem: Dummy(errors.New("Not implemented")), 153 dirs: make(map[string]os.FileInfo), 154 } 155 // Make dir 156 fs.dirs["/usr"] = DumFileInfo{IName: "usr", IDir: true} 157 fs.dirs["/usr/src"] = DumFileInfo{IName: "src", IDir: false} 158 159 err := MkdirAll(fs, "/usr/src/linux/linux-4.10", 0777) 160 if err == nil { 161 t.Fatalf("Mkdir failed") 162 } 163 } 164 165 type rmFileinfo struct { 166 DumFileInfo 167 subfiles []*rmFileinfo 168 parent *rmFileinfo 169 } 170 171 type rmFS struct { 172 Filesystem 173 files map[string]*rmFileinfo 174 } 175 176 func (fs *rmFS) ReadDir(path string) ([]os.FileInfo, error) { 177 if fi, ok := fs.files[path]; ok { 178 if fi.IsDir() { 179 s := make([]os.FileInfo, len(fi.subfiles)) 180 for i, sf := range fi.subfiles { 181 s[i] = sf 182 } 183 for _, sf := range s { 184 if sf == nil { 185 panic("sf in readdir nil") 186 } 187 } 188 return s, nil 189 } 190 return nil, ErrNotDirectory 191 } 192 193 return nil, os.ErrNotExist 194 } 195 196 func findRmFileInfoIndex(s []*rmFileinfo, needle *rmFileinfo) int { 197 for i, fi := range s { 198 if fi == needle { 199 return i 200 } 201 } 202 return -1 203 } 204 205 func (fs *rmFS) Remove(name string) error { 206 if fi, ok := fs.files[name]; ok { 207 if fi.IsDir() && len(fi.subfiles) > 0 { 208 return ErrIsDirectory // Not empty 209 } 210 211 // remove references 212 delete(fs.files, name) 213 if fi.parent != nil { 214 if i := findRmFileInfoIndex(fi.parent.subfiles, fi); i >= 0 { 215 fi.parent.subfiles = append(fi.parent.subfiles[:i], fi.parent.subfiles[i+1:]...) 216 } 217 } 218 return nil 219 } 220 221 return &os.PathError{Op: "remove", Path: name, Err: os.ErrNotExist} 222 } 223 224 func TestRemoveAll(t *testing.T) { 225 fs := &rmFS{ 226 Filesystem: Dummy(errors.New("Not implemented")), 227 files: make(map[string]*rmFileinfo), 228 } 229 230 fiTmpFile := &rmFileinfo{ 231 DumFileInfo: DumFileInfo{ 232 IName: "file", 233 IDir: false, 234 }, 235 } 236 237 fiTmp := &rmFileinfo{ 238 DumFileInfo: DumFileInfo{ 239 IName: "tmp", 240 IDir: true, 241 }, 242 subfiles: []*rmFileinfo{ 243 fiTmpFile, 244 }, 245 } 246 247 fiRoot := &rmFileinfo{ 248 DumFileInfo: DumFileInfo{ 249 IName: "/", 250 IDir: true, 251 }, 252 subfiles: []*rmFileinfo{ 253 fiTmp, 254 }, 255 } 256 fs.files["/tmp/file"] = fiTmpFile 257 fiTmpFile.parent = fiTmp 258 fs.files["/tmp"] = fiTmp 259 fiTmp.parent = fiRoot 260 fs.files["/"] = fiRoot 261 262 fiTmpFile.Name() 263 err := RemoveAll(fs, "/tmp") 264 if err != nil { 265 t.Errorf("Unexpected error remove all: %s", err) 266 } 267 268 if _, ok := fs.files["/tmp/file"]; ok { 269 t.Errorf("/tmp/file was not removed") 270 } 271 272 if _, ok := fs.files["/tmp"]; ok { 273 t.Errorf("/tmp was not removed") 274 } 275 276 if _, ok := fs.files["/"]; !ok { 277 t.Errorf("/ was removed") 278 } 279 }