(fileName, text)
| 377 | } |
| 378 | |
| 379 | function normalizeCsvRun(fileName, text) { |
| 380 | const [headerLine, ...lines] = text.split(/\r?\n/).filter(Boolean); |
| 381 | const headers = headerLine.split(","); |
| 382 | const series = []; |
| 383 | let totalRequests = 0; |
| 384 | let successWeight = 0; |
| 385 | |
| 386 | lines.forEach((line) => { |
| 387 | const cols = line.split(","); |
| 388 | const row = Object.fromEntries(headers.map((header, index) => [header, cols[index] ?? ""])); |
| 389 | const requests = toNumber(row.requests) || 0; |
| 390 | const successRate = clamp01(toNumber(row.success_ratio)); |
| 391 | totalRequests += requests; |
| 392 | if (successRate !== null) { |
| 393 | successWeight += successRate * requests; |
| 394 | } |
| 395 | series.push({ |
| 396 | minute: row.minute, |
| 397 | label: row.minute, |
| 398 | requests, |
| 399 | tpm: toNumber(row.tpm) ?? requests, |
| 400 | successRate, |
| 401 | p50Ms: toNumber(row.p50_ms), |
| 402 | p95Ms: toNumber(row.p95_ms), |
| 403 | p99Ms: toNumber(row.p99_ms), |
| 404 | apdex: clamp01(toNumber(row.apdex)), |
| 405 | }); |
| 406 | }); |
| 407 | |
| 408 | return finalizeRun({ |
| 409 | id: `upload:${fileName}`, |
| 410 | name: fileName.replace(/\.[^.]+$/, ""), |
| 411 | source: fileName, |
| 412 | kind: "minute_csv", |
| 413 | collectedAt: new Date().toISOString(), |
| 414 | durationMs: series.length ? series.length * 60 * 1000 : null, |
| 415 | overview: { |
| 416 | requestsTotal: totalRequests || null, |
| 417 | throughputPerMinute: series.length ? totalRequests / series.length : null, |
| 418 | successRate: totalRequests ? successWeight / totalRequests : null, |
| 419 | p50Ms: lastDefined(series, "p50Ms"), |
| 420 | p95Ms: lastDefined(series, "p95Ms"), |
| 421 | p99Ms: lastDefined(series, "p99Ms"), |
| 422 | peakTpm: series.length ? Math.max(...series.map((point) => point.tpm || 0)) : null, |
| 423 | apdex: mean(series.map((point) => point.apdex)), |
| 424 | }, |
| 425 | thresholds: [], |
| 426 | checks: [], |
| 427 | series, |
| 428 | }); |
| 429 | } |
| 430 | |
| 431 | function normalizeNdjsonRun(fileName, text) { |
| 432 | const counts = new Map(); |
no test coverage detected