Skip to content

Commit d1f5aab

Browse files
committed
Add tests for *WithDB constructors
Tests cover: - Using provided connection (ownsConnection=false) - Close() not closing user-provided connections - Migrations disabled by default - Migrations can be enabled - MySQL: migration fails without MigrationDSN
1 parent 73c18c5 commit d1f5aab

3 files changed

Lines changed: 307 additions & 0 deletions

File tree

backend/mysql/mysql_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,126 @@ func Test_MysqlBackend_WorkerName(t *testing.T) {
216216
}
217217
})
218218
}
219+
220+
func Test_MysqlBackendWithDB(t *testing.T) {
221+
if testing.Short() {
222+
t.Skip()
223+
}
224+
225+
t.Run("UsesProvidedConnection", func(t *testing.T) {
226+
// Create database for test
227+
adminDB, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/?parseTime=true&interpolateParams=true", testUser, testPassword))
228+
if err != nil {
229+
t.Fatal(err)
230+
}
231+
232+
dbName := "test_withdb_" + strings.ReplaceAll(uuid.NewString(), "-", "")
233+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
234+
t.Fatal(err)
235+
}
236+
defer func() {
237+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName)
238+
adminDB.Close()
239+
}()
240+
241+
// Create our own connection to the test database
242+
dsn := fmt.Sprintf("%s:%s@tcp(localhost:3306)/%s?parseTime=true&interpolateParams=true", testUser, testPassword, dbName)
243+
db, err := sql.Open("mysql", dsn)
244+
if err != nil {
245+
t.Fatal(err)
246+
}
247+
defer db.Close()
248+
249+
// Create backend with existing connection and migration DSN
250+
migrationDSN := dsn + "&multiStatements=true"
251+
backend := NewMysqlBackendWithDB(db,
252+
WithApplyMigrations(true),
253+
WithMigrationDSN(migrationDSN),
254+
)
255+
256+
// Verify the backend uses our connection
257+
if backend.db != db {
258+
t.Error("Backend should use provided db connection")
259+
}
260+
if backend.ownsConnection {
261+
t.Error("Backend should not own the connection")
262+
}
263+
264+
// Close backend - should NOT close our connection
265+
if err := backend.Close(); err != nil {
266+
t.Fatal(err)
267+
}
268+
269+
// Verify our connection is still usable
270+
if err := db.Ping(); err != nil {
271+
t.Errorf("Connection should still be open after backend.Close(): %v", err)
272+
}
273+
})
274+
275+
t.Run("MigrationsDisabledByDefault", func(t *testing.T) {
276+
// Create database for test
277+
adminDB, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/?parseTime=true&interpolateParams=true", testUser, testPassword))
278+
if err != nil {
279+
t.Fatal(err)
280+
}
281+
282+
dbName := "test_withdb2_" + strings.ReplaceAll(uuid.NewString(), "-", "")
283+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
284+
t.Fatal(err)
285+
}
286+
defer func() {
287+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName)
288+
adminDB.Close()
289+
}()
290+
291+
dsn := fmt.Sprintf("%s:%s@tcp(localhost:3306)/%s?parseTime=true&interpolateParams=true", testUser, testPassword, dbName)
292+
db, err := sql.Open("mysql", dsn)
293+
if err != nil {
294+
t.Fatal(err)
295+
}
296+
defer db.Close()
297+
298+
// Create backend without enabling migrations
299+
backend := NewMysqlBackendWithDB(db)
300+
defer backend.Close()
301+
302+
// Tables should not exist since migrations weren't applied
303+
_, err = db.Exec("SELECT 1 FROM instances LIMIT 1")
304+
if err == nil {
305+
t.Error("Expected error because table should not exist")
306+
}
307+
})
308+
309+
t.Run("MigrationFailsWithoutDSN", func(t *testing.T) {
310+
// Create database for test
311+
adminDB, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/?parseTime=true&interpolateParams=true", testUser, testPassword))
312+
if err != nil {
313+
t.Fatal(err)
314+
}
315+
316+
dbName := "test_withdb3_" + strings.ReplaceAll(uuid.NewString(), "-", "")
317+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
318+
t.Fatal(err)
319+
}
320+
defer func() {
321+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName)
322+
adminDB.Close()
323+
}()
324+
325+
dsn := fmt.Sprintf("%s:%s@tcp(localhost:3306)/%s?parseTime=true&interpolateParams=true", testUser, testPassword, dbName)
326+
db, err := sql.Open("mysql", dsn)
327+
if err != nil {
328+
t.Fatal(err)
329+
}
330+
defer db.Close()
331+
332+
// Create backend without migration DSN - should panic when trying to migrate
333+
defer func() {
334+
if r := recover(); r == nil {
335+
t.Error("Expected panic when ApplyMigrations=true without MigrationDSN")
336+
}
337+
}()
338+
339+
NewMysqlBackendWithDB(db, WithApplyMigrations(true))
340+
})
341+
}

