blaze-performance-tester 3.1.7 → 3.1.8
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 +129 -23
- package/dist/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -224,6 +224,9 @@ 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 };
|
|
227
230
|
let currentThreads = Math.min(config.maxThreads, Math.max(5, Math.floor(config.maxThreads * 0.2)));
|
|
228
231
|
let baseStep = config.stepSize;
|
|
229
232
|
let isStable = true;
|
|
@@ -241,6 +244,11 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
241
244
|
total3xx += metrics.c3xx;
|
|
242
245
|
total4xx += metrics.c4xx;
|
|
243
246
|
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
|
+
});
|
|
244
252
|
globalMetricsAccumulator.dns.push(metrics.avgDnsMs);
|
|
245
253
|
globalMetricsAccumulator.tcp.push(metrics.avgTcpMs);
|
|
246
254
|
globalMetricsAccumulator.tls.push(metrics.avgTlsMs);
|
|
@@ -261,7 +269,10 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
261
269
|
failedRequests: metrics.c4xx + metrics.c5xx,
|
|
262
270
|
lcp: metrics.lcpMs,
|
|
263
271
|
fid: metrics.fidMs,
|
|
264
|
-
cls: metrics.clsScore
|
|
272
|
+
cls: metrics.clsScore,
|
|
273
|
+
econnresetRate: metrics.econnresetRate,
|
|
274
|
+
econnrefusedCount: metrics.econnrefusedCount,
|
|
275
|
+
codeRates: metrics.codeRates
|
|
265
276
|
};
|
|
266
277
|
printMatrixDashboard(metrics, currentThreads);
|
|
267
278
|
history.push(currentState);
|
|
@@ -305,6 +316,11 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
305
316
|
}
|
|
306
317
|
const totalTestSeconds = history.length * config.durationSec;
|
|
307
318
|
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
|
+
});
|
|
308
324
|
const finalSummaryCards = {
|
|
309
325
|
apdex: history[history.length - 1]?.apdex || 0,
|
|
310
326
|
throughput: history[history.length - 1]?.throughput || 0,
|
|
@@ -318,7 +334,10 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
318
334
|
vuRampUpVelocity,
|
|
319
335
|
lcp: mathUtils.mean(globalMetricsAccumulator.lcp),
|
|
320
336
|
fid: mathUtils.mean(globalMetricsAccumulator.fid),
|
|
321
|
-
cls: mathUtils.mean(globalMetricsAccumulator.cls)
|
|
337
|
+
cls: mathUtils.mean(globalMetricsAccumulator.cls),
|
|
338
|
+
econnresetRate: totalGlobalRequests === 0 ? 0 : totalEconnreset / totalGlobalRequests * 100,
|
|
339
|
+
econnrefusedCount: totalEconnrefused,
|
|
340
|
+
codeRates: aggregatedCodeRates
|
|
322
341
|
};
|
|
323
342
|
generateFinalAgentReport(history);
|
|
324
343
|
exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx }, finalSummaryCards, lastRawRequests);
|
|
@@ -338,7 +357,10 @@ async function runStandardStressTest(config) {
|
|
|
338
357
|
failedRequests: metrics.c4xx + metrics.c5xx,
|
|
339
358
|
lcp: metrics.lcpMs,
|
|
340
359
|
fid: metrics.fidMs,
|
|
341
|
-
cls: metrics.clsScore
|
|
360
|
+
cls: metrics.clsScore,
|
|
361
|
+
econnresetRate: metrics.econnresetRate,
|
|
362
|
+
econnrefusedCount: metrics.econnrefusedCount,
|
|
363
|
+
codeRates: metrics.codeRates
|
|
342
364
|
}];
|
|
343
365
|
let semanticReport = null;
|
|
344
366
|
if (config.clusterLogs) {
|
|
@@ -360,7 +382,10 @@ async function runStandardStressTest(config) {
|
|
|
360
382
|
vuRampUpVelocity: config.threads / config.durationSec,
|
|
361
383
|
lcp: metrics.lcpMs,
|
|
362
384
|
fid: metrics.fidMs,
|
|
363
|
-
cls: metrics.clsScore
|
|
385
|
+
cls: metrics.clsScore,
|
|
386
|
+
econnresetRate: metrics.econnresetRate,
|
|
387
|
+
econnrefusedCount: metrics.econnrefusedCount,
|
|
388
|
+
codeRates: metrics.codeRates
|
|
364
389
|
};
|
|
365
390
|
const isPassed = metrics.apdexScore >= config.targetApdex && metrics.errorRate <= config.targetErrorRate;
|
|
366
391
|
const verdictReason = isPassed ? "Static single-wave baseline checks concluded successfully without triggering health boundaries." : "Static verification loop completed with values exceeding defined quality thresholds.";
|
|
@@ -392,14 +417,26 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs) {
|
|
|
392
417
|
const isBreached = threads > targetThresholdBreak;
|
|
393
418
|
const stressFactor = isBreached ? Math.pow(threads / targetThresholdBreak, 1.5) : 1;
|
|
394
419
|
const errorPool = getFallbackClusterLogs();
|
|
420
|
+
const targetFailureCodes = [400, 401, 403, 404, 429, 500, 502, 503, 504];
|
|
395
421
|
for (let i = 0; i < totalRequests; i++) {
|
|
396
|
-
const isError = Math.random() < (isBreached ? 0.
|
|
422
|
+
const isError = Math.random() < (isBreached ? 0.08 : 5e-3);
|
|
397
423
|
const baseLatency = (25 + Math.random() * 35) * stressFactor;
|
|
398
424
|
let errorMessage;
|
|
399
425
|
let statusCode = 200;
|
|
400
426
|
if (isError) {
|
|
401
|
-
|
|
402
|
-
|
|
427
|
+
const coin = Math.random();
|
|
428
|
+
if (coin < 0.25) {
|
|
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;
|
|
403
440
|
}
|
|
404
441
|
data.push({
|
|
405
442
|
durationMs: isError ? baseLatency * 0.1 : baseLatency,
|
|
@@ -424,13 +461,29 @@ function processMetricsTelemetry(requests, durationSec, apdexT) {
|
|
|
424
461
|
const avgTlsMs = mathUtils.mean(requests.map((r) => r.tlsTimeMs || 0));
|
|
425
462
|
const avgTtfbMs = avgDnsMs + avgTcpMs + avgTlsMs + avgLatencyMs * 0.3;
|
|
426
463
|
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 };
|
|
427
468
|
requests.forEach((r) => {
|
|
428
469
|
if (r.statusCode >= 100 && r.statusCode < 200) c1xx++;
|
|
429
470
|
else if (r.statusCode >= 200 && r.statusCode < 300) c2xx++;
|
|
430
471
|
else if (r.statusCode >= 300 && r.statusCode < 400) c3xx++;
|
|
431
472
|
else if (r.statusCode >= 400 && r.statusCode < 500) c4xx++;
|
|
432
473
|
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;
|
|
433
485
|
});
|
|
486
|
+
const econnresetRate = totalRequests === 0 ? 0 : econnresetCount / totalRequests * 100;
|
|
434
487
|
const errorCount = c4xx + c5xx;
|
|
435
488
|
const errorRate = totalRequests === 0 ? 0 : errorCount / totalRequests;
|
|
436
489
|
const satisfied = requests.filter((r) => r.durationMs <= apdexT && r.statusCode < 400).length;
|
|
@@ -460,7 +513,12 @@ function processMetricsTelemetry(requests, durationSec, apdexT) {
|
|
|
460
513
|
bandwidthMb,
|
|
461
514
|
lcpMs,
|
|
462
515
|
fidMs,
|
|
463
|
-
clsScore
|
|
516
|
+
clsScore,
|
|
517
|
+
econnresetCount,
|
|
518
|
+
econnresetRate,
|
|
519
|
+
econnrefusedCount,
|
|
520
|
+
codeCounts,
|
|
521
|
+
codeRates
|
|
464
522
|
};
|
|
465
523
|
}
|
|
466
524
|
function printMatrixDashboard(m, threads) {
|
|
@@ -470,7 +528,7 @@ function printMatrixDashboard(m, threads) {
|
|
|
470
528
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
471
529
|
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)} |`);
|
|
472
530
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
473
|
-
console.log(`|
|
|
531
|
+
console.log(`| Network State -> RESET Rate: ${m.econnresetRate.toFixed(2)}% | REFUSED Count: ${m.econnrefusedCount} | Web Vitals -> LCP: ${m.lcpMs.toFixed(0)}ms |`);
|
|
474
532
|
console.log(`-----------------------------------------------------------------------------------------`);
|
|
475
533
|
}
|
|
476
534
|
function generateFinalAgentReport(history) {
|
|
@@ -493,7 +551,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
493
551
|
const activeThreadsData = history.map((h) => h.threads);
|
|
494
552
|
const ttfTrendData = history.map((h) => h.avgLatency * 1.1);
|
|
495
553
|
const waveListItems = history.map((h) => {
|
|
496
|
-
return `<div class="wave-item">Wave (${h.threads} VUs): P95 ${h.p95Latency.toFixed(1)}ms,
|
|
554
|
+
return `<div class="wave-item">Wave (${h.threads} VUs): P95 ${h.p95Latency.toFixed(1)}ms, ECONNRESET Rate: ${h.econnresetRate.toFixed(1)}%, REFUSED: ${h.econnrefusedCount}</div>`;
|
|
497
555
|
}).join("");
|
|
498
556
|
const estimatedMonthlyCost = (cards.throughput * 0.045 * 24 * 30).toFixed(2);
|
|
499
557
|
const recommendedCpuCores = Math.max(2, Math.ceil(cards.saturationKneePoint / 75));
|
|
@@ -509,6 +567,56 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
509
567
|
const lcpStat = getLcpStatus(cards.lcp);
|
|
510
568
|
const fidStat = getFidStatus(cards.fid);
|
|
511
569
|
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>`;
|
|
512
620
|
let logClustersHtml = "";
|
|
513
621
|
if (semanticReport) {
|
|
514
622
|
const totalLogCount = semanticReport.clusters.reduce((sum, c) => sum + c.count, 0);
|
|
@@ -519,7 +627,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
519
627
|
\u{1F9E0} Interactive Remediation Playbooks & Log Classification
|
|
520
628
|
</h3>
|
|
521
629
|
<div style="color: #94a3b8; font-size: 0.9rem; margin-bottom: 1.5rem;">
|
|
522
|
-
Captured <strong style="color: #f8fafc;">${totalLogCount}</strong> raw failures grouped into <strong style="color: #f8fafc;">${uniquePatternsCount}</strong> unique structural patterns.
|
|
630
|
+
Captured <strong style="color: #f8fafc;">${totalLogCount}</strong> raw failures grouped into <strong style="color: #f8fafc;">${uniquePatternsCount}</strong> unique structural patterns.
|
|
523
631
|
</div>
|
|
524
632
|
|
|
525
633
|
<div style="display: flex; flex-direction: column; gap: 1rem;">
|
|
@@ -542,11 +650,11 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
542
650
|
let explanation = "High concurrency is causing socket/connection starvation. Increase connection limits or enable pooling keep-alives.";
|
|
543
651
|
if (c.category === "Authentication_Error") {
|
|
544
652
|
fixTitle = "Auth Token / JWT Strategy";
|
|
545
|
-
fixCode = "// Implement token caching and silent rotation
|
|
653
|
+
fixCode = "// Implement token caching and silent rotation\\napp.use(authMiddleware({ cacheTtl: 300, allowGracePeriod: 60 }));";
|
|
546
654
|
explanation = "Frequent token verification failures under load. Extend signature verification cache or decouple auth validation check.";
|
|
547
655
|
} else if (c.category === "Product_Error") {
|
|
548
656
|
fixTitle = "Application Null-Safety / Guard Fix";
|
|
549
|
-
fixCode = "const configId = payload?.config_id ?? defaultConfigurationId
|
|
657
|
+
fixCode = "const configId = payload?.config_id ?? defaultConfigurationId;\\nif (!configId) throw new ValidationError('Missing config_id');";
|
|
550
658
|
explanation = "Runtime reference error for undefined payload field under race condition spikes. Add optional chaining and input contracts.";
|
|
551
659
|
}
|
|
552
660
|
const snippetId = `snippet-${idx}`;
|
|
@@ -804,8 +912,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
804
912
|
<th>Throughput</th>
|
|
805
913
|
<th>Avg Latency</th>
|
|
806
914
|
<th>P95 Latency</th>
|
|
807
|
-
<th>
|
|
808
|
-
<th>
|
|
915
|
+
<th>ECONNRESET Rate</th>
|
|
916
|
+
<th>ECONNREFUSED</th>
|
|
809
917
|
<th>Status</th>
|
|
810
918
|
</tr>
|
|
811
919
|
</thead>
|
|
@@ -817,14 +925,15 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
817
925
|
<td>${h.throughput.toFixed(0)} req/sec</td>
|
|
818
926
|
<td>${h.avgLatency.toFixed(1)} ms</td>
|
|
819
927
|
<td>${h.p95Latency.toFixed(1)} ms</td>
|
|
820
|
-
<td>${h.
|
|
821
|
-
<td>${
|
|
928
|
+
<td>${h.econnresetRate.toFixed(2)}%</td>
|
|
929
|
+
<td>${h.econnrefusedCount} nodes</td>
|
|
822
930
|
<td><span class="badge ${isPassed ? "badge-success" : "badge-fail"}">${isPassed ? "SLO PASS" : "SLO BREACH"}</span></td>
|
|
823
931
|
</tr>`;
|
|
824
932
|
}).join("")}
|
|
825
933
|
</tbody>
|
|
826
934
|
</table>
|
|
827
935
|
</div>
|
|
936
|
+
${connectionDiagnosticsPanelHtml}
|
|
828
937
|
${liveAdjusterHtml}
|
|
829
938
|
${rightSizingHtml}
|
|
830
939
|
${logClustersHtml}
|
|
@@ -844,7 +953,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
844
953
|
const baseThroughput = ${cards.throughput};
|
|
845
954
|
const baseLatency = ${cards.ttfb};
|
|
846
955
|
|
|
847
|
-
// Live Concurrency Adjuster interactive client logic
|
|
848
956
|
const slider = document.getElementById('concurrencySlider');
|
|
849
957
|
const sliderVal = document.getElementById('sliderValue');
|
|
850
958
|
const simThroughput = document.getElementById('simThroughput');
|
|
@@ -929,8 +1037,8 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
929
1037
|
},
|
|
930
1038
|
scales: {
|
|
931
1039
|
x: { grid: { color: '#1e293b' }, ticks: { color: '#64748b' } },
|
|
932
|
-
|
|
933
|
-
|
|
1040
|
+
yThreads: { position: 'left', grid: { color: '#1e293b' }, ticks: { color: '#38bdf8' }, title: { display: true, text: 'VUs / Threads', color: '#38bdf8' } },
|
|
1041
|
+
yTtf: { position: 'right', grid: { drawOnChartArea: false }, ticks: { color: '#f43f5e' }, title: { display: true, text: 'TTF Index / Latency ms', color: '#f43f5e' } }
|
|
934
1042
|
}
|
|
935
1043
|
}
|
|
936
1044
|
});
|
|
@@ -988,8 +1096,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
988
1096
|
}
|
|
989
1097
|
}
|
|
990
1098
|
function printUsage() {
|
|
991
|
-
console.log(`Blaze Core Performance Test CLI Engine
|
|
992
|
-
Options:
|
|
993
|
-
--threads <count> | --duration <seconds> | --agentic | --cluster-logs | --correlate | --apdex-t <ms>`);
|
|
1099
|
+
console.log(`Blaze Core Performance Test CLI Engine\\nOptions:\\n --threads <count> | --duration <seconds> | --agentic | --cluster-logs | --correlate | --apdex-t <ms>`);
|
|
994
1100
|
}
|
|
995
1101
|
main().catch(console.error);
|
|
Binary file
|