Signed-off-by: Anthony Baire <Anthony.Baire@irisa.fr>
Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
| ... | ... |
@@ -129,6 +129,11 @@ func (daemon *Daemon) ContainerLogs(name string, config *ContainerLogsConfig) er |
| 129 | 129 |
errors := make(chan error, 2) |
| 130 | 130 |
wg := sync.WaitGroup{}
|
| 131 | 131 |
|
| 132 |
+ // write an empty chunk of data (this is to ensure that the |
|
| 133 |
+ // HTTP Response is sent immediatly, even if the container has |
|
| 134 |
+ // not yet produced any data) |
|
| 135 |
+ outStream.Write(nil) |
|
| 136 |
+ |
|
| 132 | 137 |
if config.UseStdout {
|
| 133 | 138 |
wg.Add(1) |
| 134 | 139 |
stdoutPipe := container.StdoutLogPipe() |
| ... | ... |
@@ -60,3 +60,25 @@ func (s *DockerSuite) TestLogsApiNoStdoutNorStderr(c *check.C) {
|
| 60 | 60 |
c.Fatalf("Expected %s, got %s", expected, string(body[:]))
|
| 61 | 61 |
} |
| 62 | 62 |
} |
| 63 |
+ |
|
| 64 |
+// Regression test for #12704 |
|
| 65 |
+func (s *DockerSuite) TestLogsApiFollowEmptyOutput(c *check.C) {
|
|
| 66 |
+ defer deleteAllContainers() |
|
| 67 |
+ name := "logs_test" |
|
| 68 |
+ t0 := time.Now() |
|
| 69 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "sleep", "10") |
|
| 70 |
+ if out, _, err := runCommandWithOutput(runCmd); err != nil {
|
|
| 71 |
+ c.Fatal(out, err) |
|
| 72 |
+ } |
|
| 73 |
+ |
|
| 74 |
+ _, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name), bytes.NewBuffer(nil), "")
|
|
| 75 |
+ t1 := time.Now() |
|
| 76 |
+ body.Close() |
|
| 77 |
+ if err != nil {
|
|
| 78 |
+ c.Fatal(err) |
|
| 79 |
+ } |
|
| 80 |
+ elapsed := t1.Sub(t0).Seconds() |
|
| 81 |
+ if elapsed > 5.0 {
|
|
| 82 |
+ c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed)
|
|
| 83 |
+ } |
|
| 84 |
+} |