Add DB implementation with fault injection

This commit is contained in:
Tim Van Baak 2025-01-31 09:32:23 -08:00
parent 9c42847ee2
commit b769d71f6e

View File

@ -1,11 +1,88 @@
package core
import (
"database/sql"
"errors"
"strings"
"testing"
_ "github.com/mattn/go-sqlite3"
)
type FailureDb struct {
db DB
queryError func(string, ...any) error
execError func(string, ...any) error
}
func (f *FailureDb) Query(query string, args ...any) (*sql.Rows, error) {
if f.queryError != nil {
if err := f.queryError(query, args...); err != nil {
return nil, err
}
}
return f.db.Query(query, args...)
}
func (f *FailureDb) QueryRow(query string, args ...any) *sql.Row {
return f.db.QueryRow(query, args...)
}
func (f *FailureDb) Exec(query string, args ...any) (sql.Result, error) {
if f.execError != nil {
if err := f.execError(query, args...); err != nil {
return nil, err
}
}
return f.db.Exec(query, args...)
}
func (f *FailureDb) Prepare(query string) (*sql.Stmt, error) {
return f.db.Prepare(query)
}
func (f *FailureDb) Transact(txFunc func(DB) error) error {
return f.db.Transact(func(tx DB) error {
ftx := FailureDb{
db: tx,
queryError: f.queryError,
execError: f.execError,
}
return txFunc(&ftx)
})
}
func TestFailureDb(t *testing.T) {
db := EphemeralDb(t)
fdb := FailureDb{
db: db,
queryError: func(q string, a ...any) error {
if strings.Contains(q, "2") {
return errors.New("oopsie")
}
return nil
},
}
if _, err := fdb.Query("select 1"); err != nil {
t.Fatal(err)
}
if _, err := fdb.Query("select 2"); err == nil {
t.Fatal("expected error")
}
if err := fdb.Transact(func(tx DB) error {
if _, err := tx.Query("select 1"); err != nil {
t.Fatal(err)
}
_, err := tx.Query("select 2")
return err
}); err == nil {
t.Fatal("expected error from inside transaction")
}
}
func TestDeleteSourceCascade(t *testing.T) {
db := EphemeralDb(t)