Merge branch master into bump_v1.4.0

Docker-DCO-1.1-Signed-off-by: Jessica Frazelle <jess@docker.com> (github: jfrazelle)
Upstream-commit: debf60b4665dc2bc7f11cad5a996a5fa05fe2112
Component: engine
This commit is contained in:
Jessica Frazelle
2014-12-11 15:00:03 -08:00
550 changed files with 19291 additions and 5160 deletions

View File

@ -1,10 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN mkdir /exists
RUN touch /exists/exists_file
RUN chown -R dockerio.dockerio /exists
COPY test_dir/ /exists/
RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]

View File

@ -1,8 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN touch /exists
RUN chown dockerio.dockerio exists
COPY test_dir /
RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -1,2 +0,0 @@
FROM busybox
COPY https://index.docker.io/robots.txt /

View File

@ -1,2 +0,0 @@
FROM scratch
COPY . /

View File

@ -1,17 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN mkdir /exists
RUN touch /exists/exists_file
RUN chown -R dockerio.dockerio /exists
COPY test_file1 test_file2 /exists/
ADD test_file3 test_file4 https://docker.com/robots.txt /exists/
RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -1,7 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN mkdir /exists
RUN chown -R dockerio.dockerio /exists
COPY test_file1 /exists/
ADD test_file2 test_file3 /exists/test_file1

View File

@ -1,10 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN mkdir /exists
RUN touch /exists/exists_file
RUN chown -R dockerio.dockerio /exists
COPY test_file /exists/
RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -1,9 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN touch /exists
RUN chown dockerio.dockerio /exists
COPY test_file /test_dir/
RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -1,9 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN touch /exists
RUN chown dockerio.dockerio /exists
COPY test_file /
RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /test_file | awk '{print $1}') = '-rw-r--r--' ]
RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -1,2 +0,0 @@
FROM busybox
COPY test_file .

View File

@ -1,11 +0,0 @@
FROM busybox
RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
RUN echo 'dockerio:x:1001:' >> /etc/group
RUN touch /exists
RUN chown dockerio.dockerio exists
COPY test_dir /test_dir
RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '-rw-r--r--' ]
RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]

View File

@ -0,0 +1,122 @@
package main
import (
"bytes"
"encoding/json"
"io"
"os/exec"
"testing"
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
)
func TestContainerApiGetAll(t *testing.T) {
startCount, err := getContainerCount()
if err != nil {
t.Fatalf("Cannot query container count: %v", err)
}
name := "getall"
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf("Error on container creation: %v, output: %q", err, out)
}
body, err := sockRequest("GET", "/containers/json?all=1", nil)
if err != nil {
t.Fatalf("GET all containers sockRequest failed: %v", err)
}
var inspectJSON []struct {
Names []string
}
if err = json.Unmarshal(body, &inspectJSON); err != nil {
t.Fatalf("unable to unmarshal response body: %v", err)
}
if len(inspectJSON) != startCount+1 {
t.Fatalf("Expected %d container(s), %d found (started with: %d)", startCount+1, len(inspectJSON), startCount)
}
if actual := inspectJSON[0].Names[0]; actual != "/"+name {
t.Fatalf("Container Name mismatch. Expected: %q, received: %q\n", "/"+name, actual)
}
deleteAllContainers()
logDone("container REST API - check GET json/all=1")
}
func TestContainerApiGetExport(t *testing.T) {
name := "exportcontainer"
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "touch", "/test")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf("Error on container creation: %v, output: %q", err, out)
}
body, err := sockRequest("GET", "/containers/"+name+"/export", nil)
if err != nil {
t.Fatalf("GET containers/export sockRequest failed: %v", err)
}
found := false
for tarReader := tar.NewReader(bytes.NewReader(body)); ; {
h, err := tarReader.Next()
if err != nil {
if err == io.EOF {
break
}
t.Fatal(err)
}
if h.Name == "test" {
found = true
break
}
}
if !found {
t.Fatalf("The created test file has not been found in the exported image")
}
deleteAllContainers()
logDone("container REST API - check GET containers/export")
}
func TestContainerApiGetChanges(t *testing.T) {
name := "changescontainer"
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "rm", "/etc/passwd")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf("Error on container creation: %v, output: %q", err, out)
}
body, err := sockRequest("GET", "/containers/"+name+"/changes", nil)
if err != nil {
t.Fatalf("GET containers/changes sockRequest failed: %v", err)
}
changes := []struct {
Kind int
Path string
}{}
if err = json.Unmarshal(body, &changes); err != nil {
t.Fatalf("unable to unmarshal response body: %v", err)
}
// Check the changelog for removal of /etc/passwd
success := false
for _, elem := range changes {
if elem.Path == "/etc/passwd" && elem.Kind == 2 {
success = true
}
}
if !success {
t.Fatalf("/etc/passwd has been removed but is not present in the diff")
}
deleteAllContainers()
logDone("container REST API - check GET containers/changes")
}

View File

@ -0,0 +1,25 @@
package main
import (
"bytes"
"fmt"
"os/exec"
"testing"
)
// Regression test for #9414
func TestExecApiCreateNoCmd(t *testing.T) {
defer deleteAllContainers()
name := "exec_test"
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
if out, _, err := runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
body, err := sockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": nil})
if err == nil || !bytes.Contains(body, []byte("No exec command specified")) {
t.Fatalf("Expected error when creating exec command with no Cmd specified: %q", err)
}
logDone("exec create API - returns error when missing Cmd")
}

View File

