Commit b6850fe7 authored by Peter Mundy's avatar Peter Mundy Committed by Andrew Gerrand

os: Use TempFile with default TempDir for temp test files

Use io/ioutil.TempFile with default os.TempDir for temporary test files.
For os_test.go temporary test files, use a local file system and OS
independent directory names. Avoid problems with NFS.

Fixes #848.

R=adg
CC=golang-dev
https://golang.org/cl/1806043
parent 48e4d67b
...@@ -54,6 +54,15 @@ func size(name string, t *testing.T) int64 { ...@@ -54,6 +54,15 @@ func size(name string, t *testing.T) int64 {
return int64(len) return int64(len)
} }
func newFile(testName string, t *testing.T) (f *File) {
// Use a local file system, not NFS.
f, err := ioutil.TempFile("", "_Go_"+testName)
if err != nil {
t.Fatalf("open %s: %s", testName, err)
}
return
}
func TestStat(t *testing.T) { func TestStat(t *testing.T) {
dir, err := Stat("/etc/passwd") dir, err := Stat("/etc/passwd")
if err != nil { if err != nil {
...@@ -369,25 +378,19 @@ func checkMode(t *testing.T, path string, mode uint32) { ...@@ -369,25 +378,19 @@ func checkMode(t *testing.T, path string, mode uint32) {
} }
func TestChmod(t *testing.T) { func TestChmod(t *testing.T) {
MkdirAll("_obj", 0777) f := newFile("TestChmod", t)
const Path = "_obj/_TestChmod_" defer Remove(f.Name())
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666) defer f.Close()
if err != nil {
t.Fatalf("create %s: %s", Path, err)
}
if err = Chmod(Path, 0456); err != nil { if err := Chmod(f.Name(), 0456); err != nil {
t.Fatalf("chmod %s 0456: %s", Path, err) t.Fatalf("chmod %s 0456: %s", f.Name(), err)
} }
checkMode(t, Path, 0456) checkMode(t, f.Name(), 0456)
if err = fd.Chmod(0123); err != nil { if err := f.Chmod(0123); err != nil {
t.Fatalf("fchmod %s 0123: %s", Path, err) t.Fatalf("chmod %s 0123: %s", f.Name(), err)
} }
checkMode(t, Path, 0123) checkMode(t, f.Name(), 0123)
fd.Close()
Remove(Path)
} }
func checkUidGid(t *testing.T, path string, uid, gid int) { func checkUidGid(t *testing.T, path string, uid, gid int) {
...@@ -404,31 +407,26 @@ func checkUidGid(t *testing.T, path string, uid, gid int) { ...@@ -404,31 +407,26 @@ func checkUidGid(t *testing.T, path string, uid, gid int) {
} }
func TestChown(t *testing.T) { func TestChown(t *testing.T) {
// Use /tmp, not _obj, to make sure we're on a local file system, // Use TempDir() to make sure we're on a local file system,
// so that the group ids returned by Getgroups will be allowed // so that the group ids returned by Getgroups will be allowed
// on the file. If _obj is on NFS, the Getgroups groups are // on the file. On NFS, the Getgroups groups are
// basically useless. // basically useless.
f := newFile("TestChown", t)
const Path = "/tmp/_TestChown_" defer Remove(f.Name())
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666) defer f.Close()
if err != nil { dir, err := f.Stat()
t.Fatalf("create %s: %s", Path, err)
}
dir, err := fd.Stat()
if err != nil { if err != nil {
t.Fatalf("fstat %s: %s", Path, err) t.Fatalf("stat %s: %s", f.Name(), err)
} }
defer fd.Close()
defer Remove(Path)
// Can't change uid unless root, but can try // Can't change uid unless root, but can try
// changing the group id. First try our current group. // changing the group id. First try our current group.
gid := Getgid() gid := Getgid()
t.Log("gid:", gid) t.Log("gid:", gid)
if err = Chown(Path, -1, gid); err != nil { if err = Chown(f.Name(), -1, gid); err != nil {
t.Fatalf("chown %s -1 %d: %s", Path, gid, err) t.Fatalf("chown %s -1 %d: %s", f.Name(), gid, err)
} }
checkUidGid(t, Path, dir.Uid, gid) checkUidGid(t, f.Name(), dir.Uid, gid)
// Then try all the auxiliary groups. // Then try all the auxiliary groups.
groups, err := Getgroups() groups, err := Getgroups()
...@@ -437,16 +435,16 @@ func TestChown(t *testing.T) { ...@@ -437,16 +435,16 @@ func TestChown(t *testing.T) {
} }
t.Log("groups: ", groups) t.Log("groups: ", groups)
for _, g := range groups { for _, g := range groups {
if err = Chown(Path, -1, g); err != nil { if err = Chown(f.Name(), -1, g); err != nil {
t.Fatalf("chown %s -1 %d: %s", Path, g, err) t.Fatalf("chown %s -1 %d: %s", f.Name(), g, err)
} }
checkUidGid(t, Path, dir.Uid, g) checkUidGid(t, f.Name(), dir.Uid, g)
// change back to gid to test fd.Chown // change back to gid to test fd.Chown
if err = fd.Chown(-1, gid); err != nil { if err = f.Chown(-1, gid); err != nil {
t.Fatalf("fchown %s -1 %d: %s", Path, gid, err) t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err)
} }
checkUidGid(t, Path, dir.Uid, gid) checkUidGid(t, f.Name(), dir.Uid, gid)
} }
} }
...@@ -461,53 +459,50 @@ func checkSize(t *testing.T, path string, size int64) { ...@@ -461,53 +459,50 @@ func checkSize(t *testing.T, path string, size int64) {
} }
func TestTruncate(t *testing.T) { func TestTruncate(t *testing.T) {
MkdirAll("_obj", 0777) f := newFile("TestTruncate", t)
const Path = "_obj/_TestTruncate_" defer Remove(f.Name())
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666) defer f.Close()
if err != nil {
t.Fatalf("create %s: %s", Path, err) checkSize(t, f.Name(), 0)
} f.Write([]byte("hello, world\n"))
checkSize(t, f.Name(), 13)
checkSize(t, Path, 0) f.Truncate(10)
fd.Write([]byte("hello, world\n")) checkSize(t, f.Name(), 10)
checkSize(t, Path, 13) f.Truncate(1024)
fd.Truncate(10) checkSize(t, f.Name(), 1024)
checkSize(t, Path, 10) f.Truncate(0)
fd.Truncate(1024) checkSize(t, f.Name(), 0)
checkSize(t, Path, 1024) f.Write([]byte("surprise!"))
fd.Truncate(0) checkSize(t, f.Name(), 13+9) // wrote at offset past where hello, world was.
checkSize(t, Path, 0) }
fd.Write([]byte("surprise!"))
checkSize(t, Path, 13+9) // wrote at offset past where hello, world was. // Use TempDir() to make sure we're on a local file system,
fd.Close() // so that timings are not distorted by latency and caching.
Remove(Path) // On NFS, timings can be off due to caching of meta-data on
} // NFS servers (Issue 848).
func TestChtimes(t *testing.T) { func TestChtimes(t *testing.T) {
MkdirAll("_obj", 0777) f := newFile("TestChtimes", t)
const Path = "_obj/_TestChtimes_" defer Remove(f.Name())
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666) defer f.Close()
if err != nil {
t.Fatalf("create %s: %s", Path, err) f.Write([]byte("hello, world\n"))
} f.Close()
fd.Write([]byte("hello, world\n"))
fd.Close()
preStat, err := Stat(Path) preStat, err := Stat(f.Name())
if err != nil { if err != nil {
t.Fatalf("Stat %s: %s", Path, err) t.Fatalf("Stat %s: %s", f.Name(), err)
} }
// Move access and modification time back a second // Move access and modification time back a second
const OneSecond = 1e9 // in nanoseconds const OneSecond = 1e9 // in nanoseconds
err = Chtimes(Path, preStat.Atime_ns-OneSecond, preStat.Mtime_ns-OneSecond) err = Chtimes(f.Name(), preStat.Atime_ns-OneSecond, preStat.Mtime_ns-OneSecond)
if err != nil { if err != nil {
t.Fatalf("Chtimes %s: %s", Path, err) t.Fatalf("Chtimes %s: %s", f.Name(), err)
} }
postStat, err := Stat(Path) postStat, err := Stat(f.Name())
if err != nil { if err != nil {
t.Fatalf("second Stat %s: %s", Path, err) t.Fatalf("second Stat %s: %s", f.Name(), err)
} }
if postStat.Atime_ns >= preStat.Atime_ns { if postStat.Atime_ns >= preStat.Atime_ns {
...@@ -521,8 +516,6 @@ func TestChtimes(t *testing.T) { ...@@ -521,8 +516,6 @@ func TestChtimes(t *testing.T) {
preStat.Mtime_ns, preStat.Mtime_ns,
postStat.Mtime_ns) postStat.Mtime_ns)
} }
Remove(Path)
} }
func TestChdirAndGetwd(t *testing.T) { func TestChdirAndGetwd(t *testing.T) {
...@@ -586,10 +579,9 @@ func TestTime(t *testing.T) { ...@@ -586,10 +579,9 @@ func TestTime(t *testing.T) {
} }
func TestSeek(t *testing.T) { func TestSeek(t *testing.T) {
f, err := Open("_obj/seektest", O_CREAT|O_RDWR|O_TRUNC, 0666) f := newFile("TestSeek", t)
if err != nil { defer Remove(f.Name())
t.Fatalf("open _obj/seektest: %s", err) defer f.Close()
}
const data = "hello, world\n" const data = "hello, world\n"
io.WriteString(f, data) io.WriteString(f, data)
...@@ -620,7 +612,6 @@ func TestSeek(t *testing.T) { ...@@ -620,7 +612,6 @@ func TestSeek(t *testing.T) {
t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out) t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
} }
} }
f.Close()
} }
type openErrorTest struct { type openErrorTest struct {
...@@ -706,10 +697,10 @@ func TestHostname(t *testing.T) { ...@@ -706,10 +697,10 @@ func TestHostname(t *testing.T) {
} }
func TestReadAt(t *testing.T) { func TestReadAt(t *testing.T) {
f, err := Open("_obj/readtest", O_CREAT|O_RDWR|O_TRUNC, 0666) f := newFile("TestReadAt", t)
if err != nil { defer Remove(f.Name())
t.Fatalf("open _obj/readtest: %s", err) defer f.Close()
}
const data = "hello, world\n" const data = "hello, world\n"
io.WriteString(f, data) io.WriteString(f, data)
...@@ -724,10 +715,10 @@ func TestReadAt(t *testing.T) { ...@@ -724,10 +715,10 @@ func TestReadAt(t *testing.T) {
} }
func TestWriteAt(t *testing.T) { func TestWriteAt(t *testing.T) {
f, err := Open("_obj/writetest", O_CREAT|O_RDWR|O_TRUNC, 0666) f := newFile("TestWriteAt", t)
if err != nil { defer Remove(f.Name())
t.Fatalf("open _obj/writetest: %s", err) defer f.Close()
}
const data = "hello, world\n" const data = "hello, world\n"
io.WriteString(f, data) io.WriteString(f, data)
...@@ -736,9 +727,9 @@ func TestWriteAt(t *testing.T) { ...@@ -736,9 +727,9 @@ func TestWriteAt(t *testing.T) {
t.Fatalf("WriteAt 7: %d, %v", n, err) t.Fatalf("WriteAt 7: %d, %v", n, err)
} }
b, err := ioutil.ReadFile("_obj/writetest") b, err := ioutil.ReadFile(f.Name())
if err != nil { if err != nil {
t.Fatalf("ReadFile _obj/writetest: %v", err) t.Fatalf("ReadFile %s: %v", f.Name(), err)
} }
if string(b) != "hello, WORLD\n" { if string(b) != "hello, WORLD\n" {
t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n") t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment