@@ -2,32 +2,72 @@ import { expect, test, describe } from 'vitest'
22import { app } from './utils'
33import { pgMeta } from '../lib/utils'
44
5+ const TIMEOUT = ( Number ( process . env . PG_QUERY_TIMEOUT_SECS ) ?? 10 ) + 2
6+ const STATEMENT_TIMEOUT = ( Number ( process . env . PG_QUERY_TIMEOUT_SECS ) ?? 10 ) + 1
7+
58describe ( 'test query timeout' , ( ) => {
6- test ( 'query timeout after 3s and connection cleanup' , async ( ) => {
7- const query = `SELECT pg_sleep(10);`
8- // Execute a query that will sleep for 10 seconds
9- const res = await app . inject ( {
10- method : 'POST' ,
11- path : '/query' ,
12- payload : {
13- query,
14- } ,
15- } )
16-
17- // Check that we get the proper timeout error response
18- expect ( res . statusCode ) . toBe ( 408 ) // Request Timeout
19- expect ( res . json ( ) ) . toMatchObject ( {
20- error : expect . stringContaining ( 'Query read timeout' ) ,
21- } )
22- // wait one second for the statement timeout to take effect
23- await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) )
24-
25- // Verify that the connection has been cleaned up by checking active connections
26- const connectionsRes = await pgMeta . query ( `
9+ test (
10+ `query timeout after ${ TIMEOUT } s and connection cleanup` ,
11+ async ( ) => {
12+ const query = `SELECT pg_sleep(${ TIMEOUT + 10 } );`
13+ // Execute a query that will sleep for 10 seconds
14+ const res = await app . inject ( {
15+ method : 'POST' ,
16+ path : '/query' ,
17+ query : `statementTimeoutSecs=${ STATEMENT_TIMEOUT } ` ,
18+ payload : {
19+ query,
20+ } ,
21+ } )
22+
23+ // Check that we get the proper timeout error response
24+ expect ( res . statusCode ) . toBe ( 408 ) // Request Timeout
25+ expect ( res . json ( ) ) . toMatchObject ( {
26+ error : expect . stringContaining ( 'Query read timeout' ) ,
27+ } )
28+ // wait one second for the statement timeout to take effect
29+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) )
30+
31+ // Verify that the connection has been cleaned up by checking active connections
32+ const connectionsRes = await pgMeta . query ( `
33+ SELECT * FROM pg_stat_activity where application_name = 'postgres-meta 0.0.0-automated' and query ILIKE '%${ query } %';
34+ ` )
35+
36+ // Should have no active connections except for our current query
37+ expect ( connectionsRes . data ) . toHaveLength ( 0 )
38+ } ,
39+ TIMEOUT * 1000
40+ )
41+
42+ test (
43+ 'query without timeout parameter should not have timeout' ,
44+ async ( ) => {
45+ const query = `SELECT pg_sleep(${ TIMEOUT + 10 } );`
46+ // Execute a query that will sleep for 10 seconds without specifying timeout
47+ const res = await app . inject ( {
48+ method : 'POST' ,
49+ path : '/query' ,
50+ payload : {
51+ query,
52+ } ,
53+ } )
54+
55+ // Check that we get the proper timeout error response
56+ expect ( res . statusCode ) . toBe ( 408 ) // Request Timeout
57+ expect ( res . json ( ) ) . toMatchObject ( {
58+ error : expect . stringContaining ( 'Query read timeout' ) ,
59+ } )
60+ // wait one second
61+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) )
62+
63+ // Verify that the connection has not been cleaned up sinice there is no statementTimetout
64+ const connectionsRes = await pgMeta . query ( `
2765 SELECT * FROM pg_stat_activity where application_name = 'postgres-meta 0.0.0-automated' and query ILIKE '%${ query } %';
2866 ` )
2967
30- // Should have no active connections except for our current query
31- expect ( connectionsRes . data ) . toHaveLength ( 0 )
32- } , 5000 )
68+ // Should have no active connections except for our current query
69+ expect ( connectionsRes . data ) . toHaveLength ( 1 )
70+ } ,
71+ TIMEOUT * 1000
72+ )
3373} )
0 commit comments