1+ 'use strict' ;
2+
3+ const assert = require ( 'assert' ) ;
4+ // Corrected path based on file structure: ../common.test.cjs
5+ // const {test} = require('../common.test.cjs');
6+ const { test } = require ( 'poku' ) ;
7+ const mysql = require ( '../..' ) ;
8+ const process = require ( 'process' ) ; // Ensure process is available
9+
10+ // Helper function to create a pool using test environment variables
11+ function createTestPool ( options ) {
12+ const config = {
13+ host : process . env . MYSQL_HOST ,
14+ user : process . env . MYSQL_USER ,
15+ password : process . env . MYSQL_PASSWORD ,
16+ database : process . env . MYSQL_DATABASE ,
17+ ...options ,
18+ } ;
19+ return mysql . createPool ( config ) ;
20+ }
21+
22+ // --- Test Case ---
23+
24+ test ( 'Pool emits connectionQueueAcquired event and reports correct queue depth' , function ( done ) {
25+ // 1. Setup Pool: Small limit to force queuing
26+ const connectionLimit = 2 ;
27+ const pool = createTestPool ( {
28+ connectionLimit : connectionLimit ,
29+ waitForConnections : true ,
30+ queueLimit : 0 , // No queue limit
31+ } ) ;
32+
33+ let acquiredConnections = [ ] ;
34+ let queuedAcquiredEvents = [ ] ;
35+ const expectedQueueDepths = [ 1 , 0 ] ; // Expected depth after 1st dequeue, then 2nd
36+
37+ // 2. Listen for the new event
38+ pool . on ( 'connectionQueueAcquired' , ( event ) => {
39+ queuedAcquiredEvents . push ( event ) ;
40+ } ) ;
41+
42+ // Helper to get a connection and wrap it in a Promise for control flow
43+ const getConnectionPromise = ( ) => new Promise ( ( resolve , reject ) => {
44+ pool . getConnection ( ( err , conn ) => {
45+ if ( err ) return reject ( err ) ;
46+
47+ // Store initial connections (1 and 2) for later release
48+ // We rely on the order of acquisition for this.
49+ acquiredConnections . push ( conn ) ;
50+
51+ resolve ( conn ) ;
52+ } ) ;
53+ } ) ;
54+
55+ // --- Execution Flow using Promises for reliability ---
56+
57+ let initialConnection1 ;
58+ let initialConnection2 ;
59+
60+ // 1 & 2. Saturate the pool (Acquire 2 connections)
61+ Promise . all ( [
62+ getConnectionPromise ( ) . then ( c => initialConnection1 = c ) ,
63+ getConnectionPromise ( ) . then ( c => initialConnection2 = c )
64+ ] )
65+ . then ( ( ) => {
66+ // 3 & 4. Queue requests (Request 2 more connections, they must wait)
67+ // These will use the general callback logic below
68+ pool . getConnection ( queuedConnectionCallback ) ;
69+ pool . getConnection ( queuedConnectionCallback ) ;
70+
71+ // Give time for the requests to enter the queue before releasing connections
72+ return new Promise ( r => setTimeout ( r , 50 ) ) ;
73+ } )
74+ . then ( ( ) => {
75+ // 5. Trigger Dequeue: Release the initial active connections
76+ // This is safe because the Promise.all ensures initialConnection1/2 are defined.
77+
78+ // Release 1: serves Queued Request 3 (event fired, depth 1)
79+ initialConnection1 . release ( ) ;
80+
81+ // Release 2: serves Queued Request 4 (event fired, depth 0)
82+ initialConnection2 . release ( ) ;
83+
84+ // Wait for the final two queued connections to be acquired and their callbacks to run
85+ return new Promise ( r => setTimeout ( r , 100 ) ) ;
86+ } )
87+ . then ( ( ) => {
88+ // Final Assertions and Cleanup (after all acquisitions are complete)
89+ assert . strictEqual ( queuedAcquiredEvents . length , 2 , 'Should have emitted connectionQueueAcquired exactly twice.' ) ;
90+
91+ queuedAcquiredEvents . forEach ( ( event , index ) => {
92+ const expectedDepth = expectedQueueDepths [ index ] ;
93+ assert . strictEqual (
94+ event . queueDepth ,
95+ expectedDepth ,
96+ `Event ${ index + 1 } reported queueDepth ${ event . queueDepth } , expected ${ expectedDepth } .`
97+ ) ;
98+ assert . ok ( event . connection , `Event ${ index + 1 } is missing the connection object.` ) ;
99+
100+ // Release connections acquired from the queue
101+ event . connection . release ( ) ;
102+ } ) ;
103+
104+ pool . end ( done ) ;
105+ } )
106+ . catch ( err => {
107+ pool . end ( ( ) => done ( err ) ) ;
108+ } ) ;
109+ } ) ;
110+
111+ // For the purposes of this test, we don't need the queued connections to be stored,
112+ // as they are handled and released inside the final Promise block via the event payload.
113+ function queuedConnectionCallback ( err , conn ) {
114+ if ( err ) throw err
115+ }
116+
0 commit comments