testdock

package module
v2.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2025 License: MIT Imports: 28 Imported by: 0

README

Go Reference Go Coverage CI Status

TestDock

TestDock is a Go library that simplifies database testing by providing an easy way to create and manage test databases in realistic scenarios, instead of using mocks. It supports running tests against both Docker containers and external databases, with built-in support for MongoDB and various SQL databases.

Features

  • Multiple Database Support

    • MongoDB: GetMongoDatabase function
    • PostgreSQL (with both pgx and pq drivers): GetPgxPool and GetPqConn functions
    • MySQL: GetMySQLConn function
    • Any other SQL database supported by database/sql https://go.dev/wiki/SQLDrivers: GetSQLConn function
  • Flexible Test Environment

    • Docker container support for isolated testing
    • External database support for CI/CD environments
    • Auto-mode that switches based on environment variables
  • Database Migration Support

    • Integration with goose
    • Integration with golang-migrate
    • User provided migration tool
    • Automatic migration application during test setup
  • Robust Connection Handling

    • Automatic retry mechanisms
    • Automatic selection of a free host port when deploying containers
    • Graceful cleanup after tests

Installation

go get github.com/n-r-w/testdock/v2@latest

Core Functions

  • GetPgxPool: PostgreSQL connection pool (pgx driver)
  • GetPqConn: PostgreSQL connection (libpq driver)
  • GetMySQLConn: MySQL connection
  • GetSQLConn: Generic SQL database connection
  • GetMongoDatabase: MongoDB database

Usage

Connection string format

The connection string format is driver-specific. For example:

  • For PostgreSQL: postgres://user:password@localhost:5432/database?sslmode=disable
  • For MySQL: root:password@tcp(localhost:3306)/database?parseTime=true
  • For MongoDB: mongodb://user:password@localhost:27017/database
Connection string purpose

Depending on the chosen mode (WithMode), the connection string is used differently:

RunModeExternal
  • The connection string is used directly to connect to the database
RunModeDocker
  • The connection string is used to generate the Docker container configuration
  • The port value is used 1) as the port inside the container, 2) as the external access port to the database
  • If this port is already taken on the host, then TestDock tries to find a free port by incrementing its value by 1 until a free port is found
RunModeAuto (used by default)
  • If the environment variable TESTDOCK_DSN_<DRIVER_NAME> is not set, then TestDock chooses the RunModeDocker mode and uses the input string as the container configuration
  • If the environment variable TESTDOCK_DSN_<DRIVER_NAME> is set, then TestDock chooses the RunModeExternal mode and uses the string from the environment variable to connect to the external database. In this case, the dsn parameter of the constructor function is ignored. Thus, in this mode, the dsn parameter is used as a fallback if the environment variable is not set.
PostgreSQL Example (using pgx)
import (
    "testing"
    "github.com/n-r-w/testdock/v2"
)

func TestDatabase(t *testing.T) {          
    // Get a connection pool to a test database.

    /* 
    If the environment variable TESTDOCK_DSN_PGX is set, then the input 
    connection string is ignored and the value from the environment variable
    is used. If the environment variable TESTDOCK_DSN_PGX is not set, 
    then the input connection string is used to generate the Docker container 
    configuration.
    */

    pool, _ := testdock.GetPgxPool(t, 
        testdock.DefaultPostgresDSN,
        testdock.WithMigrations("migrations", testdock.GooseMigrateFactoryPGX),        
    )
    
    // Use the pool for your tests
    // The database will be automatically cleaned up after the test
}
MongoDB Example
import (
    "testing"
    "github.com/n-r-w/testdock/v2"
)

func TestMongoDB(t *testing.T) {        
    // Get a connection to a test database
    db, _ := testdock.GetMongoDatabase(t, testdock.DefaultMongoDSN,
        testdock.WithMode(testdock.RunModeDocker),
        testdock.WithMigrations("migrations", testdock.GolangMigrateFactory),
    )
    
    // Use the database for your tests
    // The database will be automatically cleaned up after the test
}

Configuration

Environment Variables, used by RunModeAuto
  • TESTDOCK_DSN_PGX, TESTDOCK_DSN_POSTGRES - PostgreSQL-specific connection strings
  • TESTDOCK_DSN_MYSQL - MySQL-specific connection string
  • TESTDOCK_DSN_MONGODB - MongoDB-specific connection string
  • TESTDOCK_DSN_<DRIVER_NAME> - Custom connection string for a specific driver
Retry and Connection Handling
  • WithRetryTimeout(duration): Configure connection retry timeout (default 3s). Must be less than totalRetryDuration
  • WithTotalRetryDuration(duration): Configure total retry duration (default 30s). Must be greater than retryTimeout
Docker Configuration
  • WithDockerSocketEndpoint(endpoint): Custom Docker daemon socket
  • WithDockerPort(port): Override container port mapping
  • WithUnsetProxyEnv(bool): Unset proxy environment variables
Database Options
  • WithConnectDatabase(name): Override connection database
  • WithPrepareCleanUp(func): Custom cleanup handlers. The default is empty, but GetPgxPool and GetPqConn functions use it to automatically apply cleanup handlers to disconnect all users from the database before cleaning up.
  • WithLogger(logger): Custom logging implementation
Default connection strings
  • DefaultPostgresDSN: Default PostgreSQL connection string
  • DefaultMySQLDSN: Default MySQL connection string
  • DefaultMongoDSN: Default MongoDB connection string

Migrations

TestDock supports two popular migration tools:

Goose Migrations (SQL databases only)

https://github.com/pressly/goose

 db, _ := GetPqConn(t,
    "postgres://postgres:secret@127.0.0.1:5432/postgres?sslmode=disable",
    testdock.WithMigrations("migrations/pg/goose", testdock.GooseMigrateFactoryPQ),
    testdock.WithDockerImage("17.2"),
 )
Golang-Migrate Migrations (SQL databases and MongoDB)

https://github.com/golang-migrate/migrate

db, _ := GetMongoDatabase(t,
    testdock.DefaultMongoDSN,
    WithDockerRepository("mongo"),
    WithDockerImage("6.0.20"),
    WithMigrations("migrations/mongodb", testdock.GolangMigrateFactory),
 )
Custom Migrations

You can also use a custom migration tool implementing the testdock.MigrateFactory interface.

Requirements

  • Go 1.23 or higher
  • Docker (when using RunModeDocker or RunModeAuto)

License

MIT License - see LICENSE for details

Documentation

Index

Constants

View Source
const (
	// DefaultRetryTimeout is the default retry timeout.
	DefaultRetryTimeout = time.Second * 3
	// DefaultTotalRetryDuration is the default total retry duration.
	DefaultTotalRetryDuration = time.Second * 30
)
View Source
const (
	// DefaultMongoDSN - default mongodb connection string.
	DefaultMongoDSN = "mongodb://testuser:secret@127.0.0.1:27017/testdb?authSource=admin"
	// DefaultMySQLDSN - default mysql connection string.
	DefaultMySQLDSN = "root:secret@tcp(127.0.0.1:3306)/test_db"
	// DefaultPostgresDSN - default postgres connection string.
	DefaultPostgresDSN = "postgres://postgres:secret@127.0.0.1:5432/postgres?sslmode=disable"
)

Variables

View Source
var (
	// GooseMigrateFactoryPGX is a migrator for https://github.com/pressly/goose with pgx driver.
	GooseMigrateFactoryPGX = GooseMigrateFactory(goose.DialectPostgres, "pgx")
	// GooseMigrateFactoryPQ is a migrator for https://github.com/pressly/goose with pq driver.
	GooseMigrateFactoryPQ = GooseMigrateFactory(goose.DialectPostgres, "postgres")
	// GooseMigrateFactoryMySQL is a migrator for https://github.com/pressly/goose with mysql driver.
	GooseMigrateFactoryMySQL = GooseMigrateFactory(goose.DialectMySQL, "mysql")
)

Functions

This section is empty.

Types

type GolangMigrateLogger

type GolangMigrateLogger struct {
	// contains filtered or unexported fields
}

GolangMigrateLogger is a logger for golang-migrate.

func NewGolangMigrateLogger

func NewGolangMigrateLogger(l ctxlog.ILogger) *GolangMigrateLogger

NewGolangMigrateLogger creates a new golang-migrate logger.

func (*GolangMigrateLogger) Printf

func (g *GolangMigrateLogger) Printf(format string, v ...any)

Printf logs a message.

func (*GolangMigrateLogger) Verbose

func (g *GolangMigrateLogger) Verbose() bool

Verbose returns true.

type GooseLogger

type GooseLogger struct {
	// contains filtered or unexported fields
}

GooseLogger is a logger for goose.

func NewGooseLogger

func NewGooseLogger(t testing.TB, l ctxlog.ILogger) *GooseLogger

NewGooseLogger creates a new goose logger.

func (GooseLogger) Fatalf

func (l GooseLogger) Fatalf(format string, v ...any)

Fatalf logs a fatal error.

func (GooseLogger) Printf

func (l GooseLogger) Printf(format string, v ...any)

Printf logs a message.

type Informer added in v2.1.0

type Informer interface {
	// DSN returns the real database connection string.
	DSN() string
	// Host returns the host of the database server.
	Host() string
	// Port returns the port of the database server.
	Port() int
	// DatabaseName returns the database name for testing.
	DatabaseName() string
}

Informer interface for database information.

func GetMongoDatabase

func GetMongoDatabase(tb testing.TB, dsn string, opt ...Option) (*mongo.Database, Informer)

GetMongoDatabase initializes a test MongoDB database, applies migrations, and returns a database connection.

func GetMySQLConn added in v2.0.2

func GetMySQLConn(tb testing.TB, dsn string, opt ...Option) (*sql.DB, Informer)

GetMySQLConn inits a test mysql database, applies migrations. Use user root for docker test database.

func GetPgxPool

func GetPgxPool(tb testing.TB, dsn string, opt ...Option) (*pgxpool.Pool, Informer)

