diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 3e4b2edbfb..dbc4d232b6 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -1,3 +1,5 @@ +// +build daemon + package main import ( diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index 8f7263c0be..be6f1202c4 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -1,18 +1,12 @@ package main import ( - "bufio" "fmt" - "io/ioutil" - "os" "os/exec" "strconv" "strings" "testing" "time" - "unicode" - - "github.com/kr/pty" ) func TestEventsUntag(t *testing.T) { @@ -185,49 +179,6 @@ func TestEventsImageUntagDelete(t *testing.T) { logDone("events - image untag, delete is logged") } -// #5979 -func TestEventsRedirectStdout(t *testing.T) { - - since := time.Now().Unix() - - dockerCmd(t, "run", "busybox", "true") - - defer deleteAllContainers() - - file, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("could not create temp file: %v", err) - } - defer os.Remove(file.Name()) - - command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, time.Now().Unix(), file.Name()) - _, tty, err := pty.Open() - if err != nil { - t.Fatalf("Could not open pty: %v", err) - } - cmd := exec.Command("sh", "-c", command) - cmd.Stdin = tty - cmd.Stdout = tty - cmd.Stderr = tty - if err := cmd.Run(); err != nil { - t.Fatalf("run err for command %q: %v", command, err) - } - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - for _, c := range scanner.Text() { - if unicode.IsControl(c) { - t.Fatalf("found control character %v", []byte(string(c))) - } - } - } - if err := scanner.Err(); err != nil { - t.Fatalf("Scan err for command %q: %v", command, err) - } - - logDone("events - redirect stdout") -} - func TestEventsImagePull(t *testing.T) { since := time.Now().Unix() pullCmd := exec.Command(dockerBinary, "pull", "hello-world") diff --git a/integration-cli/docker_cli_events_test_unix.go b/integration-cli/docker_cli_events_test_unix.go new file mode 100644 index 0000000000..fd6c434752 --- /dev/null +++ b/integration-cli/docker_cli_events_test_unix.go @@ -0,0 +1,59 @@ +// +build !windows + +package main + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "os/exec" + "testing" + "time" + "unicode" + + "github.com/kr/pty" +) + +// #5979 +func TestEventsRedirectStdout(t *testing.T) { + + since := time.Now().Unix() + + dockerCmd(t, "run", "busybox", "true") + + defer deleteAllContainers() + + file, err := ioutil.TempFile("", "") + if err != nil { + t.Fatalf("could not create temp file: %v", err) + } + defer os.Remove(file.Name()) + + command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, time.Now().Unix(), file.Name()) + _, tty, err := pty.Open() + if err != nil { + t.Fatalf("Could not open pty: %v", err) + } + cmd := exec.Command("sh", "-c", command) + cmd.Stdin = tty + cmd.Stdout = tty + cmd.Stderr = tty + if err := cmd.Run(); err != nil { + t.Fatalf("run err for command %q: %v", command, err) + } + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + for _, c := range scanner.Text() { + if unicode.IsControl(c) { + t.Fatalf("found control character %v", []byte(string(c))) + } + } + } + if err := scanner.Err(); err != nil { + t.Fatalf("Scan err for command %q: %v", command, err) + } + + logDone("events - redirect stdout") +} diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index fafb31d89b..876b7e645a 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -20,9 +20,7 @@ import ( "time" "github.com/docker/docker/nat" - "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/networkfs/resolvconf" - "github.com/kr/pty" ) // "test123" should be printed by docker run @@ -1240,45 +1238,6 @@ func TestRunDisallowBindMountingRootToRoot(t *testing.T) { logDone("run - bind mount /:/ as volume should fail") } -// Test recursive bind mount works by default -func TestRunWithVolumesIsRecursive(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test") - if err != nil { - t.Fatal(err) - } - - defer os.RemoveAll(tmpDir) - - // Create a temporary tmpfs mount. - tmpfsDir := filepath.Join(tmpDir, "tmpfs") - if err := os.MkdirAll(tmpfsDir, 0777); err != nil { - t.Fatalf("failed to mkdir at %s - %s", tmpfsDir, err) - } - if err := mount.Mount("tmpfs", tmpfsDir, "tmpfs", ""); err != nil { - t.Fatalf("failed to create a tmpfs mount at %s - %s", tmpfsDir, err) - } - defer mount.Unmount(tmpfsDir) - - f, err := ioutil.TempFile(tmpfsDir, "touch-me") - if err != nil { - t.Fatal(err) - } - defer f.Close() - - runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox:latest", "ls", "/tmp/tmpfs") - out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd) - if err != nil && exitCode != 0 { - t.Fatal(out, stderr, err) - } - if !strings.Contains(out, filepath.Base(f.Name())) { - t.Fatal("Recursive bind mount test failed. Expected file not found") - } - - deleteAllContainers() - - logDone("run - volumes are bind mounted recursively") -} - func TestRunDnsDefaultOptions(t *testing.T) { // ci server has default resolv.conf // so rewrite it for the test @@ -2283,44 +2242,6 @@ func TestRunExecDir(t *testing.T) { logDone("run - check execdriver dir behavior") } -// #6509 -func TestRunRedirectStdout(t *testing.T) { - - defer deleteAllContainers() - - checkRedirect := func(command string) { - _, tty, err := pty.Open() - if err != nil { - t.Fatalf("Could not open pty: %v", err) - } - cmd := exec.Command("sh", "-c", command) - cmd.Stdin = tty - cmd.Stdout = tty - cmd.Stderr = tty - ch := make(chan struct{}) - if err := cmd.Start(); err != nil { - t.Fatalf("start err: %v", err) - } - go func() { - if err := cmd.Wait(); err != nil { - t.Fatalf("wait err=%v", err) - } - close(ch) - }() - - select { - case <-time.After(10 * time.Second): - t.Fatal("command timeout") - case <-ch: - } - } - - checkRedirect(dockerBinary + " run -i busybox cat /etc/passwd | grep -q root") - checkRedirect(dockerBinary + " run busybox cat /etc/passwd | grep -q root") - - logDone("run - redirect stdout") -} - // Regression test for https://github.com/docker/docker/issues/8259 func TestRunReuseBindVolumeThatIsSymlink(t *testing.T) { tmpDir, err := ioutil.TempDir(os.TempDir(), "testlink") diff --git a/integration-cli/docker_cli_run_test_unix.go b/integration-cli/docker_cli_run_test_unix.go new file mode 100644 index 0000000000..e12611cecd --- /dev/null +++ b/integration-cli/docker_cli_run_test_unix.go @@ -0,0 +1,93 @@ +// +build !windows + +package main + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/docker/docker/pkg/mount" + "github.com/kr/pty" +) + +// #6509 +func TestRunRedirectStdout(t *testing.T) { + + defer deleteAllContainers() + + checkRedirect := func(command string) { + _, tty, err := pty.Open() + if err != nil { + t.Fatalf("Could not open pty: %v", err) + } + cmd := exec.Command("sh", "-c", command) + cmd.Stdin = tty + cmd.Stdout = tty + cmd.Stderr = tty + ch := make(chan struct{}) + if err := cmd.Start(); err != nil { + t.Fatalf("start err: %v", err) + } + go func() { + if err := cmd.Wait(); err != nil { + t.Fatalf("wait err=%v", err) + } + close(ch) + }() + + select { + case <-time.After(10 * time.Second): + t.Fatal("command timeout") + case <-ch: + } + } + + checkRedirect(dockerBinary + " run -i busybox cat /etc/passwd | grep -q root") + checkRedirect(dockerBinary + " run busybox cat /etc/passwd | grep -q root") + + logDone("run - redirect stdout") +} + +// Test recursive bind mount works by default +func TestRunWithVolumesIsRecursive(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test") + if err != nil { + t.Fatal(err) + } + + defer os.RemoveAll(tmpDir) + + // Create a temporary tmpfs mount. + tmpfsDir := filepath.Join(tmpDir, "tmpfs") + if err := os.MkdirAll(tmpfsDir, 0777); err != nil { + t.Fatalf("failed to mkdir at %s - %s", tmpfsDir, err) + } + if err := mount.Mount("tmpfs", tmpfsDir, "tmpfs", ""); err != nil { + t.Fatalf("failed to create a tmpfs mount at %s - %s", tmpfsDir, err) + } + + f, err := ioutil.TempFile(tmpfsDir, "touch-me") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox:latest", "ls", "/tmp/tmpfs") + out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd) + if err != nil && exitCode != 0 { + t.Fatal(out, stderr, err) + } + if !strings.Contains(out, filepath.Base(f.Name())) { + t.Fatal("Recursive bind mount test failed. Expected file not found") + } + + deleteAllContainers() + + logDone("run - volumes are bind mounted recursively") +} diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go index c745df69f3..3130c1a264 100644 --- a/integration-cli/docker_cli_save_load_test.go +++ b/integration-cli/docker_cli_save_load_test.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "fmt" "io/ioutil" "os" @@ -11,99 +10,8 @@ import ( "sort" "strings" "testing" - - "github.com/docker/docker/vendor/src/github.com/kr/pty" ) -// save a repo and try to load it using stdout -func TestSaveAndLoadRepoStdout(t *testing.T) { - runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") - out, _, err := runCommandWithOutput(runCmd) - if err != nil { - t.Fatalf("failed to create a container: %s, %v", out, err) - } - - cleanedContainerID := stripTrailingCharacters(out) - - repoName := "foobar-save-load-test" - - inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) - if out, _, err = runCommandWithOutput(inspectCmd); err != nil { - t.Fatalf("output should've been a container id: %s, %v", out, err) - } - - commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName) - if out, _, err = runCommandWithOutput(commitCmd); err != nil { - t.Fatalf("failed to commit container: %s, %v", out, err) - } - - inspectCmd = exec.Command(dockerBinary, "inspect", repoName) - before, _, err := runCommandWithOutput(inspectCmd) - if err != nil { - t.Fatalf("the repo should exist before saving it: %s, %v", before, err) - } - - saveCmdTemplate := `%v save %v > /tmp/foobar-save-load-test.tar` - saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName) - saveCmd := exec.Command("bash", "-c", saveCmdFinal) - if out, _, err = runCommandWithOutput(saveCmd); err != nil { - t.Fatalf("failed to save repo: %s, %v", out, err) - } - - deleteImages(repoName) - - loadCmdFinal := `cat /tmp/foobar-save-load-test.tar | docker load` - loadCmd := exec.Command("bash", "-c", loadCmdFinal) - if out, _, err = runCommandWithOutput(loadCmd); err != nil { - t.Fatalf("failed to load repo: %s, %v", out, err) - } - - inspectCmd = exec.Command(dockerBinary, "inspect", repoName) - after, _, err := runCommandWithOutput(inspectCmd) - if err != nil { - t.Fatalf("the repo should exist after loading it: %s %v", after, err) - } - - if before != after { - t.Fatalf("inspect is not the same after a save / load") - } - - deleteContainer(cleanedContainerID) - deleteImages(repoName) - - os.Remove("/tmp/foobar-save-load-test.tar") - - logDone("save - save/load a repo using stdout") - - pty, tty, err := pty.Open() - if err != nil { - t.Fatalf("Could not open pty: %v", err) - } - cmd := exec.Command(dockerBinary, "save", repoName) - cmd.Stdin = tty - cmd.Stdout = tty - cmd.Stderr = tty - if err := cmd.Start(); err != nil { - t.Fatalf("start err: %v", err) - } - if err := cmd.Wait(); err == nil { - t.Fatal("did not break writing to a TTY") - } - - buf := make([]byte, 1024) - - n, err := pty.Read(buf) - if err != nil { - t.Fatal("could not read tty output") - } - - if !bytes.Contains(buf[:n], []byte("Cowardly refusing")) { - t.Fatal("help output is not being yielded", out) - } - - logDone("save - do not save to a tty") -} - // save a repo using gz compression and try to load it using stdout func TestSaveXzAndLoadRepoStdout(t *testing.T) { tempDir, err := ioutil.TempDir("", "test-save-xz-gz-load-repo-stdout") diff --git a/integration-cli/docker_cli_save_load_test_unix.go b/integration-cli/docker_cli_save_load_test_unix.go new file mode 100644 index 0000000000..c6704877ae --- /dev/null +++ b/integration-cli/docker_cli_save_load_test_unix.go @@ -0,0 +1,102 @@ +// +build !windows + +package main + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "testing" + + "github.com/docker/docker/vendor/src/github.com/kr/pty" +) + +// save a repo and try to load it using stdout +func TestSaveAndLoadRepoStdout(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") + out, _, err := runCommandWithOutput(runCmd) + if err != nil { + t.Fatalf("failed to create a container: %s, %v", out, err) + } + + cleanedContainerID := stripTrailingCharacters(out) + + repoName := "foobar-save-load-test" + + inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) + if out, _, err = runCommandWithOutput(inspectCmd); err != nil { + t.Fatalf("output should've been a container id: %s, %v", out, err) + } + + commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName) + if out, _, err = runCommandWithOutput(commitCmd); err != nil { + t.Fatalf("failed to commit container: %s, %v", out, err) + } + + inspectCmd = exec.Command(dockerBinary, "inspect", repoName) + before, _, err := runCommandWithOutput(inspectCmd) + if err != nil { + t.Fatalf("the repo should exist before saving it: %s, %v", before, err) + } + + saveCmdTemplate := `%v save %v > /tmp/foobar-save-load-test.tar` + saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName) + saveCmd := exec.Command("bash", "-c", saveCmdFinal) + if out, _, err = runCommandWithOutput(saveCmd); err != nil { + t.Fatalf("failed to save repo: %s, %v", out, err) + } + + deleteImages(repoName) + + loadCmdFinal := `cat /tmp/foobar-save-load-test.tar | docker load` + loadCmd := exec.Command("bash", "-c", loadCmdFinal) + if out, _, err = runCommandWithOutput(loadCmd); err != nil { + t.Fatalf("failed to load repo: %s, %v", out, err) + } + + inspectCmd = exec.Command(dockerBinary, "inspect", repoName) + after, _, err := runCommandWithOutput(inspectCmd) + if err != nil { + t.Fatalf("the repo should exist after loading it: %s %v", after, err) + } + + if before != after { + t.Fatalf("inspect is not the same after a save / load") + } + + deleteContainer(cleanedContainerID) + deleteImages(repoName) + + os.Remove("/tmp/foobar-save-load-test.tar") + + logDone("save - save/load a repo using stdout") + + pty, tty, err := pty.Open() + if err != nil { + t.Fatalf("Could not open pty: %v", err) + } + cmd := exec.Command(dockerBinary, "save", repoName) + cmd.Stdin = tty + cmd.Stdout = tty + cmd.Stderr = tty + if err := cmd.Start(); err != nil { + t.Fatalf("start err: %v", err) + } + if err := cmd.Wait(); err == nil { + t.Fatal("did not break writing to a TTY") + } + + buf := make([]byte, 1024) + + n, err := pty.Read(buf) + if err != nil { + t.Fatal("could not read tty output") + } + + if !bytes.Contains(buf[:n], []byte("Cowardly refusing")) { + t.Fatal("help output is not being yielded", out) + } + + logDone("save - do not save to a tty") +} diff --git a/integration-cli/docker_test_vars.go b/integration-cli/docker_test_vars.go index 78c481bd23..3bfb8ac03f 100644 --- a/integration-cli/docker_test_vars.go +++ b/integration-cli/docker_test_vars.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "runtime" ) var ( @@ -25,16 +26,26 @@ var ( workingDirectory string ) +func binarySearchCommand() *exec.Cmd { + if runtime.GOOS == "windows" { + // Windows where.exe is included since Windows Server 2003. It accepts + // wildcards, which we use here to match the development builds binary + // names (such as docker-$VERSION.exe). + return exec.Command("where.exe", "docker*.exe") + } + return exec.Command("which", "docker") +} + func init() { if dockerBin := os.Getenv("DOCKER_BINARY"); dockerBin != "" { dockerBinary = dockerBin } else { - whichCmd := exec.Command("which", "docker") + whichCmd := binarySearchCommand() out, _, err := runCommandWithOutput(whichCmd) if err == nil { dockerBinary = stripTrailingCharacters(out) } else { - fmt.Printf("ERROR: couldn't resolve full path to the Docker binary") + fmt.Printf("ERROR: couldn't resolve full path to the Docker binary (%v)", err) os.Exit(1) } } diff --git a/integration-cli/utils.go b/integration-cli/utils.go index 2de432549c..fefd66f339 100644 --- a/integration-cli/utils.go +++ b/integration-cli/utils.go @@ -100,9 +100,7 @@ func logDone(message string) { } func stripTrailingCharacters(target string) string { - target = strings.Trim(target, "\n") - target = strings.Trim(target, " ") - return target + return strings.TrimSpace(target) } func unmarshalJSON(data []byte, result interface{}) error { diff --git a/project/make/.integration-daemon-start b/project/make/.integration-daemon-start index b974422cd7..3c796399b0 100644 --- a/project/make/.integration-daemon-start +++ b/project/make/.integration-daemon-start @@ -15,10 +15,14 @@ exec 41>&1 42>&2 DOCKER_GRAPHDRIVER=${DOCKER_GRAPHDRIVER:-vfs} DOCKER_EXECDRIVER=${DOCKER_EXECDRIVER:-native} -( set -x; exec \ - docker --daemon --debug \ - --storage-driver "$DOCKER_GRAPHDRIVER" \ - --exec-driver "$DOCKER_EXECDRIVER" \ - --pidfile "$DEST/docker.pid" \ - &> "$DEST/docker.log" -) & +if [ -z "$DOCKER_TEST_HOST" ]; then + ( set -x; exec \ + docker --daemon --debug \ + --storage-driver "$DOCKER_GRAPHDRIVER" \ + --exec-driver "$DOCKER_EXECDRIVER" \ + --pidfile "$DEST/docker.pid" \ + &> "$DEST/docker.log" + ) & +else + export DOCKER_HOST="$DOCKER_TEST_HOST" +fi