diff options
Diffstat (limited to 'src/pkg/os/os_test.go')
-rw-r--r-- | src/pkg/os/os_test.go | 156 |
1 files changed, 141 insertions, 15 deletions
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go index 9462ebd42..16d5984e9 100644 --- a/src/pkg/os/os_test.go +++ b/src/pkg/os/os_test.go @@ -6,6 +6,7 @@ package os_test import ( "bytes" + "errors" "flag" "fmt" "io" @@ -13,7 +14,9 @@ import ( . "os" osexec "os/exec" "path/filepath" + "reflect" "runtime" + "sort" "strings" "syscall" "testing" @@ -382,6 +385,84 @@ func TestReaddirNValues(t *testing.T) { } } +func touch(t *testing.T, name string) { + f, err := Create(name) + if err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } +} + +func TestReaddirStatFailures(t *testing.T) { + switch runtime.GOOS { + case "windows", "plan9": + // Windows and Plan 9 already do this correctly, + // but are structured with different syscalls such + // that they don't use Lstat, so the hook below for + // testing it wouldn't work. + t.Skipf("skipping test on %v", runtime.GOOS) + } + dir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatalf("TempDir: %v", err) + } + defer RemoveAll(dir) + touch(t, filepath.Join(dir, "good1")) + touch(t, filepath.Join(dir, "x")) // will disappear or have an error + touch(t, filepath.Join(dir, "good2")) + defer func() { + *LstatP = Lstat + }() + var xerr error // error to return for x + *LstatP = func(path string) (FileInfo, error) { + if xerr != nil && strings.HasSuffix(path, "x") { + return nil, xerr + } + return Lstat(path) + } + readDir := func() ([]FileInfo, error) { + d, err := Open(dir) + if err != nil { + t.Fatal(err) + } + defer d.Close() + return d.Readdir(-1) + } + mustReadDir := func(testName string) []FileInfo { + fis, err := readDir() + if err != nil { + t.Fatalf("%s: Readdir: %v", testName, err) + } + return fis + } + names := func(fis []FileInfo) []string { + s := make([]string, len(fis)) + for i, fi := range fis { + s[i] = fi.Name() + } + sort.Strings(s) + return s + } + + if got, want := names(mustReadDir("inital readdir")), + []string{"good1", "good2", "x"}; !reflect.DeepEqual(got, want) { + t.Errorf("initial readdir got %q; want %q", got, want) + } + + xerr = ErrNotExist + if got, want := names(mustReadDir("with x disappearing")), + []string{"good1", "good2"}; !reflect.DeepEqual(got, want) { + t.Errorf("with x disappearing, got %q; want %q", got, want) + } + + xerr = errors.New("some real error") + if _, err := readDir(); err != xerr { + t.Errorf("with a non-ErrNotExist error, got error %v; want %v", err, xerr) + } +} + func TestHardLink(t *testing.T) { // Hardlinks are not supported under windows or Plan 9. if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { @@ -415,10 +496,10 @@ func TestHardLink(t *testing.T) { } } -func TestSymLink(t *testing.T) { - // Symlinks are not supported under windows or Plan 9. - if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { - return +func TestSymlink(t *testing.T) { + switch runtime.GOOS { + case "windows", "plan9", "nacl": + t.Skipf("skipping on %s", runtime.GOOS) } from, to := "symlinktestfrom", "symlinktestto" Remove(from) // Just in case. @@ -478,9 +559,9 @@ func TestSymLink(t *testing.T) { } func TestLongSymlink(t *testing.T) { - // Symlinks are not supported under windows or Plan 9. - if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { - return + switch runtime.GOOS { + case "windows", "plan9", "nacl": + t.Skipf("skipping on %s", runtime.GOOS) } s := "0123456789abcdef" // Long, but not too long: a common limit is 255. @@ -549,6 +630,10 @@ func exec(t *testing.T, dir, cmd string, args []string, expect string) { } func TestStartProcess(t *testing.T) { + if runtime.GOOS == "nacl" { + t.Skip("skipping on nacl") + } + var dir, cmd string var args []string if runtime.GOOS == "windows" { @@ -622,8 +707,10 @@ func TestFTruncate(t *testing.T) { checkSize(t, f, 1024) f.Truncate(0) checkSize(t, f, 0) - f.Write([]byte("surprise!")) - checkSize(t, f, 13+9) // wrote at offset past where hello, world was. + _, err := f.Write([]byte("surprise!")) + if err == nil { + checkSize(t, f, 13+9) // wrote at offset past where hello, world was. + } } func TestTruncate(t *testing.T) { @@ -640,8 +727,10 @@ func TestTruncate(t *testing.T) { checkSize(t, f, 1024) Truncate(f.Name(), 0) checkSize(t, f, 0) - f.Write([]byte("surprise!")) - checkSize(t, f, 13+9) // wrote at offset past where hello, world was. + _, err := f.Write([]byte("surprise!")) + if err == nil { + checkSize(t, f, 13+9) // wrote at offset past where hello, world was. + } } // Use TempDir() to make sure we're on a local file system, @@ -676,13 +765,13 @@ func TestChtimes(t *testing.T) { } postStat := st - /* Plan 9: + /* Plan 9, NaCl: Mtime is the time of the last change of content. Similarly, atime is set whenever the contents are accessed; also, it is set whenever mtime is set. */ pat := Atime(postStat) pmt := postStat.ModTime() - if !pat.Before(at) && runtime.GOOS != "plan9" { + if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" { t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat) } @@ -884,8 +973,9 @@ func run(t *testing.T, cmd []string) string { func TestHostname(t *testing.T) { // There is no other way to fetch hostname on windows, but via winapi. // On Plan 9 it is can be taken from #c/sysname as Hostname() does. - if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { - return + switch runtime.GOOS { + case "windows", "plan9", "nacl": + t.Skipf("skipping on %s", runtime.GOOS) } // Check internal Hostname() against the output of /bin/hostname. @@ -1144,6 +1234,10 @@ func TestReadAtEOF(t *testing.T) { } func testKillProcess(t *testing.T, processKiller func(p *Process)) { + if runtime.GOOS == "nacl" { + t.Skip("skipping on nacl") + } + dir, err := ioutil.TempDir("", "go-build") if err != nil { t.Fatalf("Failed to create temp directory: %v", err) @@ -1211,3 +1305,35 @@ func TestKillFindProcess(t *testing.T) { } }) } + +var nilFileMethodTests = []struct { + name string + f func(*File) error +}{ + {"Chdir", func(f *File) error { return f.Chdir() }}, + {"Close", func(f *File) error { return f.Close() }}, + {"Chmod", func(f *File) error { return f.Chmod(0) }}, + {"Chown", func(f *File) error { return f.Chown(0, 0) }}, + {"Read", func(f *File) error { _, err := f.Read(make([]byte, 0)); return err }}, + {"ReadAt", func(f *File) error { _, err := f.ReadAt(make([]byte, 0), 0); return err }}, + {"Readdir", func(f *File) error { _, err := f.Readdir(1); return err }}, + {"Readdirnames", func(f *File) error { _, err := f.Readdirnames(1); return err }}, + {"Seek", func(f *File) error { _, err := f.Seek(0, 0); return err }}, + {"Stat", func(f *File) error { _, err := f.Stat(); return err }}, + {"Sync", func(f *File) error { return f.Sync() }}, + {"Truncate", func(f *File) error { return f.Truncate(0) }}, + {"Write", func(f *File) error { _, err := f.Write(make([]byte, 0)); return err }}, + {"WriteAt", func(f *File) error { _, err := f.WriteAt(make([]byte, 0), 0); return err }}, + {"WriteString", func(f *File) error { _, err := f.WriteString(""); return err }}, +} + +// Test that all File methods give ErrInvalid if the receiver is nil. +func TestNilFileMethods(t *testing.T) { + for _, tt := range nilFileMethodTests { + var file *File + got := tt.f(file) + if got != ErrInvalid { + t.Errorf("%v should fail when f is nil; got %v", tt.name, got) + } + } +} |