OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [os/] [os_test.go] - Rev 867

Go to most recent revision | Compare with Previous | Blame | View Log

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os_test

import (
        "bytes"
        "fmt"
        "io"
        "io/ioutil"
        . "os"
        "path/filepath"
        "runtime"
        "strings"
        "testing"
        "time"
)

var dot = []string{
        "dir_unix.go",
        "env.go",
        "error.go",
        "file.go",
        "os_test.go",
        "time.go",
        "types.go",
}

type sysDir struct {
        name  string
        files []string
}

var sysdir = func() (sd *sysDir) {
        switch runtime.GOOS {
        case "windows":
                sd = &sysDir{
                        Getenv("SystemRoot") + "\\system32\\drivers\\etc",
                        []string{
                                "hosts",
                                "networks",
                                "protocol",
                                "services",
                        },
                }
        case "plan9":
                sd = &sysDir{
                        "/lib/ndb",
                        []string{
                                "common",
                                "local",
                        },
                }
        default:
                sd = &sysDir{
                        "/etc",
                        []string{
                                "group",
                                "hosts",
                                "passwd",
                        },
                }
        }
        return
}()

func size(name string, t *testing.T) int64 {
        file, err := Open(name)
        defer file.Close()
        if err != nil {
                t.Fatal("open failed:", err)
        }
        var buf [100]byte
        len := 0
        for {
                n, e := file.Read(buf[0:])
                len += n
                if e == io.EOF {
                        break
                }
                if e != nil {
                        t.Fatal("read failed:", err)
                }
        }
        return int64(len)
}

func equal(name1, name2 string) (r bool) {
        switch runtime.GOOS {
        case "windows":
                r = strings.ToLower(name1) == strings.ToLower(name2)
        default:
                r = name1 == name2
        }
        return
}

func newFile(testName string, t *testing.T) (f *File) {
        // Use a local file system, not NFS.
        // On Unix, override $TMPDIR in case the user
        // has it set to an NFS-mounted directory.
        dir := ""
        if runtime.GOOS != "windows" {
                dir = "/tmp"
        }
        f, err := ioutil.TempFile(dir, "_Go_"+testName)
        if err != nil {
                t.Fatalf("open %s: %s", testName, err)
        }
        return
}

var sfdir = sysdir.name
var sfname = sysdir.files[0]

func TestStat(t *testing.T) {
        path := sfdir + "/" + sfname
        dir, err := Stat(path)
        if err != nil {
                t.Fatal("stat failed:", err)
        }
        if !equal(sfname, dir.Name()) {
                t.Error("name should be ", sfname, "; is", dir.Name())
        }
        filesize := size(path, t)
        if dir.Size() != filesize {
                t.Error("size should be", filesize, "; is", dir.Size())
        }
}

func TestFstat(t *testing.T) {
        path := sfdir + "/" + sfname
        file, err1 := Open(path)
        defer file.Close()
        if err1 != nil {
                t.Fatal("open failed:", err1)
        }
        dir, err2 := file.Stat()
        if err2 != nil {
                t.Fatal("fstat failed:", err2)
        }
        if !equal(sfname, dir.Name()) {
                t.Error("name should be ", sfname, "; is", dir.Name())
        }
        filesize := size(path, t)
        if dir.Size() != filesize {
                t.Error("size should be", filesize, "; is", dir.Size())
        }
}

func TestLstat(t *testing.T) {
        path := sfdir + "/" + sfname
        dir, err := Lstat(path)
        if err != nil {
                t.Fatal("lstat failed:", err)
        }
        if !equal(sfname, dir.Name()) {
                t.Error("name should be ", sfname, "; is", dir.Name())
        }
        filesize := size(path, t)
        if dir.Size() != filesize {
                t.Error("size should be", filesize, "; is", dir.Size())
        }
}

// Read with length 0 should not return EOF.
func TestRead0(t *testing.T) {
        path := sfdir + "/" + sfname
        f, err := Open(path)
        if err != nil {
                t.Fatal("open failed:", err)
        }
        defer f.Close()

        b := make([]byte, 0)
        n, err := f.Read(b)
        if n != 0 || err != nil {
                t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
        }
        b = make([]byte, 100)
        n, err = f.Read(b)
        if n <= 0 || err != nil {
                t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
        }
}

func testReaddirnames(dir string, contents []string, t *testing.T) {
        file, err := Open(dir)
        defer file.Close()
        if err != nil {
                t.Fatalf("open %q failed: %v", dir, err)
        }
        s, err2 := file.Readdirnames(-1)
        if err2 != nil {
                t.Fatalf("readdirnames %q failed: %v", dir, err2)
        }
        for _, m := range contents {
                found := false
                for _, n := range s {
                        if n == "." || n == ".." {
                                t.Errorf("got %s in directory", n)
                        }
                        if equal(m, n) {
                                if found {
                                        t.Error("present twice:", m)
                                }
                                found = true
                        }
                }
                if !found {
                        t.Error("could not find", m)
                }
        }
}

func testReaddir(dir string, contents []string, t *testing.T) {
        file, err := Open(dir)
        defer file.Close()
        if err != nil {
                t.Fatalf("open %q failed: %v", dir, err)
        }
        s, err2 := file.Readdir(-1)
        if err2 != nil {
                t.Fatalf("readdir %q failed: %v", dir, err2)
        }
        for _, m := range contents {
                found := false
                for _, n := range s {
                        if equal(m, n.Name()) {
                                if found {
                                        t.Error("present twice:", m)
                                }
                                found = true
                        }
                }
                if !found {
                        t.Error("could not find", m)
                }
        }
}

func TestReaddirnames(t *testing.T) {
        testReaddirnames(".", dot, t)
        testReaddirnames(sysdir.name, sysdir.files, t)
}

func TestReaddir(t *testing.T) {
        testReaddir(".", dot, t)
        testReaddir(sysdir.name, sysdir.files, t)
}

// Read the directory one entry at a time.
func smallReaddirnames(file *File, length int, t *testing.T) []string {
        names := make([]string, length)
        count := 0
        for {
                d, err := file.Readdirnames(1)
                if err == io.EOF {
                        break
                }
                if err != nil {
                        t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
                }
                if len(d) == 0 {
                        t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
                }
                names[count] = d[0]
                count++
        }
        return names[0:count]
}

// Check that reading a directory one entry at a time gives the same result
// as reading it all at once.
func TestReaddirnamesOneAtATime(t *testing.T) {
        // big directory that doesn't change often.
        dir := "/usr/bin"
        switch runtime.GOOS {
        case "windows":
                dir = Getenv("SystemRoot") + "\\system32"
        case "plan9":
                dir = "/bin"
        }
        file, err := Open(dir)
        defer file.Close()
        if err != nil {
                t.Fatalf("open %q failed: %v", dir, err)
        }
        all, err1 := file.Readdirnames(-1)
        if err1 != nil {
                t.Fatalf("readdirnames %q failed: %v", dir, err1)
        }
        file1, err2 := Open(dir)
        if err2 != nil {
                t.Fatalf("open %q failed: %v", dir, err2)
        }
        small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
        if len(small) < len(all) {
                t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
        }
        for i, n := range all {
                if small[i] != n {
                        t.Errorf("small read %q mismatch: %v", small[i], n)
                }
        }
}

func TestReaddirNValues(t *testing.T) {
        if testing.Short() {
                t.Logf("test.short; skipping")
                return
        }
        dir, err := ioutil.TempDir("", "")
        if err != nil {
                t.Fatalf("TempDir: %v", err)
        }
        defer RemoveAll(dir)
        for i := 1; i <= 105; i++ {
                f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
                if err != nil {
                        t.Fatalf("Create: %v", err)
                }
                f.Write([]byte(strings.Repeat("X", i)))
                f.Close()
        }

        var d *File
        openDir := func() {
                var err error
                d, err = Open(dir)
                if err != nil {
                        t.Fatalf("Open directory: %v", err)
                }
        }

        readDirExpect := func(n, want int, wantErr error) {
                fi, err := d.Readdir(n)
                if err != wantErr {
                        t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
                }
                if g, e := len(fi), want; g != e {
                        t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
                }
        }

        readDirNamesExpect := func(n, want int, wantErr error) {
                fi, err := d.Readdirnames(n)
                if err != wantErr {
                        t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
                }
                if g, e := len(fi), want; g != e {
                        t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
                }
        }

        for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
                // Test the slurp case
                openDir()
                fn(0, 105, nil)
                fn(0, 0, nil)
                d.Close()

                // Slurp with -1 instead
                openDir()
                fn(-1, 105, nil)
                fn(-2, 0, nil)
                fn(0, 0, nil)
                d.Close()

                // Test the bounded case
                openDir()
                fn(1, 1, nil)
                fn(2, 2, nil)
                fn(105, 102, nil) // and tests buffer >100 case
                fn(3, 0, io.EOF)
                d.Close()
        }
}

