1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 // testStatAndLstat verifies that all os.Stat, os.Lstat os.File.Stat and os.Readdir work.
17 func testStatAndLstat(t
*testing
.T
, path
string, isLink
bool, statCheck
, lstatCheck
func(*testing
.T
, string, fs
.FileInfo
)) {
19 sfi
, err
:= os
.Stat(path
)
24 statCheck(t
, path
, sfi
)
27 lsfi
, err
:= os
.Lstat(path
)
32 lstatCheck(t
, path
, lsfi
)
35 if os
.SameFile(sfi
, lsfi
) {
36 t
.Errorf("stat and lstat of %q should not be the same", path
)
39 if !os
.SameFile(sfi
, lsfi
) {
40 t
.Errorf("stat and lstat of %q should be the same", path
)
45 f
, err
:= os
.Open(path
)
57 statCheck(t
, path
, sfi2
)
59 if !os
.SameFile(sfi
, sfi2
) {
60 t
.Errorf("stat of open %q file and stat of %q should be the same", path
, path
)
64 if os
.SameFile(sfi2
, lsfi
) {
65 t
.Errorf("stat of opened %q file and lstat of %q should not be the same", path
, path
)
68 if !os
.SameFile(sfi2
, lsfi
) {
69 t
.Errorf("stat of opened %q file and lstat of %q should be the same", path
, path
)
73 // test fs.FileInfo returned by os.Readdir
74 if len(path
) > 0 && os
.IsPathSeparator(path
[len(path
)-1]) {
75 // skip os.Readdir test of directories with slash at the end
78 parentdir
:= filepath
.Dir(path
)
79 parent
, err
:= os
.Open(parentdir
)
86 fis
, err
:= parent
.Readdir(-1)
92 base
:= filepath
.Base(path
)
93 for _
, fi2
:= range fis
{
94 if fi2
.Name() == base
{
100 t
.Errorf("failed to find %q in its parent", path
)
103 lstatCheck(t
, path
, lsfi2
)
105 if !os
.SameFile(lsfi
, lsfi2
) {
106 t
.Errorf("lstat of %q file in %q directory and %q should be the same", lsfi2
.Name(), parentdir
, path
)
110 // testIsDir verifies that fi refers to directory.
111 func testIsDir(t
*testing
.T
, path
string, fi fs
.FileInfo
) {
114 t
.Errorf("%q should be a directory", path
)
116 if fi
.Mode()&fs
.ModeSymlink
!= 0 {
117 t
.Errorf("%q should not be a symlink", path
)
121 // testIsSymlink verifies that fi refers to symlink.
122 func testIsSymlink(t
*testing
.T
, path
string, fi fs
.FileInfo
) {
125 t
.Errorf("%q should not be a directory", path
)
127 if fi
.Mode()&fs
.ModeSymlink
== 0 {
128 t
.Errorf("%q should be a symlink", path
)
132 // testIsFile verifies that fi refers to file.
133 func testIsFile(t
*testing
.T
, path
string, fi fs
.FileInfo
) {
136 t
.Errorf("%q should not be a directory", path
)
138 if fi
.Mode()&fs
.ModeSymlink
!= 0 {
139 t
.Errorf("%q should not be a symlink", path
)
143 func testDirStats(t
*testing
.T
, path
string) {
144 testStatAndLstat(t
, path
, false, testIsDir
, testIsDir
)
147 func testFileStats(t
*testing
.T
, path
string) {
148 testStatAndLstat(t
, path
, false, testIsFile
, testIsFile
)
151 func testSymlinkStats(t
*testing
.T
, path
string, isdir
bool) {
153 testStatAndLstat(t
, path
, true, testIsDir
, testIsSymlink
)
155 testStatAndLstat(t
, path
, true, testIsFile
, testIsSymlink
)
159 func testSymlinkSameFile(t
*testing
.T
, path
, link
string) {
160 pathfi
, err
:= os
.Stat(path
)
166 linkfi
, err
:= os
.Stat(link
)
171 if !os
.SameFile(pathfi
, linkfi
) {
172 t
.Errorf("os.Stat(%q) and os.Stat(%q) are not the same file", path
, link
)
175 linkfi
, err
= os
.Lstat(link
)
180 if os
.SameFile(pathfi
, linkfi
) {
181 t
.Errorf("os.Stat(%q) and os.Lstat(%q) are the same file", path
, link
)
185 func TestDirAndSymlinkStats(t
*testing
.T
) {
186 testenv
.MustHaveSymlink(t
)
188 tmpdir
:= t
.TempDir()
189 dir
:= filepath
.Join(tmpdir
, "dir")
190 if err
:= os
.Mkdir(dir
, 0777); err
!= nil {
195 dirlink
:= filepath
.Join(tmpdir
, "link")
196 if err
:= os
.Symlink(dir
, dirlink
); err
!= nil {
199 testSymlinkStats(t
, dirlink
, true)
200 testSymlinkSameFile(t
, dir
, dirlink
)
202 linklink
:= filepath
.Join(tmpdir
, "linklink")
203 if err
:= os
.Symlink(dirlink
, linklink
); err
!= nil {
206 testSymlinkStats(t
, linklink
, true)
207 testSymlinkSameFile(t
, dir
, linklink
)
210 func TestFileAndSymlinkStats(t
*testing
.T
) {
211 testenv
.MustHaveSymlink(t
)
213 tmpdir
:= t
.TempDir()
214 file
:= filepath
.Join(tmpdir
, "file")
215 if err
:= os
.WriteFile(file
, []byte(""), 0644); err
!= nil {
218 testFileStats(t
, file
)
220 filelink
:= filepath
.Join(tmpdir
, "link")
221 if err
:= os
.Symlink(file
, filelink
); err
!= nil {
224 testSymlinkStats(t
, filelink
, false)
225 testSymlinkSameFile(t
, file
, filelink
)
227 linklink
:= filepath
.Join(tmpdir
, "linklink")
228 if err
:= os
.Symlink(filelink
, linklink
); err
!= nil {
231 testSymlinkStats(t
, linklink
, false)
232 testSymlinkSameFile(t
, file
, linklink
)
235 // see issue 27225 for details
236 func TestSymlinkWithTrailingSlash(t
*testing
.T
) {
237 testenv
.MustHaveSymlink(t
)
239 tmpdir
:= t
.TempDir()
240 dir
:= filepath
.Join(tmpdir
, "dir")
241 if err
:= os
.Mkdir(dir
, 0777); err
!= nil {
244 dirlink
:= filepath
.Join(tmpdir
, "link")
245 if err
:= os
.Symlink(dir
, dirlink
); err
!= nil {
248 dirlinkWithSlash
:= dirlink
+ string(os
.PathSeparator
)
250 if runtime
.GOOS
== "windows" {
251 testSymlinkStats(t
, dirlinkWithSlash
, true)
253 testDirStats(t
, dirlinkWithSlash
)
256 fi1
, err
:= os
.Stat(dir
)
261 fi2
, err
:= os
.Stat(dirlinkWithSlash
)
266 if !os
.SameFile(fi1
, fi2
) {
267 t
.Errorf("os.Stat(%q) and os.Stat(%q) are not the same file", dir
, dirlinkWithSlash
)