Daily bump.
[official-gcc.git] / libgo / go / os / os_test.go
blob882e3da1517d800289daf368ac09a317bc4bad5c
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.
5 package os_test
7 import (
8 "bytes"
9 "flag"
10 "fmt"
11 "io"
12 "io/ioutil"
13 . "os"
14 osexec "os/exec"
15 "path/filepath"
16 "runtime"
17 "strings"
18 "syscall"
19 "testing"
20 "text/template"
21 "time"
24 var dot = []string{
25 "dir_unix.go",
26 "env.go",
27 "error.go",
28 "file.go",
29 "os_test.go",
30 "types.go",
33 type sysDir struct {
34 name string
35 files []string
38 var sysdir = func() (sd *sysDir) {
39 switch runtime.GOOS {
40 case "windows":
41 sd = &sysDir{
42 Getenv("SystemRoot") + "\\system32\\drivers\\etc",
43 []string{
44 "networks",
45 "protocol",
46 "services",
49 case "plan9":
50 sd = &sysDir{
51 "/lib/ndb",
52 []string{
53 "common",
54 "local",
57 default:
58 sd = &sysDir{
59 "/etc",
60 []string{
61 "group",
62 "hosts",
63 "passwd",
67 return
68 }()
70 func size(name string, t *testing.T) int64 {
71 file, err := Open(name)
72 if err != nil {
73 t.Fatal("open failed:", err)
75 defer file.Close()
76 var buf [100]byte
77 len := 0
78 for {
79 n, e := file.Read(buf[0:])
80 len += n
81 if e == io.EOF {
82 break
84 if e != nil {
85 t.Fatal("read failed:", err)
88 return int64(len)
91 func equal(name1, name2 string) (r bool) {
92 switch runtime.GOOS {
93 case "windows":
94 r = strings.ToLower(name1) == strings.ToLower(name2)
95 default:
96 r = name1 == name2
98 return
101 func newFile(testName string, t *testing.T) (f *File) {
102 // Use a local file system, not NFS.
103 // On Unix, override $TMPDIR in case the user
104 // has it set to an NFS-mounted directory.
105 dir := ""
106 if runtime.GOOS != "windows" {
107 dir = "/tmp"
109 f, err := ioutil.TempFile(dir, "_Go_"+testName)
110 if err != nil {
111 t.Fatalf("open %s: %s", testName, err)
113 return
116 var sfdir = sysdir.name
117 var sfname = sysdir.files[0]
119 func TestStat(t *testing.T) {
120 path := sfdir + "/" + sfname
121 dir, err := Stat(path)
122 if err != nil {
123 t.Fatal("stat failed:", err)
125 if !equal(sfname, dir.Name()) {
126 t.Error("name should be ", sfname, "; is", dir.Name())
128 filesize := size(path, t)
129 if dir.Size() != filesize {
130 t.Error("size should be", filesize, "; is", dir.Size())
134 func TestFstat(t *testing.T) {
135 path := sfdir + "/" + sfname
136 file, err1 := Open(path)
137 if err1 != nil {
138 t.Fatal("open failed:", err1)
140 defer file.Close()
141 dir, err2 := file.Stat()
142 if err2 != nil {
143 t.Fatal("fstat failed:", err2)
145 if !equal(sfname, dir.Name()) {
146 t.Error("name should be ", sfname, "; is", dir.Name())
148 filesize := size(path, t)
149 if dir.Size() != filesize {
150 t.Error("size should be", filesize, "; is", dir.Size())
154 func TestLstat(t *testing.T) {
155 path := sfdir + "/" + sfname
156 dir, err := Lstat(path)
157 if err != nil {
158 t.Fatal("lstat failed:", err)
160 if !equal(sfname, dir.Name()) {
161 t.Error("name should be ", sfname, "; is", dir.Name())
163 filesize := size(path, t)
164 if dir.Size() != filesize {
165 t.Error("size should be", filesize, "; is", dir.Size())
169 // Read with length 0 should not return EOF.
170 func TestRead0(t *testing.T) {
171 path := sfdir + "/" + sfname
172 f, err := Open(path)
173 if err != nil {
174 t.Fatal("open failed:", err)
176 defer f.Close()
178 b := make([]byte, 0)
179 n, err := f.Read(b)
180 if n != 0 || err != nil {
181 t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
183 b = make([]byte, 100)
184 n, err = f.Read(b)
185 if n <= 0 || err != nil {
186 t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
190 func testReaddirnames(dir string, contents []string, t *testing.T) {
191 file, err := Open(dir)
192 if err != nil {
193 t.Fatalf("open %q failed: %v", dir, err)
195 defer file.Close()
196 s, err2 := file.Readdirnames(-1)
197 if err2 != nil {
198 t.Fatalf("readdirnames %q failed: %v", dir, err2)
200 for _, m := range contents {
201 found := false
202 for _, n := range s {
203 if n == "." || n == ".." {
204 t.Errorf("got %s in directory", n)
206 if equal(m, n) {
207 if found {
208 t.Error("present twice:", m)
210 found = true
213 if !found {
214 t.Error("could not find", m)
219 func testReaddir(dir string, contents []string, t *testing.T) {
220 file, err := Open(dir)
221 if err != nil {
222 t.Fatalf("open %q failed: %v", dir, err)
224 defer file.Close()
225 s, err2 := file.Readdir(-1)
226 if err2 != nil {
227 t.Fatalf("readdir %q failed: %v", dir, err2)
229 for _, m := range contents {
230 found := false
231 for _, n := range s {
232 if equal(m, n.Name()) {
233 if found {
234 t.Error("present twice:", m)
236 found = true
239 if !found {
240 t.Error("could not find", m)
245 func TestReaddirnames(t *testing.T) {
246 testReaddirnames(".", dot, t)
247 testReaddirnames(sysdir.name, sysdir.files, t)
250 func TestReaddir(t *testing.T) {
251 testReaddir(".", dot, t)
252 testReaddir(sysdir.name, sysdir.files, t)
255 // Read the directory one entry at a time.
256 func smallReaddirnames(file *File, length int, t *testing.T) []string {
257 names := make([]string, length)
258 count := 0
259 for {
260 d, err := file.Readdirnames(1)
261 if err == io.EOF {
262 break
264 if err != nil {
265 t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
267 if len(d) == 0 {
268 t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
270 names[count] = d[0]
271 count++
273 return names[0:count]
276 // Check that reading a directory one entry at a time gives the same result
277 // as reading it all at once.
278 func TestReaddirnamesOneAtATime(t *testing.T) {
279 // big directory that doesn't change often.
280 dir := "/usr/bin"
281 switch runtime.GOOS {
282 case "windows":
283 dir = Getenv("SystemRoot") + "\\system32"
284 case "plan9":
285 dir = "/bin"
287 file, err := Open(dir)
288 if err != nil {
289 t.Fatalf("open %q failed: %v", dir, err)
291 defer file.Close()
292 all, err1 := file.Readdirnames(-1)
293 if err1 != nil {
294 t.Fatalf("readdirnames %q failed: %v", dir, err1)
296 file1, err2 := Open(dir)
297 if err2 != nil {
298 t.Fatalf("open %q failed: %v", dir, err2)
300 defer file1.Close()
301 small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
302 if len(small) < len(all) {
303 t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
305 for i, n := range all {
306 if small[i] != n {
307 t.Errorf("small read %q mismatch: %v", small[i], n)
312 func TestReaddirNValues(t *testing.T) {
313 if testing.Short() {
314 t.Skip("test.short; skipping")
316 dir, err := ioutil.TempDir("", "")
317 if err != nil {
318 t.Fatalf("TempDir: %v", err)
320 defer RemoveAll(dir)
321 for i := 1; i <= 105; i++ {
322 f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
323 if err != nil {
324 t.Fatalf("Create: %v", err)
326 f.Write([]byte(strings.Repeat("X", i)))
327 f.Close()
330 var d *File
331 openDir := func() {
332 var err error
333 d, err = Open(dir)
334 if err != nil {
335 t.Fatalf("Open directory: %v", err)
339 readDirExpect := func(n, want int, wantErr error) {
340 fi, err := d.Readdir(n)
341 if err != wantErr {
342 t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
344 if g, e := len(fi), want; g != e {
345 t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
349 readDirNamesExpect := func(n, want int, wantErr error) {
350 fi, err := d.Readdirnames(n)
351 if err != wantErr {
352 t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
354 if g, e := len(fi), want; g != e {
355 t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
359 for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
360 // Test the slurp case
361 openDir()
362 fn(0, 105, nil)
363 fn(0, 0, nil)
364 d.Close()
366 // Slurp with -1 instead
367 openDir()
368 fn(-1, 105, nil)
369 fn(-2, 0, nil)
370 fn(0, 0, nil)
371 d.Close()
373 // Test the bounded case
374 openDir()
375 fn(1, 1, nil)
376 fn(2, 2, nil)
377 fn(105, 102, nil) // and tests buffer >100 case
378 fn(3, 0, io.EOF)
379 d.Close()
383 func TestHardLink(t *testing.T) {
384 // Hardlinks are not supported under windows or Plan 9.
385 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
386 return
388 from, to := "hardlinktestfrom", "hardlinktestto"
389 Remove(from) // Just in case.
390 file, err := Create(to)
391 if err != nil {
392 t.Fatalf("open %q failed: %v", to, err)
394 defer Remove(to)
395 if err = file.Close(); err != nil {
396 t.Errorf("close %q failed: %v", to, err)
398 err = Link(to, from)
399 if err != nil {
400 t.Fatalf("link %q, %q failed: %v", to, from, err)
402 defer Remove(from)
403 tostat, err := Stat(to)
404 if err != nil {
405 t.Fatalf("stat %q failed: %v", to, err)
407 fromstat, err := Stat(from)
408 if err != nil {
409 t.Fatalf("stat %q failed: %v", from, err)
411 if !SameFile(tostat, fromstat) {
412 t.Errorf("link %q, %q did not create hard link", to, from)
416 func TestSymLink(t *testing.T) {
417 // Symlinks are not supported under windows or Plan 9.
418 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
419 return
421 from, to := "symlinktestfrom", "symlinktestto"
422 Remove(from) // Just in case.
423 file, err := Create(to)
424 if err != nil {
425 t.Fatalf("open %q failed: %v", to, err)
427 defer Remove(to)
428 if err = file.Close(); err != nil {
429 t.Errorf("close %q failed: %v", to, err)
431 err = Symlink(to, from)
432 if err != nil {
433 t.Fatalf("symlink %q, %q failed: %v", to, from, err)
435 defer Remove(from)
436 tostat, err := Lstat(to)
437 if err != nil {
438 t.Fatalf("stat %q failed: %v", to, err)
440 if tostat.Mode()&ModeSymlink != 0 {
441 t.Fatalf("stat %q claims to have found a symlink", to)
443 fromstat, err := Stat(from)
444 if err != nil {
445 t.Fatalf("stat %q failed: %v", from, err)
447 if !SameFile(tostat, fromstat) {
448 t.Errorf("symlink %q, %q did not create symlink", to, from)
450 fromstat, err = Lstat(from)
451 if err != nil {
452 t.Fatalf("lstat %q failed: %v", from, err)
454 if fromstat.Mode()&ModeSymlink == 0 {
455 t.Fatalf("symlink %q, %q did not create symlink", to, from)
457 fromstat, err = Stat(from)
458 if err != nil {
459 t.Fatalf("stat %q failed: %v", from, err)
461 if fromstat.Mode()&ModeSymlink != 0 {
462 t.Fatalf("stat %q did not follow symlink", from)
464 s, err := Readlink(from)
465 if err != nil {
466 t.Fatalf("readlink %q failed: %v", from, err)
468 if s != to {
469 t.Fatalf("after symlink %q != %q", s, to)
471 file, err = Open(from)
472 if err != nil {
473 t.Fatalf("open %q failed: %v", from, err)
475 file.Close()
478 func TestLongSymlink(t *testing.T) {
479 // Symlinks are not supported under windows or Plan 9.
480 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
481 return
483 s := "0123456789abcdef"
484 // Long, but not too long: a common limit is 255.
485 s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
486 from := "longsymlinktestfrom"
487 Remove(from) // Just in case.
488 err := Symlink(s, from)
489 if err != nil {
490 t.Fatalf("symlink %q, %q failed: %v", s, from, err)
492 defer Remove(from)
493 r, err := Readlink(from)
494 if err != nil {
495 t.Fatalf("readlink %q failed: %v", from, err)
497 if r != s {
498 t.Fatalf("after symlink %q != %q", r, s)
502 func TestRename(t *testing.T) {
503 from, to := "renamefrom", "renameto"
504 Remove(to) // Just in case.
505 file, err := Create(from)
506 if err != nil {
507 t.Fatalf("open %q failed: %v", to, err)
509 if err = file.Close(); err != nil {
510 t.Errorf("close %q failed: %v", to, err)
512 err = Rename(from, to)
513 if err != nil {
514 t.Fatalf("rename %q, %q failed: %v", to, from, err)
516 defer Remove(to)
517 _, err = Stat(to)
518 if err != nil {
519 t.Errorf("stat %q failed: %v", to, err)
523 func exec(t *testing.T, dir, cmd string, args []string, expect string) {
524 r, w, err := Pipe()
525 if err != nil {
526 t.Fatalf("Pipe: %v", err)
528 defer r.Close()
529 attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
530 p, err := StartProcess(cmd, args, attr)
531 if err != nil {
532 t.Fatalf("StartProcess: %v", err)
534 w.Close()
536 var b bytes.Buffer
537 io.Copy(&b, r)
538 output := b.String()
540 fi1, _ := Stat(strings.TrimSpace(output))
541 fi2, _ := Stat(expect)
542 if !SameFile(fi1, fi2) {
543 t.Errorf("exec %q returned %q wanted %q",
544 strings.Join(append([]string{cmd}, args...), " "), output, expect)
546 p.Wait()
549 func TestStartProcess(t *testing.T) {
550 var dir, cmd string
551 var args []string
552 if runtime.GOOS == "windows" {
553 cmd = Getenv("COMSPEC")
554 dir = Getenv("SystemRoot")
555 args = []string{"/c", "cd"}
556 } else {
557 cmd = "/bin/pwd"
558 dir = "/"
559 args = []string{}
561 cmddir, cmdbase := filepath.Split(cmd)
562 args = append([]string{cmdbase}, args...)
563 // Test absolute executable path.
564 exec(t, dir, cmd, args, dir)
565 // Test relative executable path.
566 exec(t, cmddir, cmdbase, args, cmddir)
569 func checkMode(t *testing.T, path string, mode FileMode) {
570 dir, err := Stat(path)
571 if err != nil {
572 t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
574 if dir.Mode()&0777 != mode {
575 t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
579 func TestChmod(t *testing.T) {
580 // Chmod is not supported under windows.
581 if runtime.GOOS == "windows" {
582 return
584 f := newFile("TestChmod", t)
585 defer Remove(f.Name())
586 defer f.Close()
588 if err := Chmod(f.Name(), 0456); err != nil {
589 t.Fatalf("chmod %s 0456: %s", f.Name(), err)
591 checkMode(t, f.Name(), 0456)
593 if err := f.Chmod(0123); err != nil {
594 t.Fatalf("chmod %s 0123: %s", f.Name(), err)
596 checkMode(t, f.Name(), 0123)
599 func checkSize(t *testing.T, f *File, size int64) {
600 dir, err := f.Stat()
601 if err != nil {
602 t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
604 if dir.Size() != size {
605 t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
609 func TestFTruncate(t *testing.T) {
610 f := newFile("TestFTruncate", t)
611 defer Remove(f.Name())
612 defer f.Close()
614 checkSize(t, f, 0)
615 f.Write([]byte("hello, world\n"))
616 checkSize(t, f, 13)
617 f.Truncate(10)
618 checkSize(t, f, 10)
619 f.Truncate(1024)
620 checkSize(t, f, 1024)
621 f.Truncate(0)
622 checkSize(t, f, 0)
623 f.Write([]byte("surprise!"))
624 checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
627 func TestTruncate(t *testing.T) {
628 f := newFile("TestTruncate", t)
629 defer Remove(f.Name())
630 defer f.Close()
632 checkSize(t, f, 0)
633 f.Write([]byte("hello, world\n"))
634 checkSize(t, f, 13)
635 Truncate(f.Name(), 10)
636 checkSize(t, f, 10)
637 Truncate(f.Name(), 1024)
638 checkSize(t, f, 1024)
639 Truncate(f.Name(), 0)
640 checkSize(t, f, 0)
641 f.Write([]byte("surprise!"))
642 checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
645 // Use TempDir() to make sure we're on a local file system,
646 // so that timings are not distorted by latency and caching.
647 // On NFS, timings can be off due to caching of meta-data on
648 // NFS servers (Issue 848).
649 func TestChtimes(t *testing.T) {
650 f := newFile("TestChtimes", t)
651 defer Remove(f.Name())
652 defer f.Close()
654 f.Write([]byte("hello, world\n"))
655 f.Close()
657 st, err := Stat(f.Name())
658 if err != nil {
659 t.Fatalf("Stat %s: %s", f.Name(), err)
661 preStat := st
663 // Move access and modification time back a second
664 at := Atime(preStat)
665 mt := preStat.ModTime()
666 err = Chtimes(f.Name(), at.Add(-time.Second), mt.Add(-time.Second))
667 if err != nil {
668 t.Fatalf("Chtimes %s: %s", f.Name(), err)
671 st, err = Stat(f.Name())
672 if err != nil {
673 t.Fatalf("second Stat %s: %s", f.Name(), err)
675 postStat := st
677 /* Plan 9:
678 Mtime is the time of the last change of content. Similarly, atime is set whenever the
679 contents are accessed; also, it is set whenever mtime is set.
681 pat := Atime(postStat)
682 pmt := postStat.ModTime()
683 if !pat.Before(at) && runtime.GOOS != "plan9" {
684 t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
687 if !pmt.Before(mt) {
688 t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
692 func TestChdirAndGetwd(t *testing.T) {
693 // TODO(brainman): file.Chdir() is not implemented on windows.
694 if runtime.GOOS == "windows" {
695 return
697 fd, err := Open(".")
698 if err != nil {
699 t.Fatalf("Open .: %s", err)
701 // These are chosen carefully not to be symlinks on a Mac
702 // (unlike, say, /var, /etc, and /tmp).
703 dirs := []string{"/", "/usr/bin"}
704 // /usr/bin does not usually exist on Plan 9.
705 if runtime.GOOS == "plan9" {
706 dirs = []string{"/", "/usr"}
708 for mode := 0; mode < 2; mode++ {
709 for _, d := range dirs {
710 if mode == 0 {
711 err = Chdir(d)
712 } else {
713 fd1, err := Open(d)
714 if err != nil {
715 t.Errorf("Open %s: %s", d, err)
716 continue
718 err = fd1.Chdir()
719 fd1.Close()
721 pwd, err1 := Getwd()
722 err2 := fd.Chdir()
723 if err2 != nil {
724 // We changed the current directory and cannot go back.
725 // Don't let the tests continue; they'll scribble
726 // all over some other directory.
727 fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
728 Exit(1)
730 if err != nil {
731 fd.Close()
732 t.Fatalf("Chdir %s: %s", d, err)
734 if err1 != nil {
735 fd.Close()
736 t.Fatalf("Getwd in %s: %s", d, err1)
738 if pwd != d {
739 fd.Close()
740 t.Fatalf("Getwd returned %q want %q", pwd, d)
744 fd.Close()
747 func TestSeek(t *testing.T) {
748 f := newFile("TestSeek", t)
749 defer Remove(f.Name())
750 defer f.Close()
752 const data = "hello, world\n"
753 io.WriteString(f, data)
755 type test struct {
756 in int64
757 whence int
758 out int64
760 var tests = []test{
761 {0, 1, int64(len(data))},
762 {0, 0, 0},
763 {5, 0, 5},
764 {0, 2, int64(len(data))},
765 {0, 0, 0},
766 {-1, 2, int64(len(data)) - 1},
767 {1 << 33, 0, 1 << 33},
768 {1 << 33, 2, 1<<33 + int64(len(data))},
770 for i, tt := range tests {
771 off, err := f.Seek(tt.in, tt.whence)
772 if off != tt.out || err != nil {
773 if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
774 // Reiserfs rejects the big seeks.
775 // http://code.google.com/p/go/issues/detail?id=91
776 break
778 t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
783 type openErrorTest struct {
784 path string
785 mode int
786 error error
789 var openErrorTests = []openErrorTest{
791 sfdir + "/no-such-file",
792 O_RDONLY,
793 syscall.ENOENT,
796 sfdir,
797 O_WRONLY,
798 syscall.EISDIR,
801 sfdir + "/" + sfname + "/no-such-file",
802 O_WRONLY,
803 syscall.ENOTDIR,
807 func TestOpenError(t *testing.T) {
808 for _, tt := range openErrorTests {
809 f, err := OpenFile(tt.path, tt.mode, 0)
810 if err == nil {
811 t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
812 f.Close()
813 continue
815 perr, ok := err.(*PathError)
816 if !ok {
817 t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
819 if perr.Err != tt.error {
820 if runtime.GOOS == "plan9" {
821 syscallErrStr := perr.Err.Error()
822 expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
823 if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
824 t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
826 continue
828 if runtime.GOOS == "dragonfly" {
829 // DragonFly incorrectly returns EACCES rather
830 // EISDIR when a directory is opened for write.
831 if tt.error == syscall.EISDIR && perr.Err == syscall.EACCES {
832 continue
835 t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
840 func TestOpenNoName(t *testing.T) {
841 f, err := Open("")
842 if err == nil {
843 t.Fatal(`Open("") succeeded`)
844 f.Close()
848 func run(t *testing.T, cmd []string) string {
849 // Run /bin/hostname and collect output.
850 r, w, err := Pipe()
851 if err != nil {
852 t.Fatal(err)
854 defer r.Close()
855 p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
856 if err != nil {
857 t.Fatal(err)
859 w.Close()
861 var b bytes.Buffer
862 io.Copy(&b, r)
863 _, err = p.Wait()
864 if err != nil {
865 t.Fatalf("run hostname Wait: %v", err)
867 err = p.Kill()
868 if err == nil {
869 t.Errorf("expected an error from Kill running 'hostname'")
871 output := b.String()
872 if n := len(output); n > 0 && output[n-1] == '\n' {
873 output = output[0 : n-1]
875 if output == "" {
876 t.Fatalf("%v produced no output", cmd)
879 return output
882 func TestHostname(t *testing.T) {
883 // There is no other way to fetch hostname on windows, but via winapi.
884 // On Plan 9 it is can be taken from #c/sysname as Hostname() does.
885 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
886 return
889 // Check internal Hostname() against the output of /bin/hostname.
890 // Allow that the internal Hostname returns a Fully Qualified Domain Name
891 // and the /bin/hostname only returns the first component
892 hostname, err := Hostname()
893 if err != nil {
894 t.Fatalf("%v", err)
896 want := run(t, []string{"/bin/hostname"})
897 if hostname != want {
898 i := strings.Index(hostname, ".")
899 if i < 0 || hostname[0:i] != want {
900 t.Errorf("Hostname() = %q, want %q", hostname, want)
905 func TestReadAt(t *testing.T) {
906 f := newFile("TestReadAt", t)
907 defer Remove(f.Name())
908 defer f.Close()
910 const data = "hello, world\n"
911 io.WriteString(f, data)
913 b := make([]byte, 5)
914 n, err := f.ReadAt(b, 7)
915 if err != nil || n != len(b) {
916 t.Fatalf("ReadAt 7: %d, %v", n, err)
918 if string(b) != "world" {
919 t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
923 func TestWriteAt(t *testing.T) {
924 f := newFile("TestWriteAt", t)
925 defer Remove(f.Name())
926 defer f.Close()
928 const data = "hello, world\n"
929 io.WriteString(f, data)
931 n, err := f.WriteAt([]byte("WORLD"), 7)
932 if err != nil || n != 5 {
933 t.Fatalf("WriteAt 7: %d, %v", n, err)
936 b, err := ioutil.ReadFile(f.Name())
937 if err != nil {
938 t.Fatalf("ReadFile %s: %v", f.Name(), err)
940 if string(b) != "hello, WORLD\n" {
941 t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
945 func writeFile(t *testing.T, fname string, flag int, text string) string {
946 f, err := OpenFile(fname, flag, 0666)
947 if err != nil {
948 t.Fatalf("Open: %v", err)
950 n, err := io.WriteString(f, text)
951 if err != nil {
952 t.Fatalf("WriteString: %d, %v", n, err)
954 f.Close()
955 data, err := ioutil.ReadFile(fname)
956 if err != nil {
957 t.Fatalf("ReadFile: %v", err)
959 return string(data)
962 func TestAppend(t *testing.T) {
963 const f = "append.txt"
964 defer Remove(f)
965 s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
966 if s != "new" {
967 t.Fatalf("writeFile: have %q want %q", s, "new")
969 s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
970 if s != "new|append" {
971 t.Fatalf("writeFile: have %q want %q", s, "new|append")
973 s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
974 if s != "new|append|append" {
975 t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
977 err := Remove(f)
978 if err != nil {
979 t.Fatalf("Remove: %v", err)
981 s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
982 if s != "new&append" {
983 t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
985 s = writeFile(t, f, O_CREATE|O_RDWR, "old")
986 if s != "old&append" {
987 t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
989 s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
990 if s != "new" {
991 t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
995 func TestStatDirWithTrailingSlash(t *testing.T) {
996 // Create new temporary directory and arrange to clean it up.
997 path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_")
998 if err != nil {
999 t.Fatalf("TempDir: %s", err)
1001 defer RemoveAll(path)
1003 // Stat of path should succeed.
1004 _, err = Stat(path)
1005 if err != nil {
1006 t.Fatalf("stat %s failed: %s", path, err)
1009 // Stat of path+"/" should succeed too.
1010 path += "/"
1011 _, err = Stat(path)
1012 if err != nil {
1013 t.Fatalf("stat %s failed: %s", path, err)
1017 func TestNilProcessStateString(t *testing.T) {
1018 var ps *ProcessState
1019 s := ps.String()
1020 if s != "<nil>" {
1021 t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
1025 func TestSameFile(t *testing.T) {
1026 fa, err := Create("a")
1027 if err != nil {
1028 t.Fatalf("Create(a): %v", err)
1030 defer Remove(fa.Name())
1031 fa.Close()
1032 fb, err := Create("b")
1033 if err != nil {
1034 t.Fatalf("Create(b): %v", err)
1036 defer Remove(fb.Name())
1037 fb.Close()
1039 ia1, err := Stat("a")
1040 if err != nil {
1041 t.Fatalf("Stat(a): %v", err)
1043 ia2, err := Stat("a")
1044 if err != nil {
1045 t.Fatalf("Stat(a): %v", err)
1047 if !SameFile(ia1, ia2) {
1048 t.Errorf("files should be same")
1051 ib, err := Stat("b")
1052 if err != nil {
1053 t.Fatalf("Stat(b): %v", err)
1055 if SameFile(ia1, ib) {
1056 t.Errorf("files should be different")
1060 func TestDevNullFile(t *testing.T) {
1061 f, err := Open(DevNull)
1062 if err != nil {
1063 t.Fatalf("Open(%s): %v", DevNull, err)
1065 defer f.Close()
1066 fi, err := f.Stat()
1067 if err != nil {
1068 t.Fatalf("Stat(%s): %v", DevNull, err)
1070 name := filepath.Base(DevNull)
1071 if fi.Name() != name {
1072 t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
1074 if fi.Size() != 0 {
1075 t.Fatalf("wrong file size have %d want 0", fi.Size())
1079 var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
1081 func TestLargeWriteToConsole(t *testing.T) {
1082 if !*testLargeWrite {
1083 t.Skip("skipping console-flooding test; enable with -large_write")
1085 b := make([]byte, 32000)
1086 for i := range b {
1087 b[i] = '.'
1089 b[len(b)-1] = '\n'
1090 n, err := Stdout.Write(b)
1091 if err != nil {
1092 t.Fatalf("Write to os.Stdout failed: %v", err)
1094 if n != len(b) {
1095 t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
1097 n, err = Stderr.Write(b)
1098 if err != nil {
1099 t.Fatalf("Write to os.Stderr failed: %v", err)
1101 if n != len(b) {
1102 t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
1106 func TestStatDirModeExec(t *testing.T) {
1107 const mode = 0111
1109 path, err := ioutil.TempDir("", "go-build")
1110 if err != nil {
1111 t.Fatalf("Failed to create temp directory: %v", err)
1113 defer RemoveAll(path)
1115 if err := Chmod(path, 0777); err != nil {
1116 t.Fatalf("Chmod %q 0777: %v", path, err)
1119 dir, err := Stat(path)
1120 if err != nil {
1121 t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
1123 if dir.Mode()&mode != mode {
1124 t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode()&mode, mode)
1128 func TestReadAtEOF(t *testing.T) {
1129 f := newFile("TestReadAtEOF", t)
1130 defer Remove(f.Name())
1131 defer f.Close()
1133 _, err := f.ReadAt(make([]byte, 10), 0)
1134 switch err {
1135 case io.EOF:
1136 // all good
1137 case nil:
1138 t.Fatalf("ReadAt succeeded")
1139 default:
1140 t.Fatalf("ReadAt failed: %s", err)
1144 func testKillProcess(t *testing.T, processKiller func(p *Process)) {
1145 t.Skip("gccgo does not have a go command")
1146 dir, err := ioutil.TempDir("", "go-build")
1147 if err != nil {
1148 t.Fatalf("Failed to create temp directory: %v", err)
1150 defer RemoveAll(dir)
1152 src := filepath.Join(dir, "main.go")
1153 f, err := Create(src)
1154 if err != nil {
1155 t.Fatalf("Failed to create %v: %v", src, err)
1157 st := template.Must(template.New("source").Parse(`
1158 package main
1159 import "time"
1160 func main() {
1161 time.Sleep(time.Second)
1164 err = st.Execute(f, nil)
1165 if err != nil {
1166 f.Close()
1167 t.Fatalf("Failed to execute template: %v", err)
1169 f.Close()
1171 exe := filepath.Join(dir, "main.exe")
1172 output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
1173 if err != nil {
1174 t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
1177 cmd := osexec.Command(exe)
1178 err = cmd.Start()
1179 if err != nil {
1180 t.Fatalf("Failed to start test process: %v", err)
1182 go func() {
1183 time.Sleep(100 * time.Millisecond)
1184 processKiller(cmd.Process)
1186 err = cmd.Wait()
1187 if err == nil {
1188 t.Errorf("Test process succeeded, but expected to fail")
1192 func TestKillStartProcess(t *testing.T) {
1193 testKillProcess(t, func(p *Process) {
1194 err := p.Kill()
1195 if err != nil {
1196 t.Fatalf("Failed to kill test process: %v", err)
1201 func TestKillFindProcess(t *testing.T) {
1202 testKillProcess(t, func(p *Process) {
1203 p2, err := FindProcess(p.Pid)
1204 if err != nil {
1205 t.Fatalf("Failed to find test process: %v", err)
1207 err = p2.Kill()
1208 if err != nil {
1209 t.Fatalf("Failed to kill test process: %v", err)