func TestHardLink(t *testing.T) {
        // Hardlinks are not supported under windows or Plan 9.
        if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
                return
        }
        from, to := "hardlinktestfrom", "hardlinktestto"
        Remove(from) // Just in case.
        file, err := Create(to)
        if err != nil {
                t.Fatalf("open %q failed: %v", to, err)
        }
        defer Remove(to)
        if err = file.Close(); err != nil {
                t.Errorf("close %q failed: %v", to, err)
        }
        err = Link(to, from)
        if err != nil {
                t.Fatalf("link %q, %q failed: %v", to, from, err)
        }
        defer Remove(from)
        tostat, err := Stat(to)
        if err != nil {
                t.Fatalf("stat %q failed: %v", to, err)
        }
        fromstat, err := Stat(from)
        if err != nil {
                t.Fatalf("stat %q failed: %v", from, err)
        }
        if !SameFile(tostat, fromstat) {
                t.Errorf("link %q, %q did not create hard link", to, from)
        }
}

func TestSymLink(t *testing.T) {
        // Symlinks are not supported under windows or Plan 9.
        if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
                return
        }
        from, to := "symlinktestfrom", "symlinktestto"
        Remove(from) // Just in case.
        file, err := Create(to)
        if err != nil {
                t.Fatalf("open %q failed: %v", to, err)
        }
        defer Remove(to)
        if err = file.Close(); err != nil {
                t.Errorf("close %q failed: %v", to, err)
        }
        err = Symlink(to, from)
        if err != nil {
                t.Fatalf("symlink %q, %q failed: %v", to, from, err)
        }
        defer Remove(from)
        tostat, err := Lstat(to)
        if err != nil {
                t.Fatalf("stat %q failed: %v", to, err)
        }
        if tostat.Mode()&ModeSymlink != 0 {
                t.Fatalf("stat %q claims to have found a symlink", to)
        }
        fromstat, err := Stat(from)
        if err != nil {
                t.Fatalf("stat %q failed: %v", from, err)
        }
        if !SameFile(tostat, fromstat) {
                t.Errorf("symlink %q, %q did not create symlink", to, from)
        }
        fromstat, err = Lstat(from)
        if err != nil {
                t.Fatalf("lstat %q failed: %v", from, err)
        }
        if fromstat.Mode()&ModeSymlink == 0 {
                t.Fatalf("symlink %q, %q did not create symlink", to, from)
        }
        fromstat, err = Stat(from)
        if err != nil {
                t.Fatalf("stat %q failed: %v", from, err)
        }
        if fromstat.Mode()&ModeSymlink != 0 {
                t.Fatalf("stat %q did not follow symlink", from)
        }
        s, err := Readlink(from)
        if err != nil {
                t.Fatalf("readlink %q failed: %v", from, err)
        }
        if s != to {
                t.Fatalf("after symlink %q != %q", s, to)
        }
        file, err = Open(from)
        if err != nil {
                t.Fatalf("open %q failed: %v", from, err)
        }
        file.Close()
}

func TestLongSymlink(t *testing.T) {
        // Symlinks are not supported under windows or Plan 9.
        if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
                return
        }
        s := "0123456789abcdef"
        // Long, but not too long: a common limit is 255.
        s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
        from := "longsymlinktestfrom"
        Remove(from) // Just in case.
        err := Symlink(s, from)
        if err != nil {
                t.Fatalf("symlink %q, %q failed: %v", s, from, err)
        }
        defer Remove(from)
        r, err := Readlink(from)
        if err != nil {
                t.Fatalf("readlink %q failed: %v", from, err)
        }
        if r != s {
                t.Fatalf("after symlink %q != %q", r, s)
        }
}

func TestRename(t *testing.T) {
        from, to := "renamefrom", "renameto"
        Remove(to) // Just in case.
        file, err := Create(from)
        if err != nil {
                t.Fatalf("open %q failed: %v", to, err)
        }
        if err = file.Close(); err != nil {
                t.Errorf("close %q failed: %v", to, err)
        }
        err = Rename(from, to)
        if err != nil {
                t.Fatalf("rename %q, %q failed: %v", to, from, err)
        }
        defer Remove(to)
        _, err = Stat(to)
        if err != nil {
                t.Errorf("stat %q failed: %v", to, err)
        }
}