backend/postgres/postgres_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,120 @@ func Test_PostgresBackend_WorkerName(t *testing.T) {
210210
}
211211
})
212212
}
213+
214+
func Test_PostgresBackendWithDB(t *testing.T) {
215+
if testing.Short() {
216+
t.Skip()
217+
}
218+
219+
t.Run("UsesProvidedConnection", func(t *testing.T) {
220+
// Create database for test
221+
adminDB, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=postgres sslmode=disable", testUser, testPassword))
222+
if err != nil {
223+
t.Fatal(err)
224+
}
225+
226+
dbName := "test_withdb_" + strings.ReplaceAll(uuid.NewString(), "-", "")
227+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
228+
t.Fatal(err)
229+
}
230+
defer func() {
231+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName + " WITH (FORCE)")
232+
adminDB.Close()
233+
}()
234+
235+
// Create our own connection to the test database
236+
db, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=%s sslmode=disable", testUser, testPassword, dbName))
237+
if err != nil {
238+
t.Fatal(err)
239+
}
240+
defer db.Close()
241+
242+
// Create backend with existing connection and apply migrations
243+
backend := NewPostgresBackendWithDB(db, WithApplyMigrations(true))
244+
245+
// Verify the backend uses our connection
246+
if backend.db != db {
247+
t.Error("Backend should use provided db connection")
248+
}
249+
if backend.ownsConnection {
250+
t.Error("Backend should not own the connection")
251+
}
252+
253+
// Close backend - should NOT close our connection
254+
if err := backend.Close(); err != nil {
255+
t.Fatal(err)
256+
}
257+
258+
// Verify our connection is still usable
259+
if err := db.Ping(); err != nil {
260+
t.Errorf("Connection should still be open after backend.Close(): %v", err)
261+
}
262+
})
263+
264+
t.Run("MigrationsDisabledByDefault", func(t *testing.T) {
265+
// Create database for test
266+
adminDB, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=postgres sslmode=disable", testUser, testPassword))
267+
if err != nil {
268+
t.Fatal(err)
269+
}
270+
271+
dbName := "test_withdb2_" + strings.ReplaceAll(uuid.NewString(), "-", "")
272+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
273+
t.Fatal(err)
274+
}
275+
defer func() {
276+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName + " WITH (FORCE)")
277+
adminDB.Close()
278+
}()
279+
280+
db, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=%s sslmode=disable", testUser, testPassword, dbName))
281+
if err != nil {
282+
t.Fatal(err)
283+
}
284+
defer db.Close()
285+
286+
// Create backend without enabling migrations
287+
backend := NewPostgresBackendWithDB(db)
288+
defer backend.Close()
289+
290+
// Tables should not exist since migrations weren't applied
291+
_, err = db.Exec("SELECT 1 FROM instances LIMIT 1")
292+
if err == nil {
293+
t.Error("Expected error because table should not exist")
294+
}
295+
})
296+
297+
t.Run("MigrationsCanBeEnabled", func(t *testing.T) {
298+
// Create database for test
299+
adminDB, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=postgres sslmode=disable", testUser, testPassword))
300+
if err != nil {
301+
t.Fatal(err)
302+
}
303+
304+
dbName := "test_withdb3_" + strings.ReplaceAll(uuid.NewString(), "-", "")
305+
if _, err := adminDB.Exec("CREATE DATABASE " + dbName); err != nil {
306+
t.Fatal(err)
307+
}
308+
defer func() {
309+
adminDB.Exec("DROP DATABASE IF EXISTS " + dbName + " WITH (FORCE)")
310+
adminDB.Close()
311+
}()
312+
313+
db, err := sql.Open("pgx", fmt.Sprintf("host=localhost port=5432 user=%s password=%s dbname=%s sslmode=disable", testUser, testPassword, dbName))
314+
if err != nil {
315+
t.Fatal(err)
316+
}
317+
defer db.Close()
318+
319+
// Create backend with migrations enabled
320+
backend := NewPostgresBackendWithDB(db, WithApplyMigrations(true))
321+
defer backend.Close()
322+
323+
// Tables should exist
324+
_, err = db.Exec("SELECT 1 FROM instances LIMIT 1")
325+
if err != nil {
326+
t.Errorf("Table should exist after migrations: %v", err)
327+
}
328+
})
329+
}

