@@ -2,32 +2,72 @@ import { expect, test, describe } from 'vitest'
2
2
import { app } from './utils'
3
3
import { pgMeta } from '../lib/utils'
4
4
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
+
5
8
describe ( '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 ( `
27
65
SELECT * FROM pg_stat_activity where application_name = 'postgres-meta 0.0.0-automated' and query ILIKE '%${ query } %';
28
66
` )
29
67
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
+ )
33
73
} )
0 commit comments