blaze-performance-tester 3.1.14 → 3.1.15
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 +23 -129
- package/dist/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -224,9 +224,6 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
224
224
|
let lastRawRequests = [];
|
|
225
225
|
let total1xx = 0, total2xx = 0, total3xx = 0, total4xx = 0, total5xx = 0;
|
|
226
226
|
let globalMetricsAccumulator = { dns: [], tcp: [], tls: [], ttfb: [], latencies: [], bandwidths: [], lcp: [], fid: [], cls: [] };
|
|
227
|
-
let totalEconnreset = 0;
|
|
228
|
-
let totalEconnrefused = 0;
|
|
229
|
-
const globalCodeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 0, 502: 0, 503: 0, 504: 0 };
|
|
230
227
|
let currentThreads = Math.min(config.maxThreads, Math.max(5, Math.floor(config.maxThreads * 0.2)));
|
|
231
228
|
let baseStep = config.stepSize;
|
|
232
229
|
let isStable = true;
|
|
@@ -244,11 +241,6 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
244
241
|
total3xx += metrics.c3xx;
|
|
245
242
|
total4xx += metrics.c4xx;
|
|
246
243
|
total5xx += metrics.c5xx;
|
|
247
|
-
totalEconnreset += metrics.econnresetCount;
|
|
248
|
-
totalEconnrefused += metrics.econnrefusedCount;
|
|
249
|
-
Object.keys(globalCodeCounts).forEach((code) => {
|
|
250
|
-
globalCodeCounts[code] += metrics.codeCounts[code] || 0;
|
|
251
|
-
});
|
|
252
244
|
globalMetricsAccumulator.dns.push(metrics.avgDnsMs);
|
|
253
245
|
globalMetricsAccumulator.tcp.push(metrics.avgTcpMs);
|
|
254
246
|
globalMetricsAccumulator.tls.push(metrics.avgTlsMs);
|
|
@@ -269,10 +261,7 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
269
261
|
failedRequests: metrics.c4xx + metrics.c5xx,
|
|
270
262
|
lcp: metrics.lcpMs,
|
|
271
263
|
fid: metrics.fidMs,
|
|
272
|
-
cls: metrics.clsScore
|
|
273
|
-
econnresetRate: metrics.econnresetRate,
|
|
274
|
-
econnrefusedCount: metrics.econnrefusedCount,
|
|
275
|
-
codeRates: metrics.codeRates
|
|
264
|
+
cls: metrics.clsScore
|
|
276
265
|
};
|
|
277
266
|
printMatrixDashboard(metrics, currentThreads);
|
|
278
267
|
history.push(currentState);
|
|
@@ -316,11 +305,6 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
316
305
|
}
|
|
317
306
|
const totalTestSeconds = history.length * config.durationSec;
|
|
318
307
|
const vuRampUpVelocity = history.length > 1 && totalTestSeconds > 0 ? (history[history.length - 1].threads - history[0].threads) / totalTestSeconds : config.threads / config.durationSec;
|
|
319
|
-
const totalGlobalRequests = total1xx + total2xx + total3xx + total4xx + total5xx;
|
|
320
|
-
const aggregatedCodeRates = {};
|
|
321
|
-
Object.keys(globalCodeCounts).forEach((code) => {
|
|
322
|
-
aggregatedCodeRates[code] = totalGlobalRequests === 0 ? 0 : globalCodeCounts[code] / totalGlobalRequests * 100;
|
|
323
|
-
});
|
|
324
308
|
const finalSummaryCards = {
|
|
325
309
|
apdex: history[history.length - 1]?.apdex || 0,
|
|
326
310
|
throughput: history[history.length - 1]?.throughput || 0,
|
|
@@ -334,10 +318,7 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
334
318
|
vuRampUpVelocity,
|
|
335
319
|
lcp: mathUtils.mean(globalMetricsAccumulator.lcp),
|
|
336
320
|
fid: mathUtils.mean(globalMetricsAccumulator.fid),
|
|
337
|
-
cls: mathUtils.mean(globalMetricsAccumulator.cls)
|
|
338
|
-
econnresetRate: totalGlobalRequests === 0 ? 0 : totalEconnreset / totalGlobalRequests * 100,
|
|
339
|
-
econnrefusedCount: totalEconnrefused,
|
|
340
|
-
codeRates: aggregatedCodeRates
|
|
321
|
+
cls: mathUtils.mean(globalMetricsAccumulator.cls)
|
|
341
322
|
};
|
|
342
323
|
generateFinalAgentReport(history);
|
|
343
324
|
exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx }, finalSummaryCards, lastRawRequests);
|
|
@@ -357,10 +338,7 @@ async function runStandardStressTest(config) {
|
|
|
357
338
|
failedRequests: metrics.c4xx + metrics.c5xx,
|
|
358
339
|
lcp: metrics.lcpMs,
|
|
359
340
|
fid: metrics.fidMs,
|
|
360
|
-
cls: metrics.clsScore
|
|
361
|
-
econnresetRate: metrics.econnresetRate,
|
|
362
|
-
econnrefusedCount: metrics.econnrefusedCount,
|
|
363
|
-
codeRates: metrics.codeRates
|
|
341
|
+
cls: metrics.clsScore
|
|
364
342
|
}];
|
|
365
343
|
let semanticReport = null;
|
|
366
344
|
if (config.clusterLogs) {
|
|
@@ -382,10 +360,7 @@ async function runStandardStressTest(config) {
|
|
|
382
360
|
vuRampUpVelocity: config.threads / config.durationSec,
|
|
383
361
|
lcp: metrics.lcpMs,
|
|
384
362
|
fid: metrics.fidMs,
|
|
385
|
-
cls: metrics.clsScore
|
|
386
|
-
econnresetRate: metrics.econnresetRate,
|
|
387
|
-
econnrefusedCount: metrics.econnrefusedCount,
|
|
388
|
-
codeRates: metrics.codeRates
|
|
363
|
+
cls: metrics.clsScore
|
|
389
364
|
};
|
|
390
365
|
const isPassed = metrics.apdexScore >= config.targetApdex && metrics.errorRate <= config.targetErrorRate;
|
|
391
366
|
const verdictReason = isPassed ? "Static single-wave baseline checks concluded successfully without triggering health boundaries." : "Static verification loop completed with values exceeding defined quality thresholds.";
|
|
@@ -417,26 +392,14 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
417
392
|
const isBreached = threads > targetThresholdBreak;
|
|
418
393
|
const stressFactor = isBreached ? Math.pow(threads / targetThresholdBreak, 1.5) : 1;
|
|
419
394
|
const errorPool = getFallbackClusterLogs();
|
|
420
|
-
const targetFailureCodes = [400, 401, 403, 404, 429, 500, 502, 503, 504];
|
|
421
395
|
for (let i = 0; i < totalRequests; i++) {
|
|
422
|
-
const isError = Math.random() < (isBreached ? 0.
|
|
396
|
+
const isError = Math.random() < (isBreached ? 0.05 : 1e-3);
|
|
423
397
|
const baseLatency = (25 + Math.random() * 35) * stressFactor;
|
|
424
398
|
let errorMessage;
|
|
425
399
|
let statusCode = 200;
|
|
426
400
|
if (isError) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
statusCode = 502;
|
|
430
|
-
errorMessage = "Error: ECONNRESET socket hang up abruptly by remote host";
|
|
431
|
-
} else if (coin < 0.5) {
|
|
432
|
-
statusCode = 503;
|
|
433
|
-
errorMessage = "Error: ECONNREFUSED 127.0.0.1:8080 - connection rejected by destination target";
|
|
434
|
-
} else {
|
|
435
|
-
statusCode = targetFailureCodes[Math.floor(Math.random() * targetFailureCodes.length)];
|
|
436
|
-
errorMessage = errorPool[Math.floor(Math.random() * errorPool.length)];
|
|
437
|
-
}
|
|
438
|
-
} else {
|
|
439
|
-
if (Math.random() < 0.03) statusCode = 302;
|
|
401
|
+
statusCode = Math.random() > 0.3 ? 500 : 404;
|
|
402
|
+
errorMessage = errorPool[Math.floor(Math.random() * errorPool.length)];
|
|
440
403
|
}
|
|
441
404
|
data.push({
|
|
442
405
|
durationMs: isError ? baseLatency * 0.1 : baseLatency,
|
|
@@ -461,29 +424,13 @@ function processMetricsTelemetry(requests, durationSec, apdexT) {
|
|
|
461
424
|
const avgTlsMs = mathUtils.mean(requests.map((r) => r.tlsTimeMs || 0));
|
|
462
425
|
const avgTtfbMs = avgDnsMs + avgTcpMs + avgTlsMs + avgLatencyMs * 0.3;
|
|
463
426
|
let c1xx = 0, c2xx = 0, c3xx = 0, c4xx = 0, c5xx = 0;
|
|
464
|
-
let econnresetCount = 0;
|
|
465
|
-
let econnrefusedCount = 0;
|
|
466
|
-
const targetCodes = [400, 401, 403, 404, 429, 500, 502, 503, 504];
|
|
467
|
-
const codeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 0, 502: 0, 503: 0, 504: 0 };
|
|
468
427
|
requests.forEach((r) => {
|
|
469
428
|
if (r.statusCode >= 100 && r.statusCode < 200) c1xx++;
|
|
470
429
|
else if (r.statusCode >= 200 && r.statusCode < 300) c2xx++;
|
|
471
430
|
else if (r.statusCode >= 300 && r.statusCode < 400) c3xx++;
|
|
472
431
|
else if (r.statusCode >= 400 && r.statusCode < 500) c4xx++;
|
|
473
432
|
else if (r.statusCode >= 500) c5xx++;
|
|
474
|
-
if (r.statusCode in codeCounts) {
|
|
475
|
-
codeCounts[r.statusCode]++;
|
|
476
|
-
}
|
|
477
|
-
if (r.errorMessage) {
|
|
478
|
-
if (r.errorMessage.includes("ECONNRESET")) econnresetCount++;
|
|
479
|
-
if (r.errorMessage.includes("ECONNREFUSED")) econnrefusedCount++;
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
const codeRates = {};
|
|
483
|
-
targetCodes.forEach((code) => {
|
|
484
|
-
codeRates[code] = totalRequests === 0 ? 0 : codeCounts[code] / totalRequests * 100;
|
|
485
433
|
});
|
|
486
|
-
const econnresetRate = totalRequests === 0 ? 0 : econnresetCount / totalRequests * 100;
|
|
487
434
|
const errorCount = c4xx + c5xx;
|
|
488
435
|
const errorRate = totalRequests === 0 ? 0 : errorCount / totalRequests;
|
|
489
436
|
const satisfied = requests.filter((r) => r.durationMs <= apdexT && r.statusCode < 400).length;
|
|
@@ -513,12 +460,7 @@ function processMetricsTelemetry(requests, durationSec, apdexT) {
|
|
|
513
460
|
bandwidthMb,
|
|
514
461
|
lcpMs,
|
|
515
462
|
fidMs,
|
|
516
|
-
clsScore
|
|
517
|
-
econnresetCount,
|
|
518
|
-
econnresetRate,
|
|
519
|
-
econnrefusedCount,
|
|
520
|
-
codeCounts,
|
|
521
|
-
codeRates
|
|
463
|
+
clsScore
|
|
522
464
|
};
|
|
523
465
|
}
|
|
524
466
|
function printMatrixDashboard(m, threads) {
|
|
@@ -528,7 +470,7 @@ function printMatrixDashboard(m, threads) {
|
|
|
528
470
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
529
471
|
console.log(`| ${pad(threads, 7)} | ${pad(m.totalRequests, 9)} | ${pad(m.avgLatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.p95LatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.requestsPerSecond.toFixed(0) + "/s", 10)} | ${pad((m.errorRate * 100).toFixed(2) + "%", 10)} | ${pad(m.apdexScore.toFixed(2), 9)} |`);
|
|
530
472
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
531
|
-
console.log(`|
|
|
473
|
+
console.log(`| Simulated Web Vitals Equivalent -> LCP: ${m.lcpMs.toFixed(0)}ms | FID: ${m.fidMs.toFixed(1)}ms | CLS: ${m.clsScore.toFixed(3)} |`);
|
|
532
474
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
533
475
|
}
|
|
534
476
|
function generateFinalAgentReport(history) {
|
|
@@ -551,7 +493,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
551
493
|
const activeThreadsData = history.map((h) => h.threads);
|
|
552
494
|
const ttfTrendData = history.map((h) => h.avgLatency * 1.1);
|
|
553
495
|
const waveListItems = history.map((h) => {
|
|
554
|
-
return `<div class="wave-item">Wave (${h.threads} VUs): P95 ${h.p95Latency.toFixed(1)}ms,
|
|
496
|
+
return `<div class="wave-item">Wave (${h.threads} VUs): P95 ${h.p95Latency.toFixed(1)}ms, Errors ${(h.errorRate * 100).toFixed(1)}%, LCP ${h.lcp.toFixed(0)}ms</div>`;
|
|
555
497
|
}).join("");
|
|
556
498
|
const estimatedMonthlyCost = (cards.throughput * 0.045 * 24 * 30).toFixed(2);
|
|
557
499
|
const recommendedCpuCores = Math.max(2, Math.ceil(cards.saturationKneePoint / 75));
|
|
@@ -567,56 +509,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
567
509
|
const lcpStat = getLcpStatus(cards.lcp);
|
|
568
510
|
const fidStat = getFidStatus(cards.fid);
|
|
569
511
|
const clsStat = getClsStatus(cards.cls);
|
|
570
|
-
const connectionDiagnosticsPanelHtml = `
|
|
571
|
-
<div class="card" style="margin-top: 2rem; background: #131c2e; border: 1px solid #1e293b;">
|
|
572
|
-
<h3 style="color: #38bdf8; font-size: 1.2rem; border-bottom: none; margin-bottom: 0.25rem;">
|
|
573
|
-
\u{1F50C} Network Connection & Detailed HTTP Status Diagnostics
|
|
574
|
-
</h3>
|
|
575
|
-
<div style="color: #94a3b8; font-size: 0.9rem; margin-bottom: 1.5rem;">
|
|
576
|
-
Real-time breakdown tracking transport anomalies and precise layer-7 distribution indicators.
|
|
577
|
-
</div>
|
|
578
|
-
|
|
579
|
-
<div style="display: grid; grid-template-columns: 1fr 2fr; gap: 2rem; flex-wrap: wrap;">
|
|
580
|
-
<div style="display: flex; flex-direction: column; gap: 1rem;">
|
|
581
|
-
<div style="background: #090d16; padding: 1.25rem; border-radius: 6px; border: 1px solid #1e293b;">
|
|
582
|
-
<div style="font-size: 0.75rem; color: #64748b; text-transform: uppercase; font-weight: bold;">ECONNRESET Rate</div>
|
|
583
|
-
<div style="font-size: 1.8rem; font-weight: bold; color: ${cards.econnresetRate > 1 ? "#ef4444" : "#10b981"};">
|
|
584
|
-
${cards.econnresetRate.toFixed(2)}<span style="font-size: 1rem; color: #94a3b8;"> %</span>
|
|
585
|
-
</div>
|
|
586
|
-
<div style="font-size: 0.8rem; color: #64748b; margin-top: 0.25rem;">Abrupt remote host termination frequency</div>
|
|
587
|
-
</div>
|
|
588
|
-
|
|
589
|
-
<div style="background: #090d16; padding: 1.25rem; border-radius: 6px; border: 1px solid #1e293b;">
|
|
590
|
-
<div style="font-size: 0.75rem; color: #64748b; text-transform: uppercase; font-weight: bold;">ECONNREFUSED Count</div>
|
|
591
|
-
<div style="font-size: 1.8rem; font-weight: bold; color: ${cards.econnrefusedCount > 0 ? "#f59e0b" : "#10b981"};">
|
|
592
|
-
${cards.econnrefusedCount}<span style="font-size: 1rem; color: #94a3b8;"> drops</span>
|
|
593
|
-
</div>
|
|
594
|
-
<div style="font-size: 0.8rem; color: #64748b; margin-top: 0.25rem;">Total complete backend port link rejections</div>
|
|
595
|
-
</div>
|
|
596
|
-
</div>
|
|
597
|
-
|
|
598
|
-
<div style="background: #090d16; padding: 1.25rem; border-radius: 6px; border: 1px solid #1e293b;">
|
|
599
|
-
<div style="font-size: 0.85rem; font-weight: bold; color: #f8fafc; margin-bottom: 1rem;">Target Response Code Matrix Rates</div>
|
|
600
|
-
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem;">
|
|
601
|
-
${Object.keys(cards.codeRates).map((code) => {
|
|
602
|
-
const percentage = cards.codeRates[code];
|
|
603
|
-
let textColor = "#cbd5e1";
|
|
604
|
-
if (percentage > 0) {
|
|
605
|
-
textColor = code.startsWith("5") ? "#f87171" : "#fde047";
|
|
606
|
-
}
|
|
607
|
-
return `
|
|
608
|
-
<div style="background: #131c2e; padding: 0.75rem; border-radius: 4px; border: 1px solid #1e293b; text-align: center;">
|
|
609
|
-
<div style="font-size: 0.8rem; font-weight: bold; color: #94a3b8;">Code ${code}</div>
|
|
610
|
-
<div style="font-size: 1.1rem; font-weight: bold; margin-top: 0.25rem; color: ${textColor};">
|
|
611
|
-
${percentage.toFixed(2)}%
|
|
612
|
-
</div>
|
|
613
|
-
</div>
|
|
614
|
-
`;
|
|
615
|
-
}).join("")}
|
|
616
|
-
</div>
|
|
617
|
-
</div>
|
|
618
|
-
</div>
|
|
619
|
-
</div>`;
|
|
620
512
|
let logClustersHtml = "";
|
|
621
513
|
if (semanticReport) {
|
|
622
514
|
const totalLogCount = semanticReport.clusters.reduce((sum, c) => sum + c.count, 0);
|
|
@@ -627,7 +519,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
627
519
|
\u{1F9E0} Interactive Remediation Playbooks & Log Classification
|
|
628
520
|
</h3>
|
|
629
521
|
<div style="color: #94a3b8; font-size: 0.9rem; margin-bottom: 1.5rem;">
|
|
630
|
-
Captured <strong style="color: #f8fafc;">${totalLogCount}</strong> raw failures grouped into <strong style="color: #f8fafc;">${uniquePatternsCount}</strong> unique structural patterns.
|
|
522
|
+
Captured <strong style="color: #f8fafc;">${totalLogCount}</strong> raw failures grouped into <strong style="color: #f8fafc;">${uniquePatternsCount}</strong> unique structural patterns. Expand a playbook to inspect automated remediation strategies and diagnostics confidence ratings.
|
|
631
523
|
</div>
|
|
632
524
|
|
|
633
525
|
<div style="display: flex; flex-direction: column; gap: 1rem;">
|
|
@@ -650,11 +542,11 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
650
542
|
let explanation = "High concurrency is causing socket/connection starvation. Increase connection limits or enable pooling keep-alives.";
|
|
651
543
|
if (c.category === "Authentication_Error") {
|
|
652
544
|
fixTitle = "Auth Token / JWT Strategy";
|
|
653
|
-
fixCode = "// Implement token caching and silent rotation
|
|
545
|
+
fixCode = "// Implement token caching and silent rotation\napp.use(authMiddleware({ cacheTtl: 300, allowGracePeriod: 60 }));";
|
|
654
546
|
explanation = "Frequent token verification failures under load. Extend signature verification cache or decouple auth validation check.";
|
|
655
547
|
} else if (c.category === "Product_Error") {
|
|
656
548
|
fixTitle = "Application Null-Safety / Guard Fix";
|
|
657
|
-
fixCode = "const configId = payload?.config_id ?? defaultConfigurationId
|
|
549
|
+
fixCode = "const configId = payload?.config_id ?? defaultConfigurationId;\nif (!configId) throw new ValidationError('Missing config_id');";
|
|
658
550
|
explanation = "Runtime reference error for undefined payload field under race condition spikes. Add optional chaining and input contracts.";
|
|
659
551
|
}
|
|
660
552
|
const snippetId = `snippet-${idx}`;
|
|
@@ -912,8 +804,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
912
804
|
<th>Throughput</th>
|
|
913
805
|
<th>Avg Latency</th>
|
|
914
806
|
<th>P95 Latency</th>
|
|
915
|
-
<th>
|
|
916
|
-
<th>
|
|
807
|
+
<th>Simulated LCP</th>
|
|
808
|
+
<th>Error Rate</th>
|
|
917
809
|
<th>Status</th>
|
|
918
810
|
</tr>
|
|
919
811
|
</thead>
|
|
@@ -925,15 +817,14 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
925
817
|
<td>${h.throughput.toFixed(0)} req/sec</td>
|
|
926
818
|
<td>${h.avgLatency.toFixed(1)} ms</td>
|
|
927
819
|
<td>${h.p95Latency.toFixed(1)} ms</td>
|
|
928
|
-
<td>${h.
|
|
929
|
-
<td>${h.
|
|
820
|
+
<td>${h.lcp.toFixed(0)} ms</td>
|
|
821
|
+
<td>${(h.errorRate * 100).toFixed(2)}%</td>
|
|
930
822
|
<td><span class="badge ${isPassed ? "badge-success" : "badge-fail"}">${isPassed ? "SLO PASS" : "SLO BREACH"}</span></td>
|
|
931
823
|
</tr>`;
|
|
932
824
|
}).join("")}
|
|
933
825
|
</tbody>
|
|
934
826
|
</table>
|
|
935
827
|
</div>
|
|
936
|
-
${connectionDiagnosticsPanelHtml}
|
|
937
828
|
${liveAdjusterHtml}
|
|
938
829
|
${rightSizingHtml}
|
|
939
830
|
${logClustersHtml}
|
|
@@ -953,6 +844,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
953
844
|
const baseThroughput = ${cards.throughput};
|
|
954
845
|
const baseLatency = ${cards.ttfb};
|
|
955
846
|
|
|
847
|
+
// Live Concurrency Adjuster interactive client logic
|
|
956
848
|
const slider = document.getElementById('concurrencySlider');
|
|
957
849
|
const sliderVal = document.getElementById('sliderValue');
|
|
958
850
|
const simThroughput = document.getElementById('simThroughput');
|
|
@@ -1037,8 +929,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
1037
929
|
},
|
|
1038
930
|
scales: {
|
|
1039
931
|
x: { grid: { color: '#1e293b' }, ticks: { color: '#64748b' } },
|
|
1040
|
-
|
|
1041
|
-
|
|
932
|
+
y_threads: { position: 'left', grid: { color: '#1e293b' }, ticks: { color: '#38bdf8' }, title: { display: true, text: 'VUs / Threads', color: '#38bdf8' } },
|
|
933
|
+
y_ttf: { position: 'right', grid: { drawOnChartArea: false }, ticks: { color: '#f43f5e' }, title: { display: true, text: 'TTF Index / Latency ms', color: '#f43f5e' } }
|
|
1042
934
|
}
|
|
1043
935
|
}
|
|
1044
936
|
});
|
|
@@ -1096,6 +988,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
1096
988
|
}
|
|
1097
989
|
}
|
|
1098
990
|
function printUsage() {
|
|
1099
|
-
console.log(`Blaze Core Performance Test CLI Engine
|
|
991
|
+
console.log(`Blaze Core Performance Test CLI Engine
|
|
992
|
+
Options:
|
|
993
|
+
--threads <count> | --duration <seconds> | --agentic | --cluster-logs | --correlate | --apdex-t <ms>`);
|
|
1100
994
|
}
|
|
1101
995
|
main().catch(console.error);
|
|
Binary file
|