-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
e2e: split out
pause
tests and add more cases
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
Showing
3 changed files
with
148 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters