github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/os/stat_test.go (about) 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. 4 5 package os_test 6 7 import ( 8 "internal/testenv" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "runtime" 13 "testing" 14 ) 15 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)) { 18 // test os.Stat 19 sfi, err := os.Stat(path) 20 if err != nil { 21 t.Error(err) 22 return 23 } 24 statCheck(t, path, sfi) 25 26 // test os.Lstat 27 lsfi, err := os.Lstat(path) 28 if err != nil { 29 t.Error(err) 30 return 31 } 32 lstatCheck(t, path, lsfi) 33 34 if isLink { 35 if os.SameFile(sfi, lsfi) { 36 t.Errorf("stat and lstat of %q should not be the same", path) 37 } 38 } else { 39 if !os.SameFile(sfi, lsfi) { 40 t.Errorf("stat and lstat of %q should be the same", path) 41 } 42 } 43 44 // test os.File.Stat 45 f, err := os.Open(path) 46 if err != nil { 47 t.Error(err) 48 return 49 } 50 defer f.Close() 51 52 sfi2, err := f.Stat() 53 if err != nil { 54 t.Error(err) 55 return 56 } 57 statCheck(t, path, sfi2) 58 59 if !os.SameFile(sfi, sfi2) { 60 t.Errorf("stat of open %q file and stat of %q should be the same", path, path) 61 } 62 63 if isLink { 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) 66 } 67 } else { 68 if !os.SameFile(sfi2, lsfi) { 69 t.Errorf("stat of opened %q file and lstat of %q should be the same", path, path) 70 } 71 } 72 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 76 return 77 } 78 parentdir := filepath.Dir(path) 79 parent, err := os.Open(parentdir) 80 if err != nil { 81 t.Error(err) 82 return 83 } 84 defer parent.Close() 85 86 fis, err := parent.Readdir(-1) 87 if err != nil { 88 t.Error(err) 89 return 90 } 91 var lsfi2 os.FileInfo 92 base := filepath.Base(path) 93 for _, fi2 := range fis { 94 if fi2.Name() == base { 95 lsfi2 = fi2 96 break 97 } 98 } 99 if lsfi2 == nil { 100 t.Errorf("failed to find %q in its parent", path) 101 return 102 } 103 lstatCheck(t, path, lsfi2) 104 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) 107 } 108 } 109 110 // testIsDir verifies that fi refers to directory. 111 func testIsDir(t *testing.T, path string, fi os.FileInfo) { 112 t.Helper() 113 if !fi.IsDir() { 114 t.Errorf("%q should be a directory", path) 115 } 116 if fi.Mode()&os.ModeSymlink != 0 { 117 t.Errorf("%q should not be a symlink", path) 118 } 119 } 120 121 // testIsSymlink verifies that fi refers to symlink. 122 func testIsSymlink(t *testing.T, path string, fi os.FileInfo) { 123 t.Helper() 124 if fi.IsDir() { 125 t.Errorf("%q should not be a directory", path) 126 } 127 if fi.Mode()&os.ModeSymlink == 0 { 128 t.Errorf("%q should be a symlink", path) 129 } 130 } 131 132 // testIsFile verifies that fi refers to file. 133 func testIsFile(t *testing.T, path string, fi os.FileInfo) { 134 t.Helper() 135 if fi.IsDir() { 136 t.Errorf("%q should not be a directory", path) 137 } 138 if fi.Mode()&os.ModeSymlink != 0 { 139 t.Errorf("%q should not be a symlink", path) 140 } 141 } 142 143 func testDirStats(t *testing.T, path string) { 144 testStatAndLstat(t, path, false, testIsDir, testIsDir) 145 } 146 147 func testFileStats(t *testing.T, path string) { 148 testStatAndLstat(t, path, false, testIsFile, testIsFile) 149 } 150 151 func testSymlinkStats(t *testing.T, path string, isdir bool) { 152 if isdir { 153 testStatAndLstat(t, path, true, testIsDir, testIsSymlink) 154 } else { 155 testStatAndLstat(t, path, true, testIsFile, testIsSymlink) 156 } 157 } 158 159 func testSymlinkSameFile(t *testing.T, path, link string) { 160 pathfi, err := os.Stat(path) 161 if err != nil { 162 t.Error(err) 163 return 164 } 165 166 linkfi, err := os.Stat(link) 167 if err != nil { 168 t.Error(err) 169 return 170 } 171 if !os.SameFile(pathfi, linkfi) { 172 t.Errorf("os.Stat(%q) and os.Stat(%q) are not the same file", path, link) 173 } 174 175 linkfi, err = os.Lstat(link) 176 if err != nil { 177 t.Error(err) 178 return 179 } 180 if os.SameFile(pathfi, linkfi) { 181 t.Errorf("os.Stat(%q) and os.Lstat(%q) are the same file", path, link) 182 } 183 } 184 185 func TestDirAndSymlinkStats(t *testing.T) { 186 testenv.MustHaveSymlink(t) 187 188 tmpdir, err := ioutil.TempDir("", "TestDirAndSymlinkStats") 189 if err != nil { 190 t.Fatal(err) 191 } 192 defer os.RemoveAll(tmpdir) 193 194 dir := filepath.Join(tmpdir, "dir") 195 err = os.Mkdir(dir, 0777) 196 if err != nil { 197 t.Fatal(err) 198 } 199 testDirStats(t, dir) 200 201 dirlink := filepath.Join(tmpdir, "link") 202 err = os.Symlink(dir, dirlink) 203 if err != nil { 204 t.Fatal(err) 205 } 206 testSymlinkStats(t, dirlink, true) 207 testSymlinkSameFile(t, dir, dirlink) 208 209 linklink := filepath.Join(tmpdir, "linklink") 210 err = os.Symlink(dirlink, linklink) 211 if err != nil { 212 t.Fatal(err) 213 } 214 testSymlinkStats(t, linklink, true) 215 testSymlinkSameFile(t, dir, linklink) 216 } 217 218 func TestFileAndSymlinkStats(t *testing.T) { 219 testenv.MustHaveSymlink(t) 220 221 tmpdir, err := ioutil.TempDir("", "TestFileAndSymlinkStats") 222 if err != nil { 223 t.Fatal(err) 224 } 225 defer os.RemoveAll(tmpdir) 226 227 file := filepath.Join(tmpdir, "file") 228 err = ioutil.WriteFile(file, []byte(""), 0644) 229 if err != nil { 230 t.Fatal(err) 231 } 232 testFileStats(t, file) 233 234 filelink := filepath.Join(tmpdir, "link") 235 err = os.Symlink(file, filelink) 236 if err != nil { 237 t.Fatal(err) 238 } 239 testSymlinkStats(t, filelink, false) 240 testSymlinkSameFile(t, file, filelink) 241 242 linklink := filepath.Join(tmpdir, "linklink") 243 err = os.Symlink(filelink, linklink) 244 if err != nil { 245 t.Fatal(err) 246 } 247 testSymlinkStats(t, linklink, false) 248 testSymlinkSameFile(t, file, linklink) 249 } 250 251 // see issue 27225 for details 252 func TestSymlinkWithTrailingSlash(t *testing.T) { 253 testenv.MustHaveSymlink(t) 254 255 tmpdir, err := ioutil.TempDir("", "TestSymlinkWithTrailingSlash") 256 if err != nil { 257 t.Fatal(err) 258 } 259 defer os.RemoveAll(tmpdir) 260 261 dir := filepath.Join(tmpdir, "dir") 262 err = os.Mkdir(dir, 0777) 263 if err != nil { 264 t.Fatal(err) 265 } 266 dirlink := filepath.Join(tmpdir, "link") 267 err = os.Symlink(dir, dirlink) 268 if err != nil { 269 t.Fatal(err) 270 } 271 dirlinkWithSlash := dirlink + string(os.PathSeparator) 272 273 if runtime.GOOS == "windows" { 274 testSymlinkStats(t, dirlinkWithSlash, true) 275 } else { 276 testDirStats(t, dirlinkWithSlash) 277 } 278 279 fi1, err := os.Stat(dir) 280 if err != nil { 281 t.Error(err) 282 return 283 } 284 fi2, err := os.Stat(dirlinkWithSlash) 285 if err != nil { 286 t.Error(err) 287 return 288 } 289 if !os.SameFile(fi1, fi2) { 290 t.Errorf("os.Stat(%q) and os.Stat(%q) are not the same file", dir, dirlinkWithSlash) 291 } 292 }