memmap_test.go - afero - [fork] go afero port for 9front
 (HTM) git clone https://git.drkhsh.at/afero.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       memmap_test.go (20689B)
       ---
            1 package afero
            2 
            3 import (
            4         "fmt"
            5         "io"
            6         "io/fs"
            7         "os"
            8         "path/filepath"
            9         "runtime"
           10         "strings"
           11         "sync"
           12         "testing"
           13         "time"
           14 )
           15 
           16 func TestNormalizePath(t *testing.T) {
           17         type test struct {
           18                 input    string
           19                 expected string
           20         }
           21 
           22         data := []test{
           23                 {".", FilePathSeparator},
           24                 {"./", FilePathSeparator},
           25                 {"..", FilePathSeparator},
           26                 {"../", FilePathSeparator},
           27                 {"./..", FilePathSeparator},
           28                 {"./../", FilePathSeparator},
           29         }
           30 
           31         for i, d := range data {
           32                 cpath := normalizePath(d.input)
           33                 if d.expected != cpath {
           34                         t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, cpath)
           35                 }
           36         }
           37 }
           38 
           39 func TestPathErrors(t *testing.T) {
           40         path := filepath.Join(".", "some", "path")
           41         path2 := filepath.Join(".", "different", "path")
           42         fs := NewMemMapFs()
           43         perm := os.FileMode(0o755)
           44         uid := 1000
           45         gid := 1000
           46 
           47         // relevant functions:
           48         // func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
           49         // func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error
           50         // func (m *MemMapFs) Create(name string) (File, error)
           51         // func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error
           52         // func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error
           53         // func (m *MemMapFs) Open(name string) (File, error)
           54         // func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
           55         // func (m *MemMapFs) Remove(name string) error
           56         // func (m *MemMapFs) Rename(oldname, newname string) error
           57         // func (m *MemMapFs) Stat(name string) (os.FileInfo, error)
           58 
           59         err := fs.Chmod(path, perm)
           60         checkPathError(t, err, "Chmod")
           61 
           62         err = fs.Chown(path, uid, gid)
           63         checkPathError(t, err, "Chown")
           64 
           65         err = fs.Chtimes(path, time.Now(), time.Now())
           66         checkPathError(t, err, "Chtimes")
           67 
           68         // fs.Create doesn't return an error
           69 
           70         err = fs.Mkdir(path2, perm)
           71         if err != nil {
           72                 t.Error(err)
           73         }
           74         err = fs.Mkdir(path2, perm)
           75         checkPathError(t, err, "Mkdir")
           76 
           77         err = fs.MkdirAll(path2, perm)
           78         if err != nil {
           79                 t.Error("MkdirAll:", err)
           80         }
           81 
           82         _, err = fs.Open(path)
           83         checkPathError(t, err, "Open")
           84 
           85         _, err = fs.OpenFile(path, os.O_RDWR, perm)
           86         checkPathError(t, err, "OpenFile")
           87 
           88         err = fs.Remove(path)
           89         checkPathError(t, err, "Remove")
           90 
           91         err = fs.RemoveAll(path)
           92         if err != nil {
           93                 t.Error("RemoveAll:", err)
           94         }
           95 
           96         err = fs.Rename(path, path2)
           97         checkPathError(t, err, "Rename")
           98 
           99         _, err = fs.Stat(path)
          100         checkPathError(t, err, "Stat")
          101 }
          102 
          103 func checkPathError(t *testing.T, err error, op string) {
          104         pathErr, ok := err.(*os.PathError)
          105         if !ok {
          106                 t.Error(op+":", err, "is not a os.PathError")
          107                 return
          108         }
          109         _, ok = pathErr.Err.(*os.PathError)
          110         if ok {
          111                 t.Error(op+":", err, "contains another os.PathError")
          112         }
          113 }
          114 
          115 // Ensure os.O_EXCL is correctly handled.
          116 func TestOpenFileExcl(t *testing.T) {
          117         const fileName = "/myFileTest"
          118         const fileMode = os.FileMode(0o765)
          119 
          120         fs := NewMemMapFs()
          121 
          122         // First creation should succeed.
          123         f, err := fs.OpenFile(fileName, os.O_CREATE|os.O_EXCL, fileMode)
          124         if err != nil {
          125                 t.Errorf("OpenFile Create Excl failed: %s", err)
          126                 return
          127         }
          128         f.Close()
          129 
          130         // Second creation should fail.
          131         _, err = fs.OpenFile(fileName, os.O_CREATE|os.O_EXCL, fileMode)
          132         if err == nil {
          133                 t.Errorf("OpenFile Create Excl should have failed, but it didn't")
          134         }
          135         checkPathError(t, err, "Open")
          136 }
          137 
          138 // Ensure Permissions are set on OpenFile/Mkdir/MkdirAll
          139 func TestPermSet(t *testing.T) {
          140         const fileName = "/myFileTest"
          141         const dirPath = "/myDirTest"
          142         const dirPathAll = "/my/path/to/dir"
          143 
          144         const fileMode = os.FileMode(0o765)
          145         // directories will also have the directory bit set
          146         const dirMode = fileMode | os.ModeDir
          147 
          148         fs := NewMemMapFs()
          149 
          150         // Test Openfile
          151         f, err := fs.OpenFile(fileName, os.O_CREATE, fileMode)
          152         if err != nil {
          153                 t.Errorf("OpenFile Create failed: %s", err)
          154                 return
          155         }
          156         f.Close()
          157 
          158         s, err := fs.Stat(fileName)
          159         if err != nil {
          160                 t.Errorf("Stat failed: %s", err)
          161                 return
          162         }
          163         if s.Mode().String() != fileMode.String() {
          164                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), fileMode.String())
          165                 return
          166         }
          167 
          168         // Test Mkdir
          169         err = fs.Mkdir(dirPath, dirMode)
          170         if err != nil {
          171                 t.Errorf("MkDir Create failed: %s", err)
          172                 return
          173         }
          174         s, err = fs.Stat(dirPath)
          175         if err != nil {
          176                 t.Errorf("Stat failed: %s", err)
          177                 return
          178         }
          179         // sets File
          180         if s.Mode().String() != dirMode.String() {
          181                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
          182                 return
          183         }
          184 
          185         // Test MkdirAll
          186         err = fs.MkdirAll(dirPathAll, dirMode)
          187         if err != nil {
          188                 t.Errorf("MkDir Create failed: %s", err)
          189                 return
          190         }
          191         s, err = fs.Stat(dirPathAll)
          192         if err != nil {
          193                 t.Errorf("Stat failed: %s", err)
          194                 return
          195         }
          196         if s.Mode().String() != dirMode.String() {
          197                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
          198                 return
          199         }
          200 }
          201 
          202 // Fails if multiple file objects use the same file.at counter in MemMapFs
          203 func TestMultipleOpenFiles(t *testing.T) {
          204         defer removeAllTestFiles(t)
          205         const fileName = "afero-demo2.txt"
          206 
          207         data := make([][]byte, len(Fss))
          208 
          209         for i, fs := range Fss {
          210                 dir := testDir(fs)
          211                 path := filepath.Join(dir, fileName)
          212                 fh1, err := fs.Create(path)
          213                 if err != nil {
          214                         t.Error("fs.Create failed: " + err.Error())
          215                 }
          216                 _, err = fh1.Write([]byte("test"))
          217                 if err != nil {
          218                         t.Error("fh.Write failed: " + err.Error())
          219                 }
          220                 _, err = fh1.Seek(0, io.SeekStart)
          221                 if err != nil {
          222                         t.Error(err)
          223                 }
          224 
          225                 fh2, err := fs.OpenFile(path, os.O_RDWR, 0o777)
          226                 if err != nil {
          227                         t.Error("fs.OpenFile failed: " + err.Error())
          228                 }
          229                 _, err = fh2.Seek(0, io.SeekEnd)
          230                 if err != nil {
          231                         t.Error(err)
          232                 }
          233                 _, err = fh2.Write([]byte("data"))
          234                 if err != nil {
          235                         t.Error(err)
          236                 }
          237                 err = fh2.Close()
          238                 if err != nil {
          239                         t.Error(err)
          240                 }
          241 
          242                 _, err = fh1.Write([]byte("data"))
          243                 if err != nil {
          244                         t.Error(err)
          245                 }
          246                 err = fh1.Close()
          247                 if err != nil {
          248                         t.Error(err)
          249                 }
          250                 // the file now should contain "datadata"
          251                 data[i], err = ReadFile(fs, path)
          252                 if err != nil {
          253                         t.Error(err)
          254                 }
          255         }
          256 
          257         for i, fs := range Fss {
          258                 if i == 0 {
          259                         continue
          260                 }
          261                 if string(data[0]) != string(data[i]) {
          262                         t.Errorf("%s and %s don't behave the same\n"+
          263                                 "%s: \"%s\"\n%s: \"%s\"\n",
          264                                 Fss[0].Name(), fs.Name(), Fss[0].Name(), data[0], fs.Name(), data[i])
          265                 }
          266         }
          267 }
          268 
          269 // Test if file.Write() fails when opened as read only
          270 func TestReadOnly(t *testing.T) {
          271         defer removeAllTestFiles(t)
          272         const fileName = "afero-demo.txt"
          273 
          274         for _, fs := range Fss {
          275                 dir := testDir(fs)
          276                 path := filepath.Join(dir, fileName)
          277 
          278                 f, err := fs.Create(path)
          279                 if err != nil {
          280                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
          281                 }
          282                 _, err = f.Write([]byte("test"))
          283                 if err != nil {
          284                         t.Error(fs.Name()+":", "Write failed: "+err.Error())
          285                 }
          286                 f.Close()
          287 
          288                 f, err = fs.Open(path)
          289                 if err != nil {
          290                         t.Error("fs.Open failed: " + err.Error())
          291                 }
          292                 _, err = f.Write([]byte("data"))
          293                 if err == nil {
          294                         t.Error(fs.Name()+":", "No write error")
          295                 }
          296                 f.Close()
          297 
          298                 f, err = fs.OpenFile(path, os.O_RDONLY, 0o644)
          299                 if err != nil {
          300                         t.Error("fs.Open failed: " + err.Error())
          301                 }
          302                 _, err = f.Write([]byte("data"))
          303                 if err == nil {
          304                         t.Error(fs.Name()+":", "No write error")
          305                 }
          306                 f.Close()
          307         }
          308 }
          309 
          310 func TestWriteCloseTime(t *testing.T) {
          311         defer removeAllTestFiles(t)
          312         const fileName = "afero-demo.txt"
          313 
          314         for _, fs := range Fss {
          315                 dir := testDir(fs)
          316                 path := filepath.Join(dir, fileName)
          317 
          318                 f, err := fs.Create(path)
          319                 if err != nil {
          320                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
          321                 }
          322                 f.Close()
          323 
          324                 f, err = fs.Create(path)
          325                 if err != nil {
          326                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
          327                 }
          328                 fi, err := f.Stat()
          329                 if err != nil {
          330                         t.Error(fs.Name()+":", "Stat failed: "+err.Error())
          331                 }
          332                 timeBefore := fi.ModTime()
          333 
          334                 // sorry for the delay, but we have to make sure time advances,
          335                 // also on non Un*x systems...
          336                 switch runtime.GOOS {
          337                 case "windows":
          338                         time.Sleep(2 * time.Second)
          339                 case "darwin":
          340                         time.Sleep(1 * time.Second)
          341                 default: // depending on the FS, this may work with < 1 second, on my old ext3 it does not
          342                         time.Sleep(1 * time.Second)
          343                 }
          344 
          345                 _, err = f.Write([]byte("test"))
          346                 if err != nil {
          347                         t.Error(fs.Name()+":", "Write failed: "+err.Error())
          348                 }
          349                 f.Close()
          350                 fi, err = fs.Stat(path)
          351                 if err != nil {
          352                         t.Error(fs.Name()+":", "fs.Stat failed: "+err.Error())
          353                 }
          354                 if fi.ModTime().Equal(timeBefore) {
          355                         t.Error(fs.Name()+":", "ModTime was not set on Close()")
          356                 }
          357         }
          358 }
          359 
          360 // This test should be run with the race detector on:
          361 // go test -race -v -timeout 10s -run TestRacingDeleteAndClose
          362 func TestRacingDeleteAndClose(t *testing.T) {
          363         fs := NewMemMapFs()
          364         pathname := "testfile"
          365         f, err := fs.Create(pathname)
          366         if err != nil {
          367                 t.Fatal(err)
          368         }
          369 
          370         in := make(chan bool)
          371 
          372         go func() {
          373                 <-in
          374                 f.Close()
          375         }()
          376         go func() {
          377                 <-in
          378                 fs.Remove(pathname)
          379         }()
          380         close(in)
          381 }
          382 
          383 // This test should be run with the race detector on:
          384 // go test -run TestMemFsDataRace -race
          385 func TestMemFsDataRace(t *testing.T) {
          386         const dir = "test_dir"
          387         fs := NewMemMapFs()
          388 
          389         if err := fs.MkdirAll(dir, 0o777); err != nil {
          390                 t.Fatal(err)
          391         }
          392 
          393         const n = 1000
          394         done := make(chan struct{})
          395 
          396         go func() {
          397                 defer close(done)
          398                 for i := 0; i < n; i++ {
          399                         fname := filepath.Join(dir, fmt.Sprintf("%d.txt", i))
          400                         if err := WriteFile(fs, fname, []byte(""), 0o777); err != nil {
          401                                 panic(err)
          402                         }
          403                         if err := fs.Remove(fname); err != nil {
          404                                 panic(err)
          405                         }
          406                 }
          407         }()
          408 
          409 loop:
          410         for {
          411                 select {
          412                 case <-done:
          413                         break loop
          414                 default:
          415                         _, err := ReadDir(fs, dir)
          416                         if err != nil {
          417                                 t.Fatal(err)
          418                         }
          419                 }
          420         }
          421 }
          422 
          423 // root is a directory
          424 func TestMemFsRootDirMode(t *testing.T) {
          425         t.Parallel()
          426 
          427         fs := NewMemMapFs()
          428         info, err := fs.Stat("/")
          429         if err != nil {
          430                 t.Fatal(err)
          431         }
          432         if !info.IsDir() {
          433                 t.Error("should be a directory")
          434         }
          435         if !info.Mode().IsDir() {
          436                 t.Errorf("FileMode is not directory, is %s", info.Mode().String())
          437         }
          438 }
          439 
          440 // MkdirAll creates intermediate directories with correct mode
          441 func TestMemFsMkdirAllMode(t *testing.T) {
          442         t.Parallel()
          443 
          444         fs := NewMemMapFs()
          445         err := fs.MkdirAll("/a/b/c", 0o755)
          446         if err != nil {
          447                 t.Fatal(err)
          448         }
          449         info, err := fs.Stat("/a")
          450         if err != nil {
          451                 t.Fatal(err)
          452         }
          453         if !info.Mode().IsDir() {
          454                 t.Error("/a: mode is not directory")
          455         }
          456         if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
          457                 t.Errorf("/a: mod time not set, got %s", info.ModTime())
          458         }
          459         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          460                 t.Errorf("/a: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
          461         }
          462         info, err = fs.Stat("/a/b")
          463         if err != nil {
          464                 t.Fatal(err)
          465         }
          466         if !info.Mode().IsDir() {
          467                 t.Error("/a/b: mode is not directory")
          468         }
          469         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          470                 t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
          471         }
          472         if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
          473                 t.Errorf("/a/b: mod time not set, got %s", info.ModTime())
          474         }
          475         info, err = fs.Stat("/a/b/c")
          476         if err != nil {
          477                 t.Fatal(err)
          478         }
          479         if !info.Mode().IsDir() {
          480                 t.Error("/a/b/c: mode is not directory")
          481         }
          482         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          483                 t.Errorf("/a/b/c: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
          484         }
          485         if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
          486                 t.Errorf("/a/b/c: mod time not set, got %s", info.ModTime())
          487         }
          488 }
          489 
          490 // MkdirAll does not change permissions of already-existing directories
          491 func TestMemFsMkdirAllNoClobber(t *testing.T) {
          492         t.Parallel()
          493 
          494         fs := NewMemMapFs()
          495         err := fs.MkdirAll("/a/b/c", 0o755)
          496         if err != nil {
          497                 t.Fatal(err)
          498         }
          499         info, err := fs.Stat("/a/b")
          500         if err != nil {
          501                 t.Fatal(err)
          502         }
          503         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          504                 t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
          505         }
          506         err = fs.MkdirAll("/a/b/c/d/e/f", 0o710)
          507         // '/a/b' is unchanged
          508         if err != nil {
          509                 t.Fatal(err)
          510         }
          511         info, err = fs.Stat("/a/b")
          512         if err != nil {
          513                 t.Fatal(err)
          514         }
          515         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          516                 t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
          517         }
          518         // new directories created with proper permissions
          519         info, err = fs.Stat("/a/b/c/d")
          520         if err != nil {
          521                 t.Fatal(err)
          522         }
          523         if info.Mode() != os.FileMode(os.ModeDir|0o710) {
          524                 t.Errorf("/a/b/c/d: wrong permissions, expected drwx--x---, got %s", info.Mode())
          525         }
          526         info, err = fs.Stat("/a/b/c/d/e")
          527         if err != nil {
          528                 t.Fatal(err)
          529         }
          530         if info.Mode() != os.FileMode(os.ModeDir|0o710) {
          531                 t.Errorf("/a/b/c/d/e: wrong permissions, expected drwx--x---, got %s", info.Mode())
          532         }
          533         info, err = fs.Stat("/a/b/c/d/e/f")
          534         if err != nil {
          535                 t.Fatal(err)
          536         }
          537         if info.Mode() != os.FileMode(os.ModeDir|0o710) {
          538                 t.Errorf("/a/b/c/d/e/f: wrong permissions, expected drwx--x---, got %s", info.Mode())
          539         }
          540 }
          541 
          542 func TestMemFsDirMode(t *testing.T) {
          543         fs := NewMemMapFs()
          544         err := fs.Mkdir("/testDir1", 0o644)
          545         if err != nil {
          546                 t.Error(err)
          547         }
          548         err = fs.MkdirAll("/sub/testDir2", 0o644)
          549         if err != nil {
          550                 t.Error(err)
          551         }
          552         info, err := fs.Stat("/testDir1")
          553         if err != nil {
          554                 t.Error(err)
          555         }
          556         if !info.IsDir() {
          557                 t.Error("should be a directory")
          558         }
          559         if !info.Mode().IsDir() {
          560                 t.Error("FileMode is not directory")
          561         }
          562         info, err = fs.Stat("/sub/testDir2")
          563         if err != nil {
          564                 t.Error(err)
          565         }
          566         if !info.IsDir() {
          567                 t.Error("should be a directory")
          568         }
          569         if !info.Mode().IsDir() {
          570                 t.Error("FileMode is not directory")
          571         }
          572 }
          573 
          574 func TestMemFsUnexpectedEOF(t *testing.T) {
          575         t.Parallel()
          576 
          577         fs := NewMemMapFs()
          578 
          579         if err := WriteFile(fs, "file.txt", []byte("abc"), 0o777); err != nil {
          580                 t.Fatal(err)
          581         }
          582 
          583         f, err := fs.Open("file.txt")
          584         if err != nil {
          585                 t.Fatal(err)
          586         }
          587         defer f.Close()
          588 
          589         // Seek beyond the end.
          590         _, err = f.Seek(512, 0)
          591         if err != nil {
          592                 t.Fatal(err)
          593         }
          594 
          595         buff := make([]byte, 256)
          596         _, err = io.ReadAtLeast(f, buff, 256)
          597 
          598         if err != io.ErrUnexpectedEOF {
          599                 t.Fatal("Expected ErrUnexpectedEOF")
          600         }
          601 }
          602 
          603 func TestMemFsChmod(t *testing.T) {
          604         t.Parallel()
          605 
          606         fs := NewMemMapFs()
          607         const file = "hello"
          608         if err := fs.Mkdir(file, 0o700); err != nil {
          609                 t.Fatal(err)
          610         }
          611 
          612         info, err := fs.Stat(file)
          613         if err != nil {
          614                 t.Fatal(err)
          615         }
          616         if info.Mode().String() != "drwx------" {
          617                 t.Fatal("mkdir failed to create a directory: mode =", info.Mode())
          618         }
          619 
          620         err = fs.Chmod(file, 0)
          621         if err != nil {
          622                 t.Error("Failed to run chmod:", err)
          623         }
          624 
          625         info, err = fs.Stat(file)
          626         if err != nil {
          627                 t.Fatal(err)
          628         }
          629         if info.Mode().String() != "d---------" {
          630                 t.Error("chmod should not change file type. New mode =", info.Mode())
          631         }
          632 }
          633 
          634 // can't use Mkdir to get around which permissions we're allowed to set
          635 func TestMemFsMkdirModeIllegal(t *testing.T) {
          636         t.Parallel()
          637 
          638         fs := NewMemMapFs()
          639         err := fs.Mkdir("/a", os.ModeSocket|0o755)
          640         if err != nil {
          641                 t.Fatal(err)
          642         }
          643         info, err := fs.Stat("/a")
          644         if err != nil {
          645                 t.Fatal(err)
          646         }
          647         if info.Mode() != os.FileMode(os.ModeDir|0o755) {
          648                 t.Fatalf("should not be able to use Mkdir to set illegal mode: %s", info.Mode().String())
          649         }
          650 }
          651 
          652 // can't use OpenFile to get around which permissions we're allowed to set
          653 func TestMemFsOpenFileModeIllegal(t *testing.T) {
          654         t.Parallel()
          655 
          656         fs := NewMemMapFs()
          657         file, err := fs.OpenFile("/a", os.O_CREATE, os.ModeSymlink|0o644)
          658         if err != nil {
          659                 t.Fatal(err)
          660         }
          661         defer file.Close()
          662         info, err := fs.Stat("/a")
          663         if err != nil {
          664                 t.Fatal(err)
          665         }
          666         if info.Mode() != os.FileMode(0o644) {
          667                 t.Fatalf("should not be able to use OpenFile to set illegal mode: %s", info.Mode().String())
          668         }
          669 }
          670 
          671 // LstatIfPossible should always return false, since MemMapFs does not
          672 // support symlinks.
          673 func TestMemFsLstatIfPossible(t *testing.T) {
          674         t.Parallel()
          675 
          676         fs := NewMemMapFs()
          677 
          678         // We assert that fs implements Lstater
          679         fsAsserted, ok := fs.(Lstater)
          680         if !ok {
          681                 t.Fatalf("The filesytem does not implement Lstater")
          682         }
          683 
          684         file, err := fs.OpenFile("/a.txt", os.O_CREATE, 0o644)
          685         if err != nil {
          686                 t.Fatalf("Error when opening file: %v", err)
          687         }
          688         defer file.Close()
          689 
          690         _, lstatCalled, err := fsAsserted.LstatIfPossible("/a.txt")
          691         if err != nil {
          692                 t.Fatalf("Function returned err: %v", err)
          693         }
          694         if lstatCalled {
          695                 t.Fatalf("Function indicated lstat was called. This should never be true.")
          696         }
          697 }
          698 
          699 func TestMemMapFsConfurrentMkdir(t *testing.T) {
          700         const dir = "test_dir"
          701         const n = 1000
          702         mfs := NewMemMapFs().(*MemMapFs)
          703 
          704         allFilePaths := make([]string, 0, n)
          705 
          706         // run concurrency test
          707         var wg sync.WaitGroup
          708         for i := 0; i < n; i++ {
          709                 fp := filepath.Join(
          710                         dir,
          711                         fmt.Sprintf("%02d", n%10),
          712                         fmt.Sprintf("%d.txt", i),
          713                 )
          714                 allFilePaths = append(allFilePaths, fp)
          715 
          716                 wg.Add(1)
          717                 go func() {
          718                         defer wg.Done()
          719 
          720                         if err := mfs.MkdirAll(filepath.Dir(fp), 0o755); err != nil {
          721                                 t.Error(err)
          722                         }
          723 
          724                         wt, err := mfs.Create(fp)
          725                         if err != nil {
          726                                 t.Error(err)
          727                         }
          728                         defer func() {
          729                                 if err := wt.Close(); err != nil {
          730                                         t.Error(err)
          731                                 }
          732                         }()
          733 
          734                         // write 30 bytes
          735                         for j := 0; j < 10; j++ {
          736                                 _, err := wt.Write([]byte("000"))
          737                                 if err != nil {
          738                                         t.Error(err)
          739                                 }
          740                         }
          741                 }()
          742         }
          743         wg.Wait()
          744 
          745         // Test1: find all files by full path access
          746         for _, fp := range allFilePaths {
          747                 info, err := mfs.Stat(fp)
          748                 if err != nil {
          749                         t.Error(err)
          750                 }
          751 
          752                 if info.Size() != 30 {
          753                         t.Errorf("file size should be 30, but got %d", info.Size())
          754                 }
          755 
          756         }
          757 
          758         // Test2: find all files by walk
          759         foundFiles := make([]string, 0, n)
          760         wErr := Walk(mfs, dir, func(path string, info fs.FileInfo, err error) error {
          761                 if err != nil {
          762                         t.Error(err)
          763                 }
          764                 if info.IsDir() {
          765                         return nil // skip dir
          766                 }
          767                 if strings.HasSuffix(info.Name(), ".txt") {
          768                         foundFiles = append(foundFiles, path)
          769                 }
          770                 return nil
          771         })
          772         if wErr != nil {
          773                 t.Error(wErr)
          774         }
          775         if len(foundFiles) != n {
          776                 t.Errorf("found %d files, but expect %d", len(foundFiles), n)
          777         }
          778 }
          779 
          780 func TestMemFsRenameDir(t *testing.T) {
          781         const srcPath = "/src"
          782         const dstPath = "/dst"
          783         const subDir = "dir"
          784         const subFile = "file.txt"
          785 
          786         fs := NewMemMapFs()
          787 
          788         err := fs.MkdirAll(srcPath+FilePathSeparator+subDir, 0o777)
          789         if err != nil {
          790                 t.Fatalf("MkDirAll failed: %s", err)
          791         }
          792 
          793         f, err := fs.Create(srcPath + FilePathSeparator + subFile)
          794         if err != nil {
          795                 t.Fatalf("Create failed: %s", err)
          796         }
          797         if err = f.Close(); err != nil {
          798                 t.Fatalf("Close failed: %s", err)
          799         }
          800 
          801         err = fs.Rename(srcPath, dstPath)
          802         if err != nil {
          803                 t.Fatalf("Rename failed: %s", err)
          804         }
          805 
          806         _, err = fs.Stat(srcPath + FilePathSeparator + subDir)
          807         if err == nil {
          808                 t.Fatalf("SubDir still exists in the source dir")
          809         }
          810 
          811         _, err = fs.Stat(srcPath + FilePathSeparator + subFile)
          812         if err == nil {
          813                 t.Fatalf("SubFile still exists in the source dir")
          814         }
          815 
          816         _, err = fs.Stat(dstPath + FilePathSeparator + subDir)
          817         if err != nil {
          818                 t.Fatalf("SubDir stat in the destination dir: %s", err)
          819         }
          820 
          821         _, err = fs.Stat(dstPath + FilePathSeparator + subFile)
          822         if err != nil {
          823                 t.Fatalf("SubFile stat in the destination dir: %s", err)
          824         }
          825 
          826         err = fs.Mkdir(srcPath, 0o777)
          827         if err != nil {
          828                 t.Fatalf("Cannot recreate the source dir: %s", err)
          829         }
          830 
          831         err = fs.Mkdir(srcPath+FilePathSeparator+subDir, 0o777)
          832         if err != nil {
          833                 t.Errorf("Cannot recreate the subdir in the source dir: %s", err)
          834         }
          835 }
          836 
          837 func TestMemMapFsRename(t *testing.T) {
          838         t.Parallel()
          839 
          840         fs := &MemMapFs{}
          841         tDir := testDir(fs)
          842         rFrom := "/renamefrom"
          843         rTo := "/renameto"
          844         rExists := "/renameexists"
          845 
          846         type test struct {
          847                 dirs   []string
          848                 from   string
          849                 to     string
          850                 exists string
          851         }
          852 
          853         parts := strings.Split(tDir, "/")
          854         root := "/"
          855         if len(parts) > 1 {
          856                 root = filepath.Join("/", parts[1])
          857         }
          858 
          859         testData := make([]test, 0, len(parts))
          860 
          861         i := len(parts)
          862         for i > 0 {
          863                 prefix := strings.Join(parts[:i], "/")
          864                 suffix := strings.Join(parts[i:], "/")
          865                 testData = append(testData, test{
          866                         dirs: []string{
          867                                 filepath.Join(prefix, rFrom, suffix),
          868                                 filepath.Join(prefix, rExists, suffix),
          869                         },
          870                         from:   filepath.Join(prefix, rFrom),
          871                         to:     filepath.Join(prefix, rTo),
          872                         exists: filepath.Join(prefix, rExists),
          873                 })
          874                 i--
          875         }
          876 
          877         for _, data := range testData {
          878                 err := fs.RemoveAll(root)
          879                 if err != nil {
          880                         t.Fatalf("%s: RemoveAll %q failed: %v", fs.Name(), root, err)
          881                 }
          882 
          883                 for _, dir := range data.dirs {
          884                         err = fs.MkdirAll(dir, os.FileMode(0o775))
          885                         if err != nil {
          886                                 t.Fatalf("%s: MkdirAll %q failed: %v", fs.Name(), dir, err)
          887                         }
          888                 }
          889 
          890                 dataCnt := len(fs.getData())
          891                 err = fs.Rename(data.from, data.to)
          892                 if err != nil {
          893                         t.Fatalf("%s: rename %q, %q failed: %v", fs.Name(), data.from, data.to, err)
          894                 }
          895                 err = fs.Mkdir(data.from, os.FileMode(0o775))
          896                 if err != nil {
          897                         t.Fatalf("%s: Mkdir %q failed: %v", fs.Name(), data.from, err)
          898                 }
          899 
          900                 err = fs.Rename(data.from, data.exists)
          901                 if err != nil {
          902                         t.Errorf("%s: rename %q, %q failed: %v", fs.Name(), data.from, data.exists, err)
          903                 }
          904 
          905                 for p := range fs.getData() {
          906                         if strings.Contains(p, data.from) {
          907                                 t.Errorf("File was not renamed to renameto: %v", p)
          908                         }
          909                 }
          910 
          911                 _, err = fs.Stat(data.to)
          912                 if err != nil {
          913                         t.Errorf("%s: stat %q failed: %v", fs.Name(), data.to, err)
          914                 }
          915 
          916                 if dataCnt != len(fs.getData()) {
          917                         t.Errorf("invalid data len: expected %v, get %v", dataCnt, len(fs.getData()))
          918                 }
          919         }
          920 }