Skip to content

Commit

Permalink
Modified tests to not use if/else condition
Browse files Browse the repository at this point in the history
Added steps to add support for new pgbouncer versions
Tests no longer use the if/else conditions to check for nil and instead reuse  and
Added comments for columns added in pgbouncer v1.23
  • Loading branch information
rahulreddy15 committed Nov 6, 2024
1 parent 1aa6db3 commit 319293f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 53 deletions.
102 changes: 51 additions & 51 deletions src/metrics/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,48 @@ func TestPopulateIndexMetricsForDatabaseNoIndexes(t *testing.T) {
}

func TestPopulatePgBouncerMetrics(t *testing.T) {

pgbouncerPriorTo23StatsRows := func() *sqlmock.Rows {
return sqlmock.NewRows([]string{
"database",
"total_xact_count",
"total_query_count",
"total_received",
"total_sent",
"total_xact_time",
"total_query_time",
"total_wait_time",
"avg_xact_count",
"avg_xact_time",
"avg_query_count",
"avg_recv",
"avg_sent",
"avg_query_time",
"avg_wait_time",
}).AddRow("testDB", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
}

pgbouncerPriorTo23ExpectedStats := func() map[string]interface{} {
return map[string]interface{}{
"pgbouncer.stats.transactionsPerSecond": float64(0),
"pgbouncer.stats.queriesPerSecond": float64(0),
"pgbouncer.stats.bytesInPerSecond": float64(0),
"pgbouncer.stats.bytesOutPerSecond": float64(0),
"pgbouncer.stats.totalTransactionDurationInMillisecondsPerSecond": float64(0),
"pgbouncer.stats.totalQueryDurationInMillisecondsPerSecond": float64(0),
"pgbouncer.stats.avgTransactionCount": float64(8),
"pgbouncer.stats.avgTransactionDurationInMilliseconds": float64(9),
"pgbouncer.stats.avgQueryCount": float64(10),
"pgbouncer.stats.avgBytesIn": float64(11),
"pgbouncer.stats.avgBytesOut": float64(12),
"pgbouncer.stats.avgQueryDurationInMilliseconds": float64(13),
"displayName": "testDB",
"entityName": "pgbouncer:testDB",
"event_type": "PgBouncerSample",
"host": "testhost",
}
}

testsCases := []struct {
name string
pgbouncerPoolsRows *sqlmock.Rows
Expand All @@ -458,6 +500,8 @@ func TestPopulatePgBouncerMetrics(t *testing.T) {
"maxwait_us",
"pool_mode",
}).AddRow("testDB", "testUser", 1, 2, 3, 4, 5, 6, 7, 8, 9, "testMode"),
pgbouncerStatsRows: pgbouncerPriorTo23StatsRows(),
expectedStats: pgbouncerPriorTo23ExpectedStats(),
expectedPool: map[string]interface{}{
"pgbouncer.pools.clientConnectionsActive": float64(1),
"pgbouncer.pools.clientConnectionsWaiting": float64(2),
Expand Down Expand Up @@ -491,6 +535,8 @@ func TestPopulatePgBouncerMetrics(t *testing.T) {
"pool_mode",
"cl_cancel_req", // Added column.
}).AddRow("testDB", "testUser", 1, 2, 3, 4, 5, 6, 7, 8, 9, "testMode", 10),
pgbouncerStatsRows: pgbouncerPriorTo23StatsRows(),
expectedStats: pgbouncerPriorTo23ExpectedStats(),
expectedPool: map[string]interface{}{
"pgbouncer.pools.clientConnectionsActive": float64(1),
"pgbouncer.pools.clientConnectionsWaiting": float64(2),
Expand Down Expand Up @@ -528,6 +574,8 @@ func TestPopulatePgBouncerMetrics(t *testing.T) {
"sv_active_cancel",
"sv_being_canceled",
}).AddRow("testDB", "testUser", 1, 2, 3, 4, 5, 6, 7, 8, 9, "testMode", 10, 11, 12, 13),
pgbouncerStatsRows: pgbouncerPriorTo23StatsRows(),
expectedStats: pgbouncerPriorTo23ExpectedStats(),
expectedPool: map[string]interface{}{
"pgbouncer.pools.clientConnectionsActive": float64(1),
"pgbouncer.pools.clientConnectionsWaiting": float64(2),
Expand Down Expand Up @@ -637,51 +685,8 @@ func TestPopulatePgBouncerMetrics(t *testing.T) {

testConnection, mock := connection.CreateMockSQL(t)

pgbouncerStatsRows := sqlmock.NewRows([]string{
"database",
"total_xact_count",
"total_query_count",
"total_received",
"total_sent",
"total_xact_time",
"total_query_time",
"total_wait_time",
"avg_xact_count",
"avg_xact_time",
"avg_query_count",
"avg_recv",
"avg_sent",
"avg_query_time",
"avg_wait_time",
}).AddRow("testDB", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

expectedStats := map[string]interface{}{
"pgbouncer.stats.transactionsPerSecond": float64(0),
"pgbouncer.stats.queriesPerSecond": float64(0),
"pgbouncer.stats.bytesInPerSecond": float64(0),
"pgbouncer.stats.bytesOutPerSecond": float64(0),
"pgbouncer.stats.totalTransactionDurationInMillisecondsPerSecond": float64(0),
"pgbouncer.stats.totalQueryDurationInMillisecondsPerSecond": float64(0),
"pgbouncer.stats.avgTransactionCount": float64(8),
"pgbouncer.stats.avgTransactionDurationInMilliseconds": float64(9),
"pgbouncer.stats.avgQueryCount": float64(10),
"pgbouncer.stats.avgBytesIn": float64(11),
"pgbouncer.stats.avgBytesOut": float64(12),
"pgbouncer.stats.avgQueryDurationInMilliseconds": float64(13),

"displayName": "testDB",
"entityName": "pgbouncer:testDB",
"event_type": "PgBouncerSample",
"host": "testhost",
}

if testCase.pgbouncerStatsRows == nil {
mock.ExpectQuery("SHOW STATS;").
WillReturnRows(pgbouncerStatsRows)
} else {
mock.ExpectQuery("SHOW STATS;").
WillReturnRows(testCase.pgbouncerStatsRows)
}
mock.ExpectQuery("SHOW STATS;").
WillReturnRows(testCase.pgbouncerStatsRows)

mock.ExpectQuery("SHOW POOLS;").
WillReturnRows(testCase.pgbouncerPoolsRows)
Expand All @@ -694,12 +699,7 @@ func TestPopulatePgBouncerMetrics(t *testing.T) {
pbEntity, err := testIntegration.Entity("testDB", "pgbouncer", id3, id4)
assert.Nil(t, err)
assert.Equal(t, len(pbEntity.Metrics), 2)
if testCase.expectedStats == nil {
assert.Equal(t, expectedStats, pbEntity.Metrics[0].Metrics)
} else {
assert.Equal(t, testCase.expectedStats, pbEntity.Metrics[0].Metrics)
}

assert.Equal(t, testCase.expectedStats, pbEntity.Metrics[0].Metrics)
assert.Equal(t, testCase.expectedPool, pbEntity.Metrics[1].Metrics)
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/metrics/pgbouncer_definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var pgbouncerStatsDefinition = &QueryDefinition{
databaseBase
TotalXactCount *int64 `db:"total_xact_count" metric_name:"pgbouncer.stats.transactionsPerSecond" source_type:"rate"`
TotalQueryCount *int64 `db:"total_query_count" metric_name:"pgbouncer.stats.queriesPerSecond" source_type:"rate"`
TotalServerAssignmentCount *int64 `db:"total_server_assignment_count" metric_name:"pgbouncer.stats.totalServerAssignmentCount" source_type:"gauge"`
TotalServerAssignmentCount *int64 `db:"total_server_assignment_count" metric_name:"pgbouncer.stats.totalServerAssignmentCount" source_type:"gauge"` // added in v1.23
TotalReceived *int64 `db:"total_received" metric_name:"pgbouncer.stats.bytesInPerSecond" source_type:"rate"`
TotalSent *int64 `db:"total_sent" metric_name:"pgbouncer.stats.bytesOutPerSecond" source_type:"rate"`
TotalXactTime *int64 `db:"total_xact_time" metric_name:"pgbouncer.stats.totalTransactionDurationInMillisecondsPerSecond" source_type:"rate"`
Expand All @@ -25,7 +25,7 @@ var pgbouncerStatsDefinition = &QueryDefinition{
AvgXactCount *int64 `db:"avg_xact_count" metric_name:"pgbouncer.stats.avgTransactionCount" source_type:"gauge"`
AvgXactTime *int64 `db:"avg_xact_time" metric_name:"pgbouncer.stats.avgTransactionDurationInMilliseconds" source_type:"gauge"`
AvgQueryCount *int64 `db:"avg_query_count" metric_name:"pgbouncer.stats.avgQueryCount" source_type:"gauge"`
AvgServerAssignmentCount *int64 `db:"avg_server_assignment_count" metric_name:"pgbouncer.stats.avgServerAssignmentCount" source_type:"gauge"`
AvgServerAssignmentCount *int64 `db:"avg_server_assignment_count" metric_name:"pgbouncer.stats.avgServerAssignmentCount" source_type:"gauge"` // added in v1.23
AvgRecv *int64 `db:"avg_recv" metric_name:"pgbouncer.stats.avgBytesIn" source_type:"gauge"`
AvgSent *int64 `db:"avg_sent" metric_name:"pgbouncer.stats.avgBytesOut" source_type:"gauge"`
AvgReq *int64 `db:"avg_req" metric_name:"pgbouncer.stats.avgRequestsPerSecond" source_type:"gauge"`
Expand Down
16 changes: 16 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ Steps to update the integration tests for the latest supported version:
- Check the release notes ([Postgres 16 example](https://www.postgresql.org/docs/release/16.0/))
3. Once the failures are understood (if any), update the corresponding JSON-schema files, you may need to generate it
using the integration output, specially if there is any metric failure.

# Testing pgbouncer upgrades

Steps to test breaking metrics changes that happen when new pgbouncer versions are released:

1. Update the `db` image and `pgbouncer` images in [docker compose](./docker-compose-pgbouncer.yml).
2. Use the command `docker compose -f ./docker-compose-pgbouncer.yml up` to get the environment running
3. Run the integration with `go run ./src/main.go -pgbouncer -username {USERNAME} -password {PASSWORD} -p 5432 -pretty > pgbouncer_output.json`
* If the terminal logs errors:
- Check which query is failing
- Explore pgbouncer release notes for changes to the `STATS` and `POOLS` tables
- Add or remove metrics to make the query succeed
- Modify tests to check for the new metrics in the latest versions
* No errors:
- Take a look at `pgbouncer_output.json` and look at the pgbouncer entities and check if metrics are reported correctly.
- If metrics are incorrectly reported, go back and look at where queries might be failing.

0 comments on commit 319293f

Please sign in to comment.