e2e: fix subtests and block parallel unsafe tests

The big mechanical change here is to NOT store `t` as a field on
the `CLI` object (which has been renamed as well to fix the odd
capitalization). The way the tests are structured meant that the
"subtests" were using the _parent_ `*testing.T` instance, which
causes various oddities including confusing messages on failure
about a child test causing a panic in the parent.

Additionally, a few tests have been blocked from running in
parallel because they are sharing `compose.yaml` fixtures and
can fail as a result (e.g. due to a port conflict on the host).
I'll fix these in follow-up PRs but want to focus on correctness
for the tests before optimizing them.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
This commit is contained in:
Milas Bowman 2022-06-15 15:55:58 -04:00
parent 005fc25823
commit d9065050fd
22 changed files with 395 additions and 358 deletions

View File

@ -33,10 +33,10 @@ import (
)
func TestComposeCancel(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("metrics on cancel Compose build", func(t *testing.T) {
c.RunDockerComposeCmd("ls")
c.RunDockerComposeCmd(t, "ls")
buildProjectPath := "fixtures/build-infinite/compose.yaml"
// require a separate groupID from the process running tests, in order to simulate ctrl+C from a terminal.
@ -44,19 +44,22 @@ func TestComposeCancel(t *testing.T) {
cmd, stdout, stderr, err := StartWithNewGroupID(c.NewDockerCmd("compose", "-f", buildProjectPath, "build", "--progress", "plain"))
assert.NilError(t, err)
c.WaitForCondition(func() (bool, string) {
c.WaitForCondition(t, func() (bool, string) {
out := stdout.String()
errors := stderr.String()
return strings.Contains(out, "RUN sleep infinity"), fmt.Sprintf("'RUN sleep infinity' not found in : \n%s\nStderr: \n%s\n", out, errors)
return strings.Contains(out,
"RUN sleep infinity"), fmt.Sprintf("'RUN sleep infinity' not found in : \n%s\nStderr: \n%s\n", out,
errors)
}, 30*time.Second, 1*time.Second)
err = syscall.Kill(-cmd.Process.Pid, syscall.SIGINT) // simulate Ctrl-C : send signal to processGroup, children will have same groupId by default
assert.NilError(t, err)
c.WaitForCondition(func() (bool, string) {
c.WaitForCondition(t, func() (bool, string) {
out := stdout.String()
errors := stderr.String()
return strings.Contains(out, "CANCELED"), fmt.Sprintf("'CANCELED' not found in : \n%s\nStderr: \n%s\n", out, errors)
return strings.Contains(out, "CANCELED"), fmt.Sprintf("'CANCELED' not found in : \n%s\nStderr: \n%s\n", out,
errors)
}, 10*time.Second, 1*time.Second)
})
}

View File

@ -23,28 +23,28 @@ import (
)
func TestCascadeStop(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-cascade-stop"
t.Run("abort-on-container-exit", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--abort-on-container-exit")
res := c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--abort-on-container-exit")
res.Assert(t, icmd.Expected{ExitCode: 1, Out: `should_fail-1 exited with code 1`})
res.Assert(t, icmd.Expected{ExitCode: 1, Out: `Aborting on container exit...`})
})
t.Run("exit-code-from", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--exit-code-from=sleep")
res := c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--exit-code-from=sleep")
res.Assert(t, icmd.Expected{ExitCode: 137, Out: `should_fail-1 exited with code 1`})
res.Assert(t, icmd.Expected{ExitCode: 137, Out: `Aborting on container exit...`})
})
t.Run("exit-code-from unknown", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--exit-code-from=unknown")
res := c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/cascade-stop-test/compose.yaml", "--project-name", projectName, "up", "--exit-code-from=unknown")
res.Assert(t, icmd.Expected{ExitCode: 1, Err: `no such service: unknown`})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}

View File

@ -28,55 +28,55 @@ import (
)
func TestLocalComposeBuild(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("build named and unnamed images", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test_nginx")
c.RunDockerOrExitError("rmi", "custom-nginx")
c.RunDockerOrExitError(t, "rmi", "build-test_nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx")
res := c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "build")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build")
res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
c.RunDockerCmd("image", "inspect", "build-test_nginx")
c.RunDockerCmd("image", "inspect", "custom-nginx")
c.RunDockerCmd(t, "image", "inspect", "build-test_nginx")
c.RunDockerCmd(t, "image", "inspect", "custom-nginx")
})
t.Run("build with build-arg", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test_nginx")
c.RunDockerOrExitError("rmi", "custom-nginx")
c.RunDockerOrExitError(t, "rmi", "build-test_nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx")
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "build", "--build-arg", "FOO=BAR")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build", "--build-arg", "FOO=BAR")
res := c.RunDockerCmd("image", "inspect", "build-test_nginx")
res := c.RunDockerCmd(t, "image", "inspect", "build-test_nginx")
res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`})
})
t.Run("build with build-arg set by env", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test_nginx")
c.RunDockerOrExitError("rmi", "custom-nginx")
c.RunDockerOrExitError(t, "rmi", "build-test_nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx")
icmd.RunCmd(c.NewDockerCmd("compose", "--project-directory", "fixtures/build-test", "build", "--build-arg", "FOO"),
func(cmd *icmd.Cmd) {
cmd.Env = append(cmd.Env, "FOO=BAR")
})
res := c.RunDockerCmd("image", "inspect", "build-test_nginx")
res := c.RunDockerCmd(t, "image", "inspect", "build-test_nginx")
res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`})
})
t.Run("build with multiple build-args ", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "-f", "multi-args_multiargs")
c.RunDockerOrExitError(t, "rmi", "-f", "multi-args_multiargs")
cmd := c.NewDockerCmd("compose", "--project-directory", "fixtures/build-test/multi-args", "build")
icmd.RunCmd(cmd, func(cmd *icmd.Cmd) {
cmd.Env = append(cmd.Env, "DOCKER_BUILDKIT=0")
})
res := c.RunDockerCmd("image", "inspect", "multi-args_multiargs")
res := c.RunDockerCmd(t, "image", "inspect", "multi-args_multiargs")
res.Assert(t, icmd.Expected{Out: `"RESULT": "SUCCESS"`})
})
@ -86,7 +86,7 @@ func TestLocalComposeBuild(t *testing.T) {
os.Unsetenv("SSH_AUTH_SOCK") //nolint:errcheck
defer os.Setenv("SSH_AUTH_SOCK", defaultSSHAUTHSOCK) //nolint:errcheck
res := c.RunDockerComposeCmdNoCheck("--project-directory", "fixtures/build-test", "build", "--ssh", "")
res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test", "build", "--ssh", "")
res.Assert(t, icmd.Expected{
ExitCode: 1,
Err: "invalid empty ssh agent socket: make sure SSH_AUTH_SOCK is set",
@ -95,24 +95,24 @@ func TestLocalComposeBuild(t *testing.T) {
})
t.Run("build succeed with ssh from Compose file", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "build-test-ssh")
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test/ssh", "build")
c.RunDockerCmd("image", "inspect", "build-test-ssh")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test/ssh", "build")
c.RunDockerCmd(t, "image", "inspect", "build-test-ssh")
})
t.Run("build succeed with ssh from CLI", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "build-test-ssh")
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
c.RunDockerComposeCmd("-f", "fixtures/build-test/ssh/compose-without-ssh.yaml", "--project-directory",
c.RunDockerComposeCmd(t, "-f", "fixtures/build-test/ssh/compose-without-ssh.yaml", "--project-directory",
"fixtures/build-test/ssh", "build", "--no-cache", "--ssh", "fake-ssh=./fixtures/build-test/ssh/fake_rsa")
c.RunDockerCmd("image", "inspect", "build-test-ssh")
c.RunDockerCmd(t, "image", "inspect", "build-test-ssh")
})
t.Run("build failed with wrong ssh key id from CLI", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "build-test-ssh")
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
res := c.RunDockerComposeCmdNoCheck("-f", "fixtures/build-test/ssh/compose-without-ssh.yaml",
res := c.RunDockerComposeCmdNoCheck(t, "-f", "fixtures/build-test/ssh/compose-without-ssh.yaml",
"--project-directory", "fixtures/build-test/ssh", "build", "--no-cache", "--ssh",
"wrong-ssh=./fixtures/build-test/ssh/fake_rsa")
res.Assert(t, icmd.Expected{
@ -122,22 +122,22 @@ func TestLocalComposeBuild(t *testing.T) {
})
t.Run("build succeed as part of up with ssh from Compose file", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "build-test-ssh")
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test/ssh", "up", "-d", "--build")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test/ssh", "up", "-d", "--build")
t.Cleanup(func() {
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test/ssh", "down")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test/ssh", "down")
})
c.RunDockerCmd("image", "inspect", "build-test-ssh")
c.RunDockerCmd(t, "image", "inspect", "build-test-ssh")
})
t.Run("build as part of up", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "build-test_nginx")
c.RunDockerOrExitError("rmi", "custom-nginx")
c.RunDockerOrExitError(t, "rmi", "build-test_nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx")
res := c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "up", "-d")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d")
t.Cleanup(func() {
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "down")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down")
})
res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
@ -146,53 +146,53 @@ func TestLocalComposeBuild(t *testing.T) {
output := HTTPGetWithRetry(t, "http://localhost:8070", http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(output, "Hello from Nginx container"))
c.RunDockerCmd("image", "inspect", "build-test_nginx")
c.RunDockerCmd("image", "inspect", "custom-nginx")
c.RunDockerCmd(t, "image", "inspect", "build-test_nginx")
c.RunDockerCmd(t, "image", "inspect", "custom-nginx")
})
t.Run("no rebuild when up again", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "up", "-d")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d")
assert.Assert(t, !strings.Contains(res.Stdout(), "COPY static"), res.Stdout())
})
t.Run("rebuild when up --build", func(t *testing.T) {
res := c.RunDockerComposeCmd("--workdir", "fixtures/build-test", "up", "-d", "--build")
res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "up", "-d", "--build")
res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"})
})
t.Run("cleanup build project", func(t *testing.T) {
c.RunDockerComposeCmd("--project-directory", "fixtures/build-test", "down")
c.RunDockerCmd("rmi", "build-test_nginx")
c.RunDockerCmd("rmi", "custom-nginx")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down")
c.RunDockerCmd(t, "rmi", "build-test_nginx")
c.RunDockerCmd(t, "rmi", "custom-nginx")
})
}
func TestBuildSecrets(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("build with secrets", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test-secret")
c.RunDockerOrExitError(t, "rmi", "build-test-secret")
res := c.RunDockerComposeCmd("--project-directory", "fixtures/build-test/secrets", "build")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test/secrets", "build")
res.Assert(t, icmd.Success)
})
}
func TestBuildTags(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("build with tags", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test-tags")
c.RunDockerOrExitError(t, "rmi", "build-test-tags")
c.RunDockerComposeCmd("--project-directory", "./fixtures/build-test/tags", "build", "--no-cache")
c.RunDockerComposeCmd(t, "--project-directory", "./fixtures/build-test/tags", "build", "--no-cache")
res := c.RunDockerCmd("image", "inspect", "build-test-tags")
res := c.RunDockerCmd(t, "image", "inspect", "build-test-tags")
expectedOutput := `"RepoTags": [
"docker/build-test-tags:1.0.0",
"build-test-tags:latest",

View File

@ -23,12 +23,12 @@ import (
)
func TestDown(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-down"
t.Run("no resource to remove", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "--project-name", projectName, "down")
res := c.RunDockerOrExitError(t, "compose", "--project-name", projectName, "down")
res.Assert(t, icmd.Expected{ExitCode: 0, Err: `No resource found to remove for project "e2e-down"`})
})
}

View File

@ -26,13 +26,13 @@ import (
)
func TestEnvPriority(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
projectDir := "./fixtures/environment/env-priority"
t.Run("up", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "env-compose-priority")
c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose-with-env.yaml",
c.RunDockerOrExitError(t, "rmi", "env-compose-priority")
c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose-with-env.yaml",
"--project-directory", projectDir, "up", "-d", "--build")
})
@ -46,7 +46,7 @@ func TestEnvPriority(t *testing.T) {
os.Setenv("WHEREAMI", "shell") //nolint:errcheck
defer os.Unsetenv("WHEREAMI") //nolint:errcheck
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose-with-env.yaml",
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose-with-env.yaml",
"--project-directory", projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override",
"run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
@ -63,7 +63,7 @@ func TestEnvPriority(t *testing.T) {
os.Setenv("WHEREAMI", "shell") //nolint:errcheck
defer os.Unsetenv("WHEREAMI") //nolint:errcheck
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose.yaml",
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose.yaml",
"--project-directory", projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override",
"run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
assert.Equal(t, strings.TrimSpace(res.Stdout()), "shell")
@ -76,9 +76,9 @@ func TestEnvPriority(t *testing.T) {
// 4. Dockerfile
// 5. Variable is not defined
t.Run("shell priority from run command", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose.yaml",
"--project-directory", projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override",
"run", "--rm", "-e", "WHEREAMI=shell-run", "env-compose-priority")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose.yaml", "--project-directory",
projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override", "run", "--rm", "-e",
"WHEREAMI=shell-run", "env-compose-priority")
assert.Equal(t, strings.TrimSpace(res.Stdout()), "shell-run")
})
@ -89,9 +89,9 @@ func TestEnvPriority(t *testing.T) {
// 4. Dockerfile
// 5. Variable is not defined
t.Run("override env file", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose.yaml",
"--project-directory", projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override",
"run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose.yaml", "--project-directory",
projectDir, "--env-file", "./fixtures/environment/env-priority/.env.override", "run", "--rm", "-e",
"WHEREAMI", "env-compose-priority")
assert.Equal(t, strings.TrimSpace(res.Stdout()), "override")
})
@ -102,8 +102,8 @@ func TestEnvPriority(t *testing.T) {
// 4. Dockerfile
// 5. Variable is not defined
t.Run("env file", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose.yaml",
"--project-directory", projectDir, "run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose.yaml", "--project-directory",
projectDir, "run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
assert.Equal(t, strings.TrimSpace(res.Stdout()), "Env File")
})
@ -114,19 +114,19 @@ func TestEnvPriority(t *testing.T) {
// 4. Dockerfile <-- Result expected
// 5. Variable is not defined
t.Run("use Dockerfile", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-priority/compose.yaml",
"--project-directory", projectDir, "--env-file", "./fixtures/environment/env-priority/.env.empty",
"run", "--rm", "-e", "WHEREAMI", "env-compose-priority")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-priority/compose.yaml", "--project-directory",
projectDir, "--env-file", "./fixtures/environment/env-priority/.env.empty", "run", "--rm", "-e", "WHEREAMI",
"env-compose-priority")
assert.Equal(t, strings.TrimSpace(res.Stdout()), "Dockerfile")
})
t.Run("down", func(t *testing.T) {
c.RunDockerComposeCmd("--project-directory", projectDir, "down")
c.RunDockerComposeCmd(t, "--project-directory", projectDir, "down")
})
}
func TestEnvInterpolation(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
projectDir := "./fixtures/environment/env-interpolation"
@ -139,7 +139,7 @@ func TestEnvInterpolation(t *testing.T) {
t.Run("shell priority from run command", func(t *testing.T) {
os.Setenv("WHEREAMI", "shell") //nolint:errcheck
defer os.Unsetenv("WHEREAMI") //nolint:errcheck
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-interpolation/compose.yaml",
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-interpolation/compose.yaml",
"--project-directory", projectDir, "config")
res.Assert(t, icmd.Expected{Out: `IMAGE: default_env:shell`})
@ -147,23 +147,22 @@ func TestEnvInterpolation(t *testing.T) {
}
func TestCommentsInEnvFile(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
projectDir := "./fixtures/environment/env-file-comments"
t.Run("comments in env files", func(t *testing.T) {
c.RunDockerOrExitError("rmi", "env-file-comments")
c.RunDockerOrExitError(t, "rmi", "env-file-comments")
c.RunDockerComposeCmd("-f", "./fixtures/environment/env-file-comments/compose.yaml",
"--project-directory", projectDir, "up", "-d", "--build")
c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-file-comments/compose.yaml", "--project-directory",
projectDir, "up", "-d", "--build")
res := c.RunDockerComposeCmd("-f", "./fixtures/environment/env-file-comments/compose.yaml",
"--project-directory", projectDir, "run", "--rm",
"-e", "COMMENT", "-e", "NO_COMMENT", "env-file-comments")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/environment/env-file-comments/compose.yaml",
"--project-directory", projectDir, "run", "--rm", "-e", "COMMENT", "-e", "NO_COMMENT", "env-file-comments")
res.Assert(t, icmd.Expected{Out: `COMMENT=1234`})
res.Assert(t, icmd.Expected{Out: `NO_COMMENT=1234#5`})
c.RunDockerComposeCmd("--project-directory", projectDir, "down", "--rmi", "all")
c.RunDockerComposeCmd(t, "--project-directory", projectDir, "down", "--rmi", "all")
})
}