GetPgxPool inits a test postgresql (pgx driver) database, applies migrations, and returns pgx connection pool to the database.

func GetPqConn

func GetPqConn(ctx context.Context, tb testing.TB, dsn string, opt ...Option) (*sql.DB, Informer)

GetPqConn inits a test postgresql (pq driver) database, applies migrations, and returns sql connection to the database.

func GetSQLConn

func GetSQLConn(tb testing.TB, driver, dsn string, opt ...Option) (*sql.DB, Informer)

GetSQLConn inits a test database, applies migrations, and returns sql connection to the database. driver: https://go.dev/wiki/SQLDrivers. Do not forget to import corresponding driver package.

type MigrateFactory

type MigrateFactory func(t testing.TB, dsn string, migrationsDir string, logger ctxlog.ILogger) (Migrator, error)

MigrateFactory creates a new migrator.

func GooseMigrateFactory

func GooseMigrateFactory(dialect goose.Dialect, driver string) MigrateFactory

GooseMigrateFactory creates a new migrator for https://github.com/pressly/goose.

type Migrator

type Migrator interface {
	Up(ctx context.Context) error
}

Migrator interface for applying migrations.

func GolangMigrateFactory

func GolangMigrateFactory(_ testing.TB, dsn, migrationsDir string, logger ctxlog.ILogger) (Migrator, error)

GolangMigrateFactory creates a new migrator for https://github.com/golang-migrate/migrate.

type Option

type Option func(*testDB)

Option option for creating a test database.

func WithConnectDatabase

func WithConnectDatabase(connectDatabase string) Option

WithConnectDatabase sets the name of the database to connect to. The default will be take from the DSN.

func WithDockerEnv

func WithDockerEnv(dockerEnv []string) Option

WithDockerEnv sets the environment variables for the docker container. The default is empty.

func WithDockerImage

func WithDockerImage(dockerImage string) Option

WithDockerImage sets the name of the docker image. The default is `latest`.

func WithDockerPort

func WithDockerPort(dockerPort int) Option

WithDockerPort sets the port for connecting to database in docker. The default is the port from the DSN.

func WithDockerRepository

func WithDockerRepository(dockerRepository string) Option

WithDockerRepository sets the name of docker hub repository. Required for RunModeDocker or RunModeAuto with empty environment variable TESTDOCK_DSN_[DRIVER].

func WithDockerSocketEndpoint

func WithDockerSocketEndpoint(dockerSocketEndpoint string) Option

WithDockerSocketEndpoint sets the docker socket endpoint for connecting to the docker daemon. The default is autodetect.

func WithLogger

func WithLogger(logger ctxlog.ILogger) Option

WithLogger sets the logger for the test database. The default is logger from testing.TB.

func WithMigrations

func WithMigrations(migrationsDir string, migrateFactory MigrateFactory) Option

WithMigrations sets the directory and factory for the migrations.

func WithMode

func WithMode(mode RunMode) Option

WithMode sets the mode for the test database. The default is RunModeAuto.

func WithPrepareCleanUp

func WithPrepareCleanUp(prepareCleanUp PrepareCleanUp) Option

WithPrepareCleanUp sets the function for prepare to delete temporary test database. The default is empty, but `GetPgxPool` and `GetPqConn` use it to automatically apply cleanup handlers to disconnect all users from the database before cleaning up.

func WithRetryTimeout

func WithRetryTimeout(retryTimeout time.Duration) Option

WithRetryTimeout sets the timeout for connecting to the database. The default is 3 second. Must be less than totalRetryDuration.

func WithTotalRetryDuration added in v2.0.3

func WithTotalRetryDuration(totalRetryDuration time.Duration) Option

WithTotalRetryDuration sets the total retry duration. The default is 30 seconds. Must be greater than retryTimeout.

func WithUnsetProxyEnv

func WithUnsetProxyEnv(unsetProxyEnv bool) Option

WithUnsetProxyEnv unsets the proxy environment variables. The default is false.

type PrepareCleanUp

type PrepareCleanUp func(db *sql.DB, databaseName string) error

PrepareCleanUp - function for prepare to delete temporary test database. For example, disconnect users.

type RunMode

type RunMode int

RunMode defines the run mode of the test database.

const (
	// RunModeUnknown - unknown run mode
	RunModeUnknown RunMode = 0
	// RunModeDocker - run the tests in docker
	RunModeDocker RunMode = 1
	// RunModeExternal - run the tests in external database
	RunModeExternal RunMode = 2
	// RunModeAuto - checks the environment variable TESTDOCK_DSN_[DRIVER]. If it is set,
	// then RunModeExternal, otherwise RunModeDocker.
	// If TESTDOCK_DSN_[DRIVER] is set and RunModeAuto, WithDSN option is ignored.
	// For example, for postgres pgx driver:
	//   TESTDOCK_DSN_PGX=postgres://postgres:secret@localhost:5432/postgres&sslmode=disable
	RunModeAuto RunMode = 3
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL