From 28af8f49b81d9a3b26e8605a75b5f8d362c3e658 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 10 Apr 2026 00:25:29 -0600 Subject: [PATCH] test(mymigrate): use single-schema test fixture for hosted MariaDB Hosted MariaDB users (e.g. todo_test_*) typically have access to a single database/schema and cannot CREATE/DROP DATABASE. Drop the per-test database isolation pattern in favour of dropping _migrations directly on entry and exit, matching msmigrate's approach. Tests must not run concurrently against the same DSN. --- .../sqlmigrate/mymigrate/mymigrate_test.go | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/database/sqlmigrate/mymigrate/mymigrate_test.go b/database/sqlmigrate/mymigrate/mymigrate_test.go index f0a7b7e..72cb02f 100644 --- a/database/sqlmigrate/mymigrate/mymigrate_test.go +++ b/database/sqlmigrate/mymigrate/mymigrate_test.go @@ -11,8 +11,12 @@ import ( ) // connect opens a *sql.Conn from MYSQL_TEST_DSN, skips the test if the -// env var is unset, and isolates the test in its own database with -// automatic cleanup. +// env var is unset, and ensures _migrations does not exist on entry, +// with cleanup on exit. +// +// Note: tests run against the database in the DSN (no per-test database) +// because hosted MariaDB users typically have access to a single schema +// only. Tests must not be run concurrently against the same DSN. func connect(t *testing.T) *sql.Conn { t.Helper() dsn := os.Getenv("MYSQL_TEST_DSN") @@ -27,46 +31,22 @@ func connect(t *testing.T) *sql.Conn { } t.Cleanup(func() { _ = db.Close() }) - // Use a per-test database so concurrent tests don't collide and - // _migrations is guaranteed not to exist on entry. - dbName := "mymigrate_test_" + sanitize(t.Name()) - if _, err := db.ExecContext(ctx, "DROP DATABASE IF EXISTS "+dbName); err != nil { - t.Fatalf("drop database: %v", err) - } - if _, err := db.ExecContext(ctx, "CREATE DATABASE "+dbName); err != nil { - t.Fatalf("create database: %v", err) - } - t.Cleanup(func() { - _, _ = db.ExecContext(ctx, "DROP DATABASE IF EXISTS "+dbName) - }) - conn, err := db.Conn(ctx) if err != nil { t.Fatalf("conn: %v", err) } t.Cleanup(func() { _ = conn.Close() }) - if _, err := conn.ExecContext(ctx, "USE "+dbName); err != nil { - t.Fatalf("use database: %v", err) + if _, err := conn.ExecContext(ctx, "DROP TABLE IF EXISTS _migrations"); err != nil { + t.Fatalf("pre-cleanup _migrations: %v", err) } + t.Cleanup(func() { + _, _ = conn.ExecContext(ctx, "DROP TABLE IF EXISTS _migrations") + }) return conn } -// sanitize converts a test name to a valid MySQL identifier suffix. -func sanitize(s string) string { - out := make([]byte, 0, len(s)) - for _, c := range []byte(s) { - switch { - case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9': - out = append(out, c) - default: - out = append(out, '_') - } - } - return string(out) -} - // TestAppliedNoMigrationsTable verifies Applied returns (nil, nil) when // the _migrations table does not exist (MySQL error 1146). Defensive // regression test against drivers that may surface the error lazily.