@artilleryio/int-core 2.21.0-28fec46 → 2.21.0-307585f
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/index.js +11 -13
- package/lib/engine_http.js +78 -111
- package/lib/engine_socketio.js +60 -76
- package/lib/engine_ws.js +34 -45
- package/lib/phases.js +18 -20
- package/lib/readers.js +5 -9
- package/lib/runner.js +43 -45
- package/lib/ssms.js +5 -9
- package/lib/weighted-pick.js +10 -18
- package/package.json +4 -4
- package/.eslintrc +0 -46
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const EventEmitter = require('events');
|
|
1
|
+
const EventEmitter = require('node:events');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
|
|
4
4
|
// NOTE: This may be called more than once, and so should be non-destructive
|
|
@@ -10,7 +10,7 @@ async function updateGlobalObject(opts = {}) {
|
|
|
10
10
|
typeof process.env.ARTILLERY_EXTENDED_HTTP_METRICS !== 'undefined';
|
|
11
11
|
|
|
12
12
|
global.artillery.metrics = global.artillery.metrics || {};
|
|
13
|
-
global.artillery.metrics.event = async
|
|
13
|
+
global.artillery.metrics.event = async (msg, opts) => {
|
|
14
14
|
if (opts.level === 'error') {
|
|
15
15
|
console.log(chalk.red(msg));
|
|
16
16
|
} else {
|
|
@@ -34,7 +34,7 @@ async function updateGlobalObject(opts = {}) {
|
|
|
34
34
|
this.extensionEvents.push(event);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
if (!global.artillery
|
|
37
|
+
if (!Object.hasOwn(global.artillery, 'globalEvents')) {
|
|
38
38
|
Object.defineProperty(global.artillery, 'globalEvents', {
|
|
39
39
|
value: new EventEmitter()
|
|
40
40
|
});
|
|
@@ -42,7 +42,7 @@ async function updateGlobalObject(opts = {}) {
|
|
|
42
42
|
|
|
43
43
|
global.artillery.__SSMS = require('./lib/ssms').SSMS;
|
|
44
44
|
|
|
45
|
-
if (!global.artillery
|
|
45
|
+
if (!Object.hasOwn(global.artillery, 'suggestedExitCode')) {
|
|
46
46
|
Object.defineProperty(global.artillery, 'suggestedExitCode', {
|
|
47
47
|
get() {
|
|
48
48
|
return global.artillery._exitCode;
|
|
@@ -61,19 +61,17 @@ async function updateGlobalObject(opts = {}) {
|
|
|
61
61
|
|
|
62
62
|
global.artillery.logger =
|
|
63
63
|
global.artillery.logger ||
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
log
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
};
|
|
70
|
-
};
|
|
64
|
+
((opts) => ({
|
|
65
|
+
log: (...args) => {
|
|
66
|
+
global.artillery.globalEvents.emit('log', opts, ...args);
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
71
69
|
|
|
72
70
|
global.artillery.log =
|
|
73
71
|
global.artillery.log ||
|
|
74
|
-
|
|
72
|
+
((...args) => {
|
|
75
73
|
global.artillery.globalEvents.emit('log', {}, ...args);
|
|
76
|
-
};
|
|
74
|
+
});
|
|
77
75
|
|
|
78
76
|
if (opts.version) {
|
|
79
77
|
global.artillery.version = opts.version;
|
package/lib/engine_http.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
4
|
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
5
|
const async = require('async');
|
|
8
6
|
const _ = require('lodash');
|
|
9
7
|
const request = require('got');
|
|
@@ -15,16 +13,16 @@ const USER_AGENT = 'Artillery (https://artillery.io)';
|
|
|
15
13
|
const engineUtil = require('@artilleryio/int-commons').engine_util;
|
|
16
14
|
const ensurePropertyIsAList = engineUtil.ensurePropertyIsAList;
|
|
17
15
|
const template = engineUtil.template;
|
|
18
|
-
const qs = require('querystring');
|
|
16
|
+
const qs = require('node:querystring');
|
|
19
17
|
const filtrex = require('filtrex');
|
|
20
|
-
const urlparse = require('url').parse;
|
|
18
|
+
const urlparse = require('node:url').parse;
|
|
21
19
|
const FormData = require('form-data');
|
|
22
20
|
const HttpAgent = require('agentkeepalive');
|
|
23
21
|
const { HttpsAgent } = HttpAgent;
|
|
24
22
|
const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
|
|
25
23
|
const decompressResponse = require('decompress-response');
|
|
26
|
-
const fs = require('fs');
|
|
27
|
-
const path = require('path');
|
|
24
|
+
const fs = require('node:fs');
|
|
25
|
+
const path = require('node:path');
|
|
28
26
|
|
|
29
27
|
const { promisify, callbackify } = require('node:util');
|
|
30
28
|
|
|
@@ -101,7 +99,7 @@ function HttpEngine(script) {
|
|
|
101
99
|
// That's done when the VU is initialized.
|
|
102
100
|
|
|
103
101
|
this.maxSockets = Infinity;
|
|
104
|
-
if (script.config.http
|
|
102
|
+
if (script.config.http?.pool) {
|
|
105
103
|
this.maxSockets = Number(script.config.http.pool);
|
|
106
104
|
}
|
|
107
105
|
const agentOpts = Object.assign(DEFAULT_AGENT_OPTIONS, {
|
|
@@ -129,8 +127,6 @@ function HttpEngine(script) {
|
|
|
129
127
|
}
|
|
130
128
|
|
|
131
129
|
HttpEngine.prototype.createScenario = function (scenarioSpec, ee) {
|
|
132
|
-
var self = this;
|
|
133
|
-
|
|
134
130
|
ensurePropertyIsAList(scenarioSpec, 'beforeRequest');
|
|
135
131
|
ensurePropertyIsAList(scenarioSpec, 'afterResponse');
|
|
136
132
|
ensurePropertyIsAList(scenarioSpec, 'beforeScenario');
|
|
@@ -144,15 +140,11 @@ HttpEngine.prototype.createScenario = function (scenarioSpec, ee) {
|
|
|
144
140
|
// entire scenario spec rather than just the userContext.
|
|
145
141
|
const beforeScenarioFns = _.map(
|
|
146
142
|
scenarioSpec.beforeScenario,
|
|
147
|
-
|
|
148
|
-
return { function: hookFunctionName };
|
|
149
|
-
}
|
|
143
|
+
(hookFunctionName) => ({ function: hookFunctionName })
|
|
150
144
|
);
|
|
151
145
|
const afterScenarioFns = _.map(
|
|
152
146
|
scenarioSpec.afterScenario,
|
|
153
|
-
|
|
154
|
-
return { function: hookFunctionName };
|
|
155
|
-
}
|
|
147
|
+
(hookFunctionName) => ({ function: hookFunctionName })
|
|
156
148
|
);
|
|
157
149
|
|
|
158
150
|
const newFlow = beforeScenarioFns.concat(
|
|
@@ -161,26 +153,24 @@ HttpEngine.prototype.createScenario = function (scenarioSpec, ee) {
|
|
|
161
153
|
|
|
162
154
|
scenarioSpec.flow = newFlow;
|
|
163
155
|
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
const tasks = _.map(scenarioSpec.flow, (rs) =>
|
|
157
|
+
this.step(rs, ee, {
|
|
166
158
|
beforeRequest: scenarioSpec.beforeRequest,
|
|
167
159
|
afterResponse: scenarioSpec.afterResponse,
|
|
168
160
|
onError: scenarioSpec.onError
|
|
169
|
-
})
|
|
170
|
-
|
|
161
|
+
})
|
|
162
|
+
);
|
|
171
163
|
|
|
172
|
-
return
|
|
164
|
+
return this.compile(tasks, scenarioSpec, ee);
|
|
173
165
|
};
|
|
174
166
|
|
|
175
167
|
HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
176
168
|
opts = opts || {};
|
|
177
|
-
|
|
178
|
-
|
|
169
|
+
const self = this;
|
|
170
|
+
const config = this.config;
|
|
179
171
|
|
|
180
172
|
if (requestSpec.loop) {
|
|
181
|
-
|
|
182
|
-
return self.step(rs, ee, opts);
|
|
183
|
-
});
|
|
173
|
+
const steps = _.map(requestSpec.loop, (rs) => self.step(rs, ee, opts));
|
|
184
174
|
|
|
185
175
|
return engineUtil.createLoopWithCount(requestSpec.count || -1, steps, {
|
|
186
176
|
loopValue: requestSpec.loopValue || '$loopCount',
|
|
@@ -193,9 +183,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
193
183
|
}
|
|
194
184
|
|
|
195
185
|
if (requestSpec.parallel) {
|
|
196
|
-
|
|
197
|
-
return self.step(rs, ee, opts);
|
|
198
|
-
});
|
|
186
|
+
const steps = _.map(requestSpec.parallel, (rs) => self.step(rs, ee, opts));
|
|
199
187
|
|
|
200
188
|
return engineUtil.createParallel(steps, {
|
|
201
189
|
limitValue: requestSpec.limit
|
|
@@ -210,17 +198,17 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
210
198
|
}
|
|
211
199
|
|
|
212
200
|
if (typeof requestSpec.log !== 'undefined') {
|
|
213
|
-
return
|
|
201
|
+
return (context, callback) => {
|
|
214
202
|
console.log(template(requestSpec.log, context));
|
|
215
|
-
return process.nextTick(
|
|
203
|
+
return process.nextTick(() => {
|
|
216
204
|
callback(null, context);
|
|
217
205
|
});
|
|
218
206
|
};
|
|
219
207
|
}
|
|
220
208
|
|
|
221
209
|
if (requestSpec.function) {
|
|
222
|
-
return
|
|
223
|
-
|
|
210
|
+
return (context, callback) => {
|
|
211
|
+
const processFunc = self.config.processor[requestSpec.function];
|
|
224
212
|
if (processFunc) {
|
|
225
213
|
let f;
|
|
226
214
|
if (processFunc.constructor.name === 'Function') {
|
|
@@ -228,23 +216,21 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
228
216
|
} else {
|
|
229
217
|
f = callbackify(processFunc);
|
|
230
218
|
}
|
|
231
|
-
return f(context, ee,
|
|
232
|
-
return callback(hookErr, context);
|
|
233
|
-
});
|
|
219
|
+
return f(context, ee, (hookErr) => callback(hookErr, context));
|
|
234
220
|
} else {
|
|
235
221
|
debug(`Function "${requestSpec.function}" not defined`);
|
|
236
222
|
debug('processor: %o', self.config.processor);
|
|
237
223
|
ee.emit('error', `Undefined function "${requestSpec.function}"`);
|
|
238
|
-
return process.nextTick(
|
|
224
|
+
return process.nextTick(() => {
|
|
239
225
|
callback(null, context);
|
|
240
226
|
});
|
|
241
227
|
}
|
|
242
228
|
};
|
|
243
229
|
}
|
|
244
230
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
231
|
+
const f = (context, callback) => {
|
|
232
|
+
const method = _.keys(requestSpec)[0].toUpperCase();
|
|
233
|
+
const params = requestSpec[method.toLowerCase()];
|
|
248
234
|
|
|
249
235
|
const onErrorHandlers = opts.onError; // only scenario-lever onError handlers are supported
|
|
250
236
|
|
|
@@ -253,15 +239,15 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
253
239
|
// is missing.
|
|
254
240
|
// This will be obsoleted by better script validation.
|
|
255
241
|
if (!params.url && !params.uri) {
|
|
256
|
-
|
|
242
|
+
const err = new Error('an URL must be specified');
|
|
257
243
|
return callback(err, context);
|
|
258
244
|
}
|
|
259
245
|
|
|
260
|
-
|
|
261
|
-
|
|
246
|
+
const tls = config.tls || {};
|
|
247
|
+
const timeout = config.timeout || _.get(config, 'http.timeout') || 10;
|
|
262
248
|
|
|
263
249
|
if (!engineUtil.isProbableEnough(params)) {
|
|
264
|
-
return process.nextTick(
|
|
250
|
+
return process.nextTick(() => {
|
|
265
251
|
callback(null, context);
|
|
266
252
|
});
|
|
267
253
|
}
|
|
@@ -278,7 +264,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
278
264
|
result = 1; // if the expression is incorrect, just proceed
|
|
279
265
|
}
|
|
280
266
|
if (!result) {
|
|
281
|
-
return process.nextTick(
|
|
267
|
+
return process.nextTick(() => {
|
|
282
268
|
callback(null, context);
|
|
283
269
|
});
|
|
284
270
|
}
|
|
@@ -301,7 +287,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
301
287
|
requestParams.https = _.extend(requestParams.https, tls);
|
|
302
288
|
}
|
|
303
289
|
|
|
304
|
-
|
|
290
|
+
const functionNames = _.concat(
|
|
305
291
|
opts.beforeRequest || [],
|
|
306
292
|
params.beforeRequest || []
|
|
307
293
|
);
|
|
@@ -309,17 +295,15 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
309
295
|
async.eachSeries(
|
|
310
296
|
functionNames,
|
|
311
297
|
function iteratee(functionName, next) {
|
|
312
|
-
|
|
298
|
+
const fn = template(functionName, context);
|
|
313
299
|
let processFunc = config.processor[fn];
|
|
314
300
|
if (!processFunc) {
|
|
315
|
-
processFunc =
|
|
316
|
-
return cb(null);
|
|
317
|
-
};
|
|
301
|
+
processFunc = (_r, _c, _e, cb) => cb(null);
|
|
318
302
|
console.log(`WARNING: custom function ${fn} could not be found`); // TODO: a 'warning' event
|
|
319
303
|
}
|
|
320
304
|
|
|
321
305
|
if (processFunc.constructor.name === 'Function') {
|
|
322
|
-
processFunc(requestParams, context, ee,
|
|
306
|
+
processFunc(requestParams, context, ee, (err) => {
|
|
323
307
|
if (err) {
|
|
324
308
|
return next(err);
|
|
325
309
|
}
|
|
@@ -384,7 +368,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
384
368
|
if (params.form) {
|
|
385
369
|
requestParams.form = _.reduce(
|
|
386
370
|
requestParams.form,
|
|
387
|
-
|
|
371
|
+
(acc, v, k) => {
|
|
388
372
|
acc[k] = template(v, context);
|
|
389
373
|
return acc;
|
|
390
374
|
},
|
|
@@ -397,7 +381,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
397
381
|
const f = new FormData();
|
|
398
382
|
requestParams.body = _.reduce(
|
|
399
383
|
requestParams.formData,
|
|
400
|
-
|
|
384
|
+
(acc, v, k) => {
|
|
401
385
|
let V = template(v, context);
|
|
402
386
|
let options;
|
|
403
387
|
if (V && _.isPlainObject(V)) {
|
|
@@ -432,7 +416,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
432
416
|
}
|
|
433
417
|
|
|
434
418
|
// Assign default headers then overwrite as needed
|
|
435
|
-
|
|
419
|
+
const defaultHeaders = lowcaseKeys(
|
|
436
420
|
config.http.defaults.headers ||
|
|
437
421
|
config.defaults.headers || { 'user-agent': USER_AGENT }
|
|
438
422
|
);
|
|
@@ -441,16 +425,13 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
441
425
|
lowcaseKeys(params.headers),
|
|
442
426
|
lowcaseKeys(requestParams.headers)
|
|
443
427
|
);
|
|
444
|
-
const templatedHeaders = _.mapValues(
|
|
445
|
-
|
|
446
|
-
function (v, k, obj) {
|
|
447
|
-
return template(v, context);
|
|
448
|
-
}
|
|
428
|
+
const templatedHeaders = _.mapValues(combinedHeaders, (v, _k, _obj) =>
|
|
429
|
+
template(v, context)
|
|
449
430
|
);
|
|
450
431
|
requestParams.headers = templatedHeaders;
|
|
451
432
|
|
|
452
433
|
// We compute the url here so that the cookies are set properly afterwards
|
|
453
|
-
|
|
434
|
+
const url = maybePrependBase(
|
|
454
435
|
template(requestParams.uri || requestParams.url, context),
|
|
455
436
|
config
|
|
456
437
|
);
|
|
@@ -473,9 +454,9 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
473
454
|
context._defaultCookie,
|
|
474
455
|
requestParams.cookie
|
|
475
456
|
);
|
|
476
|
-
Object.keys(cookie).forEach(
|
|
457
|
+
Object.keys(cookie).forEach((k) => {
|
|
477
458
|
context._jar.setCookieSync(
|
|
478
|
-
k
|
|
459
|
+
`${k}=${template(cookie[k], context)}`,
|
|
479
460
|
requestParams.url
|
|
480
461
|
);
|
|
481
462
|
});
|
|
@@ -496,7 +477,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
496
477
|
requestParams.throwHttpErrors = false;
|
|
497
478
|
|
|
498
479
|
if (!requestParams.url || !requestParams.url.startsWith('http')) {
|
|
499
|
-
|
|
480
|
+
const err = new Error(`Invalid URL - ${requestParams.url}`);
|
|
500
481
|
return callback(err, context);
|
|
501
482
|
}
|
|
502
483
|
|
|
@@ -577,9 +558,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
577
558
|
requestParams,
|
|
578
559
|
context,
|
|
579
560
|
ee,
|
|
580
|
-
|
|
581
|
-
return done(err, context);
|
|
582
|
-
}
|
|
561
|
+
(_asyncErr) => done(err, context)
|
|
583
562
|
);
|
|
584
563
|
}
|
|
585
564
|
|
|
@@ -598,18 +577,20 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
598
577
|
}
|
|
599
578
|
|
|
600
579
|
// match and capture are strict by default:
|
|
601
|
-
haveFailedMatches = _.some(
|
|
602
|
-
|
|
603
|
-
|
|
580
|
+
haveFailedMatches = _.some(
|
|
581
|
+
result.matches,
|
|
582
|
+
(v, _k) => !v.success && v.strict !== false
|
|
583
|
+
);
|
|
604
584
|
|
|
605
|
-
haveFailedCaptures = _.some(
|
|
606
|
-
|
|
607
|
-
|
|
585
|
+
haveFailedCaptures = _.some(
|
|
586
|
+
result.captures,
|
|
587
|
+
(v, _k) => v.failed
|
|
588
|
+
);
|
|
608
589
|
|
|
609
590
|
if (haveFailedMatches || haveFailedCaptures) {
|
|
610
591
|
// TODO: Emit the details of each failed capture/match
|
|
611
592
|
} else {
|
|
612
|
-
_.each(result.matches,
|
|
593
|
+
_.each(result.matches, (v, _k) => {
|
|
613
594
|
ee.emit('match', v.success, {
|
|
614
595
|
expected: v.expected,
|
|
615
596
|
got: v.got,
|
|
@@ -618,27 +599,25 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
618
599
|
});
|
|
619
600
|
});
|
|
620
601
|
|
|
621
|
-
_.each(result.captures,
|
|
602
|
+
_.each(result.captures, (v, k) => {
|
|
622
603
|
_.set(context.vars, k, v.value);
|
|
623
604
|
});
|
|
624
605
|
}
|
|
625
606
|
}
|
|
626
607
|
|
|
627
608
|
// Now run afterResponse processors
|
|
628
|
-
|
|
609
|
+
const functionNames = _.concat(
|
|
629
610
|
opts.afterResponse || [],
|
|
630
611
|
params.afterResponse || []
|
|
631
612
|
);
|
|
632
613
|
async.eachSeries(
|
|
633
614
|
functionNames,
|
|
634
615
|
function iteratee(functionName, next) {
|
|
635
|
-
|
|
616
|
+
const fn = template(functionName, context);
|
|
636
617
|
let processFunc = config.processor[fn];
|
|
637
618
|
if (!processFunc) {
|
|
638
619
|
// TODO: DRY - #223
|
|
639
|
-
processFunc =
|
|
640
|
-
return cb(null);
|
|
641
|
-
};
|
|
620
|
+
processFunc = (_r, _res, _c, _e, cb) => cb(null);
|
|
642
621
|
console.log(
|
|
643
622
|
`WARNING: custom function ${fn} could not be found`
|
|
644
623
|
); // TODO: a 'warning' event
|
|
@@ -648,25 +627,19 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
648
627
|
res.body = body;
|
|
649
628
|
|
|
650
629
|
if (processFunc.constructor.name === 'Function') {
|
|
651
|
-
processFunc(
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
context,
|
|
655
|
-
ee,
|
|
656
|
-
function (err) {
|
|
657
|
-
if (err) {
|
|
658
|
-
return next(err);
|
|
659
|
-
}
|
|
660
|
-
return next(null);
|
|
630
|
+
processFunc(requestParams, res, context, ee, (err) => {
|
|
631
|
+
if (err) {
|
|
632
|
+
return next(err);
|
|
661
633
|
}
|
|
662
|
-
|
|
634
|
+
return next(null);
|
|
635
|
+
});
|
|
663
636
|
} else {
|
|
664
637
|
processFunc(requestParams, res, context, ee)
|
|
665
638
|
.then(next)
|
|
666
639
|
.catch(next);
|
|
667
640
|
}
|
|
668
641
|
},
|
|
669
|
-
|
|
642
|
+
(err) => {
|
|
670
643
|
if (err) {
|
|
671
644
|
debug(err);
|
|
672
645
|
return done(err, context);
|
|
@@ -696,7 +669,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
696
669
|
}
|
|
697
670
|
|
|
698
671
|
if (!requestParams.url) {
|
|
699
|
-
|
|
672
|
+
const err = new Error('an URL must be specified');
|
|
700
673
|
|
|
701
674
|
// Run onError hooks and end the scenario
|
|
702
675
|
runOnErrorHooks(
|
|
@@ -706,9 +679,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
706
679
|
requestParams,
|
|
707
680
|
context,
|
|
708
681
|
ee,
|
|
709
|
-
|
|
710
|
-
return callback(err, context);
|
|
711
|
-
}
|
|
682
|
+
(_asyncErr) => callback(err, context)
|
|
712
683
|
);
|
|
713
684
|
}
|
|
714
685
|
|
|
@@ -716,13 +687,13 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
716
687
|
|
|
717
688
|
let totalDownloaded = 0;
|
|
718
689
|
request(_.omit(requestParams, ['uuid']))
|
|
719
|
-
.on('request',
|
|
690
|
+
.on('request', (req) => {
|
|
720
691
|
ee.emit('trace:http:request', requestParams, requestParams.uuid);
|
|
721
692
|
|
|
722
693
|
debugRequests('request start: %s', req.path);
|
|
723
694
|
ee.emit('counter', 'http.requests', 1);
|
|
724
695
|
ee.emit('rate', 'http.request_rate');
|
|
725
|
-
req.on('response',
|
|
696
|
+
req.on('response', (res) => {
|
|
726
697
|
res.on('end', () => {
|
|
727
698
|
ee.emit('counter', 'http.downloaded_bytes', totalDownloaded);
|
|
728
699
|
});
|
|
@@ -740,7 +711,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
740
711
|
.on('downloadProgress', (progress) => {
|
|
741
712
|
totalDownloaded = progress.total;
|
|
742
713
|
})
|
|
743
|
-
.on('error',
|
|
714
|
+
.on('error', (err, _body, _res) => {
|
|
744
715
|
ee.emit('trace:http:error', err, requestParams.uuid);
|
|
745
716
|
if (err.name === 'HTTPError') {
|
|
746
717
|
return;
|
|
@@ -755,9 +726,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
755
726
|
requestParams,
|
|
756
727
|
context,
|
|
757
728
|
ee,
|
|
758
|
-
|
|
759
|
-
return callback(err, context);
|
|
760
|
-
}
|
|
729
|
+
(_asyncErr) => callback(err, context)
|
|
761
730
|
);
|
|
762
731
|
})
|
|
763
732
|
.catch((gotErr) => {
|
|
@@ -770,9 +739,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
|
|
|
770
739
|
requestParams,
|
|
771
740
|
context,
|
|
772
741
|
ee,
|
|
773
|
-
|
|
774
|
-
return callback(gotErr, context);
|
|
775
|
-
}
|
|
742
|
+
(_asyncErr) => callback(gotErr, context)
|
|
776
743
|
);
|
|
777
744
|
});
|
|
778
745
|
}
|
|
@@ -796,12 +763,12 @@ HttpEngine.prototype._handleResponse = function (
|
|
|
796
763
|
res = decompressResponse(res);
|
|
797
764
|
}
|
|
798
765
|
|
|
799
|
-
|
|
766
|
+
const code = res.statusCode;
|
|
800
767
|
if (!context._enableCookieJar) {
|
|
801
768
|
const rawCookies = res.headers['set-cookie'];
|
|
802
769
|
if (rawCookies) {
|
|
803
770
|
context._enableCookieJar = true;
|
|
804
|
-
rawCookies.forEach(
|
|
771
|
+
rawCookies.forEach((cookieString) => {
|
|
805
772
|
try {
|
|
806
773
|
context._jar.setCookieSync(cookieString, url);
|
|
807
774
|
} catch (err) {
|
|
@@ -815,7 +782,7 @@ HttpEngine.prototype._handleResponse = function (
|
|
|
815
782
|
}
|
|
816
783
|
}
|
|
817
784
|
|
|
818
|
-
ee.emit('counter',
|
|
785
|
+
ee.emit('counter', `http.codes.${code}`, 1);
|
|
819
786
|
ee.emit('counter', 'http.responses', 1);
|
|
820
787
|
// ee.emit('rate', 'http.response_rate');
|
|
821
788
|
ee.emit('histogram', 'http.response_time', res.timings.phases.firstByte);
|
|
@@ -957,8 +924,8 @@ HttpEngine.prototype.setInitialContext = function (initialContext) {
|
|
|
957
924
|
return initialContext;
|
|
958
925
|
};
|
|
959
926
|
|
|
960
|
-
HttpEngine.prototype.compile = function compile(tasks,
|
|
961
|
-
|
|
927
|
+
HttpEngine.prototype.compile = function compile(tasks, _scenarioSpec, ee) {
|
|
928
|
+
const self = this;
|
|
962
929
|
|
|
963
930
|
return async function scenario(initialContext, callback) {
|
|
964
931
|
initialContext = self.setInitialContext(initialContext);
|
|
@@ -989,7 +956,7 @@ function maybePrependBase(uri, config) {
|
|
|
989
956
|
* Given a dictionary, return a dictionary with all keys lowercased.
|
|
990
957
|
*/
|
|
991
958
|
function lowcaseKeys(h) {
|
|
992
|
-
return _.transform(h,
|
|
959
|
+
return _.transform(h, (result, v, k) => {
|
|
993
960
|
result[k.toLowerCase()] = v;
|
|
994
961
|
});
|
|
995
962
|
}
|
|
@@ -1006,8 +973,8 @@ function runOnErrorHooks(
|
|
|
1006
973
|
async.eachSeries(
|
|
1007
974
|
functionNames,
|
|
1008
975
|
function iteratee(functionName, next) {
|
|
1009
|
-
|
|
1010
|
-
processFunc(err, requestParams, context, ee,
|
|
976
|
+
const processFunc = functions[functionName];
|
|
977
|
+
processFunc(err, requestParams, context, ee, (asyncErr) => {
|
|
1011
978
|
if (asyncErr) {
|
|
1012
979
|
return next(asyncErr);
|
|
1013
980
|
}
|