@artilleryio/int-core 2.21.0 → 2.22.0-4c4f409

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 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 function (msg, opts) {
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.hasOwnProperty('globalEvents')) {
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.hasOwnProperty('suggestedExitCode')) {
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
- function (opts) {
65
- return {
66
- log: (...args) => {
67
- global.artillery.globalEvents.emit('log', opts, ...args);
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
- function (...args) {
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;
@@ -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 && script.config.http.pool) {
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
- function (hookFunctionName) {
148
- return { function: hookFunctionName };
149
- }
143
+ (hookFunctionName) => ({ function: hookFunctionName })
150
144
  );
151
145
  const afterScenarioFns = _.map(
152
146
  scenarioSpec.afterScenario,
153
- function (hookFunctionName) {
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
- let tasks = _.map(scenarioSpec.flow, function (rs) {
165
- return self.step(rs, ee, {
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 self.compile(tasks, scenarioSpec, ee);
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
- let self = this;
178
- let config = this.config;
169
+ const self = this;
170
+ const config = this.config;
179
171
 
180
172
  if (requestSpec.loop) {
181
- let steps = _.map(requestSpec.loop, function (rs) {
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
- let steps = _.map(requestSpec.parallel, function (rs) {
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 function (context, callback) {
201
+ return (context, callback) => {
214
202
  console.log(template(requestSpec.log, context));
215
- return process.nextTick(function () {
203
+ return process.nextTick(() => {
216
204
  callback(null, context);
217
205
  });
218
206
  };
219
207
  }
220
208
 
221
209
  if (requestSpec.function) {
222
- return function (context, callback) {
223
- let processFunc = self.config.processor[requestSpec.function];
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, function (hookErr) {
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(function () {
224
+ return process.nextTick(() => {
239
225
  callback(null, context);
240
226
  });
241
227
  }
242
228
  };
243
229
  }
244
230
 
245
- let f = function (context, callback) {
246
- let method = _.keys(requestSpec)[0].toUpperCase();
247
- let params = requestSpec[method.toLowerCase()];
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
- let err = new Error('an URL must be specified');
242
+ const err = new Error('an URL must be specified');
257
243
  return callback(err, context);
258
244
  }
259
245
 
260
- let tls = config.tls || {};
261
- let timeout = config.timeout || _.get(config, 'http.timeout') || 10;
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(function () {
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(function () {
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
- let functionNames = _.concat(
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
- let fn = template(functionName, context);
298
+ const fn = template(functionName, context);
313
299
  let processFunc = config.processor[fn];
314
300
  if (!processFunc) {
315
- processFunc = function (r, c, e, cb) {
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, function (err) {
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
- function (acc, v, k) {
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
- function (acc, v, k) {
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
- let defaultHeaders = lowcaseKeys(
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
- combinedHeaders,
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
- let url = maybePrependBase(
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(function (k) {
457
+ Object.keys(cookie).forEach((k) => {
477
458
  context._jar.setCookieSync(
478
- k + '=' + template(cookie[k], context),
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
- let err = new Error(`Invalid URL - ${requestParams.url}`);
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
- function (asyncErr) {
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(result.matches, function (v, k) {
602
- return !v.success && v.strict !== false;
603
- });
580
+ haveFailedMatches = _.some(
581
+ result.matches,
582
+ (v, _k) => !v.success && v.strict !== false
583
+ );
604
584
 
605
- haveFailedCaptures = _.some(result.captures, function (v, k) {
606
- return v.failed;
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, function (v, k) {
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, function (v, k) {
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
- let functionNames = _.concat(
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
- let fn = template(functionName, context);
616
+ const fn = template(functionName, context);
636
617
  let processFunc = config.processor[fn];
637
618
  if (!processFunc) {
638
619
  // TODO: DRY - #223
639
- processFunc = function (r, res, c, e, cb) {
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
- requestParams,
653
- res,
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
- function (err) {
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
- let err = new Error('an URL must be specified');
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
- function (asyncErr) {
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', function (req) {
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', function (res) {
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', function (err, body, res) {
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
- function (asyncErr) {
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
- function (asyncErr) {
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
- let code = res.statusCode;
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(function (cookieString) {
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', 'http.codes.' + code, 1);
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, scenarioSpec, ee) {
961
- let self = this;
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, function (result, v, k) {
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
- let processFunc = functions[functionName];
1010
- processFunc(err, requestParams, context, ee, function (asyncErr) {
976
+ const processFunc = functions[functionName];
977
+ processFunc(err, requestParams, context, ee, (asyncErr) => {
1011
978
  if (asyncErr) {
1012
979
  return next(asyncErr);
1013
980
  }