Skip to content

Commit

Permalink
e2e: split out pause tests and add more cases
Browse files Browse the repository at this point in the history
Pause/unpause was being partially tested under the start/stop test.
This removes it from that test and adds dedicated pause + unpause
tests.

Note that the tests assert on current behavior, though it's been
noted where that is undesirable due to divergence from the Docker
CLI. Will change the behavior + update tests in a subsequent PR.

Signed-off-by: Milas Bowman <[email protected]>
  • Loading branch information
milas committed Jun 28, 2022
1 parent cc2dc86 commit a7773fe
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 14 deletions.
9 changes: 9 additions & 0 deletions pkg/e2e/fixtures/pause/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
a:
image: nginx:alpine
ports: [80]
b:
image: nginx:alpine
ports: [80]
depends_on:
- a
139 changes: 139 additions & 0 deletions pkg/e2e/pause_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package e2e

import (
"encoding/json"
"fmt"
"net"
"net/http"
"testing"
"time"

"github.com/stretchr/testify/require"
"gotest.tools/v3/icmd"
)

func TestPause(t *testing.T) {
cli := NewParallelCLI(t, WithEnv(
"COMPOSE_PROJECT_NAME=e2e-pause",
"COMPOSE_FILE=./fixtures/pause/compose.yaml"))

cleanup := func() {
cli.RunDockerComposeCmd(t, "down", "-v", "--remove-orphans", "-t", "0")
}
cleanup()
t.Cleanup(cleanup)

// launch both services and verify that they are accessible
cli.RunDockerComposeCmd(t, "up", "-d")
urls := map[string]string{
"a": urlForService(t, cli, "a", 80),
"b": urlForService(t, cli, "b", 80),
}
for _, url := range urls {
HTTPGetWithRetry(t, url, http.StatusOK, 50*time.Millisecond, 5*time.Second)
}

// pause a and verify that it can no longer be hit but b still can
cli.RunDockerComposeCmd(t, "pause", "a")
httpClient := http.Client{Timeout: 250 * time.Millisecond}
resp, err := httpClient.Get(urls["a"])
if resp != nil {
_ = resp.Body.Close()
}
require.Error(t, err, "a should no longer respond")
require.True(t, err.(net.Error).Timeout(), "Error should have indicated a timeout")
HTTPGetWithRetry(t, urls["b"], http.StatusOK, 50*time.Millisecond, 5*time.Second)

// unpause a and verify that both containers work again
cli.RunDockerComposeCmd(t, "unpause", "a")
for _, url := range urls {
HTTPGetWithRetry(t, url, http.StatusOK, 50*time.Millisecond, 5*time.Second)
}
}

func TestPauseServiceNotRunning(t *testing.T) {
cli := NewParallelCLI(t, WithEnv(
"COMPOSE_PROJECT_NAME=e2e-pause-svc-not-running",
"COMPOSE_FILE=./fixtures/pause/compose.yaml"))

cleanup := func() {
cli.RunDockerComposeCmd(t, "down", "-v", "--remove-orphans", "-t", "0")
}
cleanup()
t.Cleanup(cleanup)

// pause a and verify that it can no longer be hit but b still can
res := cli.RunDockerComposeCmdNoCheck(t, "pause", "a")

// TODO: `docker pause` errors in this case, should Compose be consistent?
res.Assert(t, icmd.Expected{ExitCode: 0})
}

func TestPauseServiceAlreadyPaused(t *testing.T) {
cli := NewParallelCLI(t, WithEnv(
"COMPOSE_PROJECT_NAME=e2e-pause-svc-already-paused",
"COMPOSE_FILE=./fixtures/pause/compose.yaml"))

cleanup := func() {
cli.RunDockerComposeCmd(t, "down", "-v", "--remove-orphans", "-t", "0")
}
cleanup()
t.Cleanup(cleanup)

// launch a and wait for it to come up
cli.RunDockerComposeCmd(t, "up", "-d", "a")
HTTPGetWithRetry(t, urlForService(t, cli, "a", 80), http.StatusOK, 50*time.Millisecond, 5*time.Second)

// pause a twice - first time should pass, second time fail
cli.RunDockerComposeCmd(t, "pause", "a")
res := cli.RunDockerComposeCmdNoCheck(t, "pause", "a")
res.Assert(t, icmd.Expected{ExitCode: 1, Err: "already paused"})
}

func TestPauseServiceDoesNotExist(t *testing.T) {
cli := NewParallelCLI(t, WithEnv(
"COMPOSE_PROJECT_NAME=e2e-pause-svc-not-exist",
"COMPOSE_FILE=./fixtures/pause/compose.yaml"))

cleanup := func() {
cli.RunDockerComposeCmd(t, "down", "-v", "--remove-orphans", "-t", "0")
}
cleanup()
t.Cleanup(cleanup)

// pause a and verify that it can no longer be hit but b still can
res := cli.RunDockerComposeCmdNoCheck(t, "pause", "does_not_exist")
// TODO: `compose down does_not_exist` and similar error, this should too
res.Assert(t, icmd.Expected{ExitCode: 0})
}

func urlForService(t testing.TB, cli *CLI, service string, targetPort int) string {
t.Helper()
return fmt.Sprintf(
"http://localhost:%d",
publishedPortForService(t, cli, service, targetPort),
)
}

func publishedPortForService(t testing.TB, cli *CLI, service string, targetPort int) int {
t.Helper()
res := cli.RunDockerComposeCmd(t, "ps", "--format=json", service)
var psOut []struct {
Publishers []struct {
TargetPort int
PublishedPort int
}
}
require.NoError(t, json.Unmarshal([]byte(res.Stdout()), &psOut),
"Failed to parse `%s` output", res.Cmd.String())
require.Len(t, psOut, 1, "Expected exactly 1 service")
svc := psOut[0]
for _, pp := range svc.Publishers {
if pp.TargetPort == targetPort {
return pp.PublishedPort
}
}
require.Failf(t, "No published port for target port",
"Target port: %d\nService: %s", targetPort, res.Combined())
return -1
}
14 changes: 0 additions & 14 deletions pkg/e2e/start_stop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,6 @@ func TestStartStop(t *testing.T) {
testify.Regexp(t, getProjectRegx("running"), res.Stdout())
})

t.Run("pause project", func(t *testing.T) {
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "pause")

res := c.RunDockerComposeCmd(t, "ls", "--all")
testify.Regexp(t, getProjectRegx("paused"), res.Stdout())
})

t.Run("unpause project", func(t *testing.T) {
c.RunDockerComposeCmd(t, "-f", "./fixtures/start-stop/compose.yaml", "--project-name", projectName, "unpause")

res := c.RunDockerComposeCmd(t, "ls")
testify.Regexp(t, getProjectRegx("running"), res.Stdout())
})

t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})
Expand Down

0 comments on commit a7773fe

Please sign in to comment.