Skip to content

Commit daffaca

Browse files
committed
Implement Testcontainers proof of concept
Built working POC for replacing Makefile + Docker with Testcontainers: Implementation: - testcontainers_helper.go: Helper functions for starting MySQL containers using GenericContainer (compatible with Go 1.21) - data_source_databases_testcontainers_test.go: Example test showing Testcontainers usage - Uses build tag 'testcontainers' so old tests still work Features: - Automatic container lifecycle management - Works with Docker and Podman (auto-detection) - Sets environment variables automatically - Cleanup on test completion - Compatible with existing test infrastructure Usage: go test -tags=testcontainers -v ./mysql/... -run TestAccDataSourceDatabases_WithTestcontainers Dependencies: - testcontainers-go v0.30.0 (compatible with Go 1.21) - Uses GenericContainer instead of MySQL module for compatibility This is a proof of concept - ready for testing and evaluation.
1 parent 3ed3924 commit daffaca

File tree

5 files changed

+423
-0
lines changed

5 files changed

+423
-0
lines changed

TESTCONTAINERS_POC.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Testcontainers Proof of Concept
2+
3+
This directory contains a proof of concept implementation using Testcontainers instead of the Makefile + Docker approach.
4+
5+
## What's Implemented
6+
7+
1. **`mysql/testcontainers_helper.go`**: Helper functions for starting MySQL containers
8+
2. **`mysql/data_source_databases_testcontainers_test.go`**: Example test using Testcontainers
9+
10+
## How to Use
11+
12+
### Prerequisites
13+
14+
- Docker or Podman installed
15+
- Go 1.21+ (project requirement)
16+
17+
### Running Tests
18+
19+
```bash
20+
# Run the Testcontainers-based test
21+
go test -tags=testcontainers -v ./mysql/... -run TestAccDataSourceDatabases_WithTestcontainers
22+
23+
# Run all tests (both old and new)
24+
go test -tags=testcontainers -v ./mysql/...
25+
```
26+
27+
### With Podman
28+
29+
Testcontainers automatically detects Podman. To use Podman explicitly:
30+
31+
```bash
32+
# Set Podman socket (if needed)
33+
export CONTAINER_HOST=unix://$HOME/.local/share/containers/podman/machine/podman-machine-default/podman.sock
34+
35+
# Run tests
36+
go test -tags=testcontainers -v ./mysql/... -run TestAccDataSourceDatabases_WithTestcontainers
37+
```
38+
39+
## How It Works
40+
41+
1. **Build Tag**: Code is gated behind `// +build testcontainers` tag
42+
- Old tests continue to work without Testcontainers
43+
- New tests only run when `-tags=testcontainers` is used
44+
45+
2. **Container Lifecycle**:
46+
- Container starts automatically when test begins
47+
- Environment variables are set for the test
48+
- Container terminates automatically when test completes
49+
50+
3. **Compatibility**:
51+
- Works with Docker (default)
52+
- Works with Podman (automatic detection)
53+
- Uses GenericContainer for Go 1.21 compatibility
54+
55+
## Example Test
56+
57+
```go
58+
func TestAccDataSourceDatabases_WithTestcontainers(t *testing.T) {
59+
ctx := context.Background()
60+
61+
// Start MySQL container
62+
container := startMySQLContainer(ctx, t, "mysql:8.0")
63+
defer container.SetupTestEnv(t)()
64+
65+
// Run tests (same as before)
66+
resource.Test(t, resource.TestCase{
67+
PreCheck: func() { testAccPreCheck(t) },
68+
ProviderFactories: testAccProviderFactories,
69+
Steps: []resource.TestStep{
70+
// ... test steps
71+
},
72+
})
73+
}
74+
```
75+
76+
## Benefits Over Makefile Approach
77+
78+
1. **No Shell Scripts**: Pure Go code
79+
2. **Automatic Cleanup**: Containers terminate automatically
80+
3. **Better Error Messages**: Container logs captured on failure
81+
4. **Parallel Execution**: Go's testing framework handles parallelism
82+
5. **Podman Support**: Works without configuration changes
83+
84+
## Next Steps
85+
86+
1. **Test Locally**: Verify it works with your Docker/Podman setup
87+
2. **Measure Performance**: Compare startup time vs. Makefile approach
88+
3. **Convert More Tests**: Gradually migrate other test files
89+
4. **CI/CD Integration**: Update GitHub Actions to use Testcontainers
90+
91+
## Troubleshooting
92+
93+
### Container Won't Start
94+
95+
- Check Docker/Podman is running: `docker ps` or `podman ps`
96+
- Check image exists: `docker images mysql:8.0`
97+
- Increase timeout in `testcontainers_helper.go` if needed
98+
99+
### Port Conflicts
100+
101+
- Testcontainers automatically assigns random ports
102+
- No manual port calculation needed (unlike Makefile approach)
103+
104+
### Podman Issues
105+
106+
- Ensure Podman socket is accessible
107+
- Check `CONTAINER_HOST` environment variable if needed
108+
- Testcontainers should auto-detect Podman

