From 5dbaea1ca99ecb51174259f5ebb814101c349edc Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Sat, 14 Feb 2015 01:19:57 -0800 Subject: [PATCH] integration-cli: remove timeout dependency on TestEventsUntag TestEventsUntag requires a `timeout` command which does not exist on OS X or Windows (in fact, windows has a totally different timeout program and this test was accidentally using it). - Created runCommandWithOutputForDuration. This entirely replaces runDockerCommandWithTimeout and removes dependency to `timeout` command. - Made runDockerCommandWithTimeout reuse runDockerCommandForDuration. TestEventsUntag works now on Windows. Signed-off-by: Ahmet Alp Balkan --- integration-cli/docker_cli_events_test.go | 7 ++- integration-cli/utils.go | 57 ++++++++++++++++------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index c798882ad1..4ca2c0cebb 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -15,8 +15,11 @@ func TestEventsUntag(t *testing.T) { dockerCmd(t, "tag", image, "utest:tag2") dockerCmd(t, "rmi", "utest:tag1") dockerCmd(t, "rmi", "utest:tag2") - eventsCmd := exec.Command("timeout", "0.2", dockerBinary, "events", "--since=1") - out, _, _ := runCommandWithOutput(eventsCmd) + eventsCmd := exec.Command(dockerBinary, "events", "--since=1") + out, exitCode, _, err := runCommandWithOutputForDuration(eventsCmd, time.Duration(time.Millisecond*200)) + if exitCode != 0 || err != nil { + t.Fatalf("Failed to get events - exit code %d: %s", exitCode, err) + } events := strings.Split(out, "\n") nEvents := len(events) // The last element after the split above will be an empty string, so we diff --git a/integration-cli/utils.go b/integration-cli/utils.go index f67ee78ca7..8db2a22085 100644 --- a/integration-cli/utils.go +++ b/integration-cli/utils.go @@ -3,6 +3,7 @@ package main import ( "bytes" "encoding/json" + "errors" "fmt" "io" "math/rand" @@ -63,27 +64,49 @@ func runCommandWithStdoutStderr(cmd *exec.Cmd) (stdout string, stderr string, ex return } +func runCommandWithOutputForDuration(cmd *exec.Cmd, duration time.Duration) (output string, exitCode int, timedOut bool, err error) { + var outputBuffer bytes.Buffer + if cmd.Stdout != nil { + err = errors.New("cmd.Stdout already set") + return + } + cmd.Stdout = &outputBuffer + + if cmd.Stderr != nil { + err = errors.New("cmd.Stderr already set") + return + } + cmd.Stderr = &outputBuffer + + done := make(chan error) + go func() { + exitErr := cmd.Run() + exitCode = processExitCode(exitErr) + done <- exitErr + }() + + select { + case <-time.After(duration): + killErr := cmd.Process.Kill() + if killErr != nil { + fmt.Printf("failed to kill (pid=%d): %v\n", cmd.Process.Pid, killErr) + } + timedOut = true + break + case err = <-done: + break + } + output = outputBuffer.String() + 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) - } + var timedOut bool + output, exitCode, timedOut, err = runCommandWithOutputForDuration(cmd, timeout) + if timedOut { err = ErrCmdTimeout - case <-done: - break } return }