func exec(t *testing.T, dir, cmd string, args []string, expect string) {
        r, w, err := Pipe()
        if err != nil {
                t.Fatalf("Pipe: %v", err)
        }
        attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
        p, err := StartProcess(cmd, args, attr)
        if err != nil {
                t.Fatalf("StartProcess: %v", err)
        }
        defer p.Release()
        w.Close()

        var b bytes.Buffer
        io.Copy(&b, r)
        output := b.String()
        // Accept /usr prefix because Solaris /bin is symlinked to /usr/bin.
        if output != expect && output != "/usr"+expect {
                t.Errorf("exec %q returned %q wanted %q",
                        strings.Join(append([]string{cmd}, args...), " "), output, expect)
        }
        p.Wait(0)
}

func TestStartProcess(t *testing.T) {
        var dir, cmd, le string
        var args []string
        if runtime.GOOS == "windows" {
                le = "\r\n"
                cmd = Getenv("COMSPEC")
                dir = Getenv("SystemRoot")
                args = []string{"/c", "cd"}
        } else {
                le = "\n"
                cmd = "/bin/pwd"
                dir = "/"
                args = []string{}
        }
        cmddir, cmdbase := filepath.Split(cmd)
        args = append([]string{cmdbase}, args...)
        // Test absolute executable path.
        exec(t, dir, cmd, args, dir+le)
        // Test relative executable path.
        exec(t, cmddir, cmdbase, args, filepath.Clean(cmddir)+le)
}

func checkMode(t *testing.T, path string, mode FileMode) {
        dir, err := Stat(path)
        if err != nil {
                t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
        }
        if dir.Mode()&0777 != mode {
                t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
        }
}

func TestChmod(t *testing.T) {
        // Chmod is not supported under windows.
        if runtime.GOOS == "windows" {
                return
        }
        f := newFile("TestChmod", t)
        defer Remove(f.Name())
        defer f.Close()

        if err := Chmod(f.Name(), 0456); err != nil {
                t.Fatalf("chmod %s 0456: %s", f.Name(), err)
        }
        checkMode(t, f.Name(), 0456)

        if err := f.Chmod(0123); err != nil {
                t.Fatalf("chmod %s 0123: %s", f.Name(), err)
        }
        checkMode(t, f.Name(), 0123)
}

func checkSize(t *testing.T, f *File, size int64) {
        dir, err := f.Stat()
        if err != nil {
                t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
        }
        if dir.Size() != size {
                t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
        }
}

func TestFTruncate(t *testing.T) {
        f := newFile("TestFTruncate", t)
        defer Remove(f.Name())
        defer f.Close()

        checkSize(t, f, 0)
        f.Write([]byte("hello, world\n"))
        checkSize(t, f, 13)
        f.Truncate(10)
        checkSize(t, f, 10)
        f.Truncate(1024)
        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.
}

func TestTruncate(t *testing.T) {
        f := newFile("TestTruncate", t)
        defer Remove(f.Name())
        defer f.Close()

        checkSize(t, f, 0)
        f.Write([]byte("hello, world\n"))
        checkSize(t, f, 13)
        Truncate(f.Name(), 10)
        checkSize(t, f, 10)
        Truncate(f.Name(), 1024)
        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.
}

