github.com/trdyer/afero@v1.1.1/memmap_test.go (about) 1 package afero 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 "runtime" 9 "testing" 10 "time" 11 ) 12 13 func TestNormalizePath(t *testing.T) { 14 type test struct { 15 input string 16 expected string 17 } 18 19 data := []test{ 20 {".", FilePathSeparator}, 21 {"./", FilePathSeparator}, 22 {"..", FilePathSeparator}, 23 {"../", FilePathSeparator}, 24 {"./..", FilePathSeparator}, 25 {"./../", FilePathSeparator}, 26 } 27 28 for i, d := range data { 29 cpath := normalizePath(d.input) 30 if d.expected != cpath { 31 t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, cpath) 32 } 33 } 34 } 35 36 func TestPathErrors(t *testing.T) { 37 path := filepath.Join(".", "some", "path") 38 path2 := filepath.Join(".", "different", "path") 39 fs := NewMemMapFs() 40 perm := os.FileMode(0755) 41 42 // relevant functions: 43 // func (m *MemMapFs) Chmod(name string, mode os.FileMode) error 44 // func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error 45 // func (m *MemMapFs) Create(name string) (File, error) 46 // func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error 47 // func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error 48 // func (m *MemMapFs) Open(name string) (File, error) 49 // func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) 50 // func (m *MemMapFs) Remove(name string) error 51 // func (m *MemMapFs) Rename(oldname, newname string) error 52 // func (m *MemMapFs) Stat(name string) (os.FileInfo, error) 53 54 err := fs.Chmod(path, perm) 55 checkPathError(t, err, "Chmod") 56 57 err = fs.Chtimes(path, time.Now(), time.Now()) 58 checkPathError(t, err, "Chtimes") 59 60 // fs.Create doesn't return an error 61 62 err = fs.Mkdir(path2, perm) 63 if err != nil { 64 t.Error(err) 65 } 66 err = fs.Mkdir(path2, perm) 67 checkPathError(t, err, "Mkdir") 68 69 err = fs.MkdirAll(path2, perm) 70 if err != nil { 71 t.Error("MkdirAll:", err) 72 } 73 74 _, err = fs.Open(path) 75 checkPathError(t, err, "Open") 76 77 _, err = fs.OpenFile(path, os.O_RDWR, perm) 78 checkPathError(t, err, "OpenFile") 79 80 err = fs.Remove(path) 81 checkPathError(t, err, "Remove") 82 83 err = fs.RemoveAll(path) 84 if err != nil { 85 t.Error("RemoveAll:", err) 86 } 87 88 err = fs.Rename(path, path2) 89 checkPathError(t, err, "Rename") 90 91 _, err = fs.Stat(path) 92 checkPathError(t, err, "Stat") 93 } 94 95 func checkPathError(t *testing.T, err error, op string) { 96 pathErr, ok := err.(*os.PathError) 97 if !ok { 98 t.Error(op+":", err, "is not a os.PathError") 99 return 100 } 101 _, ok = pathErr.Err.(*os.PathError) 102 if ok { 103 t.Error(op+":", err, "contains another os.PathError") 104 } 105 } 106 107 // Ensure Permissions are set on OpenFile/Mkdir/MkdirAll 108 func TestPermSet(t *testing.T) { 109 const fileName = "/myFileTest" 110 const dirPath = "/myDirTest" 111 const dirPathAll = "/my/path/to/dir" 112 113 const fileMode = os.FileMode(0765) 114 // directories will also have the directory bit set 115 const dirMode = fileMode | os.ModeDir 116 117 fs := NewMemMapFs() 118 119 // Test Openfile 120 f, err := fs.OpenFile(fileName, os.O_CREATE, fileMode) 121 if err != nil { 122 t.Errorf("OpenFile Create failed: %s", err) 123 return 124 } 125 f.Close() 126 127 s, err := fs.Stat(fileName) 128 if err != nil { 129 t.Errorf("Stat failed: %s", err) 130 return 131 } 132 if s.Mode().String() != fileMode.String() { 133 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), fileMode.String()) 134 return 135 } 136 137 // Test Mkdir 138 err = fs.Mkdir(dirPath, dirMode) 139 if err != nil { 140 t.Errorf("MkDir Create failed: %s", err) 141 return 142 } 143 s, err = fs.Stat(dirPath) 144 if err != nil { 145 t.Errorf("Stat failed: %s", err) 146 return 147 } 148 // sets File 149 if s.Mode().String() != dirMode.String() { 150 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String()) 151 return 152 } 153 154 // Test MkdirAll 155 err = fs.MkdirAll(dirPathAll, dirMode) 156 if err != nil { 157 t.Errorf("MkDir Create failed: %s", err) 158 return 159 } 160 s, err = fs.Stat(dirPathAll) 161 if err != nil { 162 t.Errorf("Stat failed: %s", err) 163 return 164 } 165 if s.Mode().String() != dirMode.String() { 166 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String()) 167 return 168 } 169 } 170 171 // Fails if multiple file objects use the same file.at counter in MemMapFs 172 func TestMultipleOpenFiles(t *testing.T) { 173 defer removeAllTestFiles(t) 174 const fileName = "afero-demo2.txt" 175 176 var data = make([][]byte, len(Fss)) 177 178 for i, fs := range Fss { 179 dir := testDir(fs) 180 path := filepath.Join(dir, fileName) 181 fh1, err := fs.Create(path) 182 if err != nil { 183 t.Error("fs.Create failed: " + err.Error()) 184 } 185 _, err = fh1.Write([]byte("test")) 186 if err != nil { 187 t.Error("fh.Write failed: " + err.Error()) 188 } 189 _, err = fh1.Seek(0, os.SEEK_SET) 190 if err != nil { 191 t.Error(err) 192 } 193 194 fh2, err := fs.OpenFile(path, os.O_RDWR, 0777) 195 if err != nil { 196 t.Error("fs.OpenFile failed: " + err.Error()) 197 } 198 _, err = fh2.Seek(0, os.SEEK_END) 199 if err != nil { 200 t.Error(err) 201 } 202 _, err = fh2.Write([]byte("data")) 203 if err != nil { 204 t.Error(err) 205 } 206 err = fh2.Close() 207 if err != nil { 208 t.Error(err) 209 } 210 211 _, err = fh1.Write([]byte("data")) 212 if err != nil { 213 t.Error(err) 214 } 215 err = fh1.Close() 216 if err != nil { 217 t.Error(err) 218 } 219 // the file now should contain "datadata" 220 data[i], err = ReadFile(fs, path) 221 if err != nil { 222 t.Error(err) 223 } 224 } 225 226 for i, fs := range Fss { 227 if i == 0 { 228 continue 229 } 230 if string(data[0]) != string(data[i]) { 231 t.Errorf("%s and %s don't behave the same\n"+ 232 "%s: \"%s\"\n%s: \"%s\"\n", 233 Fss[0].Name(), fs.Name(), Fss[0].Name(), data[0], fs.Name(), data[i]) 234 } 235 } 236 } 237 238 // Test if file.Write() fails when opened as read only 239 func TestReadOnly(t *testing.T) { 240 defer removeAllTestFiles(t) 241 const fileName = "afero-demo.txt" 242 243 for _, fs := range Fss { 244 dir := testDir(fs) 245 path := filepath.Join(dir, fileName) 246 247 f, err := fs.Create(path) 248 if err != nil { 249 t.Error(fs.Name()+":", "fs.Create failed: "+err.Error()) 250 } 251 _, err = f.Write([]byte("test")) 252 if err != nil { 253 t.Error(fs.Name()+":", "Write failed: "+err.Error()) 254 } 255 f.Close() 256 257 f, err = fs.Open(path) 258 if err != nil { 259 t.Error("fs.Open failed: " + err.Error()) 260 } 261 _, err = f.Write([]byte("data")) 262 if err == nil { 263 t.Error(fs.Name()+":", "No write error") 264 } 265 f.Close() 266 267 f, err = fs.OpenFile(path, os.O_RDONLY, 0644) 268 if err != nil { 269 t.Error("fs.Open failed: " + err.Error()) 270 } 271 _, err = f.Write([]byte("data")) 272 if err == nil { 273 t.Error(fs.Name()+":", "No write error") 274 } 275 f.Close() 276 } 277 } 278 279 func TestWriteCloseTime(t *testing.T) { 280 defer removeAllTestFiles(t) 281 const fileName = "afero-demo.txt" 282 283 for _, fs := range Fss { 284 dir := testDir(fs) 285 path := filepath.Join(dir, fileName) 286 287 f, err := fs.Create(path) 288 if err != nil { 289 t.Error(fs.Name()+":", "fs.Create failed: "+err.Error()) 290 } 291 f.Close() 292 293 f, err = fs.Create(path) 294 if err != nil { 295 t.Error(fs.Name()+":", "fs.Create failed: "+err.Error()) 296 } 297 fi, err := f.Stat() 298 if err != nil { 299 t.Error(fs.Name()+":", "Stat failed: "+err.Error()) 300 } 301 timeBefore := fi.ModTime() 302 303 // sorry for the delay, but we have to make sure time advances, 304 // also on non Un*x systems... 305 switch runtime.GOOS { 306 case "windows": 307 time.Sleep(2 * time.Second) 308 case "darwin": 309 time.Sleep(1 * time.Second) 310 default: // depending on the FS, this may work with < 1 second, on my old ext3 it does not 311 time.Sleep(1 * time.Second) 312 } 313 314 _, err = f.Write([]byte("test")) 315 if err != nil { 316 t.Error(fs.Name()+":", "Write failed: "+err.Error()) 317 } 318 f.Close() 319 fi, err = fs.Stat(path) 320 if err != nil { 321 t.Error(fs.Name()+":", "fs.Stat failed: "+err.Error()) 322 } 323 if fi.ModTime().Equal(timeBefore) { 324 t.Error(fs.Name()+":", "ModTime was not set on Close()") 325 } 326 } 327 } 328 329 // This test should be run with the race detector on: 330 // go test -race -v -timeout 10s -run TestRacingDeleteAndClose 331 func TestRacingDeleteAndClose(t *testing.T) { 332 fs := NewMemMapFs() 333 pathname := "testfile" 334 f, err := fs.Create(pathname) 335 if err != nil { 336 t.Fatal(err) 337 } 338 339 in := make(chan bool) 340 341 go func() { 342 <-in 343 f.Close() 344 }() 345 go func() { 346 <-in 347 fs.Remove(pathname) 348 }() 349 close(in) 350 } 351 352 // This test should be run with the race detector on: 353 // go test -run TestMemFsDataRace -race 354 func TestMemFsDataRace(t *testing.T) { 355 const dir = "test_dir" 356 fs := NewMemMapFs() 357 358 if err := fs.MkdirAll(dir, 0777); err != nil { 359 t.Fatal(err) 360 } 361 362 const n = 1000 363 done := make(chan struct{}) 364 365 go func() { 366 defer close(done) 367 for i := 0; i < n; i++ { 368 fname := filepath.Join(dir, fmt.Sprintf("%d.txt", i)) 369 if err := WriteFile(fs, fname, []byte(""), 0777); err != nil { 370 panic(err) 371 } 372 if err := fs.Remove(fname); err != nil { 373 panic(err) 374 } 375 } 376 }() 377 378 loop: 379 for { 380 select { 381 case <-done: 382 break loop 383 default: 384 _, err := ReadDir(fs, dir) 385 if err != nil { 386 t.Fatal(err) 387 } 388 } 389 } 390 } 391 392 func TestMemFsDirMode(t *testing.T) { 393 fs := NewMemMapFs() 394 err := fs.Mkdir("/testDir1", 0644) 395 if err != nil { 396 t.Error(err) 397 } 398 err = fs.MkdirAll("/sub/testDir2", 0644) 399 if err != nil { 400 t.Error(err) 401 } 402 info, err := fs.Stat("/testDir1") 403 if err != nil { 404 t.Error(err) 405 } 406 if !info.IsDir() { 407 t.Error("should be a directory") 408 } 409 if !info.Mode().IsDir() { 410 t.Error("FileMode is not directory") 411 } 412 info, err = fs.Stat("/sub/testDir2") 413 if err != nil { 414 t.Error(err) 415 } 416 if !info.IsDir() { 417 t.Error("should be a directory") 418 } 419 if !info.Mode().IsDir() { 420 t.Error("FileMode is not directory") 421 } 422 } 423 424 func TestMemFsUnexpectedEOF(t *testing.T) { 425 t.Parallel() 426 427 fs := NewMemMapFs() 428 429 if err := WriteFile(fs, "file.txt", []byte("abc"), 0777); err != nil { 430 t.Fatal(err) 431 } 432 433 f, err := fs.Open("file.txt") 434 if err != nil { 435 t.Fatal(err) 436 } 437 defer f.Close() 438 439 // Seek beyond the end. 440 _, err = f.Seek(512, 0) 441 if err != nil { 442 t.Fatal(err) 443 } 444 445 buff := make([]byte, 256) 446 _, err = io.ReadAtLeast(f, buff, 256) 447 448 if err != io.ErrUnexpectedEOF { 449 t.Fatal("Expected ErrUnexpectedEOF") 450 } 451 }