Skip to content

Commit d2334f9

Browse files
kterui9019claude
andcommitted
test: add integration tests for docker-compose deployer
Add comprehensive integration tests for the Docker Compose deployer: 1. Test data: - integration/testdata/docker-compose-deploy/ - integration/examples/docker-compose-deploy/ 2. Integration tests: - TestDeleteDockerComposeDeployer: Tests deployment and cleanup - TestDevCancelWithDockerComposeDeployer: Tests dev loop cancellation 3. Helper functions: - getComposeContainers: Filters containers by compose project label - waitForComposeContainersRunning: Waits for compose containers to start These tests verify that: - Docker Compose deployments work correctly - Containers are properly started with correct labels - Cleanup (delete) removes all compose containers - Dev mode can be gracefully canceled The tests use Docker Compose's project label (com.docker.compose.project) to identify containers, which works with the dynamic project naming (skaffold-{runID}) used by the deployer. This also fixes the CI error from check-samples.sh by adding the required integration/examples directory. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 20e5e84 commit d2334f9

File tree

15 files changed

+437
-0
lines changed

15 files changed

+437
-0
lines changed

integration/delete_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,65 @@ func getContainers(ctx context.Context, t *testutil.T, deployedContainers []stri
133133
return cl
134134
}
135135

136+
func getComposeContainers(ctx context.Context, t *testutil.T, projectNamePrefix string, client docker.LocalDaemon) []types.Container {
137+
t.Helper()
138+
139+
// List all containers
140+
cl, err := client.ContainerList(ctx, container.ListOptions{
141+
All: true,
142+
})
143+
t.CheckNoError(err)
144+
145+
// Filter containers by project name prefix
146+
var result []types.Container
147+
for _, c := range cl {
148+
if project, ok := c.Labels["com.docker.compose.project"]; ok {
149+
// Check if project name starts with the prefix (e.g., "skaffold-")
150+
if len(project) > len(projectNamePrefix) && project[:len(projectNamePrefix)] == projectNamePrefix {
151+
result = append(result, c)
152+
}
153+
}
154+
}
155+
156+
return result
157+
}
158+
159+
func TestDeleteDockerComposeDeployer(t *testing.T) {
160+
tests := []struct {
161+
description string
162+
dir string
163+
args []string
164+
}{
165+
{
166+
description: "docker compose deployer",
167+
dir: "testdata/docker-compose-deploy",
168+
args: []string{},
169+
},
170+
}
171+
172+
for _, test := range tests {
173+
testutil.Run(t, test.description, func(t *testutil.T) {
174+
MarkIntegrationTest(t.T, CanRunWithoutGcp)
175+
ctx := context.Background()
176+
177+
// Run skaffold to deploy with docker compose
178+
skaffold.Run(test.args...).InDir(test.dir).RunOrFail(t.T)
179+
180+
// Verify containers are running
181+
client := SetupDockerClient(t.T)
182+
containers := getComposeContainers(ctx, t, "skaffold-", client)
183+
t.CheckTrue(len(containers) > 0, "Expected at least one container to be deployed")
184+
185+
// Delete the deployment
186+
skaffold.Delete(test.args...).InDir(test.dir).RunOrFail(t.T)
187+
188+
// Verify containers are deleted
189+
containers = getComposeContainers(ctx, t, "skaffold-", client)
190+
t.CheckDeepEqual(0, len(containers))
191+
})
192+
}
193+
}
194+
136195
func TestDeleteNonExistedHelmResource(t *testing.T) {
137196
var tests = []struct {
138197
description string

integration/dev_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,48 @@ func TestDevCancelWithDockerDeployer(t *testing.T) {
187187
}
188188
}
189189

190+
func TestDevCancelWithDockerComposeDeployer(t *testing.T) {
191+
if runtime.GOOS == "windows" {
192+
t.Skip("graceful cancel doesn't work on windows")
193+
}
194+
195+
tests := []struct {
196+
description string
197+
dir string
198+
minContainers int
199+
projectPrefix string
200+
}{
201+
{
202+
description: "interrupt dev loop in Docker Compose deployer",
203+
dir: "testdata/docker-compose-deploy",
204+
minContainers: 1,
205+
projectPrefix: "skaffold-",
206+
},
207+
}
208+
209+
for _, test := range tests {
210+
t.Run(test.description, func(t *testing.T) {
211+
MarkIntegrationTest(t, CanRunWithoutGcp)
212+
p, err := skaffold.Dev().InDir(test.dir).StartWithProcess(t)
213+
if err != nil {
214+
t.Fatalf("error starting skaffold dev process")
215+
}
216+
217+
if err = waitForComposeContainersRunning(t, test.projectPrefix, test.minContainers); err != nil {
218+
t.Fatalf("failed waiting for containers: %v", err)
219+
}
220+
221+
p.Signal(syscall.SIGINT)
222+
223+
state, _ := p.Wait()
224+
225+
if state.ExitCode() != 0 {
226+
t.Fail()
227+
}
228+
})
229+
}
230+
}
231+
190232
func TestDevAPIBuildTrigger(t *testing.T) {
191233
MarkIntegrationTest(t, CanRunWithoutGcp)
192234

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.22-alpine AS builder
2+
WORKDIR /app
3+
COPY main.go .
4+
COPY go.mod .
5+
RUN go build -o app main.go
6+
7+
FROM alpine:latest
8+
WORKDIR /root/
9+
COPY --from=builder /app/app .
10+
EXPOSE 8080
11+
CMD ["./app"]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Example: Deploying with Docker Compose
2+
3+
This example demonstrates how to use Skaffold to build and deploy applications using Docker Compose.
4+
5+
## Prerequisites
6+
7+
- Docker and Docker Compose installed
8+
- Skaffold installed
9+
10+
## Project Structure
11+
12+
- `skaffold.yaml` - Skaffold configuration with Docker Compose deployment
13+
- `docker-compose.yml` - Docker Compose configuration
14+
- `Dockerfile` - Simple application Docker image
15+
- `main.go` - Simple Go web application
16+
17+
## How it Works
18+
19+
1. Skaffold builds the Docker image for the application
20+
2. Skaffold updates the `docker-compose.yml` with the built image tag
21+
3. Skaffold runs `docker compose up` to deploy the application
22+
4. When you stop Skaffold, it runs `docker compose down` to clean up
23+
24+
## Usage
25+
26+
### Run the application
27+
28+
```bash
29+
skaffold dev
30+
```
31+
32+
This will:
33+
- Build the application image
34+
- Deploy it using Docker Compose
35+
- Watch for changes and rebuild/redeploy automatically
36+
37+
### Deploy only
38+
39+
```bash
40+
skaffold run
41+
```
42+
43+
### Clean up
44+
45+
```bash
46+
skaffold delete
47+
```
48+
49+
Or simply press `Ctrl+C` when running `skaffold dev`.
50+
51+
## Configuration
52+
53+
The key part of the `skaffold.yaml` configuration is:
54+
55+
```yaml
56+
deploy:
57+
docker:
58+
useCompose: true
59+
images:
60+
- compose-app
61+
```
62+
63+
- `useCompose: true` - Enables Docker Compose deployment
64+
- `images` - List of images to build and deploy
65+
66+
## Environment Variables
67+
68+
You can customize the Docker Compose file location:
69+
70+
```bash
71+
export SKAFFOLD_COMPOSE_FILE=custom-compose.yml
72+
skaffold dev
73+
```
74+
75+
Default is `docker-compose.yml` in the current directory.
76+
77+
## Notes
78+
79+
- The Docker Compose project name will be `skaffold-{runID}`
80+
- Skaffold automatically replaces image names in the compose file with the built tags
81+
- Volumes and networks are automatically cleaned up on `skaffold delete`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: '3.8'
2+
services:
3+
app:
4+
image: compose-app
5+
ports:
6+
- "8080:8080"
7+
environment:
8+
- MESSAGE=Hello from Docker Compose!
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module compose-app
2+
3+
go 1.22
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
"os"
8+
)
9+
10+
func main() {
11+
message := os.Getenv("MESSAGE")
12+
if message == "" {
13+
message = "Hello, World!"
14+
}
15+
16+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
17+
fmt.Fprintf(w, "%s\n", message)
18+
})
19+
20+
port := ":8080"
21+
log.Printf("Server starting on port %s", port)
22+
log.Printf("Message: %s", message)
23+
24+
if err := http.ListenAndServe(port, nil); err != nil {
25+
log.Fatal(err)
26+
}
27+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: skaffold/v4beta13
2+
kind: Config
3+
metadata:
4+
name: docker-compose-deploy-example
5+
build:
6+
artifacts:
7+
- image: compose-app
8+
docker:
9+
dockerfile: Dockerfile
10+
deploy:
11+
docker:
12+
useCompose: true
13+
images:
14+
- compose-app
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.22-alpine AS builder
2+
WORKDIR /app
3+
COPY main.go .
4+
COPY go.mod .
5+
RUN go build -o app main.go
6+
7+
FROM alpine:latest
8+
WORKDIR /root/
9+
COPY --from=builder /app/app .
10+
EXPOSE 8080
11+
CMD ["./app"]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Example: Deploying with Docker Compose
2+
3+
This example demonstrates how to use Skaffold to build and deploy applications using Docker Compose.
4+
5+
## Prerequisites
6+
7+
- Docker and Docker Compose installed
8+
- Skaffold installed
9+
10+
## Project Structure
11+
12+
- `skaffold.yaml` - Skaffold configuration with Docker Compose deployment
13+
- `docker-compose.yml` - Docker Compose configuration
14+
- `Dockerfile` - Simple application Docker image
15+
- `main.go` - Simple Go web application
16+
17+
## How it Works
18+
19+
1. Skaffold builds the Docker image for the application
20+
2. Skaffold updates the `docker-compose.yml` with the built image tag
21+
3. Skaffold runs `docker compose up` to deploy the application
22+
4. When you stop Skaffold, it runs `docker compose down` to clean up
23+
24+
## Usage
25+
26+
### Run the application
27+
28+
```bash
29+
skaffold dev
30+
```
31+
32+
This will:
33+
- Build the application image
34+
- Deploy it using Docker Compose
35+
- Watch for changes and rebuild/redeploy automatically
36+
37+
### Deploy only
38+
39+
```bash
40+
skaffold run
41+
```
42+
43+
### Clean up
44+
45+
```bash
46+
skaffold delete
47+
```
48+
49+
Or simply press `Ctrl+C` when running `skaffold dev`.
50+
51+
## Configuration
52+
53+
The key part of the `skaffold.yaml` configuration is:
54+
55+
```yaml
56+
deploy:
57+
docker:
58+
useCompose: true
59+
images:
60+
- compose-app
61+
```
62+
63+
- `useCompose: true` - Enables Docker Compose deployment
64+
- `images` - List of images to build and deploy
65+
66+
## Environment Variables
67+
68+
You can customize the Docker Compose file location:
69+
70+
```bash
71+
export SKAFFOLD_COMPOSE_FILE=custom-compose.yml
72+
skaffold dev
73+
```
74+
75+
Default is `docker-compose.yml` in the current directory.
76+
77+
## Notes
78+
79+
- The Docker Compose project name will be `skaffold-{runID}`
80+
- Skaffold automatically replaces image names in the compose file with the built tags
81+
- Volumes and networks are automatically cleaned up on `skaffold delete`

0 commit comments

Comments
 (0)