diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 5102781a8c..95424b69cc 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -106,27 +106,9 @@ func TestBuildAddSingleFileToWorkdir(t *testing.T) { t.Fatal(err) } f.Close() - buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", ".") - buildCmd.Dir = buildDirectory - done := make(chan error) - go func() { - out, exitCode, err := runCommandWithOutput(buildCmd) - if err != nil || exitCode != 0 { - done <- fmt.Errorf("build failed to complete: %s %v", out, err) - return - } - done <- nil - }() - select { - case <-time.After(5 * time.Second): - if err := buildCmd.Process.Kill(); err != nil { - fmt.Printf("could not kill build (pid=%d): %v\n", buildCmd.Process.Pid, err) - } - t.Fatal("build timed out") - case err := <-done: - if err != nil { - t.Fatal(err) - } + _, exitCode, err := dockerCmdInDirWithTimeout(5*time.Second, buildDirectory, "build", "-t", "testaddimg", ".") + if err != nil || exitCode != 0 { + t.Fatalf("build failed: %s", err) } deleteImages("testaddimg") @@ -343,27 +325,9 @@ func TestBuildCopySingleFileToWorkdir(t *testing.T) { t.Fatal(err) } f.Close() - buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", ".") - buildCmd.Dir = buildDirectory - done := make(chan error) - go func() { - out, exitCode, err := runCommandWithOutput(buildCmd) - if err != nil || exitCode != 0 { - done <- fmt.Errorf("build failed to complete: %s %v", out, err) - return - } - done <- nil - }() - select { - case <-time.After(5 * time.Second): - if err := buildCmd.Process.Kill(); err != nil { - fmt.Printf("could not kill build (pid=%d): %v\n", buildCmd.Process.Pid, err) - } - t.Fatal("build timed out") - case err := <-done: - if err != nil { - t.Fatal(err) - } + _, exitCode, err := dockerCmdInDirWithTimeout(5*time.Second, buildDirectory, "build", "-t", "testcopyimg", ".") + if err != nil || exitCode != 0 { + t.Fatalf("build failed: %s", err) } deleteImages("testcopyimg") diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index e2bdc5d08d..91418ea0a4 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -345,12 +345,34 @@ func dockerCmd(t *testing.T, args ...string) (string, int, error) { return out, status, err } +// execute a docker ocmmand with a timeout +func dockerCmdWithTimeout(timeout time.Duration, args ...string) (string, int, error) { + out, status, err := runCommandWithOutputAndTimeout(exec.Command(dockerBinary, args...), timeout) + if err != nil { + return out, status, fmt.Errorf("'%s' failed with errors: %v : %q)", strings.Join(args, " "), err, out) + } + return out, status, err +} + // execute a docker command in a directory func dockerCmdInDir(t *testing.T, path string, args ...string) (string, int, error) { dockerCommand := exec.Command(dockerBinary, args...) dockerCommand.Dir = path out, status, err := runCommandWithOutput(dockerCommand) - errorOut(err, t, fmt.Sprintf("'%s' failed with errors: %v (%v)", strings.Join(args, " "), err, out)) + if err != nil { + return out, status, fmt.Errorf("'%s' failed with errors: %v : %q)", strings.Join(args, " "), err, out) + } + return out, status, err +} + +// execute a docker command in a directory with a timeout +func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...string) (string, int, error) { + dockerCommand := exec.Command(dockerBinary, args...) + dockerCommand.Dir = path + out, status, err := runCommandWithOutputAndTimeout(dockerCommand, timeout) + if err != nil { + return out, status, fmt.Errorf("'%s' failed with errors: %v : %q)", strings.Join(args, " "), err, out) + } return out, status, err } diff --git a/integration-cli/utils.go b/integration-cli/utils.go index c828e94fef..ae4cd61a39 100644 --- a/integration-cli/utils.go +++ b/integration-cli/utils.go @@ -63,6 +63,31 @@ func runCommandWithStdoutStderr(cmd *exec.Cmd) (stdout string, stderr string, ex return } +var ErrCmdTimeout = fmt.Errorf("command timed out") + +func runCommandWithOutputAndTimeout(cmd *exec.Cmd, timeout time.Duration) (output string, exitCode int, err error) { + done := make(chan error) + go func() { + output, exitCode, err = runCommandWithOutput(cmd) + if err != nil || exitCode != 0 { + done <- fmt.Errorf("failed to run command: %s", err) + return + } + done <- nil + }() + select { + case <-time.After(timeout): + killFailed := cmd.Process.Kill() + if killFailed == nil { + fmt.Printf("failed to kill (pid=%d): %v\n", cmd.Process.Pid, err) + } + err = ErrCmdTimeout + case <-done: + break + } + return +} + func runCommand(cmd *exec.Cmd) (exitCode int, err error) { exitCode = 0 err = cmd.Run()