From bc9bd9f880993816ad3207ef1f61615e3f091b5b Mon Sep 17 00:00:00 2001 From: Guillaume Tardif <guillaume.tardif@gmail.com> Date: Wed, 24 Feb 2021 10:53:06 +0100 Subject: [PATCH] Moving compose e2e tests in their own files Signed-off-by: Guillaume Tardif <guillaume.tardif@gmail.com> --- local/e2e/compose/compose_build_test.go | 75 +++++++++ local/e2e/compose/compose_run_test.go | 86 +++++++++++ local/e2e/compose/compose_test.go | 193 ------------------------ local/e2e/compose/networks_test.go | 67 ++++++++ local/e2e/compose/volumes_test.go | 78 ++++++++++ 5 files changed, 306 insertions(+), 193 deletions(-) create mode 100644 local/e2e/compose/compose_build_test.go create mode 100644 local/e2e/compose/compose_run_test.go create mode 100644 local/e2e/compose/networks_test.go create mode 100644 local/e2e/compose/volumes_test.go diff --git a/local/e2e/compose/compose_build_test.go b/local/e2e/compose/compose_build_test.go new file mode 100644 index 000000000..b587c2ef9 --- /dev/null +++ b/local/e2e/compose/compose_build_test.go @@ -0,0 +1,75 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package e2e + +import ( + "net/http" + "strings" + "testing" + "time" + + "gotest.tools/v3/assert" + "gotest.tools/v3/icmd" + + . "github.com/docker/compose-cli/utils/e2e" +) + +func TestLocalComposeBuild(t *testing.T) { + c := NewParallelE2eCLI(t, binDir) + + 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") + + res := c.RunDockerCmd("compose", "--workdir", "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") + }) + + t.Run("build as part of up", func(t *testing.T) { + c.RunDockerOrExitError("rmi", "build-test_nginx") + c.RunDockerOrExitError("rmi", "custom-nginx") + + res := c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "up", "-d") + t.Cleanup(func() { + c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "down") + }) + + res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) + + 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") + }) + + t.Run("no rebuild when up again", func(t *testing.T) { + res := c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "up", "-d") + + assert.Assert(t, !strings.Contains(res.Stdout(), "COPY static /usr/share/nginx/html"), res.Stdout()) + }) + + t.Run("cleanup build project", func(t *testing.T) { + c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "down") + c.RunDockerCmd("rmi", "build-test_nginx") + c.RunDockerCmd("rmi", "custom-nginx") + }) +} diff --git a/local/e2e/compose/compose_run_test.go b/local/e2e/compose/compose_run_test.go new file mode 100644 index 000000000..777d38695 --- /dev/null +++ b/local/e2e/compose/compose_run_test.go @@ -0,0 +1,86 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package e2e + +import ( + "strings" + "testing" + + "gotest.tools/v3/assert" + "gotest.tools/v3/icmd" + + . "github.com/docker/compose-cli/utils/e2e" +) + +func TestLocalComposeRun(t *testing.T) { + c := NewParallelE2eCLI(t, binDir) + + t.Run("compose run", func(t *testing.T) { + res := c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "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.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "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") + lines := Lines(res.Stdout()) + var runContainerID string + var truncatedSlug string + for _, line := range lines { + fields := strings.Fields(line) + containerID := fields[len(fields)-1] + assert.Assert(t, !strings.HasPrefix(containerID, "run-test_front")) + if strings.HasPrefix(containerID, "run-test_back") { + // only the one-off container for back service + assert.Assert(t, strings.HasPrefix(containerID, "run-test_back_run_"), containerID) + truncatedSlug = strings.Replace(containerID, "run-test_back_run_", "", 1) + runContainerID = containerID + } + if strings.HasPrefix(containerID, "run-test_db_1") { + assert.Assert(t, strings.Contains(line, "Up"), line) + } + } + assert.Assert(t, runContainerID != "") + res = c.RunDockerCmd("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"`}) + res.Assert(t, icmd.Expected{Out: `"com.docker.compose.oneoff": "True",`}) + res.Assert(t, icmd.Expected{Out: `"com.docker.compose.slug": "` + truncatedSlug}) + }) + + t.Run("compose run --rm", func(t *testing.T) { + res := c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "run", "--rm", "back", "/bin/sh", "-c", "echo Hello again") + lines := Lines(res.Stdout()) + assert.Equal(t, lines[len(lines)-1], "Hello again", res.Stdout()) + + res = c.RunDockerCmd("ps", "--all") + assert.Assert(t, strings.Contains(res.Stdout(), "run-test_back"), res.Stdout()) + }) + + t.Run("down", func(t *testing.T) { + c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "down") + res := c.RunDockerCmd("ps", "--all") + assert.Assert(t, !strings.Contains(res.Stdout(), "run-test"), res.Stdout()) + }) +} diff --git a/local/e2e/compose/compose_test.go b/local/e2e/compose/compose_test.go index 1d449333e..37b9355bf 100644 --- a/local/e2e/compose/compose_test.go +++ b/local/e2e/compose/compose_test.go @@ -115,199 +115,6 @@ func TestLocalComposeUp(t *testing.T) { }) } -func TestLocalComposeRun(t *testing.T) { - c := NewParallelE2eCLI(t, binDir) - - t.Run("compose run", func(t *testing.T) { - res := c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "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.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "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") - lines := Lines(res.Stdout()) - var runContainerID string - var truncatedSlug string - for _, line := range lines { - fields := strings.Fields(line) - containerID := fields[len(fields)-1] - assert.Assert(t, !strings.HasPrefix(containerID, "run-test_front")) - if strings.HasPrefix(containerID, "run-test_back") { - // only the one-off container for back service - assert.Assert(t, strings.HasPrefix(containerID, "run-test_back_run_"), containerID) - truncatedSlug = strings.Replace(containerID, "run-test_back_run_", "", 1) - runContainerID = containerID - } - if strings.HasPrefix(containerID, "run-test_db_1") { - assert.Assert(t, strings.Contains(line, "Up"), line) - } - } - assert.Assert(t, runContainerID != "") - res = c.RunDockerCmd("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"`}) - res.Assert(t, icmd.Expected{Out: `"com.docker.compose.oneoff": "True",`}) - res.Assert(t, icmd.Expected{Out: `"com.docker.compose.slug": "` + truncatedSlug}) - }) - - t.Run("compose run --rm", func(t *testing.T) { - res := c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "run", "--rm", "back", "/bin/sh", "-c", "echo Hello again") - lines := Lines(res.Stdout()) - assert.Equal(t, lines[len(lines)-1], "Hello again", res.Stdout()) - - res = c.RunDockerCmd("ps", "--all") - assert.Assert(t, strings.Contains(res.Stdout(), "run-test_back"), res.Stdout()) - }) - - t.Run("down", func(t *testing.T) { - c.RunDockerCmd("compose", "-f", "./fixtures/run-test/compose.yml", "down") - res := c.RunDockerCmd("ps", "--all") - assert.Assert(t, !strings.Contains(res.Stdout(), "run-test"), res.Stdout()) - }) -} - -func TestNetworks(t *testing.T) { - c := NewParallelE2eCLI(t, binDir) - - 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") - }) - - t.Run("up", func(t *testing.T) { - c.RunDockerCmd("compose", "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "up", "-d") - }) - - t.Run("check running project", func(t *testing.T) { - res := c.RunDockerCmd("compose", "-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.Assert(t, icmd.Expected{Out: projectName + "_dbnet"}) - res.Assert(t, icmd.Expected{Out: "microservices"}) - }) - - t.Run("down", func(t *testing.T) { - _ = c.RunDockerCmd("compose", "--project-name", projectName, "down") - }) - - t.Run("check networks after down", func(t *testing.T) { - res := c.RunDockerCmd("network", "ls") - assert.Assert(t, !strings.Contains(res.Combined(), projectName), res.Combined()) - assert.Assert(t, !strings.Contains(res.Combined(), "microservices"), res.Combined()) - }) -} - -func TestLocalComposeBuild(t *testing.T) { - c := NewParallelE2eCLI(t, binDir) - - 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") - - res := c.RunDockerCmd("compose", "--workdir", "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") - }) - - t.Run("build as part of up", func(t *testing.T) { - c.RunDockerOrExitError("rmi", "build-test_nginx") - c.RunDockerOrExitError("rmi", "custom-nginx") - - res := c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "up", "-d") - t.Cleanup(func() { - c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "down") - }) - - res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) - - 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") - }) - - t.Run("no rebuild when up again", func(t *testing.T) { - res := c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "up", "-d") - - assert.Assert(t, !strings.Contains(res.Stdout(), "COPY static /usr/share/nginx/html"), res.Stdout()) - }) - - t.Run("cleanup build project", func(t *testing.T) { - c.RunDockerCmd("compose", "--workdir", "fixtures/build-test", "down") - c.RunDockerCmd("rmi", "build-test_nginx") - c.RunDockerCmd("rmi", "custom-nginx") - }) -} - -func TestLocalComposeVolume(t *testing.T) { - c := NewParallelE2eCLI(t, binDir) - - 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.RunDockerCmd("compose", "--workdir", "fixtures/volume-test", "--project-name", projectName, "up", "-d") - }) - - t.Run("access bind mount data", func(t *testing.T) { - output := HTTPGetWithRetry(t, "http://localhost:8090", http.StatusOK, 2*time.Second, 20*time.Second) - assert.Assert(t, strings.Contains(output, "Hello from Nginx container")) - }) - - t.Run("check container volume specs", func(t *testing.T) { - res := c.RunDockerCmd("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":"","RW":true,"Propagation":""`), output) - assert.Assert(t, strings.Contains(output, `"Destination":"/myconfig","Mode":"","RW":false,"Propagation":"rprivate"`), output) - }) - - t.Run("check config content", func(t *testing.T) { - output := c.RunDockerCmd("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() - 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 .HostConfig.Mounts }}") - output := res.Stdout() - // nolint - assert.Assert(t, strings.Contains(output, `"Type":"bind"`)) - assert.Assert(t, strings.Contains(output, `"Target":"/usr/share/nginx/html"`)) - }) - - t.Run("cleanup volume project", func(t *testing.T) { - c.RunDockerCmd("compose", "--project-name", projectName, "down") - c.RunDockerCmd("volume", "rm", projectName+"_staticVol") - }) -} - func TestComposePull(t *testing.T) { c := NewParallelE2eCLI(t, binDir) diff --git a/local/e2e/compose/networks_test.go b/local/e2e/compose/networks_test.go new file mode 100644 index 000000000..f90d5796f --- /dev/null +++ b/local/e2e/compose/networks_test.go @@ -0,0 +1,67 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package e2e + +import ( + "net/http" + "strings" + "testing" + "time" + + "gotest.tools/v3/assert" + "gotest.tools/v3/icmd" + + . "github.com/docker/compose-cli/utils/e2e" +) + +func TestNetworks(t *testing.T) { + c := NewParallelE2eCLI(t, binDir) + + 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") + }) + + t.Run("up", func(t *testing.T) { + c.RunDockerCmd("compose", "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "up", "-d") + }) + + t.Run("check running project", func(t *testing.T) { + res := c.RunDockerCmd("compose", "-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.Assert(t, icmd.Expected{Out: projectName + "_dbnet"}) + res.Assert(t, icmd.Expected{Out: "microservices"}) + }) + + t.Run("down", func(t *testing.T) { + _ = c.RunDockerCmd("compose", "--project-name", projectName, "down") + }) + + t.Run("check networks after down", func(t *testing.T) { + res := c.RunDockerCmd("network", "ls") + assert.Assert(t, !strings.Contains(res.Combined(), projectName), res.Combined()) + assert.Assert(t, !strings.Contains(res.Combined(), "microservices"), res.Combined()) + }) +} diff --git a/local/e2e/compose/volumes_test.go b/local/e2e/compose/volumes_test.go new file mode 100644 index 000000000..b129170cb --- /dev/null +++ b/local/e2e/compose/volumes_test.go @@ -0,0 +1,78 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package e2e + +import ( + "net/http" + "strings" + "testing" + "time" + + "gotest.tools/v3/assert" + + . "github.com/docker/compose-cli/utils/e2e" +) + +func TestLocalComposeVolume(t *testing.T) { + c := NewParallelE2eCLI(t, binDir) + + 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.RunDockerCmd("compose", "--workdir", "fixtures/volume-test", "--project-name", projectName, "up", "-d") + }) + + t.Run("access bind mount data", func(t *testing.T) { + output := HTTPGetWithRetry(t, "http://localhost:8090", http.StatusOK, 2*time.Second, 20*time.Second) + assert.Assert(t, strings.Contains(output, "Hello from Nginx container")) + }) + + t.Run("check container volume specs", func(t *testing.T) { + res := c.RunDockerCmd("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":"","RW":true,"Propagation":""`), output) + assert.Assert(t, strings.Contains(output, `"Destination":"/myconfig","Mode":"","RW":false,"Propagation":"rprivate"`), output) + }) + + t.Run("check config content", func(t *testing.T) { + output := c.RunDockerCmd("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() + 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 .HostConfig.Mounts }}") + output := res.Stdout() + // nolint + assert.Assert(t, strings.Contains(output, `"Type":"bind"`)) + assert.Assert(t, strings.Contains(output, `"Target":"/usr/share/nginx/html"`)) + }) + + t.Run("cleanup volume project", func(t *testing.T) { + c.RunDockerCmd("compose", "--project-name", projectName, "down") + c.RunDockerCmd("volume", "rm", projectName+"_staticVol") + }) +}