Add Config.Copy() in pgx and pgxpool packages. Conn.Config() and Pool.Config() return copy of the original config.
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
|
||||
"github.com/jackc/pgconn"
|
||||
"github.com/jackc/pgx/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -125,3 +127,79 @@ func testCopyFrom(t *testing.T, db interface {
|
||||
assert.NoError(t, rows.Err())
|
||||
assert.Equal(t, inputRows, outputRows)
|
||||
}
|
||||
|
||||
func assertConfigsEqual(t *testing.T, expected, actual *pgxpool.Config, testName string) {
|
||||
if !assert.NotNil(t, expected) {
|
||||
return
|
||||
}
|
||||
if !assert.NotNil(t, actual) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equalf(t, expected.ConnString(), actual.ConnString(), "%s - ConnString", testName)
|
||||
|
||||
// Can't test function equality, so just test that they are set or not.
|
||||
assert.Equalf(t, expected.AfterConnect == nil, actual.AfterConnect == nil, "%s - AfterConnect", testName)
|
||||
assert.Equalf(t, expected.BeforeAcquire == nil, actual.BeforeAcquire == nil, "%s - BeforeAcquire", testName)
|
||||
assert.Equalf(t, expected.AfterRelease == nil, actual.AfterRelease == nil, "%s - AfterRelease", testName)
|
||||
|
||||
assert.Equalf(t, expected.MaxConnLifetime, actual.MaxConnLifetime, "%s - MaxConnLifetime", testName)
|
||||
assert.Equalf(t, expected.MaxConnIdleTime, actual.MaxConnIdleTime, "%s - MaxConnIdleTime", testName)
|
||||
assert.Equalf(t, expected.MaxConns, actual.MaxConns, "%s - MaxConns", testName)
|
||||
assert.Equalf(t, expected.MinConns, actual.MinConns, "%s - MinConns", testName)
|
||||
assert.Equalf(t, expected.HealthCheckPeriod, actual.HealthCheckPeriod, "%s - HealthCheckPeriod", testName)
|
||||
assert.Equalf(t, expected.LazyConnect, actual.LazyConnect, "%s - LazyConnect", testName)
|
||||
|
||||
assertConnConfigsEqual(t, expected.ConnConfig, actual.ConnConfig, testName)
|
||||
}
|
||||
|
||||
func assertConnConfigsEqual(t *testing.T, expected, actual *pgx.ConnConfig, testName string) {
|
||||
if !assert.NotNil(t, expected) {
|
||||
return
|
||||
}
|
||||
if !assert.NotNil(t, actual) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equalf(t, expected.Logger, actual.Logger, "%s - Logger", testName)
|
||||
assert.Equalf(t, expected.LogLevel, actual.LogLevel, "%s - LogLevel", testName)
|
||||
assert.Equalf(t, expected.ConnString(), actual.ConnString(), "%s - ConnString", testName)
|
||||
|
||||
// Can't test function equality, so just test that they are set or not.
|
||||
assert.Equalf(t, expected.BuildStatementCache == nil, actual.BuildStatementCache == nil, "%s - BuildStatementCache", testName)
|
||||
|
||||
assert.Equalf(t, expected.PreferSimpleProtocol, actual.PreferSimpleProtocol, "%s - PreferSimpleProtocol", testName)
|
||||
|
||||
assert.Equalf(t, expected.Host, actual.Host, "%s - Host", testName)
|
||||
assert.Equalf(t, expected.Database, actual.Database, "%s - Database", testName)
|
||||
assert.Equalf(t, expected.Port, actual.Port, "%s - Port", testName)
|
||||
assert.Equalf(t, expected.User, actual.User, "%s - User", testName)
|
||||
assert.Equalf(t, expected.Password, actual.Password, "%s - Password", testName)
|
||||
assert.Equalf(t, expected.ConnectTimeout, actual.ConnectTimeout, "%s - ConnectTimeout", testName)
|
||||
assert.Equalf(t, expected.RuntimeParams, actual.RuntimeParams, "%s - RuntimeParams", testName)
|
||||
|
||||
// Can't test function equality, so just test that they are set or not.
|
||||
assert.Equalf(t, expected.ValidateConnect == nil, actual.ValidateConnect == nil, "%s - ValidateConnect", testName)
|
||||
assert.Equalf(t, expected.AfterConnect == nil, actual.AfterConnect == nil, "%s - AfterConnect", testName)
|
||||
|
||||
if assert.Equalf(t, expected.TLSConfig == nil, actual.TLSConfig == nil, "%s - TLSConfig", testName) {
|
||||
if expected.TLSConfig != nil {
|
||||
assert.Equalf(t, expected.TLSConfig.InsecureSkipVerify, actual.TLSConfig.InsecureSkipVerify, "%s - TLSConfig InsecureSkipVerify", testName)
|
||||
assert.Equalf(t, expected.TLSConfig.ServerName, actual.TLSConfig.ServerName, "%s - TLSConfig ServerName", testName)
|
||||
}
|
||||
}
|
||||
|
||||
if assert.Equalf(t, len(expected.Fallbacks), len(actual.Fallbacks), "%s - Fallbacks", testName) {
|
||||
for i := range expected.Fallbacks {
|
||||
assert.Equalf(t, expected.Fallbacks[i].Host, actual.Fallbacks[i].Host, "%s - Fallback %d - Host", testName, i)
|
||||
assert.Equalf(t, expected.Fallbacks[i].Port, actual.Fallbacks[i].Port, "%s - Fallback %d - Port", testName, i)
|
||||
|
||||
if assert.Equalf(t, expected.Fallbacks[i].TLSConfig == nil, actual.Fallbacks[i].TLSConfig == nil, "%s - Fallback %d - TLSConfig", testName, i) {
|
||||
if expected.Fallbacks[i].TLSConfig != nil {
|
||||
assert.Equalf(t, expected.Fallbacks[i].TLSConfig.InsecureSkipVerify, actual.Fallbacks[i].TLSConfig.InsecureSkipVerify, "%s - Fallback %d - TLSConfig InsecureSkipVerify", testName)
|
||||
assert.Equalf(t, expected.Fallbacks[i].TLSConfig.ServerName, actual.Fallbacks[i].TLSConfig.ServerName, "%s - Fallback %d - TLSConfig ServerName", testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-2
@@ -121,6 +121,16 @@ type Config struct {
|
||||
createdByParseConfig bool // Used to enforce created by ParseConfig rule.
|
||||
}
|
||||
|
||||
// Copy returns a deep copy of the config that is safe to use and modify.
|
||||
// The only exception is the tls.Config:
|
||||
// according to the tls.Config docs it must not be modified after creation.
|
||||
func (c *Config) Copy() *Config {
|
||||
newConfig := new(Config)
|
||||
*newConfig = *c
|
||||
newConfig.ConnConfig = c.ConnConfig.Copy()
|
||||
return newConfig
|
||||
}
|
||||
|
||||
func (c *Config) ConnString() string { return c.ConnConfig.ConnString() }
|
||||
|
||||
// Connect creates a new Pool and immediately establishes one connection. ctx can be used to cancel this initial
|
||||
@@ -373,8 +383,8 @@ func (p *Pool) AcquireAllIdle(ctx context.Context) []*Conn {
|
||||
return conns
|
||||
}
|
||||
|
||||
// Config returns config that was used to initialize this pool.
|
||||
func (p *Pool) Config() *Config { return p.config }
|
||||
// Config returns a copy of config that was used to initialize this pool.
|
||||
func (p *Pool) Config() *Config { return p.config.Copy() }
|
||||
|
||||
func (p *Pool) Stat() *Stat {
|
||||
return &Stat{s: p.p.Stat()}
|
||||
|
||||
+23
-1
@@ -28,7 +28,7 @@ func TestConnectConfig(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
pool, err := pgxpool.ConnectConfig(context.Background(), config)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, config, pool.Config())
|
||||
assertConfigsEqual(t, config, pool.Config(), "Pool.Config() returns original config")
|
||||
pool.Close()
|
||||
}
|
||||
|
||||
@@ -78,6 +78,28 @@ func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
||||
require.PanicsWithValue(t, "config must be created by ParseConfig", func() { pgxpool.ConnectConfig(context.Background(), config) })
|
||||
}
|
||||
|
||||
func TestConfigCopyReturnsEqualConfig(t *testing.T) {
|
||||
connString := "postgres://jack:secret@localhost:5432/mydb?application_name=pgxtest&search_path=myschema&connect_timeout=5"
|
||||
original, err := pgxpool.ParseConfig(connString)
|
||||
require.NoError(t, err)
|
||||
|
||||
copied := original.Copy()
|
||||
|
||||
assertConfigsEqual(t, original, copied, t.Name())
|
||||
}
|
||||
|
||||
func TestConfigCopyCanBeUsedToConnect(t *testing.T) {
|
||||
connString := os.Getenv("PGX_TEST_DATABASE")
|
||||
original, err := pgxpool.ParseConfig(connString)
|
||||
require.NoError(t, err)
|
||||
|
||||
copied := original.Copy()
|
||||
assert.NotPanics(t, func() {
|
||||
_, err = pgxpool.ConnectConfig(context.Background(), copied)
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestPoolAcquireAndConnRelease(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user