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 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.08 : 5e-3);
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
- 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;
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(`| Network State -> RESET Rate: ${m.econnresetRate.toFixed(2)}% | REFUSED Count: ${m.econnrefusedCount} | Web Vitals -> LCP: ${m.lcpMs.toFixed(0)}ms |`);
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, ECONNRESET Rate: ${h.econnresetRate.toFixed(1)}%, REFUSED: ${h.econnrefusedCount}</div>`;
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\\napp.use(authMiddleware({ cacheTtl: 300, allowGracePeriod: 60 }));";
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;\\nif (!configId) throw new ValidationError('Missing config_id');";
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>ECONNRESET Rate</th>
916
- <th>ECONNREFUSED</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.econnresetRate.toFixed(2)}%</td>
929
- <td>${h.econnrefusedCount} nodes</td>
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
- 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' } }
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\\nOptions:\\n --threads <count> | --duration <seconds> | --agentic | --cluster-logs | --correlate | --apdex-t <ms>`);
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blaze-performance-tester",
3
- "version": "3.1.14",
3
+ "version": "3.1.15",
4
4
  "description": "A high-performance, multi-threaded load testing engine built with Rust and QuickJS.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",