@ -2,7 +2,6 @@ package main
import (
"encoding/json"
"fmt"
"os/exec"
"testing"
)
@ -10,7 +9,9 @@ import (
func TestInspectApiContainerResponse(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to create a container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
@ -23,7 +24,7 @@ func TestInspectApiContainerResponse(t *testing.T) {
if testVersion != "latest" {
endpoint = "/" + testVersion + endpoint
}
body, err := sockRequest("GET", endpoint)
body, err := sockRequest("GET", endpoint, nil)
if err != nil {
t.Fatalf("sockRequest failed for %s version: %v", testVersion, err)
}

View File

@ -0,0 +1,53 @@
package main
import (
"os/exec"
"strings"
"testing"
)
func TestResizeApiResponse(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
defer deleteAllContainers()
cleanedContainerID := stripTrailingCharacters(out)
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
_, err = sockRequest("POST", endpoint, nil)
if err != nil {
t.Fatalf("resize Request failed %v", err)
}
logDone("container resize - when started")
}
func TestResizeApiResponseWhenContainerNotStarted(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
defer deleteAllContainers()
cleanedContainerID := stripTrailingCharacters(out)
// make sure the exited cintainer is not running
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
body, err := sockRequest("POST", endpoint, nil)
if err == nil {
t.Fatalf("resize should fail when container is not started")
}
if !strings.Contains(string(body), "Cannot resize container") && !strings.Contains(string(body), cleanedContainerID) {
t.Fatalf("resize should fail with message 'Cannot resize container' but instead received %s", string(body))
}
logDone("container resize - when not started should not resize")
}

View File

@ -50,7 +50,7 @@ func TestAttachMultipleAndRestart(t *testing.T) {
t.Fatal(err)
}
if _, err := startCommand(c); err != nil {
if err := c.Start(); err != nil {
t.Fatal(err)
}
@ -87,3 +87,50 @@ func TestAttachMultipleAndRestart(t *testing.T) {
logDone("attach - multiple attach")
}
func TestAttachTtyWithoutStdin(t *testing.T) {
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatalf("failed to start container: %v (%v)", out, err)
}
id := strings.TrimSpace(out)
if err := waitRun(id); err != nil {
t.Fatal(err)
}
defer func() {
cmd := exec.Command(dockerBinary, "kill", id)
if out, _, err := runCommandWithOutput(cmd); err != nil {
t.Fatalf("failed to kill container: %v (%v)", out, err)
}
}()
done := make(chan struct{})
go func() {
defer close(done)
cmd := exec.Command(dockerBinary, "attach", id)
if _, err := cmd.StdinPipe(); err != nil {
t.Fatal(err)
}
expected := "cannot enable tty mode"
if out, _, err := runCommandWithOutput(cmd); err == nil {
t.Fatal("attach should have failed")
} else if !strings.Contains(out, expected) {
t.Fatal("attach failed with error %q: expected %q", out, expected)
}
}()
select {
case <-done:
case <-time.After(attachWait):
t.Fatal("attach is running but should have failed")
}
logDone("attach - forbid piped stdin to tty enabled container")
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -10,23 +9,29 @@ import (
func TestCommitAfterContainerIsDone(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("failed to run container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to run container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID)
_, _, err = runCommandWithOutput(waitCmd)
errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
}
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID)
out, _, err = runCommandWithOutput(commitCmd)
errorOut(err, t, fmt.Sprintf("failed to commit container to image: %v %v", out, err))
if err != nil {
t.Fatalf("failed to commit container to image: %s, %v", out, err)
}
cleanedImageID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID)
out, _, err = runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("failed to inspect image: %v %v", out, err))
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("failed to inspect image: %s, %v", out, err)
}
deleteContainer(cleanedContainerID)
deleteImages(cleanedImageID)
@ -37,23 +42,29 @@ func TestCommitAfterContainerIsDone(t *testing.T) {
func TestCommitWithoutPause(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("failed to run container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to run container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID)
_, _, err = runCommandWithOutput(waitCmd)
errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
if _, _, err = runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", out, err)
}
commitCmd := exec.Command(dockerBinary, "commit", "-p=false", cleanedContainerID)
out, _, err = runCommandWithOutput(commitCmd)
errorOut(err, t, fmt.Sprintf("failed to commit container to image: %v %v", out, err))
if err != nil {
t.Fatalf("failed to commit container to image: %s, %v", out, err)
}
cleanedImageID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID)
out, _, err = runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("failed to inspect image: %v %v", out, err))
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("failed to inspect image: %s, %v", out, err)
}
deleteContainer(cleanedContainerID)
deleteImages(cleanedImageID)
@ -81,7 +92,7 @@ func TestCommitNewFile(t *testing.T) {
t.Fatal(err, out)
}
if actual := strings.Trim(out, "\r\n"); actual != "koye" {
t.Fatalf("expected output koye received %s", actual)
t.Fatalf("expected output koye received %q", actual)
}
deleteAllContainers()
@ -90,9 +101,63 @@ func TestCommitNewFile(t *testing.T) {
logDone("commit - commit file and read")
}
func TestCommitTTY(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-t", "--name", "tty", "busybox", "/bin/ls")
func TestCommitHardlink(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-t", "--name", "hardlinks", "busybox", "sh", "-c", "touch file1 && ln file1 file2 && ls -di file1 file2")
firstOuput, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
chunks := strings.Split(strings.TrimSpace(firstOuput), " ")
inode := chunks[0]
found := false
for _, chunk := range chunks[1:] {
if chunk == inode {
found = true
break
}
}
if !found {
t.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
}
cmd = exec.Command(dockerBinary, "commit", "hardlinks", "hardlinks")
imageID, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(imageID, err)
}
imageID = strings.Trim(imageID, "\r\n")
cmd = exec.Command(dockerBinary, "run", "-t", "hardlinks", "ls", "-di", "file1", "file2")
secondOuput, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
chunks = strings.Split(strings.TrimSpace(secondOuput), " ")
inode = chunks[0]
found = false
for _, chunk := range chunks[1:] {
if chunk == inode {
found = true
break
}
}
if !found {
t.Fatalf("Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
}
deleteAllContainers()
deleteImages(imageID)
logDone("commit - commit hardlinks")
}
func TestCommitTTY(t *testing.T) {
defer deleteImages("ttytest")
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "-t", "--name", "tty", "busybox", "/bin/ls")
if _, err := runCommand(cmd); err != nil {
t.Fatal(err)
}
@ -105,7 +170,6 @@ func TestCommitTTY(t *testing.T) {
imageID = strings.Trim(imageID, "\r\n")
cmd = exec.Command(dockerBinary, "run", "ttytest", "/bin/ls")
if _, err := runCommand(cmd); err != nil {
t.Fatal(err)
}
@ -124,6 +188,7 @@ func TestCommitWithHostBindMount(t *testing.T) {
if err != nil {
t.Fatal(imageID, err)
}
imageID = strings.Trim(imageID, "\r\n")
cmd = exec.Command(dockerBinary, "run", "bindtest", "true")

View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
@ -22,7 +23,7 @@ const (
// Test for #5656
// Check that garbage paths don't escape the container's rootfs
func TestCpGarbagePath(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -30,7 +31,7 @@ func TestCpGarbagePath(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -58,7 +59,7 @@ func TestCpGarbagePath(t *testing.T) {
path := filepath.Join("../../../../../../../../../../../../", cpFullPath)
_, _, err = cmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
if err != nil {
t.Fatalf("couldn't copy from garbage path: %s:%s %s", cleanedContainerID, path, err)
}
@ -84,7 +85,7 @@ func TestCpGarbagePath(t *testing.T) {
// Check that relative paths are relative to the container's rootfs
func TestCpRelativePath(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -92,7 +93,7 @@ func TestCpRelativePath(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -121,7 +122,7 @@ func TestCpRelativePath(t *testing.T) {
path, _ := filepath.Rel("/", cpFullPath)
_, _, err = cmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
if err != nil {
t.Fatalf("couldn't copy from relative path: %s:%s %s", cleanedContainerID, path, err)
}
@ -147,7 +148,7 @@ func TestCpRelativePath(t *testing.T) {
// Check that absolute paths are relative to the container's rootfs
func TestCpAbsolutePath(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath)
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -155,7 +156,7 @@ func TestCpAbsolutePath(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -184,7 +185,7 @@ func TestCpAbsolutePath(t *testing.T) {
path := cpFullPath
_, _, err = cmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
if err != nil {
t.Fatalf("couldn't copy from absolute path: %s:%s %s", cleanedContainerID, path, err)
}
@ -211,7 +212,7 @@ func TestCpAbsolutePath(t *testing.T) {
// Test for #5619
// Check that absolute symlinks are still relative to the container's rootfs
func TestCpAbsoluteSymlink(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" container_path")
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpFullPath+" container_path")
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -219,7 +220,7 @@ func TestCpAbsoluteSymlink(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -248,7 +249,7 @@ func TestCpAbsoluteSymlink(t *testing.T) {
path := filepath.Join("/", "container_path")
_, _, err = cmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
if err != nil {
t.Fatalf("couldn't copy from absolute path: %s:%s %s", cleanedContainerID, path, err)
}
@ -275,7 +276,7 @@ func TestCpAbsoluteSymlink(t *testing.T) {
// Test for #5619
// Check that symlinks which are part of the resource path are still relative to the container's rootfs
func TestCpSymlinkComponent(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path")
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path")
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -283,7 +284,7 @@ func TestCpSymlinkComponent(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -312,7 +313,7 @@ func TestCpSymlinkComponent(t *testing.T) {
path := filepath.Join("/", "container_path", cpTestName)
_, _, err = cmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":"+path, tmpdir)
if err != nil {
t.Fatalf("couldn't copy from symlink path component: %s:%s %s", cleanedContainerID, path, err)
}
@ -338,7 +339,7 @@ func TestCpSymlinkComponent(t *testing.T) {
// Check that cp with unprivileged user doesn't return any error
func TestCpUnprivilegedUser(t *testing.T) {
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
@ -346,7 +347,7 @@ func TestCpUnprivilegedUser(t *testing.T) {
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = cmd(t, "wait", cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
@ -372,6 +373,112 @@ func TestCpUnprivilegedUser(t *testing.T) {
logDone("cp - unprivileged user")
}
func TestCpVolumePath(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "cp-test-volumepath")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
outDir, err := ioutil.TempDir("", "cp-test-volumepath-out")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(outDir)
_, err = os.Create(tmpDir + "/test")
if err != nil {
t.Fatal(err)
}
out, exitCode, err := dockerCmd(t, "run", "-d", "-v", "/foo", "-v", tmpDir+"/test:/test", "-v", tmpDir+":/baz", "busybox", "/bin/sh", "-c", "touch /foo/bar")
if err != nil || exitCode != 0 {
t.Fatal("failed to create a container", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
out, _, err = dockerCmd(t, "wait", cleanedContainerID)
if err != nil || stripTrailingCharacters(out) != "0" {
t.Fatal("failed to set up container", out, err)
}
// Copy actual volume path
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/foo", outDir)
if err != nil {
t.Fatalf("couldn't copy from volume path: %s:%s %v", cleanedContainerID, "/foo", err)
}
stat, err := os.Stat(outDir + "/foo")
if err != nil {
t.Fatal(err)
}
if !stat.IsDir() {
t.Fatal("expected copied content to be dir")
}
stat, err = os.Stat(outDir + "/foo/bar")
if err != nil {
t.Fatal(err)
}
if stat.IsDir() {
t.Fatal("Expected file `bar` to be a file")
}
// Copy file nested in volume
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/foo/bar", outDir)
if err != nil {
t.Fatalf("couldn't copy from volume path: %s:%s %v", cleanedContainerID, "/foo", err)
}
stat, err = os.Stat(outDir + "/bar")
if err != nil {
t.Fatal(err)
}
if stat.IsDir() {
t.Fatal("Expected file `bar` to be a file")
}
// Copy Bind-mounted dir
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/baz", outDir)
if err != nil {
t.Fatalf("couldn't copy from bind-mounted volume path: %s:%s %v", cleanedContainerID, "/baz", err)
}
stat, err = os.Stat(outDir + "/baz")
if err != nil {
t.Fatal(err)
}
if !stat.IsDir() {
t.Fatal("Expected `baz` to be a dir")
}
// Copy file nested in bind-mounted dir
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/baz/test", outDir)
fb, err := ioutil.ReadFile(outDir + "/baz/test")
if err != nil {
t.Fatal(err)
}
fb2, err := ioutil.ReadFile(tmpDir + "/test")
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(fb, fb2) {
t.Fatalf("Expected copied file to be duplicate of bind-mounted file")
}
// Copy bind-mounted file
_, _, err = dockerCmd(t, "cp", cleanedContainerID+":/test", outDir)
fb, err = ioutil.ReadFile(outDir + "/test")
if err != nil {
t.Fatal(err)
}
fb2, err = ioutil.ReadFile(tmpDir + "/test")
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(fb, fb2) {
t.Fatalf("Expected copied file to be duplicate of bind-mounted file")
}
logDone("cp - volume path")
}
func TestCpToDot(t *testing.T) {
out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
if err != nil || exitCode != 0 {
@ -405,7 +512,7 @@ func TestCpToDot(t *testing.T) {
}
content, err := ioutil.ReadFile("./test")
if string(content) != "lololol\n" {
t.Fatal("Wrong content in copied file %q, should be %q", content, "lololol\n")
t.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
}
logDone("cp - to dot path")
}

View File

@ -2,7 +2,7 @@ package main
import (
"encoding/json"
"fmt"
"os"
"os/exec"
"testing"
"time"
@ -12,13 +12,17 @@ import (
func TestCreateArgs(t *testing.T) {
runCmd := exec.Command(dockerBinary, "create", "busybox", "command", "arg1", "arg2", "arg with space")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err))
out, _, err = runCommandWithOutput(inspectCmd)
if err != nil {
t.Fatalf("out should've been a container id: %s, %v", out, err)
}
containers := []struct {
ID string
@ -27,7 +31,7 @@ func TestCreateArgs(t *testing.T) {
Args []string
Image string
}{}
if err := json.Unmarshal([]byte(inspectOut), &containers); err != nil {
if err := json.Unmarshal([]byte(out), &containers); err != nil {
t.Fatalf("Error inspecting the container: %s", err)
}
if len(containers) != 1 {
@ -60,20 +64,24 @@ func TestCreateArgs(t *testing.T) {
func TestCreateHostConfig(t *testing.T) {
runCmd := exec.Command(dockerBinary, "create", "-P", "busybox", "echo")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err))
out, _, err = runCommandWithOutput(inspectCmd)
if err != nil {
t.Fatalf("out should've been a container id: %s, %v", out, err)
}
containers := []struct {
HostConfig *struct {
PublishAllPorts bool
}
}{}
if err := json.Unmarshal([]byte(inspectOut), &containers); err != nil {
if err := json.Unmarshal([]byte(out), &containers); err != nil {
t.Fatalf("Error inspecting the container: %s", err)
}
if len(containers) != 1 {
@ -98,19 +106,43 @@ func TestCreateHostConfig(t *testing.T) {
func TestCreateEchoStdout(t *testing.T) {
runCmd := exec.Command(dockerBinary, "create", "busybox", "echo", "test123")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "start", "-ai", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out != "test123\n" {
t.Errorf("container should've printed 'test123', got '%s'", out)
t.Errorf("container should've printed 'test123', got %q", out)
}
deleteAllContainers()
logDone("create - echo test123")
}
func TestCreateVolumesCreated(t *testing.T) {
name := "test_create_volume"
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-v", "/foo", "busybox")); err != nil {
t.Fatal(out, err)
}
dir, err := inspectFieldMap(name, "Volumes", "/foo")
if err != nil {
t.Fatalf("Error getting volume host path: %q", err)
}
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
t.Fatalf("Volume was not created")
}
if err != nil {
t.Fatalf("Error statting volume host path: %q", err)
}
logDone("create - volumes are created")
}

View File

@ -2,7 +2,9 @@ package main
import (
"encoding/json"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
)
@ -92,3 +94,193 @@ func TestDaemonStartIptablesFalse(t *testing.T) {
logDone("daemon - started daemon with iptables=false")
}
// Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and
// no longer has an IP associated, we should gracefully handle that case and associate
// an IP with it rather than fail daemon start
func TestDaemonStartBridgeWithoutIPAssociation(t *testing.T) {
d := NewDaemon(t)
// rather than depending on brctl commands to verify docker0 is created and up
// let's start the daemon and stop it, and then make a modification to run the
// actual test
if err := d.Start(); err != nil {
t.Fatalf("Could not start daemon: %v", err)
}
if err := d.Stop(); err != nil {
t.Fatalf("Could not stop daemon: %v", err)
}
// now we will remove the ip from docker0 and then try starting the daemon
ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0")
stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd)
if err != nil {
t.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr)
}
if err := d.Start(); err != nil {
warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix"
t.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning)
}
// cleanup - stop the daemon if test passed
if err := d.Stop(); err != nil {
t.Fatalf("Could not stop daemon: %v", err)
}
logDone("daemon - successful daemon start when bridge has no IP association")
}
func TestDaemonIptablesClean(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: %s, %v", out, err)
}
// get output from iptables with container running
ipTablesSearchString := "tcp dpt:80"
ipTablesCmd := exec.Command("iptables", "-nvL")
out, _, err := runCommandWithOutput(ipTablesCmd)
if err != nil {
t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
}
if !strings.Contains(out, ipTablesSearchString) {
t.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
}
if err := d.Stop(); err != nil {
t.Fatalf("Could not stop daemon: %v", err)
}
// get output from iptables after restart
ipTablesCmd = exec.Command("iptables", "-nvL")
out, _, err = runCommandWithOutput(ipTablesCmd)
if err != nil {
t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
}
if strings.Contains(out, ipTablesSearchString) {
t.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out)
}
deleteAllContainers()
logDone("daemon - run,iptables - iptables rules cleaned after daemon restart")
}
func TestDaemonIptablesCreate(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", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil {
t.Fatalf("Could not run top: %s, %v", out, err)
}
// get output from iptables with container running
ipTablesSearchString := "tcp dpt:80"
ipTablesCmd := exec.Command("iptables", "-nvL")
out, _, err := runCommandWithOutput(ipTablesCmd)
if err != nil {
t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
}
if !strings.Contains(out, ipTablesSearchString) {
t.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
}
if err := d.Restart(); err != nil {
t.Fatalf("Could not restart daemon: %v", err)
}
// make sure the container is not running
runningOut, err := d.Cmd("inspect", "--format='{{.State.Running}}'", "top")
if err != nil {
t.Fatalf("Could not inspect on container: %s, %v", out, err)
}
if strings.TrimSpace(runningOut) != "true" {
t.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut))
}
// get output from iptables after restart
ipTablesCmd = exec.Command("iptables", "-nvL")
out, _, err = runCommandWithOutput(ipTablesCmd)
if err != nil {
t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
}
if !strings.Contains(out, ipTablesSearchString) {
t.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out)
}
deleteAllContainers()
logDone("daemon - run,iptables - iptables rules for always restarted container created after daemon restart")
}
func TestDaemonLoggingLevel(t *testing.T) {
d := NewDaemon(t)
if err := d.Start("--log-level=bogus"); err == nil {
t.Fatal("Daemon should not have been able to start")
}
d = NewDaemon(t)
if err := d.Start("--log-level=debug"); err != nil {
t.Fatal(err)
}
d.Stop()
content, _ := ioutil.ReadFile(d.logFile.Name())
if !strings.Contains(string(content), `level="debug"`) {
t.Fatalf(`Missing level="debug" in log file:\n%s`, string(content))
}
d = NewDaemon(t)
if err := d.Start("--log-level=fatal"); err != nil {
t.Fatal(err)
}
d.Stop()
content, _ = ioutil.ReadFile(d.logFile.Name())
if strings.Contains(string(content), `level="debug"`) {
t.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content))
}
d = NewDaemon(t)
if err := d.Start("-D"); err != nil {
t.Fatal(err)
}
d.Stop()
content, _ = ioutil.ReadFile(d.logFile.Name())
if !strings.Contains(string(content), `level="debug"`) {
t.Fatalf(`Missing level="debug" in log file using -D:\n%s`, string(content))
}
d = NewDaemon(t)
if err := d.Start("--debug"); err != nil {
t.Fatal(err)
}
d.Stop()
content, _ = ioutil.ReadFile(d.logFile.Name())
if !strings.Contains(string(content), `level="debug"`) {
t.Fatalf(`Missing level="debug" in log file using --debug:\n%s`, string(content))
}
d = NewDaemon(t)
if err := d.Start("--debug", "--log-level=fatal"); err != nil {
t.Fatal(err)
}
d.Stop()
content, _ = ioutil.ReadFile(d.logFile.Name())
if !strings.Contains(string(content), `level="debug"`) {
t.Fatalf(`Missing level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content))
}
logDone("daemon - Logging Level")
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -11,14 +10,18 @@ import (
func TestDiffFilenameShownInOutput(t *testing.T) {
containerCmd := `echo foo > /root/bar`
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd)
cid, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf("failed to start the container: %s, %v", out, err)
}
cleanCID := stripTrailingCharacters(cid)
cleanCID := stripTrailingCharacters(out)
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
out, _, err := runCommandWithOutput(diffCmd)
errorOut(err, t, fmt.Sprintf("failed to run diff: %v %v", out, err))
out, _, err = runCommandWithOutput(diffCmd)
if err != nil {
t.Fatalf("failed to run diff: %s %v", out, err)
}
found := false
for _, line := range strings.Split(out, "\n") {
@ -44,14 +47,18 @@ func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
for i := 0; i < 20; i++ {
containerCmd := `echo foo > /root/bar`
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd)
cid, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("%s", err))
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal(out, err)
}
cleanCID := stripTrailingCharacters(cid)
cleanCID := stripTrailingCharacters(out)
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
out, _, err := runCommandWithOutput(diffCmd)
errorOut(err, t, fmt.Sprintf("failed to run diff: %v %v", out, err))
out, _, err = runCommandWithOutput(diffCmd)
if err != nil {
t.Fatalf("failed to run diff: %s, %v", out, err)
}
deleteContainer(cleanCID)
@ -67,13 +74,18 @@ func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sleep", "0")
cid, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("%s", err))
cleanCID := stripTrailingCharacters(cid)
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal(out, err)
}
cleanCID := stripTrailingCharacters(out)
diffCmd := exec.Command(dockerBinary, "diff", cleanCID)
out, _, err := runCommandWithOutput(diffCmd)
errorOut(err, t, fmt.Sprintf("failed to run diff: %v %v", out, err))
out, _, err = runCommandWithOutput(diffCmd)
if err != nil {
t.Fatalf("failed to run diff: %s, %v", out, err)
}
deleteContainer(cleanCID)
expected := map[string]bool{
@ -85,7 +97,7 @@ func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) {
for _, line := range strings.Split(out, "\n") {
if line != "" && !expected[line] {
t.Errorf("'%s' is shown in the diff but shouldn't", line)
t.Errorf("%q is shown in the diff but shouldn't", line)
}
}

View File

@ -16,12 +16,12 @@ import (
)
func TestEventsUntag(t *testing.T) {
out, _, _ := cmd(t, "images", "-q")
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
cmd(t, "tag", image, "utest:tag1")
cmd(t, "tag", image, "utest:tag2")
cmd(t, "rmi", "utest:tag1")
cmd(t, "rmi", "utest:tag2")
dockerCmd(t, "tag", image, "utest:tag1")
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)
events := strings.Split(out, "\n")
@ -38,11 +38,15 @@ func TestEventsUntag(t *testing.T) {
}
func TestEventsPause(t *testing.T) {
out, _, _ := cmd(t, "images", "-q")
name := "testeventpause"
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
cmd(t, "run", "-d", "--name", "testeventpause", image, "sleep", "2")
cmd(t, "pause", "testeventpause")
cmd(t, "unpause", "testeventpause")
dockerCmd(t, "run", "-d", "--name", name, image, "sleep", "2")
dockerCmd(t, "pause", name)
dockerCmd(t, "unpause", name)
defer deleteAllContainers()
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ = runCommandWithOutput(eventsCmd)
events := strings.Split(out, "\n")
@ -57,14 +61,21 @@ func TestEventsPause(t *testing.T) {
t.Fatalf("event should be pause, not %#v", pauseEvent)
}
if unpauseEvent[len(unpauseEvent)-1] != "unpause" {
t.Fatalf("event should be pause, not %#v", unpauseEvent)
t.Fatalf("event should be unpause, not %#v", unpauseEvent)
}
waitCmd := exec.Command(dockerBinary, "wait", name)
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
logDone("events - pause/unpause is logged")
}
func TestEventsContainerFailStartDie(t *testing.T) {
out, _, _ := cmd(t, "images", "-q")
defer deleteAllContainers()
out, _, _ := dockerCmd(t, "images", "-q")
image := strings.Split(out, "\n")[0]
eventsCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testeventdie", image, "blerg")
_, _, err := runCommandWithOutput(eventsCmd)
@ -93,8 +104,9 @@ func TestEventsContainerFailStartDie(t *testing.T) {
}
func TestEventsLimit(t *testing.T) {
defer deleteAllContainers()
for i := 0; i < 30; i++ {
cmd(t, "run", "busybox", "echo", strconv.Itoa(i))
dockerCmd(t, "run", "busybox", "echo", strconv.Itoa(i))
}
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ := runCommandWithOutput(eventsCmd)
@ -107,7 +119,7 @@ func TestEventsLimit(t *testing.T) {
}
func TestEventsContainerEvents(t *testing.T) {
cmd(t, "run", "--rm", "busybox", "true")
dockerCmd(t, "run", "--rm", "busybox", "true")
eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
out, exitCode, err := runCommandWithOutput(eventsCmd)
if exitCode != 0 || err != nil {
@ -126,13 +138,13 @@ func TestEventsContainerEvents(t *testing.T) {
t.Fatalf("event should be create, not %#v", createEvent)
}
if startEvent[len(startEvent)-1] != "start" {
t.Fatalf("event should be pause, not %#v", startEvent)
t.Fatalf("event should be start, not %#v", startEvent)
}
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be pause, not %#v", dieEvent)
t.Fatalf("event should be die, not %#v", dieEvent)
}
if destroyEvent[len(destroyEvent)-1] != "destroy" {
t.Fatalf("event should be pause, not %#v", destroyEvent)
t.Fatalf("event should be destroy, not %#v", destroyEvent)
}
logDone("events - container create, start, die, destroy is logged")
@ -178,7 +190,7 @@ func TestEventsRedirectStdout(t *testing.T) {
since := time.Now().Unix()
cmd(t, "run", "busybox", "true")
dockerCmd(t, "run", "busybox", "true")
defer deleteAllContainers()
@ -215,3 +227,119 @@ func TestEventsRedirectStdout(t *testing.T) {
logDone("events - redirect stdout")
}
func TestEventsImagePull(t *testing.T) {
since := time.Now().Unix()
pullCmd := exec.Command(dockerBinary, "pull", "scratch")
if out, _, err := runCommandWithOutput(pullCmd); err != nil {
t.Fatalf("pulling the scratch image from has failed: %s, %v", out, err)
}
eventsCmd := exec.Command(dockerBinary, "events",
fmt.Sprintf("--since=%d", since),
fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ := runCommandWithOutput(eventsCmd)
events := strings.Split(strings.TrimSpace(out), "\n")
event := strings.TrimSpace(events[len(events)-1])
if !strings.HasSuffix(event, "scratch:latest: pull") {
t.Fatalf("Missing pull event - got:%q", event)
}
logDone("events - image pull is logged")
}
func TestEventsImageImport(t *testing.T) {
since := time.Now().Unix()
defer deleteImages("cirros")
server, err := fileServer(map[string]string{
"/cirros.tar.gz": "/cirros.tar.gz",
})
if err != nil {
t.Fatal(err)
}
defer server.Close()
fileURL := fmt.Sprintf("%s/cirros.tar.gz", server.URL)
importCmd := exec.Command(dockerBinary, "import", fileURL, "cirros")
out, _, err := runCommandWithOutput(importCmd)
if err != nil {
t.Errorf("import failed with errors: %v, output: %q", err, out)
}
eventsCmd := exec.Command(dockerBinary, "events",
fmt.Sprintf("--since=%d", since),
fmt.Sprintf("--until=%d", time.Now().Unix()))
out, _, _ = runCommandWithOutput(eventsCmd)
events := strings.Split(strings.TrimSpace(out), "\n")
event := strings.TrimSpace(events[len(events)-1])
if !strings.HasSuffix(event, ": import") {
t.Fatalf("Missing pull event - got:%q", event)
}
logDone("events - image import is logged")
}
func TestEventsFilters(t *testing.T) {
since := time.Now().Unix()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
if err != nil {
t.Fatal(out, err)
}
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
if err != nil {
t.Fatal(out, err)
}
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", "event=die")
out, exitCode, err := runCommandWithOutput(eventsCmd)
if exitCode != 0 || err != nil {
t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
}
events := strings.Split(out, "\n")
events = events[:len(events)-1]
if len(events) != 2 {
t.Fatalf("Expected 2 events, got %d: %v", len(events), events)
}
dieEvent := strings.Fields(events[len(events)-1])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
dieEvent = strings.Fields(events[len(events)-2])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
eventsCmd = exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", "event=die", "--filter", "event=start")
out, exitCode, err = runCommandWithOutput(eventsCmd)
if exitCode != 0 || err != nil {
t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
}
events = strings.Split(out, "\n")
events = events[:len(events)-1]
if len(events) != 4 {
t.Fatalf("Expected 4 events, got %d: %v", len(events), events)
}
startEvent := strings.Fields(events[len(events)-4])
if startEvent[len(startEvent)-1] != "start" {
t.Fatalf("event should be start, not %#v", startEvent)
}
dieEvent = strings.Fields(events[len(events)-3])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
startEvent = strings.Fields(events[len(events)-2])
if startEvent[len(startEvent)-1] != "start" {
t.Fatalf("event should be start, not %#v", startEvent)
}
dieEvent = strings.Fields(events[len(events)-1])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
logDone("events - filters")
}

View File

@ -2,6 +2,7 @@ package main
import (
"bufio"
"os"
"os/exec"
"strings"
"testing"
@ -10,13 +11,15 @@ import (
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)
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
t.Fatal(out, err)
}
execCmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/tmp/file")
out, _, err = runCommandWithOutput(execCmd)
errorOut(err, t, out)
out, _, err := runCommandWithOutput(execCmd)
if err != nil {
t.Fatal(out, err)
}
out = strings.Trim(out, "\r\n")
@ -29,10 +32,51 @@ func TestExec(t *testing.T) {
logDone("exec - basic test")
}
func TestExecInteractiveStdinClose(t *testing.T) {
defer deleteAllContainers()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "busybox", "/bin/cat"))
if err != nil {
t.Fatal(err)
}
contId := strings.TrimSpace(out)
returnchan := make(chan struct{})
go func() {
var err error
cmd := exec.Command(dockerBinary, "exec", "-i", contId, "/bin/ls", "/")
cmd.Stdin = os.Stdin
if err != nil {
t.Fatal(err)
}
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err, out)
}
if string(out) == "" {
t.Fatalf("Output was empty, likely blocked by standard input")
}
returnchan <- struct{}{}
}()
select {
case <-returnchan:
case <-time.After(10 * time.Second):
t.Fatal("timed out running docker exec")
}
logDone("exec - interactive mode closes stdin after execution")
}
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)
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
t.Fatal(out, err)
}
execCmd := exec.Command(dockerBinary, "exec", "-i", "testing", "sh")
stdin, err := execCmd.StdinPipe()
@ -84,17 +128,22 @@ func TestExecInteractive(t *testing.T) {
func TestExecAfterContainerRestart(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "exec", cleanedContainerID, "echo", "hello")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
outStr := strings.TrimSpace(out)
if outStr != "hello" {
@ -137,3 +186,168 @@ func TestExecAfterDaemonRestart(t *testing.T) {
logDone("exec - exec running container after daemon restart")
}
// Regresssion test for #9155, #9044
func TestExecEnv(t *testing.T) {
defer deleteAllContainers()
runCmd := exec.Command(dockerBinary, "run",
"-e", "LALA=value1",
"-e", "LALA=value2",
"-d", "--name", "testing", "busybox", "top")
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
t.Fatal(out, err)
}
execCmd := exec.Command(dockerBinary, "exec", "testing", "env")
out, _, err := runCommandWithOutput(execCmd)
if err != nil {
t.Fatal(out, err)
}
if strings.Contains(out, "LALA=value1") ||
!strings.Contains(out, "LALA=value2") ||
!strings.Contains(out, "HOME=/root") {
t.Errorf("exec env(%q), expect %q, %q", out, "LALA=value2", "HOME=/root")
}
logDone("exec - exec inherits correct env")
}
func TestExecExitStatus(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "top", "busybox", "top")
if out, _, _, err := runCommandWithStdoutStderr(runCmd); err != nil {
t.Fatal(out, err)
}
// Test normal (non-detached) case first
cmd := exec.Command(dockerBinary, "exec", "top", "sh", "-c", "exit 23")
ec, _ := runCommand(cmd)
if ec != 23 {
t.Fatalf("Should have had an ExitCode of 23, not: %d", ec)
}
logDone("exec - exec non-zero ExitStatus")
}
func TestExecPausedContainer(t *testing.T) {
defer deleteAllContainers()
defer unpauseAllContainers()
runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal(out, err)
}
ContainerID := stripTrailingCharacters(out)
pausedCmd := exec.Command(dockerBinary, "pause", "testing")
out, _, _, err = runCommandWithStdoutStderr(pausedCmd)
if err != nil {
t.Fatal(out, err)
}
execCmd := exec.Command(dockerBinary, "exec", "-i", "-t", ContainerID, "echo", "hello")
out, _, err = runCommandWithOutput(execCmd)
if err == nil {
t.Fatal("container should fail to exec new command if it is paused")
}
expected := ContainerID + " is paused, unpause the container before exec"
if !strings.Contains(out, expected) {
t.Fatal("container should not exec new command if it is paused")
}
logDone("exec - exec should not exec a pause container")
}
// regression test for #9476
func TestExecTtyCloseStdin(t *testing.T) {
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "-d", "-it", "--name", "exec_tty_stdin", "busybox")
if out, _, err := runCommandWithOutput(cmd); err != nil {
t.Fatal(out, err)
}
cmd = exec.Command(dockerBinary, "exec", "-i", "exec_tty_stdin", "cat")
stdinRw, err := cmd.StdinPipe()
if err != nil {
t.Fatal(err)
}
stdinRw.Write([]byte("test"))
stdinRw.Close()
if out, _, err := runCommandWithOutput(cmd); err != nil {
t.Fatal(out, err)
}
cmd = exec.Command(dockerBinary, "top", "exec_tty_stdin")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(out, err)
}
outArr := strings.Split(out, "\n")
if len(outArr) > 3 || strings.Contains(out, "nsenter-exec") {
// This is the really bad part
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rm", "-f", "exec_tty_stdin")); err != nil {
t.Fatal(out, err)
}
t.Fatalf("exec process left running\n\t %s", out)
}
logDone("exec - stdin is closed properly with tty enabled")
}
func TestExecTtyWithoutStdin(t *testing.T) {
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatalf("failed to start container: %v (%v)", out, err)
}
id := strings.TrimSpace(out)
if err := waitRun(id); err != nil {
t.Fatal(err)
}
defer func() {
cmd := exec.Command(dockerBinary, "kill", id)
if out, _, err := runCommandWithOutput(cmd); err != nil {
t.Fatalf("failed to kill container: %v (%v)", out, err)
}
}()
done := make(chan struct{})
go func() {
defer close(done)
cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
if _, err := cmd.StdinPipe(); err != nil {
t.Fatal(err)
}
expected := "cannot enable tty mode"
if out, _, err := runCommandWithOutput(cmd); err == nil {
t.Fatal("exec should have failed")
} else if !strings.Contains(out, expected) {
t.Fatal("exec failed with error %q: expected %q", out, expected)
}
}()
select {
case <-done:
case <-time.After(3 * time.Second):
t.Fatal("exec is running but should have failed")
}
logDone("exec - forbid piped stdin to tty enabled container")
}

View File

@ -26,19 +26,23 @@ func TestExportContainerAndImportImage(t *testing.T) {
exportCmdTemplate := `%v export %v > /tmp/testexp.tar`
exportCmdFinal := fmt.Sprintf(exportCmdTemplate, dockerBinary, cleanedContainerID)
exportCmd := exec.Command("bash", "-c", exportCmdFinal)
out, _, err = runCommandWithOutput(exportCmd)
errorOut(err, t, fmt.Sprintf("failed to export container: %v %v", out, err))
if out, _, err = runCommandWithOutput(exportCmd); err != nil {
t.Fatalf("failed to export container: %s, %v", out, err)
}
importCmdFinal := `cat /tmp/testexp.tar | docker import - repo/testexp:v1`
importCmd := exec.Command("bash", "-c", importCmdFinal)
out, _, err = runCommandWithOutput(importCmd)
errorOut(err, t, fmt.Sprintf("failed to import image: %v %v", out, err))
if err != nil {
t.Fatalf("failed to import image: %s, %v", out, err)
}
cleanedImageID := stripTrailingCharacters(out)
inspectCmd = exec.Command(dockerBinary, "inspect", cleanedImageID)
out, _, err = runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("output should've been an image id: %v %v", out, err))
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("output should've been an image id: %s, %v", out, err)
}
deleteContainer(cleanedContainerID)
deleteImages("repo/testexp:v1")

View File

@ -46,9 +46,8 @@ RUN echo "Z"`,
}
out, exitCode, err := runCommandWithOutput(exec.Command(dockerBinary, "history", "testbuildhistory"))
errorOut(err, t, fmt.Sprintf("image history failed: %v %v", out, err))
if err != nil || exitCode != 0 {
t.Fatal("failed to get image history")
t.Fatalf("failed to get image history: %s, %v", out, err)
}
actualValues := strings.Split(out, "\n")[1:27]

View File

@ -3,6 +3,8 @@ package main
import (
"fmt"
"os/exec"
"reflect"
"sort"
"strings"
"testing"
"time"
@ -11,7 +13,9 @@ import (
func TestImagesEnsureImageIsListed(t *testing.T) {
imagesCmd := exec.Command(dockerBinary, "images")
out, _, err := runCommandWithOutput(imagesCmd)
errorOut(err, t, fmt.Sprintf("listing images failed with errors: %v", err))
if err != nil {
t.Fatalf("listing images failed with errors: %s, %v", out, err)
}
if !strings.Contains(out, "busybox") {
t.Fatal("images should've listed busybox")
@ -46,7 +50,9 @@ func TestImagesOrderedByCreationDate(t *testing.T) {
}
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "images", "-q", "--no-trunc"))
errorOut(err, t, fmt.Sprintf("listing images failed with errors: %v", err))
if err != nil {
t.Fatalf("listing images failed with errors: %s, %v", out, err)
}
imgs := strings.Split(out, "\n")
if imgs[0] != id3 {
t.Fatalf("First image must be %s, got %s", id3, imgs[0])
@ -60,3 +66,59 @@ func TestImagesOrderedByCreationDate(t *testing.T) {
logDone("images - ordering by creation date")
}
func TestImagesErrorWithInvalidFilterNameTest(t *testing.T) {
imagesCmd := exec.Command(dockerBinary, "images", "-f", "FOO=123")
out, _, err := runCommandWithOutput(imagesCmd)
if !strings.Contains(out, "Invalid filter") {
t.Fatalf("error should occur when listing images with invalid filter name FOO, %s, %v", out, err)
}
logDone("images - invalid filter name check working")
}
func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
imageName := "images_filter_test"
defer deleteAllContainers()
defer deleteImages(imageName)
buildImage(imageName,
`FROM scratch
RUN touch /test/foo
RUN touch /test/bar
RUN touch /test/baz`, true)
filters := []string{
"dangling=true",
"Dangling=true",
" dangling=true",
"dangling=true ",
"dangling = true",
}
imageListings := make([][]string, 5, 5)
for idx, filter := range filters {
cmd := exec.Command(dockerBinary, "images", "-f", filter)
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
listing := strings.Split(out, "\n")
sort.Strings(listing)
imageListings[idx] = listing
}
for idx, listing := range imageListings {
if idx < 4 && !reflect.DeepEqual(listing, imageListings[idx+1]) {
for idx, errListing := range imageListings {
fmt.Printf("out %d", idx)
for _, image := range errListing {
fmt.Print(image)
}
fmt.Print("")
}
t.Fatalf("All output must be the same")
}
}
logDone("images - white space trimming and lower casing")
}

View File

@ -16,7 +16,7 @@ func TestImportDisplay(t *testing.T) {
}
defer server.Close()
fileURL := fmt.Sprintf("%s/cirros.tar.gz", server.URL)
importCmd := exec.Command(dockerBinary, "import", fileURL)
importCmd := exec.Command(dockerBinary, "import", fileURL, "cirros")
out, _, err := runCommandWithOutput(importCmd)
if err != nil {
t.Errorf("import failed with errors: %v, output: %q", err, out)
@ -26,5 +26,7 @@ func TestImportDisplay(t *testing.T) {
t.Fatalf("display is messed up: %d '\\n' instead of 2", n)
}
deleteImages("cirros")
logDone("import - cirros was imported and display is fine")
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -11,10 +10,8 @@ import (
func TestInfoEnsureSucceeds(t *testing.T) {
versionCmd := exec.Command(dockerBinary, "info")
out, exitCode, err := runCommandWithOutput(versionCmd)
errorOut(err, t, fmt.Sprintf("encountered error while running docker info: %v", err))
if err != nil || exitCode != 0 {
t.Fatal("failed to execute docker info")
t.Fatalf("failed to execute docker info: %s, %v", out, err)
}
stringsToCheck := []string{"Containers:", "Execution Driver:", "Kernel Version:"}

View File

@ -10,13 +10,14 @@ func TestInspectImage(t *testing.T) {
imageTest := "scratch"
imageTestID := "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"
imagesCmd := exec.Command(dockerBinary, "inspect", "--format='{{.Id}}'", imageTest)
out, exitCode, err := runCommandWithOutput(imagesCmd)
if exitCode != 0 || err != nil {
t.Fatalf("failed to inspect image")
t.Fatalf("failed to inspect image: %s, %v", out, err)
}
if id := strings.TrimSuffix(out, "\n"); id != imageTestID {
t.Fatalf("Expected id: %s for image: %s but received id: %s", imageTestID, imageTest, id)
}
logDone("inspect - inspect an image")
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -10,21 +9,27 @@ import (
func TestKillContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err))
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("out should've been a container id: %s, %v", out, err)
}
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
out, _, err = runCommandWithOutput(killCmd)
errorOut(err, t, fmt.Sprintf("failed to kill container: %v %v", out, err))
if out, _, err = runCommandWithOutput(killCmd); err != nil {
t.Fatalf("failed to kill container: %s, %v", out, err)
}
listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q")
out, _, err = runCommandWithOutput(listRunningContainersCmd)
errorOut(err, t, fmt.Sprintf("failed to list running containers: %v", err))
if err != nil {
t.Fatalf("failed to list running containers: %s, %v", out, err)
}
if strings.Contains(out, cleanedContainerID) {
t.Fatal("killed container is still running")
@ -38,21 +43,27 @@ func TestKillContainer(t *testing.T) {
func TestKillDifferentUserContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-u", "daemon", "-d", "busybox", "sh", "-c", "sleep 10")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err))
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("out should've been a container id: %s, %v", out, err)
}
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
out, _, err = runCommandWithOutput(killCmd)
errorOut(err, t, fmt.Sprintf("failed to kill container: %v %v", out, err))
if out, _, err = runCommandWithOutput(killCmd); err != nil {
t.Fatalf("failed to kill container: %s, %v", out, err)
}
listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q")
out, _, err = runCommandWithOutput(listRunningContainersCmd)
errorOut(err, t, fmt.Sprintf("failed to list running containers: %v", err))
if err != nil {
t.Fatalf("failed to list running containers: %s, %v", out, err)
}
if strings.Contains(out, cleanedContainerID) {
t.Fatal("killed container is still running")

View File

@ -1,12 +1,13 @@
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"reflect"
"strings"
"testing"
"time"
"github.com/docker/docker/pkg/iptables"
)
@ -14,7 +15,9 @@ import (
func TestLinksEtcHostsRegularFile(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !strings.HasPrefix(out, "-") {
t.Errorf("/etc/hosts should be a regular file")
@ -28,7 +31,9 @@ func TestLinksEtcHostsRegularFile(t *testing.T) {
func TestLinksEtcHostsContentMatch(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hosts")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
hosts, err := ioutil.ReadFile("/etc/hosts")
if os.IsNotExist(err) {
@ -51,7 +56,7 @@ func TestLinksPingUnlinkedContainers(t *testing.T) {
if exitCode == 0 {
t.Fatal("run ping did not fail")
} else if exitCode != 1 {
errorOut(err, t, fmt.Sprintf("run ping failed with errors: %v", err))
t.Fatalf("run ping failed with errors: %v", err)
}
logDone("links - ping unlinked container")
@ -59,21 +64,21 @@ func TestLinksPingUnlinkedContainers(t *testing.T) {
func TestLinksPingLinkedContainers(t *testing.T) {
var out string
out, _, _ = cmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
out, _, _ = dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
idA := stripTrailingCharacters(out)
out, _, _ = cmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
out, _, _ = dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
idB := stripTrailingCharacters(out)
cmd(t, "run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
cmd(t, "kill", idA)
cmd(t, "kill", idB)
dockerCmd(t, "run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
dockerCmd(t, "kill", idA)
dockerCmd(t, "kill", idB)
deleteAllContainers()
logDone("links - ping linked container")
}
func TestLinksIpTablesRulesWhenLinkAndUnlink(t *testing.T) {
cmd(t, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "sleep", "10")
cmd(t, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "sleep", "10")
childIP := findContainerIP(t, "child")
parentIP := findContainerIP(t, "parent")
@ -84,13 +89,13 @@ func TestLinksIpTablesRulesWhenLinkAndUnlink(t *testing.T) {
t.Fatal("Iptables rules not found")
}
cmd(t, "rm", "--link", "parent/http")
dockerCmd(t, "rm", "--link", "parent/http")
if iptables.Exists(sourceRule...) || iptables.Exists(destinationRule...) {
t.Fatal("Iptables rules should be removed when unlink")
}
cmd(t, "kill", "child")
cmd(t, "kill", "parent")
dockerCmd(t, "kill", "child")
dockerCmd(t, "kill", "parent")
deleteAllContainers()
logDone("link - verify iptables when link and unlink")
@ -102,9 +107,9 @@ func TestLinksInspectLinksStarted(t *testing.T) {
result []string
)
defer deleteAllContainers()
cmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
cmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
cmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sleep", "10")
links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
if err != nil {
t.Fatal(err)
@ -117,7 +122,7 @@ func TestLinksInspectLinksStarted(t *testing.T) {
output := convertSliceOfStringsToMap(result)
equal := deepEqual(expected, output)
equal := reflect.DeepEqual(output, expected)
if !equal {
t.Fatalf("Links %s, expected %s", result, expected)
@ -131,9 +136,9 @@ func TestLinksInspectLinksStopped(t *testing.T) {
result []string
)
defer deleteAllContainers()
cmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
cmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
cmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
if err != nil {
t.Fatal(err)
@ -146,7 +151,7 @@ func TestLinksInspectLinksStopped(t *testing.T) {
output := convertSliceOfStringsToMap(result)
equal := deepEqual(expected, output)
equal := reflect.DeepEqual(output, expected)
if !equal {
t.Fatalf("Links %s, but expected %s", result, expected)
@ -154,3 +159,75 @@ func TestLinksInspectLinksStopped(t *testing.T) {
logDone("link - links in stopped container inspect")
}
func TestLinksNotStartedParentNotFail(t *testing.T) {
defer deleteAllContainers()
runCmd := exec.Command(dockerBinary, "create", "--name=first", "busybox", "top")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "create", "--name=second", "--link=first:first", "busybox", "top")
out, _, _, err = runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "start", "first")
out, _, _, err = runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatal(out, err)
}
logDone("link - container start not failing on updating stopped parent links")
}
func TestLinksHostsFilesInject(t *testing.T) {
defer deleteAllContainers()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "one", "busybox", "top"))
if err != nil {
t.Fatal(err, out)
}
idOne := strings.TrimSpace(out)
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "two", "--link", "one:onetwo", "busybox", "top"))
if err != nil {
t.Fatal(err, out)
}
idTwo := strings.TrimSpace(out)
time.Sleep(1 * time.Second)
contentOne, err := readContainerFile(idOne, "hosts")
if err != nil {
t.Fatal(err, string(contentOne))
}
contentTwo, err := readContainerFile(idTwo, "hosts")
if err != nil {
t.Fatal(err, string(contentTwo))
}
if !strings.Contains(string(contentTwo), "onetwo") {
t.Fatal("Host is not present in updated hosts file", string(contentTwo))
}
logDone("link - ensure containers hosts files are updated with the link alias.")
}
func TestLinksNetworkHostContainer(t *testing.T) {
defer deleteAllContainers()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top"))
if err != nil {
t.Fatal(err, out)
}
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true"))
if err == nil || !strings.Contains(out, "--net=host can't be used with links. This would result in undefined behavior.") {
t.Fatalf("Running container linking to a container with --net host should have failed: %s", out)
}
logDone("link - error thrown when linking to container with --net host")
}

View File

@ -0,0 +1,35 @@
package main
import (
"bytes"
"io"
"os"
"os/exec"
"testing"
)
func TestLoginWithoutTTY(t *testing.T) {
cmd := exec.Command(dockerBinary, "login")
// setup STDOUT and STDERR so that we see any output and errors in our console
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
// create a buffer with text then a new line as a return
buf := bytes.NewBuffer([]byte("buffer test string \n"))
// use a pipe for stdin and manually copy the data so that
// the process does not get the TTY
in, err := cmd.StdinPipe()
if err != nil {
t.Fatal(err)
}
// copy the bytes into the commands stdin along with a new line
go io.Copy(in, buf)
// run the command and block until it's done
if err := cmd.Run(); err == nil {
t.Fatal("Expected non nil err when loginning in & TTY not available")
}
logDone("login - login without TTY")
}

View File

@ -16,14 +16,18 @@ func TestLogsContainerSmallerThanPage(t *testing.T) {
testLen := 32767
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
if len(out) != testLen+1 {
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
@ -39,14 +43,18 @@ func TestLogsContainerBiggerThanPage(t *testing.T) {
testLen := 32768
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
if len(out) != testLen+1 {
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
@ -62,14 +70,18 @@ func TestLogsContainerMuchBiggerThanPage(t *testing.T) {
testLen := 33000
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo -n =; done; echo", testLen))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
if len(out) != testLen+1 {
t.Fatalf("Expected log length of %d, received %d\n", testLen+1, len(out))
@ -85,14 +97,18 @@ func TestLogsTimestamps(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", "-t", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
lines := strings.Split(out, "\n")
@ -124,14 +140,18 @@ func TestLogsSeparateStderr(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
stdout, stderr, _, err := runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
if stdout != "" {
t.Fatalf("Expected empty stdout stream, got %v", stdout)
@ -152,14 +172,18 @@ func TestLogsStderrInStdout(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "busybox", "sh", "-c", fmt.Sprintf("echo %s 1>&2", msg))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", cleanedContainerID)
stdout, stderr, _, err := runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
if stderr != "" {
t.Fatalf("Expected empty stderr stream, got %v", stdout)
@ -180,14 +204,18 @@ func TestLogsTail(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen))
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
logsCmd := exec.Command(dockerBinary, "logs", "--tail", "5", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
lines := strings.Split(out, "\n")
@ -197,7 +225,9 @@ func TestLogsTail(t *testing.T) {
logsCmd = exec.Command(dockerBinary, "logs", "--tail", "all", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
lines = strings.Split(out, "\n")
@ -207,7 +237,9 @@ func TestLogsTail(t *testing.T) {
logsCmd = exec.Command(dockerBinary, "logs", "--tail", "random", cleanedContainerID)
out, _, _, err = runCommandWithStdoutStderr(logsCmd)
errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to log container: %s, %v", out, err)
}
lines = strings.Split(out, "\n")
@ -223,7 +255,9 @@ func TestLogsFollowStopped(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
@ -250,3 +284,54 @@ func TestLogsFollowStopped(t *testing.T) {
deleteContainer(cleanedContainerID)
logDone("logs - logs follow stopped container")
}
// Regression test for #8832
func TestLogsFollowSlowStdoutConsumer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", `usleep 200000;yes X | head -c 200000`)
out, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatalf("run failed with errors: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
stopSlowRead := make(chan bool)
go func() {
exec.Command(dockerBinary, "wait", cleanedContainerID).Run()
stopSlowRead <- true
}()
logCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID)
stdout, err := logCmd.StdoutPipe()
if err != nil {
t.Fatal(err)
}
if err := logCmd.Start(); err != nil {
t.Fatal(err)
}
// First read slowly
bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
if err != nil {
t.Fatal(err)
}
// After the container has finished we can continue reading fast
bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil)
if err != nil {
t.Fatal(err)
}
actual := bytes1 + bytes2
expected := 200000
if actual != expected {
t.Fatalf("Invalid bytes read: %d, expected %d", actual, expected)
}
logDone("logs - follow slow consumer")
}

View File

@ -11,7 +11,7 @@ import (
func TestNetworkNat(t *testing.T) {
iface, err := net.InterfaceByName("eth0")
if err != nil {
t.Skip("Test not running with `make test`. Interface eth0 not found: %s", err)
t.Skipf("Test not running with `make test`. Interface eth0 not found: %s", err)
}
ifaceAddrs, err := iface.Addrs()
@ -26,17 +26,24 @@ func TestNetworkNat(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-dt", "-p", "8080:8080", "busybox", "nc", "-lp", "8080")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("run1 failed with errors: %v (%s)", err, out))
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "run", "busybox", "sh", "-c", fmt.Sprintf("echo hello world | nc -w 30 %s 8080", ifaceIP))
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("run2 failed with errors: %v (%s)", err, out))
if err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to retrieve logs for container: %v %v", cleanedContainerID, err))
if err != nil {
t.Fatalf("failed to retrieve logs for container: %s, %v", out, err)
}
out = strings.Trim(out, "\r\n")
if expected := "hello world"; out != expected {
@ -44,8 +51,9 @@ func TestNetworkNat(t *testing.T) {
}
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
out, _, err = runCommandWithOutput(killCmd)
errorOut(err, t, fmt.Sprintf("failed to kill container: %v %v", out, err))
if out, _, err = runCommandWithOutput(killCmd); err != nil {
t.Fatalf("failed to kill container: %s, %v", out, err)
}
deleteAllContainers()
logDone("network - make sure nat works through the host")

View File

@ -11,12 +11,16 @@ func TestPortList(t *testing.T) {
// one port
runCmd := exec.Command(dockerBinary, "run", "-d", "-p", "9876:80", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
firstID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", firstID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
t.Error("Port list is not correct")
@ -24,14 +28,17 @@ func TestPortList(t *testing.T) {
runCmd = exec.Command(dockerBinary, "port", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{"80/tcp -> 0.0.0.0:9876"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "rm", "-f", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
// three port
runCmd = exec.Command(dockerBinary, "run", "-d",
@ -40,12 +47,16 @@ func TestPortList(t *testing.T) {
"-p", "9878:82",
"busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
ID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", ID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
t.Error("Port list is not correct")
@ -53,7 +64,9 @@ func TestPortList(t *testing.T) {
runCmd = exec.Command(dockerBinary, "port", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{
"80/tcp -> 0.0.0.0:9876",
@ -63,7 +76,9 @@ func TestPortList(t *testing.T) {
}
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
// more and one port mapped to the same container port
runCmd = exec.Command(dockerBinary, "run", "-d",
@ -73,12 +88,16 @@ func TestPortList(t *testing.T) {
"-p", "9878:82",
"busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
ID = stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", ID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"}) {
t.Error("Port list is not correct")
@ -86,7 +105,9 @@ func TestPortList(t *testing.T) {
runCmd = exec.Command(dockerBinary, "port", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertPortList(t, out, []string{
"80/tcp -> 0.0.0.0:9876",
@ -96,8 +117,9 @@ func TestPortList(t *testing.T) {
t.Error("Port list is not correct\n", out)
}
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
deleteAllContainers()

View File

@ -10,34 +10,45 @@ import (
func TestPsListContainers(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
firstID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
secondID := stripTrailingCharacters(out)
// not long running
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
thirdID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
fourthID := stripTrailingCharacters(out)
// make sure third one is not running
runCmd = exec.Command(dockerBinary, "wait", thirdID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
// all
runCmd = exec.Command(dockerBinary, "ps", "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}) {
t.Error("Container list is not in the correct order")
@ -46,7 +57,9 @@ func TestPsListContainers(t *testing.T) {
// running
runCmd = exec.Command(dockerBinary, "ps")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, []string{fourthID, secondID, firstID}) {
t.Error("Container list is not in the correct order")
@ -57,7 +70,9 @@ func TestPsListContainers(t *testing.T) {
// limit
runCmd = exec.Command(dockerBinary, "ps", "-n=2", "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected := []string{fourthID, thirdID}
if !assertContainerList(out, expected) {
@ -66,7 +81,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "-n=2")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -75,7 +92,9 @@ func TestPsListContainers(t *testing.T) {
// since
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{fourthID, thirdID, secondID}
if !assertContainerList(out, expected) {
@ -84,7 +103,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -93,7 +114,9 @@ func TestPsListContainers(t *testing.T) {
// before
runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID, "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{secondID, firstID}
if !assertContainerList(out, expected) {
@ -102,7 +125,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -111,7 +136,9 @@ func TestPsListContainers(t *testing.T) {
// since & before
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{thirdID, secondID}
if !assertContainerList(out, expected) {
@ -120,7 +147,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
}
@ -128,7 +157,9 @@ func TestPsListContainers(t *testing.T) {
// since & limit
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2", "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{fourthID, thirdID}
if !assertContainerList(out, expected) {
@ -137,7 +168,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -146,7 +179,9 @@ func TestPsListContainers(t *testing.T) {
// before & limit
runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1", "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{thirdID}
if !assertContainerList(out, expected) {
@ -155,7 +190,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -164,7 +201,9 @@ func TestPsListContainers(t *testing.T) {
// since & before & limit
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1", "-a")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
expected = []string{thirdID}
if !assertContainerList(out, expected) {
@ -173,7 +212,9 @@ func TestPsListContainers(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if !assertContainerList(out, expected) {
t.Error("Container list is not in the correct order")
@ -205,7 +246,9 @@ func TestPsListContainersSize(t *testing.T) {
name := "test_size"
runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
id, err := getIDByName(name)
if err != nil {
t.Fatal(err)
@ -222,7 +265,9 @@ func TestPsListContainersSize(t *testing.T) {
case <-time.After(3 * time.Second):
t.Fatalf("Calling \"docker ps -s\" timed out!")
}
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
lines := strings.Split(strings.Trim(out, "\n "), "\n")
sizeIndex := strings.Index(lines[0], "SIZE")
idIndex := strings.Index(lines[0], "CONTAINER ID")
@ -247,24 +292,31 @@ func TestPsListContainersFilterStatus(t *testing.T) {
// start exited container
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
firstID := stripTrailingCharacters(out)
// make sure the exited cintainer is not running
runCmd = exec.Command(dockerBinary, "wait", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
// start running container
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 360")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
secondID := stripTrailingCharacters(out)
// filter containers by exited
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=exited")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
containerOut := strings.TrimSpace(out)
if containerOut != firstID[:12] {
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
@ -272,7 +324,9 @@ func TestPsListContainersFilterStatus(t *testing.T) {
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=running")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
containerOut = strings.TrimSpace(out)
if containerOut != secondID[:12] {
t.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out)
@ -283,6 +337,66 @@ func TestPsListContainersFilterStatus(t *testing.T) {
logDone("ps - test ps filter status")
}
func TestPsListContainersFilterID(t *testing.T) {
// start container
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal(out, err)
}
firstID := stripTrailingCharacters(out)
// start another container
runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 360")
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
// filter containers by id
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=id="+firstID)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
containerOut := strings.TrimSpace(out)
if containerOut != firstID[:12] {
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
}
deleteAllContainers()
logDone("ps - test ps filter id")
}
func TestPsListContainersFilterName(t *testing.T) {
// start container
runCmd := exec.Command(dockerBinary, "run", "-d", "--name=a_name_to_match", "busybox")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal(out, err)
}
firstID := stripTrailingCharacters(out)
// start another container
runCmd = exec.Command(dockerBinary, "run", "-d", "--name=b_name_to_match", "busybox", "sh", "-c", "sleep 360")
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
// filter containers by name
runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=name=a_name_to_match")
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
containerOut := strings.TrimSpace(out)
if containerOut != firstID[:12] {
t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
}
deleteAllContainers()
logDone("ps - test ps filter name")
}
func TestPsListContainersFilterExited(t *testing.T) {
deleteAllContainers()
defer deleteAllContainers()

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"testing"
)
@ -11,11 +10,8 @@ import (
// pulling an image from the central registry should work
func TestPullImageFromCentralRegistry(t *testing.T) {
pullCmd := exec.Command(dockerBinary, "pull", "scratch")
out, exitCode, err := runCommandWithOutput(pullCmd)
errorOut(err, t, fmt.Sprintf("%s %s", out, err))
if err != nil || exitCode != 0 {
t.Fatal("pulling the scratch image from the registry has failed")
if out, _, err := runCommandWithOutput(pullCmd); err != nil {
t.Fatalf("pulling the scratch image from the registry has failed: %s, %v", out, err)
}
logDone("pull - pull scratch")
}
@ -23,10 +19,8 @@ func TestPullImageFromCentralRegistry(t *testing.T) {
// pulling a non-existing image from the central registry should return a non-zero exit code
func TestPullNonExistingImage(t *testing.T) {
pullCmd := exec.Command(dockerBinary, "pull", "fooblahblah1234")
_, exitCode, err := runCommandWithOutput(pullCmd)
if err == nil || exitCode == 0 {
t.Fatal("expected non-zero exit status when pulling non-existing image")
if out, _, err := runCommandWithOutput(pullCmd); err == nil {
t.Fatalf("expected non-zero exit status when pulling non-existing image: %s", out)
}
logDone("pull - pull fooblahblah1234 (non-existing image)")
}

View File

@ -15,22 +15,17 @@ func TestPushBusyboxImage(t *testing.T) {
// tag the image to upload it tot he private registry
repoName := fmt.Sprintf("%v/busybox", privateRegistryURL)
tagCmd := exec.Command(dockerBinary, "tag", "busybox", repoName)
out, exitCode, err := runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("%v %v", out, err))
if err != nil || exitCode != 0 {
t.Fatal("image tagging failed")
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatalf("image tagging failed: %s, %v", out, err)
}
pushCmd := exec.Command(dockerBinary, "push", repoName)
out, exitCode, err = runCommandWithOutput(pushCmd)
errorOut(err, t, fmt.Sprintf("%v %v", out, err))
if out, _, err := runCommandWithOutput(pushCmd); err != nil {
t.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err)
}
deleteImages(repoName)
if err != nil || exitCode != 0 {
t.Fatal("pushing the image to the private registry has failed")
}
logDone("push - push busybox to private registry")
}
@ -39,10 +34,8 @@ func TestPushUnprefixedRepo(t *testing.T) {
// skip this test until we're able to use a registry
t.Skip()
pushCmd := exec.Command(dockerBinary, "push", "busybox")
_, exitCode, err := runCommandWithOutput(pushCmd)
if err == nil || exitCode == 0 {
t.Fatal("pushing an unprefixed repo didn't result in a non-zero exit status")
if out, _, err := runCommandWithOutput(pushCmd); err == nil {
t.Fatalf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out)
}
logDone("push - push unprefixed busybox repo --> must fail")
}

View File

@ -10,29 +10,37 @@ import (
func TestRestartStoppedContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "foobar")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out != "foobar\n" {
t.Errorf("container should've printed 'foobar'")
}
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out != "foobar\nfoobar\n" {
t.Errorf("container should've printed 'foobar' twice")
@ -46,7 +54,9 @@ func TestRestartStoppedContainer(t *testing.T) {
func TestRestartRunningContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "echo foobar && sleep 30 && echo 'should not print this'")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
@ -54,19 +64,24 @@ func TestRestartRunningContainer(t *testing.T) {
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out != "foobar\n" {
t.Errorf("container should've printed 'foobar'")
}
runCmd = exec.Command(dockerBinary, "restart", "-t", "1", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "logs", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
time.Sleep(1 * time.Second)
@ -83,13 +98,17 @@ func TestRestartRunningContainer(t *testing.T) {
func TestRestartWithVolumes(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "-v", "/test", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ len .Volumes }}", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out = strings.Trim(out, " \n\r"); out != "1" {
t.Errorf("expect 1 volume received %s", out)
@ -97,15 +116,20 @@ func TestRestartWithVolumes(t *testing.T) {
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ .Volumes }}", cleanedContainerID)
volumes, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, volumes)
if err != nil {
t.Fatal(volumes, err)
}
runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatal(out, err)
}
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ len .Volumes }}", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
if out = strings.Trim(out, " \n\r"); out != "1" {
t.Errorf("expect 1 volume after restart received %s", out)
@ -113,7 +137,9 @@ func TestRestartWithVolumes(t *testing.T) {
runCmd = exec.Command(dockerBinary, "inspect", "--format", "{{ .Volumes }}", cleanedContainerID)
volumesAfterRestart, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, volumesAfterRestart)
if err != nil {
t.Fatal(volumesAfterRestart, err)
}
if volumes != volumesAfterRestart {
volumes = strings.Trim(volumes, " \n\r")

View File

@ -102,10 +102,11 @@ func TestRmContainerOrphaning(t *testing.T) {
t.Fatalf("%v: %s", err, out)
}
if !strings.Contains(out, img1) {
t.Fatalf("Orphaned container (could not find '%s' in docker images): %s", img1, out)
t.Fatalf("Orphaned container (could not find %q in docker images): %s", img1, out)
}
deleteAllContainers()
deleteImages(img1)
logDone("rm - container orphaning")
}
@ -114,7 +115,7 @@ func TestRmInvalidContainer(t *testing.T) {
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rm", "unknown")); err == nil {
t.Fatal("Expected error on rm unknown container, got none")
} else if !strings.Contains(out, "failed to remove one or more containers") {
t.Fatal("Expected output to contain 'failed to remove one or more containers', got %q", out)
t.Fatalf("Expected output to contain 'failed to remove one or more containers', got %q", out)
}
logDone("rm - delete unknown container")

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -13,7 +12,9 @@ func TestRmiWithContainerFails(t *testing.T) {
// create a container
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err))
if err != nil {
t.Fatalf("failed to create a container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
@ -28,7 +29,7 @@ func TestRmiWithContainerFails(t *testing.T) {
}
// make sure it didn't delete the busybox name
images, _, _ := cmd(t, "images")
images, _, _ := dockerCmd(t, "images")
if !strings.Contains(images, "busybox") {
t.Fatalf("The name 'busybox' should not have been removed from images: %q", images)
}
@ -39,41 +40,41 @@ func TestRmiWithContainerFails(t *testing.T) {
}
func TestRmiTag(t *testing.T) {
imagesBefore, _, _ := cmd(t, "images", "-a")
cmd(t, "tag", "busybox", "utest:tag1")
cmd(t, "tag", "busybox", "utest/docker:tag2")
cmd(t, "tag", "busybox", "utest:5000/docker:tag3")
imagesBefore, _, _ := dockerCmd(t, "images", "-a")
dockerCmd(t, "tag", "busybox", "utest:tag1")
dockerCmd(t, "tag", "busybox", "utest/docker:tag2")
dockerCmd(t, "tag", "busybox", "utest:5000/docker:tag3")
{
imagesAfter, _, _ := cmd(t, "images", "-a")
if nLines(imagesAfter) != nLines(imagesBefore)+3 {
imagesAfter, _, _ := dockerCmd(t, "images", "-a")
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+3 {
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
}
}
cmd(t, "rmi", "utest/docker:tag2")
dockerCmd(t, "rmi", "utest/docker:tag2")
{
imagesAfter, _, _ := cmd(t, "images", "-a")
if nLines(imagesAfter) != nLines(imagesBefore)+2 {
imagesAfter, _, _ := dockerCmd(t, "images", "-a")
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+2 {
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
}
}
cmd(t, "rmi", "utest:5000/docker:tag3")
dockerCmd(t, "rmi", "utest:5000/docker:tag3")
{
imagesAfter, _, _ := cmd(t, "images", "-a")
if nLines(imagesAfter) != nLines(imagesBefore)+1 {
imagesAfter, _, _ := dockerCmd(t, "images", "-a")
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+1 {
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
}
}
cmd(t, "rmi", "utest:tag1")
dockerCmd(t, "rmi", "utest:tag1")
{
imagesAfter, _, _ := cmd(t, "images", "-a")
if nLines(imagesAfter) != nLines(imagesBefore)+0 {
imagesAfter, _, _ := dockerCmd(t, "images", "-a")
if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+0 {
t.Fatalf("before: %q\n\nafter: %q\n", imagesBefore, imagesAfter)
}
}
logDone("tag,rmi- tagging the same images multiple times then removing tags")
logDone("rmi - tag,rmi- tagging the same images multiple times then removing tags")
}
func TestRmiTagWithExistingContainers(t *testing.T) {
@ -98,3 +99,23 @@ func TestRmiTagWithExistingContainers(t *testing.T) {
logDone("rmi - delete tag with existing containers")
}
func TestRmiForceWithExistingContainers(t *testing.T) {
image := "busybox-clone"
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "--no-cache", "-t", image, "/docker-busybox")); err != nil {
t.Fatalf("Could not build %s: %s, %v", image, out, err)
}
if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "test-force-rmi", image, "/bin/true")); err != nil {
t.Fatalf("Could not run container: %s, %v", out, err)
}
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", "-f", image))
if err != nil {
t.Fatalf("Could not remove image %s: %s, %v", image, out, err)
}
deleteAllContainers()
logDone("rmi - force delete with existing containers")
}

View File

@ -13,11 +13,13 @@ import (
"reflect"
"regexp"
"sort"
"strconv"
"strings"
"sync"
"testing"
"time"
"github.com/docker/docker/nat"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/networkfs/resolvconf"
"github.com/kr/pty"
@ -42,7 +44,7 @@ func TestRunEchoStdout(t *testing.T) {
// "test" should be printed
func TestRunEchoStdoutWithMemoryLimit(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-m", "4m", "busybox", "echo", "test")
runCmd := exec.Command(dockerBinary, "run", "-m", "16m", "busybox", "echo", "test")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatalf("failed to run container: %v, output: %q", err, out)
@ -79,7 +81,7 @@ func TestRunEchoStdoutWitCPULimit(t *testing.T) {
// "test" should be printed
func TestRunEchoStdoutWithCPUAndMemoryLimit(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "-m", "4m", "busybox", "echo", "test")
runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "-m", "16m", "busybox", "echo", "test")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatalf("failed to run container: %v, output: %q", err, out)
@ -142,8 +144,6 @@ func TestRunPingGoogle(t *testing.T) {
t.Fatalf("failed to run container: %v, output: %q", err, out)
}
errorOut(err, t, "container should've been able to ping 8.8.8.8")
deleteAllContainers()
logDone("run - ping 8.8.8.8")
@ -153,11 +153,8 @@ func TestRunPingGoogle(t *testing.T) {
// some versions of lxc might make this test fail
func TestRunExitCodeZero(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "busybox", "true")
exitCode, err := runCommand(runCmd)
errorOut(err, t, fmt.Sprintf("%s", err))
if exitCode != 0 {
t.Errorf("container should've exited with exit code 0")
if out, _, err := runCommandWithOutput(runCmd); err != nil {
t.Errorf("container should've exited with exit code 0: %s, %v", out, err)
}
deleteAllContainers()
@ -194,26 +191,31 @@ func TestRunStdinPipe(t *testing.T) {
out = stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", out)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
if out, _, err := runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("out should've been a container id: %s %v", out, err)
}
waitCmd := exec.Command(dockerBinary, "wait", out)
_, _, err = runCommandWithOutput(waitCmd)
errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
logsCmd := exec.Command(dockerBinary, "logs", out)
containerLogs, _, err := runCommandWithOutput(logsCmd)
errorOut(err, t, fmt.Sprintf("error thrown while trying to get container logs: %s", err))
logsOut, _, err := runCommandWithOutput(logsCmd)
if err != nil {
t.Fatalf("error thrown while trying to get container logs: %s, %v", logsOut, err)
}
containerLogs = stripTrailingCharacters(containerLogs)
containerLogs := stripTrailingCharacters(logsOut)
if containerLogs != "blahblah" {
t.Errorf("logs didn't print the container's logs %s", containerLogs)
}
rmCmd := exec.Command(dockerBinary, "rm", out)
_, _, err = runCommandWithOutput(rmCmd)
errorOut(err, t, fmt.Sprintf("rm failed to remove container %s", err))
if out, _, err = runCommandWithOutput(rmCmd); err != nil {
t.Fatalf("rm failed to remove container: %s, %v", out, err)
}
deleteAllContainers()
@ -231,16 +233,20 @@ func TestRunDetachedContainerIDPrinting(t *testing.T) {
out = stripTrailingCharacters(out)
inspectCmd := exec.Command(dockerBinary, "inspect", out)
inspectOut, _, err := runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
if inspectOut, _, err := runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("out should've been a container id: %s %v", inspectOut, err)
}
waitCmd := exec.Command(dockerBinary, "wait", out)
_, _, err = runCommandWithOutput(waitCmd)
errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
if waitOut, _, err := runCommandWithOutput(waitCmd); err != nil {
t.Fatalf("error thrown while waiting for container: %s, %v", waitOut, err)
}
rmCmd := exec.Command(dockerBinary, "rm", out)
rmOut, _, err := runCommandWithOutput(rmCmd)
errorOut(err, t, "rm failed to remove container")
if err != nil {
t.Fatalf("rm failed to remove container: %s, %v", rmOut, err)
}
rmOut = stripTrailingCharacters(rmOut)
if rmOut != out {
@ -268,7 +274,9 @@ func TestRunWorkingDirectory(t *testing.T) {
runCmd = exec.Command(dockerBinary, "run", "--workdir", "/root", "busybox", "pwd")
out, _, _, err = runCommandWithStdoutStderr(runCmd)
errorOut(err, t, out)
if err != nil {
t.Fatal(out, err)
}
out = stripTrailingCharacters(out)
@ -555,7 +563,8 @@ func TestRunCreateVolumeWithSymlink(t *testing.T) {
// Tests that a volume path that has a symlink exists in a container mounting it with `--volumes-from`.
func TestRunVolumesFromSymlinkPath(t *testing.T) {
buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-volumesfromsymlinkpath", "-")
name := "docker-test-volumesfromsymlinkpath"
buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
buildCmd.Stdin = strings.NewReader(`FROM busybox
RUN mkdir /baz && ln -s /baz /foo
VOLUME ["/foo/bar"]`)
@ -565,7 +574,7 @@ func TestRunVolumesFromSymlinkPath(t *testing.T) {
t.Fatalf("could not build 'docker-test-volumesfromsymlinkpath': %v", err)
}
cmd := exec.Command(dockerBinary, "run", "--name", "test-volumesfromsymlinkpath", "docker-test-volumesfromsymlinkpath")
cmd := exec.Command(dockerBinary, "run", "--name", "test-volumesfromsymlinkpath", name)
exitCode, err := runCommand(cmd)
if err != nil || exitCode != 0 {
t.Fatalf("[run] (volume) err: %v, exitcode: %d", err, exitCode)
@ -577,8 +586,8 @@ func TestRunVolumesFromSymlinkPath(t *testing.T) {
t.Fatalf("[run] err: %v, exitcode: %d", err, exitCode)
}
deleteImages("docker-test-volumesfromsymlinkpath")
deleteAllContainers()
deleteImages(name)
logDone("run - volumes-from symlink path")
}
@ -789,7 +798,7 @@ func TestRunLoopbackWhenNetworkDisabled(t *testing.T) {
}
func TestRunNetHostNotAllowedWithLinks(t *testing.T) {
_, _, err := cmd(t, "run", "--name", "linked", "busybox", "true")
_, _, err := dockerCmd(t, "run", "--name", "linked", "busybox", "true")
cmd := exec.Command(dockerBinary, "run", "--net=host", "--link", "linked:linked", "busybox", "true")
_, _, err = runCommandWithOutput(cmd)
@ -884,6 +893,7 @@ func TestRunUnPrivilegedCanMknod(t *testing.T) {
}
func TestRunCapDropInvalid(t *testing.T) {
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "--cap-drop=CHPASS", "busybox", "ls")
out, _, err := runCommandWithOutput(cmd)
if err == nil {
@ -954,6 +964,8 @@ func TestRunCapDropALLAddMknodCannotMknod(t *testing.T) {
}
func TestRunCapAddInvalid(t *testing.T) {
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "--cap-add=CHPASS", "busybox", "ls")
out, _, err := runCommandWithOutput(cmd)
if err == nil {
@ -1183,7 +1195,7 @@ func TestRunModeHostname(t *testing.T) {
t.Fatal(err)
}
if actual := strings.Trim(out, "\r\n"); actual != hostname {
t.Fatalf("expected %q, but says: '%s'", hostname, actual)
t.Fatalf("expected %q, but says: %q", hostname, actual)
}
deleteAllContainers()
@ -1192,7 +1204,7 @@ func TestRunModeHostname(t *testing.T) {
}
func TestRunRootWorkdir(t *testing.T) {
s, _, err := cmd(t, "run", "--workdir", "/", "busybox", "pwd")
s, _, err := dockerCmd(t, "run", "--workdir", "/", "busybox", "pwd")
if err != nil {
t.Fatal(s, err)
}
@ -1206,7 +1218,7 @@ func TestRunRootWorkdir(t *testing.T) {
}
func TestRunAllowBindMountingRoot(t *testing.T) {
s, _, err := cmd(t, "run", "-v", "/:/host", "busybox", "ls", "/host")
s, _, err := dockerCmd(t, "run", "-v", "/:/host", "busybox", "ls", "/host")
if err != nil {
t.Fatal(s, err)
}
@ -1245,6 +1257,7 @@ func TestRunWithVolumesIsRecursive(t *testing.T) {
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 {
@ -1358,11 +1371,11 @@ func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
actualSearch := resolvconf.GetSearchDomains([]byte(out))
if len(actualSearch) != len(hostSearch) {
t.Fatalf("expected %q search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
t.Fatalf("expected %q search domain(s), but it has: %q", len(hostSearch), len(actualSearch))
}
for i := range actualSearch {
if actualSearch[i] != hostSearch[i] {
t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
t.Fatalf("expected %q domain, but says: %q", actualSearch[i], hostSearch[i])
}
}
@ -1374,11 +1387,11 @@ func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
actualNameservers := resolvconf.GetNameservers([]byte(out))
if len(actualNameservers) != len(hostNamservers) {
t.Fatalf("expected %q nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
t.Fatalf("expected %q nameserver(s), but it has: %q", len(hostNamservers), len(actualNameservers))
}
for i := range actualNameservers {
if actualNameservers[i] != hostNamservers[i] {
t.Fatalf("expected %q nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
t.Fatalf("expected %q nameserver, but says: %q", actualNameservers[i], hostNamservers[i])
}
}
@ -1422,7 +1435,7 @@ func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
}
for i := range actualSearch {
if actualSearch[i] != hostSearch[i] {
t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
t.Fatalf("expected %q domain, but says: %q", actualSearch[i], hostSearch[i])
}
}
@ -1605,7 +1618,7 @@ func TestRunCopyVolumeContent(t *testing.T) {
}
// Test that the content is copied from the image to the volume
cmd := exec.Command(dockerBinary, "run", "--rm", "-v", "/hello", name, "sh", "-c", "find", "/hello")
cmd := exec.Command(dockerBinary, "run", "--rm", "-v", "/hello", name, "find", "/hello")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out)
@ -1710,6 +1723,8 @@ func TestRunExitOnStdinClose(t *testing.T) {
// Test for #2267
func TestRunWriteHostsFileAndNotCommit(t *testing.T) {
defer deleteAllContainers()
name := "writehosts"
cmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo test2267 >> /etc/hosts && cat /etc/hosts")
out, _, err := runCommandWithOutput(cmd)
@ -1737,6 +1752,8 @@ func TestRunWriteHostsFileAndNotCommit(t *testing.T) {
// Test for #2267
func TestRunWriteHostnameFileAndNotCommit(t *testing.T) {
defer deleteAllContainers()
name := "writehostname"
cmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo test2267 >> /etc/hostname && cat /etc/hostname")
out, _, err := runCommandWithOutput(cmd)
@ -1764,6 +1781,8 @@ func TestRunWriteHostnameFileAndNotCommit(t *testing.T) {
// Test for #2267
func TestRunWriteResolvFileAndNotCommit(t *testing.T) {
defer deleteAllContainers()
name := "writeresolv"
cmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo test2267 >> /etc/resolv.conf && cat /etc/resolv.conf")
out, _, err := runCommandWithOutput(cmd)
@ -1790,13 +1809,15 @@ func TestRunWriteResolvFileAndNotCommit(t *testing.T) {
}
func TestRunWithBadDevice(t *testing.T) {
defer deleteAllContainers()
name := "baddevice"
cmd := exec.Command(dockerBinary, "run", "--name", name, "--device", "/etc", "busybox", "true")
out, _, err := runCommandWithOutput(cmd)
if err == nil {
t.Fatal("Run should fail with bad device")
}
expected := `"/etc": not a device node`
expected := `\"/etc\": not a device node`
if !strings.Contains(out, expected) {
t.Fatalf("Output should contain %q, actual out: %q", expected, out)
}
@ -1804,6 +1825,8 @@ func TestRunWithBadDevice(t *testing.T) {
}
func TestRunEntrypoint(t *testing.T) {
defer deleteAllContainers()
name := "entrypoint"
cmd := exec.Command(dockerBinary, "run", "--name", name, "--entrypoint", "/bin/echo", "busybox", "-n", "foobar")
out, _, err := runCommandWithOutput(cmd)
@ -1818,6 +1841,8 @@ func TestRunEntrypoint(t *testing.T) {
}
func TestRunBindMounts(t *testing.T) {
defer deleteAllContainers()
tmpDir, err := ioutil.TempDir("", "docker-test-container")
if err != nil {
t.Fatal(err)
@ -1872,37 +1897,25 @@ func TestRunMutableNetworkFiles(t *testing.T) {
for _, fn := range []string{"resolv.conf", "hosts"} {
deleteAllContainers()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sh", "-c", fmt.Sprintf("echo success >/etc/%s; while true; do sleep 1; done", fn)))
if err != nil {
t.Fatal(err, out)
}
time.Sleep(1 * time.Second)
contID := strings.TrimSpace(out)
f, err := os.Open(filepath.Join("/var/lib/docker/containers", contID, fn))
content, err := runCommandAndReadContainerFile(fn, exec.Command(dockerBinary, "run", "-d", "--name", "c1", "busybox", "sh", "-c", fmt.Sprintf("echo success >/etc/%s; while true; do sleep 1; done", fn)))
if err != nil {
t.Fatal(err)
}
content, err := ioutil.ReadAll(f)
f.Close()
if strings.TrimSpace(string(content)) != "success" {
t.Fatal("Content was not what was modified in the container", string(content))
}
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c2", "busybox", "sh", "-c", fmt.Sprintf("while true; do cat /etc/%s; sleep 1; done", fn)))
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "c2", "busybox", "sh", "-c", fmt.Sprintf("while true; do cat /etc/%s; sleep 1; done", fn)))
if err != nil {
t.Fatal(err)
}
contID = strings.TrimSpace(out)
contID := strings.TrimSpace(out)
resolvConfPath := filepath.Join("/var/lib/docker/containers", contID, fn)
resolvConfPath := containerStorageFile(contID, fn)
f, err = os.OpenFile(resolvConfPath, os.O_WRONLY|os.O_SYNC|os.O_APPEND, 0644)
f, err := os.OpenFile(resolvConfPath, os.O_WRONLY|os.O_SYNC|os.O_APPEND, 0644)
if err != nil {
t.Fatal(err)
}
@ -2010,6 +2023,41 @@ func TestRunNetworkNotInitializedNoneMode(t *testing.T) {
logDone("run - network must not be initialized in 'none' mode")
}
func TestRunSetMacAddress(t *testing.T) {
mac := "12:34:56:78:9a:bc"
cmd := exec.Command("/bin/bash", "-c", dockerBinary+` run -i --rm --mac-address=`+mac+` busybox /bin/sh -c "ip link show eth0 | tail -1 | awk '{ print \$2 }'"`)
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
actualMac := strings.TrimSpace(out)
if actualMac != mac {
t.Fatalf("Set MAC address with --mac-address failed. The container has an incorrect MAC address: %q, expected: %q", actualMac, mac)
}
deleteAllContainers()
logDone("run - setting MAC address with --mac-address")
}
func TestRunInspectMacAddress(t *testing.T) {
mac := "12:34:56:78:9a:bc"
cmd := exec.Command(dockerBinary, "run", "-d", "--mac-address="+mac, "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
id := strings.TrimSpace(out)
inspectedMac, err := inspectField(id, "NetworkSettings.MacAddress")
if err != nil {
t.Fatal(err)
}
if inspectedMac != mac {
t.Fatalf("docker inspect outputs wrong MAC address: %q, should be: %q", inspectedMac, mac)
}
deleteAllContainers()
logDone("run - inspecting MAC address")
}
func TestRunDeallocatePortOnMissingIptablesRule(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
@ -2260,7 +2308,7 @@ func TestRunRedirectStdout(t *testing.T) {
}()
select {
case <-time.After(time.Second):
case <-time.After(10 * time.Second):
t.Fatal("command timeout")
case <-ch:
}
@ -2392,8 +2440,6 @@ func TestRunNoOutputFromPullInStdout(t *testing.T) {
}
func TestRunVolumesCleanPaths(t *testing.T) {
defer deleteAllContainers()
if _, err := buildImage("run_volumes_clean_paths",
`FROM busybox
VOLUME /foo/`,
@ -2401,6 +2447,7 @@ func TestRunVolumesCleanPaths(t *testing.T) {
t.Fatal(err)
}
defer deleteImages("run_volumes_clean_paths")
defer deleteAllContainers()
cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "-v", "/bar/", "--name", "dark_helmet", "run_volumes_clean_paths")
if out, _, err := runCommandWithOutput(cmd); err != nil {
@ -2440,3 +2487,287 @@ func TestRunVolumesCleanPaths(t *testing.T) {
logDone("run - volume paths are cleaned")
}
// Regression test for #3631
func TestRunSlowStdoutConsumer(t *testing.T) {
defer deleteAllContainers()
c := exec.Command("/bin/bash", "-c", dockerBinary+` run --rm -i busybox /bin/sh -c "dd if=/dev/zero of=/foo bs=1024 count=2000 &>/dev/null; catv /foo"`)
stdout, err := c.StdoutPipe()
if err != nil {
t.Fatal(err)
}
if err := c.Start(); err != nil {
t.Fatal(err)
}
n, err := consumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
if err != nil {
t.Fatal(err)
}
expected := 2 * 1024 * 2000
if n != expected {
t.Fatalf("Expected %d, got %d", expected, n)
}
logDone("run - slow consumer")
}
func TestRunAllowPortRangeThroughExpose(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-d", "--expose", "3000-3003", "-P", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err)
}
id := strings.TrimSpace(out)
portstr, err := inspectFieldJSON(id, "NetworkSettings.Ports")
if err != nil {
t.Fatal(err)
}
var ports nat.PortMap
err = unmarshalJSON([]byte(portstr), &ports)
for port, binding := range ports {
portnum, _ := strconv.Atoi(strings.Split(string(port), "/")[0])
if portnum < 3000 || portnum > 3003 {
t.Fatalf("Port is out of range ", portnum, binding, out)
}
if binding == nil || len(binding) != 1 || len(binding[0].HostPort) == 0 {
t.Fatal("Port is not mapped for the port "+port, out)
}
}
if err := deleteContainer(id); err != nil {
t.Fatal(err)
}
logDone("run - allow port range through --expose flag")
}
func TestRunUnknownCommand(t *testing.T) {
defer deleteAllContainers()
runCmd := exec.Command(dockerBinary, "create", "busybox", "/bin/nada")
cID, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatalf("Failed to create container: %v, output: %q", err, cID)
}
cID = strings.TrimSpace(cID)
runCmd = exec.Command(dockerBinary, "start", cID)
_, _, _, err = runCommandWithStdoutStderr(runCmd)
if err == nil {
t.Fatalf("Container should not have been able to start!")
}
runCmd = exec.Command(dockerBinary, "inspect", "--format={{.State.ExitCode}}", cID)
rc, _, _, err2 := runCommandWithStdoutStderr(runCmd)
rc = strings.TrimSpace(rc)
if err2 != nil {
t.Fatalf("Error getting status of container: %v", err2)
}
if rc != "-1" {
t.Fatalf("ExitCode(%v) was supposed to be -1", rc)
}
logDone("run - Unknown Command")
}
func TestRunModeIpcHost(t *testing.T) {
hostIpc, err := os.Readlink("/proc/1/ns/ipc")
if err != nil {
t.Fatal(err)
}
cmd := exec.Command(dockerBinary, "run", "--ipc=host", "busybox", "readlink", "/proc/self/ns/ipc")
out2, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out2)
}
out2 = strings.Trim(out2, "\n")
if hostIpc != out2 {
t.Fatalf("IPC different with --ipc=host %s != %s\n", hostIpc, out2)
}
cmd = exec.Command(dockerBinary, "run", "busybox", "readlink", "/proc/self/ns/ipc")
out2, _, err = runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out2)
}
out2 = strings.Trim(out2, "\n")
if hostIpc == out2 {
t.Fatalf("IPC should be different without --ipc=host %s != %s\n", hostIpc, out2)
}
deleteAllContainers()
logDone("run - hostname and several network modes")
}
func TestRunModeIpcContainer(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out)
}
id := strings.TrimSpace(out)
state, err := inspectField(id, "State.Running")
if err != nil {
t.Fatal(err)
}
if state != "true" {
t.Fatal("Container state is 'not running'")
}
pid1, err := inspectField(id, "State.Pid")
if err != nil {
t.Fatal(err)
}
parentContainerIpc, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/ipc", pid1))
if err != nil {
t.Fatal(err)
}
cmd = exec.Command(dockerBinary, "run", fmt.Sprintf("--ipc=container:%s", id), "busybox", "readlink", "/proc/self/ns/ipc")
out2, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out2)
}
out2 = strings.Trim(out2, "\n")
if parentContainerIpc != out2 {
t.Fatalf("IPC different with --ipc=container:%s %s != %s\n", id, parentContainerIpc, out2)
}
deleteAllContainers()
logDone("run - hostname and several network modes")
}
func TestContainerNetworkMode(t *testing.T) {
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out)
}
id := strings.TrimSpace(out)
if err := waitRun(id); err != nil {
t.Fatal(err)
}
pid1, err := inspectField(id, "State.Pid")
if err != nil {
t.Fatal(err)
}
parentContainerNet, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/net", pid1))
if err != nil {
t.Fatal(err)
}
cmd = exec.Command(dockerBinary, "run", fmt.Sprintf("--net=container:%s", id), "busybox", "readlink", "/proc/self/ns/net")
out2, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out2)
}
out2 = strings.Trim(out2, "\n")
if parentContainerNet != out2 {
t.Fatalf("NET different with --net=container:%s %s != %s\n", id, parentContainerNet, out2)
}
deleteAllContainers()
logDone("run - container shared network namespace")
}
func TestRunTLSverify(t *testing.T) {
cmd := exec.Command(dockerBinary, "ps")
out, ec, err := runCommandWithOutput(cmd)
if err != nil || ec != 0 {
t.Fatalf("Should have worked: %v:\n%v", err, out)
}
// Regardless of whether we specify true or false we need to
// test to make sure tls is turned on if --tlsverify is specified at all
cmd = exec.Command(dockerBinary, "--tlsverify=false", "ps")
out, ec, err = runCommandWithOutput(cmd)
if err == nil || ec == 0 || !strings.Contains(out, "trying to connect") {
t.Fatalf("Should have failed: \nec:%v\nout:%v\nerr:%v", ec, out, err)
}
cmd = exec.Command(dockerBinary, "--tlsverify=true", "ps")
out, ec, err = runCommandWithOutput(cmd)
if err == nil || ec == 0 || !strings.Contains(out, "cert") {
t.Fatalf("Should have failed: \nec:%v\nout:%v\nerr:%v", ec, out, err)
}
logDone("run - verify tls is set for --tlsverify")
}
func TestRunPortFromDockerRangeInUse(t *testing.T) {
defer deleteAllContainers()
// first find allocator current position
cmd := exec.Command(dockerBinary, "run", "-d", "-p", ":80", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(out, err)
}
id := strings.TrimSpace(out)
cmd = exec.Command(dockerBinary, "port", id)
out, _, err = runCommandWithOutput(cmd)
if err != nil {
t.Fatal(out, err)
}
out = strings.TrimSpace(out)
out = strings.Split(out, ":")[1]
lastPort, err := strconv.Atoi(out)
if err != nil {
t.Fatal(err)
}
port := lastPort + 1
l, err := net.Listen("tcp", ":"+strconv.Itoa(port))
if err != nil {
t.Fatal(err)
}
defer l.Close()
cmd = exec.Command(dockerBinary, "run", "-d", "-p", ":80", "busybox", "top")
out, _, err = runCommandWithOutput(cmd)
if err != nil {
t.Fatalf(out, err)
}
id = strings.TrimSpace(out)
cmd = exec.Command(dockerBinary, "port", id)
out, _, err = runCommandWithOutput(cmd)
if err != nil {
t.Fatal(out, err)
}
logDone("run - find another port if port from autorange already bound")
}
func TestRunTtyWithPipe(t *testing.T) {
defer deleteAllContainers()
done := make(chan struct{})
go func() {
defer close(done)
cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true")
if _, err := cmd.StdinPipe(); err != nil {
t.Fatal(err)
}
expected := "cannot enable tty mode"
if out, _, err := runCommandWithOutput(cmd); err == nil {
t.Fatal("run should have failed")
} else if !strings.Contains(out, expected) {
t.Fatal("run failed with error %q: expected %q", out, expected)
}
}()
select {
case <-done:
case <-time.After(3 * time.Second):
t.Fatal("container is running but should have failed")
}
logDone("run - forbid piped stdin with tty")
}

View File

@ -1,53 +1,68 @@
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"reflect"
"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)
errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err))
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)
out, _, err = runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("output should've been a container id: %v %v", cleanedContainerID, err))
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)
out, _, err = runCommandWithOutput(commitCmd)
errorOut(err, t, fmt.Sprintf("failed to commit container: %v %v", out, err))
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)
errorOut(err, t, fmt.Sprintf("the repo should exist before saving it: %v %v", before, err))
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)
out, _, err = runCommandWithOutput(saveCmd)
errorOut(err, t, fmt.Sprintf("failed to save repo: %v %v", out, err))
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)
out, _, err = runCommandWithOutput(loadCmd)
errorOut(err, t, fmt.Sprintf("failed to load repo: %v %v", out, err))
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)
errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", after, err))
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")
@ -58,8 +73,35 @@ func TestSaveAndLoadRepoStdout(t *testing.T) {
os.Remove("/tmp/foobar-save-load-test.tar")
logDone("save - save a repo using stdout")
logDone("load - load a repo using stdout")
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
@ -129,92 +171,29 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
logDone("load - save a repo with xz compression & load it using stdout")
}
// save a repo using xz+gz compression and try to load it using stdout
func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
tempDir, err := ioutil.TempDir("", "test-save-xz-gz-load-repo-stdout")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)
tarballPath := filepath.Join(tempDir, "foobar-save-load-test.tar.xz.gz")
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf("failed to create a container: %v %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
repoName := "foobar-save-load-test-xz-gz"
inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
out, _, err = runCommandWithOutput(inspectCmd)
if err != nil {
t.Fatalf("output should've been a container id: %v %v", cleanedContainerID, err)
}
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
out, _, err = runCommandWithOutput(commitCmd)
if err != nil {
t.Fatalf("failed to commit container: %v %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: %v %v", before, err)
}
saveCmdTemplate := `%v save %v | xz -c | gzip -c > %s`
saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName, tarballPath)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err = runCommandWithOutput(saveCmd)
if err != nil {
t.Fatalf("failed to save repo: %v %v", out, err)
}
deleteImages(repoName)
loadCmdFinal := fmt.Sprintf(`cat %s | docker load`, tarballPath)
loadCmd := exec.Command("bash", "-c", loadCmdFinal)
out, _, err = runCommandWithOutput(loadCmd)
if err == nil {
t.Fatalf("expected error, but succeeded with no error and output: %v", out)
}
inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
after, _, err := runCommandWithOutput(inspectCmd)
if err == nil {
t.Fatalf("the repo should not exist: %v", after)
}
deleteContainer(cleanedContainerID)
deleteImages(repoName)
logDone("load - save a repo with xz+gz compression & load it using stdout")
}
func TestSaveSingleTag(t *testing.T) {
repoName := "foobar-save-single-tag-test"
tagCmdFinal := fmt.Sprintf("%v tag busybox:latest %v:latest", dockerBinary, repoName)
tagCmd := exec.Command("bash", "-c", tagCmdFinal)
out, _, err := runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("failed to tag repo: %v %v", out, err))
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatalf("failed to tag repo: %s, %v", out, err)
}
idCmdFinal := fmt.Sprintf("%v images -q --no-trunc %v", dockerBinary, repoName)
idCmd := exec.Command("bash", "-c", idCmdFinal)
out, _, err = runCommandWithOutput(idCmd)
errorOut(err, t, fmt.Sprintf("failed to get repo ID: %v %v", out, err))
out, _, err := runCommandWithOutput(idCmd)
if err != nil {
t.Fatalf("failed to get repo ID: %s, %v", out, err)
}
cleanedImageID := stripTrailingCharacters(out)
saveCmdFinal := fmt.Sprintf("%v save %v:latest | tar t | grep -E '(^repositories$|%v)'", dockerBinary, repoName, cleanedImageID)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err = runCommandWithOutput(saveCmd)
errorOut(err, t, fmt.Sprintf("failed to save repo with image ID and 'repositories' file: %v %v", out, err))
if out, _, err = runCommandWithOutput(saveCmd); err != nil {
t.Fatalf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err)
}
deleteImages(repoName)
@ -226,27 +205,33 @@ func TestSaveImageId(t *testing.T) {
tagCmdFinal := fmt.Sprintf("%v tag scratch:latest %v:latest", dockerBinary, repoName)
tagCmd := exec.Command("bash", "-c", tagCmdFinal)
out, _, err := runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("failed to tag repo: %v %v", out, err))
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatalf("failed to tag repo: %s, %v", out, err)
}
idLongCmdFinal := fmt.Sprintf("%v images -q --no-trunc %v", dockerBinary, repoName)
idLongCmd := exec.Command("bash", "-c", idLongCmdFinal)
out, _, err = runCommandWithOutput(idLongCmd)
errorOut(err, t, fmt.Sprintf("failed to get repo ID: %v %v", out, err))
out, _, err := runCommandWithOutput(idLongCmd)
if err != nil {
t.Fatalf("failed to get repo ID: %s, %v", out, err)
}
cleanedLongImageID := stripTrailingCharacters(out)
idShortCmdFinal := fmt.Sprintf("%v images -q %v", dockerBinary, repoName)
idShortCmd := exec.Command("bash", "-c", idShortCmdFinal)
out, _, err = runCommandWithOutput(idShortCmd)
errorOut(err, t, fmt.Sprintf("failed to get repo short ID: %v %v", out, err))
if err != nil {
t.Fatalf("failed to get repo short ID: %s, %v", out, err)
}
cleanedShortImageID := stripTrailingCharacters(out)
saveCmdFinal := fmt.Sprintf("%v save %v | tar t | grep %v", dockerBinary, cleanedShortImageID, cleanedLongImageID)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err = runCommandWithOutput(saveCmd)
errorOut(err, t, fmt.Sprintf("failed to save repo with image ID: %v %v", out, err))
if out, _, err = runCommandWithOutput(saveCmd); err != nil {
t.Fatalf("failed to save repo with image ID: %s, %v", out, err)
}
deleteImages(repoName)
@ -257,40 +242,50 @@ func TestSaveImageId(t *testing.T) {
func TestSaveAndLoadRepoFlags(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err))
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)
out, _, err = runCommandWithOutput(inspectCmd)
errorOut(err, t, fmt.Sprintf("output should've been a container id: %v %v", cleanedContainerID, err))
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)
out, _, err = runCommandWithOutput(commitCmd)
errorOut(err, t, fmt.Sprintf("failed to commit container: %v %v", out, err))
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)
errorOut(err, t, fmt.Sprintf("the repo should exist before saving it: %v %v", before, err))
if err != nil {
t.Fatalf("the repo should exist before saving it: %s, %v", before, err)
}
saveCmdTemplate := `%v save -o /tmp/foobar-save-load-test.tar %v`
saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err = runCommandWithOutput(saveCmd)
errorOut(err, t, fmt.Sprintf("failed to save repo: %v %v", out, err))
if out, _, err = runCommandWithOutput(saveCmd); err != nil {
t.Fatalf("failed to save repo: %s, %v", out, err)
}
deleteImages(repoName)
loadCmdFinal := `docker load -i /tmp/foobar-save-load-test.tar`
loadCmd := exec.Command("bash", "-c", loadCmdFinal)
out, _, err = runCommandWithOutput(loadCmd)
errorOut(err, t, fmt.Sprintf("failed to load repo: %v %v", out, err))
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)
errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", after, err))
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")
@ -301,8 +296,7 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
os.Remove("/tmp/foobar-save-load-test.tar")
logDone("save - save a repo using -o")
logDone("load - load a repo using -i")
logDone("save - save a repo using -o && load a repo using -i")
}
func TestSaveMultipleNames(t *testing.T) {
@ -311,24 +305,90 @@ func TestSaveMultipleNames(t *testing.T) {
// Make one image
tagCmdFinal := fmt.Sprintf("%v tag scratch:latest %v-one:latest", dockerBinary, repoName)
tagCmd := exec.Command("bash", "-c", tagCmdFinal)
out, _, err := runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("failed to tag repo: %v %v", out, err))
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatalf("failed to tag repo: %s, %v", out, err)
}
defer deleteImages(repoName + "-one")
// Make two images
tagCmdFinal = fmt.Sprintf("%v tag scratch:latest %v-two:latest", dockerBinary, repoName)
tagCmd = exec.Command("bash", "-c", tagCmdFinal)
out, _, err = runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("failed to tag repo: %v %v", out, err))
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatalf("failed to tag repo: %s, %v", out, err)
}
defer deleteImages(repoName + "-two")
saveCmdFinal := fmt.Sprintf("%v save %v-one %v-two:latest | tar xO repositories | grep -q -E '(-one|-two)'", dockerBinary, repoName, repoName)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err = runCommandWithOutput(saveCmd)
errorOut(err, t, fmt.Sprintf("failed to save multiple repos: %v %v", out, err))
if out, _, err := runCommandWithOutput(saveCmd); err != nil {
t.Fatalf("failed to save multiple repos: %s, %v", out, err)
}
deleteImages(repoName)
logDone("save - save by multiple names")
}
func TestSaveRepoWithMultipleImages(t *testing.T) {
makeImage := func(from string, tag string) string {
runCmd := exec.Command(dockerBinary, "run", "-d", from, "true")
var (
out string
err error
)
if out, _, err = runCommandWithOutput(runCmd); err != nil {
t.Fatalf("failed to create a container: %v %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, tag)
if out, _, err = runCommandWithOutput(commitCmd); err != nil {
t.Fatalf("failed to commit container: %v %v", out, err)
}
imageID := stripTrailingCharacters(out)
deleteContainer(cleanedContainerID)
return imageID
}
repoName := "foobar-save-multi-images-test"
tagFoo := repoName + ":foo"
tagBar := repoName + ":bar"
idFoo := makeImage("busybox:latest", tagFoo)
idBar := makeImage("busybox:latest", tagBar)
deleteImages(repoName)
// create the archive
saveCmdFinal := fmt.Sprintf("%v save %v | tar t | grep 'VERSION' |cut -d / -f1", dockerBinary, repoName)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err := runCommandWithOutput(saveCmd)
if err != nil {
t.Fatalf("failed to save multiple images: %s, %v", out, err)
}
actual := strings.Split(stripTrailingCharacters(out), "\n")
// make the list of expected layers
historyCmdFinal := fmt.Sprintf("%v history -q --no-trunc %v", dockerBinary, "busybox:latest")
historyCmd := exec.Command("bash", "-c", historyCmdFinal)
out, _, err = runCommandWithOutput(historyCmd)
if err != nil {
t.Fatalf("failed to get history: %s, %v", out, err)
}
expected := append(strings.Split(stripTrailingCharacters(out), "\n"), idFoo, idBar)
sort.Strings(actual)
sort.Strings(expected)
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("achive does not contains the right layers: got %v, expected %v", actual, expected)
}
logDone("save - save repository with multiple images")
}
// Issue #6722 #5892 ensure directories are included in changes
func TestSaveDirectoryPermissions(t *testing.T) {
layerEntries := []string{"opt/", "opt/a/", "opt/a/b/", "opt/a/b/c"}
@ -336,12 +396,12 @@ func TestSaveDirectoryPermissions(t *testing.T) {
name := "save-directory-permissions"
tmpDir, err := ioutil.TempDir("", "save-layers-with-directories")
extractionDirectory := filepath.Join(tmpDir, "image-extraction-dir")
os.Mkdir(extractionDirectory, 0777)
if err != nil {
t.Errorf("failed to create temporary directory: %s", err)
}
extractionDirectory := filepath.Join(tmpDir, "image-extraction-dir")
os.Mkdir(extractionDirectory, 0777)
defer os.RemoveAll(tmpDir)
defer deleteImages(name)
_, err = buildImage(name,
@ -355,8 +415,7 @@ func TestSaveDirectoryPermissions(t *testing.T) {
saveCmdFinal := fmt.Sprintf("%s save %s | tar -xf - -C %s", dockerBinary, name, extractionDirectory)
saveCmd := exec.Command("bash", "-c", saveCmdFinal)
out, _, err := runCommandWithOutput(saveCmd)
if err != nil {
if out, _, err := runCommandWithOutput(saveCmd); err != nil {
t.Errorf("failed to save and extract image: %s", out)
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -11,10 +10,8 @@ import (
func TestSearchOnCentralRegistry(t *testing.T) {
searchCmd := exec.Command(dockerBinary, "search", "busybox")
out, exitCode, err := runCommandWithOutput(searchCmd)
errorOut(err, t, fmt.Sprintf("encountered error while searching: %v", err))
if err != nil || exitCode != 0 {
t.Fatal("failed to search on the central registry")
t.Fatalf("failed to search on the central registry: %s, %v", out, err)
}
if !strings.Contains(out, "Busybox base image.") {

View File

@ -1,6 +1,7 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -11,8 +12,8 @@ import (
func TestStartAttachReturnsOnError(t *testing.T) {
defer deleteAllContainers()
cmd(t, "run", "-d", "--name", "test", "busybox")
cmd(t, "stop", "test")
dockerCmd(t, "run", "-d", "--name", "test", "busybox")
dockerCmd(t, "wait", "test")
// Expect this to fail because the above container is stopped, this is what we want
if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "--link", "test:test", "busybox")); err == nil {
@ -38,12 +39,83 @@ func TestStartAttachReturnsOnError(t *testing.T) {
logDone("start - error on start with attach exits")
}
// gh#8555: Exit code should be passed through when using start -a
func TestStartAttachCorrectExitCode(t *testing.T) {
defer deleteAllContainers()
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1")
out, _, _, err := runCommandWithStdoutStderr(runCmd)
if err != nil {
t.Fatalf("failed to run container: %v, output: %q", err, out)
}
out = stripTrailingCharacters(out)
// make sure the container has exited before trying the "start -a"
waitCmd := exec.Command(dockerBinary, "wait", out)
if out, _, err = runCommandWithOutput(waitCmd); err != nil {
t.Fatal(out, err)
}
startCmd := exec.Command(dockerBinary, "start", "-a", out)
startOut, exitCode, err := runCommandWithOutput(startCmd)
if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
}
if exitCode != 1 {
t.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode)
}
logDone("start - correct exit code returned with -a")
}
func TestStartRecordError(t *testing.T) {
defer deleteAllContainers()
// when container runs successfully, we should not have state.Error
dockerCmd(t, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top")
stateErr, err := inspectField("test", "State.Error")
if err != nil {
t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
}
if stateErr != "" {
t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
}
// Expect this to fail and records error because of ports conflict
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top"))
if err == nil {
t.Fatalf("Expected error but got none, output %q", out)
}
stateErr, err = inspectField("test2", "State.Error")
if err != nil {
t.Fatalf("Failed to inspect %q state's error, got error %q", "test2", err)
}
expected := "port is already allocated"
if stateErr == "" || !strings.Contains(stateErr, expected) {
t.Fatalf("State.Error(%q) does not include %q", stateErr, expected)
}
// Expect the conflict to be resolved when we stop the initial container
dockerCmd(t, "stop", "test")
dockerCmd(t, "start", "test2")
stateErr, err = inspectField("test2", "State.Error")
if err != nil {
t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
}
if stateErr != "" {
t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
}
logDone("start - set state error when start fails")
}
// gh#8726: a failed Start() breaks --volumes-from on subsequent Start()'s
func TestStartVolumesFromFailsCleanly(t *testing.T) {
defer deleteAllContainers()
// Create the first data volume
cmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")
dockerCmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")
// Expect this to fail because the data test after contaienr doesn't exist yet
if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "consumer", "--volumes-from", "data_before", "--volumes-from", "data_after", "busybox")); err == nil {
@ -51,13 +123,13 @@ func TestStartVolumesFromFailsCleanly(t *testing.T) {
}
// Create the second data volume
cmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")
dockerCmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")
// Now, all the volumes should be there
cmd(t, "start", "consumer")
dockerCmd(t, "start", "consumer")
// Check that we have the volumes we want
out, _, _ := cmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
out, _, _ := dockerCmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
n_volumes := strings.Trim(out, " \r\n'")
if n_volumes != "2" {
t.Fatalf("Missing volumes: expected 2, got %s", n_volumes)

View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"os/exec"
"strings"
"testing"
)
@ -13,8 +14,9 @@ func TestTagUnprefixedRepoByName(t *testing.T) {
}
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "testfoobarbaz")
out, _, err := runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("%v %v", out, err))
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatal(out, err)
}
deleteImages("testfoobarbaz")
@ -25,12 +27,15 @@ func TestTagUnprefixedRepoByName(t *testing.T) {
func TestTagUnprefixedRepoByID(t *testing.T) {
getIDCmd := exec.Command(dockerBinary, "inspect", "-f", "{{.Id}}", "busybox")
out, _, err := runCommandWithOutput(getIDCmd)
errorOut(err, t, fmt.Sprintf("failed to get the image ID of busybox: %v", err))
if err != nil {
t.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
}
cleanedImageID := stripTrailingCharacters(out)
tagCmd := exec.Command(dockerBinary, "tag", cleanedImageID, "testfoobarbaz")
out, _, err = runCommandWithOutput(tagCmd)
errorOut(err, t, fmt.Sprintf("%s %s", out, err))
if out, _, err = runCommandWithOutput(tagCmd); err != nil {
t.Fatal(out, err)
}
deleteImages("testfoobarbaz")
@ -88,3 +93,42 @@ func TestTagValidPrefixedRepo(t *testing.T) {
logDone(logMessage)
}
}
// tag an image with an existed tag name without -f option should fail
func TestTagExistedNameWithoutForce(t *testing.T) {
if err := pullImageIfNotExist("busybox:latest"); err != nil {
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
}
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatal(out, err)
}
tagCmd = exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
out, _, err := runCommandWithOutput(tagCmd)
if err == nil || !strings.Contains(out, "Conflict: Tag test is already set to image") {
t.Fatal("tag busybox busybox:test should have failed,because busybox:test is existed")
}
deleteImages("busybox:test")
logDone("tag - busybox with an existed tag name without -f option --> must fail")
}
// tag an image with an existed tag name with -f option should work
func TestTagExistedNameWithForce(t *testing.T) {
if err := pullImageIfNotExist("busybox:latest"); err != nil {
t.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
}
tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "busybox:test")
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatal(out, err)
}
tagCmd = exec.Command(dockerBinary, "tag", "-f", "busybox:latest", "busybox:test")
if out, _, err := runCommandWithOutput(tagCmd); err != nil {
t.Fatal(out, err)
}
deleteImages("busybox:test")
logDone("tag - busybox with an existed tag name with -f option work")
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -10,17 +9,21 @@ import (
func TestTopMultipleArgs(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox", "sleep", "20")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
if err != nil {
t.Fatalf("failed to start the container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
defer deleteContainer(cleanedContainerID)
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID, "-o", "pid")
out, _, err = runCommandWithOutput(topCmd)
errorOut(err, t, fmt.Sprintf("failed to run top: %v %v", out, err))
if err != nil {
t.Fatalf("failed to run top: %s, %v", out, err)
}
if !strings.Contains(out, "PID") {
errorOut(nil, t, fmt.Sprintf("did not see PID after top -o pid"))
t.Fatalf("did not see PID after top -o pid: %s", out)
}
logDone("top - multiple arguments")
@ -29,27 +32,34 @@ func TestTopMultipleArgs(t *testing.T) {
func TestTopNonPrivileged(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox", "sleep", "20")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
if err != nil {
t.Fatalf("failed to start the container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID)
out, _, err = runCommandWithOutput(topCmd)
errorOut(err, t, fmt.Sprintf("failed to run top: %v %v", out, err))
out1, _, err := runCommandWithOutput(topCmd)
if err != nil {
t.Fatalf("failed to run top: %s, %v", out1, err)
}
topCmd = exec.Command(dockerBinary, "top", cleanedContainerID)
out2, _, err2 := runCommandWithOutput(topCmd)
errorOut(err2, t, fmt.Sprintf("failed to run top: %v %v", out2, err2))
out2, _, err := runCommandWithOutput(topCmd)
if err != nil {
t.Fatalf("failed to run top: %s, %v", out2, err)
}
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
_, err = runCommand(killCmd)
errorOut(err, t, fmt.Sprintf("failed to kill container: %v", err))
if out, _, err = runCommandWithOutput(killCmd); err != nil {
t.Fatalf("failed to kill container: %s, %v", out, err)
}
deleteContainer(cleanedContainerID)
if !strings.Contains(out, "sleep 20") && !strings.Contains(out2, "sleep 20") {
if !strings.Contains(out1, "sleep 20") && !strings.Contains(out2, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed twice")
} else if !strings.Contains(out, "sleep 20") {
} else if !strings.Contains(out1, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed the first time")
} else if !strings.Contains(out2, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed the second itime")
@ -61,27 +71,34 @@ func TestTopNonPrivileged(t *testing.T) {
func TestTopPrivileged(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--privileged", "-i", "-d", "busybox", "sleep", "20")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
if err != nil {
t.Fatalf("failed to start the container: %s, %v", out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
topCmd := exec.Command(dockerBinary, "top", cleanedContainerID)
out, _, err = runCommandWithOutput(topCmd)
errorOut(err, t, fmt.Sprintf("failed to run top: %v %v", out, err))
out1, _, err := runCommandWithOutput(topCmd)
if err != nil {
t.Fatalf("failed to run top: %s, %v", out1, err)
}
topCmd = exec.Command(dockerBinary, "top", cleanedContainerID)
out2, _, err2 := runCommandWithOutput(topCmd)
errorOut(err2, t, fmt.Sprintf("failed to run top: %v %v", out2, err2))
out2, _, err := runCommandWithOutput(topCmd)
if err != nil {
t.Fatalf("failed to run top: %s, %v", out2, err)
}
killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID)
_, err = runCommand(killCmd)
errorOut(err, t, fmt.Sprintf("failed to kill container: %v", err))
if out, _, err = runCommandWithOutput(killCmd); err != nil {
t.Fatalf("failed to kill container: %s, %v", out, err)
}
deleteContainer(cleanedContainerID)
if !strings.Contains(out, "sleep 20") && !strings.Contains(out2, "sleep 20") {
if !strings.Contains(out1, "sleep 20") && !strings.Contains(out2, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed twice")
} else if !strings.Contains(out, "sleep 20") {
} else if !strings.Contains(out1, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed the first time")
} else if !strings.Contains(out2, "sleep 20") {
t.Fatal("top should've listed `sleep 20` in the process list, but failed the second itime")

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"os/exec"
"strings"
"testing"
@ -10,11 +9,9 @@ import (
// ensure docker version works
func TestVersionEnsureSucceeds(t *testing.T) {
versionCmd := exec.Command(dockerBinary, "version")
out, exitCode, err := runCommandWithOutput(versionCmd)
errorOut(err, t, fmt.Sprintf("encountered error while running docker version: %v", err))
if err != nil || exitCode != 0 {
t.Fatal("failed to execute docker version")
out, _, err := runCommandWithOutput(versionCmd)
if err != nil {
t.Fatalf("failed to execute docker version: %s, %v", out, err)
}
stringsToCheck := []string{

View File

@ -16,10 +16,11 @@ var (
// the private registry to use for tests
privateRegistryURL = "127.0.0.1:5000"
dockerBasePath = "/var/lib/docker"
execDriverPath = dockerBasePath + "/execdriver/native"
volumesConfigPath = dockerBasePath + "/volumes"
volumesStoragePath = dockerBasePath + "/vfs/dir"
dockerBasePath = "/var/lib/docker"
execDriverPath = dockerBasePath + "/execdriver/native"
volumesConfigPath = dockerBasePath + "/volumes"
volumesStoragePath = dockerBasePath + "/vfs/dir"
containerStoragePath = dockerBasePath + "/containers"
workingDirectory string
)

View File

@ -1,6 +1,8 @@
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
@ -41,10 +43,10 @@ func NewDaemon(t *testing.T) *Daemon {
t.Fatal("Please set the DEST environment variable")
}
dir := filepath.Join(dest, fmt.Sprintf("daemon%d", time.Now().Unix()))
dir := filepath.Join(dest, fmt.Sprintf("daemon%d", time.Now().UnixNano()%100000000))
daemonFolder, err := filepath.Abs(dir)
if err != nil {
t.Fatalf("Could not make '%s' an absolute path: %v", dir, err)
t.Fatalf("Could not make %q an absolute path: %v", dir, err)
}
if err := os.MkdirAll(filepath.Join(daemonFolder, "graph"), 0600); err != nil {
@ -69,10 +71,23 @@ func (d *Daemon) Start(arg ...string) error {
args := []string{
"--host", d.sock(),
"--daemon", "--debug",
"--daemon",
"--graph", fmt.Sprintf("%s/graph", d.folder),
"--pidfile", fmt.Sprintf("%s/docker.pid", d.folder),
}
// If we don't explicitly set the log-level or debug flag(-D) then
// turn on debug mode
foundIt := false
for _, a := range arg {
if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") {
foundIt = true
}
}
if !foundIt {
args = append(args, "--debug")
}
if d.storageDriver != "" {
args = append(args, "--storage-driver", d.storageDriver)
}
@ -83,7 +98,7 @@ func (d *Daemon) Start(arg ...string) error {
args = append(args, arg...)
d.cmd = exec.Command(dockerBinary, args...)
d.logFile, err = os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
d.logFile, err = os.OpenFile(filepath.Join(d.folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
if err != nil {
d.t.Fatalf("Could not create %s/docker.log: %v", d.folder, err)
}
@ -107,8 +122,13 @@ func (d *Daemon) Start(arg ...string) error {
tick := time.Tick(500 * time.Millisecond)
// make sure daemon is ready to receive requests
startTime := time.Now().Unix()
for {
d.t.Log("waiting for daemon to start")
if time.Now().Unix()-startTime > 5 {
// After 5 seconds, give up
return errors.New("Daemon exited and never started")
}
select {
case <-time.After(2 * time.Second):
return errors.New("timeout: daemon does not respond")
@ -231,7 +251,7 @@ func (d *Daemon) Cmd(name string, arg ...string) (string, error) {
return string(b), err
}
func sockRequest(method, endpoint string) ([]byte, error) {
func sockRequest(method, endpoint string, data interface{}) ([]byte, error) {
// FIX: the path to sock should not be hardcoded
sock := filepath.Join("/", "var", "run", "docker.sock")
c, err := net.DialTimeout("unix", sock, time.Duration(10*time.Second))
@ -242,7 +262,12 @@ func sockRequest(method, endpoint string) ([]byte, error) {
client := httputil.NewClientConn(c, nil)
defer client.Close()
req, err := http.NewRequest(method, endpoint, nil)
jsonData := bytes.NewBuffer(nil)
if err := json.NewEncoder(jsonData).Encode(data); err != nil {
return nil, err
}
req, err := http.NewRequest(method, endpoint, jsonData)
req.Header.Set("Content-Type", "application/json")
if err != nil {
return nil, fmt.Errorf("could not create new request: %v", err)
@ -254,7 +279,8 @@ func sockRequest(method, endpoint string) ([]byte, error) {
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("received status != 200 OK: %s", resp.Status)
body, _ := ioutil.ReadAll(resp.Body)
return body, fmt.Errorf("received status != 200 OK: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
@ -302,8 +328,51 @@ func deleteAllContainers() error {
return nil
}
func getPausedContainers() (string, error) {
getPausedContainersCmd := exec.Command(dockerBinary, "ps", "-f", "status=paused", "-q", "-a")
out, exitCode, err := runCommandWithOutput(getPausedContainersCmd)
if exitCode != 0 && err == nil {
err = fmt.Errorf("failed to get a list of paused containers: %v\n", out)
}
return out, err
}
func unpauseContainer(container string) error {
unpauseCmd := exec.Command(dockerBinary, "unpause", container)
exitCode, err := runCommand(unpauseCmd)
if exitCode != 0 && err == nil {
err = fmt.Errorf("failed to unpause container")
}
return nil
}
func unpauseAllContainers() error {
containers, err := getPausedContainers()
if err != nil {
fmt.Println(containers)
return err
}
containers = strings.Replace(containers, "\n", " ", -1)
containers = strings.Trim(containers, " ")
containerList := strings.Split(containers, " ")
for _, value := range containerList {
if err = unpauseContainer(value); err != nil {
return err
}
}
return nil
}
func deleteImages(images ...string) error {
rmiCmd := exec.Command(dockerBinary, "rmi", strings.Join(images, " "))
args := make([]string, 1, 2)
args[0] = "rmi"
args = append(args, images...)
rmiCmd := exec.Command(dockerBinary, args...)
exitCode, err := runCommand(rmiCmd)
// set error manually if not set
if exitCode != 0 && err == nil {
@ -317,7 +386,7 @@ func imageExists(image string) error {
inspectCmd := exec.Command(dockerBinary, "inspect", image)
exitCode, err := runCommand(inspectCmd)
if exitCode != 0 && err == nil {
err = fmt.Errorf("couldn't find image '%s'", image)
err = fmt.Errorf("couldn't find image %q", image)
}
return err
}
@ -328,20 +397,17 @@ func pullImageIfNotExist(image string) (err error) {
_, exitCode, err := runCommandWithOutput(pullCmd)
if err != nil || exitCode != 0 {
err = fmt.Errorf("image '%s' wasn't found locally and it couldn't be pulled: %s", image, err)
err = fmt.Errorf("image %q wasn't found locally and it couldn't be pulled: %s", image, err)
}
}
return
}
// deprecated, use dockerCmd instead
func cmd(t *testing.T, args ...string) (string, int, error) {
return dockerCmd(t, args...)
}
func dockerCmd(t *testing.T, args ...string) (string, int, error) {
out, status, err := runCommandWithOutput(exec.Command(dockerBinary, args...))
errorOut(err, t, fmt.Sprintf("'%s' failed with errors: %v (%v)", strings.Join(args, " "), err, out))
if err != nil {
t.Fatalf("%q failed with errors: %s, %v", strings.Join(args, " "), out, err)
}
return out, status, err
}
@ -349,7 +415,7 @@ func dockerCmd(t *testing.T, args ...string) (string, int, error) {
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, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
}
return out, status, err
}
@ -360,7 +426,7 @@ func dockerCmdInDir(t *testing.T, path string, args ...string) (string, int, err
dockerCommand.Dir = path
out, status, err := runCommandWithOutput(dockerCommand)
if err != nil {
return out, status, fmt.Errorf("'%s' failed with errors: %v : %q)", strings.Join(args, " "), err, out)
return out, status, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
}
return out, status, err
}
@ -371,7 +437,7 @@ func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...strin
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, fmt.Errorf("%q failed with errors: %v : %q)", strings.Join(args, " "), err, out)
}
return out, status, err
}
@ -531,7 +597,7 @@ func getContainerState(t *testing.T, id string) (int, bool, error) {
)
out, exitCode, err := dockerCmd(t, "inspect", "--format={{.State.Running}} {{.State.ExitCode}}", id)
if err != nil || exitCode != 0 {
return 0, false, fmt.Errorf("'%s' doesn't exist: %s", id, err)
return 0, false, fmt.Errorf("%q doesn't exist: %s", id, err)
}
out = strings.Trim(out, "\n")
@ -570,6 +636,25 @@ func buildImageWithOut(name, dockerfile string, useCache bool) (string, string,
return id, out, nil
}
func buildImageWithStdoutStderr(name, dockerfile string, useCache bool) (string, string, string, error) {
args := []string{"build", "-t", name}
if !useCache {
args = append(args, "--no-cache")
}
args = append(args, "-")
buildCmd := exec.Command(dockerBinary, args...)
buildCmd.Stdin = strings.NewReader(dockerfile)
stdout, stderr, exitCode, err := runCommandWithStdoutStderr(buildCmd)
if err != nil || exitCode != 0 {
return "", stdout, stderr, fmt.Errorf("failed to build the image: %s", stdout)
}
id, err := getIDByName(name)
if err != nil {
return "", stdout, stderr, err
}
return id, stdout, stderr, nil
}
func buildImage(name, dockerfile string, useCache bool) (string, error) {
id, _, err := buildImageWithOut(name, dockerfile, useCache)
return id, err
@ -712,3 +797,36 @@ func readFile(src string, t *testing.T) (content string) {
}
return string(data)
}
func containerStorageFile(containerId, basename string) string {
return filepath.Join("/var/lib/docker/containers", containerId, basename)
}
// docker commands that use this function must be run with the '-d' switch.
func runCommandAndReadContainerFile(filename string, cmd *exec.Cmd) ([]byte, error) {
out, _, err := runCommandWithOutput(cmd)
if err != nil {
return nil, fmt.Errorf("%v: %q", err, out)
}
time.Sleep(1 * time.Second)
contID := strings.TrimSpace(out)
return readContainerFile(contID, filename)
}
func readContainerFile(containerId, filename string) ([]byte, error) {
f, err := os.Open(containerStorageFile(containerId, filename))
if err != nil {
return nil, err
}
defer f.Close()
content, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
return content, nil
}

View File

@ -13,7 +13,6 @@ import (
"reflect"
"strings"
"syscall"
"testing"
"time"
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
@ -96,13 +95,6 @@ func runCommand(cmd *exec.Cmd) (exitCode int, err error) {
return
}
func startCommand(cmd *exec.Cmd) (exitCode int, err error) {
exitCode = 0
err = cmd.Start()
exitCode = processExitCode(err)
return
}
func logDone(message string) {
fmt.Printf("[PASSED]: %s\n", message)
}
@ -113,22 +105,6 @@ func stripTrailingCharacters(target string) string {
return target
}
func errorOut(err error, t *testing.T, message string) {
if err != nil {
t.Fatal(message)
}
}
func errorOutOnNonNilError(err error, t *testing.T, message string) {
if err == nil {
t.Fatalf(message)
}
}
func nLines(s string) int {
return strings.Count(s, "\n")
}
func unmarshalJSON(data []byte, result interface{}) error {
err := json.Unmarshal(data, result)
if err != nil {
@ -138,10 +114,6 @@ func unmarshalJSON(data []byte, result interface{}) error {
return nil
}
func deepEqual(expected interface{}, result interface{}) bool {
return reflect.DeepEqual(result, expected)
}
func convertSliceOfStringsToMap(input []string) map[string]struct{} {
output := make(map[string]struct{})
for _, v := range input {
@ -266,3 +238,26 @@ func makeRandomString(n int) string {
}
return string(b)
}
// Reads chunkSize bytes from reader after every interval.
// Returns total read bytes.
func consumeWithSpeed(reader io.Reader, chunkSize int, interval time.Duration, stop chan bool) (n int, err error) {
buffer := make([]byte, chunkSize)
for {
select {
case <-stop:
return
default:
var readBytes int
readBytes, err = reader.Read(buffer)
n += readBytes
if err != nil {
if err == io.EOF {
err = nil
}
return
}
time.Sleep(interval)
}
}
}