aboutsummaryrefslogtreecommitdiff
path: root/src/os/exec/exec_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-06-29 19:20:51 -0700
committerIan Lance Taylor <iant@golang.org>2016-06-30 16:35:56 +0000
commit95483f262b619a53793baf86512aeabf44fc9d3a (patch)
tree11fc2439e128b099242c4a347392b9fa0a7f0d7a /src/os/exec/exec_test.go
parent6c136493012b8a1f96f3edc9fa56aed70d34291a (diff)
downloadgo-95483f262b619a53793baf86512aeabf44fc9d3a.tar.gz
go-95483f262b619a53793baf86512aeabf44fc9d3a.zip
os/exec: start checking for context cancelation in Start
Previously we started checking for context cancelation in Wait, but that meant that when using StdoutPipe context cancelation never took effect. Fixes #16222. Change-Id: I89cd26d3499a6080bf1a07718ce38d825561899e Reviewed-on: https://go-review.googlesource.com/24650 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/os/exec/exec_test.go')
-rw-r--r--src/os/exec/exec_test.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 41f9dfe1c6..4cc9847721 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -878,3 +878,73 @@ func TestContext(t *testing.T) {
t.Fatal("timeout waiting for child process death")
}
}
+
+func TestContextCancel(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ c := helperCommandContext(t, ctx, "cat")
+
+ r, w, err := os.Pipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Stdin = r
+
+ stdout, err := c.StdoutPipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ readDone := make(chan struct{})
+ go func() {
+ defer close(readDone)
+ var a [1024]byte
+ for {
+ n, err := stdout.Read(a[:])
+ if err != nil {
+ if err != io.EOF {
+ t.Errorf("unexpected read error: %v", err)
+ }
+ return
+ }
+ t.Logf("%s", a[:n])
+ }
+ }()
+
+ if err := c.Start(); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := r.Close(); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := io.WriteString(w, "echo"); err != nil {
+ t.Fatal(err)
+ }
+
+ cancel()
+
+ // Calling cancel should have killed the process, so writes
+ // should now fail. Give the process a little while to die.
+ start := time.Now()
+ for {
+ if _, err := io.WriteString(w, "echo"); err != nil {
+ break
+ }
+ if time.Since(start) > time.Second {
+ t.Fatal("cancelling context did not stop program")
+ }
+ time.Sleep(time.Millisecond)
+ }
+
+ if err := w.Close(); err != nil {
+ t.Error("error closing write end of pipe: %v", err)
+ }
+ <-readDone
+
+ if err := c.Wait(); err == nil {
+ t.Error("program unexpectedly exited successfully")
+ } else {
+ t.Logf("exit status: %v", err)
+ }
+}