Skip to content

Commit 25ea9aa

Browse files
committed
Enforce DOCKER_IMAGE validation in all test functions
- Update getSharedMySQLContainer to validate DOCKER_IMAGE is set - Fail early if image parameter doesn't match DOCKER_IMAGE - Fail early if sharedContainer is nil (TestMain should have created it) - Add validation to startMySQLContainer and startSharedMySQLContainer - Update all test files to use empty string instead of hardcoded 'mysql:8.0' - Tests now use DOCKER_IMAGE env var set by workflow, not hardcoded values
1 parent f8a0df9 commit 25ea9aa

10 files changed

+58
-36
lines changed

mysql/data_source_databases_testcontainers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
// Uses shared container set up in TestMain
1616
func TestAccDataSourceDatabases_WithTestcontainers(t *testing.T) {
1717
// Use shared container set up in TestMain
18-
_ = getSharedMySQLContainer(t, "mysql:8.0")
18+
_ = getSharedMySQLContainer(t, "")
1919

2020
// Run the same test logic as the original test
2121
resource.Test(t, resource.TestCase{

mysql/data_source_tables_testcontainers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
// Uses shared container set up in TestMain
1616
func TestAccDataSourceTables_WithTestcontainers(t *testing.T) {
1717
// Use shared container set up in TestMain
18-
_ = getSharedMySQLContainer(t, "mysql:8.0")
18+
_ = getSharedMySQLContainer(t, "")
1919

2020
// Run the same test logic as the original test
2121
resource.Test(t, resource.TestCase{

mysql/resource_database_testcontainers_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// Uses shared container set up in TestMain
1717
func TestAccDatabase_WithTestcontainers(t *testing.T) {
1818
// Use shared container set up in TestMain
19-
_ = getSharedMySQLContainer(t, "mysql:8.0")
19+
_ = getSharedMySQLContainer(t, "")
2020

2121
dbName := "terraform_acceptance_test"
2222
resource.Test(t, resource.TestCase{
@@ -45,7 +45,7 @@ func TestAccDatabase_WithTestcontainers(t *testing.T) {
4545
// Uses shared container set up in TestMain
4646
func TestAccDatabase_collationChange_WithTestcontainers(t *testing.T) {
4747
// Use shared container set up in TestMain
48-
_ = getSharedMySQLContainer(t, "mysql:8.0")
48+
_ = getSharedMySQLContainer(t, "")
4949

5050
dbName := "terraform_acceptance_test"
5151

mysql/resource_default_roles_testcontainers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
// Uses shared container set up in TestMain (MySQL 8.0 required for default roles)
1616
func TestAccDefaultRoles_basic_WithTestcontainers(t *testing.T) {
1717
// Use shared container set up in TestMain
18-
_ = getSharedMySQLContainer(t, "mysql:8.0")
18+
_ = getSharedMySQLContainer(t, "")
1919

2020
resource.Test(t, resource.TestCase{
2121
PreCheck: func() { testAccPreCheck(t) },

mysql/resource_global_variable_testcontainers_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
// Uses shared container set up in TestMain
1515
func TestAccGlobalVar_basic_WithTestcontainers(t *testing.T) {
1616
// Use shared container set up in TestMain
17-
_ = getSharedMySQLContainer(t, "mysql:8.0")
17+
_ = getSharedMySQLContainer(t, "")
1818

1919
varName := "max_connections"
2020
resourceName := "mysql_global_variable.test"
@@ -41,7 +41,7 @@ func TestAccGlobalVar_basic_WithTestcontainers(t *testing.T) {
4141
// Uses shared container set up in TestMain
4242
func TestAccGlobalVar_parseBoolean_WithTestcontainers(t *testing.T) {
4343
// Use shared container set up in TestMain
44-
_ = getSharedMySQLContainer(t, "mysql:8.0")
44+
_ = getSharedMySQLContainer(t, "")
4545

4646
varName := "autocommit"
4747
resourceName := "mysql_global_variable.test"

mysql/resource_grant_testcontainers_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// Uses shared container set up in TestMain
1717
func TestAccGrant_WithTestcontainers(t *testing.T) {
1818
// Use shared container set up in TestMain
19-
_ = getSharedMySQLContainer(t, "mysql:8.0")
19+
_ = getSharedMySQLContainer(t, "")
2020

2121
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
2222
userName := fmt.Sprintf("jdoe-%s", dbName)
@@ -58,7 +58,7 @@ func TestAccGrant_WithTestcontainers(t *testing.T) {
5858
// TestAccRevokePrivRefresh_WithTestcontainers tests privilege revocation and refresh
5959
func TestAccRevokePrivRefresh_WithTestcontainers(t *testing.T) {
6060
// Use shared container set up in TestMain
61-
_ = getSharedMySQLContainer(t, "mysql:8.0")
61+
_ = getSharedMySQLContainer(t, "")
6262

6363
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
6464

@@ -108,7 +108,7 @@ func TestAccRevokePrivRefresh_WithTestcontainers(t *testing.T) {
108108
// TestAccBroken_WithTestcontainers tests error handling for duplicate grants
109109
func TestAccBroken_WithTestcontainers(t *testing.T) {
110110
// Use shared container set up in TestMain
111-
_ = getSharedMySQLContainer(t, "mysql:8.0")
111+
_ = getSharedMySQLContainer(t, "")
112112

113113
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
114114
resource.Test(t, resource.TestCase{
@@ -144,7 +144,7 @@ func TestAccBroken_WithTestcontainers(t *testing.T) {
144144
// TestAccDifferentHosts_WithTestcontainers tests grants with different hosts
145145
func TestAccDifferentHosts_WithTestcontainers(t *testing.T) {
146146
// Use shared container set up in TestMain
147-
_ = getSharedMySQLContainer(t, "mysql:8.0")
147+
_ = getSharedMySQLContainer(t, "")
148148

149149
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
150150
resource.Test(t, resource.TestCase{
@@ -180,7 +180,7 @@ func TestAccDifferentHosts_WithTestcontainers(t *testing.T) {
180180
// TestAccGrantComplex_WithTestcontainers tests complex grant scenarios
181181
func TestAccGrantComplex_WithTestcontainers(t *testing.T) {
182182
// Use shared container set up in TestMain
183-
_ = getSharedMySQLContainer(t, "mysql:8.0")
183+
_ = getSharedMySQLContainer(t, "")
184184

185185
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
186186
resource.Test(t, resource.TestCase{
@@ -251,7 +251,7 @@ func TestAccGrantComplex_WithTestcontainers(t *testing.T) {
251251
// TestAccGrantComplexMySQL8_WithTestcontainers tests MySQL 8.0 specific grants
252252
func TestAccGrantComplexMySQL8_WithTestcontainers(t *testing.T) {
253253
// Use shared container set up in TestMain
254-
_ = getSharedMySQLContainer(t, "mysql:8.0")
254+
_ = getSharedMySQLContainer(t, "")
255255

256256
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
257257
resource.Test(t, resource.TestCase{
@@ -277,7 +277,7 @@ func TestAccGrantComplexMySQL8_WithTestcontainers(t *testing.T) {
277277
// TestAccGrant_role_WithTestcontainers tests role grants (requires MySQL 8.0+)
278278
func TestAccGrant_role_WithTestcontainers(t *testing.T) {
279279
// Use shared container set up in TestMain
280-
_ = getSharedMySQLContainer(t, "mysql:8.0")
280+
_ = getSharedMySQLContainer(t, "")
281281

282282
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
283283
roleName := fmt.Sprintf("TFRole-exp%d", rand.Intn(100))
@@ -312,7 +312,7 @@ func TestAccGrant_role_WithTestcontainers(t *testing.T) {
312312
// TestAccGrant_roleToUser_WithTestcontainers tests granting roles to users (requires MySQL 8.0+)
313313
func TestAccGrant_roleToUser_WithTestcontainers(t *testing.T) {
314314
// Use shared container set up in TestMain
315-
_ = getSharedMySQLContainer(t, "mysql:8.0")
315+
_ = getSharedMySQLContainer(t, "")
316316

317317
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
318318
roleName := fmt.Sprintf("TFRole-%d", rand.Intn(100))
@@ -336,7 +336,7 @@ func TestAccGrant_roleToUser_WithTestcontainers(t *testing.T) {
336336
// TestAccGrant_complexRoleGrants_WithTestcontainers tests complex role grant scenarios (requires MySQL 8.0+)
337337
func TestAccGrant_complexRoleGrants_WithTestcontainers(t *testing.T) {
338338
// Use shared container set up in TestMain
339-
_ = getSharedMySQLContainer(t, "mysql:8.0")
339+
_ = getSharedMySQLContainer(t, "")
340340

341341
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
342342
resource.Test(t, resource.TestCase{
@@ -354,7 +354,7 @@ func TestAccGrant_complexRoleGrants_WithTestcontainers(t *testing.T) {
354354
// TestAccGrantOnProcedure_WithTestcontainers tests procedure grants
355355
func TestAccGrantOnProcedure_WithTestcontainers(t *testing.T) {
356356
// Use shared container set up in TestMain
357-
_ = getSharedMySQLContainer(t, "mysql:8.0")
357+
_ = getSharedMySQLContainer(t, "")
358358

359359
procedureName := "test_procedure"
360360
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
@@ -395,7 +395,7 @@ func TestAccGrantOnProcedure_WithTestcontainers(t *testing.T) {
395395
// TestAllowDuplicateUsersDifferentTables_WithTestcontainers tests allowing duplicate grants on different tables
396396
func TestAllowDuplicateUsersDifferentTables_WithTestcontainers(t *testing.T) {
397397
// Use shared container set up in TestMain
398-
_ = getSharedMySQLContainer(t, "mysql:8.0")
398+
_ = getSharedMySQLContainer(t, "")
399399

400400
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
401401

@@ -464,7 +464,7 @@ func TestAllowDuplicateUsersDifferentTables_WithTestcontainers(t *testing.T) {
464464
// TestDisallowDuplicateUsersSameTable_WithTestcontainers tests disallowing duplicate grants on same table
465465
func TestDisallowDuplicateUsersSameTable_WithTestcontainers(t *testing.T) {
466466
// Use shared container set up in TestMain
467-
_ = getSharedMySQLContainer(t, "mysql:8.0")
467+
_ = getSharedMySQLContainer(t, "")
468468

469469
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
470470

mysql/resource_role_testcontainers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
// Uses shared container set up in TestMain (MySQL 8.0 required for roles)
1515
func TestAccRole_basic_WithTestcontainers(t *testing.T) {
1616
// Use shared container set up in TestMain
17-
_ = getSharedMySQLContainer(t, "mysql:8.0")
17+
_ = getSharedMySQLContainer(t, "")
1818

1919
roleName := "tf-test-role"
2020
resourceName := "mysql_role.test"

mysql/resource_user_password_testcontainers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
// Uses shared container set up in TestMain
1515
func TestAccUserPassword_basic_WithTestcontainers(t *testing.T) {
1616
// Use shared container set up in TestMain
17-
_ = getSharedMySQLContainer(t, "mysql:8.0")
17+
_ = getSharedMySQLContainer(t, "")
1818

1919
resource.Test(t, resource.TestCase{
2020
PreCheck: func() { testAccPreCheck(t) },

mysql/resource_user_testcontainers_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// Uses shared container set up in TestMain
1717
func TestAccUser_basic_WithTestcontainers(t *testing.T) {
1818
// Use shared container set up in TestMain
19-
_ = getSharedMySQLContainer(t, "mysql:8.0")
19+
_ = getSharedMySQLContainer(t, "")
2020

2121
resource.Test(t, resource.TestCase{
2222
PreCheck: func() { testAccPreCheck(t) },
@@ -63,7 +63,7 @@ func TestAccUser_basic_WithTestcontainers(t *testing.T) {
6363
// Note: mysql_no_login plugin may not be available in all MySQL distributions
6464
func TestAccUser_auth_WithTestcontainers(t *testing.T) {
6565
// Use shared container set up in TestMain
66-
_ = getSharedMySQLContainer(t, "mysql:8.0")
66+
_ = getSharedMySQLContainer(t, "")
6767

6868
resource.Test(t, resource.TestCase{
6969
PreCheck: func() {
@@ -122,7 +122,7 @@ func TestAccUser_auth_WithTestcontainers(t *testing.T) {
122122
// Uses shared container set up in TestMain
123123
func TestAccUser_authConnect_WithTestcontainers(t *testing.T) {
124124
// Use shared container set up in TestMain
125-
_ = getSharedMySQLContainer(t, "mysql:8.0")
125+
_ = getSharedMySQLContainer(t, "")
126126

127127
resource.Test(t, resource.TestCase{
128128
PreCheck: func() { testAccPreCheck(t) },
@@ -164,7 +164,7 @@ func TestAccUser_authConnect_WithTestcontainers(t *testing.T) {
164164
// Uses shared container set up in TestMain
165165
func TestAccUser_authConnectRetainOldPassword_WithTestcontainers(t *testing.T) {
166166
// Use shared container set up in TestMain
167-
_ = getSharedMySQLContainer(t, "mysql:8.0")
167+
_ = getSharedMySQLContainer(t, "")
168168

169169
resource.Test(t, resource.TestCase{
170170
PreCheck: func() { testAccPreCheck(t) },
@@ -199,7 +199,7 @@ func TestAccUser_authConnectRetainOldPassword_WithTestcontainers(t *testing.T) {
199199
// Uses shared container set up in TestMain
200200
func TestAccUser_deprecated_WithTestcontainers(t *testing.T) {
201201
// Use shared container set up in TestMain
202-
_ = getSharedMySQLContainer(t, "mysql:8.0")
202+
_ = getSharedMySQLContainer(t, "")
203203

204204
resource.Test(t, resource.TestCase{
205205
PreCheck: func() { testAccPreCheck(t) },

mysql/testcontainers_helper.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ type MySQLTestContainer struct {
6363

6464
// startMySQLContainer starts a MySQL/Percona/MariaDB container for testing
6565
// Supports MySQL, Percona, and MariaDB images
66+
// image must not be empty - function will panic if empty
6667
func startMySQLContainer(ctx context.Context, t *testing.T, image string) *MySQLTestContainer {
68+
if image == "" {
69+
t.Fatalf("ERROR: startMySQLContainer called with empty image. DOCKER_IMAGE must be set.")
70+
}
6771
// Determine timeout based on image/version
6872
timeout := 120 * time.Second
6973
if contains(image, "5.6") || contains(image, "5.7") || contains(image, "6.1") || contains(image, "6.5") {
@@ -155,24 +159,42 @@ func contains(s, substr string) bool {
155159
return strings.Contains(s, substr)
156160
}
157161

158-
// getSharedMySQLContainer returns a shared MySQL container for all tests
159-
// The container is created once and reused across all tests in the package
162+
// getSharedMySQLContainer returns the shared MySQL container set up by TestMain
163+
// The image parameter is ignored - TestMain uses DOCKER_IMAGE env var
164+
// This function validates that DOCKER_IMAGE is set and fails early if not
160165
func getSharedMySQLContainer(t *testing.T, image string) *MySQLTestContainer {
161-
sharedContainerOnce.Do(func() {
162-
ctx := context.Background()
163-
sharedContainer = startMySQLContainer(ctx, t, image)
166+
// Validate that DOCKER_IMAGE is set (required by TestMain)
167+
dockerImage := os.Getenv("DOCKER_IMAGE")
168+
if dockerImage == "" {
169+
t.Fatalf("ERROR: DOCKER_IMAGE environment variable is not set. This is required for MySQL/Percona/MariaDB tests.\n" +
170+
"Please set DOCKER_IMAGE to the appropriate Docker image (e.g., mysql:5.6, percona:8.0, mariadb:10.10)\n" +
171+
"The 'image' parameter to getSharedMySQLContainer is ignored - use DOCKER_IMAGE env var instead.")
172+
}
173+
174+
// Validate that the provided image matches DOCKER_IMAGE (if provided)
175+
if image != "" && image != dockerImage {
176+
t.Fatalf("ERROR: getSharedMySQLContainer called with image '%s' but DOCKER_IMAGE is set to '%s'.\n"+
177+
"Remove the hardcoded image parameter - TestMain uses DOCKER_IMAGE env var to create the shared container.",
178+
image, dockerImage)
179+
}
180+
181+
// TestMain should have already created sharedContainer
182+
// If it's nil, something went wrong in TestMain
183+
if sharedContainer == nil {
184+
t.Fatalf("ERROR: sharedContainer is nil. TestMain should have created it using DOCKER_IMAGE='%s'.\n"+
185+
"This indicates a problem with TestMain initialization.", dockerImage)
186+
}
164187

165-
// Set up environment variables for the shared container
166-
os.Setenv("MYSQL_ENDPOINT", sharedContainer.Endpoint)
167-
os.Setenv("MYSQL_USERNAME", sharedContainer.Username)
168-
os.Setenv("MYSQL_PASSWORD", sharedContainer.Password)
169-
})
170188
return sharedContainer
171189
}
172190

173191
// startSharedMySQLContainer starts a shared MySQL container without requiring a testing.T
174192
// Used by TestMain for initial setup
193+
// image must not be empty - function will return error if empty
175194
func startSharedMySQLContainer(image string) (*MySQLTestContainer, error) {
195+
if image == "" {
196+
return nil, fmt.Errorf("ERROR: startSharedMySQLContainer called with empty image. DOCKER_IMAGE must be set")
197+
}
176198
ctx := context.Background()
177199

178200
// Determine timeout based on image/version

0 commit comments

Comments
 (0)