@@ -12,67 +12,88 @@ global.WebSocket = class {
1212 }
1313} ;
1414
15+ // --- Capture Request IDs for time sync vs. API calls ---
16+ // We override _getRequestId so that for each API call the first call is used for
17+ // the time sync update and the second call is used for the actual API request.
18+ let capturedTimeSyncRequestId = null ;
19+ let capturedApiRequestId = null ;
20+ const originalGetRequestId = Client . prototype . _getRequestId ;
21+ Client . prototype . _getRequestId = function ( ) {
22+ const id = originalGetRequestId . call ( this ) ;
23+ if ( capturedTimeSyncRequestId === null ) {
24+ capturedTimeSyncRequestId = id ;
25+ } else if ( capturedApiRequestId === null ) {
26+ capturedApiRequestId = id ;
27+ }
28+ return id ;
29+ } ;
30+
1531/**
1632 * Helper function to run an API method with time sync enabled and then disabled.
17- * It forces an update (by setting lastTimeRequest to an old value) before each call.
18- * The simulateResponse callback simulates the corresponding response by calling _parseMessage.
33+ * It forces a time update (by setting lastTimeRequest to an old value) before each call.
34+ * The simulateResponse callback simulates the corresponding responses by calling _parseMessage.
35+ * The callback receives two parameters: timeSyncRequestId and apiRequestId.
1936 */
2037async function runThrough ( methodName , callFunc , simulateResponse ) {
38+ // Reset captured IDs for this run.
39+ capturedTimeSyncRequestId = null ;
40+ capturedApiRequestId = null ;
41+
2142 console . log ( `\n=== Running ${ methodName } with time sync ENABLED ===` ) ;
22- // Force a time update by setting lastTimeRequest to an old value .
43+ // Force a time update.
2344 client . lastTimeRequest = Date . now ( ) / 1000 - 20 ;
2445 // Call the API method.
2546 callFunc ( ) ;
26- // Simulate a response if needed.
27- if ( simulateResponse ) simulateResponse ( ) ;
28- // Wait longer for the time sync update to complete.
47+ // Allow the _getRequestId calls to occur.
48+ await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
49+ // Simulate two responses: first for the time sync update, then for the API response.
50+ if ( simulateResponse ) simulateResponse ( capturedTimeSyncRequestId , capturedApiRequestId ) ;
51+ // Wait for responses to be processed.
2952 await new Promise ( resolve => setTimeout ( resolve , 300 ) ) ;
3053 console . log ( `${ methodName } -> timeDiff: ${ client . timeDiff . toFixed ( 6 ) } sec` ) ;
3154
3255 // Now disable time sync.
33- // Clear any pending time requests so they don't update timeDiff later.
3456 client . storedPromises = { } ;
3557 client . setEnableTimeSync ( false ) ;
3658 console . log ( `\n=== Running ${ methodName } with time sync DISABLED ===` ) ;
3759 const previousTimeDiff = client . timeDiff ;
3860 client . lastTimeRequest = Date . now ( ) / 1000 - 20 ;
61+ // Reset captured IDs for the disabled run.
62+ capturedTimeSyncRequestId = null ;
63+ capturedApiRequestId = null ;
3964 callFunc ( ) ;
40- // When time sync is disabled, do NOT simulate a response.
65+ // When time sync is disabled, do NOT simulate a time sync response.
4166 await new Promise ( resolve => setTimeout ( resolve , 300 ) ) ;
4267 console . log ( `${ methodName } -> timeDiff: ${ client . timeDiff . toFixed ( 6 ) } sec (should remain ${ previousTimeDiff . toFixed ( 6 ) } sec)` ) ;
4368 // Re-enable time sync for subsequent tests.
4469 client . setEnableTimeSync ( true ) ;
4570}
4671
4772async function runTest ( ) {
48- // Create a new client instance with only endpoint and autoReconnect .
73+ // Create a new client instance.
4974 client = new Client ( '127.0.0.1:17000' , true ) ;
5075
51- // Override _sendTimeRequest to simulate an immediate server time response with variable delay.
76+ // Override _sendTimeRequest to simulate a server time response with variable delay.
5277 client . _sendTimeRequest = function ( requestId ) {
5378 console . log ( `_sendTimeRequest called with requestId: ${ requestId } ` ) ;
54- // Simulate variable network delay (e.g., 50 to 300ms)
5579 const delay = Math . floor ( Math . random ( ) * 250 ) + 50 ;
5680 setTimeout ( ( ) => {
57- // Simulate a server timestamp in nanoseconds.
5881 const simulatedTimestamp = Date . now ( ) * 1e6 ;
5982 console . log ( `Simulated timestamp for request ${ requestId } after ${ delay } ms: ${ simulatedTimestamp } ` ) ;
60- if ( client . storedPromises [ requestId ] ) {
61- client . storedPromises [ requestId ] . resolve ( simulatedTimestamp ) ;
62- delete client . storedPromises [ requestId ] ;
83+ if ( this . storedPromises [ requestId ] ) {
84+ this . storedPromises [ requestId ] . resolve ( simulatedTimestamp ) ;
85+ delete this . storedPromises [ requestId ] ;
6386 }
6487 } , delay ) ;
6588 } ;
6689
67- // Override _updateTimeDiff to perform one measurement and log its details .
90+ // Override _updateTimeDiff to log the measurement .
6891 client . _updateTimeDiff = function ( ) {
6992 if ( ! this . enableTimeSync ) return ;
7093 const requestId = this . _getRequestId ( ) ;
7194 const timeSent = Date . now ( ) / 1000 ;
72- // Call _requestTime (which now calls our overridden _sendTimeRequest).
7395 this . _requestTime ( requestId )
7496 . then ( timestamp => {
75- // Simulate a time response arriving.
7697 this . timeReceived = Date . now ( ) / 1000 ;
7798 const roundTripTime = this . timeReceived - timeSent ;
7899 const serverTime = ( timestamp / 1e9 ) + roundTripTime / 2 ;
@@ -88,46 +109,73 @@ async function runTest() {
88109 . catch ( err => console . error ( err ) ) ;
89110 } ;
90111
91- // Use the production _requestTime (which already checks enableTimeSync).
92- // No override needed here.
93-
94- // Now run through several public API methods.
112+ // Run tests for each public API method.
95113 await runThrough (
96114 "requestApiVersion" ,
97115 ( ) => client . requestApiVersion ( ) ,
98- ( ) => {
99- // Simulate a valid API version response.
100- const response = fakeData . createApiVersionResponse ( ) ;
101- client . _parseMessage ( response ) ;
116+ ( timeSyncId , apiId ) => {
117+ // Simulate time sync response.
118+ const timeResponse = {
119+ messageType : fakeData . Container . Type . eTimeResponse ,
120+ timeResponse : { requestId : timeSyncId , timestamp : Date . now ( ) * 1e6 }
121+ } ;
122+ client . _parseMessage ( timeResponse ) ;
123+ // Simulate API version response.
124+ const apiResponse = fakeData . createApiVersionResponse ( apiId ) ;
125+ client . _parseMessage ( apiResponse ) ;
102126 }
103127 ) ;
104128
105129 await runThrough (
106130 "requestLogLimits" ,
107131 ( ) => client . requestLogLimits ( ) ,
108- ( ) => {
109- const response = fakeData . createLogLimitsResponse ( ) ;
110- client . _parseMessage ( response ) ;
132+ ( timeSyncId , apiId ) => {
133+ const timeResponse = {
134+ messageType : fakeData . Container . Type . eTimeResponse ,
135+ timeResponse : { requestId : timeSyncId , timestamp : Date . now ( ) * 1e6 }
136+ } ;
137+ client . _parseMessage ( timeResponse ) ;
138+ const apiResponse = fakeData . createLogLimitsResponse ( apiId ) ;
139+ client . _parseMessage ( apiResponse ) ;
111140 }
112141 ) ;
113142
114143 await runThrough (
115144 "requestLoggedNodes" ,
116145 ( ) => client . requestLoggedNodes ( ) ,
117- ( ) => {
118- const response = fakeData . createLoggedNodesResponse ( 1 ) ;
119- client . _parseMessage ( response ) ;
146+ ( timeSyncId , apiId ) => {
147+ const timeResponse = {
148+ messageType : fakeData . Container . Type . eTimeResponse ,
149+ timeResponse : { requestId : timeSyncId , timestamp : Date . now ( ) * 1e6 }
150+ } ;
151+ client . _parseMessage ( timeResponse ) ;
152+ const apiResponse = fakeData . createLoggedNodesResponse ( apiId ) ;
153+ client . _parseMessage ( apiResponse ) ;
120154 }
121155 ) ;
122156
157+ // Ensure that the node mapping includes "CPULoad" before calling requestDataPoints.
158+ if ( ! ( "CPULoad" in client . nameToId ) ) {
159+ console . log ( "Mapping missing CPULoad. Simulating logged nodes response to update mapping." ) ;
160+ client . _parseMessage ( fakeData . createLoggedNodesResponse ( 999 ) ) ;
161+ }
162+
123163 await runThrough (
124164 "requestDataPoints" ,
125165 ( ) => client . requestDataPoints ( [ "Output" , "CPULoad" ] , 1531313250.0 , 1531461231.0 , 500 ) ,
126- ( ) => {
127- const response = fakeData . createDataPointResponse ( ) ;
128- client . _parseMessage ( response ) ;
166+ ( timeSyncId , apiId ) => {
167+ const timeResponse = {
168+ messageType : fakeData . Container . Type . eTimeResponse ,
169+ timeResponse : { requestId : timeSyncId , timestamp : Date . now ( ) * 1e6 }
170+ } ;
171+ client . _parseMessage ( timeResponse ) ;
172+ const apiResponse = fakeData . createDataPointResponse ( apiId ) ;
173+ client . _parseMessage ( apiResponse ) ;
129174 }
130175 ) ;
176+
177+ // Disconnect the client to close the open WebSocket and allow the process to exit.
178+ client . disconnect ( ) ;
131179}
132180
133181let client ;
0 commit comments