diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 6cf2f9975e..1fec3912e6 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -260,15 +260,14 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { c.Fatalf("Error on container creation: %v, output: %q", err, out) } type b struct { - body []byte - err error + status int + body []byte + err error } bc := make(chan b, 1) go func() { status, body, err := sockRequest("GET", "/containers/"+name+"/stats", nil) - c.Assert(status, check.Equals, http.StatusOK) - c.Assert(err, check.IsNil) - bc <- b{body, err} + bc <- b{status, body, err} }() // allow some time to stream the stats from the container @@ -283,9 +282,8 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { case <-time.After(2 * time.Second): c.Fatal("stream was not closed after container was removed") case sr := <-bc: - if sr.err != nil { - c.Fatal(sr.err) - } + c.Assert(sr.err, check.IsNil) + c.Assert(sr.status, check.Equals, http.StatusOK) dec := json.NewDecoder(bytes.NewBuffer(sr.body)) var s *types.Stats @@ -297,6 +295,7 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { } func (s *DockerSuite) TestGetStoppedContainerStats(c *check.C) { + // TODO: this test does nothing because we are c.Assert'ing in goroutine var ( name = "statscontainer" runCmd = exec.Command(dockerBinary, "create", "--name", name, "busybox", "top") diff --git a/integration-cli/docker_cli_attach_test.go b/integration-cli/docker_cli_attach_test.go index 4dd45ddff3..fc2ea1a1d1 100644 --- a/integration-cli/docker_cli_attach_test.go +++ b/integration-cli/docker_cli_attach_test.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "fmt" "io" "os/exec" "strings" @@ -89,7 +90,6 @@ func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) { } func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) { - cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox") out, _, err := runCommandWithOutput(cmd) if err != nil { @@ -108,29 +108,32 @@ func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) { } }() - done := make(chan struct{}) + done := make(chan error) go func() { defer close(done) cmd := exec.Command(dockerBinary, "attach", id) if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + done <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("attach should have failed") + done <- fmt.Errorf("attach should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("attach failed with error %q: expected %q", out, expected) + done <- fmt.Errorf("attach failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-done: + c.Assert(err, check.IsNil) case <-time.After(attachWait): c.Fatal("attach is running but should have failed") } - } func (s *DockerSuite) TestAttachDisconnect(c *check.C) { diff --git a/integration-cli/docker_cli_attach_unix_test.go b/integration-cli/docker_cli_attach_unix_test.go index bae83d994a..82808a5b08 100644 --- a/integration-cli/docker_cli_attach_unix_test.go +++ b/integration-cli/docker_cli_attach_unix_test.go @@ -27,14 +27,14 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { c.Fatal(err) } - done := make(chan struct{}) - + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) _, tty, err := pty.Open() if err != nil { - c.Fatalf("could not open pty: %v", err) + errChan <- err + return } attachCmd := exec.Command(dockerBinary, "attach", id) attachCmd.Stdin = tty @@ -42,7 +42,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { attachCmd.Stderr = tty if err := attachCmd.Run(); err != nil { - c.Fatalf("attach returned error %s", err) + errChan <- err + return } }() @@ -51,7 +52,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { c.Fatalf("error thrown while waiting for container: %s, %v", out, err) } select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(attachWait): c.Fatal("timed out without attach returning") } @@ -71,12 +73,10 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { cmd.Stdout = tty cmd.Stderr = tty - detached := make(chan struct{}) + errChan := make(chan error) go func() { - if err := cmd.Run(); err != nil { - c.Fatalf("attach returned error %s", err) - } - close(detached) + errChan <- cmd.Run() + close(errChan) }() time.Sleep(500 * time.Millisecond) @@ -87,7 +87,12 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { time.Sleep(100 * time.Millisecond) cpty.Write([]byte{17}) - <-detached + select { + case err := <-errChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("timeout while detaching") + } cpty, tty, err = pty.Open() if err != nil { @@ -119,9 +124,7 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { select { case err := <-readErr: - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) case <-time.After(2 * time.Second): c.Fatal("timeout waiting for attach read") } diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 3343427831..b74dce2cfa 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -15,7 +15,6 @@ import ( "runtime" "strconv" "strings" - "sync" "text/template" "time" @@ -764,17 +763,17 @@ ADD test_file .`, } defer ctx.Close() - done := make(chan struct{}) + errChan := make(chan error) go func() { - if _, err := buildImageFromContext(name, ctx, true); err != nil { - c.Fatal(err) - } - close(done) + _, err := buildImageFromContext(name, ctx, true) + errChan <- err + close(errChan) }() select { case <-time.After(5 * time.Second): c.Fatal("Build with adding to workdir timed out") - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) } } @@ -1365,17 +1364,17 @@ COPY test_file .`, } defer ctx.Close() - done := make(chan struct{}) + errChan := make(chan error) go func() { - if _, err := buildImageFromContext(name, ctx, true); err != nil { - c.Fatal(err) - } - close(done) + _, err := buildImageFromContext(name, ctx, true) + errChan <- err + close(errChan) }() select { case <-time.After(5 * time.Second): c.Fatal("Build with adding to workdir timed out") - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) } } @@ -1829,9 +1828,6 @@ func (s *DockerSuite) TestBuildForceRm(c *check.C) { // * When docker events sees container start, close the "docker build" command // * Wait for docker events to emit a dying event. func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { - var wg sync.WaitGroup - defer wg.Wait() - name := "testbuildcancelation" // (Note: one year, will never finish) @@ -1849,26 +1845,21 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { containerID := make(chan string) startEpoch := daemonTime(c).Unix() + // Watch for events since epoch. + eventsCmd := exec.Command( + dockerBinary, "events", + "--since", strconv.FormatInt(startEpoch, 10)) + stdout, err := eventsCmd.StdoutPipe() + if err != nil { + c.Fatal(err) + } + if err := eventsCmd.Start(); err != nil { + c.Fatal(err) + } + defer eventsCmd.Process.Kill() - wg.Add(1) // Goroutine responsible for watching start/die events from `docker events` go func() { - defer wg.Done() - // Watch for events since epoch. - eventsCmd := exec.Command( - dockerBinary, "events", - "--since", strconv.FormatInt(startEpoch, 10)) - stdout, err := eventsCmd.StdoutPipe() - err = eventsCmd.Start() - if err != nil { - c.Fatalf("failed to start 'docker events': %s", err) - } - - go func() { - <-finish - eventsCmd.Process.Kill() - }() - cid := <-containerID matchStart := regexp.MustCompile(cid + `(.*) start$`) @@ -1886,19 +1877,13 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { close(eventDie) } } - - err = eventsCmd.Wait() - if err != nil && !IsKilled(err) { - c.Fatalf("docker events had bad exit status: %s", err) - } }() buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".") buildCmd.Dir = ctx.Dir stdoutBuild, err := buildCmd.StdoutPipe() - err = buildCmd.Start() - if err != nil { + if err := buildCmd.Start(); err != nil { c.Fatalf("failed to run build: %s", err) } @@ -1923,14 +1908,12 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { // Send a kill to the `docker build` command. // Causes the underlying build to be cancelled due to socket close. - err = buildCmd.Process.Kill() - if err != nil { + if err := buildCmd.Process.Kill(); err != nil { c.Fatalf("error killing build command: %s", err) } // Get the exit status of `docker build`, check it exited because killed. - err = buildCmd.Wait() - if err != nil && !IsKilled(err) { + if err := buildCmd.Wait(); err != nil && !IsKilled(err) { c.Fatalf("wait failed during build run: %T %s", err, err) } diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index b1cc26b9a1..80cc0c69d5 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -75,8 +75,7 @@ func (s *DockerSuite) TestEventsLimit(c *check.C) { waitGroup.Add(1) go func() { defer waitGroup.Done() - err := exec.Command(dockerBinary, args...).Run() - errChan <- err + errChan <- exec.Command(dockerBinary, args...).Run() }() } @@ -229,8 +228,7 @@ func (s *DockerSuite) TestEventsImageImport(c *check.C) { if err != nil { c.Fatal(err) } - err = eventsCmd.Start() - if err != nil { + if err := eventsCmd.Start(); err != nil { c.Fatal(err) } defer eventsCmd.Process.Kill() @@ -424,30 +422,23 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) { func (s *DockerSuite) TestEventsStreaming(c *check.C) { start := daemonTime(c).Unix() - finish := make(chan struct{}) - defer close(finish) id := make(chan string) eventCreate := make(chan struct{}) eventStart := make(chan struct{}) eventDie := make(chan struct{}) eventDestroy := make(chan struct{}) + eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10)) + stdout, err := eventsCmd.StdoutPipe() + if err != nil { + c.Fatal(err) + } + if err := eventsCmd.Start(); err != nil { + c.Fatalf("failed to start 'docker events': %s", err) + } + defer eventsCmd.Process.Kill() + go func() { - eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10)) - stdout, err := eventsCmd.StdoutPipe() - if err != nil { - c.Fatal(err) - } - err = eventsCmd.Start() - if err != nil { - c.Fatalf("failed to start 'docker events': %s", err) - } - - go func() { - <-finish - eventsCmd.Process.Kill() - }() - containerID := <-id matchCreate := regexp.MustCompile(containerID + `: \(from busybox:latest\) create$`) @@ -468,11 +459,6 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) { close(eventDestroy) } } - - err = eventsCmd.Wait() - if err != nil && !IsKilled(err) { - c.Fatalf("docker events had bad exit status: %s", err) - } }() runCmd := exec.Command(dockerBinary, "run", "-d", "busybox:latest", "true") @@ -516,5 +502,4 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) { case <-eventDestroy: // ignore, done } - } diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index cbdd597565..4b36d7b532 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -74,15 +74,14 @@ func (s *DockerSuite) TestExecInteractive(c *check.C) { if err := stdin.Close(); err != nil { c.Fatal(err) } - finish := make(chan struct{}) + errChan := make(chan error) go func() { - if err := execCmd.Wait(); err != nil { - c.Fatal(err) - } - close(finish) + errChan <- execCmd.Wait() + close(errChan) }() select { - case <-finish: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("docker exec failed to exit on stdin close") } @@ -278,25 +277,29 @@ func (s *DockerSuite) TestExecTtyWithoutStdin(c *check.C) { } }() - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true") if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + errChan <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("exec should have failed") + errChan <- fmt.Errorf("exec should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("exec failed with error %q: expected %q", out, expected) + errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("exec is running but should have failed") } @@ -326,17 +329,22 @@ func (s *DockerSuite) TestExecStopNotHanging(c *check.C) { c.Fatal(err) } - wait := make(chan struct{}) + type dstop struct { + out []byte + err error + } + + ch := make(chan dstop) go func() { - if out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput(); err != nil { - c.Fatal(out, err) - } - close(wait) + out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput() + ch <- dstop{out, err} + close(ch) }() select { case <-time.After(3 * time.Second): c.Fatal("Container stop timed out") - case <-wait: + case s := <-ch: + c.Assert(s.err, check.IsNil) } } @@ -359,6 +367,7 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { var wg sync.WaitGroup var mu sync.Mutex execCgroups := []sort.StringSlice{} + errChan := make(chan error) // exec a few times concurrently to get consistent failure for i := 0; i < 5; i++ { wg.Add(1) @@ -366,7 +375,8 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { cmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/self/cgroup") out, _, err := runCommandWithOutput(cmd) if err != nil { - c.Fatal(out, err) + errChan <- err + return } cg := sort.StringSlice(strings.Split(string(out), "\n")) @@ -377,6 +387,11 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { }() } wg.Wait() + close(errChan) + + for err := range errChan { + c.Assert(err, check.IsNil) + } for _, cg := range execCgroups { if !reflect.DeepEqual(cg, containerCgroups) { diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go index a7c8916226..0a3e1af981 100644 --- a/integration-cli/docker_cli_logs_test.go +++ b/integration-cli/docker_cli_logs_test.go @@ -260,16 +260,15 @@ func (s *DockerSuite) TestLogsFollowStopped(c *check.C) { c.Fatal(err) } - ch := make(chan struct{}) + errChan := make(chan error) go func() { - if err := logsCmd.Wait(); err != nil { - c.Fatal(err) - } - close(ch) + errChan <- logsCmd.Wait() + close(errChan) }() select { - case <-ch: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("Following logs is hanged") } @@ -298,9 +297,7 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) { logCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID) stdout, err := logCmd.StdoutPipe() - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) if err := logCmd.Start(); err != nil { c.Fatal(err) @@ -308,15 +305,11 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) { // First read slowly bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead) - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) // After the container has finished we can continue reading fast bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil) - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) actual := bytes1 + bytes2 expected := 200000 diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 271051815a..bb34575fba 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -255,7 +255,6 @@ func assertContainerList(out string, expected []string) bool { } func (s *DockerSuite) TestPsListContainersSize(c *check.C) { - cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello") runCommandWithOutput(cmd) cmd = exec.Command(dockerBinary, "ps", "-s", "-n=1") diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index c3b25558d9..0cf5c31eee 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -756,17 +756,22 @@ func (s *DockerSuite) TestRunTwoConcurrentContainers(c *check.C) { group := sync.WaitGroup{} group.Add(2) + errChan := make(chan error, 2) for i := 0; i < 2; i++ { go func() { defer group.Done() cmd := exec.Command(dockerBinary, "run", "busybox", "sleep", "2") - if _, err := runCommand(cmd); err != nil { - c.Fatal(err) - } + _, err := runCommand(cmd) + errChan <- err }() } group.Wait() + close(errChan) + + for err := range errChan { + c.Assert(err, check.IsNil) + } } func (s *DockerSuite) TestRunEnvironment(c *check.C) { @@ -1851,22 +1856,20 @@ func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) { if err := stdin.Close(); err != nil { c.Fatal(err) } - finish := make(chan struct{}) + finish := make(chan error) go func() { - if err := runCmd.Wait(); err != nil { - c.Fatal(err) - } + finish <- runCmd.Wait() close(finish) }() select { - case <-finish: + case err := <-finish: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("docker run failed to exit on stdin close") } state, err := inspectField(name, "State.Running") - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) + if state != "false" { c.Fatal("Container must be stopped after stdin closing") } @@ -2762,25 +2765,29 @@ func (s *DockerSuite) TestRunPortFromDockerRangeInUse(c *check.C) { } func (s *DockerSuite) TestRunTtyWithPipe(c *check.C) { - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true") if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + errChan <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("run should have failed") + errChan <- fmt.Errorf("run should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("run failed with error %q: expected %q", out, expected) + errChan <- fmt.Errorf("run failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("container is running but should have failed") } @@ -2875,19 +2882,19 @@ func (s *DockerSuite) TestRunAllowPortRangeThroughPublish(c *check.C) { } func (s *DockerSuite) TestRunOOMExitCode(c *check.C) { - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) - + defer close(errChan) runCmd := exec.Command(dockerBinary, "run", "-m", "4MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done") out, exitCode, _ := runCommandWithOutput(runCmd) if expected := 137; exitCode != expected { - c.Fatalf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) + errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(30 * time.Second): c.Fatal("Timeout waiting for container to die on OOM") } @@ -3030,9 +3037,7 @@ func (s *DockerSuite) TestRunPidHostWithChildIsKillable(c *check.C) { }() select { case err := <-errchan: - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) case <-time.After(5 * time.Second): c.Fatal("Kill container timed out") } diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index 43fa821509..59b623162d 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -29,21 +29,22 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) { cmd.Stdin = tty cmd.Stdout = tty cmd.Stderr = tty - ch := make(chan struct{}) if err := cmd.Start(); err != nil { c.Fatalf("start err: %v", err) } + ch := make(chan error) go func() { - if err := cmd.Wait(); err != nil { - c.Fatalf("wait err=%v", err) - } + ch <- cmd.Wait() close(ch) }() select { case <-time.After(10 * time.Second): c.Fatal("command timeout") - case <-ch: + case err := <-ch: + if err != nil { + c.Fatalf("wait err=%v", err) + } } } diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go index 13ecedd57c..fddc8c97bb 100644 --- a/integration-cli/docker_cli_start_test.go +++ b/integration-cli/docker_cli_start_test.go @@ -20,18 +20,19 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) { c.Fatal("Expected error but got none") } - ch := make(chan struct{}) + ch := make(chan error) go func() { // Attempt to start attached to the container that won't start // This should return an error immediately since the container can't be started if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil { - c.Fatal("Expected error but got none") + ch <- fmt.Errorf("Expected error but got none") } close(ch) }() select { - case <-ch: + case err := <-ch: + c.Assert(err, check.IsNil) case <-time.After(time.Second): c.Fatalf("Attach did not exit properly") }