@artilleryio/int-core 1.0.0 → 2.0.1

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,10 +1,8 @@
1
1
  const EventEmitter = require('events');
2
2
  const chalk = require('chalk');
3
3
 
4
- const { createGlobalObject } = require('../artillery/lib/artillery-global');
5
-
6
4
  // NOTE: This may be called more than once, and so should be non-destructive
7
- async function updateGlobalObject(opts) {
5
+ async function updateGlobalObject(opts = {}) {
8
6
  global.artillery = global.artillery || {};
9
7
 
10
8
  global.artillery.runtimeOptions = global.artillery.runtimeOptions || {};
@@ -57,10 +55,28 @@ async function updateGlobalObject(opts) {
57
55
  }
58
56
  });
59
57
  }
58
+
59
+ global.artillery.logger = global.artillery.logger || function (opts) {
60
+ return {
61
+ log: (...args) => {
62
+ global.artillery.globalEvents.emit('log', opts, ...args);
63
+ }
64
+ };
65
+ };
66
+
67
+ global.artillery.log = global.artillery.log || function (...args) {
68
+ global.artillery.globalEvents.emit('log', {}, ...args);
69
+ };
70
+
71
+ if (opts.version) {
72
+ global.artillery.version = opts.version;
73
+ }
74
+ if (opts.telemetry) {
75
+ global.artillery.telemetry = opts.telemetry;
76
+ }
60
77
  }
61
78
 
62
79
  async function main() {
63
- await createGlobalObject();
64
80
  await updateGlobalObject();
65
81
  }
66
82
 
@@ -26,6 +26,8 @@ const decompressResponse = require('decompress-response');
26
26
 
27
27
  const { promisify } = require('node:util');
28
28
 
29
+ const crypto = require('node:crypto');
30
+
29
31
  module.exports = HttpEngine;
30
32
 
