Make sure log pipes are closed

Pipes are still not closed (and goroutines leaked) if neither pipe is
used.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff
2015-05-12 13:50:51 -04:00
parent c9821d8dd6
commit e3ba3dd5b8
3 changed files with 80 additions and 25 deletions
+51
View File
@@ -1,7 +1,9 @@
package main
import (
"encoding/json"
"fmt"
"io"
"os/exec"
"regexp"
"strconv"
@@ -393,3 +395,52 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
}
}
func (s *DockerSuite) TestLogsFollowGoroutinesWithStdout(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 2; done")
id := strings.TrimSpace(out)
c.Assert(waitRun(id), check.IsNil)
type info struct {
NGoroutines int
}
getNGoroutines := func() int {
var i info
status, b, err := sockRequest("GET", "/info", nil)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, 200)
c.Assert(json.Unmarshal(b, &i), check.IsNil)
return i.NGoroutines
}
nroutines := getNGoroutines()
cmd := exec.Command(dockerBinary, "logs", "-f", id)
r, w := io.Pipe()
cmd.Stdout = w
c.Assert(cmd.Start(), check.IsNil)
// Make sure pipe is written to
chErr := make(chan error)
go func() {
b := make([]byte, 1)
_, err := r.Read(b)
chErr <- err
}()
c.Assert(<-chErr, check.IsNil)
c.Assert(cmd.Process.Kill(), check.IsNil)
// NGoroutines is not updated right away, so we need to wait before failing
t := time.After(5 * time.Second)
for {
select {
case <-t:
c.Assert(nroutines, check.Equals, getNGoroutines())
default:
if nroutines == getNGoroutines() {
return
}
time.Sleep(100 * time.Millisecond)
}
}
}