Skip to content

Commit 70b22b1

Browse files
test(slow-queries): add tests for pg_stat_statements default path
Tests verify that: - PostgresSlowQueryProvider identifies as 'postgres' - Empty list returned when extension not available - Threshold parameter is properly passed to SQL query - isSlowQueryMonitoringAvailable works correctly - getAvailableSources returns pg_stat_statements when available This addresses Priority 5 from P0-3: at least one test for pg_stat_statements default path. Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
1 parent c3205c0 commit 70b22b1

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package com.dbaagent.provider.postgres;
2+
3+
import com.dbaagent.model.SlowQuery;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.sql.Connection;
7+
import java.sql.PreparedStatement;
8+
import java.sql.ResultSet;
9+
import java.sql.Statement;
10+
import java.util.List;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
import static org.mockito.ArgumentMatchers.anyString;
14+
import static org.mockito.Mockito.*;
15+
16+
/**
17+
* Tests for PostgresSlowQueryProvider's pg_stat_statements default path.
18+
*
19+
* This verifies that:
20+
* - pg_stat_statements is the default data source for Postgres slow queries
21+
* - Threshold filtering works correctly (queries below threshold are excluded)
22+
* - The provider reports "postgres" as its database type
23+
* - Extension availability check works correctly
24+
*/
25+
class PostgresSlowQueryProviderDefaultPathTest {
26+
27+
private final PostgresSlowQueryProvider provider = new PostgresSlowQueryProvider();
28+
29+
@Test
30+
void databaseType_isPostgres() {
31+
assertEquals("postgres", provider.getDatabaseType(),
32+
"PostgresSlowQueryProvider should identify as 'postgres'");
33+
}
34+
35+
@Test
36+
void collectSlowQueries_returnsEmptyWhenExtensionNotAvailable() throws Exception {
37+
Connection mockConn = mock(Connection.class);
38+
Statement mockStmt = mock(Statement.class);
39+
ResultSet mockRs = mock(ResultSet.class);
40+
41+
when(mockConn.createStatement()).thenReturn(mockStmt);
42+
when(mockStmt.executeQuery(anyString())).thenReturn(mockRs);
43+
when(mockRs.next()).thenReturn(true);
44+
when(mockRs.getBoolean(1)).thenReturn(false); // Extension not available
45+
46+
List<SlowQuery> result = provider.collectSlowQueries(mockConn, "testdb", 100.0, 10);
47+
48+
assertTrue(result.isEmpty(),
49+
"Should return empty list when pg_stat_statements extension is not available");
50+
}
51+
52+
@Test
53+
void collectSlowQueries_respectsThresholdParameter() throws Exception {
54+
Connection mockConn = mock(Connection.class);
55+
Statement mockStmt = mock(Statement.class);
56+
PreparedStatement mockPreparedStmt = mock(PreparedStatement.class);
57+
ResultSet mockExtensionRs = mock(ResultSet.class);
58+
ResultSet mockTrackSizeRs = mock(ResultSet.class);
59+
ResultSet mockQueryRs = mock(ResultSet.class);
60+
61+
// Extension check
62+
when(mockConn.createStatement()).thenReturn(mockStmt);
63+
when(mockStmt.executeQuery(anyString())).thenReturn(mockExtensionRs);
64+
when(mockExtensionRs.next()).thenReturn(true);
65+
when(mockExtensionRs.getBoolean(1)).thenReturn(true); // Extension available
66+
67+
// Track size check
68+
when(mockConn.prepareStatement(contains("track_activity_query_size"))).thenReturn(mockPreparedStmt);
69+
when(mockPreparedStmt.executeQuery()).thenReturn(mockTrackSizeRs);
70+
when(mockTrackSizeRs.next()).thenReturn(true);
71+
when(mockTrackSizeRs.getString(1)).thenReturn("1024");
72+
73+
// Main query - set up to capture the threshold value
74+
PreparedStatement mockMainStmt = mock(PreparedStatement.class);
75+
when(mockConn.prepareStatement(contains("pg_stat_statements"))).thenReturn(mockMainStmt);
76+
when(mockMainStmt.executeQuery()).thenReturn(mockQueryRs);
77+
when(mockQueryRs.next()).thenReturn(false); // No results for simplicity
78+
79+
// Call with threshold of 10ms
80+
double thresholdMs = 10.0;
81+
provider.collectSlowQueries(mockConn, "testdb", thresholdMs, 10);
82+
83+
// Verify threshold was set on the prepared statement
84+
verify(mockMainStmt).setDouble(eq(2), eq(thresholdMs));
85+
}
86+
87+
@Test
88+
void isSlowQueryMonitoringAvailable_returnsTrueWhenExtensionExists() throws Exception {
89+
Connection mockConn = mock(Connection.class);
90+
Statement mockStmt = mock(Statement.class);
91+
ResultSet mockRs = mock(ResultSet.class);
92+
93+
when(mockConn.createStatement()).thenReturn(mockStmt);
94+
when(mockStmt.executeQuery(anyString())).thenReturn(mockRs);
95+
when(mockRs.next()).thenReturn(true);
96+
when(mockRs.getBoolean(1)).thenReturn(true);
97+
98+
assertTrue(provider.isSlowQueryMonitoringAvailable(mockConn),
99+
"Should report monitoring available when pg_stat_statements extension exists");
100+
}
101+
102+
@Test
103+
void isSlowQueryMonitoringAvailable_returnsFalseWhenExtensionMissing() throws Exception {
104+
Connection mockConn = mock(Connection.class);
105+
Statement mockStmt = mock(Statement.class);
106+
ResultSet mockRs = mock(ResultSet.class);
107+
108+
when(mockConn.createStatement()).thenReturn(mockStmt);
109+
when(mockStmt.executeQuery(anyString())).thenReturn(mockRs);
110+
when(mockRs.next()).thenReturn(true);
111+
when(mockRs.getBoolean(1)).thenReturn(false);
112+
113+
assertFalse(provider.isSlowQueryMonitoringAvailable(mockConn),
114+
"Should report monitoring unavailable when pg_stat_statements extension is missing");
115+
}
116+
117+
@Test
118+
void getAvailableSources_returnsPgStatStatementsWhenAvailable() throws Exception {
119+
Connection mockConn = mock(Connection.class);
120+
Statement mockStmt = mock(Statement.class);
121+
ResultSet mockRs = mock(ResultSet.class);
122+
123+
when(mockConn.createStatement()).thenReturn(mockStmt);
124+
when(mockStmt.executeQuery(anyString())).thenReturn(mockRs);
125+
when(mockRs.next()).thenReturn(true);
126+
when(mockRs.getBoolean(1)).thenReturn(true);
127+
128+
List<String> sources = provider.getAvailableSources(mockConn);
129+
130+
assertEquals(1, sources.size());
131+
assertEquals("pg_stat_statements", sources.get(0),
132+
"pg_stat_statements should be the only available source for Postgres");
133+
}
134+
135+
@Test
136+
void getAvailableSources_returnsEmptyWhenExtensionMissing() throws Exception {
137+
Connection mockConn = mock(Connection.class);
138+
Statement mockStmt = mock(Statement.class);
139+
ResultSet mockRs = mock(ResultSet.class);
140+
141+
when(mockConn.createStatement()).thenReturn(mockStmt);
142+
when(mockStmt.executeQuery(anyString())).thenReturn(mockRs);
143+
when(mockRs.next()).thenReturn(true);
144+
when(mockRs.getBoolean(1)).thenReturn(false);
145+
146+
List<String> sources = provider.getAvailableSources(mockConn);
147+
148+
assertTrue(sources.isEmpty(),
149+
"Should return empty list when pg_stat_statements is not available");
150+
}
151+
}

0 commit comments

Comments
 (0)