Source file
src/os/file_test.go
1
2
3
4
5 package os_test
6
7 import (
8 "internal/testenv"
9 "io/fs"
10 . "os"
11 "path/filepath"
12 "testing"
13 )
14
15 func TestDirFSReadLink(t *testing.T) {
16 testenv.MustHaveSymlink(t)
17
18 root := t.TempDir()
19 subdir := filepath.Join(root, "dir")
20 if err := Mkdir(subdir, 0o777); err != nil {
21 t.Fatal(err)
22 }
23 links := map[string]string{
24 filepath.Join(root, "parent-link"): filepath.Join("..", "foo"),
25 filepath.Join(root, "sneaky-parent-link"): filepath.Join("dir", "..", "..", "foo"),
26 filepath.Join(root, "abs-link"): filepath.Join(root, "foo"),
27 filepath.Join(root, "rel-link"): "foo",
28 filepath.Join(root, "rel-sub-link"): filepath.Join("dir", "foo"),
29 filepath.Join(subdir, "parent-link"): filepath.Join("..", "foo"),
30 }
31 for newname, oldname := range links {
32 if err := Symlink(oldname, newname); err != nil {
33 t.Fatal(err)
34 }
35 }
36
37 fsys := DirFS(root)
38 want := map[string]string{
39 "rel-link": "foo",
40 "rel-sub-link": filepath.Join("dir", "foo"),
41 "dir/parent-link": filepath.Join("..", "foo"),
42 "parent-link": filepath.Join("..", "foo"),
43 "sneaky-parent-link": filepath.Join("dir", "..", "..", "foo"),
44 "abs-link": filepath.Join(root, "foo"),
45 }
46 for name, want := range want {
47 got, err := fs.ReadLink(fsys, name)
48 if got != want || err != nil {
49 t.Errorf("fs.ReadLink(fsys, %q) = %q, %v; want %q, <nil>", name, got, err, want)
50 }
51 }
52
53 const nonesuch = "dir/nonesuch"
54 _, err := fs.ReadLink(fsys, nonesuch)
55 if err == nil {
56 t.Fatal("fs.ReadLink of nonexistent file succeeded")
57 }
58 pe, ok := err.(*PathError)
59 if !ok {
60 t.Fatalf("fs.ReadLink error type = %T; want *PathError", err)
61 }
62 if pe.Path != nonesuch {
63 t.Errorf("fs.ReadLink(%q) error path = %q; want %q", nonesuch, pe.Path, nonesuch)
64 }
65 }
66
67 func TestDirFSLstat(t *testing.T) {
68 testenv.MustHaveSymlink(t)
69
70 root := t.TempDir()
71 subdir := filepath.Join(root, "dir")
72 if err := Mkdir(subdir, 0o777); err != nil {
73 t.Fatal(err)
74 }
75 if err := Symlink("dir", filepath.Join(root, "link")); err != nil {
76 t.Fatal(err)
77 }
78
79 fsys := DirFS(root)
80 want := map[string]fs.FileMode{
81 "link": fs.ModeSymlink,
82 "dir": fs.ModeDir,
83 }
84 for name, want := range want {
85 info, err := fs.Lstat(fsys, name)
86 var got fs.FileMode
87 if info != nil {
88 got = info.Mode().Type()
89 }
90 if got != want || err != nil {
91 t.Errorf("fs.Lstat(fsys, %q).Mode().Type() = %v, %v; want %v, <nil>", name, got, err, want)
92 }
93 }
94
95 const nonesuch = "dir/nonesuch"
96 _, err := fs.Lstat(fsys, nonesuch)
97 if err == nil {
98 t.Fatal("fs.Lstat of nonexistent file succeeded")
99 }
100 pe, ok := err.(*PathError)
101 if !ok {
102 t.Fatalf("fs.Lstat error type = %T; want *PathError", err)
103 }
104 if pe.Path != nonesuch {
105 t.Errorf("fs.Lstat(%q) error path = %q; want %q", nonesuch, pe.Path, nonesuch)
106 }
107 }
108
109 func TestDirFSWalkDir(t *testing.T) {
110 testenv.MustHaveSymlink(t)
111
112 root := t.TempDir()
113 subdir := filepath.Join(root, "dir")
114 if err := Mkdir(subdir, 0o777); err != nil {
115 t.Fatal(err)
116 }
117 if err := Symlink("dir", filepath.Join(root, "link")); err != nil {
118 t.Fatal(err)
119 }
120 if err := WriteFile(filepath.Join(root, "dir", "a"), nil, 0o666); err != nil {
121 t.Fatal(err)
122 }
123 fsys := DirFS(root)
124
125 t.Run("SymlinkRoot", func(t *testing.T) {
126 wantTypes := map[string]fs.FileMode{
127 "link": fs.ModeDir,
128 "link/a": 0,
129 }
130 marks := make(map[string]int)
131 err := fs.WalkDir(fsys, "link", func(path string, entry fs.DirEntry, err error) error {
132 marks[path]++
133 if want, ok := wantTypes[path]; !ok {
134 t.Errorf("Unexpected path %q in walk", path)
135 } else if got := entry.Type(); got != want {
136 t.Errorf("%s entry type = %v; want %v", path, got, want)
137 }
138 if err != nil {
139 t.Errorf("%s: %v", path, err)
140 }
141 return nil
142 })
143 if err != nil {
144 t.Fatal(err)
145 }
146 for path := range wantTypes {
147 if got := marks[path]; got != 1 {
148 t.Errorf("%s visited %d times; expected 1", path, got)
149 }
150 }
151 })
152
153 t.Run("SymlinkPresent", func(t *testing.T) {
154 wantTypes := map[string]fs.FileMode{
155 ".": fs.ModeDir,
156 "dir": fs.ModeDir,
157 "dir/a": 0,
158 "link": fs.ModeSymlink,
159 }
160 marks := make(map[string]int)
161 err := fs.WalkDir(fsys, ".", func(path string, entry fs.DirEntry, err error) error {
162 marks[path]++
163 if want, ok := wantTypes[path]; !ok {
164 t.Errorf("Unexpected path %q in walk", path)
165 } else if got := entry.Type(); got != want {
166 t.Errorf("%s entry type = %v; want %v", path, got, want)
167 }
168 if err != nil {
169 t.Errorf("%s: %v", path, err)
170 }
171 return nil
172 })
173 if err != nil {
174 t.Fatal(err)
175 }
176 for path := range wantTypes {
177 if got := marks[path]; got != 1 {
178 t.Errorf("%s visited %d times; expected 1", path, got)
179 }
180 }
181 })
182 }
183
View as plain text