go.mod

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ require (
1010
github.com/hashicorp/go-version v1.7.0
1111
github.com/hashicorp/terraform-plugin-log v0.9.0
1212
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0
13+
github.com/testcontainers/testcontainers-go v0.30.0
14+
github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0
1315
github.com/tidwall/gjson v1.17.1
1416
golang.org/x/net v0.26.0
1517
golang.org/x/oauth2 v0.21.0
@@ -20,17 +22,31 @@ require (
2022
cloud.google.com/go/auth v0.5.1 // indirect
2123
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
2224
cloud.google.com/go/compute/metadata v0.3.0 // indirect
25+
dario.cat/mergo v1.0.0 // indirect
2326
filippo.io/edwards25519 v1.1.0 // indirect
2427
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
28+
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
2529
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
30+
github.com/Microsoft/go-winio v0.6.1 // indirect
31+
github.com/Microsoft/hcsshim v0.11.4 // indirect
2632
github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton // indirect
2733
github.com/agext/levenshtein v1.2.3 // indirect
2834
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
35+
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
2936
github.com/cloudflare/circl v1.3.8 // indirect
37+
github.com/containerd/containerd v1.7.12 // indirect
38+
github.com/containerd/log v0.1.0 // indirect
39+
github.com/cpuguy83/dockercfg v0.3.1 // indirect
40+
github.com/distribution/reference v0.5.0 // indirect
41+
github.com/docker/docker v25.0.5+incompatible // indirect
42+
github.com/docker/go-connections v0.5.0 // indirect
43+
github.com/docker/go-units v0.5.0 // indirect
3044
github.com/fatih/color v1.17.0 // indirect
3145
github.com/felixge/httpsnoop v1.0.4 // indirect
3246
github.com/go-logr/logr v1.4.2 // indirect
3347
github.com/go-logr/stdr v1.2.2 // indirect
48+
github.com/go-ole/go-ole v1.2.6 // indirect
49+
github.com/gogo/protobuf v1.3.2 // indirect
3450
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
3551
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3652
github.com/golang/protobuf v1.5.4 // indirect
@@ -56,28 +72,47 @@ require (
5672
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
5773
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
5874
github.com/hashicorp/yamux v0.1.1 // indirect
75+
github.com/klauspost/compress v1.16.0 // indirect
5976
github.com/kylelemons/godebug v1.1.0 // indirect
77+
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
78+
github.com/magiconair/properties v1.8.7 // indirect
6079
github.com/mattn/go-colorable v0.1.13 // indirect
6180
github.com/mattn/go-isatty v0.0.20 // indirect
6281
github.com/mitchellh/copystructure v1.2.0 // indirect
6382
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
6483
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
6584
github.com/mitchellh/mapstructure v1.5.0 // indirect
6685
github.com/mitchellh/reflectwalk v1.0.2 // indirect
86+
github.com/moby/patternmatcher v0.6.0 // indirect
87+
github.com/moby/sys/sequential v0.5.0 // indirect
88+
github.com/moby/sys/user v0.1.0 // indirect
89+
github.com/moby/term v0.5.0 // indirect
90+
github.com/morikuni/aec v1.0.0 // indirect
6791
github.com/oklog/run v1.1.0 // indirect
92+
github.com/opencontainers/go-digest v1.0.0 // indirect
93+
github.com/opencontainers/image-spec v1.1.0 // indirect
6894
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
95+
github.com/pkg/errors v0.9.1 // indirect
96+
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
97+
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
98+
github.com/shoenig/go-m1cpu v0.1.6 // indirect
99+
github.com/sirupsen/logrus v1.9.3 // indirect
69100
github.com/tidwall/match v1.1.1 // indirect
70101
github.com/tidwall/pretty v1.2.1 // indirect
102+
github.com/tklauser/go-sysconf v0.3.12 // indirect
103+
github.com/tklauser/numcpus v0.6.1 // indirect
71104
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
72105
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
73106
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
107+
github.com/yusufpapurcu/wmi v1.2.3 // indirect
74108
github.com/zclconf/go-cty v1.14.4 // indirect
75109
go.opencensus.io v0.24.0 // indirect
76110
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect
77111
go.opentelemetry.io/otel v1.27.0 // indirect
78112
go.opentelemetry.io/otel/metric v1.27.0 // indirect
79113
go.opentelemetry.io/otel/trace v1.27.0 // indirect
80114
golang.org/x/crypto v0.24.0 // indirect
115+
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
81116
golang.org/x/mod v0.18.0 // indirect
82117
golang.org/x/sync v0.7.0 // indirect
83118
golang.org/x/sys v0.21.0 // indirect

0 commit comments

Comments
 (0)