View File

@ -25,19 +25,20 @@ import (
)
func TestLocalComposeExec(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "compose-e2e-exec"
c.RunDockerComposeCmd("--project-directory", "fixtures/simple-composefile", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/simple-composefile", "--project-name", projectName, "up",
"-d")
t.Run("exec true", func(t *testing.T) {
res := c.RunDockerOrExitError("exec", "compose-e2e-exec-simple-1", "/bin/true")
res := c.RunDockerOrExitError(t, "exec", "compose-e2e-exec-simple-1", "/bin/true")
res.Assert(t, icmd.Expected{ExitCode: 0})
})
t.Run("exec false", func(t *testing.T) {
res := c.RunDockerOrExitError("exec", "compose-e2e-exec-simple-1", "/bin/false")
res := c.RunDockerOrExitError(t, "exec", "compose-e2e-exec-simple-1", "/bin/false")
res.Assert(t, icmd.Expected{ExitCode: 1})
})
@ -50,7 +51,7 @@ func TestLocalComposeExec(t *testing.T) {
})
t.Run("exec without env set", func(t *testing.T) {
res := c.RunDockerOrExitError("exec", "-e", "FOO", "compose-e2e-exec-simple-1", "/usr/bin/env")
res := c.RunDockerOrExitError(t, "exec", "-e", "FOO", "compose-e2e-exec-simple-1", "/usr/bin/env")
res.Assert(t, icmd.Expected{ExitCode: 0})
assert.Check(t, !strings.Contains(res.Stdout(), "FOO="))
})

View File

