(t *testing.T)
| 1308 | } |
| 1309 | |
| 1310 | func TestCheckIdleConn(t *testing.T) { |
| 1311 | controllerConn, err := sql.Open("pgx", os.Getenv("PGX_TEST_DATABASE")) |
| 1312 | require.NoError(t, err) |
| 1313 | defer closeDB(t, controllerConn) |
| 1314 | |
| 1315 | skipCockroachDB(t, controllerConn, "Server does not support pg_terminate_backend() (https://github.com/cockroachdb/cockroach/issues/35897)") |
| 1316 | |
| 1317 | db, err := sql.Open("pgx", os.Getenv("PGX_TEST_DATABASE")) |
| 1318 | require.NoError(t, err) |
| 1319 | defer closeDB(t, db) |
| 1320 | |
| 1321 | var conns []*sql.Conn |
| 1322 | for range 3 { |
| 1323 | c, err := db.Conn(context.Background()) |
| 1324 | require.NoError(t, err) |
| 1325 | conns = append(conns, c) |
| 1326 | } |
| 1327 | |
| 1328 | require.EqualValues(t, 3, db.Stats().OpenConnections) |
| 1329 | |
| 1330 | var pids []uint32 |
| 1331 | for _, c := range conns { |
| 1332 | err := c.Raw(func(driverConn any) error { |
| 1333 | pids = append(pids, driverConn.(*stdlib.Conn).Conn().PgConn().PID()) |
| 1334 | return nil |
| 1335 | }) |
| 1336 | require.NoError(t, err) |
| 1337 | err = c.Close() |
| 1338 | require.NoError(t, err) |
| 1339 | } |
| 1340 | |
| 1341 | // The database/sql connection pool seems to automatically close idle connections to only keep 2 alive. |
| 1342 | // require.EqualValues(t, 3, db.Stats().OpenConnections) |
| 1343 | |
| 1344 | _, err = controllerConn.ExecContext(context.Background(), `select pg_terminate_backend(n) from unnest($1::int[]) n`, pids) |
| 1345 | require.NoError(t, err) |
| 1346 | |
| 1347 | // All conns are dead they don't know it and neither does the pool. But because of database/sql automatically closing |
| 1348 | // idle connections we can't be sure how many we should have. require.EqualValues(t, 3, db.Stats().OpenConnections) |
| 1349 | |
| 1350 | // Wait long enough so the pool will realize it needs to check the connections. |
| 1351 | time.Sleep(time.Second) |
| 1352 | |
| 1353 | // Pool should try all existing connections and find them dead, then create a new connection which should successfully ping. |
| 1354 | err = db.PingContext(context.Background()) |
| 1355 | require.NoError(t, err) |
| 1356 | |
| 1357 | // The original 3 conns should have been terminated and the a new conn established for the ping. |
| 1358 | require.EqualValues(t, 1, db.Stats().OpenConnections) |
| 1359 | c, err := db.Conn(context.Background()) |
| 1360 | require.NoError(t, err) |
| 1361 | |
| 1362 | var cPID uint32 |
| 1363 | err = c.Raw(func(driverConn any) error { |
| 1364 | cPID = driverConn.(*stdlib.Conn).Conn().PgConn().PID() |
| 1365 | return nil |
| 1366 | }) |
| 1367 | require.NoError(t, err) |
nothing calls this directly
no test coverage detected