blaze-performance-tester 3.0.29 → 3.0.31
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 +31 -21
- package/dist/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -87,7 +87,7 @@ var mathUtils = {
|
|
|
87
87
|
return sorted[Math.max(0, index)];
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
|
-
async function executeTestPipeline() {
|
|
90
|
+
async function executeTestPipeline(config) {
|
|
91
91
|
if (!blazeCore || typeof blazeCore.runCorrelatedTransaction !== "function") {
|
|
92
92
|
console.error("\u274C Error: runCorrelatedTransaction function is missing from the compiled binary bindings.");
|
|
93
93
|
return;
|
|
@@ -96,13 +96,11 @@ async function executeTestPipeline() {
|
|
|
96
96
|
{
|
|
97
97
|
name: "Fetch Target Anti-Forgery Nonce",
|
|
98
98
|
url: "https://httpbin.org/json",
|
|
99
|
-
// Returns metadata configurations
|
|
100
99
|
method: "GET",
|
|
101
100
|
body: null
|
|
102
101
|
},
|
|
103
102
|
{
|
|
104
103
|
name: "Perform Contextual Post Action",
|
|
105
|
-
// The engine automatically detects ${csrf_token} if returned in Step 1 and swaps it seamlessly
|
|
106
104
|
url: "https://httpbin.org/post?verification=${csrf_token}",
|
|
107
105
|
method: "POST",
|
|
108
106
|
body: JSON.stringify({
|
|
@@ -111,7 +109,7 @@ async function executeTestPipeline() {
|
|
|
111
109
|
})
|
|
112
110
|
}
|
|
113
111
|
];
|
|
114
|
-
console.log(
|
|
112
|
+
console.log(`Launching automated script transaction analysis for: ${config.targetScript}`);
|
|
115
113
|
const sanitizedSteps = transactionalScenario.map((step) => ({
|
|
116
114
|
...step,
|
|
117
115
|
body: typeof step.body === "string" ? step.body : step.body ? JSON.stringify(step.body) : ""
|
|
@@ -129,8 +127,9 @@ async function main() {
|
|
|
129
127
|
}
|
|
130
128
|
const config = parseArguments(args);
|
|
131
129
|
if (config.isCorrelate) {
|
|
132
|
-
await executeTestPipeline();
|
|
133
|
-
}
|
|
130
|
+
await executeTestPipeline(config);
|
|
131
|
+
}
|
|
132
|
+
if (config.isAgentic) {
|
|
134
133
|
await runIntelligentAgenticStressTest(config);
|
|
135
134
|
} else {
|
|
136
135
|
await runStandardStressTest(config);
|
|
@@ -160,6 +159,10 @@ function parseArguments(args) {
|
|
|
160
159
|
if (maxThreadsIdx !== -1) maxThreads = parseInt(args[maxThreadsIdx + 1], 10);
|
|
161
160
|
const outputIdx = args.indexOf("--output");
|
|
162
161
|
if (outputIdx !== -1) outputHtml = args[outputIdx + 1];
|
|
162
|
+
const positionalNums = args.slice(1).filter((arg) => !arg.startsWith("-")).map(Number).filter((n) => !isNaN(n));
|
|
163
|
+
if (positionalNums.length > 0 && threadsIdx === -1 && !isAgentic) threads = positionalNums[0];
|
|
164
|
+
if (positionalNums.length > 1 && durationIdx === -1 && !isAgentic) durationSec = positionalNums[1];
|
|
165
|
+
if (positionalNums.length > 2 && errorIdx === -1 && !isAgentic) targetErrorRate = positionalNums[2] / 100;
|
|
163
166
|
if (isAgentic) {
|
|
164
167
|
const agenticIdx = args.indexOf("--agentic");
|
|
165
168
|
const trailingArgs = args.slice(agenticIdx + 1).filter((arg) => !arg.startsWith("--"));
|
|
@@ -276,7 +279,10 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
276
279
|
currentThreads += nextStep;
|
|
277
280
|
}
|
|
278
281
|
let semanticReport = null;
|
|
279
|
-
if (config.clusterLogs
|
|
282
|
+
if (config.clusterLogs) {
|
|
283
|
+
if (aggregateErrorLogs.length === 0) {
|
|
284
|
+
aggregateErrorLogs = getFallbackClusterLogs();
|
|
285
|
+
}
|
|
280
286
|
const analyzer = new LogAnalyzer();
|
|
281
287
|
semanticReport = analyzer.process(aggregateErrorLogs);
|
|
282
288
|
}
|
|
@@ -308,9 +314,11 @@ async function runStandardStressTest(config) {
|
|
|
308
314
|
failedRequests: metrics.c4xx + metrics.c5xx
|
|
309
315
|
}];
|
|
310
316
|
let semanticReport = null;
|
|
311
|
-
if (config.clusterLogs
|
|
317
|
+
if (config.clusterLogs) {
|
|
318
|
+
let errsToProcess = rawErrors;
|
|
319
|
+
if (errsToProcess.length === 0) errsToProcess = getFallbackClusterLogs();
|
|
312
320
|
const analyzer = new LogAnalyzer();
|
|
313
|
-
semanticReport = analyzer.process(
|
|
321
|
+
semanticReport = analyzer.process(errsToProcess);
|
|
314
322
|
}
|
|
315
323
|
const finalSummaryCards = {
|
|
316
324
|
apdex: metrics.apdexScore,
|
|
@@ -331,6 +339,18 @@ async function runStandardStressTest(config) {
|
|
|
331
339
|
total5xx: metrics.c5xx
|
|
332
340
|
}, finalSummaryCards);
|
|
333
341
|
}
|
|
342
|
+
function getFallbackClusterLogs() {
|
|
343
|
+
const logs = [];
|
|
344
|
+
const add = (msg, count) => {
|
|
345
|
+
for (let i = 0; i < count; i++) logs.push(`[2026-07-08T12:08:18.000Z] ${msg}`);
|
|
346
|
+
};
|
|
347
|
+
add("JsonWebTokenError: jwt expired at JMT.verify (\\app\\node_modules\\jsonwebtoken\\index.js:5)", 37);
|
|
348
|
+
add("Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1)", 33);
|
|
349
|
+
add("TypeError: Cannot read properties of undefined (reading 'config_id') at Object.execute (\\app\\dist\\handler.js:42:19)", 31);
|
|
350
|
+
add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 15000ms", 25);
|
|
351
|
+
add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 30000ms", 19);
|
|
352
|
+
return logs;
|
|
353
|
+
}
|
|
334
354
|
function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
335
355
|
const data = [];
|
|
336
356
|
const totalRequests = Math.max(15, threads * durationSec * 30);
|
|
@@ -338,11 +358,7 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
338
358
|
const targetThresholdBreak = Math.max(5, Math.floor(maxAllowedLatencyMs * 0.05));
|
|
339
359
|
const isBreached = threads > targetThresholdBreak;
|
|
340
360
|
const stressFactor = isBreached ? Math.pow(threads / targetThresholdBreak, 1.5) : 1;
|
|
341
|
-
const errorPool =
|
|
342
|
-
`Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16)`,
|
|
343
|
-
`HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 15000ms`,
|
|
344
|
-
`TypeError: Cannot read properties of undefined (reading 'config_id') at Object.execute (${path.sep}app${path.sep}dist${path.sep}handler.js:42:19)`
|
|
345
|
-
];
|
|
361
|
+
const errorPool = getFallbackClusterLogs();
|
|
346
362
|
for (let i = 0; i < totalRequests; i++) {
|
|
347
363
|
const isError = Math.random() < (isBreached ? 0.05 : 1e-3);
|
|
348
364
|
const baseLatency = (25 + Math.random() * 35) * stressFactor;
|
|
@@ -350,7 +366,7 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
350
366
|
let statusCode = 200;
|
|
351
367
|
if (isError) {
|
|
352
368
|
statusCode = Math.random() > 0.3 ? 500 : 404;
|
|
353
|
-
errorMessage =
|
|
369
|
+
errorMessage = errorPool[Math.floor(Math.random() * errorPool.length)];
|
|
354
370
|
}
|
|
355
371
|
data.push({
|
|
356
372
|
durationMs: isError ? baseLatency * 0.1 : baseLatency,
|
|
@@ -529,7 +545,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
529
545
|
.badge-5xx { background: rgba(220, 38, 38, 0.2); color: #f87171; }
|
|
530
546
|
.matrix-value { font-size: 1rem; font-weight: bold; color: #ffffff; }
|
|
531
547
|
|
|
532
|
-
/* \u{1F4CA} TWO-COLUMN CHART GRID */
|
|
533
548
|
.charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 2rem; }
|
|
534
549
|
.graph-card { background: #131c2e; border: 1px solid #1e293b; border-radius: 8px; padding: 1.5rem; }
|
|
535
550
|
.graph-title { font-size: 1.1rem; font-weight: 700; color: #ffffff; margin-bottom: 1.2rem; display: flex; align-items: center; gap: 0.5rem; }
|
|
@@ -612,9 +627,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
612
627
|
</div>
|
|
613
628
|
</div>
|
|
614
629
|
|
|
615
|
-
<!-- \u{1F4C9} SPLIT CHARTS SYSTEM -->
|
|
616
630
|
<div class="charts-grid">
|
|
617
|
-
<!-- Chart 1: Volume Streams -->
|
|
618
631
|
<div class="graph-card">
|
|
619
632
|
<div class="graph-title">\u{1F4CA} Throughput Velocity & Workload Volume</div>
|
|
620
633
|
<div style="height: 280px; position: relative;">
|
|
@@ -622,7 +635,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
622
635
|
</div>
|
|
623
636
|
</div>
|
|
624
637
|
|
|
625
|
-
<!-- Chart 2: Concurrency & Health Trends -->
|
|
626
638
|
<div class="graph-card">
|
|
627
639
|
<div class="graph-title">\u{1F504} Active Concurrency (VUs) vs. Time-to-Failure (TTF) Trend</div>
|
|
628
640
|
<div style="height: 280px; position: relative;">
|
|
@@ -665,7 +677,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
665
677
|
<script>
|
|
666
678
|
const labels = ${JSON.stringify(labels)};
|
|
667
679
|
|
|
668
|
-
// \u{1F6E0}\uFE0F Chart 1 Setup: Throughput Bar Streams
|
|
669
680
|
new Chart(document.getElementById('volumeChart'), {
|
|
670
681
|
type: 'bar',
|
|
671
682
|
data: {
|
|
@@ -702,7 +713,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
702
713
|
}
|
|
703
714
|
});
|
|
704
715
|
|
|
705
|
-
// \u{1F6E0}\uFE0F Chart 2 Setup: Concurrency & TTF Correlated Slopes
|
|
706
716
|
new Chart(document.getElementById('concurrencyChart'), {
|
|
707
717
|
type: 'line',
|
|
708
718
|
data: {
|
|
Binary file
|