@artilleryio/int-core 2.2.0-a4feb0d → 2.2.0-bfa0fe5

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.
@@ -713,7 +713,17 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
713
713
  .catch((gotErr) => {
714
714
  // TODO: Handle the error properly with run hooks
715
715
  debug(gotErr);
716
- return callback(gotErr, context);
716
+ runOnErrorHooks(
717
+ onErrorHandlers,
718
+ config.processor,
719
+ gotErr,
720
+ requestParams,
721
+ context,
722
+ ee,
723
+ function (asyncErr) {
724
+ return callback(gotErr, context);
725
+ }
726
+ );
717
727
  });
718
728
  }
719
729
  ); // eachSeries
@@ -52,16 +52,52 @@ function markEndTime(ee, _, startedAt) {
52
52
  }
53
53
 
54
54
  function isResponseRequired(spec) {
55
- return spec.emit && spec.response && spec.response.channel;
55
+ return (
56
+ spec.emit && spec.response && (spec.response.channel || spec.response.on)
57
+ );
56
58
  }
57
59
 
58
60
  function isAcknowledgeRequired(spec) {
59
61
  return spec.emit && spec.acknowledge;
60
62
  }
61
63
 
64
+ function isValid(data, response) {
65
+ if (_.isArray(response.data)) {
66
+ //we check if it's an array first (as arrays are objects), and if it's an array, do a deep equality check between both arrays
67
+ return deepEqual(data, response.data);
68
+ }
69
+
70
+ if (_.isObject(response.data)) {
71
+ //`json` key is added at some point to the response.data object, to use with `captureOrMatch` function
72
+ //we should omit it when comparing the response to the data
73
+ const expectedResponse = _.omit(response.data, 'json');
74
+ const actualResponse = data[data.length - 1]; // if response.data is not an array, we compare it to the last element of the actual response
75
+
76
+ return deepEqual(actualResponse, expectedResponse);
77
+ }
78
+
79
+ if (_.isString(response.data)) {
80
+ const expectedResponse = response.data;
81
+ let actualResponse = data[data.length - 1]; // if response.data is not an array, we compare it to the last element of the actual response
82
+
83
+ // unless the user wants to test against the entire response
84
+ if (response.concat) {
85
+ actualResponse = data.join('');
86
+ }
87
+
88
+ debug(
89
+ `checking if string ${expectedResponse} is a partial match for string ${actualResponse}`
90
+ );
91
+ return actualResponse.includes(expectedResponse); //we accept a partial match if it's a string
92
+ }
93
+
94
+ debug(`unexpected data type for response.data: ${typeof response.data}`);
95
+ return false;
96
+ }
97
+
62
98
  function processResponse(ee, data, response, context, callback) {
63
99
  // Do we have supplied data to validate?
64
- if (response.data && !deepEqual(data, response.data)) {
100
+ if (response.data && !isValid(data, response)) {
65
101
  debug('data is not valid:');
66
102
  debug(data);
67
103
  debug(response);
@@ -186,9 +222,12 @@ SocketIoEngine.prototype.step = function (requestSpec, ee) {
186
222
  }
187
223
 
188
224
  if (isAcknowledgeRequired(requestSpec)) {
189
- const ackCallback = function () {
225
+ const ackCallback = function (...args) {
190
226
  const response = {
191
- data: template(requestSpec.acknowledge.data, context),
227
+ data: template(
228
+ requestSpec.acknowledge.data || requestSpec.acknowledge.args,
229
+ context
230
+ ),
192
231
  capture: template(requestSpec.acknowledge.capture, context),
193
232
  match: template(requestSpec.acknowledge.match, context)
194
233
  };
@@ -198,8 +237,9 @@ SocketIoEngine.prototype.step = function (requestSpec, ee) {
198
237
  r.json = '$.0'; // Default to the first callback argument
199
238
  }
200
239
  });
240
+
201
241
  // Acknowledge data can take up multiple arguments of the emit callback
202
- processResponse(ee, arguments, response, context, function (err) {
242
+ processResponse(ee, args, response, context, function (err) {
203
243
  if (!err) {
204
244
  markEndTime(ee, context, startedAt);
205
245
  }
@@ -219,32 +259,44 @@ SocketIoEngine.prototype.step = function (requestSpec, ee) {
219
259
  socketio.emit(...outgoing);
220
260
  }
221
261
  markEndTime(ee, context, startedAt);
222
- return callback(null, context);
262
+ return callback(err, context);
223
263
  }
224
264
  }; // endCallback
225
265
 
226
266
  if (isResponseRequired(requestSpec)) {
227
267
  const response = {
228
- channel: template(requestSpec.response.channel, context),
229
- data: template(requestSpec.response.data, context),
268
+ channel: template(
269
+ requestSpec.response.channel || requestSpec.response.on,
270
+ context
271
+ ),
272
+ concat: template(requestSpec.response.concat, context),
273
+ data: template(
274
+ requestSpec.response.data || requestSpec.response.args,
275
+ context
276
+ ),
230
277
  capture: template(requestSpec.response.capture, context),
231
278
  match: template(requestSpec.response.match, context)
232
279
  };
233
280
 
234
281
  // Listen for the socket.io response on the specified channel
235
282
  let done = false;
283
+ let responseData = [];
236
284
 
237
- socketio.on(response.channel, function receive(data) {
238
- done = true;
239
- processResponse(ee, data, response, context, function (err) {
240
- if (!err) {
241
- markEndTime(ee, context, startedAt);
242
- }
243
- // Stop listening on the response channel
244
- socketio.off(response.channel);
285
+ socketio.on(response.channel, function receive(...args) {
286
+ responseData.push(...args);
287
+ if (isValid(responseData, response)) {
288
+ done = true;
245
289
 
246
- return endCallback(err, context, false);
247
- });
290
+ processResponse(ee, responseData, response, context, function (err) {
291
+ if (!err) {
292
+ markEndTime(ee, context, startedAt);
293
+ }
294
+ // Stop listening on the response channel
295
+ socketio.off(response.channel);
296
+
297
+ return endCallback(err, context, false);
298
+ });
299
+ }
248
300
  });
249
301
 
250
302
  // Send the data on the specified socket.io channel
@@ -254,6 +306,27 @@ SocketIoEngine.prototype.step = function (requestSpec, ee) {
254
306
 
255
307
  setTimeout(function responseTimeout() {
256
308
  if (!done) {
309
+ if (responseData.length) {
310
+ processResponse(
311
+ ee,
312
+ responseData,
313
+ response,
314
+ context,
315
+ function (err) {
316
+ if (!err) {
317
+ markEndTime(ee, context, startedAt);
318
+ }
319
+ // Stop listening on the response channel
320
+ socketio.off(response.channel);
321
+
322
+ // called
323
+ return endCallback(err, context, false);
324
+ }
325
+ );
326
+
327
+ return;
328
+ }
329
+
257
330
  const err = 'response timeout';
258
331
  ee.emit('error', err);
259
332
  return callback(err, context);
@@ -315,6 +388,10 @@ SocketIoEngine.prototype.loadContextSocket = function (namespace, context, cb) {
315
388
  socket.once('connect_error', function (err) {
316
389
  cb(err, null);
317
390
  });
391
+
392
+ socket.once('error', function (err) {
393
+ cb(err, socket);
394
+ });
318
395
  } else {
319
396
  return cb(null, context.sockets[namespace]);
320
397
  }
package/lib/runner.js CHANGED
@@ -327,8 +327,13 @@ function runScenario(script, metrics, runState, contextVars, options) {
327
327
  if (options.scenarioName) {
328
328
  let foundIndex;
329
329
  const foundScenario = script.scenarios.filter((scenario, index) => {
330
- foundIndex = index;
331
- return new RegExp(options.scenarioName).test(scenario.name);
330
+ const hasScenario = new RegExp(options.scenarioName).test(scenario.name);
331
+
332
+ if (hasScenario) {
333
+ foundIndex = index;
334
+ }
335
+
336
+ return hasScenario;
332
337
  });
333
338
 
334
339
  if (foundScenario?.length === 0) {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@artilleryio/int-core",
3
- "version": "2.2.0-a4feb0d",
3
+ "version": "2.2.0-bfa0fe5",
4
4
  "main": "./index.js",
5
5
  "license": "MPL-2.0",
6
6
  "dependencies": {
7
- "@artilleryio/int-commons": "2.0.2-a4feb0d",
7
+ "@artilleryio/int-commons": "2.0.3-bfa0fe5",
8
8
  "@artilleryio/sketches-js": "^2.1.1",
9
9
  "agentkeepalive": "^4.1.0",
10
10
  "arrivals": "^2.1.2",