|  | @@ -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)
 | 
	
		
			
				|  |  |  
 |