1 // Copyright 2009 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.
42 var sysdir
= func() *sysDir
{
53 switch runtime
.GOARCH
{
55 /// At this point the test harness has not had a chance
56 // to move us into the ./src/os directory, so the
57 // current working directory is the root of the app.
58 wd
, err
:= syscall
.Getwd()
65 "ResourceRules.plist",
72 Getenv("SystemRoot") + "\\system32\\drivers\\etc",
98 func size(name
string, t
*testing
.T
) int64 {
99 file
, err
:= Open(name
)
101 t
.Fatal("open failed:", err
)
107 n
, e
:= file
.Read(buf
[0:])
113 t
.Fatal("read failed:", err
)
119 func equal(name1
, name2
string) (r
bool) {
120 switch runtime
.GOOS
{
122 r
= strings
.ToLower(name1
) == strings
.ToLower(name2
)
129 // localTmp returns a local temporary directory not on NFS.
130 func localTmp() string {
131 switch runtime
.GOOS
{
132 case "android", "windows":
135 switch runtime
.GOARCH
{
143 func newFile(testName
string, t
*testing
.T
) (f
*File
) {
144 f
, err
:= ioutil
.TempFile(localTmp(), "_Go_"+testName
)
146 t
.Fatalf("TempFile %s: %s", testName
, err
)
151 func newDir(testName
string, t
*testing
.T
) (name
string) {
152 name
, err
:= ioutil
.TempDir(localTmp(), "_Go_"+testName
)
154 t
.Fatalf("TempDir %s: %s", testName
, err
)
159 var sfdir
= sysdir
.name
160 var sfname
= sysdir
.files
[0]
162 func TestStat(t
*testing
.T
) {
163 path
:= sfdir
+ "/" + sfname
164 dir
, err
:= Stat(path
)
166 t
.Fatal("stat failed:", err
)
168 if !equal(sfname
, dir
.Name()) {
169 t
.Error("name should be ", sfname
, "; is", dir
.Name())
171 filesize
:= size(path
, t
)
172 if dir
.Size() != filesize
{
173 t
.Error("size should be", filesize
, "; is", dir
.Size())
177 func TestFstat(t
*testing
.T
) {
178 path
:= sfdir
+ "/" + sfname
179 file
, err1
:= Open(path
)
181 t
.Fatal("open failed:", err1
)
184 dir
, err2
:= file
.Stat()
186 t
.Fatal("fstat failed:", err2
)
188 if !equal(sfname
, dir
.Name()) {
189 t
.Error("name should be ", sfname
, "; is", dir
.Name())
191 filesize
:= size(path
, t
)
192 if dir
.Size() != filesize
{
193 t
.Error("size should be", filesize
, "; is", dir
.Size())
197 func TestLstat(t
*testing
.T
) {
198 path
:= sfdir
+ "/" + sfname
199 dir
, err
:= Lstat(path
)
201 t
.Fatal("lstat failed:", err
)
203 if !equal(sfname
, dir
.Name()) {
204 t
.Error("name should be ", sfname
, "; is", dir
.Name())
206 filesize
:= size(path
, t
)
207 if dir
.Size() != filesize
{
208 t
.Error("size should be", filesize
, "; is", dir
.Size())
212 // Read with length 0 should not return EOF.
213 func TestRead0(t
*testing
.T
) {
214 path
:= sfdir
+ "/" + sfname
217 t
.Fatal("open failed:", err
)
223 if n
!= 0 || err
!= nil {
224 t
.Errorf("Read(0) = %d, %v, want 0, nil", n
, err
)
226 b
= make([]byte, 100)
228 if n
<= 0 || err
!= nil {
229 t
.Errorf("Read(100) = %d, %v, want >0, nil", n
, err
)
233 // Reading a closed file should should return ErrClosed error
234 func TestReadClosed(t
*testing
.T
) {
235 path
:= sfdir
+ "/" + sfname
236 file
, err
:= Open(path
)
238 t
.Fatal("open failed:", err
)
240 file
.Close() // close immediately
242 b
:= make([]byte, 100)
243 _
, err
= file
.Read(b
)
245 e
, ok
:= err
.(*PathError
)
247 t
.Fatalf("Read: %T(%v), want PathError", e
, e
)
250 if e
.Err
!= ErrClosed
{
251 t
.Errorf("Read: %v, want PathError(ErrClosed)", e
)
255 func testReaddirnames(dir
string, contents
[]string, t
*testing
.T
) {
256 file
, err
:= Open(dir
)
258 t
.Fatalf("open %q failed: %v", dir
, err
)
261 s
, err2
:= file
.Readdirnames(-1)
263 t
.Fatalf("readdirnames %q failed: %v", dir
, err2
)
265 for _
, m
:= range contents
{
267 for _
, n
:= range s
{
268 if n
== "." || n
== ".." {
269 t
.Errorf("got %s in directory", n
)
273 t
.Error("present twice:", m
)
279 t
.Error("could not find", m
)
284 func testReaddir(dir
string, contents
[]string, t
*testing
.T
) {
285 file
, err
:= Open(dir
)
287 t
.Fatalf("open %q failed: %v", dir
, err
)
290 s
, err2
:= file
.Readdir(-1)
292 t
.Fatalf("readdir %q failed: %v", dir
, err2
)
294 for _
, m
:= range contents
{
296 for _
, n
:= range s
{
297 if equal(m
, n
.Name()) {
299 t
.Error("present twice:", m
)
305 t
.Error("could not find", m
)
310 func TestReaddirnames(t
*testing
.T
) {
311 testReaddirnames(".", dot
, t
)
312 testReaddirnames(sysdir
.name
, sysdir
.files
, t
)
315 func TestReaddir(t
*testing
.T
) {
316 testReaddir(".", dot
, t
)
317 testReaddir(sysdir
.name
, sysdir
.files
, t
)
320 func benchmarkReaddirname(path
string, b
*testing
.B
) {
322 for i
:= 0; i
< b
.N
; i
++ {
325 b
.Fatalf("open %q failed: %v", path
, err
)
327 ns
, err
:= f
.Readdirnames(-1)
330 b
.Fatalf("readdirnames %q failed: %v", path
, err
)
334 b
.Logf("benchmarkReaddirname %q: %d entries", path
, nentries
)
337 func benchmarkReaddir(path
string, b
*testing
.B
) {
339 for i
:= 0; i
< b
.N
; i
++ {
342 b
.Fatalf("open %q failed: %v", path
, err
)
344 fs
, err
:= f
.Readdir(-1)
347 b
.Fatalf("readdir %q failed: %v", path
, err
)
351 b
.Logf("benchmarkReaddir %q: %d entries", path
, nentries
)
354 func BenchmarkReaddirname(b
*testing
.B
) {
355 benchmarkReaddirname(".", b
)
358 func BenchmarkReaddir(b
*testing
.B
) {
359 benchmarkReaddir(".", b
)
362 // Read the directory one entry at a time.
363 func smallReaddirnames(file
*File
, length
int, t
*testing
.T
) []string {
364 names
:= make([]string, length
)
367 d
, err
:= file
.Readdirnames(1)
372 t
.Fatalf("readdirnames %q failed: %v", file
.Name(), err
)
375 t
.Fatalf("readdirnames %q returned empty slice and no error", file
.Name())
380 return names
[0:count
]
383 // Check that reading a directory one entry at a time gives the same result
384 // as reading it all at once.
385 func TestReaddirnamesOneAtATime(t
*testing
.T
) {
386 // big directory that doesn't change often.
388 switch runtime
.GOOS
{
392 switch runtime
.GOARCH
{
403 dir
= Getenv("SystemRoot") + "\\system32"
405 file
, err
:= Open(dir
)
407 t
.Fatalf("open %q failed: %v", dir
, err
)
410 all
, err1
:= file
.Readdirnames(-1)
412 t
.Fatalf("readdirnames %q failed: %v", dir
, err1
)
414 file1
, err2
:= Open(dir
)
416 t
.Fatalf("open %q failed: %v", dir
, err2
)
419 small
:= smallReaddirnames(file1
, len(all
)+100, t
) // +100 in case we screw up
420 if len(small
) < len(all
) {
421 t
.Fatalf("len(small) is %d, less than %d", len(small
), len(all
))
423 for i
, n
:= range all
{
425 t
.Errorf("small read %q mismatch: %v", small
[i
], n
)
430 func TestReaddirNValues(t
*testing
.T
) {
432 t
.Skip("test.short; skipping")
434 dir
, err
:= ioutil
.TempDir("", "")
436 t
.Fatalf("TempDir: %v", err
)
439 for i
:= 1; i
<= 105; i
++ {
440 f
, err
:= Create(filepath
.Join(dir
, fmt
.Sprintf("%d", i
)))
442 t
.Fatalf("Create: %v", err
)
444 f
.Write([]byte(strings
.Repeat("X", i
)))
453 t
.Fatalf("Open directory: %v", err
)
457 readDirExpect
:= func(n
, want
int, wantErr error
) {
458 fi
, err
:= d
.Readdir(n
)
460 t
.Fatalf("Readdir of %d got error %v, want %v", n
, err
, wantErr
)
462 if g
, e
:= len(fi
), want
; g
!= e
{
463 t
.Errorf("Readdir of %d got %d files, want %d", n
, g
, e
)
467 readDirNamesExpect
:= func(n
, want
int, wantErr error
) {
468 fi
, err
:= d
.Readdirnames(n
)
470 t
.Fatalf("Readdirnames of %d got error %v, want %v", n
, err
, wantErr
)
472 if g
, e
:= len(fi
), want
; g
!= e
{
473 t
.Errorf("Readdirnames of %d got %d files, want %d", n
, g
, e
)
477 for _
, fn
:= range []func(int, int, error
){readDirExpect
, readDirNamesExpect
} {
478 // Test the slurp case
484 // Slurp with -1 instead
491 // Test the bounded case
495 fn(105, 102, nil) // and tests buffer >100 case
501 func touch(t
*testing
.T
, name
string) {
502 f
, err
:= Create(name
)
506 if err
:= f
.Close(); err
!= nil {
511 func TestReaddirStatFailures(t
*testing
.T
) {
512 switch runtime
.GOOS
{
513 case "windows", "plan9":
514 // Windows and Plan 9 already do this correctly,
515 // but are structured with different syscalls such
516 // that they don't use Lstat, so the hook below for
517 // testing it wouldn't work.
518 t
.Skipf("skipping test on %v", runtime
.GOOS
)
520 dir
, err
:= ioutil
.TempDir("", "")
522 t
.Fatalf("TempDir: %v", err
)
525 touch(t
, filepath
.Join(dir
, "good1"))
526 touch(t
, filepath
.Join(dir
, "x")) // will disappear or have an error
527 touch(t
, filepath
.Join(dir
, "good2"))
531 var xerr error
// error to return for x
532 *LstatP
= func(path
string) (FileInfo
, error
) {
533 if xerr
!= nil && strings
.HasSuffix(path
, "x") {
538 readDir
:= func() ([]FileInfo
, error
) {
546 mustReadDir
:= func(testName
string) []FileInfo
{
547 fis
, err
:= readDir()
549 t
.Fatalf("%s: Readdir: %v", testName
, err
)
553 names
:= func(fis
[]FileInfo
) []string {
554 s
:= make([]string, len(fis
))
555 for i
, fi
:= range fis
{
562 if got
, want
:= names(mustReadDir("initial readdir")),
563 []string{"good1", "good2", "x"}; !reflect
.DeepEqual(got
, want
) {
564 t
.Errorf("initial readdir got %q; want %q", got
, want
)
568 if got
, want
:= names(mustReadDir("with x disappearing")),
569 []string{"good1", "good2"}; !reflect
.DeepEqual(got
, want
) {
570 t
.Errorf("with x disappearing, got %q; want %q", got
, want
)
573 xerr
= errors
.New("some real error")
574 if _
, err
:= readDir(); err
!= xerr
{
575 t
.Errorf("with a non-ErrNotExist error, got error %v; want %v", err
, xerr
)
579 // Readdir on a regular file should fail.
580 func TestReaddirOfFile(t
*testing
.T
) {
581 f
, err
:= ioutil
.TempFile("", "_Go_ReaddirOfFile")
585 defer Remove(f
.Name())
586 f
.Write([]byte("foo"))
588 reg
, err
:= Open(f
.Name())
594 names
, err
:= reg
.Readdirnames(-1)
596 t
.Error("Readdirnames succeeded; want non-nil error")
599 t
.Errorf("unexpected dir names in regular file: %q", names
)
603 func TestHardLink(t
*testing
.T
) {
604 testenv
.MustHaveLink(t
)
607 from
, to
:= "hardlinktestfrom", "hardlinktestto"
608 Remove(from
) // Just in case.
609 file
, err
:= Create(to
)
611 t
.Fatalf("open %q failed: %v", to
, err
)
614 if err
= file
.Close(); err
!= nil {
615 t
.Errorf("close %q failed: %v", to
, err
)
619 t
.Fatalf("link %q, %q failed: %v", to
, from
, err
)
622 none
:= "hardlinktestnone"
623 err
= Link(none
, none
)
624 // Check the returned error is well-formed.
625 if lerr
, ok
:= err
.(*LinkError
); !ok || lerr
.Error() == "" {
626 t
.Errorf("link %q, %q failed to return a valid error", none
, none
)
630 tostat
, err
:= Stat(to
)
632 t
.Fatalf("stat %q failed: %v", to
, err
)
634 fromstat
, err
:= Stat(from
)
636 t
.Fatalf("stat %q failed: %v", from
, err
)
638 if !SameFile(tostat
, fromstat
) {
639 t
.Errorf("link %q, %q did not create hard link", to
, from
)
643 // chtmpdir changes the working directory to a new temporary directory and
644 // provides a cleanup function. Used when PWD is read-only.
645 func chtmpdir(t
*testing
.T
) func() {
646 if runtime
.GOOS
!= "darwin" ||
(runtime
.GOARCH
!= "arm" && runtime
.GOARCH
!= "arm64") {
647 return func() {} // only needed on darwin/arm{,64}
649 oldwd
, err
:= Getwd()
651 t
.Fatalf("chtmpdir: %v", err
)
653 d
, err
:= ioutil
.TempDir("", "test")
655 t
.Fatalf("chtmpdir: %v", err
)
657 if err
:= Chdir(d
); err
!= nil {
658 t
.Fatalf("chtmpdir: %v", err
)
661 if err
:= Chdir(oldwd
); err
!= nil {
662 t
.Fatalf("chtmpdir: %v", err
)
668 func TestSymlink(t
*testing
.T
) {
669 testenv
.MustHaveSymlink(t
)
672 from
, to
:= "symlinktestfrom", "symlinktestto"
673 Remove(from
) // Just in case.
674 file
, err
:= Create(to
)
676 t
.Fatalf("open %q failed: %v", to
, err
)
679 if err
= file
.Close(); err
!= nil {
680 t
.Errorf("close %q failed: %v", to
, err
)
682 err
= Symlink(to
, from
)
684 t
.Fatalf("symlink %q, %q failed: %v", to
, from
, err
)
687 tostat
, err
:= Lstat(to
)
689 t
.Fatalf("stat %q failed: %v", to
, err
)
691 if tostat
.Mode()&ModeSymlink
!= 0 {
692 t
.Fatalf("stat %q claims to have found a symlink", to
)
694 fromstat
, err
:= Stat(from
)
696 t
.Fatalf("stat %q failed: %v", from
, err
)
698 if !SameFile(tostat
, fromstat
) {
699 t
.Errorf("symlink %q, %q did not create symlink", to
, from
)
701 fromstat
, err
= Lstat(from
)
703 t
.Fatalf("lstat %q failed: %v", from
, err
)
705 if fromstat
.Mode()&ModeSymlink
== 0 {
706 t
.Fatalf("symlink %q, %q did not create symlink", to
, from
)
708 fromstat
, err
= Stat(from
)
710 t
.Fatalf("stat %q failed: %v", from
, err
)
712 if fromstat
.Mode()&ModeSymlink
!= 0 {
713 t
.Fatalf("stat %q did not follow symlink", from
)
715 s
, err
:= Readlink(from
)
717 t
.Fatalf("readlink %q failed: %v", from
, err
)
720 t
.Fatalf("after symlink %q != %q", s
, to
)
722 file
, err
= Open(from
)
724 t
.Fatalf("open %q failed: %v", from
, err
)
729 func TestLongSymlink(t
*testing
.T
) {
730 testenv
.MustHaveSymlink(t
)
733 s
:= "0123456789abcdef"
734 // Long, but not too long: a common limit is 255.
735 s
= s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
+ s
736 from
:= "longsymlinktestfrom"
737 Remove(from
) // Just in case.
738 err
:= Symlink(s
, from
)
740 t
.Fatalf("symlink %q, %q failed: %v", s
, from
, err
)
743 r
, err
:= Readlink(from
)
745 t
.Fatalf("readlink %q failed: %v", from
, err
)
748 t
.Fatalf("after symlink %q != %q", r
, s
)
752 func TestRename(t
*testing
.T
) {
754 from
, to
:= "renamefrom", "renameto"
755 // Ensure we are not testing the overwrite case here.
759 file
, err
:= Create(from
)
761 t
.Fatalf("open %q failed: %v", from
, err
)
763 if err
= file
.Close(); err
!= nil {
764 t
.Errorf("close %q failed: %v", from
, err
)
766 err
= Rename(from
, to
)
768 t
.Fatalf("rename %q, %q failed: %v", to
, from
, err
)
773 t
.Errorf("stat %q failed: %v", to
, err
)
777 func TestRenameOverwriteDest(t
*testing
.T
) {
779 from
, to
:= "renamefrom", "renameto"
784 toData
:= []byte("to")
785 fromData
:= []byte("from")
787 err
:= ioutil
.WriteFile(to
, toData
, 0777)
789 t
.Fatalf("write file %q failed: %v", to
, err
)
792 err
= ioutil
.WriteFile(from
, fromData
, 0777)
794 t
.Fatalf("write file %q failed: %v", from
, err
)
796 err
= Rename(from
, to
)
798 t
.Fatalf("rename %q, %q failed: %v", to
, from
, err
)
804 t
.Errorf("from file %q still exists", from
)
806 if err
!= nil && !IsNotExist(err
) {
807 t
.Fatalf("stat from: %v", err
)
809 toFi
, err
:= Stat(to
)
811 t
.Fatalf("stat %q failed: %v", to
, err
)
813 if toFi
.Size() != int64(len(fromData
)) {
814 t
.Errorf(`"to" size = %d; want %d (old "from" size)`, toFi
.Size(), len(fromData
))
818 func TestRenameFailed(t
*testing
.T
) {
820 from
, to
:= "renamefrom", "renameto"
821 // Ensure we are not testing the overwrite case here.
825 err
:= Rename(from
, to
)
826 switch err
:= err
.(type) {
828 if err
.Op
!= "rename" {
829 t
.Errorf("rename %q, %q: err.Op: want %q, got %q", from
, to
, "rename", err
.Op
)
832 t
.Errorf("rename %q, %q: err.Old: want %q, got %q", from
, to
, from
, err
.Old
)
835 t
.Errorf("rename %q, %q: err.New: want %q, got %q", from
, to
, to
, err
.New
)
838 t
.Errorf("rename %q, %q: expected error, got nil", from
, to
)
840 // cleanup whatever was placed in "renameto"
843 t
.Errorf("rename %q, %q: expected %T, got %T %v", from
, to
, new(LinkError
), err
, err
)
847 func TestRenameToDirFailed(t
*testing
.T
) {
849 from
, to
:= "renamefrom", "renameto"
858 err
:= Rename(from
, to
)
859 switch err
:= err
.(type) {
861 if err
.Op
!= "rename" {
862 t
.Errorf("rename %q, %q: err.Op: want %q, got %q", from
, to
, "rename", err
.Op
)
865 t
.Errorf("rename %q, %q: err.Old: want %q, got %q", from
, to
, from
, err
.Old
)
868 t
.Errorf("rename %q, %q: err.New: want %q, got %q", from
, to
, to
, err
.New
)
871 t
.Errorf("rename %q, %q: expected error, got nil", from
, to
)
873 // cleanup whatever was placed in "renameto"
876 t
.Errorf("rename %q, %q: expected %T, got %T %v", from
, to
, new(LinkError
), err
, err
)
880 func exec(t
*testing
.T
, dir
, cmd
string, args
[]string, expect
string) {
883 t
.Fatalf("Pipe: %v", err
)
886 attr
:= &ProcAttr
{Dir
: dir
, Files
: []*File
{nil, w
, Stderr
}}
887 p
, err
:= StartProcess(cmd
, args
, attr
)
889 t
.Fatalf("StartProcess: %v", err
)
897 fi1
, _
:= Stat(strings
.TrimSpace(output
))
898 fi2
, _
:= Stat(expect
)
899 if !SameFile(fi1
, fi2
) {
900 t
.Errorf("exec %q returned %q wanted %q",
901 strings
.Join(append([]string{cmd
}, args
...), " "), output
, expect
)
906 func TestStartProcess(t
*testing
.T
) {
907 testenv
.MustHaveExec(t
)
911 switch runtime
.GOOS
{
913 t
.Skip("android doesn't have /bin/pwd")
915 cmd
= Getenv("COMSPEC")
916 dir
= Getenv("SystemRoot")
917 args
= []string{"/c", "cd"}
923 cmddir
, cmdbase
:= filepath
.Split(cmd
)
924 args
= append([]string{cmdbase
}, args
...)
925 // Test absolute executable path.
926 exec(t
, dir
, cmd
, args
, dir
)
927 // Test relative executable path.
928 exec(t
, cmddir
, cmdbase
, args
, cmddir
)
931 func checkMode(t
*testing
.T
, path
string, mode FileMode
) {
932 dir
, err
:= Stat(path
)
934 t
.Fatalf("Stat %q (looking for mode %#o): %s", path
, mode
, err
)
936 if dir
.Mode()&0777 != mode
{
937 t
.Errorf("Stat %q: mode %#o want %#o", path
, dir
.Mode(), mode
)
941 func TestChmod(t
*testing
.T
) {
942 // Chmod is not supported under windows.
943 if runtime
.GOOS
== "windows" {
946 f
:= newFile("TestChmod", t
)
947 defer Remove(f
.Name())
950 if err
:= Chmod(f
.Name(), 0456); err
!= nil {
951 t
.Fatalf("chmod %s 0456: %s", f
.Name(), err
)
953 checkMode(t
, f
.Name(), 0456)
955 if err
:= f
.Chmod(0123); err
!= nil {
956 t
.Fatalf("chmod %s 0123: %s", f
.Name(), err
)
958 checkMode(t
, f
.Name(), 0123)
961 func checkSize(t
*testing
.T
, f
*File
, size
int64) {
964 t
.Fatalf("Stat %q (looking for size %d): %s", f
.Name(), size
, err
)
966 if dir
.Size() != size
{
967 t
.Errorf("Stat %q: size %d want %d", f
.Name(), dir
.Size(), size
)
971 func TestFTruncate(t
*testing
.T
) {
972 f
:= newFile("TestFTruncate", t
)
973 defer Remove(f
.Name())
977 f
.Write([]byte("hello, world\n"))
982 checkSize(t
, f
, 1024)
985 _
, err
:= f
.Write([]byte("surprise!"))
987 checkSize(t
, f
, 13+9) // wrote at offset past where hello, world was.
991 func TestTruncate(t
*testing
.T
) {
992 f
:= newFile("TestTruncate", t
)
993 defer Remove(f
.Name())
997 f
.Write([]byte("hello, world\n"))
999 Truncate(f
.Name(), 10)
1001 Truncate(f
.Name(), 1024)
1002 checkSize(t
, f
, 1024)
1003 Truncate(f
.Name(), 0)
1005 _
, err
:= f
.Write([]byte("surprise!"))
1007 checkSize(t
, f
, 13+9) // wrote at offset past where hello, world was.
1011 // Use TempDir (via newFile) to make sure we're on a local file system,
1012 // so that timings are not distorted by latency and caching.
1013 // On NFS, timings can be off due to caching of meta-data on
1014 // NFS servers (Issue 848).
1015 func TestChtimes(t
*testing
.T
) {
1016 f
:= newFile("TestChtimes", t
)
1017 defer Remove(f
.Name())
1019 f
.Write([]byte("hello, world\n"))
1022 testChtimes(t
, f
.Name())
1025 // Use TempDir (via newDir) to make sure we're on a local file system,
1026 // so that timings are not distorted by latency and caching.
1027 // On NFS, timings can be off due to caching of meta-data on
1028 // NFS servers (Issue 848).
1029 func TestChtimesDir(t
*testing
.T
) {
1030 name
:= newDir("TestChtimes", t
)
1031 defer RemoveAll(name
)
1033 testChtimes(t
, name
)
1036 func testChtimes(t
*testing
.T
, name
string) {
1037 st
, err
:= Stat(name
)
1039 t
.Fatalf("Stat %s: %s", name
, err
)
1043 // Move access and modification time back a second
1044 at
:= Atime(preStat
)
1045 mt
:= preStat
.ModTime()
1046 err
= Chtimes(name
, at
.Add(-time
.Second
), mt
.Add(-time
.Second
))
1048 t
.Fatalf("Chtimes %s: %s", name
, err
)
1051 st
, err
= Stat(name
)
1053 t
.Fatalf("second Stat %s: %s", name
, err
)
1058 Mtime is the time of the last change of content. Similarly, atime is set whenever the
1059 contents are accessed; also, it is set whenever mtime is set.
1061 pat
:= Atime(postStat
)
1062 pmt
:= postStat
.ModTime()
1063 if !pat
.Before(at
) && runtime
.GOOS
!= "plan9" && runtime
.GOOS
!= "nacl" {
1064 t
.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at
, pat
)
1067 if !pmt
.Before(mt
) {
1068 t
.Errorf("ModTime didn't go backwards; was=%v, after=%v", mt
, pmt
)
1072 func TestChdirAndGetwd(t
*testing
.T
) {
1073 // TODO(brainman): file.Chdir() is not implemented on windows.
1074 if runtime
.GOOS
== "windows" {
1077 fd
, err
:= Open(".")
1079 t
.Fatalf("Open .: %s", err
)
1081 // These are chosen carefully not to be symlinks on a Mac
1082 // (unlike, say, /var, /etc), except /tmp, which we handle below.
1083 dirs
:= []string{"/", "/usr/bin", "/tmp"}
1084 // /usr/bin does not usually exist on Plan 9 or Android.
1085 switch runtime
.GOOS
{
1087 dirs
= []string{"/", "/system/bin"}
1089 dirs
= []string{"/", "/usr"}
1091 switch runtime
.GOARCH
{
1092 case "arm", "arm64":
1093 d1
, err
:= ioutil
.TempDir("", "d1")
1095 t
.Fatalf("TempDir: %v", err
)
1097 d2
, err
:= ioutil
.TempDir("", "d2")
1099 t
.Fatalf("TempDir: %v", err
)
1101 dirs
= []string{d1
, d2
}
1104 oldwd
:= Getenv("PWD")
1105 for mode
:= 0; mode
< 2; mode
++ {
1106 for _
, d
:= range dirs
{
1112 t
.Errorf("Open %s: %s", d
, err
)
1119 Setenv("PWD", "/tmp")
1121 pwd
, err1
:= Getwd()
1122 Setenv("PWD", oldwd
)
1125 // We changed the current directory and cannot go back.
1126 // Don't let the tests continue; they'll scribble
1127 // all over some other directory.
1128 fmt
.Fprintf(Stderr
, "fchdir back to dot failed: %s\n", err2
)
1133 t
.Fatalf("Chdir %s: %s", d
, err
)
1137 t
.Fatalf("Getwd in %s: %s", d
, err1
)
1141 t
.Fatalf("Getwd returned %q want %q", pwd
, d
)
1148 // Test that Chdir+Getwd is program-wide.
1149 func TestProgWideChdir(t
*testing
.T
) {
1151 c
:= make(chan bool)
1152 cpwd
:= make(chan string)
1153 for i
:= 0; i
< N
; i
++ {
1155 // Lock half the goroutines in their own operating system
1156 // thread to exercise more scheduler possibilities.
1158 // On Plan 9, after calling LockOSThread, the goroutines
1159 // run on different processes which don't share the working
1160 // directory. This used to be an issue because Go expects
1161 // the working directory to be program-wide.
1163 runtime
.LockOSThread()
1168 t
.Errorf("Getwd on goroutine %d: %v", i
, err
)
1174 oldwd
, err
:= Getwd()
1176 t
.Fatalf("Getwd: %v", err
)
1178 d
, err
:= ioutil
.TempDir("", "test")
1180 t
.Fatalf("TempDir: %v", err
)
1183 if err
:= Chdir(oldwd
); err
!= nil {
1184 t
.Fatalf("Chdir: %v", err
)
1188 if err
:= Chdir(d
); err
!= nil {
1189 t
.Fatalf("Chdir: %v", err
)
1191 // OS X sets TMPDIR to a symbolic link.
1192 // So we resolve our working directory again before the test.
1195 t
.Fatalf("Getwd: %v", err
)
1198 for i
:= 0; i
< N
; i
++ {
1201 t
.Errorf("Getwd returned %q; want %q", pwd
, d
)
1206 func TestSeek(t
*testing
.T
) {
1207 f
:= newFile("TestSeek", t
)
1208 defer Remove(f
.Name())
1211 const data
= "hello, world\n"
1212 io
.WriteString(f
, data
)
1220 {0, io
.SeekCurrent
, int64(len(data
))},
1221 {0, io
.SeekStart
, 0},
1222 {5, io
.SeekStart
, 5},
1223 {0, io
.SeekEnd
, int64(len(data
))},
1224 {0, io
.SeekStart
, 0},
1225 {-1, io
.SeekEnd
, int64(len(data
)) - 1},
1226 {1 << 33, io
.SeekStart
, 1 << 33},
1227 {1 << 33, io
.SeekEnd
, 1<<33 + int64(len(data
))},
1229 for i
, tt
:= range tests
{
1230 off
, err
:= f
.Seek(tt
.in
, tt
.whence
)
1231 if off
!= tt
.out || err
!= nil {
1232 if e
, ok
:= err
.(*PathError
); ok
&& e
.Err
== syscall
.EINVAL
&& tt
.out
> 1<<32 {
1233 // Reiserfs rejects the big seeks.
1234 // https://golang.org/issue/91
1237 t
.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i
, tt
.in
, tt
.whence
, off
, err
, tt
.out
)
1242 type openErrorTest
struct {
1248 var openErrorTests
= []openErrorTest
{
1250 sfdir
+ "/no-such-file",
1260 sfdir
+ "/" + sfname
+ "/no-such-file",
1266 func TestOpenError(t
*testing
.T
) {
1267 for _
, tt
:= range openErrorTests
{
1268 f
, err
:= OpenFile(tt
.path
, tt
.mode
, 0)
1270 t
.Errorf("Open(%q, %d) succeeded", tt
.path
, tt
.mode
)
1274 perr
, ok
:= err
.(*PathError
)
1276 t
.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt
.path
, tt
.mode
, err
)
1278 if perr
.Err
!= tt
.error
{
1279 if runtime
.GOOS
== "plan9" {
1280 syscallErrStr
:= perr
.Err
.Error()
1281 expectedErrStr
:= strings
.Replace(tt
.error
.Error(), "file ", "", 1)
1282 if !strings
.HasSuffix(syscallErrStr
, expectedErrStr
) {
1283 // Some Plan 9 file servers incorrectly return
1284 // EACCES rather than EISDIR when a directory is
1285 // opened for write.
1286 if tt
.error
== syscall
.EISDIR
&& strings
.HasSuffix(syscallErrStr
, syscall
.EACCES
.Error()) {
1289 t
.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt
.path
, tt
.mode
, syscallErrStr
, expectedErrStr
)
1293 if runtime
.GOOS
== "dragonfly" {
1294 // DragonFly incorrectly returns EACCES rather
1295 // EISDIR when a directory is opened for write.
1296 if tt
.error
== syscall
.EISDIR
&& perr
.Err
== syscall
.EACCES
{
1300 t
.Errorf("Open(%q, %d) = _, %q; want %q", tt
.path
, tt
.mode
, perr
.Err
.Error(), tt
.error
.Error())
1305 func TestOpenNoName(t
*testing
.T
) {
1308 t
.Fatal(`Open("") succeeded`)
1313 func runBinHostname(t
*testing
.T
) string {
1314 // Run /bin/hostname and collect output.
1320 const path
= "/bin/hostname"
1321 p
, err
:= StartProcess(path
, []string{"hostname"}, &ProcAttr
{Files
: []*File
{nil, w
, Stderr
}})
1323 if _
, err
:= Stat(path
); IsNotExist(err
) {
1324 t
.Skipf("skipping test; test requires %s but it does not exist", path
)
1334 t
.Fatalf("run hostname Wait: %v", err
)
1338 t
.Errorf("expected an error from Kill running 'hostname'")
1340 output
:= b
.String()
1341 if n
:= len(output
); n
> 0 && output
[n
-1] == '\n' {
1342 output
= output
[0 : n
-1]
1345 t
.Fatalf("/bin/hostname produced no output")
1351 func testWindowsHostname(t
*testing
.T
) {
1352 hostname
, err
:= Hostname()
1356 cmd
:= osexec
.Command("hostname")
1357 out
, err
:= cmd
.CombinedOutput()
1359 t
.Fatalf("Failed to execute hostname command: %v %s", err
, out
)
1361 want
:= strings
.Trim(string(out
), "\r\n")
1362 if hostname
!= want
{
1363 t
.Fatalf("Hostname() = %q, want %q", hostname
, want
)
1367 func TestHostname(t
*testing
.T
) {
1368 // There is no other way to fetch hostname on windows, but via winapi.
1369 // On Plan 9 it can be taken from #c/sysname as Hostname() does.
1370 switch runtime
.GOOS
{
1371 case "android", "plan9":
1372 t
.Skipf("%s doesn't have /bin/hostname", runtime
.GOOS
)
1374 testWindowsHostname(t
)
1378 testenv
.MustHaveExec(t
)
1380 // Check internal Hostname() against the output of /bin/hostname.
1381 // Allow that the internal Hostname returns a Fully Qualified Domain Name
1382 // and the /bin/hostname only returns the first component
1383 hostname
, err
:= Hostname()
1387 want
:= runBinHostname(t
)
1388 if hostname
!= want
{
1389 i
:= strings
.Index(hostname
, ".")
1390 if i
< 0 || hostname
[0:i
] != want
{
1391 t
.Errorf("Hostname() = %q, want %q", hostname
, want
)
1396 func TestReadAt(t
*testing
.T
) {
1397 f
:= newFile("TestReadAt", t
)
1398 defer Remove(f
.Name())
1401 const data
= "hello, world\n"
1402 io
.WriteString(f
, data
)
1404 b
:= make([]byte, 5)
1405 n
, err
:= f
.ReadAt(b
, 7)
1406 if err
!= nil || n
!= len(b
) {
1407 t
.Fatalf("ReadAt 7: %d, %v", n
, err
)
1409 if string(b
) != "world" {
1410 t
.Fatalf("ReadAt 7: have %q want %q", string(b
), "world")
1414 // Verify that ReadAt doesn't affect seek offset.
1415 // In the Plan 9 kernel, there used to be a bug in the implementation of
1416 // the pread syscall, where the channel offset was erroneously updated after
1417 // calling pread on a file.
1418 func TestReadAtOffset(t
*testing
.T
) {
1419 f
:= newFile("TestReadAtOffset", t
)
1420 defer Remove(f
.Name())
1423 const data
= "hello, world\n"
1424 io
.WriteString(f
, data
)
1427 b
:= make([]byte, 5)
1429 n
, err
:= f
.ReadAt(b
, 7)
1430 if err
!= nil || n
!= len(b
) {
1431 t
.Fatalf("ReadAt 7: %d, %v", n
, err
)
1433 if string(b
) != "world" {
1434 t
.Fatalf("ReadAt 7: have %q want %q", string(b
), "world")
1438 if err
!= nil || n
!= len(b
) {
1439 t
.Fatalf("Read: %d, %v", n
, err
)
1441 if string(b
) != "hello" {
1442 t
.Fatalf("Read: have %q want %q", string(b
), "hello")
1446 func TestWriteAt(t
*testing
.T
) {
1447 f
:= newFile("TestWriteAt", t
)
1448 defer Remove(f
.Name())
1451 const data
= "hello, world\n"
1452 io
.WriteString(f
, data
)
1454 n
, err
:= f
.WriteAt([]byte("WORLD"), 7)
1455 if err
!= nil || n
!= 5 {
1456 t
.Fatalf("WriteAt 7: %d, %v", n
, err
)
1459 b
, err
:= ioutil
.ReadFile(f
.Name())
1461 t
.Fatalf("ReadFile %s: %v", f
.Name(), err
)
1463 if string(b
) != "hello, WORLD\n" {
1464 t
.Fatalf("after write: have %q want %q", string(b
), "hello, WORLD\n")
1468 func writeFile(t
*testing
.T
, fname
string, flag
int, text
string) string {
1469 f
, err
:= OpenFile(fname
, flag
, 0666)
1471 t
.Fatalf("Open: %v", err
)
1473 n
, err
:= io
.WriteString(f
, text
)
1475 t
.Fatalf("WriteString: %d, %v", n
, err
)
1478 data
, err
:= ioutil
.ReadFile(fname
)
1480 t
.Fatalf("ReadFile: %v", err
)
1485 func TestAppend(t
*testing
.T
) {
1487 const f
= "append.txt"
1489 s
:= writeFile(t
, f
, O_CREATE|O_TRUNC|O_RDWR
, "new")
1491 t
.Fatalf("writeFile: have %q want %q", s
, "new")
1493 s
= writeFile(t
, f
, O_APPEND|O_RDWR
, "|append")
1494 if s
!= "new|append" {
1495 t
.Fatalf("writeFile: have %q want %q", s
, "new|append")
1497 s
= writeFile(t
, f
, O_CREATE|O_APPEND|O_RDWR
, "|append")
1498 if s
!= "new|append|append" {
1499 t
.Fatalf("writeFile: have %q want %q", s
, "new|append|append")
1503 t
.Fatalf("Remove: %v", err
)
1505 s
= writeFile(t
, f
, O_CREATE|O_APPEND|O_RDWR
, "new&append")
1506 if s
!= "new&append" {
1507 t
.Fatalf("writeFile: after append have %q want %q", s
, "new&append")
1509 s
= writeFile(t
, f
, O_CREATE|O_RDWR
, "old")
1510 if s
!= "old&append" {
1511 t
.Fatalf("writeFile: after create have %q want %q", s
, "old&append")
1513 s
= writeFile(t
, f
, O_CREATE|O_TRUNC|O_RDWR
, "new")
1515 t
.Fatalf("writeFile: after truncate have %q want %q", s
, "new")
1519 func TestStatDirWithTrailingSlash(t
*testing
.T
) {
1520 // Create new temporary directory and arrange to clean it up.
1521 path
, err
:= ioutil
.TempDir("", "/_TestStatDirWithSlash_")
1523 t
.Fatalf("TempDir: %s", err
)
1525 defer RemoveAll(path
)
1527 // Stat of path should succeed.
1530 t
.Fatalf("stat %s failed: %s", path
, err
)
1533 // Stat of path+"/" should succeed too.
1537 t
.Fatalf("stat %s failed: %s", path
, err
)
1541 func TestNilProcessStateString(t
*testing
.T
) {
1542 var ps
*ProcessState
1545 t
.Errorf("(*ProcessState)(nil).String() = %q, want %q", s
, "<nil>")
1549 func TestSameFile(t
*testing
.T
) {
1551 fa
, err
:= Create("a")
1553 t
.Fatalf("Create(a): %v", err
)
1555 defer Remove(fa
.Name())
1557 fb
, err
:= Create("b")
1559 t
.Fatalf("Create(b): %v", err
)
1561 defer Remove(fb
.Name())
1564 ia1
, err
:= Stat("a")
1566 t
.Fatalf("Stat(a): %v", err
)
1568 ia2
, err
:= Stat("a")
1570 t
.Fatalf("Stat(a): %v", err
)
1572 if !SameFile(ia1
, ia2
) {
1573 t
.Errorf("files should be same")
1576 ib
, err
:= Stat("b")
1578 t
.Fatalf("Stat(b): %v", err
)
1580 if SameFile(ia1
, ib
) {
1581 t
.Errorf("files should be different")
1585 func TestDevNullFile(t
*testing
.T
) {
1586 f
, err
:= Open(DevNull
)
1588 t
.Fatalf("Open(%s): %v", DevNull
, err
)
1593 t
.Fatalf("Stat(%s): %v", DevNull
, err
)
1595 name
:= filepath
.Base(DevNull
)
1596 if fi
.Name() != name
{
1597 t
.Fatalf("wrong file name have %v want %v", fi
.Name(), name
)
1600 t
.Fatalf("wrong file size have %d want 0", fi
.Size())
1604 var testLargeWrite
= flag
.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
1606 func TestLargeWriteToConsole(t
*testing
.T
) {
1607 if !*testLargeWrite
{
1608 t
.Skip("skipping console-flooding test; enable with -large_write")
1610 b
:= make([]byte, 32000)
1615 n
, err
:= Stdout
.Write(b
)
1617 t
.Fatalf("Write to os.Stdout failed: %v", err
)
1620 t
.Errorf("Write to os.Stdout should return %d; got %d", len(b
), n
)
1622 n
, err
= Stderr
.Write(b
)
1624 t
.Fatalf("Write to os.Stderr failed: %v", err
)
1627 t
.Errorf("Write to os.Stderr should return %d; got %d", len(b
), n
)
1631 func TestStatDirModeExec(t
*testing
.T
) {
1634 path
, err
:= ioutil
.TempDir("", "go-build")
1636 t
.Fatalf("Failed to create temp directory: %v", err
)
1638 defer RemoveAll(path
)
1640 if err
:= Chmod(path
, 0777); err
!= nil {
1641 t
.Fatalf("Chmod %q 0777: %v", path
, err
)
1644 dir
, err
:= Stat(path
)
1646 t
.Fatalf("Stat %q (looking for mode %#o): %s", path
, mode
, err
)
1648 if dir
.Mode()&mode
!= mode
{
1649 t
.Errorf("Stat %q: mode %#o want %#o", path
, dir
.Mode()&mode
, mode
)
1653 func TestStatStdin(t
*testing
.T
) {
1654 switch runtime
.GOOS
{
1655 case "android", "plan9":
1656 t
.Skipf("%s doesn't have /bin/sh", runtime
.GOOS
)
1659 testenv
.MustHaveExec(t
)
1661 if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
1662 st
, err
:= Stdin
.Stat()
1664 t
.Fatalf("Stat failed: %v", err
)
1666 fmt
.Println(st
.Mode() & ModeNamedPipe
)
1671 if runtime
.GOOS
== "windows" {
1672 cmd
= osexec
.Command("cmd", "/c", "echo output | "+Args
[0]+" -test.run=TestStatStdin")
1674 cmd
= osexec
.Command("/bin/sh", "-c", "echo output | "+Args
[0]+" -test.run=TestStatStdin")
1676 cmd
.Env
= append(Environ(), "GO_WANT_HELPER_PROCESS=1")
1678 output
, err
:= cmd
.CombinedOutput()
1680 t
.Fatalf("Failed to spawn child process: %v %q", err
, string(output
))
1683 // result will be like "prw-rw-rw"
1684 if len(output
) < 1 || output
[0] != 'p' {
1685 t
.Fatalf("Child process reports stdin is not pipe '%v'", string(output
))
1689 func TestReadAtEOF(t
*testing
.T
) {
1690 f
:= newFile("TestReadAtEOF", t
)
1691 defer Remove(f
.Name())
1694 _
, err
:= f
.ReadAt(make([]byte, 10), 0)
1699 t
.Fatalf("ReadAt succeeded")
1701 t
.Fatalf("ReadAt failed: %s", err
)
1705 func TestLongPath(t
*testing
.T
) {
1706 tmpdir
:= newDir("TestLongPath", t
)
1707 defer func(d
string) {
1708 if err
:= RemoveAll(d
); err
!= nil {
1709 t
.Fatalf("RemoveAll failed: %v", err
)
1713 // Test the boundary of 247 and fewer bytes (normal) and 248 and more bytes (adjusted).
1714 sizes
:= []int{247, 248, 249, 400}
1715 for len(tmpdir
) < 400 {
1716 tmpdir
+= "/dir3456789"
1718 for _
, sz
:= range sizes
{
1719 t
.Run(fmt
.Sprintf("length=%d", sz
), func(t
*testing
.T
) {
1720 sizedTempDir
:= tmpdir
[:sz
-1] + "x" // Ensure it does not end with a slash.
1722 // The various sized runs are for this call to trigger the boundary
1724 if err
:= MkdirAll(sizedTempDir
, 0755); err
!= nil {
1725 t
.Fatalf("MkdirAll failed: %v", err
)
1727 data
:= []byte("hello world\n")
1728 if err
:= ioutil
.WriteFile(sizedTempDir
+"/foo.txt", data
, 0644); err
!= nil {
1729 t
.Fatalf("ioutil.WriteFile() failed: %v", err
)
1731 if err
:= Rename(sizedTempDir
+"/foo.txt", sizedTempDir
+"/bar.txt"); err
!= nil {
1732 t
.Fatalf("Rename failed: %v", err
)
1734 mtime
:= time
.Now().Truncate(time
.Minute
)
1735 if err
:= Chtimes(sizedTempDir
+"/bar.txt", mtime
, mtime
); err
!= nil {
1736 t
.Fatalf("Chtimes failed: %v", err
)
1738 names
:= []string{"bar.txt"}
1739 if testenv
.HasSymlink() {
1740 if err
:= Symlink(sizedTempDir
+"/bar.txt", sizedTempDir
+"/symlink.txt"); err
!= nil {
1741 t
.Fatalf("Symlink failed: %v", err
)
1743 names
= append(names
, "symlink.txt")
1745 if testenv
.HasLink() {
1746 if err
:= Link(sizedTempDir
+"/bar.txt", sizedTempDir
+"/link.txt"); err
!= nil {
1747 t
.Fatalf("Link failed: %v", err
)
1749 names
= append(names
, "link.txt")
1751 for _
, wantSize
:= range []int64{int64(len(data
)), 0} {
1752 for _
, name
:= range names
{
1753 path
:= sizedTempDir
+ "/" + name
1754 dir
, err
:= Stat(path
)
1756 t
.Fatalf("Stat(%q) failed: %v", path
, err
)
1758 filesize
:= size(path
, t
)
1759 if dir
.Size() != filesize || filesize
!= wantSize
{
1760 t
.Errorf("Size(%q) is %d, len(ReadFile()) is %d, want %d", path
, dir
.Size(), filesize
, wantSize
)
1763 if err
:= Truncate(sizedTempDir
+"/bar.txt", 0); err
!= nil {
1764 t
.Fatalf("Truncate failed: %v", err
)
1771 func testKillProcess(t
*testing
.T
, processKiller
func(p
*Process
)) {
1772 testenv
.MustHaveExec(t
)
1774 // Re-exec the test binary itself to emulate "sleep 1".
1775 cmd
:= osexec
.Command(Args
[0], "-test.run", "TestSleep")
1778 t
.Fatalf("Failed to start test process: %v", err
)
1781 time
.Sleep(100 * time
.Millisecond
)
1782 processKiller(cmd
.Process
)
1786 t
.Errorf("Test process succeeded, but expected to fail")
1790 // TestSleep emulates "sleep 1". It is a helper for testKillProcess, so we
1791 // don't have to rely on an external "sleep" command being available.
1792 func TestSleep(t
*testing
.T
) {
1793 if testing
.Short() {
1794 t
.Skip("Skipping in short mode")
1796 time
.Sleep(time
.Second
)
1799 func TestKillStartProcess(t
*testing
.T
) {
1800 testKillProcess(t
, func(p
*Process
) {
1803 t
.Fatalf("Failed to kill test process: %v", err
)
1808 func TestGetppid(t
*testing
.T
) {
1809 if runtime
.GOOS
== "plan9" {
1810 // TODO: golang.org/issue/8206
1811 t
.Skipf("skipping test on plan9; see issue 8206")
1814 testenv
.MustHaveExec(t
)
1816 if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
1817 fmt
.Print(Getppid())
1821 cmd
:= osexec
.Command(Args
[0], "-test.run=TestGetppid")
1822 cmd
.Env
= append(Environ(), "GO_WANT_HELPER_PROCESS=1")
1824 // verify that Getppid() from the forked process reports our process id
1825 output
, err
:= cmd
.CombinedOutput()
1827 t
.Fatalf("Failed to spawn child process: %v %q", err
, string(output
))
1830 childPpid
:= string(output
)
1831 ourPid
:= fmt
.Sprintf("%d", Getpid())
1832 if childPpid
!= ourPid
{
1833 t
.Fatalf("Child process reports parent process id '%v', expected '%v'", childPpid
, ourPid
)
1837 func TestKillFindProcess(t
*testing
.T
) {
1838 testKillProcess(t
, func(p
*Process
) {
1839 p2
, err
:= FindProcess(p
.Pid
)
1841 t
.Fatalf("Failed to find test process: %v", err
)
1845 t
.Fatalf("Failed to kill test process: %v", err
)
1850 var nilFileMethodTests
= []struct {
1854 {"Chdir", func(f
*File
) error
{ return f
.Chdir() }},
1855 {"Close", func(f
*File
) error
{ return f
.Close() }},
1856 {"Chmod", func(f
*File
) error
{ return f
.Chmod(0) }},
1857 {"Chown", func(f
*File
) error
{ return f
.Chown(0, 0) }},
1858 {"Read", func(f
*File
) error
{ _
, err
:= f
.Read(make([]byte, 0)); return err
}},
1859 {"ReadAt", func(f
*File
) error
{ _
, err
:= f
.ReadAt(make([]byte, 0), 0); return err
}},
1860 {"Readdir", func(f
*File
) error
{ _
, err
:= f
.Readdir(1); return err
}},
1861 {"Readdirnames", func(f
*File
) error
{ _
, err
:= f
.Readdirnames(1); return err
}},
1862 {"Seek", func(f
*File
) error
{ _
, err
:= f
.Seek(0, io
.SeekStart
); return err
}},
1863 {"Stat", func(f
*File
) error
{ _
, err
:= f
.Stat(); return err
}},
1864 {"Sync", func(f
*File
) error
{ return f
.Sync() }},
1865 {"Truncate", func(f
*File
) error
{ return f
.Truncate(0) }},
1866 {"Write", func(f
*File
) error
{ _
, err
:= f
.Write(make([]byte, 0)); return err
}},
1867 {"WriteAt", func(f
*File
) error
{ _
, err
:= f
.WriteAt(make([]byte, 0), 0); return err
}},
1868 {"WriteString", func(f
*File
) error
{ _
, err
:= f
.WriteString(""); return err
}},
1871 // Test that all File methods give ErrInvalid if the receiver is nil.
1872 func TestNilFileMethods(t
*testing
.T
) {
1873 for _
, tt
:= range nilFileMethodTests
{
1876 if got
!= ErrInvalid
{
1877 t
.Errorf("%v should fail when f is nil; got %v", tt
.name
, got
)
1882 func mkdirTree(t
*testing
.T
, root
string, level
, max
int) {
1887 for i
:= 'a'; i
< 'c'; i
++ {
1888 dir
:= filepath
.Join(root
, string(i
))
1889 if err
:= Mkdir(dir
, 0700); err
!= nil {
1892 mkdirTree(t
, dir
, level
, max
)
1896 // Test that simultaneous RemoveAll do not report an error.
1897 // As long as it gets removed, we should be happy.
1898 func TestRemoveAllRace(t
*testing
.T
) {
1899 if runtime
.GOOS
== "windows" {
1900 // Windows has very strict rules about things like
1901 // removing directories while someone else has
1902 // them open. The racing doesn't work out nicely
1903 // like it does on Unix.
1904 t
.Skip("skipping on windows")
1907 n
:= runtime
.GOMAXPROCS(16)
1908 defer runtime
.GOMAXPROCS(n
)
1909 root
, err
:= ioutil
.TempDir("", "issue")
1913 mkdirTree(t
, root
, 1, 6)
1914 hold
:= make(chan struct{})
1915 var wg sync
.WaitGroup
1916 for i
:= 0; i
< 4; i
++ {
1921 err
:= RemoveAll(root
)
1923 t
.Errorf("unexpected error: %T, %q", err
, err
)
1927 close(hold
) // let workers race to remove root