Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)
| ... | ... |
@@ -1,4 +1,4 @@ |
| 1 |
-.PHONY: all binary build cross default docs docs-build docs-shell shell test test-integration |
|
| 1 |
+.PHONY: all binary build cross default docs docs-build docs-shell shell test test-integration test-integration-cli |
|
| 2 | 2 |
|
| 3 | 3 |
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) |
| 4 | 4 |
DOCKER_IMAGE := docker:$(GIT_BRANCH) |
| ... | ... |
@@ -23,11 +23,14 @@ docs-shell: docs-build |
| 23 | 23 |
docker run --rm -i -t -p 8000:8000 "$(DOCKER_DOCS_IMAGE)" bash |
| 24 | 24 |
|
| 25 | 25 |
test: build |
| 26 |
- $(DOCKER_RUN_DOCKER) hack/make.sh test test-integration |
|
| 26 |
+ $(DOCKER_RUN_DOCKER) hack/make.sh binary test test-integration test-integration-cli |
|
| 27 | 27 |
|
| 28 | 28 |
test-integration: build |
| 29 | 29 |
$(DOCKER_RUN_DOCKER) hack/make.sh test-integration |
| 30 | 30 |
|
| 31 |
+test-integration-cli: build |
|
| 32 |
+ $(DOCKER_RUN_DOCKER) hack/make.sh binary test-integration-cli |
|
| 33 |
+ |
|
| 31 | 34 |
shell: build |
| 32 | 35 |
$(DOCKER_RUN_DOCKER) bash |
| 33 | 36 |
|
| 145 | 146 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,37 @@ |
| 0 |
+#!/bin/bash |
|
| 1 |
+ |
|
| 2 |
+DEST=$1 |
|
| 3 |
+DOCKERBIN=$DEST/../binary/docker-$VERSION |
|
| 4 |
+DYNDOCKERBIN=$DEST/../dynbinary/docker-$VERSION |
|
| 5 |
+DOCKERINITBIN=$DEST/../dynbinary/dockerinit-$VERSION |
|
| 6 |
+ |
|
| 7 |
+set -e |
|
| 8 |
+ |
|
| 9 |
+bundle_test_integration_cli() {
|
|
| 10 |
+ go_test_dir ./integration-cli |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 13 |
+if [ -x "/usr/bin/docker" ]; then |
|
| 14 |
+ echo "docker found at /usr/bin/docker" |
|
| 15 |
+elif [ -x "$DOCKERBIN" ]; then |
|
| 16 |
+ ln -s $DOCKERBIN /usr/bin/docker |
|
| 17 |
+elif [ -x "$DYNDOCKERBIN" ]; then |
|
| 18 |
+ ln -s $DYNDOCKERBIN /usr/bin/docker |
|
| 19 |
+ ln -s $DOCKERINITBIN /usr/bin/dockerinit |
|
| 20 |
+else |
|
| 21 |
+ echo >&2 'error: binary or dynbinary must be run before test-integration-cli' |
|
| 22 |
+ false |
|
| 23 |
+fi |
|
| 24 |
+ |
|
| 25 |
+ |
|
| 26 |
+docker -d -D -p $DEST/docker.pid &> $DEST/docker.log & |
|
| 27 |
+sleep 2 |
|
| 28 |
+docker info |
|
| 29 |
+DOCKERD_PID=`cat $DEST/docker.pid` |
|
| 30 |
+ |
|
| 31 |
+bundle_test_integration_cli 2>&1 \ |
|
| 32 |
+ | tee $DEST/test.log |
|
| 33 |
+ |
|
| 34 |
+kill $DOCKERD_PID |
|
| 35 |
+wait $DOCKERD_PID |
|
| 36 |
+ |
| 0 | 37 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,60 @@ |
| 0 |
+FROM busybox |
|
| 1 |
+RUN echo "foo" |
|
| 2 |
+RUN echo "foo" |
|
| 3 |
+RUN echo "foo" |
|
| 4 |
+RUN echo "foo" |
|
| 5 |
+RUN echo "foo" |
|
| 6 |
+RUN echo "foo" |
|
| 7 |
+RUN echo "foo" |
|
| 8 |
+RUN echo "foo" |
|
| 9 |
+RUN echo "foo" |
|
| 10 |
+RUN echo "foo" |
|
| 11 |
+RUN echo "foo" |
|
| 12 |
+RUN echo "foo" |
|
| 13 |
+RUN echo "foo" |
|
| 14 |
+RUN echo "foo" |
|
| 15 |
+RUN echo "foo" |
|
| 16 |
+RUN echo "foo" |
|
| 17 |
+RUN echo "foo" |
|
| 18 |
+RUN echo "foo" |
|
| 19 |
+RUN echo "foo" |
|
| 20 |
+RUN echo "foo" |
|
| 21 |
+RUN echo "foo" |
|
| 22 |
+RUN echo "foo" |
|
| 23 |
+RUN echo "foo" |
|
| 24 |
+RUN echo "foo" |
|
| 25 |
+RUN echo "foo" |
|
| 26 |
+RUN echo "foo" |
|
| 27 |
+RUN echo "foo" |
|
| 28 |
+RUN echo "foo" |
|
| 29 |
+RUN echo "foo" |
|
| 30 |
+RUN echo "foo" |
|
| 31 |
+RUN echo "foo" |
|
| 32 |
+RUN echo "foo" |
|
| 33 |
+RUN echo "foo" |
|
| 34 |
+RUN echo "foo" |
|
| 35 |
+RUN echo "foo" |
|
| 36 |
+RUN echo "foo" |
|
| 37 |
+RUN echo "foo" |
|
| 38 |
+RUN echo "foo" |
|
| 39 |
+RUN echo "foo" |
|
| 40 |
+RUN echo "foo" |
|
| 41 |
+RUN echo "foo" |
|
| 42 |
+RUN echo "foo" |
|
| 43 |
+RUN echo "foo" |
|
| 44 |
+RUN echo "foo" |
|
| 45 |
+RUN echo "foo" |
|
| 46 |
+RUN echo "foo" |
|
| 47 |
+RUN echo "foo" |
|
| 48 |
+RUN echo "foo" |
|
| 49 |
+RUN echo "foo" |
|
| 50 |
+RUN echo "foo" |
|
| 51 |
+RUN echo "foo" |
|
| 52 |
+RUN echo "foo" |
|
| 53 |
+RUN echo "foo" |
|
| 54 |
+RUN echo "foo" |
|
| 55 |
+RUN echo "foo" |
|
| 56 |
+RUN echo "foo" |
|
| 57 |
+RUN echo "foo" |
|
| 58 |
+RUN echo "foo" |
|
| 59 |
+RUN echo "foo" |
| 0 | 60 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "path/filepath" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func TestBuildSixtySteps(t *testing.T) {
|
|
| 10 |
+ buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildSixtySteps") |
|
| 11 |
+ buildCmd := exec.Command(dockerBinary, "build", "-t", "foobuildsixtysteps", ".") |
|
| 12 |
+ buildCmd.Dir = buildDirectory |
|
| 13 |
+ out, exitCode, err := runCommandWithOutput(buildCmd) |
|
| 14 |
+ errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
|
|
| 15 |
+ |
|
| 16 |
+ if err != nil || exitCode != 0 {
|
|
| 17 |
+ t.Fatal("failed to build the image")
|
|
| 18 |
+ } |
|
| 19 |
+ |
|
| 20 |
+ go deleteImages("foobuildsixtysteps")
|
|
| 21 |
+ |
|
| 22 |
+ logDone("build - build an image with sixty build steps")
|
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+// TODO: TestCaching |
|
| 26 |
+ |
|
| 27 |
+// TODO: TestADDCacheInvalidation |
| 0 | 28 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,34 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "testing" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func TestCommitAfterContainerIsDone(t *testing.T) {
|
|
| 9 |
+ runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo") |
|
| 10 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 11 |
+ errorOut(err, t, fmt.Sprintf("failed to run container: %v %v", out, err))
|
|
| 12 |
+ |
|
| 13 |
+ cleanedContainerID := stripTrailingCharacters(out) |
|
| 14 |
+ |
|
| 15 |
+ waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID) |
|
| 16 |
+ _, _, err = runCommandWithOutput(waitCmd) |
|
| 17 |
+ errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
|
|
| 18 |
+ |
|
| 19 |
+ commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID) |
|
| 20 |
+ out, _, err = runCommandWithOutput(commitCmd) |
|
| 21 |
+ errorOut(err, t, fmt.Sprintf("failed to commit container to image: %v %v", out, err))
|
|
| 22 |
+ |
|
| 23 |
+ cleanedImageID := stripTrailingCharacters(out) |
|
| 24 |
+ |
|
| 25 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID) |
|
| 26 |
+ out, _, err = runCommandWithOutput(inspectCmd) |
|
| 27 |
+ errorOut(err, t, fmt.Sprintf("failed to inspect image: %v %v", out, err))
|
|
| 28 |
+ |
|
| 29 |
+ go deleteContainer(cleanedContainerID) |
|
| 30 |
+ go deleteImages(cleanedImageID) |
|
| 31 |
+ |
|
| 32 |
+ logDone("commit - echo foo and commit the image")
|
|
| 33 |
+} |
| 0 | 34 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,66 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// ensure that an added file shows up in docker diff |
|
| 10 |
+func TestDiffFilenameShownInOutput(t *testing.T) {
|
|
| 11 |
+ containerCmd := `echo foo > /root/bar` |
|
| 12 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd) |
|
| 13 |
+ cid, _, err := runCommandWithOutput(runCmd) |
|
| 14 |
+ errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
|
|
| 15 |
+ |
|
| 16 |
+ cleanCID := stripTrailingCharacters(cid) |
|
| 17 |
+ |
|
| 18 |
+ diffCmd := exec.Command(dockerBinary, "diff", cleanCID) |
|
| 19 |
+ out, _, err := runCommandWithOutput(diffCmd) |
|
| 20 |
+ errorOut(err, t, fmt.Sprintf("failed to run diff: %v %v", out, err))
|
|
| 21 |
+ |
|
| 22 |
+ found := false |
|
| 23 |
+ for _, line := range strings.Split(out, "\n") {
|
|
| 24 |
+ if strings.Contains("A /root/bar", line) {
|
|
| 25 |
+ found = true |
|
| 26 |
+ break |
|
| 27 |
+ } |
|
| 28 |
+ } |
|
| 29 |
+ if !found {
|
|
| 30 |
+ t.Errorf("couldn't find the new file in docker diff's output: %v", out)
|
|
| 31 |
+ } |
|
| 32 |
+ go deleteContainer(cleanCID) |
|
| 33 |
+ |
|
| 34 |
+ logDone("diff - check if created file shows up")
|
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+// test to ensure GH #3840 doesn't occur any more |
|
| 38 |
+func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) {
|
|
| 39 |
+ // this is a list of files which shouldn't show up in `docker diff` |
|
| 40 |
+ dockerinitFiles := []string{"/etc/resolv.conf", "/etc/hostname", "/etc/hosts", "/.dockerinit", "/.dockerenv"}
|
|
| 41 |
+ |
|
| 42 |
+ // we might not run into this problem from the first run, so start a few containers |
|
| 43 |
+ for i := 0; i < 20; i++ {
|
|
| 44 |
+ containerCmd := `echo foo > /root/bar` |
|
| 45 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd) |
|
| 46 |
+ cid, _, err := runCommandWithOutput(runCmd) |
|
| 47 |
+ errorOut(err, t, fmt.Sprintf("%s", err))
|
|
| 48 |
+ |
|
| 49 |
+ cleanCID := stripTrailingCharacters(cid) |
|
| 50 |
+ |
|
| 51 |
+ diffCmd := exec.Command(dockerBinary, "diff", cleanCID) |
|
| 52 |
+ out, _, err := runCommandWithOutput(diffCmd) |
|
| 53 |
+ errorOut(err, t, fmt.Sprintf("failed to run diff: %v %v", out, err))
|
|
| 54 |
+ |
|
| 55 |
+ go deleteContainer(cleanCID) |
|
| 56 |
+ |
|
| 57 |
+ for _, filename := range dockerinitFiles {
|
|
| 58 |
+ if strings.Contains(out, filename) {
|
|
| 59 |
+ t.Errorf("found file which should've been ignored %v in diff output", filename)
|
|
| 60 |
+ } |
|
| 61 |
+ } |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ logDone("diff - check if ignored files show up in diff")
|
|
| 65 |
+} |
| 0 | 66 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os" |
|
| 5 |
+ "os/exec" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// export an image and try to import it into a new one |
|
| 10 |
+func TestExportContainerAndImportImage(t *testing.T) {
|
|
| 11 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") |
|
| 12 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 13 |
+ if err != nil {
|
|
| 14 |
+ t.Fatal("failed to create a container", out, err)
|
|
| 15 |
+ } |
|
| 16 |
+ |
|
| 17 |
+ cleanedContainerID := stripTrailingCharacters(out) |
|
| 18 |
+ |
|
| 19 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) |
|
| 20 |
+ out, _, err = runCommandWithOutput(inspectCmd) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ t.Fatalf("output should've been a container id: %s %s ", cleanedContainerID, err)
|
|
| 23 |
+ } |
|
| 24 |
+ |
|
| 25 |
+ exportCmdTemplate := `%v export %v > /tmp/testexp.tar` |
|
| 26 |
+ exportCmdFinal := fmt.Sprintf(exportCmdTemplate, dockerBinary, cleanedContainerID) |
|
| 27 |
+ exportCmd := exec.Command("bash", "-c", exportCmdFinal)
|
|
| 28 |
+ out, _, err = runCommandWithOutput(exportCmd) |
|
| 29 |
+ errorOut(err, t, fmt.Sprintf("failed to export container: %v %v", out, err))
|
|
| 30 |
+ |
|
| 31 |
+ importCmdFinal := `cat /tmp/testexp.tar | docker import - testexp` |
|
| 32 |
+ importCmd := exec.Command("bash", "-c", importCmdFinal)
|
|
| 33 |
+ out, _, err = runCommandWithOutput(importCmd) |
|
| 34 |
+ errorOut(err, t, fmt.Sprintf("failed to import image: %v %v", out, err))
|
|
| 35 |
+ |
|
| 36 |
+ cleanedImageID := stripTrailingCharacters(out) |
|
| 37 |
+ |
|
| 38 |
+ inspectCmd = exec.Command(dockerBinary, "inspect", cleanedImageID) |
|
| 39 |
+ out, _, err = runCommandWithOutput(inspectCmd) |
|
| 40 |
+ errorOut(err, t, fmt.Sprintf("output should've been an image id: %v %v", out, err))
|
|
| 41 |
+ |
|
| 42 |
+ go deleteImages("testexp")
|
|
| 43 |
+ go deleteContainer(cleanedContainerID) |
|
| 44 |
+ |
|
| 45 |
+ os.Remove("/tmp/testexp.tar")
|
|
| 46 |
+ |
|
| 47 |
+ logDone("export - export a container")
|
|
| 48 |
+ logDone("import - import an image")
|
|
| 49 |
+} |
| 0 | 50 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,20 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func TestImagesEnsureImageIsListed(t *testing.T) {
|
|
| 10 |
+ imagesCmd := exec.Command(dockerBinary, "images") |
|
| 11 |
+ out, _, err := runCommandWithOutput(imagesCmd) |
|
| 12 |
+ errorOut(err, t, fmt.Sprintf("listing images failed with errors: %v", err))
|
|
| 13 |
+ |
|
| 14 |
+ if !strings.Contains(out, "busybox") {
|
|
| 15 |
+ t.Fatal("images should've listed busybox")
|
|
| 16 |
+ } |
|
| 17 |
+ |
|
| 18 |
+ logDone("images - busybox should be listed")
|
|
| 19 |
+} |
| 0 | 20 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// ensure docker info succeeds |
|
| 10 |
+func TestInfoEnsureSucceeds(t *testing.T) {
|
|
| 11 |
+ versionCmd := exec.Command(dockerBinary, "info") |
|
| 12 |
+ out, exitCode, err := runCommandWithOutput(versionCmd) |
|
| 13 |
+ errorOut(err, t, fmt.Sprintf("encountered error while running docker info: %v", err))
|
|
| 14 |
+ |
|
| 15 |
+ if err != nil || exitCode != 0 {
|
|
| 16 |
+ t.Fatal("failed to execute docker info")
|
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ stringsToCheck := []string{"Containers:", "Execution Driver:", "Kernel Version:"}
|
|
| 20 |
+ |
|
| 21 |
+ for _, linePrefix := range stringsToCheck {
|
|
| 22 |
+ if !strings.Contains(out, linePrefix) {
|
|
| 23 |
+ t.Errorf("couldn't find string %v in output", linePrefix)
|
|
| 24 |
+ } |
|
| 25 |
+ } |
|
| 26 |
+ |
|
| 27 |
+ logDone("info - verify that it works")
|
|
| 28 |
+} |
| 0 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,36 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func TestKillContainer(t *testing.T) {
|
|
| 10 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10") |
|
| 11 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 12 |
+ errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err))
|
|
| 13 |
+ |
|
| 14 |
+ cleanedContainerID := stripTrailingCharacters(out) |
|
| 15 |
+ |
|
| 16 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) |
|
| 17 |
+ inspectOut, _, err := runCommandWithOutput(inspectCmd) |
|
| 18 |
+ errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err))
|
|
| 19 |
+ |
|
| 20 |
+ killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID) |
|
| 21 |
+ out, _, err = runCommandWithOutput(killCmd) |
|
| 22 |
+ errorOut(err, t, fmt.Sprintf("failed to kill container: %v %v", out, err))
|
|
| 23 |
+ |
|
| 24 |
+ listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q") |
|
| 25 |
+ out, _, err = runCommandWithOutput(listRunningContainersCmd) |
|
| 26 |
+ errorOut(err, t, fmt.Sprintf("failed to list running containers: %v", err))
|
|
| 27 |
+ |
|
| 28 |
+ if strings.Contains(out, cleanedContainerID) {
|
|
| 29 |
+ t.Fatal("killed container is still running")
|
|
| 30 |
+ } |
|
| 31 |
+ |
|
| 32 |
+ go deleteContainer(cleanedContainerID) |
|
| 33 |
+ |
|
| 34 |
+ logDone("kill - kill container running sleep 10")
|
|
| 35 |
+} |
| 0 | 36 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,30 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "testing" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// pulling an image from the central registry should work |
|
| 9 |
+func TestPullImageFromCentralRegistry(t *testing.T) {
|
|
| 10 |
+ pullCmd := exec.Command(dockerBinary, "pull", "busybox") |
|
| 11 |
+ out, exitCode, err := runCommandWithOutput(pullCmd) |
|
| 12 |
+ errorOut(err, t, fmt.Sprintf("%s %s", out, err))
|
|
| 13 |
+ |
|
| 14 |
+ if err != nil || exitCode != 0 {
|
|
| 15 |
+ t.Fatal("pulling the busybox image from the registry has failed")
|
|
| 16 |
+ } |
|
| 17 |
+ logDone("pull - pull busybox")
|
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+// pulling a non-existing image from the central registry should return a non-zero exit code |
|
| 21 |
+func TestPullNonExistingImage(t *testing.T) {
|
|
| 22 |
+ pullCmd := exec.Command(dockerBinary, "pull", "fooblahblah1234") |
|
| 23 |
+ _, exitCode, err := runCommandWithOutput(pullCmd) |
|
| 24 |
+ |
|
| 25 |
+ if err == nil || exitCode == 0 {
|
|
| 26 |
+ t.Fatal("expected non-zero exit status when pulling non-existing image")
|
|
| 27 |
+ } |
|
| 28 |
+ logDone("pull - pull fooblahblah1234 (non-existing image)")
|
|
| 29 |
+} |
| 0 | 30 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,48 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "testing" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// these tests need a freshly started empty private docker registry |
|
| 9 |
+ |
|
| 10 |
+// pulling an image from the central registry should work |
|
| 11 |
+func TestPushBusyboxImage(t *testing.T) {
|
|
| 12 |
+ // skip this test until we're able to use a registry |
|
| 13 |
+ t.Skip() |
|
| 14 |
+ // tag the image to upload it tot he private registry |
|
| 15 |
+ repoName := fmt.Sprintf("%v/busybox", privateRegistryURL)
|
|
| 16 |
+ tagCmd := exec.Command(dockerBinary, "tag", "busybox", repoName) |
|
| 17 |
+ out, exitCode, err := runCommandWithOutput(tagCmd) |
|
| 18 |
+ errorOut(err, t, fmt.Sprintf("%v %v", out, err))
|
|
| 19 |
+ |
|
| 20 |
+ if err != nil || exitCode != 0 {
|
|
| 21 |
+ t.Fatal("image tagging failed")
|
|
| 22 |
+ } |
|
| 23 |
+ |
|
| 24 |
+ pushCmd := exec.Command(dockerBinary, "push", repoName) |
|
| 25 |
+ out, exitCode, err = runCommandWithOutput(pushCmd) |
|
| 26 |
+ errorOut(err, t, fmt.Sprintf("%v %v", out, err))
|
|
| 27 |
+ |
|
| 28 |
+ go deleteImages(repoName) |
|
| 29 |
+ |
|
| 30 |
+ if err != nil || exitCode != 0 {
|
|
| 31 |
+ t.Fatal("pushing the image to the private registry has failed")
|
|
| 32 |
+ } |
|
| 33 |
+ logDone("push - push busybox to private registry")
|
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+// pushing an image without a prefix should throw an error |
|
| 37 |
+func TestPushUnprefixedRepo(t *testing.T) {
|
|
| 38 |
+ // skip this test until we're able to use a registry |
|
| 39 |
+ t.Skip() |
|
| 40 |
+ pushCmd := exec.Command(dockerBinary, "push", "busybox") |
|
| 41 |
+ _, exitCode, err := runCommandWithOutput(pushCmd) |
|
| 42 |
+ |
|
| 43 |
+ if err == nil || exitCode == 0 {
|
|
| 44 |
+ t.Fatal("pushing an unprefixed repo didn't result in a non-zero exit status")
|
|
| 45 |
+ } |
|
| 46 |
+ logDone("push - push unprefixed busybox repo --> must fail")
|
|
| 47 |
+} |
| 0 | 48 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,255 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// "test123" should be printed by docker run |
|
| 10 |
+func TestDockerRunEchoStdout(t *testing.T) {
|
|
| 11 |
+ runCmd := exec.Command(dockerBinary, "run", "busybox", "echo", "test123") |
|
| 12 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 13 |
+ errorOut(err, t, out) |
|
| 14 |
+ |
|
| 15 |
+ if out != "test123\n" {
|
|
| 16 |
+ t.Errorf("container should've printed 'test123'")
|
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ deleteAllContainers() |
|
| 20 |
+ |
|
| 21 |
+ logDone("run - echo test123")
|
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+// "test" should be printed |
|
| 25 |
+func TestDockerRunEchoStdoutWithMemoryLimit(t *testing.T) {
|
|
| 26 |
+ runCmd := exec.Command(dockerBinary, "run", "-m", "2786432", "busybox", "echo", "test") |
|
| 27 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 28 |
+ errorOut(err, t, out) |
|
| 29 |
+ |
|
| 30 |
+ if out != "test\n" {
|
|
| 31 |
+ t.Errorf("container should've printed 'test'")
|
|
| 32 |
+ |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ deleteAllContainers() |
|
| 36 |
+ |
|
| 37 |
+ logDone("run - echo with memory limit")
|
|
| 38 |
+} |
|
| 39 |
+ |
|
| 40 |
+// "test" should be printed |
|
| 41 |
+func TestDockerRunEchoStdoutWitCPULimit(t *testing.T) {
|
|
| 42 |
+ runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "busybox", "echo", "test") |
|
| 43 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 44 |
+ errorOut(err, t, out) |
|
| 45 |
+ |
|
| 46 |
+ if out != "test\n" {
|
|
| 47 |
+ t.Errorf("container should've printed 'test'")
|
|
| 48 |
+ } |
|
| 49 |
+ |
|
| 50 |
+ deleteAllContainers() |
|
| 51 |
+ |
|
| 52 |
+ logDone("run - echo with CPU limit")
|
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+// "test" should be printed |
|
| 56 |
+func TestDockerRunEchoStdoutWithCPUAndMemoryLimit(t *testing.T) {
|
|
| 57 |
+ runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "-m", "2786432", "busybox", "echo", "test") |
|
| 58 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 59 |
+ errorOut(err, t, out) |
|
| 60 |
+ |
|
| 61 |
+ if out != "test\n" {
|
|
| 62 |
+ t.Errorf("container should've printed 'test'")
|
|
| 63 |
+ } |
|
| 64 |
+ |
|
| 65 |
+ deleteAllContainers() |
|
| 66 |
+ |
|
| 67 |
+ logDone("run - echo with CPU and memory limit")
|
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// "test" should be printed |
|
| 71 |
+func TestDockerRunEchoNamedContainer(t *testing.T) {
|
|
| 72 |
+ runCmd := exec.Command(dockerBinary, "run", "--name", "testfoonamedcontainer", "busybox", "echo", "test") |
|
| 73 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 74 |
+ errorOut(err, t, out) |
|
| 75 |
+ |
|
| 76 |
+ if out != "test\n" {
|
|
| 77 |
+ t.Errorf("container should've printed 'test'")
|
|
| 78 |
+ } |
|
| 79 |
+ |
|
| 80 |
+ if err := deleteContainer("testfoonamedcontainer"); err != nil {
|
|
| 81 |
+ t.Errorf("failed to remove the named container: %v", err)
|
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ deleteAllContainers() |
|
| 85 |
+ |
|
| 86 |
+ logDone("run - echo with named container")
|
|
| 87 |
+} |
|
| 88 |
+ |
|
| 89 |
+// it should be possible to ping Google DNS resolver |
|
| 90 |
+// this will fail when Internet access is unavailable |
|
| 91 |
+func TestDockerRunPingGoogle(t *testing.T) {
|
|
| 92 |
+ runCmd := exec.Command(dockerBinary, "run", "busybox", "ping", "-c", "1", "8.8.8.8") |
|
| 93 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 94 |
+ errorOut(err, t, out) |
|
| 95 |
+ |
|
| 96 |
+ errorOut(err, t, "container should've been able to ping 8.8.8.8") |
|
| 97 |
+ |
|
| 98 |
+ deleteAllContainers() |
|
| 99 |
+ |
|
| 100 |
+ logDone("run - ping 8.8.8.8")
|
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+// the exit code should be 0 |
|
| 104 |
+// some versions of lxc might make this test fail |
|
| 105 |
+func TestDockerRunExitCodeZero(t *testing.T) {
|
|
| 106 |
+ runCmd := exec.Command(dockerBinary, "run", "busybox", "true") |
|
| 107 |
+ exitCode, err := runCommand(runCmd) |
|
| 108 |
+ errorOut(err, t, fmt.Sprintf("%s", err))
|
|
| 109 |
+ |
|
| 110 |
+ if exitCode != 0 {
|
|
| 111 |
+ t.Errorf("container should've exited with exit code 0")
|
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ deleteAllContainers() |
|
| 115 |
+ |
|
| 116 |
+ logDone("run - exit with 0")
|
|
| 117 |
+} |
|
| 118 |
+ |
|
| 119 |
+// the exit code should be 1 |
|
| 120 |
+// some versions of lxc might make this test fail |
|
| 121 |
+func TestDockerRunExitCodeOne(t *testing.T) {
|
|
| 122 |
+ runCmd := exec.Command(dockerBinary, "run", "busybox", "false") |
|
| 123 |
+ exitCode, err := runCommand(runCmd) |
|
| 124 |
+ if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
|
|
| 125 |
+ t.Fatal(err) |
|
| 126 |
+ } |
|
| 127 |
+ if exitCode != 1 {
|
|
| 128 |
+ t.Errorf("container should've exited with exit code 1")
|
|
| 129 |
+ } |
|
| 130 |
+ |
|
| 131 |
+ deleteAllContainers() |
|
| 132 |
+ |
|
| 133 |
+ logDone("run - exit with 1")
|
|
| 134 |
+} |
|
| 135 |
+ |
|
| 136 |
+// it should be possible to pipe in data via stdin to a process running in a container |
|
| 137 |
+// some versions of lxc might make this test fail |
|
| 138 |
+func TestRunStdinPipe(t *testing.T) {
|
|
| 139 |
+ runCmd := exec.Command("bash", "-c", `echo "blahblah" | docker run -i -a stdin busybox cat`)
|
|
| 140 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 141 |
+ errorOut(err, t, out) |
|
| 142 |
+ |
|
| 143 |
+ out = stripTrailingCharacters(out) |
|
| 144 |
+ |
|
| 145 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", out) |
|
| 146 |
+ inspectOut, _, err := runCommandWithOutput(inspectCmd) |
|
| 147 |
+ errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
|
|
| 148 |
+ |
|
| 149 |
+ waitCmd := exec.Command(dockerBinary, "wait", out) |
|
| 150 |
+ _, _, err = runCommandWithOutput(waitCmd) |
|
| 151 |
+ errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
|
|
| 152 |
+ |
|
| 153 |
+ logsCmd := exec.Command(dockerBinary, "logs", out) |
|
| 154 |
+ containerLogs, _, err := runCommandWithOutput(logsCmd) |
|
| 155 |
+ errorOut(err, t, fmt.Sprintf("error thrown while trying to get container logs: %s", err))
|
|
| 156 |
+ |
|
| 157 |
+ containerLogs = stripTrailingCharacters(containerLogs) |
|
| 158 |
+ |
|
| 159 |
+ if containerLogs != "blahblah" {
|
|
| 160 |
+ t.Errorf("logs didn't print the container's logs %s", containerLogs)
|
|
| 161 |
+ } |
|
| 162 |
+ |
|
| 163 |
+ rmCmd := exec.Command(dockerBinary, "rm", out) |
|
| 164 |
+ _, _, err = runCommandWithOutput(rmCmd) |
|
| 165 |
+ errorOut(err, t, fmt.Sprintf("rm failed to remove container %s", err))
|
|
| 166 |
+ |
|
| 167 |
+ deleteAllContainers() |
|
| 168 |
+ |
|
| 169 |
+ logDone("run - pipe in with -i -a stdin")
|
|
| 170 |
+} |
|
| 171 |
+ |
|
| 172 |
+// the container's ID should be printed when starting a container in detached mode |
|
| 173 |
+func TestDockerRunDetachedContainerIDPrinting(t *testing.T) {
|
|
| 174 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") |
|
| 175 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 176 |
+ errorOut(err, t, out) |
|
| 177 |
+ |
|
| 178 |
+ out = stripTrailingCharacters(out) |
|
| 179 |
+ |
|
| 180 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", out) |
|
| 181 |
+ inspectOut, _, err := runCommandWithOutput(inspectCmd) |
|
| 182 |
+ errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
|
|
| 183 |
+ |
|
| 184 |
+ waitCmd := exec.Command(dockerBinary, "wait", out) |
|
| 185 |
+ _, _, err = runCommandWithOutput(waitCmd) |
|
| 186 |
+ errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
|
|
| 187 |
+ |
|
| 188 |
+ rmCmd := exec.Command(dockerBinary, "rm", out) |
|
| 189 |
+ rmOut, _, err := runCommandWithOutput(rmCmd) |
|
| 190 |
+ errorOut(err, t, "rm failed to remove container") |
|
| 191 |
+ |
|
| 192 |
+ rmOut = stripTrailingCharacters(rmOut) |
|
| 193 |
+ if rmOut != out {
|
|
| 194 |
+ t.Errorf("rm didn't print the container ID %s %s", out, rmOut)
|
|
| 195 |
+ } |
|
| 196 |
+ |
|
| 197 |
+ deleteAllContainers() |
|
| 198 |
+ |
|
| 199 |
+ logDone("run - print container ID in detached mode")
|
|
| 200 |
+} |
|
| 201 |
+ |
|
| 202 |
+// the working directory should be set correctly |
|
| 203 |
+func TestDockerRunWorkingDirectory(t *testing.T) {
|
|
| 204 |
+ runCmd := exec.Command(dockerBinary, "run", "-w", "/root", "busybox", "pwd") |
|
| 205 |
+ out, _, _, err := runCommandWithStdoutStderr(runCmd) |
|
| 206 |
+ errorOut(err, t, out) |
|
| 207 |
+ |
|
| 208 |
+ out = stripTrailingCharacters(out) |
|
| 209 |
+ |
|
| 210 |
+ if out != "/root" {
|
|
| 211 |
+ t.Errorf("-w failed to set working directory")
|
|
| 212 |
+ } |
|
| 213 |
+ |
|
| 214 |
+ runCmd = exec.Command(dockerBinary, "run", "--workdir", "/root", "busybox", "pwd") |
|
| 215 |
+ out, _, _, err = runCommandWithStdoutStderr(runCmd) |
|
| 216 |
+ errorOut(err, t, out) |
|
| 217 |
+ |
|
| 218 |
+ out = stripTrailingCharacters(out) |
|
| 219 |
+ |
|
| 220 |
+ if out != "/root" {
|
|
| 221 |
+ t.Errorf("--workdir failed to set working directory")
|
|
| 222 |
+ } |
|
| 223 |
+ |
|
| 224 |
+ deleteAllContainers() |
|
| 225 |
+ |
|
| 226 |
+ logDone("run - run with working directory set by -w")
|
|
| 227 |
+ logDone("run - run with working directory set by --workdir")
|
|
| 228 |
+} |
|
| 229 |
+ |
|
| 230 |
+// pinging Google's DNS resolver should fail when we disable the networking |
|
| 231 |
+func TestDockerRunWithoutNetworking(t *testing.T) {
|
|
| 232 |
+ runCmd := exec.Command(dockerBinary, "run", "--networking=false", "busybox", "ping", "-c", "1", "8.8.8.8") |
|
| 233 |
+ out, _, exitCode, err := runCommandWithStdoutStderr(runCmd) |
|
| 234 |
+ if err != nil && exitCode != 1 {
|
|
| 235 |
+ t.Fatal(out, err) |
|
| 236 |
+ } |
|
| 237 |
+ if exitCode != 1 {
|
|
| 238 |
+ t.Errorf("--networking=false should've disabled the network; the container shouldn't have been able to ping 8.8.8.8")
|
|
| 239 |
+ } |
|
| 240 |
+ |
|
| 241 |
+ runCmd = exec.Command(dockerBinary, "run", "-n=false", "busybox", "ping", "-c", "1", "8.8.8.8") |
|
| 242 |
+ out, _, exitCode, err = runCommandWithStdoutStderr(runCmd) |
|
| 243 |
+ if err != nil && exitCode != 1 {
|
|
| 244 |
+ t.Fatal(out, err) |
|
| 245 |
+ } |
|
| 246 |
+ if exitCode != 1 {
|
|
| 247 |
+ t.Errorf("-n=false should've disabled the network; the container shouldn't have been able to ping 8.8.8.8")
|
|
| 248 |
+ } |
|
| 249 |
+ |
|
| 250 |
+ deleteAllContainers() |
|
| 251 |
+ |
|
| 252 |
+ logDone("run - disable networking with --networking=false")
|
|
| 253 |
+ logDone("run - disable networking with -n=false")
|
|
| 254 |
+} |
| 0 | 255 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,52 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os" |
|
| 5 |
+ "os/exec" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// save a repo and try to load it |
|
| 10 |
+func TestSaveAndLoadRepo(t *testing.T) {
|
|
| 11 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") |
|
| 12 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 13 |
+ errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err))
|
|
| 14 |
+ |
|
| 15 |
+ cleanedContainerID := stripTrailingCharacters(out) |
|
| 16 |
+ |
|
| 17 |
+ repoName := "foobar-save-load-test" |
|
| 18 |
+ |
|
| 19 |
+ inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) |
|
| 20 |
+ out, _, err = runCommandWithOutput(inspectCmd) |
|
| 21 |
+ errorOut(err, t, fmt.Sprintf("output should've been a container id: %v %v", cleanedContainerID, err))
|
|
| 22 |
+ |
|
| 23 |
+ commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName) |
|
| 24 |
+ out, _, err = runCommandWithOutput(commitCmd) |
|
| 25 |
+ errorOut(err, t, fmt.Sprintf("failed to commit container: %v %v", out, err))
|
|
| 26 |
+ |
|
| 27 |
+ saveCmdTemplate := `%v save %v > /tmp/foobar-save-load-test.tar` |
|
| 28 |
+ saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName) |
|
| 29 |
+ saveCmd := exec.Command("bash", "-c", saveCmdFinal)
|
|
| 30 |
+ out, _, err = runCommandWithOutput(saveCmd) |
|
| 31 |
+ errorOut(err, t, fmt.Sprintf("failed to save repo: %v %v", out, err))
|
|
| 32 |
+ |
|
| 33 |
+ deleteImages(repoName) |
|
| 34 |
+ |
|
| 35 |
+ loadCmdFinal := `cat /tmp/foobar-save-load-test.tar | docker load` |
|
| 36 |
+ loadCmd := exec.Command("bash", "-c", loadCmdFinal)
|
|
| 37 |
+ out, _, err = runCommandWithOutput(loadCmd) |
|
| 38 |
+ errorOut(err, t, fmt.Sprintf("failed to load repo: %v %v", out, err))
|
|
| 39 |
+ |
|
| 40 |
+ inspectCmd = exec.Command(dockerBinary, "inspect", repoName) |
|
| 41 |
+ out, _, err = runCommandWithOutput(inspectCmd) |
|
| 42 |
+ errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", out, err))
|
|
| 43 |
+ |
|
| 44 |
+ go deleteImages(repoName) |
|
| 45 |
+ go deleteContainer(cleanedContainerID) |
|
| 46 |
+ |
|
| 47 |
+ os.Remove("/tmp/foobar-save-load-test.tar")
|
|
| 48 |
+ |
|
| 49 |
+ logDone("save - save a repo")
|
|
| 50 |
+ logDone("load - load a repo")
|
|
| 51 |
+} |
| 0 | 52 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// search for repos named "registry" on the central registry |
|
| 10 |
+func TestSearchOnCentralRegistry(t *testing.T) {
|
|
| 11 |
+ searchCmd := exec.Command(dockerBinary) |
|
| 12 |
+ out, exitCode, err := runCommandWithOutput(searchCmd) |
|
| 13 |
+ errorOut(err, t, fmt.Sprintf("encountered error while searching: %v", err))
|
|
| 14 |
+ |
|
| 15 |
+ if err != nil || exitCode != 0 {
|
|
| 16 |
+ t.Fatal("failed to search on the central registry")
|
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ if !strings.Contains(out, "registry") {
|
|
| 20 |
+ t.Fatal("couldn't find any repository named (or containing) 'registry'")
|
|
| 21 |
+ } |
|
| 22 |
+ |
|
| 23 |
+ logDone("search - search for repositories named (or containing) 'registry'")
|
|
| 24 |
+} |
| 0 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,86 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "testing" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// tagging a named image in a new unprefixed repo should work |
|
| 9 |
+func TestTagUnprefixedRepoByName(t *testing.T) {
|
|
| 10 |
+ pullCmd := exec.Command(dockerBinary, "pull", "busybox") |
|
| 11 |
+ out, exitCode, err := runCommandWithOutput(pullCmd) |
|
| 12 |
+ errorOut(err, t, fmt.Sprintf("%s %s", out, err))
|
|
| 13 |
+ |
|
| 14 |
+ if err != nil || exitCode != 0 {
|
|
| 15 |
+ t.Fatal("pulling the busybox image from the registry has failed")
|
|
| 16 |
+ } |
|
| 17 |
+ |
|
| 18 |
+ tagCmd := exec.Command(dockerBinary, "tag", "busybox", "testfoobarbaz") |
|
| 19 |
+ out, _, err = runCommandWithOutput(tagCmd) |
|
| 20 |
+ errorOut(err, t, fmt.Sprintf("%v %v", out, err))
|
|
| 21 |
+ |
|
| 22 |
+ deleteImages("testfoobarbaz")
|
|
| 23 |
+ |
|
| 24 |
+ logDone("tag - busybox -> testfoobarbaz")
|
|
| 25 |
+} |
|
| 26 |
+ |
|
| 27 |
+// tagging an image by ID in a new unprefixed repo should work |
|
| 28 |
+func TestTagUnprefixedRepoByID(t *testing.T) {
|
|
| 29 |
+ getIDCmd := exec.Command(dockerBinary, "inspect", "-f", "{{.id}}", "busybox")
|
|
| 30 |
+ out, _, err := runCommandWithOutput(getIDCmd) |
|
| 31 |
+ errorOut(err, t, fmt.Sprintf("failed to get the image ID of busybox: %v", err))
|
|
| 32 |
+ |
|
| 33 |
+ cleanedImageID := stripTrailingCharacters(out) |
|
| 34 |
+ tagCmd := exec.Command(dockerBinary, "tag", cleanedImageID, "testfoobarbaz") |
|
| 35 |
+ out, _, err = runCommandWithOutput(tagCmd) |
|
| 36 |
+ errorOut(err, t, fmt.Sprintf("%s %s", out, err))
|
|
| 37 |
+ |
|
| 38 |
+ deleteImages("testfoobarbaz")
|
|
| 39 |
+ |
|
| 40 |
+ logDone("tag - busybox's image ID -> testfoobarbaz")
|
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// ensure we don't allow the use of invalid tags; these tag operations should fail |
|
| 44 |
+func TestTagInvalidUnprefixedRepo(t *testing.T) {
|
|
| 45 |
+ // skip this until we start blocking bad tags |
|
| 46 |
+ t.Skip() |
|
| 47 |
+ |
|
| 48 |
+ invalidRepos := []string{"-foo", "fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo", "f"}
|
|
| 49 |
+ |
|
| 50 |
+ for _, repo := range invalidRepos {
|
|
| 51 |
+ tagCmd := exec.Command(dockerBinary, "tag", "busybox", repo) |
|
| 52 |
+ _, _, err := runCommandWithOutput(tagCmd) |
|
| 53 |
+ if err == nil {
|
|
| 54 |
+ t.Errorf("tag busybox %v should have failed", repo)
|
|
| 55 |
+ continue |
|
| 56 |
+ } |
|
| 57 |
+ logMessage := fmt.Sprintf("tag - busybox %v --> must fail", repo)
|
|
| 58 |
+ logDone(logMessage) |
|
| 59 |
+ } |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 62 |
+// ensure we allow the use of valid tags |
|
| 63 |
+func TestTagValidPrefixedRepo(t *testing.T) {
|
|
| 64 |
+ pullCmd := exec.Command(dockerBinary, "pull", "busybox") |
|
| 65 |
+ out, exitCode, err := runCommandWithOutput(pullCmd) |
|
| 66 |
+ errorOut(err, t, fmt.Sprintf("%s %s", out, err))
|
|
| 67 |
+ |
|
| 68 |
+ if err != nil || exitCode != 0 {
|
|
| 69 |
+ t.Fatal("pulling the busybox image from the registry has failed")
|
|
| 70 |
+ } |
|
| 71 |
+ |
|
| 72 |
+ validRepos := []string{"fooo/bar", "fooaa/test"}
|
|
| 73 |
+ |
|
| 74 |
+ for _, repo := range validRepos {
|
|
| 75 |
+ tagCmd := exec.Command(dockerBinary, "tag", "busybox", repo) |
|
| 76 |
+ _, _, err := runCommandWithOutput(tagCmd) |
|
| 77 |
+ if err != nil {
|
|
| 78 |
+ t.Errorf("tag busybox %v should have worked: %s", repo, err)
|
|
| 79 |
+ continue |
|
| 80 |
+ } |
|
| 81 |
+ go deleteImages(repo) |
|
| 82 |
+ logMessage := fmt.Sprintf("tag - busybox %v", repo)
|
|
| 83 |
+ logDone(logMessage) |
|
| 84 |
+ } |
|
| 85 |
+} |
| 0 | 86 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,32 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func TestTop(t *testing.T) {
|
|
| 10 |
+ runCmd := exec.Command(dockerBinary, "run", "-i", "-d", "busybox", "sleep", "20") |
|
| 11 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 12 |
+ errorOut(err, t, fmt.Sprintf("failed to start the container: %v", err))
|
|
| 13 |
+ |
|
| 14 |
+ cleanedContainerID := stripTrailingCharacters(out) |
|
| 15 |
+ |
|
| 16 |
+ topCmd := exec.Command(dockerBinary, "top", cleanedContainerID) |
|
| 17 |
+ out, _, err = runCommandWithOutput(topCmd) |
|
| 18 |
+ errorOut(err, t, fmt.Sprintf("failed to run top: %v %v", out, err))
|
|
| 19 |
+ |
|
| 20 |
+ killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID) |
|
| 21 |
+ _, err = runCommand(killCmd) |
|
| 22 |
+ errorOut(err, t, fmt.Sprintf("failed to kill container: %v", err))
|
|
| 23 |
+ |
|
| 24 |
+ go deleteContainer(cleanedContainerID) |
|
| 25 |
+ |
|
| 26 |
+ if !strings.Contains(out, "sleep 20") {
|
|
| 27 |
+ t.Fatal("top should've listed sleep 20 in the process list")
|
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ logDone("top - sleep process should be listed")
|
|
| 31 |
+} |
| 0 | 32 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+ "testing" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// ensure docker version works |
|
| 10 |
+func TestVersionEnsureSucceeds(t *testing.T) {
|
|
| 11 |
+ versionCmd := exec.Command(dockerBinary, "version") |
|
| 12 |
+ out, exitCode, err := runCommandWithOutput(versionCmd) |
|
| 13 |
+ errorOut(err, t, fmt.Sprintf("encountered error while running docker version: %v", err))
|
|
| 14 |
+ |
|
| 15 |
+ if err != nil || exitCode != 0 {
|
|
| 16 |
+ t.Fatal("failed to execute docker version")
|
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ stringsToCheck := []string{"Client version:", "Go version (client):", "Git commit (client):", "Server version:", "Git commit (server):", "Go version (server):", "Last stable version:"}
|
|
| 20 |
+ |
|
| 21 |
+ for _, linePrefix := range stringsToCheck {
|
|
| 22 |
+ if !strings.Contains(out, linePrefix) {
|
|
| 23 |
+ t.Errorf("couldn't find string %v in output", linePrefix)
|
|
| 24 |
+ } |
|
| 25 |
+ } |
|
| 26 |
+ |
|
| 27 |
+ logDone("version - verify that it works and that the output is properly formatted")
|
|
| 28 |
+} |
| 0 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+// the docker binary to use |
|
| 7 |
+var dockerBinary = "docker" |
|
| 8 |
+ |
|
| 9 |
+// the private registry image to use for tests involving the registry |
|
| 10 |
+var registryImageName = "registry" |
|
| 11 |
+ |
|
| 12 |
+// the private registry to use for tests |
|
| 13 |
+var privateRegistryURL = "127.0.0.1:5000" |
|
| 14 |
+ |
|
| 15 |
+var workingDirectory string |
|
| 16 |
+ |
|
| 17 |
+func init() {
|
|
| 18 |
+ if dockerBin := os.Getenv("DOCKER_BINARY"); dockerBin != "" {
|
|
| 19 |
+ dockerBinary = dockerBin |
|
| 20 |
+ } |
|
| 21 |
+ if registryImage := os.Getenv("REGISTRY_IMAGE"); registryImage != "" {
|
|
| 22 |
+ registryImageName = registryImage |
|
| 23 |
+ } |
|
| 24 |
+ if registry := os.Getenv("REGISTRY_URL"); registry != "" {
|
|
| 25 |
+ privateRegistryURL = registry |
|
| 26 |
+ } |
|
| 27 |
+ workingDirectory, _ = os.Getwd() |
|
| 28 |
+} |
| 0 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,56 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os/exec" |
|
| 5 |
+ "strings" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func deleteContainer(container string) error {
|
|
| 9 |
+ container = strings.Replace(container, "\n", " ", -1) |
|
| 10 |
+ container = strings.Trim(container, " ") |
|
| 11 |
+ rmArgs := fmt.Sprintf("rm %v", container)
|
|
| 12 |
+ rmSplitArgs := strings.Split(rmArgs, " ") |
|
| 13 |
+ rmCmd := exec.Command(dockerBinary, rmSplitArgs...) |
|
| 14 |
+ exitCode, err := runCommand(rmCmd) |
|
| 15 |
+ // set error manually if not set |
|
| 16 |
+ if exitCode != 0 && err == nil {
|
|
| 17 |
+ err = fmt.Errorf("failed to remove container: `docker rm` exit is non-zero")
|
|
| 18 |
+ } |
|
| 19 |
+ |
|
| 20 |
+ return err |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+func getAllContainers() (string, error) {
|
|
| 24 |
+ getContainersCmd := exec.Command(dockerBinary, "ps", "-q", "-a") |
|
| 25 |
+ out, exitCode, err := runCommandWithOutput(getContainersCmd) |
|
| 26 |
+ if exitCode != 0 && err == nil {
|
|
| 27 |
+ err = fmt.Errorf("failed to get a list of containers: %v\n", out)
|
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ return out, err |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func deleteAllContainers() error {
|
|
| 34 |
+ containers, err := getAllContainers() |
|
| 35 |
+ if err != nil {
|
|
| 36 |
+ fmt.Println(containers) |
|
| 37 |
+ return err |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ if err = deleteContainer(containers); err != nil {
|
|
| 41 |
+ return err |
|
| 42 |
+ } |
|
| 43 |
+ return nil |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+func deleteImages(images string) error {
|
|
| 47 |
+ rmiCmd := exec.Command(dockerBinary, "rmi", images) |
|
| 48 |
+ exitCode, err := runCommand(rmiCmd) |
|
| 49 |
+ // set error manually if not set |
|
| 50 |
+ if exitCode != 0 && err == nil {
|
|
| 51 |
+ err = fmt.Errorf("failed to remove image: `docker rmi` exit is non-zero")
|
|
| 52 |
+ } |
|
| 53 |
+ |
|
| 54 |
+ return err |
|
| 55 |
+} |
| 0 | 56 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,109 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "bytes" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "io" |
|
| 6 |
+ "os/exec" |
|
| 7 |
+ "strings" |
|
| 8 |
+ "syscall" |
|
| 9 |
+ "testing" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+func getExitCode(err error) (int, error) {
|
|
| 13 |
+ exitCode := 0 |
|
| 14 |
+ if exiterr, ok := err.(*exec.ExitError); ok {
|
|
| 15 |
+ if procExit := exiterr.Sys().(syscall.WaitStatus); ok {
|
|
| 16 |
+ return procExit.ExitStatus(), nil |
|
| 17 |
+ } |
|
| 18 |
+ } |
|
| 19 |
+ return exitCode, fmt.Errorf("failed to get exit code")
|
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) {
|
|
| 23 |
+ exitCode = 0 |
|
| 24 |
+ out, err := cmd.CombinedOutput() |
|
| 25 |
+ if err != nil {
|
|
| 26 |
+ var exiterr error |
|
| 27 |
+ if exitCode, exiterr = getExitCode(err); exiterr != nil {
|
|
| 28 |
+ // TODO: Fix this so we check the error's text. |
|
| 29 |
+ // we've failed to retrieve exit code, so we set it to 127 |
|
| 30 |
+ exitCode = 127 |
|
| 31 |
+ } |
|
| 32 |
+ } |
|
| 33 |
+ output = string(out) |
|
| 34 |
+ return |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+func runCommandWithStdoutStderr(cmd *exec.Cmd) (stdout string, stderr string, exitCode int, err error) {
|
|
| 38 |
+ exitCode = 0 |
|
| 39 |
+ var stderrBuffer bytes.Buffer |
|
| 40 |
+ stderrPipe, err := cmd.StderrPipe() |
|
| 41 |
+ if err != nil {
|
|
| 42 |
+ return "", "", -1, err |
|
| 43 |
+ } |
|
| 44 |
+ go io.Copy(&stderrBuffer, stderrPipe) |
|
| 45 |
+ out, err := cmd.Output() |
|
| 46 |
+ |
|
| 47 |
+ if err != nil {
|
|
| 48 |
+ var exiterr error |
|
| 49 |
+ if exitCode, exiterr = getExitCode(err); exiterr != nil {
|
|
| 50 |
+ // TODO: Fix this so we check the error's text. |
|
| 51 |
+ // we've failed to retrieve exit code, so we set it to 127 |
|
| 52 |
+ exitCode = 127 |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+ stdout = string(out) |
|
| 56 |
+ stderr = string(stderrBuffer.Bytes()) |
|
| 57 |
+ return |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+func runCommand(cmd *exec.Cmd) (exitCode int, err error) {
|
|
| 61 |
+ exitCode = 0 |
|
| 62 |
+ err = cmd.Run() |
|
| 63 |
+ if err != nil {
|
|
| 64 |
+ var exiterr error |
|
| 65 |
+ if exitCode, exiterr = getExitCode(err); exiterr != nil {
|
|
| 66 |
+ // TODO: Fix this so we check the error's text. |
|
| 67 |
+ // we've failed to retrieve exit code, so we set it to 127 |
|
| 68 |
+ exitCode = 127 |
|
| 69 |
+ } |
|
| 70 |
+ } |
|
| 71 |
+ return |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+func startCommand(cmd *exec.Cmd) (exitCode int, err error) {
|
|
| 75 |
+ exitCode = 0 |
|
| 76 |
+ err = cmd.Start() |
|
| 77 |
+ if err != nil {
|
|
| 78 |
+ var exiterr error |
|
| 79 |
+ if exitCode, exiterr = getExitCode(err); exiterr != nil {
|
|
| 80 |
+ // TODO: Fix this so we check the error's text. |
|
| 81 |
+ // we've failed to retrieve exit code, so we set it to 127 |
|
| 82 |
+ exitCode = 127 |
|
| 83 |
+ } |
|
| 84 |
+ } |
|
| 85 |
+ return |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+func logDone(message string) {
|
|
| 89 |
+ fmt.Printf("[PASSED]: %s\n", message)
|
|
| 90 |
+} |
|
| 91 |
+ |
|
| 92 |
+func stripTrailingCharacters(target string) string {
|
|
| 93 |
+ target = strings.Trim(target, "\n") |
|
| 94 |
+ target = strings.Trim(target, " ") |
|
| 95 |
+ return target |
|
| 96 |
+} |
|
| 97 |
+ |
|
| 98 |
+func errorOut(err error, t *testing.T, message string) {
|
|
| 99 |
+ if err != nil {
|
|
| 100 |
+ t.Fatal(message) |
|
| 101 |
+ } |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+func errorOutOnNonNilError(err error, t *testing.T, message string) {
|
|
| 105 |
+ if err == nil {
|
|
| 106 |
+ t.Fatalf(message) |
|
| 107 |
+ } |
|
| 108 |
+} |