backend/sqlite/sqlite_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sqlite
22

33
import (
4+
"database/sql"
45
"testing"
56

67
"github.com/cschleiden/go-workflows/backend"
@@ -73,3 +74,69 @@ func Test_SqliteBackend_WorkerName(t *testing.T) {
7374
require.Equal(t, customWorkerName, backend.workerName)
7475
})
7576
}
77+
78+
func Test_SqliteBackendWithDB(t *testing.T) {
79+
t.Run("UsesProvidedConnection", func(t *testing.T) {
80+
// Create our own database connection
81+
db, err := sql.Open("sqlite", "file:testdb?mode=memory&cache=shared")
82+
require.NoError(t, err)
83+
defer db.Close()
84+
85+
// Configure connection as recommended
86+
_, err = db.Exec("PRAGMA journal_mode=WAL;")
87+
require.NoError(t, err)
88+
_, err = db.Exec("PRAGMA busy_timeout = 5000;")
89+
require.NoError(t, err)
90+
db.SetMaxOpenConns(1)
91+
92+
// Create backend with existing connection and apply migrations
93+
backend := NewSqliteBackendWithDB(db, WithApplyMigrations(true))
94+
95+
// Verify the backend works
96+
require.NotNil(t, backend)
97+
require.Equal(t, db, backend.db)
98+
require.False(t, backend.ownsConnection)
99+
100+
// Close backend - should NOT close our connection
101+
err = backend.Close()
102+
require.NoError(t, err)
103+
104+
// Verify our connection is still usable
105+
err = db.Ping()
106+
require.NoError(t, err)
107+
})
108+
109+
t.Run("MigrationsDisabledByDefault", func(t *testing.T) {
110+
db, err := sql.Open("sqlite", "file:testdb2?mode=memory&cache=shared")
111+
require.NoError(t, err)
112+
defer db.Close()
113+
114+
db.SetMaxOpenConns(1)
115+
116+
// Create backend without enabling migrations
117+
backend := NewSqliteBackendWithDB(db)
118+
defer backend.Close()
119+
120+
// Tables should not exist since migrations weren't applied
121+
_, err = db.Exec("SELECT 1 FROM instances LIMIT 1")
122+
require.Error(t, err) // Table doesn't exist
123+
})
124+
125+
t.Run("MigrationsCanBeEnabled", func(t *testing.T) {
126+
db, err := sql.Open("sqlite", "file:testdb3?mode=memory&cache=shared")
127+
require.NoError(t, err)
128+
defer db.Close()
129+
130+
_, err = db.Exec("PRAGMA journal_mode=WAL;")
131+
require.NoError(t, err)
132+
db.SetMaxOpenConns(1)
133+
134+
// Create backend with migrations enabled
135+
backend := NewSqliteBackendWithDB(db, WithApplyMigrations(true))
136+
defer backend.Close()
137+
138+
// Tables should exist
139+
_, err = db.Exec("SELECT 1 FROM instances LIMIT 1")
140+
require.NoError(t, err)
141+
})
142+
}

0 commit comments

Comments
 (0)