diff options
Diffstat (limited to 'libgo/go/os/exec/exec_test.go')
-rw-r--r-- | libgo/go/os/exec/exec_test.go | 123 |
1 files changed, 111 insertions, 12 deletions
diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go index f9ffde602ca..f4c025e839f 100644 --- a/libgo/go/os/exec/exec_test.go +++ b/libgo/go/os/exec/exec_test.go @@ -11,6 +11,7 @@ import ( "bufio" "bytes" "fmt" + "internal/testenv" "io" "io/ioutil" "log" @@ -28,9 +29,8 @@ import ( ) func helperCommand(t *testing.T, s ...string) *exec.Cmd { - if runtime.GOOS == "nacl" { - t.Skip("skipping on nacl") - } + testenv.MustHaveExec(t) + cs := []string{"-test.run=TestHelperProcess", "--"} cs = append(cs, s...) cmd := exec.Command(os.Args[0], cs...) @@ -53,6 +53,8 @@ func TestEcho(t *testing.T) { } func TestCommandRelativeName(t *testing.T) { + testenv.MustHaveExec(t) + // Run our own binary as a relative path // (e.g. "_test/exec.test") our parent directory. base := filepath.Base(os.Args[0]) // "exec.test" @@ -250,6 +252,12 @@ func TestPipeLookPathLeak(t *testing.T) { } func numOpenFDS(t *testing.T) (n int, lsof []byte) { + if runtime.GOOS == "android" { + // Android's stock lsof does not obey the -p option, + // so extra filtering is needed. (golang.org/issue/10206) + return numOpenFDsAndroid(t) + } + lsof, err := exec.Command("lsof", "-b", "-n", "-p", strconv.Itoa(os.Getpid())).Output() if err != nil { t.Skip("skipping test; error finding or running lsof") @@ -257,6 +265,45 @@ func numOpenFDS(t *testing.T) (n int, lsof []byte) { return bytes.Count(lsof, []byte("\n")), lsof } +func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) { + raw, err := exec.Command("lsof").Output() + if err != nil { + t.Skip("skipping test; error finding or running lsof") + } + + // First find the PID column index by parsing the first line, and + // select lines containing pid in the column. + pid := []byte(strconv.Itoa(os.Getpid())) + pidCol := -1 + + s := bufio.NewScanner(bytes.NewReader(raw)) + for s.Scan() { + line := s.Bytes() + fields := bytes.Fields(line) + if pidCol < 0 { + for i, v := range fields { + if bytes.Equal(v, []byte("PID")) { + pidCol = i + break + } + } + lsof = append(lsof, line...) + continue + } + if bytes.Equal(fields[pidCol], pid) { + lsof = append(lsof, '\n') + lsof = append(lsof, line...) + } + } + if pidCol < 0 { + t.Fatal("error processing lsof output: unexpected header format") + } + if err := s.Err(); err != nil { + t.Fatalf("error processing lsof output: %v", err) + } + return bytes.Count(lsof, []byte("\n")), lsof +} + var testedAlreadyLeaked = false // basefds returns the number of expected file descriptors @@ -275,15 +322,15 @@ func closeUnexpectedFds(t *testing.T, m string) { } func TestExtraFilesFDShuffle(t *testing.T) { - t.Skip("flaky test; see http://golang.org/issue/5780") + t.Skip("flaky test; see https://golang.org/issue/5780") switch runtime.GOOS { case "darwin": - // TODO(cnicolaou): http://golang.org/issue/2603 + // TODO(cnicolaou): https://golang.org/issue/2603 // leads to leaked file descriptors in this test when it's // run from a builder. closeUnexpectedFds(t, "TestExtraFilesFDShuffle") case "netbsd": - // http://golang.org/issue/3955 + // https://golang.org/issue/3955 closeUnexpectedFds(t, "TestExtraFilesFDShuffle") case "windows": t.Skip("no operating system support; skipping") @@ -379,8 +426,9 @@ func TestExtraFilesFDShuffle(t *testing.T) { } func TestExtraFiles(t *testing.T) { - switch runtime.GOOS { - case "nacl", "windows": + testenv.MustHaveExec(t) + + if runtime.GOOS == "windows" { t.Skipf("skipping test on %q", runtime.GOOS) } @@ -608,21 +656,21 @@ func TestHelperProcess(*testing.T) { // file descriptors... case "darwin": // TODO(bradfitz): broken? Sometimes. - // http://golang.org/issue/2603 + // https://golang.org/issue/2603 // Skip this additional part of the test for now. case "netbsd": // TODO(jsing): This currently fails on NetBSD due to // the cloned file descriptors that result from opening // /dev/urandom. - // http://golang.org/issue/3955 + // https://golang.org/issue/3955 case "plan9": // TODO(0intro): Determine why Plan 9 is leaking // file descriptors. - // http://golang.org/issue/7118 + // https://golang.org/issue/7118 case "solaris": // TODO(aram): This fails on Solaris because libc opens // its own files, as it sees fit. Darwin does the same, - // see: http://golang.org/issue/2603 + // see: https://golang.org/issue/2603 default: // Now verify that there are no other open fds. var files []*os.File @@ -721,3 +769,54 @@ func TestHelperProcess(*testing.T) { os.Exit(2) } } + +// Issue 9173: ignore stdin pipe writes if the program completes successfully. +func TestIgnorePipeErrorOnSuccess(t *testing.T) { + testenv.MustHaveExec(t) + + // We really only care about testing this on Unixy things. + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("skipping test on %q", runtime.GOOS) + } + + cmd := helperCommand(t, "echo", "foo") + var out bytes.Buffer + cmd.Stdin = strings.NewReader(strings.Repeat("x", 10<<20)) + cmd.Stdout = &out + if err := cmd.Run(); err != nil { + t.Fatal(err) + } + if got, want := out.String(), "foo\n"; got != want { + t.Errorf("output = %q; want %q", got, want) + } +} + +type badWriter struct{} + +func (w *badWriter) Write(data []byte) (int, error) { + return 0, io.ErrUnexpectedEOF +} + +func TestClosePipeOnCopyError(t *testing.T) { + testenv.MustHaveExec(t) + + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("skipping test on %s - no yes command", runtime.GOOS) + } + cmd := exec.Command("yes") + cmd.Stdout = new(badWriter) + c := make(chan int, 1) + go func() { + err := cmd.Run() + if err == nil { + t.Errorf("yes completed successfully") + } + c <- 1 + }() + select { + case <-c: + // ok + case <-time.After(5 * time.Second): + t.Fatalf("yes got stuck writing to bad writer") + } +} |