31
33
  const DEFAULT_AGENT_OPTIONS = {
@@ -534,6 +536,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
534
536
  let haveFailedCaptures = false;
535
537
 
536
538
  if (result !== null) {
539
+ ee.emit('trace:http:capture', result, uuid);
537
540
  if (
538
541
  Object.keys(result.matches).length > 0 ||
539
542
  Object.keys(result.captures).length > 0
@@ -651,13 +654,16 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
651
654
 
652
655
  requestParams.retry = 0; // disable retries - ignored when using streams
653
656
 
657
+ const uuid = crypto.randomUUID();
654
658
  request(requestParams)
655
659
  .on('request', function (req) {
660
+ ee.emit('trace:http:request', requestParams, uuid);
661
+
656
662
  debugRequests('request start: %s', req.path);
657
663
  ee.emit('counter', 'http.requests', 1);
658
664
  ee.emit('rate', 'http.request_rate');
659
665
  req.on('response', function (res) {
660
-
666
+ ee.emit('trace:http:response', res, uuid);
661
667
  self._handleResponse(
662
668
  requestParams,
663
669
  res,
@@ -670,6 +676,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
670
676
 
671
677
  })
672
678
  .on('error', function (err, body, res) {
679
+ ee.emit('trace:http:error', err, uuid);
673
680
  if (err.name === 'HTTPError') {
674
681
  return;
675
682
  }
@@ -8,6 +8,7 @@ const async = require('async');
8
8
  const _ = require('lodash');
9
9
 
10
10
  const io = require('socket.io-client');
11
+ const wildcardPatch = require('socketio-wildcard')(io.Manager);
11
12
 
12
13
  const deepEqual = require('fast-deep-equal');
13
14
  const debug = require('debug')('socketio');
@@ -302,7 +303,9 @@ SocketIoEngine.prototype.loadContextSocket = function (namespace, context, cb) {
302
303
  const socket = io(target, options);
303
304
  context.sockets[namespace] = socket;
304
305
 
305
- socket.onAny(() => {
306
+ wildcardPatch(socket);
307
+
308
+ socket.on('*', function () {
306
309
  context.__receivedMessageCount++;
307
310
  });
308
311
 
package/lib/phases.js CHANGED
@@ -12,6 +12,7 @@ const arrivals = require('arrivals');
12
12
  const debug = require('debug')('phases');
13
13
  const crypto = require('crypto');
14
14
  const driftless = require('driftless');
15
+ const sleep = require('../../artillery/lib/util/sleep');
15
16
 
16
17
  module.exports = phaser;
17
18
 
@@ -96,47 +97,67 @@ function createRamp(spec, ee) {
96
97
  const duration = spec.duration || 1;
97
98
  const arrivalRate = spec.arrivalRate;
98
99
  const rampTo = spec.rampTo;
100
+ const worker = spec.worker;
101
+ const totalWorkers = spec.totalWorkers;
99
102
 
100
- const tick = 1000 / Math.max(arrivalRate, rampTo); // smallest tick
101
103
  const difference = rampTo - arrivalRate;
102
- const periods = duration * 1000 / tick;
104
+ const periods = duration;
105
+ debug(`worker ${worker} totalWorkers ${totalWorkers} arrivalRate ${arrivalRate} rampTo ${rampTo} difference ${difference} periods ${periods}`);
106
+
107
+ const periodArrivals = [];
108
+ const periodTick = [];
109
+ // if there is only one peridod we generate mean arrivals
110
+ if (periods === 1) {
111
+ periodArrivals[0] = Math.floor((rampTo + arrivalRate) / 2);
112
+ periodTick[0] = 1000 / periodArrivals;
113
+ } else {
114
+ // for each period we calculate the corresponding arrivals:
115
+ // knowing that arrivals(0) = arrivalRate and arrivals(duration -1) = rampTo
116
+ // then: arrivals(t) = difference / (duration-1) * t + arrivalRate
117
+ for (let i = 0; i < periods; i++) {
118
+ const rawPeriodArrivals = (difference / (duration - 1)) * i + arrivalRate;
119
+
120
+ // We use the floor of the expected arrivals, then we add up all decimal digits
121
+ // and evaluate if one or more workers should bump their arrivalRate.
122
+ periodArrivals[i] = Math.floor(rawPeriodArrivals);
123
+
124
+ // Think of fractionalPart * workers as the amount of arrivals that could not be
125
+ // shared evenly across all workers.
126
+ if (Math.round((rawPeriodArrivals % 1) * totalWorkers) >= worker) {
127
+ periodArrivals[i] = periodArrivals[i] + 1;
128
+ }
103
129
 
104
- function arrivalProbability(currentStep) {
105
- // linear function ax + b
106
- // normalized to 0 <= f(t) <= 1
107
- // Anything under function value should be an arrival
130
+ // Needed ticks to get to periodArrivals in 1000ms
131
+ periodTick[i] = periodArrivals[i] > 0 ? Math.floor(1000 / periodArrivals[i]) : 1000;
132
+ }
133
+ }
108
134
 
109
- let t = currentStep * tick / 1000;
110
- return ((difference / duration) * t + arrivalRate) / Math.max(rampTo, arrivalRate);
111
- };
135
+ debug(`periodArrivals ${periodArrivals}`);
136
+ debug(`periodTick ${periodTick}`);
112
137
 
113
- let probabilities = Array.from({length: periods}, () => Math.random());
138
+ return async function rampTask(callback) {
139
+ ee.emit('phaseStarted', spec);
140
+ for (let period = 0; period < periods; period++) {
141
+ ticker(period);
142
+ await sleep(1000);
143
+ }
114
144
 
115
- debug(
116
- `rampTo: tick = ${tick}; difference = ${difference}; rampTo = ${rampTo}; arrivalRate = ${arrivalRate}; periods = ${periods}`
117
- );
145
+ ee.emit('phaseCompleted', spec);
146
+ }
118
147
 
119
- return function rampTask(callback) {
120
- ee.emit('phaseStarted', spec);
121
- let currentStep = 1;
122
- const timer = driftless.setDriftlessInterval(function maybeArrival() {
123
- if (currentStep <= periods) {
124
- let arrivalBreakpoint = arrivalProbability(currentStep);
125
- let roll = probabilities[currentStep-1];
126
- debug(`roll:${roll} <= breakpoint:${arrivalBreakpoint}`);
127
- if (roll <= arrivalBreakpoint) {
128
- ee.emit('arrival', spec);
129
- }
130
-
131
- currentStep++;
148
+ function ticker(currentPeriod) {
149
+ let currentArrivals = 0;
150
+ let arrivalTimer = driftless.setDriftlessInterval(function arrivals() {
151
+ if (currentArrivals < periodArrivals[currentPeriod]) {
152
+ ee.emit('arrival', spec);
153
+ currentArrivals++;
132
154
  } else {
133
- driftless.clearDriftless(timer);
134
- ee.emit('phaseCompleted', spec);
135
-
136
- return callback(null);
155
+ currentPeriod++;
156
+ driftless.clearDriftless(arrivalTimer);
137
157
  }
138
- }, tick);
139
- };
158
+ }, periodTick[currentPeriod]);
159
+ return;
160
+ }
140
161
  }
141
162
 
142
163
  function createArrivalCount(spec, ee) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artilleryio/int-core",
3
- "version": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "main": "./index.js",
5
5
  "dependencies": {
6
6
  "@artilleryio/sketches-js": "^1.0.4",
@@ -39,6 +39,8 @@
39
39
  "ws": "^7.5.7"
40
40
  },
41
41
  "scripts": {
42
+ "lint": "eslint --ext \".js,.ts,.tsx\" .",
43
+ "lint-fix": "npm run lint -- --fix",
42
44
  "test": "tap --no-coverage --timeout=300 test/core/unit/*.test.js && bash test/core/run.sh"
43
45
  },
44
46
  "devDependencies": {