github.com/jimsnab/afero@v1.11.2/symlink_test.go (about) 1 package afero 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 "testing" 8 ) 9 10 func TestSymlinkIfPossible(t *testing.T) { 11 wd, _ := os.Getwd() 12 defer func() { 13 os.Chdir(wd) 14 }() 15 16 osFs := &OsFs{} 17 18 workDir, err := TempDir(osFs, "", "afero-symlink") 19 if err != nil { 20 t.Fatal(err) 21 } 22 23 defer func() { 24 osFs.RemoveAll(workDir) 25 }() 26 27 memWorkDir := "/sym" 28 29 memFs := NewMemMapFs() 30 overlayFs1 := &CopyOnWriteFs{base: osFs, layer: memFs} 31 overlayFs2 := &CopyOnWriteFs{base: memFs, layer: osFs} 32 overlayFsMemOnly := &CopyOnWriteFs{base: memFs, layer: NewMemMapFs()} 33 basePathFs := &BasePathFs{source: osFs, path: workDir} 34 basePathFsMem := &BasePathFs{source: memFs, path: memWorkDir} 35 roFs := &ReadOnlyFs{source: osFs} 36 roFsMem := &ReadOnlyFs{source: memFs} 37 38 pathFileMem := filepath.Join(memWorkDir, "aferom.txt") 39 osPath := filepath.Join(workDir, "afero.txt") 40 41 WriteFile(osFs, osPath, []byte("Hi, Afero!"), 0o777) 42 WriteFile(memFs, filepath.Join(pathFileMem), []byte("Hi, Afero!"), 0o777) 43 44 testLink := func(l Linker, source, destination string, output *string) { 45 if fs, ok := l.(Fs); ok { 46 dir := filepath.Dir(destination) 47 if dir != "" { 48 fs.MkdirAll(dir, 0o777) 49 } 50 } 51 52 err := l.SymlinkIfPossible(source, destination) 53 if (err == nil) && (output != nil) { 54 t.Fatalf("Error creating symlink, succeeded when expecting error %v", *output) 55 } else if (err != nil) && (output == nil) { 56 t.Fatalf("Error creating symlink, expected success, got %v", err) 57 } else if err != nil && err.Error() != *output && !strings.HasSuffix(err.Error(), *output) { 58 t.Fatalf("Error creating symlink, expected error '%v', instead got output '%v'", *output, err) 59 } else { 60 // test passed, if expecting a successful link, check the link with lstat if able 61 if output == nil { 62 if lst, ok := l.(Lstater); ok { 63 _, ok, err := lst.LstatIfPossible(destination) 64 if !ok { 65 if err != nil { 66 t.Fatalf("Error calling lstat on file after successful link, got: %v", err) 67 } else { 68 t.Fatalf("Error calling lstat on file after successful link, result didn't use lstat (not link)") 69 } 70 return 71 } 72 } 73 } 74 } 75 } 76 77 notSupported := ErrNoSymlink.Error() 78 79 testLink(osFs, osPath, filepath.Join(workDir, "os/link.txt"), nil) 80 testLink(overlayFs1, osPath, filepath.Join(workDir, "overlay/link1.txt"), ¬Supported) 81 testLink(overlayFs2, pathFileMem, filepath.Join(workDir, "overlay2/link2.txt"), nil) 82 testLink(overlayFsMemOnly, pathFileMem, filepath.Join(memWorkDir, "overlay3/link.txt"), ¬Supported) 83 testLink(basePathFs, "afero.txt", "basepath/link.txt", nil) 84 testLink(basePathFsMem, pathFileMem, "link/file.txt", ¬Supported) 85 testLink(roFs, osPath, filepath.Join(workDir, "ro/link.txt"), ¬Supported) 86 testLink(roFsMem, pathFileMem, filepath.Join(memWorkDir, "ro/link.txt"), ¬Supported) 87 } 88 89 func TestReadlinkIfPossible(t *testing.T) { 90 wd, _ := os.Getwd() 91 defer func() { 92 os.Chdir(wd) 93 }() 94 95 osFs := &OsFs{} 96 97 workDir, err := TempDir(osFs, "", "afero-readlink") 98 if err != nil { 99 t.Fatal(err) 100 } 101 102 defer func() { 103 osFs.RemoveAll(workDir) 104 }() 105 106 memWorkDir := "/read" 107 108 memFs := NewMemMapFs() 109 overlayFs1 := &CopyOnWriteFs{base: osFs, layer: memFs} 110 overlayFs2 := &CopyOnWriteFs{base: memFs, layer: osFs} 111 overlayFsMemOnly := &CopyOnWriteFs{base: memFs, layer: NewMemMapFs()} 112 basePathFs := &BasePathFs{source: osFs, path: workDir} 113 basePathFsMem := &BasePathFs{source: memFs, path: memWorkDir} 114 roFs := &ReadOnlyFs{source: osFs} 115 roFsMem := &ReadOnlyFs{source: memFs} 116 117 pathFileMem := filepath.Join(memWorkDir, "aferom.txt") 118 osPath := filepath.Join(workDir, "afero.txt") 119 120 WriteFile(osFs, osPath, []byte("Hi, Afero!"), 0o777) 121 WriteFile(memFs, filepath.Join(pathFileMem), []byte("Hi, Afero!"), 0o777) 122 123 createLink := func(l Linker, source, destination string) error { 124 if fs, ok := l.(Fs); ok { 125 dir := filepath.Dir(destination) 126 if dir != "" { 127 fs.MkdirAll(dir, 0o777) 128 } 129 } 130 131 return l.SymlinkIfPossible(source, destination) 132 } 133 134 testRead := func(r LinkReader, name string, output *string) { 135 _, err := r.ReadlinkIfPossible(name) 136 if (err != nil) && (output == nil) { 137 t.Fatalf("Error reading link, expected success, got error: %v", err) 138 } else if (err == nil) && (output != nil) { 139 t.Fatalf("Error reading link, succeeded when expecting error: %v", *output) 140 } else if err != nil && err.Error() != *output && !strings.HasSuffix(err.Error(), *output) { 141 t.Fatalf("Error reading link, expected error '%v', instead received '%v'", *output, err) 142 } 143 } 144 145 notSupported := ErrNoReadlink.Error() 146 147 err = createLink(osFs, osPath, filepath.Join(workDir, "os/link.txt")) 148 if err != nil { 149 t.Fatal("Error creating test link: ", err) 150 } 151 152 testRead(osFs, filepath.Join(workDir, "os/link.txt"), nil) 153 testRead(overlayFs1, filepath.Join(workDir, "os/link.txt"), nil) 154 testRead(overlayFs2, filepath.Join(workDir, "os/link.txt"), nil) 155 testRead(overlayFsMemOnly, pathFileMem, ¬Supported) 156 testRead(basePathFs, "os/link.txt", nil) 157 testRead(basePathFsMem, pathFileMem, ¬Supported) 158 testRead(roFs, filepath.Join(workDir, "os/link.txt"), nil) 159 testRead(roFsMem, pathFileMem, ¬Supported) 160 }