blaze-performance-tester 3.0.23 → 3.0.25
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/dist/cli.js +130 -4
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -74,19 +74,68 @@ try {
|
|
|
74
74
|
process.exit(1);
|
|
75
75
|
}
|
|
76
76
|
var mathUtils = {
|
|
77
|
+
//[cite: 2]
|
|
77
78
|
mean: (arr) => arr.length === 0 ? 0 : arr.reduce((p, c) => p + c, 0) / arr.length,
|
|
79
|
+
//[cite: 2]
|
|
78
80
|
stdDev: (arr, mean) => {
|
|
79
81
|
if (arr.length === 0) return 0;
|
|
80
82
|
const r = arr.reduce((p, c) => p + Math.pow(c - mean, 2), 0);
|
|
81
83
|
return Math.sqrt(r / arr.length);
|
|
82
84
|
},
|
|
85
|
+
//[cite: 2]
|
|
83
86
|
percentile: (arr, p) => {
|
|
84
87
|
if (arr.length === 0) return 0;
|
|
85
88
|
const sorted = [...arr].sort((a, b) => a - b);
|
|
86
89
|
const index = Math.ceil(p / 100 * sorted.length) - 1;
|
|
87
90
|
return sorted[Math.max(0, index)];
|
|
88
91
|
}
|
|
92
|
+
//[cite: 2]
|
|
89
93
|
};
|
|
94
|
+
async function executeTestPipeline() {
|
|
95
|
+
if (!blazeCore || typeof blazeCore.runCorrelatedTransaction !== "function") {
|
|
96
|
+
console.error("\u274C Error: runCorrelatedTransaction function is missing from the compiled binary bindings.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const transactionalScenario = [
|
|
100
|
+
//[cite: 1]
|
|
101
|
+
{
|
|
102
|
+
//[cite: 1]
|
|
103
|
+
name: "Fetch Target Anti-Forgery Nonce",
|
|
104
|
+
//[cite: 1]
|
|
105
|
+
url: "https://httpbin.org/json",
|
|
106
|
+
// Returns metadata configurations //[cite: 1]
|
|
107
|
+
method: "GET",
|
|
108
|
+
//[cite: 1]
|
|
109
|
+
body: null
|
|
110
|
+
//[cite: 1]
|
|
111
|
+
},
|
|
112
|
+
//[cite: 1]
|
|
113
|
+
{
|
|
114
|
+
//[cite: 1]
|
|
115
|
+
name: "Perform Contextual Post Action",
|
|
116
|
+
//[cite: 1]
|
|
117
|
+
// The engine automatically detects ${csrf_token} if returned in Step 1 and swaps it seamlessly //[cite: 1]
|
|
118
|
+
url: "https://httpbin.org/post?verification=${csrf_token}",
|
|
119
|
+
//[cite: 1]
|
|
120
|
+
method: "POST",
|
|
121
|
+
//[cite: 1]
|
|
122
|
+
body: JSON.stringify({
|
|
123
|
+
//[cite: 1]
|
|
124
|
+
data: "performance_payload",
|
|
125
|
+
//[cite: 1]
|
|
126
|
+
security_token: "${csrf_token}"
|
|
127
|
+
//[cite: 1]
|
|
128
|
+
})
|
|
129
|
+
//[cite: 1]
|
|
130
|
+
}
|
|
131
|
+
//[cite: 1]
|
|
132
|
+
];
|
|
133
|
+
console.log("Launching automated script transaction analysis...");
|
|
134
|
+
const success = await blazeCore.runCorrelatedTransaction(transactionalScenario);
|
|
135
|
+
if (success) {
|
|
136
|
+
console.log("Pipeline run complete. Parameter tracking successfully mitigated breaking changes.");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
90
139
|
async function main() {
|
|
91
140
|
const args = process.argv.slice(2);
|
|
92
141
|
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
@@ -94,7 +143,9 @@ async function main() {
|
|
|
94
143
|
return;
|
|
95
144
|
}
|
|
96
145
|
const config = parseArguments(args);
|
|
97
|
-
if (config.
|
|
146
|
+
if (config.isCorrelate) {
|
|
147
|
+
await executeTestPipeline();
|
|
148
|
+
} else if (config.isAgentic) {
|
|
98
149
|
await runIntelligentAgenticStressTest(config);
|
|
99
150
|
} else {
|
|
100
151
|
await runStandardStressTest(config);
|
|
@@ -103,6 +154,7 @@ async function main() {
|
|
|
103
154
|
function parseArguments(args) {
|
|
104
155
|
const targetScript = path.resolve(args[0] || ".");
|
|
105
156
|
const isAgentic = args.includes("--agentic");
|
|
157
|
+
const isCorrelate = args.includes("--correlate");
|
|
106
158
|
const clusterLogs = args.includes("--cluster-logs");
|
|
107
159
|
let threads = 10;
|
|
108
160
|
let durationSec = 10;
|
|
@@ -138,17 +190,31 @@ function parseArguments(args) {
|
|
|
138
190
|
if (trailingArgs[2]) targetErrorRate = parseFloat(trailingArgs[2]) / 100;
|
|
139
191
|
}
|
|
140
192
|
return {
|
|
193
|
+
//[cite: 2]
|
|
141
194
|
targetScript,
|
|
195
|
+
//[cite: 2]
|
|
142
196
|
isAgentic,
|
|
197
|
+
//[cite: 2]
|
|
198
|
+
isCorrelate,
|
|
199
|
+
//[cite: 2]
|
|
143
200
|
clusterLogs,
|
|
201
|
+
//[cite: 2]
|
|
144
202
|
threads,
|
|
203
|
+
//[cite: 2]
|
|
145
204
|
durationSec,
|
|
205
|
+
//[cite: 2]
|
|
146
206
|
targetApdex,
|
|
207
|
+
//[cite: 2]
|
|
147
208
|
targetErrorRate,
|
|
209
|
+
//[cite: 2]
|
|
148
210
|
maxThreads,
|
|
211
|
+
//[cite: 2]
|
|
149
212
|
stepSize: 15,
|
|
213
|
+
//[cite: 2]
|
|
150
214
|
maxAllowedLatencyMs,
|
|
215
|
+
//[cite: 2]
|
|
151
216
|
outputHtml
|
|
217
|
+
//[cite: 2]
|
|
152
218
|
};
|
|
153
219
|
}
|
|
154
220
|
async function runBlazeCoreEngine(config) {
|
|
@@ -197,14 +263,23 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
197
263
|
globalMetricsAccumulator.latencies.push(metrics.avgLatencyMs);
|
|
198
264
|
globalMetricsAccumulator.bandwidths.push(metrics.bandwidthMb);
|
|
199
265
|
const currentState = {
|
|
266
|
+
//[cite: 2]
|
|
200
267
|
threads: currentThreads,
|
|
268
|
+
//[cite: 2]
|
|
201
269
|
avgLatency: metrics.avgLatencyMs,
|
|
270
|
+
//[cite: 2]
|
|
202
271
|
p95Latency: metrics.p95LatencyMs,
|
|
272
|
+
//[cite: 2]
|
|
203
273
|
errorRate: metrics.errorRate,
|
|
274
|
+
//[cite: 2]
|
|
204
275
|
apdex: metrics.apdexScore,
|
|
276
|
+
//[cite: 2]
|
|
205
277
|
throughput: metrics.requestsPerSecond,
|
|
278
|
+
//[cite: 2]
|
|
206
279
|
successRequests: metrics.c2xx + metrics.c3xx,
|
|
280
|
+
//[cite: 2]
|
|
207
281
|
failedRequests: metrics.c4xx + metrics.c5xx
|
|
282
|
+
//[cite: 2]
|
|
208
283
|
};
|
|
209
284
|
printMatrixDashboard(metrics, currentThreads);
|
|
210
285
|
history.push(currentState);
|
|
@@ -243,14 +318,23 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
243
318
|
semanticReport = analyzer.process(aggregateErrorLogs);
|
|
244
319
|
}
|
|
245
320
|
const finalSummaryCards = {
|
|
321
|
+
//[cite: 2]
|
|
246
322
|
apdex: history[history.length - 1]?.apdex || 0,
|
|
323
|
+
//[cite: 2]
|
|
247
324
|
throughput: history[history.length - 1]?.throughput || 0,
|
|
325
|
+
//[cite: 2]
|
|
248
326
|
bandwidth: mathUtils.mean(globalMetricsAccumulator.bandwidths),
|
|
327
|
+
//[cite: 2]
|
|
249
328
|
ttfb: mathUtils.mean(globalMetricsAccumulator.ttfb),
|
|
329
|
+
//[cite: 2]
|
|
250
330
|
dns: mathUtils.mean(globalMetricsAccumulator.dns),
|
|
331
|
+
//[cite: 2]
|
|
251
332
|
tcp: mathUtils.mean(globalMetricsAccumulator.tcp),
|
|
333
|
+
//[cite: 2]
|
|
252
334
|
tls: mathUtils.mean(globalMetricsAccumulator.tls),
|
|
335
|
+
//[cite: 2]
|
|
253
336
|
stdDev: mathUtils.stdDev(globalMetricsAccumulator.latencies, mathUtils.mean(globalMetricsAccumulator.latencies))
|
|
337
|
+
//[cite: 2]
|
|
254
338
|
};
|
|
255
339
|
generateFinalAgentReport(history);
|
|
256
340
|
exportHtmlDashboard(history, config, verdictReason, semanticReport, { total2xx, total3xx, total4xx, total5xx }, finalSummaryCards);
|
|
@@ -260,14 +344,23 @@ async function runStandardStressTest(config) {
|
|
|
260
344
|
const { metrics, rawErrors } = await runBlazeCoreEngine(config);
|
|
261
345
|
printMatrixDashboard(metrics, config.threads);
|
|
262
346
|
const history = [{
|
|
347
|
+
//[cite: 2]
|
|
263
348
|
threads: config.threads,
|
|
349
|
+
//[cite: 2]
|
|
264
350
|
avgLatency: metrics.avgLatencyMs,
|
|
351
|
+
//[cite: 2]
|
|
265
352
|
p95Latency: metrics.p95LatencyMs,
|
|
353
|
+
//[cite: 2]
|
|
266
354
|
errorRate: metrics.errorRate,
|
|
355
|
+
//[cite: 2]
|
|
267
356
|
apdex: metrics.apdexScore,
|
|
357
|
+
//[cite: 2]
|
|
268
358
|
throughput: metrics.requestsPerSecond,
|
|
359
|
+
//[cite: 2]
|
|
269
360
|
successRequests: metrics.c2xx + metrics.c3xx,
|
|
361
|
+
//[cite: 2]
|
|
270
362
|
failedRequests: metrics.c4xx + metrics.c5xx
|
|
363
|
+
//[cite: 2]
|
|
271
364
|
}];
|
|
272
365
|
let semanticReport = null;
|
|
273
366
|
if (config.clusterLogs && rawErrors.length > 0) {
|
|
@@ -275,22 +368,33 @@ async function runStandardStressTest(config) {
|
|
|
275
368
|
semanticReport = analyzer.process(rawErrors);
|
|
276
369
|
}
|
|
277
370
|
const finalSummaryCards = {
|
|
371
|
+
//[cite: 2]
|
|
278
372
|
apdex: metrics.apdexScore,
|
|
373
|
+
//[cite: 2]
|
|
279
374
|
throughput: metrics.requestsPerSecond,
|
|
375
|
+
//[cite: 2]
|
|
280
376
|
bandwidth: metrics.bandwidthMb,
|
|
377
|
+
//[cite: 2]
|
|
281
378
|
ttfb: metrics.avgTtfbMs,
|
|
379
|
+
//[cite: 2]
|
|
282
380
|
dns: metrics.avgDnsMs,
|
|
381
|
+
//[cite: 2]
|
|
283
382
|
tcp: metrics.avgTcpMs,
|
|
383
|
+
//[cite: 2]
|
|
284
384
|
tls: metrics.avgTlsMs,
|
|
385
|
+
//[cite: 2]
|
|
285
386
|
stdDev: metrics.stdDevMs
|
|
387
|
+
//[cite: 2]
|
|
286
388
|
};
|
|
287
389
|
const isPassed = metrics.apdexScore >= config.targetApdex && metrics.errorRate <= config.targetErrorRate;
|
|
288
390
|
const verdictReason = isPassed ? "Static single-wave baseline checks concluded successfully without triggering health boundaries." : "Static verification loop completed with values exceeding defined quality thresholds.";
|
|
289
391
|
exportHtmlDashboard(history, config, verdictReason, semanticReport, {
|
|
392
|
+
//[cite: 2]
|
|
290
393
|
total2xx: metrics.c2xx,
|
|
291
394
|
total3xx: metrics.c3xx,
|
|
292
395
|
total4xx: metrics.c4xx,
|
|
293
396
|
total5xx: metrics.c5xx
|
|
397
|
+
//[cite: 2]
|
|
294
398
|
}, finalSummaryCards);
|
|
295
399
|
}
|
|
296
400
|
function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
@@ -301,9 +405,13 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
301
405
|
const isBreached = threads > targetThresholdBreak;
|
|
302
406
|
const stressFactor = isBreached ? Math.pow(threads / targetThresholdBreak, 1.5) : 1;
|
|
303
407
|
const errorPool = [
|
|
408
|
+
//[cite: 2]
|
|
304
409
|
`Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16)`,
|
|
410
|
+
//[cite: 2]
|
|
305
411
|
`HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 15000ms`,
|
|
412
|
+
//[cite: 2]
|
|
306
413
|
`TypeError: Cannot read properties of undefined (reading 'config_id') at Object.execute (${path.sep}app${path.sep}dist${path.sep}handler.js:42:19)`
|
|
414
|
+
//[cite: 2]
|
|
307
415
|
];
|
|
308
416
|
for (let i = 0; i < totalRequests; i++) {
|
|
309
417
|
const isError = Math.random() < (isBreached ? 0.05 : 1e-3);
|
|
@@ -315,13 +423,21 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
315
423
|
errorMessage = `[${(/* @__PURE__ */ new Date()).toISOString()}] ` + errorPool[Math.floor(Math.random() * errorPool.length)];
|
|
316
424
|
}
|
|
317
425
|
data.push({
|
|
426
|
+
//[cite: 2]
|
|
318
427
|
durationMs: isError ? baseLatency * 0.1 : baseLatency,
|
|
428
|
+
//[cite: 2]
|
|
319
429
|
timestampMs: startTime + Math.random() * (durationSec * 1e3),
|
|
430
|
+
//[cite: 2]
|
|
320
431
|
dnsTimeMs: 1 + Math.random() * 0.9,
|
|
432
|
+
//[cite: 2]
|
|
321
433
|
tcpTimeMs: 4 + Math.random() * 1.5,
|
|
434
|
+
//[cite: 2]
|
|
322
435
|
tlsTimeMs: 6 + Math.random() * 1.8,
|
|
436
|
+
//[cite: 2]
|
|
323
437
|
statusCode,
|
|
438
|
+
//[cite: 2]
|
|
324
439
|
errorMessage
|
|
440
|
+
//[cite: 2]
|
|
325
441
|
});
|
|
326
442
|
}
|
|
327
443
|
return data.sort((a, b) => a.timestampMs - b.timestampMs);
|
|
@@ -351,22 +467,32 @@ function processMetricsTelemetry(requests, durationSec) {
|
|
|
351
467
|
const apdexScore = totalRequests === 0 ? 0 : (satisfied + tolerating / 2) / totalRequests;
|
|
352
468
|
const bandwidthMb = totalRequests * 1.2 / durationSec / 10;
|
|
353
469
|
return {
|
|
470
|
+
//[cite: 2]
|
|
354
471
|
totalRequests,
|
|
472
|
+
//[cite: 2]
|
|
355
473
|
requestsPerSecond: totalRequests / durationSec,
|
|
474
|
+
//[cite: 2]
|
|
356
475
|
avgLatencyMs,
|
|
476
|
+
//[cite: 2]
|
|
357
477
|
stdDevMs,
|
|
478
|
+
//[cite: 2]
|
|
358
479
|
p95LatencyMs,
|
|
480
|
+
//[cite: 2]
|
|
359
481
|
errorRate,
|
|
482
|
+
//[cite: 2]
|
|
360
483
|
apdexScore,
|
|
484
|
+
//[cite: 2]
|
|
361
485
|
c2xx,
|
|
362
486
|
c3xx,
|
|
363
487
|
c4xx,
|
|
364
488
|
c5xx,
|
|
489
|
+
//[cite: 2]
|
|
365
490
|
avgDnsMs,
|
|
366
491
|
avgTcpMs,
|
|
367
492
|
avgTlsMs,
|
|
368
493
|
avgTtfbMs,
|
|
369
494
|
bandwidthMb
|
|
495
|
+
//[cite: 2]
|
|
370
496
|
};
|
|
371
497
|
}
|
|
372
498
|
function printMatrixDashboard(m, threads) {
|
|
@@ -700,8 +826,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
700
826
|
},
|
|
701
827
|
scales: {
|
|
702
828
|
x: { grid: { color: '#1e293b' }, ticks: { color: '#64748b' } },
|
|
703
|
-
|
|
704
|
-
|
|
829
|
+
y_threads: { position: 'left', grid: { color: '#1e293b' }, ticks: { color: '#38bdf8' }, title: { display: true, text: 'VUs / Threads', color: '#38bdf8' } },
|
|
830
|
+
y_ttf: { position: 'right', grid: { drawOnChartArea: false }, ticks: { color: '#f43f5e' }, title: { display: true, text: 'TTF Index / Latency ms', color: '#f43f5e' } }
|
|
705
831
|
}
|
|
706
832
|
}
|
|
707
833
|
});
|
|
@@ -716,6 +842,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
716
842
|
function printUsage() {
|
|
717
843
|
console.log(`Blaze Core Performance Test CLI Engine
|
|
718
844
|
Options:
|
|
719
|
-
--threads <count> | --duration <seconds> | --agentic | --cluster-logs`);
|
|
845
|
+
--threads <count> | --duration <seconds> | --agentic | --cluster-logs | --correlate`);
|
|
720
846
|
}
|
|
721
847
|
main().catch(console.error);
|
|
Binary file
|