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:
@ -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' ]
|
||||
@ -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' ]
|
||||
@ -1,2 +0,0 @@
|
||||
FROM busybox
|
||||
COPY https://index.docker.io/robots.txt /
|
||||
@ -1,2 +0,0 @@
|
||||
FROM scratch
|
||||
COPY . /
|
||||
@ -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' ]
|
||||
@ -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
|
||||
@ -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' ]
|
||||
@ -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' ]
|
||||
@ -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' ]
|
||||
@ -1,2 +0,0 @@
|
||||
FROM busybox
|
||||
COPY test_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' ]
|
||||
122
components/engine/integration-cli/docker_api_containers_test.go
Normal file
122
components/engine/integration-cli/docker_api_containers_test.go
Normal 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")
|
||||
}
|
||||
25
components/engine/integration-cli/docker_api_exec_test.go
Normal file
25
components/engine/integration-cli/docker_api_exec_test.go
Normal 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")
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
|
||||
53
components/engine/integration-cli/docker_api_resize_test.go
Normal file
53
components/engine/integration-cli/docker_api_resize_test.go
Normal 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")
|
||||
}
|
||||
@ -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
@ -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")
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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:"}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
35
components/engine/integration-cli/docker_cli_login_test.go
Normal file
35
components/engine/integration-cli/docker_cli_login_test.go
Normal 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")
|
||||
}
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
|
||||
@ -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.") {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user