mirror of https://github.com/docker/compose.git
				
				
				
			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 <milas.bowman@docker.com>
This commit is contained in:
		
							parent
							
								
									cc2dc868c2
								
							
						
					
					
						commit
						26014d49a5
					
				|  | @ -0,0 +1,9 @@ | |||
| services: | ||||
|   a: | ||||
|     image:  nginx:alpine | ||||
|     ports: [80] | ||||
|   b: | ||||
|     image:  nginx:alpine | ||||
|     ports: [80] | ||||
|     depends_on: | ||||
|       - a | ||||
|  | @ -0,0 +1,155 @@ | |||
| /* | ||||
|    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 ( | ||||
| 	"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 | ||||
| } | ||||
|  | @ -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") | ||||
| 	}) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue