40 lines
1.3 KiB
Go
40 lines
1.3 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"sync/atomic"
|
|
"testing"
|
|
)
|
|
|
|
var failedPingClosed atomic.Int32
|
|
var errPingUnavailable = errors.New("database unavailable")
|
|
|
|
type failedPingDriver struct{}
|
|
type failedPingConnection struct{}
|
|
|
|
func (failedPingDriver) Open(string) (driver.Conn, error) { return failedPingConnection{}, nil }
|
|
func (failedPingConnection) Prepare(string) (driver.Stmt, error) {
|
|
return nil, errors.New("not implemented")
|
|
}
|
|
func (failedPingConnection) Begin() (driver.Tx, error) { return nil, errors.New("not implemented") }
|
|
func (failedPingConnection) Close() error { failedPingClosed.Add(1); return nil }
|
|
func (failedPingConnection) Ping(context.Context) error { return errPingUnavailable }
|
|
|
|
func init() { sql.Register("goOmniFailPing", failedPingDriver{}) }
|
|
|
|
func TestOpenClosesPoolWhenStartupPingFails(t *testing.T) {
|
|
failedPingClosed.Store(0)
|
|
cfg := DefaultConfig()
|
|
cfg.Driver, cfg.DSN = "goOmniFailPing", "test"
|
|
pool, err := Open(context.Background(), cfg)
|
|
if pool != nil || !errors.Is(err, errPingUnavailable) {
|
|
t.Fatalf("unexpected startup result: db=%v err=%v", pool, err)
|
|
}
|
|
if closed := failedPingClosed.Load(); closed != 1 {
|
|
t.Fatalf("startup failure closed %d connections, want 1", closed)
|
|
}
|
|
}
|