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, os
.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 os.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 os
.FileInfo
) {
114 t
.Errorf("%q should be a directory", path
)
116 if fi
.Mode()&os
.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 os
.FileInfo
) {
125 t
.Errorf("%q should not be a directory", path
)
127 if fi
.Mode()&os
.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 os
.FileInfo
) {
136 t
.Errorf("%q should not be a directory", path
)
138 if fi
.Mode()&os
.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
, err
:= ioutil
.TempDir("", "TestDirAndSymlinkStats")
192 defer os
.RemoveAll(tmpdir
)
194 dir
:= filepath
.Join(tmpdir
, "dir")
195 err
= os
.Mkdir(dir
, 0777)
201 dirlink
:= filepath
.Join(tmpdir
, "link")
202 err
= os
.Symlink(dir
, dirlink
)
206 testSymlinkStats(t
, dirlink
, true)
207 testSymlinkSameFile(t
, dir
, dirlink
)
209 linklink
:= filepath
.Join(tmpdir
, "linklink")
210 err
= os
.Symlink(dirlink
, linklink
)
214 testSymlinkStats(t
, linklink
, true)
215 testSymlinkSameFile(t
, dir
, linklink
)
218 func TestFileAndSymlinkStats(t
*testing
.T
) {
219 testenv
.MustHaveSymlink(t
)
221 tmpdir
, err
:= ioutil
.TempDir("", "TestFileAndSymlinkStats")
225 defer os
.RemoveAll(tmpdir
)
227 file
:= filepath
.Join(tmpdir
, "file")
228 err
= ioutil
.WriteFile(file
, []byte(""), 0644)
232 testFileStats(t
, file
)
234 filelink
:= filepath
.Join(tmpdir
, "link")
235 err
= os
.Symlink(file
, filelink
)
239 testSymlinkStats(t
, filelink
, false)
240 testSymlinkSameFile(t
, file
, filelink
)
242 linklink
:= filepath
.Join(tmpdir
, "linklink")
243 err
= os
.Symlink(filelink
, linklink
)
247 testSymlinkStats(t
, linklink
, false)
248 testSymlinkSameFile(t
, file
, linklink
)
251 // see issue 27225 for details
252 func TestSymlinkWithTrailingSlash(t
*testing
.T
) {
253 testenv
.MustHaveSymlink(t
)
255 tmpdir
, err
:= ioutil
.TempDir("", "TestSymlinkWithTrailingSlash")
259 defer os
.RemoveAll(tmpdir
)
261 dir
:= filepath
.Join(tmpdir
, "dir")
262 err
= os
.Mkdir(dir
, 0777)
266 dirlink
:= filepath
.Join(tmpdir
, "link")
267 err
= os
.Symlink(dir
, dirlink
)
271 dirlinkWithSlash
:= dirlink
+ string(os
.PathSeparator
)
273 if runtime
.GOOS
== "windows" {
274 testSymlinkStats(t
, dirlinkWithSlash
, true)
276 testDirStats(t
, dirlinkWithSlash
)
279 fi1
, err
:= os
.Stat(dir
)
284 fi2
, err
:= os
.Stat(dirlinkWithSlash
)
289 if !os
.SameFile(fi1
, fi2
) {
290 t
.Errorf("os.Stat(%q) and os.Stat(%q) are not the same file", dir
, dirlinkWithSlash
)