// Use TempDir() to make sure we're on a local file system,
// so that timings are not distorted by latency and caching.
// On NFS, timings can be off due to caching of meta-data on
// NFS servers (Issue 848).
func TestChtimes(t *testing.T) {
        f := newFile("TestChtimes", t)
        defer Remove(f.Name())
        defer f.Close()

        f.Write([]byte("hello, world\n"))
        f.Close()

        st, err := Stat(f.Name())
        if err != nil {
                t.Fatalf("Stat %s: %s", f.Name(), err)
        }
        preStat := st

        // Move access and modification time back a second
        at := Atime(preStat)
        mt := preStat.ModTime()
        err = Chtimes(f.Name(), at.Add(-time.Second), mt.Add(-time.Second))
        if err != nil {
                t.Fatalf("Chtimes %s: %s", f.Name(), err)
        }

        st, err = Stat(f.Name())
        if err != nil {
                t.Fatalf("second Stat %s: %s", f.Name(), err)
        }
        postStat := st

        /* Plan 9:
                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" {
                t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
        }

        if !pmt.Before(mt) {
                t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
        }
}

func TestChdirAndGetwd(t *testing.T) {
        // TODO(brainman): file.Chdir() is not implemented on windows.
        if runtime.GOOS == "windows" {
                return
        }
        fd, err := Open(".")
        if err != nil {
                t.Fatalf("Open .: %s", err)
        }
        // These are chosen carefully not to be symlinks on a Mac
        // (unlike, say, /var, /etc, and /tmp).
        dirs := []string{"/", "/usr/bin"}
        // /usr/bin does not usually exist on Plan 9.
        if runtime.GOOS == "plan9" {
                dirs = []string{"/", "/usr"}
        }
        for mode := 0; mode < 2; mode++ {
                for _, d := range dirs {
                        if mode == 0 {
                                err = Chdir(d)
                        } else {
                                fd1, err := Open(d)
                                if err != nil {
                                        t.Errorf("Open %s: %s", d, err)
                                        continue
                                }
                                err = fd1.Chdir()
                                fd1.Close()
                        }
                        pwd, err1 := Getwd()
                        err2 := fd.Chdir()
                        if err2 != nil {
                                // We changed the current directory and cannot go back.
                                // Don't let the tests continue; they'll scribble
                                // all over some other directory.
                                fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
                                Exit(1)
                        }
                        if err != nil {
                                fd.Close()
                                t.Fatalf("Chdir %s: %s", d, err)
                        }
                        if err1 != nil {
                                fd.Close()
                                t.Fatalf("Getwd in %s: %s", d, err1)
                        }
                        if pwd != d {
                                fd.Close()
                                t.Fatalf("Getwd returned %q want %q", pwd, d)
                        }
                }
        }
        fd.Close()
}

func TestTime(t *testing.T) {
        // Just want to check that Time() is getting something.
        // A common failure mode on Darwin is to get 0, 0,
        // because it returns the time in registers instead of
        // filling in the structure passed to the system call.
        // Too bad the compiler doesn't know that
        // 365.24*86400 is an integer.
        sec, nsec, err := Time()
        if sec < (2009-1970)*36524*864 {
                t.Errorf("Time() = %d, %d, %s; not plausible", sec, nsec, err)
        }
}

func TestSeek(t *testing.T) {
        f := newFile("TestSeek", t)
        defer Remove(f.Name())
        defer f.Close()

        const data = "hello, world\n"
        io.WriteString(f, data)

        type test struct {
                in     int64
                whence int
                out    int64
        }
        var tests = []test{
                {0, 1, int64(len(data))},
                {0, 0, 0},
                {5, 0, 5},
                {0, 2, int64(len(data))},
                {0, 0, 0},
                {-1, 2, int64(len(data)) - 1},
                {1 << 33, 0, 1 << 33},
                {1 << 33, 2, 1<<33 + int64(len(data))},
        }
        for i, tt := range tests {
                off, err := f.Seek(tt.in, tt.whence)
                if off != tt.out || err != nil {
                        if e, ok := err.(*PathError); ok && e.Err == EINVAL && tt.out > 1<<32 {
                                // Reiserfs rejects the big seeks.
                                // http://code.google.com/p/go/issues/detail?id=91
                                break
                        }
                        t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
                }
        }
}

type openErrorTest struct {
        path  string
        mode  int
        error error
}

var openErrorTests = []openErrorTest{
        {
                sfdir + "/no-such-file",
                O_RDONLY,
                ENOENT,
        },
        {
                sfdir,
                O_WRONLY,
                EISDIR,
        },
        {
                sfdir + "/" + sfname + "/no-such-file",
                O_WRONLY,
                ENOTDIR,
        },
}

func TestOpenError(t *testing.T) {
        for _, tt := range openErrorTests {
                f, err := OpenFile(tt.path, tt.mode, 0)
                if err == nil {
                        t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
                        f.Close()
                        continue
                }
                perr, ok := err.(*PathError)
                if !ok {
                        t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
                }
                if perr.Err != tt.error {
                        if runtime.GOOS == "plan9" {
                                syscallErrStr := perr.Err.Error()
                                expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
                                if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
                                        t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
                                }
                        } else {
                                t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
                        }
                }
        }
}

func TestOpenNoName(t *testing.T) {
        f, err := Open("")
        if err == nil {
                t.Fatal(`Open("") succeeded`)
                f.Close()
        }
}

func run(t *testing.T, cmd []string) string {
        // Run /bin/hostname and collect output.
        r, w, err := Pipe()
        if err != nil {
                t.Fatal(err)
        }
        p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
        if err != nil {
                t.Fatal(err)
        }
        defer p.Release()
        w.Close()

        var b bytes.Buffer
        io.Copy(&b, r)
        _, err = p.Wait(0)
        if err != nil {
                t.Fatalf("run hostname Wait: %v", err)
        }
        err = p.Kill()
        if err == nil {
                t.Errorf("expected an error from Kill running 'hostname'")
        }
        output := b.String()
        if n := len(output); n > 0 && output[n-1] == '\n' {
                output = output[0 : n-1]
        }
        if output == "" {
                t.Fatalf("%v produced no output", cmd)
        }

        return output
}

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
        }

        // Check internal Hostname() against the output of /bin/hostname.
        // Allow that the internal Hostname returns a Fully Qualified Domain Name
        // and the /bin/hostname only returns the first component
        hostname, err := Hostname()
        if err != nil {
                t.Fatalf("%v", err)
        }
        want := run(t, []string{"/bin/hostname"})
        if hostname != want {
                i := strings.Index(hostname, ".")
                if i < 0 || hostname[0:i] != want {
                        t.Errorf("Hostname() = %q, want %q", hostname, want)
                }
        }
}

func TestReadAt(t *testing.T) {
        f := newFile("TestReadAt", t)
        defer Remove(f.Name())
        defer f.Close()

        const data = "hello, world\n"
        io.WriteString(f, data)

        b := make([]byte, 5)
        n, err := f.ReadAt(b, 7)
        if err != nil || n != len(b) {
                t.Fatalf("ReadAt 7: %d, %v", n, err)
        }
        if string(b) != "world" {
                t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
        }
}

func TestWriteAt(t *testing.T) {
        f := newFile("TestWriteAt", t)
        defer Remove(f.Name())
        defer f.Close()

        const data = "hello, world\n"
        io.WriteString(f, data)

        n, err := f.WriteAt([]byte("WORLD"), 7)
        if err != nil || n != 5 {
                t.Fatalf("WriteAt 7: %d, %v", n, err)
        }

        b, err := ioutil.ReadFile(f.Name())
        if err != nil {
                t.Fatalf("ReadFile %s: %v", f.Name(), err)
        }
        if string(b) != "hello, WORLD\n" {
                t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
        }
}

func writeFile(t *testing.T, fname string, flag int, text string) string {
        f, err := OpenFile(fname, flag, 0666)
        if err != nil {
                t.Fatalf("Open: %v", err)
        }
        n, err := io.WriteString(f, text)
        if err != nil {
                t.Fatalf("WriteString: %d, %v", n, err)
        }
        f.Close()
        data, err := ioutil.ReadFile(fname)
        if err != nil {
                t.Fatalf("ReadFile: %v", err)
        }
        return string(data)
}

func TestAppend(t *testing.T) {
        const f = "append.txt"
        defer Remove(f)
        s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
        if s != "new" {
                t.Fatalf("writeFile: have %q want %q", s, "new")
        }
        s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
        if s != "new|append" {
                t.Fatalf("writeFile: have %q want %q", s, "new|append")
        }
        s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
        if s != "new|append|append" {
                t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
        }
        err := Remove(f)
        if err != nil {
                t.Fatalf("Remove: %v", err)
        }
        s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
        if s != "new&append" {
                t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
        }
        s = writeFile(t, f, O_CREATE|O_RDWR, "old")
        if s != "old&append" {
                t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
        }
        s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
        if s != "new" {
                t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
        }
}

func TestStatDirWithTrailingSlash(t *testing.T) {
        // Create new dir, in _test so it will get
        // cleaned up by make if not by us.
        path := "_test/_TestStatDirWithSlash_"
        err := MkdirAll(path, 0777)
        if err != nil {
                t.Fatalf("MkdirAll %q: %s", path, err)
        }
        defer RemoveAll(path)

        // Stat of path should succeed.
        _, err = Stat(path)
        if err != nil {
                t.Fatal("stat failed:", err)
        }

        // Stat of path+"/" should succeed too.
        _, err = Stat(path + "/")
        if err != nil {
                t.Fatal("stat failed:", err)
        }
}

func TestNilWaitmsgString(t *testing.T) {
        var w *Waitmsg
        s := w.String()
        if s != "<nil>" {
                t.Errorf("(*Waitmsg)(nil).String() = %q, want %q", s, "<nil>")
        }
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.