@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 +20 -4
- package/lib/engine_http.js +8 -1
- package/lib/engine_socketio.js +4 -1
- package/lib/phases.js +53 -32
- package/package.json +3 -1
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
|
|
package/lib/engine_http.js
CHANGED
|
@@ -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
|
}
|
package/lib/engine_socketio.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
};
|
|
135
|
+
debug(`periodArrivals ${periodArrivals}`);
|
|
136
|
+
debug(`periodTick ${periodTick}`);
|
|
112
137
|
|
|
113
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
);
|
|
145
|
+
ee.emit('phaseCompleted', spec);
|
|
146
|
+
}
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return callback(null);
|
|
155
|
+
currentPeriod++;
|
|
156
|
+
driftless.clearDriftless(arrivalTimer);
|
|
137
157
|
}
|
|
138
|
-
},
|
|
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": "
|
|
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": {
|