Change MaxConns default from 25 to 4 to match pgxpool defaults. This ensures consistent behavior between DATABASE_URI and config file modes, and removes the warning log when using URI mode. Defaults now reference: https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool#Config
215 lines
5.4 KiB
Go
215 lines
5.4 KiB
Go
package pgdb
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"go.ntppool.org/common/database"
|
|
)
|
|
|
|
func TestCreatePoolConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cfg *database.PostgresConfig
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "valid config",
|
|
cfg: &database.PostgresConfig{
|
|
Host: "localhost",
|
|
Port: 5432,
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
SSLMode: "require",
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "valid config with defaults",
|
|
cfg: &database.PostgresConfig{
|
|
Host: "localhost",
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
// Port and SSLMode will use defaults
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "missing host",
|
|
cfg: &database.PostgresConfig{
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "missing user",
|
|
cfg: &database.PostgresConfig{
|
|
Host: "localhost",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "missing database name",
|
|
cfg: &database.PostgresConfig{
|
|
Host: "localhost",
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid sslmode",
|
|
cfg: &database.PostgresConfig{
|
|
Host: "localhost",
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
SSLMode: "invalid",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
poolCfg, err := CreatePoolConfig(tt.cfg)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("CreatePoolConfig() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !tt.wantErr && poolCfg == nil {
|
|
t.Error("CreatePoolConfig() returned nil config without error")
|
|
}
|
|
if !tt.wantErr && poolCfg != nil {
|
|
// Verify config fields are set correctly
|
|
if poolCfg.ConnConfig.Host != tt.cfg.Host && tt.cfg.Host != "" {
|
|
t.Errorf("Expected Host=%s, got %s", tt.cfg.Host, poolCfg.ConnConfig.Host)
|
|
}
|
|
if poolCfg.ConnConfig.User != tt.cfg.User {
|
|
t.Errorf("Expected User=%s, got %s", tt.cfg.User, poolCfg.ConnConfig.User)
|
|
}
|
|
if poolCfg.ConnConfig.Password != tt.cfg.Pass {
|
|
t.Errorf("Expected Password to be set correctly")
|
|
}
|
|
if poolCfg.ConnConfig.Database != tt.cfg.Name {
|
|
t.Errorf("Expected Database=%s, got %s", tt.cfg.Name, poolCfg.ConnConfig.Database)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDefaultPoolOptions(t *testing.T) {
|
|
opts := DefaultPoolOptions()
|
|
|
|
// Verify expected defaults
|
|
if opts.MinConns != 0 {
|
|
t.Errorf("Expected MinConns=0, got %d", opts.MinConns)
|
|
}
|
|
if opts.MaxConns != 4 {
|
|
t.Errorf("Expected MaxConns=4 (pgxpool default), got %d", opts.MaxConns)
|
|
}
|
|
if opts.MaxConnLifetime != time.Hour {
|
|
t.Errorf("Expected MaxConnLifetime=1h, got %v", opts.MaxConnLifetime)
|
|
}
|
|
if opts.MaxConnIdleTime != 30*time.Minute {
|
|
t.Errorf("Expected MaxConnIdleTime=30m, got %v", opts.MaxConnIdleTime)
|
|
}
|
|
if opts.HealthCheckPeriod != time.Minute {
|
|
t.Errorf("Expected HealthCheckPeriod=1m, got %v", opts.HealthCheckPeriod)
|
|
}
|
|
if len(opts.ConfigFiles) == 0 {
|
|
t.Error("Expected ConfigFiles to be non-empty")
|
|
}
|
|
}
|
|
|
|
func TestCreatePoolConfigDefaults(t *testing.T) {
|
|
// Test that defaults are applied correctly
|
|
cfg := &database.PostgresConfig{
|
|
Host: "localhost",
|
|
User: "testuser",
|
|
Pass: "testpass",
|
|
Name: "testdb",
|
|
// Port and SSLMode not set
|
|
}
|
|
|
|
poolCfg, err := CreatePoolConfig(cfg)
|
|
if err != nil {
|
|
t.Fatalf("CreatePoolConfig() failed: %v", err)
|
|
}
|
|
|
|
// Verify defaults were applied
|
|
if poolCfg.ConnConfig.Port != 5432 {
|
|
t.Errorf("Expected default Port=5432, got %d", poolCfg.ConnConfig.Port)
|
|
}
|
|
}
|
|
|
|
func TestOpenPoolWithDatabaseURI(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skipping integration test")
|
|
}
|
|
|
|
// This test requires a running PostgreSQL instance
|
|
uri := os.Getenv("TEST_DATABASE_URI")
|
|
if uri == "" {
|
|
t.Skip("TEST_DATABASE_URI not set")
|
|
}
|
|
|
|
ctx := context.Background()
|
|
t.Setenv("DATABASE_URI", uri)
|
|
|
|
pool, err := OpenPool(ctx, DefaultPoolOptions())
|
|
if err != nil {
|
|
t.Fatalf("OpenPool failed: %v", err)
|
|
}
|
|
defer pool.Close()
|
|
|
|
// Verify connection works
|
|
var result int
|
|
err = pool.QueryRow(ctx, "SELECT 1").Scan(&result)
|
|
if err != nil {
|
|
t.Fatalf("query failed: %v", err)
|
|
}
|
|
if result != 1 {
|
|
t.Errorf("expected 1, got %d", result)
|
|
}
|
|
}
|
|
|
|
func TestDatabaseURIPrecedence(t *testing.T) {
|
|
// Test that DATABASE_URI takes precedence over config files
|
|
// We use localhost with a port that's unlikely to have postgres running
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
|
|
// Set DATABASE_URI to a parseable URI pointing to a non-listening port
|
|
t.Setenv("DATABASE_URI", "postgres://testuser:testpass@127.0.0.1:59999/testdb?connect_timeout=1")
|
|
|
|
// Set config files to a nonexistent path - if this were used, we'd get
|
|
// "config file not found" error instead of connection refused
|
|
opts := DefaultPoolOptions()
|
|
opts.ConfigFiles = []string{"/nonexistent/path/database.yaml"}
|
|
|
|
_, err := OpenPool(ctx, opts)
|
|
|
|
// Should fail with connection error (not config file error)
|
|
// This proves DATABASE_URI was used instead of config files
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
// The error should be about connection failure, not about missing config file
|
|
errStr := err.Error()
|
|
if strings.Contains(errStr, "config file") || strings.Contains(errStr, "no such file") {
|
|
t.Errorf("expected connection error, got config file error: %v", err)
|
|
}
|
|
}
|