@ -26,21 +26,22 @@ import (
)
func TestLocalComposeRun(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("compose run", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "back")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "back")
lines := Lines(res.Stdout())
assert.Equal(t, lines[len(lines)-1], "Hello there!!", res.Stdout())
assert.Assert(t, !strings.Contains(res.Combined(), "orphan"))
res = c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "back", "echo", "Hello one more time")
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "back", "echo",
"Hello one more time")
lines = Lines(res.Stdout())
assert.Equal(t, lines[len(lines)-1], "Hello one more time", res.Stdout())
assert.Assert(t, !strings.Contains(res.Combined(), "orphan"))
})
t.Run("check run container exited", func(t *testing.T) {
res := c.RunDockerCmd("ps", "--all")
res := c.RunDockerCmd(t, "ps", "--all")
lines := Lines(res.Stdout())
var runContainerID string
var truncatedSlug string
@ -59,7 +60,7 @@ func TestLocalComposeRun(t *testing.T) {
}
}
assert.Assert(t, runContainerID != "")
res = c.RunDockerCmd("inspect", runContainerID)
res = c.RunDockerCmd(t, "inspect", runContainerID)
res.Assert(t, icmd.Expected{Out: ` "Status": "exited"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.container-number": "1"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.project": "run-test"`})
@ -68,40 +69,43 @@ func TestLocalComposeRun(t *testing.T) {
})
t.Run("compose run --rm", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "--rm", "back", "echo", "Hello again")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "--rm", "back", "echo",
"Hello again")
lines := Lines(res.Stdout())
assert.Equal(t, lines[len(lines)-1], "Hello again", res.Stdout())
res = c.RunDockerCmd("ps", "--all")
res = c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, strings.Contains(res.Stdout(), "run-test_back"), res.Stdout())
})
t.Run("down", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "down")
res := c.RunDockerCmd("ps", "--all")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "down")
res := c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, !strings.Contains(res.Stdout(), "run-test"), res.Stdout())
})
t.Run("compose run --volumes", func(t *testing.T) {
wd, err := os.Getwd()
assert.NilError(t, err)
res := c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "--volumes", wd+":/foo", "back", "/bin/sh", "-c", "ls /foo")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "--volumes", wd+":/foo",
"back", "/bin/sh", "-c", "ls /foo")
res.Assert(t, icmd.Expected{Out: "compose_run_test.go"})
res = c.RunDockerCmd("ps", "--all")
res = c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, strings.Contains(res.Stdout(), "run-test_back"), res.Stdout())
})
t.Run("compose run --publish", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "--publish", "8081:80", "-d", "back", "/bin/sh", "-c", "sleep 1")
res := c.RunDockerCmd("ps")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "--publish", "8081:80", "-d", "back",
"/bin/sh", "-c", "sleep 1")
res := c.RunDockerCmd(t, "ps")
assert.Assert(t, strings.Contains(res.Stdout(), "8081->80/tcp"), res.Stdout())
})
t.Run("compose run orphan", func(t *testing.T) {
// Use different compose files to get an orphan container
c.RunDockerComposeCmd("-f", "./fixtures/run-test/orphan.yaml", "run", "simple")
res := c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "run", "back", "echo", "Hello")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/orphan.yaml", "run", "simple")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "back", "echo", "Hello")
assert.Assert(t, strings.Contains(res.Combined(), "orphan"))
cmd := c.NewDockerCmd("compose", "-f", "./fixtures/run-test/compose.yaml", "run", "back", "echo", "Hello")
@ -112,21 +116,21 @@ func TestLocalComposeRun(t *testing.T) {
})
t.Run("down", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/run-test/compose.yaml", "down")
c.RunDockerComposeCmd("-f", "./fixtures/run-test/orphan.yaml", "down")
res := c.RunDockerCmd("ps", "--all")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "down")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/orphan.yaml", "down")
res := c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, !strings.Contains(res.Stdout(), "run-test"), res.Stdout())
})
t.Run("run starts only container and dependencies", func(t *testing.T) {
// ensure that even if another service is up run does not start it: https://github.com/docker/compose/issues/9459
res := c.RunDockerComposeCmd("-f", "./fixtures/run-test/deps.yaml", "up", "service_b")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/deps.yaml", "up", "service_b")
res.Assert(t, icmd.Success)
res = c.RunDockerComposeCmd("-f", "./fixtures/run-test/deps.yaml", "run", "service_a")
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/deps.yaml", "run", "service_a")
assert.Assert(t, strings.Contains(res.Combined(), "shared_dep"), res.Combined())
assert.Assert(t, !strings.Contains(res.Combined(), "service_b"), res.Combined())
c.RunDockerComposeCmd("-f", "./fixtures/run-test/deps.yaml", "down", "--remove-orphans")
c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/deps.yaml", "down", "--remove-orphans")
})
}

View File

@ -31,31 +31,30 @@ import (
"gotest.tools/v3/icmd"
)
var binDir string
func TestLocalComposeUp(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
// this test shares a fixture with TestCompatibility and can't run at the same time
c := NewCLI(t)
const projectName = "compose-e2e-demo"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/sentences/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/sentences/compose.yaml", "--project-name", projectName, "up", "-d")
})
t.Run("check accessing running app", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res := c.RunDockerComposeCmd(t, "-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `web`})
endpoint := "http://localhost:90"
output := HTTPGetWithRetry(t, endpoint+"/words/noun", http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(output, `"word":`))
res = c.RunDockerCmd("network", "ls")
res = c.RunDockerCmd(t, "network", "ls")
res.Assert(t, icmd.Expected{Out: projectName + "_default"})
})
t.Run("top", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "top")
res := c.RunDockerComposeCmd(t, "-p", projectName, "top")
output := res.Stdout()
head := []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"}
for _, h := range head {
@ -66,7 +65,7 @@ func TestLocalComposeUp(t *testing.T) {
})
t.Run("check compose labels", func(t *testing.T) {
res := c.RunDockerCmd("inspect", projectName+"-web-1")
res := c.RunDockerCmd(t, "inspect", projectName+"-web-1")
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.container-number": "1"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.project": "compose-e2e-demo"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.oneoff": "False",`})
@ -76,55 +75,55 @@ func TestLocalComposeUp(t *testing.T) {
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.service": "web"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.version":`})
res = c.RunDockerCmd("network", "inspect", projectName+"_default")
res = c.RunDockerCmd(t, "network", "inspect", projectName+"_default")
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.network": "default"`})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.project": `})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.version": `})
})
t.Run("check user labels", func(t *testing.T) {
res := c.RunDockerCmd("inspect", projectName+"-web-1")
res := c.RunDockerCmd(t, "inspect", projectName+"-web-1")
res.Assert(t, icmd.Expected{Out: `"my-label": "test"`})
})
t.Run("check healthcheck output", func(t *testing.T) {
c.WaitForCmdResult(c.NewDockerCmd("compose", "-p", projectName, "ps", "--format", "json"),
c.WaitForCmdResult(t, c.NewDockerCmd("compose", "-p", projectName, "ps", "--format", "json"),
StdoutContains(`"Name":"compose-e2e-demo-web-1","Command":"/dispatcher","Project":"compose-e2e-demo","Service":"web","State":"running","Health":"healthy"`),
5*time.Second, 1*time.Second)
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res := c.RunDockerComposeCmd(t, "-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `NAME COMMAND SERVICE STATUS PORTS`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-web-1 "/dispatcher" web running (healthy) 0.0.0.0:90->80/tcp`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-db-1 "docker-entrypoint.s…" db running 5432/tcp`})
})
t.Run("images", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "images")
res := c.RunDockerComposeCmd(t, "-p", projectName, "images")
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-db-1 gtardif/sentences-db latest`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-web-1 gtardif/sentences-web latest`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-words-1 gtardif/sentences-api latest`})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
t.Run("check containers after down", func(t *testing.T) {
res := c.RunDockerCmd("ps", "--all")
res := c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, !strings.Contains(res.Combined(), projectName), res.Combined())
})
t.Run("check networks after down", func(t *testing.T) {
res := c.RunDockerCmd("network", "ls")
res := c.RunDockerCmd(t, "network", "ls")
assert.Assert(t, !strings.Contains(res.Combined(), projectName), res.Combined())
})
}
func TestComposePull(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
res := c.RunDockerOrExitError("compose", "--project-directory", "fixtures/simple-composefile", "pull")
res := c.RunDockerOrExitError(t, "compose", "--project-directory", "fixtures/simple-composefile", "pull")
output := res.Combined()
assert.Assert(t, strings.Contains(output, "simple Pulled"))
@ -132,102 +131,108 @@ func TestComposePull(t *testing.T) {
}
func TestDownComposefileInParentFolder(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
tmpFolder, err := ioutil.TempDir("fixtures/simple-composefile", "test-tmp")
assert.NilError(t, err)
defer os.Remove(tmpFolder) // nolint: errcheck
projectName := filepath.Base(tmpFolder)
res := c.RunDockerComposeCmd("--project-directory", tmpFolder, "up", "-d")
res := c.RunDockerComposeCmd(t, "--project-directory", tmpFolder, "up", "-d")
res.Assert(t, icmd.Expected{Err: "Started", ExitCode: 0})
res = c.RunDockerComposeCmd("-p", projectName, "down")
res = c.RunDockerComposeCmd(t, "-p", projectName, "down")
res.Assert(t, icmd.Expected{Err: "Removed", ExitCode: 0})
}
func TestAttachRestart(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
cmd := c.NewDockerCmd("compose", "--ansi=never", "--project-directory", "./fixtures/attach-restart", "up")
res := icmd.StartCmd(cmd)
defer c.RunDockerOrExitError("compose", "-p", "attach-restart", "down")
defer c.RunDockerOrExitError(t, "compose", "-p", "attach-restart", "down")
c.WaitForCondition(func() (bool, string) {
c.WaitForCondition(t, func() (bool, string) {
debug := res.Combined()
return strings.Count(res.Stdout(), "failing-1 exited with code 1") == 3, fmt.Sprintf("'failing-1 exited with code 1' not found 3 times in : \n%s\n", debug)
return strings.Count(res.Stdout(),
"failing-1 exited with code 1") == 3, fmt.Sprintf("'failing-1 exited with code 1' not found 3 times in : \n%s\n",
debug)
}, 2*time.Minute, 2*time.Second)
assert.Equal(t, strings.Count(res.Stdout(), "failing-1 | world"), 3, res.Combined())
}
func TestInitContainer(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
res := c.RunDockerOrExitError("compose", "--ansi=never", "--project-directory", "./fixtures/init-container", "up")
defer c.RunDockerOrExitError("compose", "-p", "init-container", "down")
res := c.RunDockerOrExitError(t, "compose", "--ansi=never", "--project-directory", "./fixtures/init-container", "up")
defer c.RunDockerOrExitError(t, "compose", "-p", "init-container", "down")
testify.Regexp(t, "foo-1 | hello(?m:.*)bar-1 | world", res.Stdout())
}
func TestRm(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "compose-e2e-rm"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "up", "-d")
})
t.Run("rm -sf", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "rm", "-sf", "simple")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "rm",
"-sf", "simple")
res.Assert(t, icmd.Expected{Err: "Removed", ExitCode: 0})
})
t.Run("check containers after rm -sf", func(t *testing.T) {
res := c.RunDockerCmd("ps", "--all")
res := c.RunDockerCmd(t, "ps", "--all")
assert.Assert(t, !strings.Contains(res.Combined(), projectName+"_simple"), res.Combined())
})
t.Run("rm -sf <none>", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "rm", "-sf", "simple")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-composefile/compose.yaml", "-p", projectName, "rm",
"-sf", "simple")
res.Assert(t, icmd.Expected{ExitCode: 0})
})
t.Run("down", func(t *testing.T) {
c.RunDockerComposeCmd("-p", projectName, "down")
c.RunDockerComposeCmd(t, "-p", projectName, "down")
})
}
func TestCompatibility(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
// this test shares a fixture with TestLocalComposeUp and can't run at the same time
c := NewCLI(t)
const projectName = "compose-e2e-compatibility"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("--compatibility", "-f", "./fixtures/sentences/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "--compatibility", "-f", "./fixtures/sentences/compose.yaml", "--project-name",
projectName, "up", "-d")
})
t.Run("check container names", func(t *testing.T) {
res := c.RunDockerCmd("ps", "--format", "{{.Names}}")
res := c.RunDockerCmd(t, "ps", "--format", "{{.Names}}")
res.Assert(t, icmd.Expected{Out: "compose-e2e-compatibility_web_1"})
res.Assert(t, icmd.Expected{Out: "compose-e2e-compatibility_words_1"})
res.Assert(t, icmd.Expected{Out: "compose-e2e-compatibility_db_1"})
})
t.Run("down", func(t *testing.T) {
c.RunDockerComposeCmd("-p", projectName, "down")
c.RunDockerComposeCmd(t, "-p", projectName, "down")
})
}
func TestConvert(t *testing.T) {
const projectName = "compose-e2e-convert"
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
wd, err := os.Getwd()
assert.NilError(t, err)
t.Run("up", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/simple-build-test/compose.yaml", "-p", projectName, "convert")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-build-test/compose.yaml", "-p", projectName, "convert")
res.Assert(t, icmd.Expected{Out: fmt.Sprintf(`services:
nginx:
build:

View File

@ -26,12 +26,12 @@ import (
)
func TestCopy(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "copy_e2e"
t.Cleanup(func() {
c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "--project-name", projectName, "down")
c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "--project-name", projectName, "down")
os.Remove("./fixtures/cp-test/from-default.txt") //nolint:errcheck
os.Remove("./fixtures/cp-test/from-indexed.txt") //nolint:errcheck
@ -39,41 +39,45 @@ func TestCopy(t *testing.T) {
})
t.Run("start service", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "--project-name", projectName, "up", "--scale", "nginx=5", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "--project-name", projectName, "up",
"--scale", "nginx=5", "-d")
})
t.Run("make sure service is running", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res := c.RunDockerComposeCmd(t, "-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `nginx running`})
})
t.Run("copy to container copies the file to the all containers by default", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "./fixtures/cp-test/cp-me.txt", "nginx:/tmp/default.txt")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp",
"./fixtures/cp-test/cp-me.txt", "nginx:/tmp/default.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
output := c.RunDockerCmd("exec", projectName+"-nginx-1", "cat", "/tmp/default.txt").Stdout()
output := c.RunDockerCmd(t, "exec", projectName+"-nginx-1", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
output = c.RunDockerCmd("exec", projectName+"-nginx-2", "cat", "/tmp/default.txt").Stdout()
output = c.RunDockerCmd(t, "exec", projectName+"-nginx-2", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
output = c.RunDockerCmd("exec", projectName+"-nginx-3", "cat", "/tmp/default.txt").Stdout()
output = c.RunDockerCmd(t, "exec", projectName+"-nginx-3", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
})
t.Run("copy to container with a given index copies the file to the given container", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "--index=3", "./fixtures/cp-test/cp-me.txt", "nginx:/tmp/indexed.txt")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "--index=3",
"./fixtures/cp-test/cp-me.txt", "nginx:/tmp/indexed.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
output := c.RunDockerCmd("exec", projectName+"-nginx-3", "cat", "/tmp/indexed.txt").Stdout()
output := c.RunDockerCmd(t, "exec", projectName+"-nginx-3", "cat", "/tmp/indexed.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
res = c.RunDockerOrExitError("exec", projectName+"-nginx-2", "cat", "/tmp/indexed.txt")
res = c.RunDockerOrExitError(t, "exec", projectName+"-nginx-2", "cat", "/tmp/indexed.txt")
res.Assert(t, icmd.Expected{ExitCode: 1})
})
t.Run("copy from a container copies the file to the host from the first container by default", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "nginx:/tmp/default.txt", "./fixtures/cp-test/from-default.txt")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp",
"nginx:/tmp/default.txt", "./fixtures/cp-test/from-default.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
data, err := os.ReadFile("./fixtures/cp-test/from-default.txt")
@ -82,7 +86,8 @@ func TestCopy(t *testing.T) {
})
t.Run("copy from a container with a given index copies the file to host", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "--index=3", "nginx:/tmp/indexed.txt", "./fixtures/cp-test/from-indexed.txt")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "--index=3",
"nginx:/tmp/indexed.txt", "./fixtures/cp-test/from-indexed.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
data, err := os.ReadFile("./fixtures/cp-test/from-indexed.txt")
@ -91,13 +96,15 @@ func TestCopy(t *testing.T) {
})
t.Run("copy to and from a container also work with folder", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "./fixtures/cp-test/cp-folder", "nginx:/tmp")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp",
"./fixtures/cp-test/cp-folder", "nginx:/tmp")
res.Assert(t, icmd.Expected{ExitCode: 0})
output := c.RunDockerCmd("exec", projectName+"-nginx-1", "cat", "/tmp/cp-folder/cp-me.txt").Stdout()
output := c.RunDockerCmd(t, "exec", projectName+"-nginx-1", "cat", "/tmp/cp-folder/cp-me.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world from folder`), output)
res = c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "nginx:/tmp/cp-folder", "./fixtures/cp-test/cp-folder2")
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp",
"nginx:/tmp/cp-folder", "./fixtures/cp-test/cp-folder2")
res.Assert(t, icmd.Expected{ExitCode: 0})
data, err := os.ReadFile("./fixtures/cp-test/cp-folder2/cp-me.txt")

View File

@ -38,7 +38,7 @@ func TestComposeRunDdev(t *testing.T) {
}
_ = os.Setenv("DDEV_DEBUG", "true")
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
dir, err := os.MkdirTemp("", t.Name()+"-")
assert.NilError(t, err)
@ -48,8 +48,8 @@ func TestComposeRunDdev(t *testing.T) {
siteName := filepath.Base(dir)
t.Cleanup(func() {
_ = c.RunCmdInDir(dir, "./ddev", "delete", "-Oy")
_ = c.RunCmdInDir(dir, "./ddev", "poweroff")
_ = c.RunCmdInDir(t, dir, "./ddev", "delete", "-Oy")
_ = c.RunCmdInDir(t, dir, "./ddev", "poweroff")
_ = os.RemoveAll(dir)
})
@ -59,28 +59,28 @@ func TestComposeRunDdev(t *testing.T) {
}
compressedFilename := fmt.Sprintf("ddev_%s-%s.%s.tar.gz", osName, runtime.GOARCH, ddevVersion)
c.RunCmdInDir(dir, "curl", "-LO",
c.RunCmdInDir(t, dir, "curl", "-LO",
fmt.Sprintf("https://github.com/drud/ddev/releases/download/%s/%s",
ddevVersion,
compressedFilename))
c.RunCmdInDir(dir, "tar", "-xzf", compressedFilename)
c.RunCmdInDir(t, dir, "tar", "-xzf", compressedFilename)
// Create a simple index.php we can test against.
c.RunCmdInDir(dir, "sh", "-c", "echo '<?php\nprint \"ddev is working\";' >index.php")
c.RunCmdInDir(t, dir, "sh", "-c", "echo '<?php\nprint \"ddev is working\";' >index.php")
c.RunCmdInDir(dir, "./ddev", "config", "--auto")
c.RunCmdInDir(dir, "./ddev", "config", "global", "--use-docker-compose-from-path")
vRes := c.RunCmdInDir(dir, "./ddev", "version")
c.RunCmdInDir(t, dir, "./ddev", "config", "--auto")
c.RunCmdInDir(t, dir, "./ddev", "config", "global", "--use-docker-compose-from-path")
vRes := c.RunCmdInDir(t, dir, "./ddev", "version")
out := vRes.Stdout()
fmt.Printf("ddev version: %s\n", out)
c.RunCmdInDir(dir, "./ddev", "poweroff")
c.RunCmdInDir(t, dir, "./ddev", "poweroff")
c.RunCmdInDir(dir, "./ddev", "start", "-y")
c.RunCmdInDir(t, dir, "./ddev", "start", "-y")
curlRes := c.RunCmdInDir(dir, "curl", "-sSL", fmt.Sprintf("http://%s.ddev.site", siteName))
curlRes := c.RunCmdInDir(t, dir, "curl", "-sSL", fmt.Sprintf("http://%s.ddev.site", siteName))
out = curlRes.Stdout()
fmt.Println(out)
assert.Assert(c.test, strings.Contains(out, "ddev is working"), "Could not start project")
assert.Assert(t, strings.Contains(out, "ddev is working"), "Could not start project")
}

View File

@ -29,12 +29,13 @@ import (
"testing"
"time"
"github.com/docker/compose/v2/cmd/compose"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/icmd"
"gotest.tools/v3/poll"
"github.com/docker/compose/v2/cmd/compose"
)
var (
@ -56,21 +57,19 @@ func init() {
}
}
// E2eCLI is used to wrap the CLI for end to end testing
// nolint stutter
type E2eCLI struct {
BinDir string
// CLI is used to wrap the CLI for end to end testing
type CLI struct {
ConfigDir string
test *testing.T
}
// NewParallelE2eCLI returns a configured TestE2eCLI with t.Parallel() set
func NewParallelE2eCLI(t *testing.T, binDir string) *E2eCLI {
// NewParallelCLI returns a configured CLI with t.Parallel() set
func NewParallelCLI(t *testing.T) *CLI {
t.Parallel()
return newE2eCLI(t, binDir)
return NewCLI(t)
}
func newE2eCLI(t *testing.T, binDir string) *E2eCLI {
// NewCLI returns a CLI to use for E2E tests
func NewCLI(t testing.TB) *CLI {
d, err := ioutil.TempDir("", "")
assert.Check(t, is.Nil(err))
@ -103,7 +102,7 @@ func newE2eCLI(t *testing.T, binDir string) *E2eCLI {
}
}
return &E2eCLI{binDir, d, t}
return &CLI{ConfigDir: d}
}
func dirContents(dir string) []string {
@ -156,7 +155,7 @@ func CopyFile(sourceFile string, destinationFile string) error {
}
// NewCmd creates a cmd object configured with the test environment set
func (c *E2eCLI) NewCmd(command string, args ...string) icmd.Cmd {
func (c *CLI) NewCmd(command string, args ...string) icmd.Cmd {
env := append(os.Environ(),
"DOCKER_CONFIG="+c.ConfigDir,
"KUBECONFIG=invalid",
@ -168,7 +167,7 @@ func (c *E2eCLI) NewCmd(command string, args ...string) icmd.Cmd {
}
// NewCmdWithEnv creates a cmd object configured with the test environment set with additional env vars
func (c *E2eCLI) NewCmdWithEnv(envvars []string, command string, args ...string) icmd.Cmd {
func (c *CLI) NewCmdWithEnv(envvars []string, command string, args ...string) icmd.Cmd {
env := append(os.Environ(),
append(envvars,
"DOCKER_CONFIG="+c.ConfigDir,
@ -181,63 +180,63 @@ func (c *E2eCLI) NewCmdWithEnv(envvars []string, command string, args ...string)
}
// MetricsSocket get the path where test metrics will be sent
func (c *E2eCLI) MetricsSocket() string {
func (c *CLI) MetricsSocket() string {
return filepath.Join(c.ConfigDir, "./docker-cli.sock")
}
// NewDockerCmd creates a docker cmd without running it
func (c *E2eCLI) NewDockerCmd(args ...string) icmd.Cmd {
func (c *CLI) NewDockerCmd(args ...string) icmd.Cmd {
return c.NewCmd(DockerExecutableName, args...)
}
// RunDockerOrExitError runs a docker command and returns a result
func (c *E2eCLI) RunDockerOrExitError(args ...string) *icmd.Result {
fmt.Printf("\t[%s] docker %s\n", c.test.Name(), strings.Join(args, " "))
func (c *CLI) RunDockerOrExitError(t testing.TB, args ...string) *icmd.Result {
fmt.Printf("\t[%s] docker %s\n", t.Name(), strings.Join(args, " "))
return icmd.RunCmd(c.NewDockerCmd(args...))
}
// RunCmd runs a command, expects no error and returns a result
func (c *E2eCLI) RunCmd(args ...string) *icmd.Result {
fmt.Printf("\t[%s] %s\n", c.test.Name(), strings.Join(args, " "))
assert.Assert(c.test, len(args) >= 1, "require at least one command in parameters")
func (c *CLI) RunCmd(t testing.TB, args ...string) *icmd.Result {
fmt.Printf("\t[%s] %s\n", t.Name(), strings.Join(args, " "))
assert.Assert(t, len(args) >= 1, "require at least one command in parameters")
res := icmd.RunCmd(c.NewCmd(args[0], args[1:]...))
res.Assert(c.test, icmd.Success)
res.Assert(t, icmd.Success)
return res
}
// RunCmdInDir runs a command in a given dir, expects no error and returns a result
func (c *E2eCLI) RunCmdInDir(dir string, args ...string) *icmd.Result {
fmt.Printf("\t[%s] %s\n", c.test.Name(), strings.Join(args, " "))
assert.Assert(c.test, len(args) >= 1, "require at least one command in parameters")
func (c *CLI) RunCmdInDir(t testing.TB, dir string, args ...string) *icmd.Result {
fmt.Printf("\t[%s] %s\n", t.Name(), strings.Join(args, " "))
assert.Assert(t, len(args) >= 1, "require at least one command in parameters")
cmd := c.NewCmd(args[0], args[1:]...)
cmd.Dir = dir
res := icmd.RunCmd(cmd)
res.Assert(c.test, icmd.Success)
res.Assert(t, icmd.Success)
return res
}
// RunDockerCmd runs a docker command, expects no error and returns a result
func (c *E2eCLI) RunDockerCmd(args ...string) *icmd.Result {
func (c *CLI) RunDockerCmd(t testing.TB, args ...string) *icmd.Result {
if len(args) > 0 && args[0] == compose.PluginName {
c.test.Fatal("This test called 'RunDockerCmd' for 'compose'. Please prefer 'RunDockerComposeCmd' to be able to test as a plugin and standalone")
t.Fatal("This test called 'RunDockerCmd' for 'compose'. Please prefer 'RunDockerComposeCmd' to be able to test as a plugin and standalone")
}
res := c.RunDockerOrExitError(args...)
res.Assert(c.test, icmd.Success)
res := c.RunDockerOrExitError(t, args...)
res.Assert(t, icmd.Success)
return res
}
// RunDockerComposeCmd runs a docker compose command, expects no error and returns a result
func (c *E2eCLI) RunDockerComposeCmd(args ...string) *icmd.Result {
res := c.RunDockerComposeCmdNoCheck(args...)
res.Assert(c.test, icmd.Success)
func (c *CLI) RunDockerComposeCmd(t testing.TB, args ...string) *icmd.Result {
res := c.RunDockerComposeCmdNoCheck(t, args...)
res.Assert(t, icmd.Success)
return res
}
// RunDockerComposeCmdNoCheck runs a docker compose command, don't presume of any expectation and returns a result
func (c *E2eCLI) RunDockerComposeCmdNoCheck(args ...string) *icmd.Result {
func (c *CLI) RunDockerComposeCmdNoCheck(t testing.TB, args ...string) *icmd.Result {
if composeStandaloneMode {
composeBinary, err := findExecutable(DockerComposeExecutableName, []string{"../../bin", "../../../bin"})
assert.NilError(c.test, err)
assert.NilError(t, err)
return icmd.RunCmd(c.NewCmd(composeBinary, args...))
}
args = append([]string{"compose"}, args...)
@ -252,22 +251,22 @@ func StdoutContains(expected string) func(*icmd.Result) bool {
}
// WaitForCmdResult try to execute a cmd until resulting output matches given predicate
func (c *E2eCLI) WaitForCmdResult(command icmd.Cmd, predicate func(*icmd.Result) bool, timeout time.Duration, delay time.Duration) {
assert.Assert(c.test, timeout.Nanoseconds() > delay.Nanoseconds(), "timeout must be greater than delay")
func (c *CLI) WaitForCmdResult(t testing.TB, command icmd.Cmd, predicate func(*icmd.Result) bool, timeout time.Duration, delay time.Duration) {
assert.Assert(t, timeout.Nanoseconds() > delay.Nanoseconds(), "timeout must be greater than delay")
var res *icmd.Result
checkStopped := func(logt poll.LogT) poll.Result {
fmt.Printf("\t[%s] %s\n", c.test.Name(), strings.Join(command.Command, " "))
fmt.Printf("\t[%s] %s\n", t.Name(), strings.Join(command.Command, " "))
res = icmd.RunCmd(command)
if !predicate(res) {
return poll.Continue("Cmd output did not match requirement: %q", res.Combined())
}
return poll.Success()
}
poll.WaitOn(c.test, checkStopped, poll.WithDelay(delay), poll.WithTimeout(timeout))
poll.WaitOn(t, checkStopped, poll.WithDelay(delay), poll.WithTimeout(timeout))
}
// WaitForCondition wait for predicate to execute to true
func (c *E2eCLI) WaitForCondition(predicate func() (bool, string), timeout time.Duration, delay time.Duration) {
func (c *CLI) WaitForCondition(t testing.TB, predicate func() (bool, string), timeout time.Duration, delay time.Duration) {
checkStopped := func(logt poll.LogT) poll.Result {
pass, description := predicate()
if !pass {
@ -275,7 +274,7 @@ func (c *E2eCLI) WaitForCondition(predicate func() (bool, string), timeout time.
}
return poll.Success()
}
poll.WaitOn(c.test, checkStopped, poll.WithDelay(delay), poll.WithTimeout(timeout))
poll.WaitOn(t, checkStopped, poll.WithDelay(delay), poll.WithTimeout(timeout))
}
// Lines split output into lines
@ -286,7 +285,7 @@ func Lines(output string) []string {
// HTTPGetWithRetry performs an HTTP GET on an `endpoint`, using retryDelay also as a request timeout.
// In the case of an error or the response status is not the expeted one, it retries the same request,
// returning the response body as a string (empty if we could not reach it)
func HTTPGetWithRetry(t *testing.T, endpoint string, expectedStatus int, retryDelay time.Duration, timeout time.Duration) string {
func HTTPGetWithRetry(t testing.TB, endpoint string, expectedStatus int, retryDelay time.Duration, timeout time.Duration) string {
var (
r *http.Response
err error

View File

@ -25,39 +25,40 @@ import (
)
func TestIPC(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "ipc_e2e"
var cid string
t.Run("create ipc mode container", func(t *testing.T) {
res := c.RunDockerCmd("run", "-d", "--rm", "--ipc=shareable", "--name", "ipc_mode_container", "alpine", "top")
res := c.RunDockerCmd(t, "run", "-d", "--rm", "--ipc=shareable", "--name", "ipc_mode_container", "alpine",
"top")
cid = strings.Trim(res.Stdout(), "\n")
})
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/ipc-test/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/ipc-test/compose.yaml", "--project-name", projectName, "up", "-d")
})
t.Run("check running project", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res := c.RunDockerComposeCmd(t, "-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `shareable`})
})
t.Run("check ipcmode in container inspect", func(t *testing.T) {
res := c.RunDockerCmd("inspect", projectName+"-shareable-1")
res := c.RunDockerCmd(t, "inspect", projectName+"-shareable-1")
res.Assert(t, icmd.Expected{Out: `"IpcMode": "shareable",`})
res = c.RunDockerCmd("inspect", projectName+"-service-1")
res = c.RunDockerCmd(t, "inspect", projectName+"-service-1")
res.Assert(t, icmd.Expected{Out: `"IpcMode": "container:`})
res = c.RunDockerCmd("inspect", projectName+"-container-1")
res = c.RunDockerCmd(t, "inspect", projectName+"-container-1")
res.Assert(t, icmd.Expected{Out: fmt.Sprintf(`"IpcMode": "container:%s",`, cid)})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
t.Run("remove ipc mode container", func(t *testing.T) {
_ = c.RunDockerCmd("rm", "-f", "ipc_mode_container")
_ = c.RunDockerCmd(t, "rm", "-f", "ipc_mode_container")
})
}

View File

@ -26,33 +26,33 @@ import (
)
func TestLocalComposeLogs(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "compose-e2e-logs"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/logs-test/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/logs-test/compose.yaml", "--project-name", projectName, "up", "-d")
})
t.Run("logs", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "logs")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "logs")
res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
res.Assert(t, icmd.Expected{Out: `hello`})
})
t.Run("logs ping", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "logs", "ping")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "logs", "ping")
res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
assert.Assert(t, !strings.Contains(res.Stdout(), "hello"))
})
t.Run("logs hello", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "logs", "hello", "ping")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "logs", "hello", "ping")
res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
res.Assert(t, icmd.Expected{Out: `hello`})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}

View File

@ -24,32 +24,32 @@ import (
)
func TestComposeMetrics(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("catch specific failure metrics", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "-f", "fixtures/does-not-exist/compose.yaml", "build")
res := c.RunDockerOrExitError(t, "compose", "-f", "fixtures/does-not-exist/compose.yaml", "build")
expectedErr := "fixtures/does-not-exist/compose.yaml: no such file or directory"
if runtime.GOOS == "windows" {
expectedErr = "does-not-exist\\compose.yaml: The system cannot find the path specified"
}
res.Assert(t, icmd.Expected{ExitCode: 14, Err: expectedErr})
res = c.RunDockerOrExitError("compose", "-f", "fixtures/wrong-composefile/compose.yaml", "up", "-d")
res = c.RunDockerOrExitError(t, "compose", "-f", "fixtures/wrong-composefile/compose.yaml", "up", "-d")
res.Assert(t, icmd.Expected{ExitCode: 15, Err: "services.simple Additional property wrongField is not allowed"})
res = c.RunDockerOrExitError("compose", "up")
res = c.RunDockerOrExitError(t, "compose", "up")
res.Assert(t, icmd.Expected{ExitCode: 14, Err: "no configuration file provided: not found"})
res = c.RunDockerOrExitError("compose", "up", "-f", "fixtures/wrong-composefile/compose.yaml")
res = c.RunDockerOrExitError(t, "compose", "up", "-f", "fixtures/wrong-composefile/compose.yaml")
res.Assert(t, icmd.Expected{ExitCode: 16, Err: "unknown shorthand flag: 'f' in -f"})
res = c.RunDockerOrExitError("compose", "up", "--file", "fixtures/wrong-composefile/compose.yaml")
res = c.RunDockerOrExitError(t, "compose", "up", "--file", "fixtures/wrong-composefile/compose.yaml")
res.Assert(t, icmd.Expected{ExitCode: 16, Err: "unknown flag: --file"})
res = c.RunDockerOrExitError("compose", "donw", "--file", "fixtures/wrong-composefile/compose.yaml")
res = c.RunDockerOrExitError(t, "compose", "donw", "--file", "fixtures/wrong-composefile/compose.yaml")
res.Assert(t, icmd.Expected{ExitCode: 16, Err: `unknown docker command: "compose donw"`})
res = c.RunDockerOrExitError("compose", "--file", "fixtures/wrong-composefile/build-error.yml", "build")
res = c.RunDockerOrExitError(t, "compose", "--file", "fixtures/wrong-composefile/build-error.yml", "build")
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
res = c.RunDockerOrExitError("compose", "--file", "fixtures/wrong-composefile/build-error.yml", "up")
res = c.RunDockerOrExitError(t, "compose", "--file", "fixtures/wrong-composefile/build-error.yml", "up")
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
res = c.RunDockerOrExitError("compose", "--file", "fixtures/wrong-composefile/unknown-image.yml", "pull")
res = c.RunDockerOrExitError(t, "compose", "--file", "fixtures/wrong-composefile/unknown-image.yml", "pull")
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
res = c.RunDockerOrExitError("compose", "--file", "fixtures/wrong-composefile/unknown-image.yml", "up")
res = c.RunDockerOrExitError(t, "compose", "--file", "fixtures/wrong-composefile/unknown-image.yml", "up")
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
})
}

View File

@ -27,126 +27,135 @@ import (
)
func TestNetworks(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
// fixture is shared with TestNetworkModes and is not safe to run concurrently
c := NewCLI(t)
const projectName = "network_e2e"
t.Run("ensure we do not reuse previous networks", func(t *testing.T) {
c.RunDockerOrExitError("network", "rm", projectName+"_dbnet")
c.RunDockerOrExitError("network", "rm", "microservices")
c.RunDockerOrExitError(t, "network", "rm", projectName+"_dbnet")
c.RunDockerOrExitError(t, "network", "rm", "microservices")
})
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "up",
"-d")
})
t.Run("check running project", func(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res := c.RunDockerComposeCmd(t, "-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `web`})
endpoint := "http://localhost:80"
output := HTTPGetWithRetry(t, endpoint+"/words/noun", http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(output, `"word":`))
res = c.RunDockerCmd("network", "ls")
res = c.RunDockerCmd(t, "network", "ls")
res.Assert(t, icmd.Expected{Out: projectName + "_dbnet"})
res.Assert(t, icmd.Expected{Out: "microservices"})
})
t.Run("port", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "port", "words", "8080")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "port", "words", "8080")
res.Assert(t, icmd.Expected{Out: `0.0.0.0:8080`})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
t.Run("check networks after down", func(t *testing.T) {
res := c.RunDockerCmd("network", "ls")
res := c.RunDockerCmd(t, "network", "ls")
assert.Assert(t, !strings.Contains(res.Combined(), projectName), res.Combined())
assert.Assert(t, !strings.Contains(res.Combined(), "microservices"), res.Combined())
})
}
func TestNetworkAliasses(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
func TestNetworkAliases(t *testing.T) {
c := NewParallelCLI(t)
const projectName = "network_alias_e2e"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "up",
"-d")
})
t.Run("curl alias", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "exec", "-T", "container1", "curl", "http://alias-of-container2/")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName,
"exec", "-T", "container1", "curl", "http://alias-of-container2/")
assert.Assert(t, strings.Contains(res.Stdout(), "Welcome to nginx!"), res.Stdout())
})
t.Run("curl links", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "exec", "-T", "container1", "curl", "http://container/")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName,
"exec", "-T", "container1", "curl", "http://container/")
assert.Assert(t, strings.Contains(res.Stdout(), "Welcome to nginx!"), res.Stdout())
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}
func TestNetworkLinks(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "network_link_e2e"
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/network-links/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/network-links/compose.yaml", "--project-name", projectName, "up",
"-d")
})
t.Run("curl links in default bridge network", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/network-links/compose.yaml", "--project-name", projectName, "exec", "-T", "container2", "curl", "http://container1/")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/network-links/compose.yaml", "--project-name", projectName,
"exec", "-T", "container2", "curl", "http://container1/")
assert.Assert(t, strings.Contains(res.Stdout(), "Welcome to nginx!"), res.Stdout())
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}
func TestIPAMConfig(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "ipam_e2e"
t.Run("ensure we do not reuse previous networks", func(t *testing.T) {
c.RunDockerOrExitError("network", "rm", projectName+"_default")
c.RunDockerOrExitError(t, "network", "rm", projectName+"_default")
})
t.Run("up", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/ipam/compose.yaml", "--project-name", projectName, "up", "-d")
c.RunDockerComposeCmd(t, "-f", "./fixtures/ipam/compose.yaml", "--project-name", projectName, "up", "-d")
})
t.Run("ensure service get fixed IP assigned", func(t *testing.T) {
res := c.RunDockerCmd("inspect", projectName+"-foo-1", "-f", "{{ .NetworkSettings.Networks."+projectName+"_default.IPAddress }}")
res := c.RunDockerCmd(t, "inspect", projectName+"-foo-1", "-f",
"{{ .NetworkSettings.Networks."+projectName+"_default.IPAddress }}")
res.Assert(t, icmd.Expected{Out: "10.1.0.100"})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}
func TestNetworkModes(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
// fixture is shared with TestNetworks and is not safe to run concurrently
c := NewCLI(t)
const projectName = "network_mode_service_run"
t.Run("run with service mode dependency", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "run", "-T", "mydb", "echo", "success")
res := c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "run", "-T", "mydb", "echo", "success")
res.Assert(t, icmd.Expected{Out: "success"})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}

View File

@ -27,20 +27,20 @@ import (
)
func TestPs(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-ps"
res := c.RunDockerComposeCmd("-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "up", "-d")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "up", "-d")
if assert.NoError(t, res.Error) {
t.Cleanup(func() {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}
assert.Contains(t, res.Combined(), "Container e2e-ps-busybox-1 Started", res.Combined())
t.Run("pretty", func(t *testing.T) {
res = c.RunDockerComposeCmd("-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "ps")
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "ps")
lines := strings.Split(res.Combined(), "\n")
assert.Equal(t, 4, len(lines))
count := 0
@ -58,7 +58,8 @@ func TestPs(t *testing.T) {
})
t.Run("json", func(t *testing.T) {
res = c.RunDockerComposeCmd("-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "ps", "--format", "json")
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/ps-test/compose.yaml", "--project-name", projectName, "ps",
"--format", "json")
var output []api.ContainerSummary
err := json.Unmarshal([]byte(res.Combined()), &output)
assert.NoError(t, err)

View File

@ -27,7 +27,7 @@ import (
)
func TestRestart(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-restart"
getServiceRegx := func(service string, status string) string {
@ -38,27 +38,26 @@ func TestRestart(t *testing.T) {
t.Run("Up a project", func(t *testing.T) {
// This is just to ensure the containers do NOT exist
c.RunDockerOrExitError("compose", "--project-name", projectName, "down")
c.RunDockerOrExitError(t, "compose", "--project-name", projectName, "down")
res := c.RunDockerOrExitError("compose", "-f", "./fixtures/restart-test/compose.yaml", "--project-name", projectName, "up", "-d")
res := c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/restart-test/compose.yaml", "--project-name", projectName, "up", "-d")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-restart-restart-1 Started"), res.Combined())
c.WaitForCmdResult(c.NewDockerCmd("compose", "--project-name", projectName, "ps", "-a", "--format", "json"),
StdoutContains(`"State":"exited"`),
10*time.Second, 1*time.Second)
c.WaitForCmdResult(t, c.NewDockerCmd("compose", "--project-name", projectName, "ps", "-a", "--format", "json"),
StdoutContains(`"State":"exited"`), 10*time.Second, 1*time.Second)
res = c.RunDockerOrExitError("compose", "--project-name", projectName, "ps", "-a")
res = c.RunDockerOrExitError(t, "compose", "--project-name", projectName, "ps", "-a")
testify.Regexp(t, getServiceRegx("restart", "exited"), res.Stdout())
_ = c.RunDockerOrExitError("compose", "-f", "./fixtures/restart-test/compose.yaml", "--project-name", projectName, "restart")
_ = c.RunDockerOrExitError(t, "compose", "-f", "./fixtures/restart-test/compose.yaml", "--project-name", projectName, "restart")
// Give the same time but it must NOT exit
time.Sleep(time.Second)
res = c.RunDockerOrExitError("compose", "--project-name", projectName, "ps")
res = c.RunDockerOrExitError(t, "compose", "--project-name", projectName, "ps")
testify.Regexp(t, getServiceRegx("restart", "running"), res.Stdout())
// Clean up
c.RunDockerOrExitError("compose", "--project-name", projectName, "down")
c.RunDockerOrExitError(t, "compose", "--project-name", projectName, "down")
})
}

View File

@ -30,39 +30,44 @@ import (
)
func TestDisplayScanMessageAfterBuild(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
// assert docker scan plugin is available
c.RunDockerOrExitError("scan", "--help")
c.RunDockerOrExitError(t, "scan", "--help")
t.Run("display on compose build", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-compose-build", "build")
defer c.RunDockerOrExitError("rmi", "-f", "scan-msg-test-compose-build_nginx")
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p",
"scan-msg-test-compose-build", "build")
defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-compose-build_nginx")
res.Assert(t, icmd.Expected{Err: utils.ScanSuggestMsg})
})
t.Run("do not display on compose build with quiet flag", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-quiet", "build", "--quiet")
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-quiet",
"build", "--quiet")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
res = c.RunDockerCmd("rmi", "-f", "scan-msg-test-quiet_nginx")
res = c.RunDockerCmd(t, "rmi", "-f", "scan-msg-test-quiet_nginx")
assert.Assert(t, !strings.Contains(res.Combined(), "No such image"))
res = c.RunDockerComposeCmd("-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-q", "build", "-q")
defer c.RunDockerOrExitError("rmi", "-f", "scan-msg-test-q_nginx")
res = c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-q",
"build", "-q")
defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-q_nginx")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
})
_ = c.RunDockerOrExitError("rmi", "scan-msg-test_nginx")
_ = c.RunDockerOrExitError(t, "rmi", "scan-msg-test_nginx")
t.Run("display on compose up if image is built", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up", "-d")
defer c.RunDockerOrExitError("compose", "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "down")
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up",
"-d")
defer c.RunDockerOrExitError(t, "compose", "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "down")
res.Assert(t, icmd.Expected{Err: utils.ScanSuggestMsg})
})
t.Run("do not display on compose up if no image built", func(t *testing.T) { // re-run the same Compose aproject
res := c.RunDockerComposeCmd("-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up", "-d")
defer c.RunDockerOrExitError("compose", "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "down", "--rmi", "all")
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up",
"-d")
defer c.RunDockerOrExitError(t, "compose", "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "down", "--rmi", "all")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
})
@ -72,7 +77,7 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) {
err := ioutil.WriteFile(scanConfigFile, []byte(`{"optin":true}`), 0644)
assert.NilError(t, err)
res := c.RunDockerCmd("build", "-t", "test-image-scan-msg", "fixtures/simple-build-test/nginx-build")
res := c.RunDockerCmd(t, "build", "-t", "test-image-scan-msg", "fixtures/simple-build-test/nginx-build")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
})
}

View File

@ -23,7 +23,7 @@ import (
)
func TestSecretFromEnv(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
t.Run("compose run", func(t *testing.T) {
res := icmd.RunCmd(c.NewDockerCmd("compose", "-f", "./fixtures/env-secret/compose.yaml", "run", "foo"),

View File

@ -23,11 +23,11 @@ import (
)
func TestStartFail(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-start-fail"
res := c.RunDockerOrExitError("compose", "-f", "fixtures/start-fail/compose.yaml", "--project-name", projectName, "up", "-d")
res := c.RunDockerOrExitError(t, "compose", "-f", "fixtures/start-fail/compose.yaml", "--project-name", projectName, "up", "-d")
res.Assert(t, icmd.Expected{ExitCode: 1, Err: `container for service "fail" is unhealthy`})
c.RunDockerComposeCmd("--project-name", projectName, "down")
c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
}

View File

@ -26,7 +26,7 @@ import (
)
func TestStartStop(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-start-stop-no-dependencies"
getProjectRegx := func(status string) string {
@ -42,103 +42,106 @@ func TestStartStop(t *testing.T) {
}
t.Run("Up a project", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "up", "-d")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "up",
"-d")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-no-dependencies-simple-1 Started"), res.Combined())
res = c.RunDockerComposeCmd("ls", "--all")
res = c.RunDockerComposeCmd(t, "ls", "--all")
testify.Regexp(t, getProjectRegx("running"), res.Stdout())
res = c.RunDockerComposeCmd("--project-name", projectName, "ps")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps")
testify.Regexp(t, getServiceRegx("simple", "running"), res.Stdout())
testify.Regexp(t, getServiceRegx("another", "running"), res.Stdout())
})
t.Run("stop project", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "stop")
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "stop")
res := c.RunDockerComposeCmd("ls")
res := c.RunDockerComposeCmd(t, "ls")
assert.Assert(t, !strings.Contains(res.Combined(), "e2e-start-stop-no-dependencies"), res.Combined())
res = c.RunDockerComposeCmd("ls", "--all")
res = c.RunDockerComposeCmd(t, "ls", "--all")
testify.Regexp(t, getProjectRegx("exited"), res.Stdout())
res = c.RunDockerComposeCmd("--project-name", projectName, "ps")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps")
assert.Assert(t, !strings.Contains(res.Combined(), "e2e-start-stop-no-dependencies-words-1"), res.Combined())
res = c.RunDockerComposeCmd("--project-name", projectName, "ps", "--all")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--all")
testify.Regexp(t, getServiceRegx("simple", "exited"), res.Stdout())
testify.Regexp(t, getServiceRegx("another", "exited"), res.Stdout())
})
t.Run("start project", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "start")
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "start")
res := c.RunDockerComposeCmd("ls")
res := c.RunDockerComposeCmd(t, "ls")
testify.Regexp(t, getProjectRegx("running"), res.Stdout())
})
t.Run("pause project", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "pause")
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "pause")
res := c.RunDockerComposeCmd("ls", "--all")
res := c.RunDockerComposeCmd(t, "ls", "--all")
testify.Regexp(t, getProjectRegx("paused"), res.Stdout())
})
t.Run("unpause project", func(t *testing.T) {
c.RunDockerComposeCmd("-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "unpause")
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "unpause")
res := c.RunDockerComposeCmd("ls")
res := c.RunDockerComposeCmd(t, "ls")
testify.Regexp(t, getProjectRegx("running"), res.Stdout())
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}
func TestStartStopWithDependencies(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "e2e-start-stop-with-dependencies"
defer c.RunDockerComposeCmd("--project-name", projectName, "rm", "-fsv")
defer c.RunDockerComposeCmd(t, "--project-name", projectName, "rm", "-fsv")
t.Run("Up", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/dependencies/compose.yaml", "--project-name", projectName, "up", "-d")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/dependencies/compose.yaml", "--project-name", projectName,
"up", "-d")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-foo-1 Started"), res.Combined())
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Started"), res.Combined())
})
t.Run("stop foo", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "stop", "foo")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "stop", "foo")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-foo-1 Stopped"), res.Combined())
res = c.RunDockerComposeCmd("--project-name", projectName, "ps", "--status", "running")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--status", "running")
assert.Assert(t, strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-bar-1"), res.Combined())
assert.Assert(t, !strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-foo-1"), res.Combined())
})
t.Run("start foo", func(t *testing.T) {
res := c.RunDockerComposeCmd("--project-name", projectName, "stop")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "stop")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Stopped"), res.Combined())
res = c.RunDockerComposeCmd("--project-name", projectName, "start", "foo")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "start", "foo")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Started"), res.Combined())
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-foo-1 Started"), res.Combined())
res = c.RunDockerComposeCmd("--project-name", projectName, "ps", "--status", "running")
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--status", "running")
assert.Assert(t, strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-bar-1"), res.Combined())
assert.Assert(t, strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-foo-1"), res.Combined())
})
t.Run("Up no-deps links", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
res := c.RunDockerComposeCmd("-f", "./fixtures/links/compose.yaml", "--project-name", projectName, "up", "--no-deps", "-d", "foo")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/links/compose.yaml", "--project-name", projectName, "up",
"--no-deps", "-d", "foo")
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-foo-1 Started"), res.Combined())
assert.Assert(t, !strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Started"), res.Combined())
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd("--project-name", projectName, "down")
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
}

