blaze-performance-tester 3.0.37 → 3.0.39
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 +62 -32
- package/dist/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -293,6 +293,8 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
293
293
|
const analyzer = new LogAnalyzer();
|
|
294
294
|
semanticReport = analyzer.process(aggregateErrorLogs);
|
|
295
295
|
}
|
|
296
|
+
const totalTestSeconds = history.length * config.durationSec;
|
|
297
|
+
const vuRampUpVelocity = history.length > 1 && totalTestSeconds > 0 ? (history[history.length - 1].threads - history[0].threads) / totalTestSeconds : config.threads / config.durationSec;
|
|
296
298
|
const finalSummaryCards = {
|
|
297
299
|
apdex: history[history.length - 1]?.apdex || 0,
|
|
298
300
|
throughput: history[history.length - 1]?.throughput || 0,
|
|
@@ -302,7 +304,8 @@ async function runIntelligentAgenticStressTest(config) {
|
|
|
302
304
|
tcp: mathUtils.mean(globalMetricsAccumulator.tcp),
|
|
303
305
|
tls: mathUtils.mean(globalMetricsAccumulator.tls),
|
|
304
306
|
stdDev: mathUtils.stdDev(globalMetricsAccumulator.latencies, mathUtils.mean(globalMetricsAccumulator.latencies)),
|
|
305
|
-
saturationKneePoint: saturationKneePoint || history[history.length - 1]?.threads || 50
|
|
307
|
+
saturationKneePoint: saturationKneePoint || history[history.length - 1]?.threads || 50,
|
|
308
|
+
vuRampUpVelocity
|
|
306
309
|
};
|
|
307
310
|
generateFinalAgentReport(history);
|
|
308
311
|
exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx }, finalSummaryCards, lastRawRequests);
|
|
@@ -337,7 +340,8 @@ async function runStandardStressTest(config) {
|
|
|
337
340
|
tcp: metrics.avgTcpMs,
|
|
338
341
|
tls: metrics.avgTlsMs,
|
|
339
342
|
stdDev: metrics.stdDevMs,
|
|
340
|
-
saturationKneePoint: config.threads
|
|
343
|
+
saturationKneePoint: config.threads,
|
|
344
|
+
vuRampUpVelocity: config.threads / config.durationSec
|
|
341
345
|
};
|
|
342
346
|
const isPassed = metrics.apdexScore >= config.targetApdex && metrics.errorRate <= config.targetErrorRate;
|
|
343
347
|
const verdictReason = isPassed ? "Static single-wave baseline checks concluded successfully without triggering health boundaries." : "Static verification loop completed with values exceeding defined quality thresholds.";
|
|
@@ -480,23 +484,14 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
480
484
|
logClustersHtml = `
|
|
481
485
|
<div class="card" style="margin-top: 2rem; background: #131c2e; border: 1px solid #1e293b;">
|
|
482
486
|
<h3 style="border-bottom: none; padding-bottom: 0rem; margin-bottom: 0.25rem; display: flex; align-items: center; gap: 0.5rem; color: #ffffff; font-size: 1.2rem;">
|
|
483
|
-
\u{1F9E0}
|
|
487
|
+
\u{1F9E0} Interactive Remediation Playbooks & Log Classification
|
|
484
488
|
</h3>
|
|
485
489
|
<div style="color: #94a3b8; font-size: 0.9rem; margin-bottom: 1.5rem;">
|
|
486
|
-
Captured <strong style="color: #f8fafc;">${totalLogCount}</strong> raw failures grouped into <strong style="color: #f8fafc;">${uniquePatternsCount}</strong> unique structural patterns.
|
|
490
|
+
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.
|
|
487
491
|
</div>
|
|
488
492
|
|
|
489
|
-
<
|
|
490
|
-
|
|
491
|
-
<tr style="border-bottom: 1px solid #1e293b;">
|
|
492
|
-
<th style="width: 8%; padding: 0.75rem; text-align: left; color: #64748b; font-size: 0.85rem; font-weight: bold; text-transform: none;">Count</th>
|
|
493
|
-
<th style="width: 22%; padding: 0.75rem; text-align: left; color: #64748b; font-size: 0.85rem; font-weight: bold; text-transform: none;">Classification Category</th>
|
|
494
|
-
<th style="width: 10%; padding: 0.75rem; text-align: left; color: #64748b; font-size: 0.85rem; font-weight: bold; text-transform: none;">Severity</th>
|
|
495
|
-
<th style="width: 60%; padding: 0.75rem; text-align: left; color: #64748b; font-size: 0.85rem; font-weight: bold; text-transform: none;">Structural Abstract Blueprint / Dynamic Log Fingerprint</th>
|
|
496
|
-
</tr>
|
|
497
|
-
</thead>
|
|
498
|
-
<tbody>
|
|
499
|
-
${semanticReport.clusters.map((c) => {
|
|
493
|
+
<div style="display: flex; flex-direction: column; gap: 1rem;">
|
|
494
|
+
${semanticReport.clusters.map((c, idx) => {
|
|
500
495
|
let catColor = "#fb923c";
|
|
501
496
|
if (c.category === "Authentication_Error") catColor = "#c084fc";
|
|
502
497
|
if (c.category === "Product_Error") catColor = "#f87171";
|
|
@@ -504,25 +499,46 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
504
499
|
let sevBg = c.severity === "CRITICAL" ? "#dc2626" : "#ea580c";
|
|
505
500
|
const rawTemplate = c.template || "";
|
|
506
501
|
const cleanedTemplate = rawTemplate.replace(/\[\d{4}-\d{2}-\d{2}.*?\]\s*/, "");
|
|
502
|
+
let fixTitle = "Infrastructure Pool & Tuning Fix";
|
|
503
|
+
let fixCode = "const pool = new Pool({ max: 50, idleTimeoutMillis: 30000 });";
|
|
504
|
+
let explanation = "High concurrency is causing socket/connection starvation. Increase connection limits or enable pooling keep-alives.";
|
|
505
|
+
if (c.category === "Authentication_Error") {
|
|
506
|
+
fixTitle = "Auth Token / JWT Strategy";
|
|
507
|
+
fixCode = "// Implement token caching and silent rotation\napp.use(authMiddleware({ cacheTtl: 300, allowGracePeriod: 60 }));";
|
|
508
|
+
explanation = "Frequent token verification failures under load. Extend signature verification cache or decouple auth validation check.";
|
|
509
|
+
} else if (c.category === "Product_Error") {
|
|
510
|
+
fixTitle = "Application Null-Safety / Guard Fix";
|
|
511
|
+
fixCode = "const configId = payload?.config_id ?? defaultConfigurationId;\nif (!configId) throw new ValidationError('Missing config_id');";
|
|
512
|
+
explanation = "Runtime reference error for undefined payload field under race condition spikes. Add optional chaining and input contracts.";
|
|
513
|
+
}
|
|
514
|
+
const snippetId = `snippet-${idx}`;
|
|
507
515
|
return `
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
<
|
|
511
|
-
|
|
512
|
-
<span style="
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
516
|
+
<details style="background: #090d16; border: 1px solid #1e293b; border-radius: 6px; overflow: hidden;">
|
|
517
|
+
<summary style="padding: 1rem; cursor: pointer; display: flex; align-items: center; justify-content: space-between; user-select: none;">
|
|
518
|
+
<div style="display: flex; align-items: center; gap: 1rem;">
|
|
519
|
+
<span style="font-size: 1.1rem; font-weight: bold; color: #f8fafc; background: #131c2e; padding: 0.2rem 0.6rem; border-radius: 4px;">${c.count}x</span>
|
|
520
|
+
<span style="color: ${catColor}; font-weight: 600; font-size: 0.95rem;">${c.category}</span>
|
|
521
|
+
<span style="background: ${sevBg}; color: #ffffff; padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.65rem; font-weight: bold; letter-spacing: 0.05em;">${c.severity}</span>
|
|
522
|
+
</div>
|
|
523
|
+
<div style="color: #64748b; font-size: 0.85rem; font-family: monospace;">Expand Playbook \u25BC</div>
|
|
524
|
+
</summary>
|
|
525
|
+
<div style="padding: 1.25rem; border-top: 1px solid #1e293b; background: #0f172a;">
|
|
526
|
+
<div style="margin-bottom: 1rem;">
|
|
527
|
+
<div style="color: #64748b; font-size: 0.75rem; text-transform: uppercase; font-weight: bold; margin-bottom: 0.25rem;">Detected Log Fingerprint</div>
|
|
528
|
+
<code style="color: #cbd5e1; font-family: monospace; font-size: 0.85rem; word-break: break-all;">${cleanedTemplate}</code>
|
|
529
|
+
</div>
|
|
530
|
+
<div style="margin-bottom: 1.25rem;">
|
|
531
|
+
<div style="color: #38bdf8; font-size: 0.9rem; font-weight: bold; margin-bottom: 0.25rem;">\u{1F4A1} Playbook Strategy: ${fixTitle}</div>
|
|
532
|
+
<div style="color: #94a3b8; font-size: 0.85rem; line-height: 1.4; margin-bottom: 0.75rem;">${explanation}</div>
|
|
533
|
+
<div style="position: relative; background: #0b111e; border: 1px solid #1e293b; border-radius: 4px; padding: 0.75rem;">
|
|
534
|
+
<button onclick="copyToClipboard('${snippetId}')" style="position: absolute; top: 0.5rem; right: 0.5rem; background: #1e293b; color: #38bdf8; border: none; padding: 0.2rem 0.5rem; border-radius: 3px; font-size: 0.7rem; cursor: pointer;">Copy Fix</button>
|
|
535
|
+
<pre id="${snippetId}" style="margin: 0; color: #4ade80; font-family: monospace; font-size: 0.85rem; white-space: pre-wrap;">${fixCode}</pre>
|
|
520
536
|
</div>
|
|
521
|
-
</
|
|
522
|
-
</
|
|
537
|
+
</div>
|
|
538
|
+
</div>
|
|
539
|
+
</details>`;
|
|
523
540
|
}).join("")}
|
|
524
|
-
|
|
525
|
-
</table>
|
|
541
|
+
</div>
|
|
526
542
|
</div>`;
|
|
527
543
|
}
|
|
528
544
|
const liveAdjusterHtml = `
|
|
@@ -580,7 +596,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
580
596
|
h1 { color: #38bdf8; margin: 0; font-size: 2rem; }
|
|
581
597
|
.meta { color: #94a3b8; font-size: 0.9rem; margin-top: 0.5rem; }
|
|
582
598
|
|
|
583
|
-
.cards-wrapper { display: grid; grid-template-columns: repeat(
|
|
599
|
+
.cards-wrapper { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
|
|
584
600
|
.metric-card { background: #131c2e; border: 1px solid #1e293b; border-radius: 6px; padding: 1.25rem; position: relative; }
|
|
585
601
|
.card-title { font-size: 0.75rem; font-weight: 700; color: #64748b; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem; }
|
|
586
602
|
.card-value { font-size: 1.6rem; font-weight: 700; color: #ffffff; }
|
|
@@ -588,6 +604,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
588
604
|
.card-value.green { color: #10b981; }
|
|
589
605
|
.card-value.orange { color: #f97316; }
|
|
590
606
|
.card-value.purple { color: #a855f7; }
|
|
607
|
+
.card-value.cyan { color: #38bdf8; }
|
|
591
608
|
.card-subtext { font-size: 0.8rem; color: #10b981; font-weight: 500; margin-left: 0.4rem; display: inline-block; }
|
|
592
609
|
|
|
593
610
|
.top-layout-grid { display: grid; grid-template-columns: 1fr 400px; gap: 1.5rem; margin-bottom: 2rem; }
|
|
@@ -646,6 +663,10 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
646
663
|
<div class="card-title">Avg Time To First Byte</div>
|
|
647
664
|
<div class="card-value">${cards.ttfb.toFixed(1)}<span class="unit">ms</span></div>
|
|
648
665
|
</div>
|
|
666
|
+
<div class="metric-card">
|
|
667
|
+
<div class="card-title">VU Ramp-up Velocity</div>
|
|
668
|
+
<div class="card-value cyan">${cards.vuRampUpVelocity.toFixed(1)}<span class="unit">VUs/s</span></div>
|
|
669
|
+
</div>
|
|
649
670
|
<div class="metric-card">
|
|
650
671
|
<div class="card-title">DNS Lookup</div>
|
|
651
672
|
<div class="card-value">${cards.dns.toFixed(2)}<span class="unit">ms</span></div>
|
|
@@ -760,6 +781,15 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
760
781
|
</div>
|
|
761
782
|
|
|
762
783
|
<script>
|
|
784
|
+
function copyToClipboard(containerId) {
|
|
785
|
+
const text = document.getElementById(containerId).innerText;
|
|
786
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
787
|
+
alert('Copied remediation snippet to clipboard!');
|
|
788
|
+
}).catch(err => {
|
|
789
|
+
console.error('Failed to copy text: ', err);
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
|
|
763
793
|
const labels = ${JSON.stringify(labels)};
|
|
764
794
|
const baseThroughput = ${cards.throughput};
|
|
765
795
|
const baseLatency = ${cards.ttfb};
|
|
Binary file
|