@@ -166,6 +166,24 @@ async function waitForDrainCheck(): Promise<void> {
166166 await new Promise ( ( resolve ) => setImmediate ( resolve ) )
167167}
168168
169+ async function loadPgConnectionModuleWithConfig ( configOverrides : Record < string , unknown > ) {
170+ vi . resetModules ( )
171+
172+ const configModule = await import ( '../../config' )
173+ configModule . getConfig ( { reload : true } )
174+ configModule . mergeConfig ( {
175+ databaseApplicationName : 'storage-test' ,
176+ databaseConnectionTimeout : 3000 ,
177+ databaseFreePoolAfterInactivity : 1000 ,
178+ databaseMaxConnections : 20 ,
179+ databaseSSLRootCert : undefined ,
180+ databaseTlsSessionResumption : false ,
181+ ...configOverrides ,
182+ } as Parameters < typeof configModule . mergeConfig > [ 0 ] )
183+
184+ return import ( './pg-connection' )
185+ }
186+
169187describe ( 'getPgCancelConnectionTarget' , ( ) => {
170188 it ( 'uses direct client host and port for TCP cancel connections' , ( ) => {
171189 expect (
@@ -1067,3 +1085,95 @@ describe('PgPoolStrategy', () => {
10671085 }
10681086 } )
10691087} )
1088+
1089+ describe ( 'PgPoolStrategy TLS session resumption wiring' , ( ) => {
1090+ afterEach ( ( ) => {
1091+ vi . resetModules ( )
1092+ } )
1093+
1094+ function createDynamicTestablePgPoolStrategy ( PgPoolStrategyCtor : typeof PgPoolStrategy ) {
1095+ return class DynamicTestablePgPoolStrategy extends PgPoolStrategyCtor {
1096+ getCurrentPoolForTest ( ) : Pool {
1097+ return this . getPool ( )
1098+ }
1099+ }
1100+ }
1101+
1102+ it ( 'installs the session getter, slot marker, and custom client when enabled with SSL' , async ( ) => {
1103+ const { PgPoolStrategy : DynamicPgPoolStrategy } = await loadPgConnectionModuleWithConfig ( {
1104+ databaseSSLRootCert : '<cert>' ,
1105+ databaseTlsSessionResumption : true ,
1106+ } )
1107+ const { TlsSessionResumptionClient } = await import ( './tls-session-resumption' )
1108+ const DynamicTestablePgPoolStrategy = createDynamicTestablePgPoolStrategy ( DynamicPgPoolStrategy )
1109+ const strategy = new DynamicTestablePgPoolStrategy (
1110+ createPoolStrategySettings ( {
1111+ dbUrl : 'postgres://postgres:postgres@1.2.3.4:5432/postgres' ,
1112+ } )
1113+ )
1114+
1115+ try {
1116+ const pool = strategy . getCurrentPoolForTest ( )
1117+ const ssl = pool . options . ssl as object
1118+
1119+ expect ( ssl ) . toBeDefined ( )
1120+ expect ( pool . options . Client ) . toBe ( TlsSessionResumptionClient )
1121+
1122+ const sessionDescriptor = Object . getOwnPropertyDescriptor ( ssl , 'session' )
1123+ expect ( sessionDescriptor ?. get ) . toBeInstanceOf ( Function )
1124+ expect ( sessionDescriptor ?. enumerable ) . toBe ( true )
1125+ expect ( sessionDescriptor ?. configurable ) . toBe ( true )
1126+ expect ( sessionDescriptor ?. get ?. call ( ssl ) ) . toBeUndefined ( )
1127+
1128+ expect ( Object . getOwnPropertySymbols ( ssl ) ) . toHaveLength ( 1 )
1129+ const tlsConnectOptions = Object . assign ( { } , ssl )
1130+ expect ( Object . getOwnPropertySymbols ( tlsConnectOptions ) ) . toHaveLength ( 0 )
1131+ expect ( Object . prototype . hasOwnProperty . call ( tlsConnectOptions , 'session' ) ) . toBe ( true )
1132+ } finally {
1133+ await strategy . destroy ( )
1134+ }
1135+ } )
1136+
1137+ it ( 'leaves SSL options untouched when the feature flag is disabled' , async ( ) => {
1138+ const { PgPoolStrategy : DynamicPgPoolStrategy } = await loadPgConnectionModuleWithConfig ( {
1139+ databaseSSLRootCert : '<cert>' ,
1140+ databaseTlsSessionResumption : false ,
1141+ } )
1142+ const DynamicTestablePgPoolStrategy = createDynamicTestablePgPoolStrategy ( DynamicPgPoolStrategy )
1143+ const strategy = new DynamicTestablePgPoolStrategy (
1144+ createPoolStrategySettings ( {
1145+ dbUrl : 'postgres://postgres:postgres@1.2.3.4:5432/postgres' ,
1146+ } )
1147+ )
1148+
1149+ try {
1150+ const pool = strategy . getCurrentPoolForTest ( )
1151+ const ssl = pool . options . ssl as object
1152+
1153+ expect ( ssl ) . toBeDefined ( )
1154+ expect ( pool . options . Client ) . toBeUndefined ( )
1155+ expect ( Object . getOwnPropertyDescriptor ( ssl , 'session' ) ) . toBeUndefined ( )
1156+ expect ( Object . getOwnPropertySymbols ( ssl ) ) . toHaveLength ( 0 )
1157+ } finally {
1158+ await strategy . destroy ( )
1159+ }
1160+ } )
1161+
1162+ it ( 'does not install the custom client when SSL settings are absent' , async ( ) => {
1163+ const { PgPoolStrategy : DynamicPgPoolStrategy } = await loadPgConnectionModuleWithConfig ( {
1164+ databaseSSLRootCert : undefined ,
1165+ databaseTlsSessionResumption : true ,
1166+ } )
1167+ const DynamicTestablePgPoolStrategy = createDynamicTestablePgPoolStrategy ( DynamicPgPoolStrategy )
1168+ const strategy = new DynamicTestablePgPoolStrategy ( createPoolStrategySettings ( ) )
1169+
1170+ try {
1171+ const pool = strategy . getCurrentPoolForTest ( )
1172+
1173+ expect ( pool . options . ssl ) . toBeUndefined ( )
1174+ expect ( pool . options . Client ) . toBeUndefined ( )
1175+ } finally {
1176+ await strategy . destroy ( )
1177+ }
1178+ } )
1179+ } )
0 commit comments