View File

@ -29,16 +29,17 @@ import (
)
func TestLocalComposeVolume(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "compose-e2e-volume"
t.Run("up with build and no image name, volume", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "compose-e2e-volume_nginx")
c.RunDockerOrExitError("volume", "rm", projectName+"_staticVol")
c.RunDockerOrExitError("volume", "rm", "myvolume")
c.RunDockerComposeCmd("--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "-d")
c.RunDockerOrExitError(t, "rmi", "compose-e2e-volume_nginx")
c.RunDockerOrExitError(t, "volume", "rm", projectName+"_staticVol")
c.RunDockerOrExitError(t, "volume", "rm", "myvolume")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up",
"-d")
})
t.Run("access bind mount data", func(t *testing.T) {
@ -47,7 +48,7 @@ func TestLocalComposeVolume(t *testing.T) {
})
t.Run("check container volume specs", func(t *testing.T) {
res := c.RunDockerCmd("inspect", "compose-e2e-volume-nginx2-1", "--format", "{{ json .Mounts }}")
res := c.RunDockerCmd(t, "inspect", "compose-e2e-volume-nginx2-1", "--format", "{{ json .Mounts }}")
output := res.Stdout()
// nolint
assert.Assert(t, strings.Contains(output, `"Destination":"/usr/src/app/node_modules","Driver":"local","Mode":"z","RW":true,"Propagation":""`), output)
@ -55,17 +56,17 @@ func TestLocalComposeVolume(t *testing.T) {
})
t.Run("check config content", func(t *testing.T) {
output := c.RunDockerCmd("exec", "compose-e2e-volume-nginx2-1", "cat", "/myconfig").Stdout()
output := c.RunDockerCmd(t, "exec", "compose-e2e-volume-nginx2-1", "cat", "/myconfig").Stdout()
assert.Assert(t, strings.Contains(output, `Hello from Nginx container`), output)
})
t.Run("check secrets content", func(t *testing.T) {
output := c.RunDockerCmd("exec", "compose-e2e-volume-nginx2-1", "cat", "/run/secrets/mysecret").Stdout()
output := c.RunDockerCmd(t, "exec", "compose-e2e-volume-nginx2-1", "cat", "/run/secrets/mysecret").Stdout()
assert.Assert(t, strings.Contains(output, `Hello from Nginx container`), output)
})
t.Run("check container bind-mounts specs", func(t *testing.T) {
res := c.RunDockerCmd("inspect", "compose-e2e-volume-nginx-1", "--format", "{{ json .Mounts }}")
res := c.RunDockerCmd(t, "inspect", "compose-e2e-volume-nginx-1", "--format", "{{ json .Mounts }}")
output := res.Stdout()
// nolint
assert.Assert(t, strings.Contains(output, `"Type":"bind"`))
@ -73,20 +74,20 @@ func TestLocalComposeVolume(t *testing.T) {
})
t.Run("should inherit anonymous volumes", func(t *testing.T) {
c.RunDockerOrExitError("exec", "compose-e2e-volume-nginx2-1", "touch", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError("compose", "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "--force-recreate", "-d")
c.RunDockerOrExitError("exec", "compose-e2e-volume-nginx2-1", "ls", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError(t, "exec", "compose-e2e-volume-nginx2-1", "touch", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError(t, "compose", "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "--force-recreate", "-d")
c.RunDockerOrExitError(t, "exec", "compose-e2e-volume-nginx2-1", "ls", "/usr/src/app/node_modules/test")
})
t.Run("should renew anonymous volumes", func(t *testing.T) {
c.RunDockerOrExitError("exec", "compose-e2e-volume-nginx2-1", "touch", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError("compose", "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "--force-recreate", "--renew-anon-volumes", "-d")
c.RunDockerOrExitError("exec", "compose-e2e-volume-nginx2-1", "ls", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError(t, "exec", "compose-e2e-volume-nginx2-1", "touch", "/usr/src/app/node_modules/test")
c.RunDockerOrExitError(t, "compose", "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "--force-recreate", "--renew-anon-volumes", "-d")
c.RunDockerOrExitError(t, "exec", "compose-e2e-volume-nginx2-1", "ls", "/usr/src/app/node_modules/test")
})
t.Run("cleanup volume project", func(t *testing.T) {
c.RunDockerComposeCmd("--project-name", projectName, "down", "--volumes")
ls := c.RunDockerCmd("volume", "ls").Stdout()
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "--volumes")
ls := c.RunDockerCmd(t, "volume", "ls").Stdout()
assert.Assert(t, !strings.Contains(ls, projectName+"_staticVol"))
assert.Assert(t, !strings.Contains(ls, "myvolume"))
})
@ -96,7 +97,7 @@ func TestProjectVolumeBind(t *testing.T) {
if composeStandaloneMode {
t.Skip()
}
c := NewParallelE2eCLI(t, binDir)
c := NewParallelCLI(t)
const projectName = "compose-e2e-project-volume-bind"
t.Run("up on project volume with bind specification", func(t *testing.T) {
@ -104,17 +105,17 @@ func TestProjectVolumeBind(t *testing.T) {
assert.NilError(t, err)
defer os.RemoveAll(tmpDir) // nolint
c.RunDockerComposeCmd("--project-name", projectName, "down")
c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
c.RunDockerOrExitError("volume", "rm", "-f", projectName+"_project_data").Assert(t, icmd.Success)
c.RunDockerOrExitError(t, "volume", "rm", "-f", projectName+"_project_data").Assert(t, icmd.Success)
cmd := c.NewCmdWithEnv([]string{"TEST_DIR=" + tmpDir},
"docker", "compose", "--project-directory", "fixtures/project-volume-bind-test", "--project-name", projectName, "up", "-d")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
defer c.RunDockerComposeCmd("--project-name", projectName, "down")
defer c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
c.RunCmd("sh", "-c", "echo SUCCESS > "+filepath.Join(tmpDir, "resultfile")).Assert(t, icmd.Success)
c.RunCmd(t, "sh", "-c", "echo SUCCESS > "+filepath.Join(tmpDir, "resultfile")).Assert(t, icmd.Success)
ret := c.RunDockerOrExitError("exec", "frontend", "bash", "-c", "cat /data/resultfile").Assert(t, icmd.Success)
ret := c.RunDockerOrExitError(t, "exec", "frontend", "bash", "-c", "cat /data/resultfile").Assert(t, icmd.Success)
assert.Assert(t, strings.Contains(ret.Stdout(), "SUCCESS"))
})
}