2
0

Test every QueryExecMode

This commit is contained in:
Jack Christensen
2022-03-05 13:57:48 -06:00
parent aad3d65e16
commit 0d8e109c21
6 changed files with 118 additions and 120 deletions
+50 -59
View File
@@ -74,41 +74,32 @@ func skipPostgreSQLVersionLessThan(t testing.TB, db *sql.DB, minVersion int64) {
require.NoError(t, err)
}
func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, db *sql.DB)) {
t.Run("SimpleProto",
func(t *testing.T) {
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err)
config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
db := stdlib.OpenDB(*config)
defer func() {
err := db.Close()
func testWithAllQueryExecModes(t *testing.T, f func(t *testing.T, db *sql.DB)) {
for _, mode := range []pgx.QueryExecMode{
pgx.QueryExecModeCacheStatement,
pgx.QueryExecModeCacheDescribe,
pgx.QueryExecModeDescribeExec,
pgx.QueryExecModeExec,
pgx.QueryExecModeSimpleProtocol,
} {
t.Run(mode.String(),
func(t *testing.T) {
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err)
}()
f(t, db)
config.DefaultQueryExecMode = mode
db := stdlib.OpenDB(*config)
defer func() {
err := db.Close()
require.NoError(t, err)
}()
ensureDBValid(t, db)
},
)
f(t, db)
t.Run("DefaultProto",
func(t *testing.T) {
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
require.NoError(t, err)
db := stdlib.OpenDB(*config)
defer func() {
err := db.Close()
require.NoError(t, err)
}()
f(t, db)
ensureDBValid(t, db)
},
)
ensureDBValid(t, db)
},
)
}
}
// Do a simple query to ensure the DB is still usable. This is of less use in stdlib as the connection pool should
@@ -267,7 +258,7 @@ func TestQueryCloseRowsEarly(t *testing.T) {
}
func TestConnExec(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.Exec("create temporary table t(a varchar not null)")
require.NoError(t, err)
@@ -281,7 +272,7 @@ func TestConnExec(t *testing.T) {
}
func TestConnQuery(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
rows, err := db.Query("select 'foo', n from generate_series($1::int, $2::int) n", int32(1), int32(10))
@@ -313,7 +304,7 @@ func TestConnQuery(t *testing.T) {
// https://github.com/jackc/pgx/issues/781
func TestConnQueryDifferentScanPlansIssue781(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
var s string
var b bool
@@ -328,7 +319,7 @@ func TestConnQueryDifferentScanPlansIssue781(t *testing.T) {
}
func TestConnQueryNull(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
rows, err := db.Query("select $1::int", nil)
require.NoError(t, err)
@@ -353,7 +344,7 @@ func TestConnQueryNull(t *testing.T) {
}
func TestConnQueryRowByteSlice(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
expected := []byte{222, 173, 190, 239}
var actual []byte
@@ -364,7 +355,7 @@ func TestConnQueryRowByteSlice(t *testing.T) {
}
func TestConnQueryFailure(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.Query("select 'foo")
require.Error(t, err)
require.IsType(t, new(pgconn.PgError), err)
@@ -372,7 +363,7 @@ func TestConnQueryFailure(t *testing.T) {
}
func TestConnSimpleSlicePassThrough(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server does not support cardinality function")
var n int64
@@ -385,7 +376,7 @@ func TestConnSimpleSlicePassThrough(t *testing.T) {
// Test type that pgx would handle natively in binary, but since it is not a
// database/sql native type should be passed through as a string
func TestConnQueryRowPgxBinary(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
sql := "select $1::int4[]"
expected := "{1,2,3}"
var actual string
@@ -397,7 +388,7 @@ func TestConnQueryRowPgxBinary(t *testing.T) {
}
func TestConnQueryRowUnknownType(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server does not support point type")
sql := "select $1::point"
@@ -411,7 +402,7 @@ func TestConnQueryRowUnknownType(t *testing.T) {
}
func TestConnQueryJSONIntoByteSlice(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.Exec(`
create temporary table docs(
body json not null
@@ -471,7 +462,7 @@ func TestConnExecInsertByteSliceIntoJSON(t *testing.T) {
}
func TestTransactionLifeCycle(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.Exec("create temporary table t(a varchar not null)")
require.NoError(t, err)
@@ -505,7 +496,7 @@ func TestTransactionLifeCycle(t *testing.T) {
}
func TestConnBeginTxIsolation(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server always uses serializable isolation level")
var defaultIsoLevel string
@@ -561,7 +552,7 @@ func TestConnBeginTxIsolation(t *testing.T) {
}
func TestConnBeginTxReadOnly(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
require.NoError(t, err)
defer tx.Rollback()
@@ -579,7 +570,7 @@ func TestConnBeginTxReadOnly(t *testing.T) {
}
func TestBeginTxContextCancel(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.Exec("drop table if exists t")
require.NoError(t, err)
@@ -607,7 +598,7 @@ func TestBeginTxContextCancel(t *testing.T) {
}
func TestAcquireConn(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
var conns []*pgx.Conn
for i := 1; i < 6; i++ {
@@ -643,7 +634,7 @@ func TestAcquireConn(t *testing.T) {
}
func TestConnRaw(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
conn, err := db.Conn(context.Background())
require.NoError(t, err)
@@ -659,7 +650,7 @@ func TestConnRaw(t *testing.T) {
// https://github.com/jackc/pgx/issues/673
func TestReleaseConnWithTxInProgress(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server does not support backend PID")
c1, err := stdlib.AcquireConn(db)
@@ -690,14 +681,14 @@ func TestReleaseConnWithTxInProgress(t *testing.T) {
}
func TestConnPingContextSuccess(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
err := db.PingContext(context.Background())
require.NoError(t, err)
})
}
func TestConnPrepareContextSuccess(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
stmt, err := db.PrepareContext(context.Background(), "select now()")
require.NoError(t, err)
err = stmt.Close()
@@ -706,14 +697,14 @@ func TestConnPrepareContextSuccess(t *testing.T) {
}
func TestConnExecContextSuccess(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
_, err := db.ExecContext(context.Background(), "create temporary table exec_context_test(id serial primary key)")
require.NoError(t, err)
})
}
func TestConnExecContextFailureRetry(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
// We get a connection, immediately close it, and then get it back;
// DB.Conn along with Conn.ResetSession does the retry for us.
{
@@ -730,7 +721,7 @@ func TestConnExecContextFailureRetry(t *testing.T) {
}
func TestConnQueryContextSuccess(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
rows, err := db.QueryContext(context.Background(), "select * from generate_series(1,10) n")
require.NoError(t, err)
@@ -744,7 +735,7 @@ func TestConnQueryContextSuccess(t *testing.T) {
}
func TestConnQueryContextFailureRetry(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
// We get a connection, immediately close it, and then get it back;
// DB.Conn along with Conn.ResetSession does the retry for us.
{
@@ -762,7 +753,7 @@ func TestConnQueryContextFailureRetry(t *testing.T) {
}
func TestRowsColumnTypeDatabaseTypeName(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
rows, err := db.Query("select 42::bigint")
require.NoError(t, err)
@@ -846,7 +837,7 @@ func TestStmtQueryContextSuccess(t *testing.T) {
}
func TestRowsColumnTypes(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
columnTypesTests := []struct {
Name string
TypeName string
@@ -984,7 +975,7 @@ func TestRowsColumnTypes(t *testing.T) {
}
func TestQueryLifeCycle(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipCockroachDB(t, db, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
rows, err := db.Query("SELECT 'foo', n FROM generate_series($1::int, $2::int) n WHERE 3 = $3", 1, 10, 3)
@@ -1033,7 +1024,7 @@ func TestQueryLifeCycle(t *testing.T) {
// https://github.com/jackc/pgx/issues/409
func TestScanJSONIntoJSONRawMessage(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
var msg json.RawMessage
err := db.QueryRow("select '{}'::json").Scan(&msg)
@@ -1088,7 +1079,7 @@ func TestRegisterConnConfig(t *testing.T) {
// https://github.com/jackc/pgx/issues/958
func TestConnQueryRowConstraintErrors(t *testing.T) {
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
testWithAllQueryExecModes(t, func(t *testing.T, db *sql.DB) {
skipPostgreSQLVersionLessThan(t, db, 11)
skipCockroachDB(t, db, "Server does not support deferred constraint (https://github.com/cockroachdb/cockroach/issues/31632)")