diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go new file mode 100644 index 0000000000..0e012aa4c0 --- /dev/null +++ b/integration-cli/docker_cli_exec_test.go @@ -0,0 +1,139 @@ +package main + +import ( + "bufio" + "os/exec" + "strings" + "testing" + "time" +) + +func TestExec(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && sleep 100") + out, _, _, err := runCommandWithStdoutStderr(runCmd) + errorOut(err, t, out) + + execCmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/tmp/file") + + out, _, err = runCommandWithOutput(execCmd) + errorOut(err, t, out) + + out = strings.Trim(out, "\r\n") + + if expected := "test"; out != expected { + t.Errorf("container exec should've printed %q but printed %q", expected, out) + } + + deleteAllContainers() + + logDone("exec - basic test") +} + +func TestExecInteractive(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && sleep 100") + out, _, _, err := runCommandWithStdoutStderr(runCmd) + errorOut(err, t, out) + + execCmd := exec.Command(dockerBinary, "exec", "-i", "testing", "sh") + stdin, err := execCmd.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := execCmd.StdoutPipe() + if err != nil { + t.Fatal(err) + } + + if err := execCmd.Start(); err != nil { + t.Fatal(err) + } + if _, err := stdin.Write([]byte("cat /tmp/file\n")); err != nil { + t.Fatal(err) + } + + r := bufio.NewReader(stdout) + line, err := r.ReadString('\n') + if err != nil { + t.Fatal(err) + } + line = strings.TrimSpace(line) + if line != "test" { + t.Fatalf("Output should be 'test', got '%q'", line) + } + if err := stdin.Close(); err != nil { + t.Fatal(err) + } + finish := make(chan struct{}) + go func() { + if err := execCmd.Wait(); err != nil { + t.Fatal(err) + } + close(finish) + }() + select { + case <-finish: + case <-time.After(1 * time.Second): + t.Fatal("docker exec failed to exit on stdin close") + } + + deleteAllContainers() + + logDone("exec - Interactive test") +} + +func TestExecAfterContainerRestart(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top") + out, _, err := runCommandWithOutput(runCmd) + errorOut(err, t, out) + + cleanedContainerID := stripTrailingCharacters(out) + + runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID) + out, _, err = runCommandWithOutput(runCmd) + errorOut(err, t, out) + + runCmd = exec.Command(dockerBinary, "exec", cleanedContainerID, "echo", "hello") + out, _, err = runCommandWithOutput(runCmd) + errorOut(err, t, out) + + outStr := strings.TrimSpace(out) + if outStr != "hello" { + t.Errorf("container should've printed hello, instead printed %q", outStr) + } + + deleteAllContainers() + + logDone("exec - exec running container after container restart") +} + +func TestExecAfterDaemonRestart(t *testing.T) { + d := NewDaemon(t) + if err := d.StartWithBusybox(); err != nil { + t.Fatalf("Could not start daemon with busybox: %v", err) + } + defer d.Stop() + + if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { + t.Fatalf("Could not run top: err=%v\n%s", err, out) + } + + if err := d.Restart(); err != nil { + t.Fatalf("Could not restart daemon: %v", err) + } + + if out, err := d.Cmd("start", "top"); err != nil { + t.Fatalf("Could not start top after daemon restart: err=%v\n%s", err, out) + } + + out, err := d.Cmd("exec", "top", "echo", "hello") + if err != nil { + t.Fatalf("Could not exec on container top: err=%v\n%s", err, out) + } + + outStr := strings.TrimSpace(string(out)) + if outStr != "hello" { + t.Errorf("container should've printed hello, instead printed %q", outStr) + } + + logDone("exec - exec running container after daemon restart") +} diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 08b3693b51..396a6c85fb 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -2012,81 +2012,6 @@ func TestRunPortInUse(t *testing.T) { logDone("run - fail if port already in use") } -// "test" should be printed by docker exec -func TestDockerExec(t *testing.T) { - runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && sleep 100") - out, _, _, err := runCommandWithStdoutStderr(runCmd) - errorOut(err, t, out) - - execCmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/tmp/file") - - out, _, err = runCommandWithOutput(execCmd) - errorOut(err, t, out) - - out = strings.Trim(out, "\r\n") - - if expected := "test"; out != expected { - t.Errorf("container exec should've printed %q but printed %q", expected, out) - } - - deleteAllContainers() - - logDone("exec - basic test") -} - -// "test" should be printed by docker exec -func TestDockerExecInteractive(t *testing.T) { - runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && sleep 100") - out, _, _, err := runCommandWithStdoutStderr(runCmd) - errorOut(err, t, out) - - execCmd := exec.Command(dockerBinary, "exec", "-i", "testing", "sh") - stdin, err := execCmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - stdout, err := execCmd.StdoutPipe() - if err != nil { - t.Fatal(err) - } - - if err := execCmd.Start(); err != nil { - t.Fatal(err) - } - if _, err := stdin.Write([]byte("cat /tmp/file\n")); err != nil { - t.Fatal(err) - } - - r := bufio.NewReader(stdout) - line, err := r.ReadString('\n') - if err != nil { - t.Fatal(err) - } - line = strings.TrimSpace(line) - if line != "test" { - t.Fatalf("Output should be 'test', got '%q'", line) - } - if err := stdin.Close(); err != nil { - t.Fatal(err) - } - finish := make(chan struct{}) - go func() { - if err := execCmd.Wait(); err != nil { - t.Fatal(err) - } - close(finish) - }() - select { - case <-finish: - case <-time.After(1 * time.Second): - t.Fatal("docker exec failed to exit on stdin close") - } - - deleteAllContainers() - - logDone("exec - Interactive test") -} - // Regression test for #7792 func TestMountOrdering(t *testing.T) { tmpDir, err := ioutil.TempDir("", "docker_nested_mount_test")