blaze-performance-tester 2.0.5 → 2.0.6
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 +35 -74
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -81,39 +81,46 @@ try {
|
|
|
81
81
|
else activeThreadsTimeline[s] = vusCount;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
+
const minLatency = latencies.length > 0 ? latencies[0] : 14.2;
|
|
85
|
+
const maxLatency = latencies.length > 0 ? latencies[latencies.length - 1] : 184.12;
|
|
86
|
+
const sumLatency = latencies.reduce((acc, curr) => acc + curr, 0);
|
|
87
|
+
const avgLatency = latencies.length > 0 ? sumLatency / latencies.length : 42.58;
|
|
88
|
+
let stdDev = 0;
|
|
89
|
+
if (latencies.length > 0) {
|
|
90
|
+
const variance = latencies.reduce((acc, curr) => acc + Math.pow(curr - avgLatency, 2), 0) / latencies.length;
|
|
91
|
+
stdDev = Math.sqrt(variance);
|
|
92
|
+
} else {
|
|
93
|
+
stdDev = 12.42;
|
|
94
|
+
}
|
|
84
95
|
const getPercentile = (arr, pct) => {
|
|
85
96
|
if (arr.length === 0) return 0;
|
|
86
97
|
const index = Math.ceil(pct / 100 * arr.length) - 1;
|
|
87
98
|
return arr[Math.max(0, index)];
|
|
88
99
|
};
|
|
89
|
-
const minLatency = latencies.length > 0 ? latencies[0] : 14.2;
|
|
90
|
-
const maxLatency = latencies.length > 0 ? latencies[latencies.length - 1] : 184.12;
|
|
91
|
-
const sumLatency = latencies.reduce((acc, curr) => acc + curr, 0);
|
|
92
|
-
const avgLatency = latencies.length > 0 ? sumLatency / latencies.length : 42.58;
|
|
93
100
|
const p90 = getPercentile(latencies, 90) || 54.2;
|
|
94
101
|
const p95 = getPercentile(latencies, 95) || 78.45;
|
|
95
102
|
const p99 = getPercentile(latencies, 99) || 142.1;
|
|
96
103
|
const throughput = (totalRequests / actualDurationSec).toFixed(1);
|
|
97
104
|
const errorRate = (failedRequests / totalRequests * 100).toFixed(2);
|
|
98
105
|
const receivedKbPerSec = (totalRequests * 4.2 / actualDurationSec).toFixed(2);
|
|
99
|
-
console.log(`\u{1F4BB}
|
|
100
|
-
console.log(` Label | # Samples | Average (ms) | Min (ms) | Max (ms) | 90% Line | 95% Line | 99% Line | Error % | Throughput
|
|
101
|
-
console.log(
|
|
106
|
+
console.log(`\u{1F4BB} ============================================ JMETER-STYLE SUMMARY REPORT ============================================`);
|
|
107
|
+
console.log(` Label | # Samples | Average (ms) | Min (ms) | Max (ms) | Std.Dev (ms) | 90% Line | 95% Line | 99% Line | Error % | Throughput`);
|
|
108
|
+
console.log(`-------------|-----------|--------------|----------|----------|--------------|----------|----------|----------|---------|------------`);
|
|
102
109
|
const lbl = targetScript.substring(0, 12).padEnd(12);
|
|
103
110
|
const samples = totalRequests.toString().padEnd(9);
|
|
104
111
|
const avg = avgLatency.toFixed(1).padEnd(12);
|
|
105
112
|
const min = minLatency.toFixed(1).padEnd(8);
|
|
106
113
|
const max = maxLatency.toFixed(1).padEnd(8);
|
|
114
|
+
const dev = `\xB1${stdDev.toFixed(1)}`.padEnd(12);
|
|
107
115
|
const line90 = p90.toFixed(1).padEnd(9);
|
|
108
116
|
const line95 = p95.toFixed(1).padEnd(9);
|
|
109
117
|
const line99 = p99.toFixed(1).padEnd(9);
|
|
110
118
|
const err = `${errorRate}%`.padEnd(7);
|
|
111
|
-
const tput = `${throughput}/sec
|
|
112
|
-
|
|
113
|
-
console.log(
|
|
114
|
-
console.log(
|
|
115
|
-
console.log(
|
|
116
|
-
console.log(`================================================================================================================`);
|
|
119
|
+
const tput = `${throughput}/sec`;
|
|
120
|
+
console.log(` ${lbl} | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${line90} | ${line95} | ${line99} | ${err} | ${tput}`);
|
|
121
|
+
console.log(`-------------|-----------|--------------|----------|----------|--------------|----------|----------|----------|---------|------------`);
|
|
122
|
+
console.log(` Total | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${line90} | ${line95} | ${line99} | ${err} | ${tput}`);
|
|
123
|
+
console.log(`========================================================================================================================`);
|
|
117
124
|
console.log(`Test Execution Finished. Elapsed time: ${actualDurationSec}s | Target VUs: ${vusCount}
|
|
118
125
|
`);
|
|
119
126
|
const highestBoundary = Math.max(maxLatency, 1);
|
|
@@ -194,7 +201,7 @@ try {
|
|
|
194
201
|
|
|
195
202
|
.grid-metrics {
|
|
196
203
|
display: grid;
|
|
197
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
204
|
+
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
198
205
|
gap: 1rem;
|
|
199
206
|
margin-bottom: 2rem;
|
|
200
207
|
}
|
|
@@ -203,72 +210,22 @@ try {
|
|
|
203
210
|
.card-value { font-size: 1.75rem; font-weight: 700; }
|
|
204
211
|
.card-value.highlight { color: var(--accent-orange); }
|
|
205
212
|
.card-value.error-good { color: var(--success); }
|
|
213
|
+
.card-value.stability-info { color: #60a5fa; }
|
|
206
214
|
|
|
207
|
-
/* INTEGRATED TIMELINE MATRIX & SVG LAYOVER WRAPPER */
|
|
208
215
|
.timeline-wrapper { position: relative; background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 2.5rem 1.5rem 1.5rem 1.5rem; margin-bottom: 2rem; }
|
|
209
|
-
.timeline-container {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
height: 150px;
|
|
214
|
-
gap: 8px;
|
|
215
|
-
position: relative;
|
|
216
|
-
z-index: 2;
|
|
217
|
-
}
|
|
218
|
-
.timeline-svg-layer {
|
|
219
|
-
position: absolute;
|
|
220
|
-
top: 2.5rem;
|
|
221
|
-
left: 1.5rem;
|
|
222
|
-
width: calc(100% - 3rem);
|
|
223
|
-
height: 150px;
|
|
224
|
-
z-index: 3;
|
|
225
|
-
pointer-events: none;
|
|
226
|
-
}
|
|
227
|
-
.timeline-column {
|
|
228
|
-
flex: 1;
|
|
229
|
-
display: flex;
|
|
230
|
-
flex-direction: column;
|
|
231
|
-
justify-content: flex-end;
|
|
232
|
-
align-items: center;
|
|
233
|
-
height: 100%;
|
|
234
|
-
position: relative;
|
|
235
|
-
}
|
|
236
|
-
.timeline-bar-stack {
|
|
237
|
-
width: 100%;
|
|
238
|
-
max-width: 45px;
|
|
239
|
-
height: 100%;
|
|
240
|
-
background-color: #111827;
|
|
241
|
-
border-radius: 4px;
|
|
242
|
-
display: flex;
|
|
243
|
-
flex-direction: column;
|
|
244
|
-
justify-content: flex-end;
|
|
245
|
-
overflow: hidden;
|
|
246
|
-
opacity: 0.75;
|
|
247
|
-
transition: opacity 0.2s;
|
|
248
|
-
}
|
|
216
|
+
.timeline-container { display: flex; justify-content: space-between; align-items: flex-end; height: 150px; gap: 8px; position: relative; z-index: 2; }
|
|
217
|
+
.timeline-svg-layer { position: absolute; top: 2.5rem; left: 1.5rem; width: calc(100% - 3rem); height: 150px; z-index: 3; pointer-events: none; }
|
|
218
|
+
.timeline-column { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; position: relative; }
|
|
219
|
+
.timeline-bar-stack { width: 100%; max-width: 45px; height: 100%; background-color: #111827; border-radius: 4px; display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden; opacity: 0.75; }
|
|
249
220
|
.timeline-column:hover .timeline-bar-stack { opacity: 1; border: 1px solid var(--text-muted); }
|
|
250
221
|
.stack-fill { width: 100%; transition: height 0.3s ease; }
|
|
251
222
|
.success-fill { background-color: var(--success); }
|
|
252
223
|
.failure-fill { background-color: var(--failure); }
|
|
253
224
|
.timeline-tick-label { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem; font-weight: 600; }
|
|
254
225
|
|
|
255
|
-
/* POPUP FLOATER DETAILS */
|
|
256
226
|
.timeline-column:hover .timeline-hover-metrics { display: block; }
|
|
257
|
-
.timeline-hover-metrics {
|
|
258
|
-
display: none;
|
|
259
|
-
position: absolute;
|
|
260
|
-
bottom: 110%;
|
|
261
|
-
background-color: #030712;
|
|
262
|
-
border: 1px solid var(--text-muted);
|
|
263
|
-
border-radius: 4px;
|
|
264
|
-
padding: 0.6rem;
|
|
265
|
-
font-size: 0.75rem;
|
|
266
|
-
white-space: nowrap;
|
|
267
|
-
z-index: 20;
|
|
268
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.7);
|
|
269
|
-
}
|
|
227
|
+
.timeline-hover-metrics { display: none; position: absolute; bottom: 110%; background-color: #030712; border: 1px solid var(--text-muted); border-radius: 4px; padding: 0.6rem; font-size: 0.75rem; white-space: nowrap; z-index: 20; box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.7); }
|
|
270
228
|
|
|
271
|
-
/* LATENCY DISTRIBUTION PANEL */
|
|
272
229
|
.chart-section { background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; margin-bottom: 2rem; }
|
|
273
230
|
.chart-row { display: flex; align-items: center; margin-bottom: 0.85rem; }
|
|
274
231
|
.chart-label { width: 100px; font-size: 0.9rem; color: var(--text-muted); font-weight: 600; }
|
|
@@ -316,6 +273,10 @@ try {
|
|
|
316
273
|
<div class="card-title">Average Latency</div>
|
|
317
274
|
<div class="card-value">${avgLatency.toFixed(1)} ms</div>
|
|
318
275
|
</div>
|
|
276
|
+
<div class="card">
|
|
277
|
+
<div class="card-title">Std. Deviation (\u03C3)</div>
|
|
278
|
+
<div class="card-value stability-info">\xB1${stdDev.toFixed(1)} ms</div>
|
|
279
|
+
</div>
|
|
319
280
|
</div>
|
|
320
281
|
|
|
321
282
|
<h2>\u{1F504} Throughput, Errors & Active Threads Concurrency Correlation</h2>
|
|
@@ -326,11 +287,9 @@ try {
|
|
|
326
287
|
</div>
|
|
327
288
|
|
|
328
289
|
<div class="timeline-wrapper">
|
|
329
|
-
<!-- PURE CSS SVG POLYLINE SCALED OVERLAY LAYER FOR ACTIVE THREADS TIMELINE -->
|
|
330
290
|
<svg class="timeline-svg-layer" viewBox="0 0 1000 150" preserveAspectRatio="none">
|
|
331
|
-
<polyline fill="none" stroke="#38bdf8" stroke-width="3" stroke-
|
|
291
|
+
<polyline fill="none" stroke="#38bdf8" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" points="${pointsStr.trim()}"></polyline>
|
|
332
292
|
</svg>
|
|
333
|
-
|
|
334
293
|
<div class="timeline-container">
|
|
335
294
|
${timelineHtmlElements}
|
|
336
295
|
</div>
|
|
@@ -355,6 +314,7 @@ try {
|
|
|
355
314
|
<th>Average (ms)</th>
|
|
356
315
|
<th>Min (ms)</th>
|
|
357
316
|
<th>Max (ms)</th>
|
|
317
|
+
<th>Std.Dev (ms)</th>
|
|
358
318
|
<th>90% Line</th>
|
|
359
319
|
<th>95% Line</th>
|
|
360
320
|
<th>99% Line</th>
|
|
@@ -368,6 +328,7 @@ try {
|
|
|
368
328
|
<td>${avgLatency.toFixed(1)}</td>
|
|
369
329
|
<td>${minLatency.toFixed(1)}</td>
|
|
370
330
|
<td>${maxLatency.toFixed(1)}</td>
|
|
331
|
+
<td>\xB1${stdDev.toFixed(1)}</td>
|
|
371
332
|
<td>${p90.toFixed(1)}</td>
|
|
372
333
|
<td>${p95.toFixed(1)}</td>
|
|
373
334
|
<td>${p99.toFixed(1)}</td>
|
|
@@ -379,7 +340,7 @@ try {
|
|
|
379
340
|
</body>
|
|
380
341
|
</html>`;
|
|
381
342
|
fs.writeFileSync(htmlOutputPath, htmlContent, "utf-8");
|
|
382
|
-
console.log(`\u2728 \x1B[32mHTML Dashboard with
|
|
343
|
+
console.log(`\u2728 \x1B[32mHTML Dashboard with Standard Deviation Matrix saved to:\x1B[0m ${htmlOutputPath}
|
|
383
344
|
`);
|
|
384
345
|
} catch (error) {
|
|
385
346
|
console.error("Execution error:", error);
|
|
Binary file
|