| 1 | import assert from "node:assert/strict"; |
| 2 | import test from "node:test"; |
| 3 | import { timingMarkdown, timingReport } from "./ci-timings.mjs"; |
| 4 | |
| 5 | const stamp = seconds => new Date(Date.UTC(2026, 0, 1, 0, 0, seconds)).toISOString(); |
| 6 | |
| 7 | test("timing report separates queue, execution, wall time and selected stages", () => { |
| 8 | const run = { created_at: stamp(0) }; |
| 9 | const jobs = { jobs: [ |
| 10 | { name: "desktop-prepare", created_at: stamp(1), started_at: stamp(6), completed_at: stamp(26), conclusion: "success", steps: [ |
| 11 | { name: "Install frontend dependencies", started_at: stamp(7), completed_at: stamp(12), conclusion: "success" }, |
| 12 | { name: "Build stable frontend", started_at: stamp(12), completed_at: stamp(20), conclusion: "success" }, |
| 13 | ] }, |
| 14 | { name: "desktop-browser-group (motion)", created_at: stamp(2), started_at: stamp(12), completed_at: stamp(32), conclusion: "success", steps: [ |
| 15 | { name: "Test desktop browser group", started_at: stamp(20), completed_at: stamp(30), conclusion: "success" }, |
| 16 | ] }, |
| 17 | { name: "desktop-windows-go", created_at: stamp(3), started_at: stamp(4), completed_at: stamp(24), conclusion: "success", steps: [ |
| 18 | { name: "test (Windows desktop and update helper)", started_at: stamp(8), completed_at: stamp(23), conclusion: "success" }, |
| 19 | ] }, |
| 20 | { name: "sign Windows candidate", created_at: stamp(3), started_at: stamp(4), completed_at: stamp(24), conclusion: "success", steps: [ |
| 21 | { name: "Finalize amd64 in the shared Certum session", started_at: stamp(8), completed_at: stamp(23), conclusion: "success" }, |
| 22 | ] }, |
| 23 | { name: "skipped", created_at: stamp(1), conclusion: "skipped", steps: [] }, |
| 24 | ] }; |
| 25 | const report = timingReport(run, jobs); |
| 26 | assert.equal(report.workflowElapsed, 32_000); |
| 27 | assert.equal(report.runnerSum, 80_000); |
| 28 | assert.equal(report.queueSum, 17_000); |
| 29 | assert.deepEqual(report.stages.map(stage => stage.kind), ["browser group", "frontend build", "dependency install", "Go test", "Windows signing"]); |
| 30 | const markdown = timingMarkdown(report, "Measured CI timing"); |
| 31 | assert.match(markdown, /Total workflow wait: \*\*0m 32s\*\*/); |
| 32 | assert.match(markdown, /Sum of runner execution: \*\*1m 20s\*\*/); |
| 33 | assert.match(markdown, /Step durations exclude job queue time/); |
| 34 | }); |
| 35 | |
| 36 | test("running jobs use the observation time for wall time", () => { |
| 37 | const report = timingReport({ created_at: stamp(0) }, { jobs: [ |
| 38 | { name: "app-memory", created_at: stamp(1), started_at: stamp(2), completed_at: null, conclusion: null, steps: [] }, |
| 39 | ] }, { now: new Date(stamp(45)) }); |
| 40 | assert.equal(report.workflowElapsed, 45_000); |
| 41 | assert.equal(report.runnerSum, 0); |
| 42 | }); |
| 43 |