fable 3.1.69 → 3.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fable",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.71",
|
|
4
4
|
"description": "A service dependency injection, configuration and logging library.",
|
|
5
5
|
"main": "source/Fable.js",
|
|
6
6
|
"scripts": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"homepage": "https://github.com/stevenvelozo/fable",
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"pict-docuserve": "^0.1.5",
|
|
55
|
-
"quackage": "^1.1.
|
|
55
|
+
"quackage": "^1.1.2"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"async.eachlimit": "^0.5.2",
|
|
@@ -27,27 +27,63 @@ class FableServiceRestClient extends libFableServiceBase
|
|
|
27
27
|
// of the request options before they are passed to the request library.
|
|
28
28
|
this.prepareRequestOptions = (pOptions) => { return pOptions; };
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
|
|
30
|
+
// Default per-request timeout (ms). Applied in preRequest when a caller
|
|
31
|
+
// does not supply their own. Node 20+ installs a ~5s socket timeout on
|
|
32
|
+
// http.globalAgent that aborts legitimately long-running requests; any
|
|
33
|
+
// explicit `timeout` on the request options takes that default out of
|
|
34
|
+
// play. See the "Request Timeout" test suite for the behaviors covered.
|
|
35
|
+
if (typeof this.options.RequestTimeout === 'number')
|
|
36
|
+
{
|
|
37
|
+
this.defaultRequestTimeout = this.options.RequestTimeout;
|
|
38
|
+
}
|
|
39
|
+
else if (typeof this.fable.settings.RestClientRequestTimeout === 'number')
|
|
40
|
+
{
|
|
41
|
+
this.defaultRequestTimeout = this.fable.settings.RestClientRequestTimeout;
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
{
|
|
45
|
+
this.defaultRequestTimeout = 60000;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Always install our own http/https agents so every request bypasses
|
|
49
|
+
// http.globalAgent (and its Node 20+ mystery socket timeout). The
|
|
50
|
+
// KeepAlive flag only controls whether keepAlive is enabled on our own
|
|
51
|
+
// agents, not whether we have agents at all. Additional tuning
|
|
52
|
+
// (maxSockets, agent timeout, etc.) flows through KeepAliveAgentOptions.
|
|
53
|
+
let tmpKeepAlive = Boolean(this.options.KeepAlive || this.fable.settings.RestClientKeepAlive);
|
|
54
|
+
let tmpAgentOptions = Object.assign({}, this.options.KeepAliveAgentOptions);
|
|
34
55
|
if (tmpKeepAlive)
|
|
35
56
|
{
|
|
36
|
-
|
|
57
|
+
tmpAgentOptions.keepAlive = true;
|
|
37
58
|
}
|
|
59
|
+
this._installHttpAgents(tmpAgentOptions);
|
|
38
60
|
}
|
|
39
61
|
|
|
40
62
|
/**
|
|
41
63
|
* Initialize HTTP keep-alive agents and wire them into prepareRequestOptions.
|
|
42
|
-
*
|
|
43
|
-
*
|
|
64
|
+
* Back-compat entry point: always forces keepAlive on. Prefer configuring
|
|
65
|
+
* the RestClient via the KeepAlive / KeepAliveAgentOptions constructor
|
|
66
|
+
* options instead of calling this method directly.
|
|
67
|
+
*
|
|
68
|
+
* @param {Object} [pAgentOptions] - Additional options passed to the Http/Https Agent constructors (e.g. timeout).
|
|
44
69
|
*/
|
|
45
|
-
initializeKeepAliveAgent()
|
|
70
|
+
initializeKeepAliveAgent(pAgentOptions)
|
|
46
71
|
{
|
|
47
|
-
let tmpAgentOptions = { keepAlive: true };
|
|
72
|
+
let tmpAgentOptions = Object.assign({ keepAlive: true }, pAgentOptions);
|
|
73
|
+
this._installHttpAgents(tmpAgentOptions);
|
|
74
|
+
}
|
|
48
75
|
|
|
49
|
-
|
|
50
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Construct http/https Agents from the given options and wire them into
|
|
78
|
+
* prepareRequestOptions so every request carries an explicit agent.
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} pAgentOptions - Options passed directly to the Http/Https Agent constructors.
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
_installHttpAgents(pAgentOptions)
|
|
84
|
+
{
|
|
85
|
+
this.httpAgent = new libHttp.Agent(pAgentOptions);
|
|
86
|
+
this.httpsAgent = new libHttps.Agent(pAgentOptions);
|
|
51
87
|
|
|
52
88
|
// Capture any previously set prepareRequestOptions so we can chain
|
|
53
89
|
let tmpPreviousPrepareRequestOptions = this.prepareRequestOptions;
|
|
@@ -101,6 +137,14 @@ class FableServiceRestClient extends libFableServiceBase
|
|
|
101
137
|
tmpOptions.url = this.fable.settings.RestClientURLPrefix + tmpOptions.url;
|
|
102
138
|
}
|
|
103
139
|
|
|
140
|
+
// Apply the default request timeout when the caller hasn't supplied
|
|
141
|
+
// one. Setting any numeric value (including 0) suppresses the Node 20+
|
|
142
|
+
// http.globalAgent ~5s socket timeout.
|
|
143
|
+
if (typeof tmpOptions.timeout !== 'number')
|
|
144
|
+
{
|
|
145
|
+
tmpOptions.timeout = this.defaultRequestTimeout;
|
|
146
|
+
}
|
|
147
|
+
|
|
104
148
|
return this.prepareRequestOptions(tmpOptions);
|
|
105
149
|
}
|
|
106
150
|
|
package/test/RestClient_test.js
CHANGED
|
@@ -148,52 +148,84 @@ suite
|
|
|
148
148
|
|
|
149
149
|
suite
|
|
150
150
|
(
|
|
151
|
-
'
|
|
151
|
+
'HTTP Agent',
|
|
152
152
|
function ()
|
|
153
153
|
{
|
|
154
154
|
test
|
|
155
155
|
(
|
|
156
|
-
'
|
|
156
|
+
'Always installs http/https agents, even when KeepAlive is not set.',
|
|
157
157
|
function ()
|
|
158
158
|
{
|
|
159
|
+
// Without an explicit agent, requests would fall through to
|
|
160
|
+
// http.globalAgent and hit the Node 20+ ~5s socket timeout.
|
|
159
161
|
let testFable = new libFable();
|
|
160
|
-
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {
|
|
162
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-DefaultAgent');
|
|
161
163
|
|
|
162
164
|
Expect(tmpRestClient.httpAgent).to.be.an('object');
|
|
163
165
|
Expect(tmpRestClient.httpsAgent).to.be.an('object');
|
|
166
|
+
Expect(Boolean(tmpRestClient.httpAgent.keepAlive)).to.equal(false);
|
|
167
|
+
Expect(Boolean(tmpRestClient.httpsAgent.keepAlive)).to.equal(false);
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
test
|
|
171
|
+
(
|
|
172
|
+
'Enables keepAlive on agents when KeepAlive option is set.',
|
|
173
|
+
function ()
|
|
174
|
+
{
|
|
175
|
+
let testFable = new libFable();
|
|
176
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', { KeepAlive: true }, 'RestClient-KeepAlive-Options');
|
|
177
|
+
|
|
164
178
|
Expect(tmpRestClient.httpAgent.keepAlive).to.equal(true);
|
|
165
179
|
Expect(tmpRestClient.httpsAgent.keepAlive).to.equal(true);
|
|
166
180
|
}
|
|
167
181
|
);
|
|
168
182
|
test
|
|
169
183
|
(
|
|
170
|
-
'
|
|
184
|
+
'Enables keepAlive on agents via fable settings.',
|
|
171
185
|
function ()
|
|
172
186
|
{
|
|
173
187
|
let testFable = new libFable({ RestClientKeepAlive: true });
|
|
174
188
|
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-KeepAlive-Settings');
|
|
175
189
|
|
|
176
|
-
Expect(tmpRestClient.httpAgent).to.be.an('object');
|
|
177
|
-
Expect(tmpRestClient.httpsAgent).to.be.an('object');
|
|
178
190
|
Expect(tmpRestClient.httpAgent.keepAlive).to.equal(true);
|
|
179
191
|
Expect(tmpRestClient.httpsAgent.keepAlive).to.equal(true);
|
|
180
192
|
}
|
|
181
193
|
);
|
|
182
194
|
test
|
|
183
195
|
(
|
|
184
|
-
'
|
|
196
|
+
'Passes additional agent options through KeepAliveAgentOptions.',
|
|
185
197
|
function ()
|
|
186
198
|
{
|
|
187
199
|
let testFable = new libFable();
|
|
188
|
-
let tmpRestClient = testFable.instantiateServiceProvider('RestClient',
|
|
200
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient',
|
|
201
|
+
{
|
|
202
|
+
KeepAlive: true,
|
|
203
|
+
KeepAliveAgentOptions: { timeout: 300000, maxSockets: 32 }
|
|
204
|
+
}, 'RestClient-KeepAlive-AgentOpts');
|
|
189
205
|
|
|
190
|
-
Expect(tmpRestClient.httpAgent).to.equal(
|
|
191
|
-
Expect(tmpRestClient.
|
|
206
|
+
Expect(tmpRestClient.httpAgent.keepAlive).to.equal(true);
|
|
207
|
+
Expect(tmpRestClient.httpAgent.options.timeout).to.equal(300000);
|
|
208
|
+
Expect(tmpRestClient.httpAgent.options.maxSockets).to.equal(32);
|
|
209
|
+
Expect(tmpRestClient.httpsAgent.options.timeout).to.equal(300000);
|
|
192
210
|
}
|
|
193
211
|
);
|
|
194
212
|
test
|
|
195
213
|
(
|
|
196
|
-
'
|
|
214
|
+
'KeepAliveAgentOptions apply even when KeepAlive is not enabled.',
|
|
215
|
+
function ()
|
|
216
|
+
{
|
|
217
|
+
// Tuning options still flow through when keepAlive is off.
|
|
218
|
+
let testFable = new libFable();
|
|
219
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient',
|
|
220
|
+
{ KeepAliveAgentOptions: { maxSockets: 8 } }, 'RestClient-AgentOpts-NoKeepAlive');
|
|
221
|
+
|
|
222
|
+
Expect(Boolean(tmpRestClient.httpAgent.keepAlive)).to.equal(false);
|
|
223
|
+
Expect(tmpRestClient.httpAgent.options.maxSockets).to.equal(8);
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
test
|
|
227
|
+
(
|
|
228
|
+
'Injects the http agent on http:// URLs.',
|
|
197
229
|
function (fTestComplete)
|
|
198
230
|
{
|
|
199
231
|
var tmpServer = libHTTP.createServer(function (pReq, pRes)
|
|
@@ -206,9 +238,8 @@ suite
|
|
|
206
238
|
{
|
|
207
239
|
var tmpPort = tmpServer.address().port;
|
|
208
240
|
var testFable = new libFable();
|
|
209
|
-
var tmpRestClient = testFable.instantiateServiceProvider('RestClient', {
|
|
241
|
+
var tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-AgentInject-HTTP');
|
|
210
242
|
|
|
211
|
-
// Wrap prepareRequestOptions to capture the final options
|
|
212
243
|
var tmpOriginalPrepare = tmpRestClient.prepareRequestOptions;
|
|
213
244
|
var tmpCapturedAgent = null;
|
|
214
245
|
tmpRestClient.prepareRequestOptions = function (pOptions)
|
|
@@ -222,7 +253,6 @@ suite
|
|
|
222
253
|
function (pError, pResponse, pBody)
|
|
223
254
|
{
|
|
224
255
|
Expect(tmpCapturedAgent).to.equal(tmpRestClient.httpAgent);
|
|
225
|
-
Expect(pBody).to.be.an('object');
|
|
226
256
|
Expect(pBody.OK).to.equal(true);
|
|
227
257
|
tmpServer.close();
|
|
228
258
|
fTestComplete();
|
|
@@ -232,7 +262,25 @@ suite
|
|
|
232
262
|
);
|
|
233
263
|
test
|
|
234
264
|
(
|
|
235
|
-
'
|
|
265
|
+
'Selects the https agent for https:// URLs.',
|
|
266
|
+
function ()
|
|
267
|
+
{
|
|
268
|
+
// We don't need a live HTTPS server to verify the selection
|
|
269
|
+
// logic — invoke prepareRequestOptions directly and inspect
|
|
270
|
+
// which agent was chosen.
|
|
271
|
+
let testFable = new libFable();
|
|
272
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-AgentInject-HTTPS');
|
|
273
|
+
|
|
274
|
+
let tmpHttps = tmpRestClient.prepareRequestOptions({ url: 'https://example.com/x' });
|
|
275
|
+
let tmpHttp = tmpRestClient.prepareRequestOptions({ url: 'http://example.com/x' });
|
|
276
|
+
|
|
277
|
+
Expect(tmpHttps.agent).to.equal(tmpRestClient.httpsAgent);
|
|
278
|
+
Expect(tmpHttp.agent).to.equal(tmpRestClient.httpAgent);
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
test
|
|
282
|
+
(
|
|
283
|
+
'Chains with previously set prepareRequestOptions.',
|
|
236
284
|
function (fTestComplete)
|
|
237
285
|
{
|
|
238
286
|
var tmpServer = libHTTP.createServer(function (pReq, pRes)
|
|
@@ -247,13 +295,10 @@ suite
|
|
|
247
295
|
var testFable = new libFable();
|
|
248
296
|
var tmpRestClient = testFable.instantiateServiceProvider('RestClient', { KeepAlive: true }, 'RestClient-KeepAlive-Chain');
|
|
249
297
|
|
|
250
|
-
|
|
251
|
-
var tmpKeepAlivePrepare = tmpRestClient.prepareRequestOptions;
|
|
298
|
+
var tmpInstalledPrepare = tmpRestClient.prepareRequestOptions;
|
|
252
299
|
tmpRestClient.prepareRequestOptions = function (pOptions)
|
|
253
300
|
{
|
|
254
|
-
|
|
255
|
-
let tmpResult = tmpKeepAlivePrepare(pOptions);
|
|
256
|
-
// Then add custom header
|
|
301
|
+
let tmpResult = tmpInstalledPrepare(pOptions);
|
|
257
302
|
if (!tmpResult.headers)
|
|
258
303
|
{
|
|
259
304
|
tmpResult.headers = {};
|
|
@@ -265,7 +310,6 @@ suite
|
|
|
265
310
|
tmpRestClient.getJSON('http://localhost:' + tmpPort + '/test',
|
|
266
311
|
function (pError, pResponse, pBody)
|
|
267
312
|
{
|
|
268
|
-
Expect(pBody).to.be.an('object');
|
|
269
313
|
Expect(pBody.CustomHeader).to.equal('test-value');
|
|
270
314
|
tmpServer.close();
|
|
271
315
|
fTestComplete();
|
|
@@ -273,6 +317,165 @@ suite
|
|
|
273
317
|
});
|
|
274
318
|
}
|
|
275
319
|
);
|
|
320
|
+
test
|
|
321
|
+
(
|
|
322
|
+
'initializeKeepAliveAgent remains a back-compat entry point.',
|
|
323
|
+
function ()
|
|
324
|
+
{
|
|
325
|
+
let testFable = new libFable();
|
|
326
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-BackCompat');
|
|
327
|
+
|
|
328
|
+
// Default constructor: no keepAlive
|
|
329
|
+
Expect(Boolean(tmpRestClient.httpAgent.keepAlive)).to.equal(false);
|
|
330
|
+
|
|
331
|
+
// Calling the legacy method flips keepAlive on
|
|
332
|
+
tmpRestClient.initializeKeepAliveAgent({ maxSockets: 4 });
|
|
333
|
+
Expect(tmpRestClient.httpAgent.keepAlive).to.equal(true);
|
|
334
|
+
Expect(tmpRestClient.httpAgent.options.maxSockets).to.equal(4);
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
suite
|
|
341
|
+
(
|
|
342
|
+
'Request Timeout',
|
|
343
|
+
function ()
|
|
344
|
+
{
|
|
345
|
+
// Helper: spin up a local HTTP server that never responds so we can
|
|
346
|
+
// verify that the simple-get 'Request timed out' path fires on our
|
|
347
|
+
// configured timeout rather than any ambient http.globalAgent default.
|
|
348
|
+
var createHangingServer = function (fOnListen)
|
|
349
|
+
{
|
|
350
|
+
var tmpServer = libHTTP.createServer(function (pReq, pRes)
|
|
351
|
+
{
|
|
352
|
+
// Intentionally never write or end the response
|
|
353
|
+
});
|
|
354
|
+
tmpServer.listen(0, function ()
|
|
355
|
+
{
|
|
356
|
+
fOnListen(tmpServer, tmpServer.address().port);
|
|
357
|
+
});
|
|
358
|
+
return tmpServer;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
test
|
|
362
|
+
(
|
|
363
|
+
'Applies the library default timeout (60000ms) when none is supplied.',
|
|
364
|
+
function ()
|
|
365
|
+
{
|
|
366
|
+
let testFable = new libFable();
|
|
367
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-DefaultTimeout');
|
|
368
|
+
|
|
369
|
+
Expect(tmpRestClient.defaultRequestTimeout).to.equal(60000);
|
|
370
|
+
|
|
371
|
+
let tmpPrepared = tmpRestClient.preRequest({ url: 'http://example.com/x', method: 'GET' });
|
|
372
|
+
Expect(tmpPrepared.timeout).to.equal(60000);
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
test
|
|
376
|
+
(
|
|
377
|
+
'RequestTimeout constructor option overrides the library default.',
|
|
378
|
+
function ()
|
|
379
|
+
{
|
|
380
|
+
let testFable = new libFable();
|
|
381
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', { RequestTimeout: 60000 }, 'RestClient-OptTimeout');
|
|
382
|
+
|
|
383
|
+
Expect(tmpRestClient.defaultRequestTimeout).to.equal(60000);
|
|
384
|
+
|
|
385
|
+
let tmpPrepared = tmpRestClient.preRequest({ url: 'http://example.com/x', method: 'GET' });
|
|
386
|
+
Expect(tmpPrepared.timeout).to.equal(60000);
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
test
|
|
390
|
+
(
|
|
391
|
+
'RestClientRequestTimeout fable setting overrides the library default.',
|
|
392
|
+
function ()
|
|
393
|
+
{
|
|
394
|
+
let testFable = new libFable({ RestClientRequestTimeout: 45000 });
|
|
395
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-SettingTimeout');
|
|
396
|
+
|
|
397
|
+
Expect(tmpRestClient.defaultRequestTimeout).to.equal(45000);
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
test
|
|
401
|
+
(
|
|
402
|
+
'Constructor option takes precedence over fable setting.',
|
|
403
|
+
function ()
|
|
404
|
+
{
|
|
405
|
+
let testFable = new libFable({ RestClientRequestTimeout: 45000 });
|
|
406
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', { RequestTimeout: 15000 }, 'RestClient-TimeoutPrecedence');
|
|
407
|
+
|
|
408
|
+
Expect(tmpRestClient.defaultRequestTimeout).to.equal(15000);
|
|
409
|
+
}
|
|
410
|
+
);
|
|
411
|
+
test
|
|
412
|
+
(
|
|
413
|
+
'Caller-supplied timeout on the request options is preserved.',
|
|
414
|
+
function ()
|
|
415
|
+
{
|
|
416
|
+
let testFable = new libFable();
|
|
417
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-CallerTimeout');
|
|
418
|
+
|
|
419
|
+
let tmpPrepared = tmpRestClient.preRequest({ url: 'http://example.com/x', method: 'GET', timeout: 1234 });
|
|
420
|
+
Expect(tmpPrepared.timeout).to.equal(1234);
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
test
|
|
424
|
+
(
|
|
425
|
+
'Explicit timeout of 0 on the request options is preserved.',
|
|
426
|
+
function ()
|
|
427
|
+
{
|
|
428
|
+
// 0 is a valid numeric value — it signals "override the mystery
|
|
429
|
+
// default with no timeout" and must not be replaced.
|
|
430
|
+
let testFable = new libFable();
|
|
431
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {}, 'RestClient-ZeroTimeout');
|
|
432
|
+
|
|
433
|
+
let tmpPrepared = tmpRestClient.preRequest({ url: 'http://example.com/x', method: 'GET', timeout: 0 });
|
|
434
|
+
Expect(tmpPrepared.timeout).to.equal(0);
|
|
435
|
+
}
|
|
436
|
+
);
|
|
437
|
+
test
|
|
438
|
+
(
|
|
439
|
+
'RequestTimeout value of 0 is honored.',
|
|
440
|
+
function ()
|
|
441
|
+
{
|
|
442
|
+
let testFable = new libFable();
|
|
443
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', { RequestTimeout: 0 }, 'RestClient-ZeroOptTimeout');
|
|
444
|
+
|
|
445
|
+
Expect(tmpRestClient.defaultRequestTimeout).to.equal(0);
|
|
446
|
+
|
|
447
|
+
let tmpPrepared = tmpRestClient.preRequest({ url: 'http://example.com/x', method: 'GET' });
|
|
448
|
+
Expect(tmpPrepared.timeout).to.equal(0);
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
test
|
|
452
|
+
(
|
|
453
|
+
'A short RequestTimeout actually aborts a hanging request.',
|
|
454
|
+
function (fTestComplete)
|
|
455
|
+
{
|
|
456
|
+
this.timeout(5000);
|
|
457
|
+
var tmpServer;
|
|
458
|
+
tmpServer = createHangingServer(function (pServer, pPort)
|
|
459
|
+
{
|
|
460
|
+
var testFable = new libFable();
|
|
461
|
+
var tmpRestClient = testFable.instantiateServiceProvider('RestClient', { RequestTimeout: 300 }, 'RestClient-LiveTimeout');
|
|
462
|
+
|
|
463
|
+
var tmpStart = Date.now();
|
|
464
|
+
tmpRestClient.getJSON('http://localhost:' + pPort + '/hangs',
|
|
465
|
+
function (pError, pResponse, pBody)
|
|
466
|
+
{
|
|
467
|
+
var tmpElapsed = Date.now() - tmpStart;
|
|
468
|
+
Expect(pError).to.be.an.instanceof(Error);
|
|
469
|
+
Expect(pError.message).to.contain('timed out');
|
|
470
|
+
// Guard against the Node 20+ ~5s globalAgent timeout
|
|
471
|
+
// silently beating our 300ms setting.
|
|
472
|
+
Expect(tmpElapsed).to.be.lessThan(2500);
|
|
473
|
+
pServer.close();
|
|
474
|
+
fTestComplete();
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
);
|
|
276
479
|
}
|
|
277
480
|
);
|
|
278
481
|
|