Skip to content

perf(test): run the API unit coverage lane at four workers - #1480

Merged
juliopolycarpo merged 2 commits into
mainfrom
perf/unit-coverage-parallel-workers
Oct 12, 2026
Merged

juliopolycarpo merged 2 commits into
mainfrom
perf/unit-coverage-parallel-workers

Conversation

@juliopolycarpo

@juliopolycarpo juliopolycarpo commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Run API unit coverage at four isolated workers per CI shard now that Bun 1.4.3 has removed the known epoll_ctl abort path. Keep one bun test invocation and one LCOV per unit shard.

Changes

  • Set apps/api's test:coverage:unit to --parallel=4 and pin it in the lane tests.
  • Allow any positive worker count in the qualification guard without relaxing its coverage-file checks.
  • Record Bun 1.4.3 measurements and remaining upstream defects in the testing reference and CI comments. Keep integration unisolated while the runner-hang issue remains open; unit-lane soak does not change that gate.

Test Plan

  • bun run check passes

  • bun run test passes

  • bun run build passes

  • New UI strings use @mangostudio/shared/i18n (no hardcoded strings)

  • Manually smoke-tested: login, chat creation, image generation

  • Reported local validation: bun run check; root scripts, 3,517 passed and 13 skipped. Restoring --parallel=1 makes both updated lane assertions fail on the expected worker flag.

  • Current-head CI passed tooling/typecheck, all four coverage shards, frontend tests, build and automated smoke checks at fa1d578. Full local bun run test, bun run build and manual smoke were not run. No UI strings were added.

Screenshots / GIFs

Not applicable.

Notes

  • Ref Run test lanes across available CPUs by default, with a worker-count override flag #889. This addresses API unit coverage width only; it does not deliver CPU-count defaults or a CLI worker override for every lane.
  • Ref oven-sh/bun#37968, already resolved upstream by oven-sh/bun#44581 in Bun 1.4.3. The stdio descriptor leak remains, with oven-sh/bun#38008 unmerged. oven-sh/bun#39709 remains open, so integration stays unisolated and the watchdog stays enabled.
  • Recorded local measurements on 1.4.3+c6da4a4d3, WSL2 pinned to four cores, 437 unit files, output redirected to a file: coverage shards took 65–69s at one worker and 19–20s at four. All four shards passed at each width with identical file partitions. The unsharded unit soak was 12/12 clean, with 5,380 passed per run.
  • Both widths covered 61,807 lines; merged coverable lines differed by 51, moving line coverage from 80.15% to 80.20%, within the QA verdict's 0.1pp epsilon. These are local measurements, not a hosted speedup claim. Root-script contention and serial integration limit the expected CI saving.
  • Twelve clean local runs do not establish hosted reliability at the previous 2/36 failure rate. Watch main-branch shard runs for aborts or watchdog kills and revert the flag if they recur.

Run `test:coverage:unit` at `--parallel=4` instead of one isolated
worker. Bun 1.4.3 carries oven-sh/bun#44581, which closed
oven-sh/bun#37968: the `EEXIST: epoll_ctl` abort that lost whole files
under in-process workers. The per-file stdio dup leak behind it is
still there (oven-sh/bun#38008 is unmerged); what the release removed
is the wrong-epoll release that turned the leak into a failure.

Pinned to four cores on 1.4.3, the unit lane at four workers was 12 of
12 clean where it failed 4 of 10 before, and the coverage lane with its
CI flags dropped from 65-69s to 19-20s per shard at four shards. Both
widths split the 437 files identically and cover the same 61,807 lines.
Coverable lines differ by 51 in the merged report, which moves line
coverage 0.05pp, inside the QA verdict's 0.1pp epsilon.

The lane stays one invocation, so it still writes one LCOV. The plain
`test:unit` worker processes, the unisolated integration lane and the
shard watchdog are unchanged: oven-sh/bun#39709 is still open.

Record the measurements and the upstream state in the testing
reference, and correct the comments that still described the fix as
pending.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>
@juliopolycarpo juliopolycarpo added type: test Test coverage, test infrastructure, or test reliability work. type: ci CI, release, checks, automation, or GitHub workflow changes. area: docs Documentation tree, guides, reference docs, or contributor docs. type: perf Performance-focused changes (matches the perf commit type). labels Oct 12, 2026
@github-actions github-actions Bot added area: api Elysia routes, API modules, middleware, or backend services. area: build Binary build, runtime paths, packaging, or standalone output. labels Oct 12, 2026
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

PR head: fa1d578 • base: a39ca7e • CI run

CI duration (wall clock, critical path, slowest jobs)

CI Duration

Report-only timing from the Actions jobs API; runner variance does not affect the gate.
Comparisons cover the jobs both runs share, so main-only stages never skew the baseline.

Metric Base Head Δ
Wall clock (shared jobs) 15m 31s 12m 6s 🟢 ▼ -3m 25s
Critical path Distribution / Runtime / Runtime windows-arm64 · 11m 46s Distribution / Runtime / Runtime windows-x64 · 8m 26s 🟢 ▼ -3m 20s

Since previous PR run: 13m 36s → 12m 6s (🟢 ▼ -1m 30s)

Five slowest head jobs

Job Base Head Δ
Distribution / Runtime / Runtime windows-x64 11m 30s 8m 26s 🟢 ▼ -3m 4s
Distribution / Runtime / Runtime darwin-arm64 7m 18s 7m 43s 🔴 ▲ +25s
Distribution / Runtime / Runtime windows-arm64 11m 46s 7m 40s 🟢 ▼ -4m 6s
Distribution / Runtime / Runtime darwin-x64 9m 34s 5m 40s 🟢 ▼ -3m 54s
Distribution / Runtime / Runtime linux-arm64-musl 6m 48s 5m 14s 🟢 ▼ -1m 34s

QA Gate — Coverage & Quality

Base: a39ca7e • Head: 79434a5 • generated 2026-10-12T05:59:44.952Z

✅ No attention signals — collected metrics look healthy against base.

LoC (code): ⚪ ▲ = 0 • Line coverage (all workspaces): 🟢 ▲ +0.03pp • Quick check: pass • Duplication: ⚪ ▲ = 0 • Bundle gzip: ⚪ ▲ = 0 • Locked deps: ⚪ ▲ = 0 • Tests passed: ⚪ ▲ = 0

Metric details (coverage, LoC, bundle, dependencies, tests, duplication, tooling)

Coverage

API/shared branches and statements are source-derived from LCOV line hits because Bun LCOV does not emit branch or statement records.

Rust crates: line, function and region coverage from cargo llvm-cov over the ubuntu libtest run. Branch coverage is not collected and doctests are not instrumented. A crate shows n/a when the Rust lane did not run for the change or its profile data is incomplete.

Component Metric Base Head Δ
apps/api lines 89.99% (80,106/89,019) 90.04% (80,106/88,966) 🟢 ▲ +0.05pp
apps/api statements 80.85% (32,600/40,322) 80.85% (32,600/40,322) ⚪ ▲ = 0
apps/api functions 87.78% (8,086/9,212) 87.70% (8,081/9,214) 🔴 ▼ -0.08pp
apps/api branches 55.84% (12,418/22,237) 55.90% (12,430/22,237) 🟢 ▲ +0.06pp
apps/frontend lines 86.41% (55,878/64,666) 86.41% (55,878/64,666) ⚪ ▲ = 0
apps/frontend statements 83.49% (15,383/18,424) 83.49% (15,383/18,424) ⚪ ▲ = 0
apps/frontend functions 80.04% (4,067/5,081) 80.04% (4,067/5,081) ⚪ ▲ = 0
apps/frontend branches 55.18% (7,646/13,857) 55.18% (7,646/13,857) ⚪ ▲ = 0
apps/shared lines 89.74% (22,014/24,532) 89.74% (22,014/24,532) ⚪ ▲ = 0
apps/shared statements 80.25% (4,656/5,802) 80.25% (4,656/5,802) ⚪ ▲ = 0
apps/shared functions 79.96% (850/1,063) 79.96% (850/1,063) ⚪ ▲ = 0
apps/shared branches 50.52% (1,564/3,096) 50.52% (1,564/3,096) ⚪ ▲ = 0
crates/mango-protocol lines 94.82% (7,469/7,877) n/a n/a
crates/mango-protocol functions 94.34% (984/1,043) n/a n/a
crates/mango-protocol regions 94.88% (11,159/11,761) n/a n/a
crates/mangostudio-launcher lines 35.78% (78/218) n/a n/a
crates/mangostudio-launcher functions 36.36% (12/33) n/a n/a
crates/mangostudio-launcher regions 34.94% (123/352) n/a n/a
crates/mangostudio-runtime lines 92.34% (55,410/60,007) n/a n/a
crates/mangostudio-runtime functions 91.05% (6,184/6,792) n/a n/a
crates/mangostudio-runtime regions 92.07% (85,959/93,365) n/a n/a
crates/mangostudio-runtime-contract lines 99.61% (763/766) n/a n/a
crates/mangostudio-runtime-contract functions 100.00% (111/111) n/a n/a
crates/mangostudio-runtime-contract regions 99.64% (1,111/1,115) n/a n/a

Lines of Code

Authored source: production and test files of every discovered component. Generated, fixture, config and docs lines are recorded in the envelope but not counted here.

Component Base Head Δ
apps/api 1,313 files / 203,252 lines 1,313 files / 203,252 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
apps/frontend 995 files / 105,245 lines 995 files / 105,245 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
apps/shared 304 files / 40,533 lines 304 files / 40,533 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mango-protocol 74 files / 15,735 lines 74 files / 15,735 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-launcher 1 files / 284 lines 1 files / 284 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-runtime 248 files / 105,094 lines 248 files / 105,094 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
crates/mangostudio-runtime-contract 8 files / 1,468 lines 8 files / 1,468 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
packages/cli 1 files / 76 lines 1 files / 76 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
packages/protocol 71 files / 9,140 lines 71 files / 9,140 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
scripts 464 files / 67,847 lines 464 files / 67,847 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0
total 3,479 files / 548,674 lines 3,479 files / 548,674 lines files ⚪ ▲ = 0 • code ⚪ ▲ = 0

Frontend Bundle

Metric Base Head Δ
gzip total 1.32 MiB 1.32 MiB ⚪ ▲ = 0
gzip JavaScript 1.30 MiB 1.30 MiB ⚪ ▲ = 0
gzip CSS 20.3 KiB 20.3 KiB ⚪ ▲ = 0
gzip HTML 809 B 809 B ⚪ ▲ = 0
tracked files 121 121 ⚪ ▲ = 0

Dependencies

Metric Base Head Δ
locked packages 513 513 ⚪ ▲ = 0
direct dependencies 42 42 ⚪ ▲ = 0
direct devDependencies 39 39 ⚪ ▲ = 0
workspace manifests 5 5 ⚪ ▲ = 0

Tests

Single full-suite pass (unit + integration, from the coverage run).

Base Head Δ passed
14,014 passed (root 3,472 / frontend 2,821 / api 6,542 / shared 1,179) · exit 0 · 119s 14,014 passed (root 3,472 / frontend 2,821 / api 6,542 / shared 1,179) · exit 0 · 79s ⚪ ▲ = 0

Test lanes

One row per lane, deduplicated by test. ≥ marks a lower bound: a shard report or process receipt was missing, cut off or timed out. A partial or unavailable lane is never counted as zero, and a total over one is never complete.

Component Lane Base Head Δ passed
apps/api api-unit 5,380 passed · 1 skipped 5,380 passed · 1 skipped ⚪ ▲ = 0
apps/api api-integration 1,162 passed · 22 skipped 1,162 passed · 22 skipped ⚪ ▲ = 0
apps/api total 6,542 passed · 23 skipped 6,542 passed · 23 skipped ⚪ ▲ = 0
apps/frontend frontend 2,821 passed 2,821 passed ⚪ ▲ = 0
apps/frontend total 2,821 passed 2,821 passed ⚪ ▲ = 0
apps/shared shared 1,179 passed · 1 skipped 1,179 passed · 1 skipped ⚪ ▲ = 0
apps/shared total 1,179 passed · 1 skipped 1,179 passed · 1 skipped ⚪ ▲ = 0
scripts root 3,472 passed · 58 skipped 3,472 passed · 58 skipped ⚪ ▲ = 0
scripts total 3,472 passed · 58 skipped 3,472 passed · 58 skipped ⚪ ▲ = 0
repository total 14,014 passed · 82 skipped 14,014 passed · 82 skipped ⚪ ▲ = 0

Code Duplication (jscpd)

Metric Base Head Δ
clones 1,775 1,775 ⚪ ▲ = 0
duplicated lines 25,149 25,149 ⚪ ▲ = 0
percentage 5.39% 5.39% ⚪ ▲ = 0

Repo Tooling

Metric Base Head Δ
Full repo check pass pass ⚪ ▲ = 0
TS errors (total) 0 0 ⚪ ▲ = 0
Circular dependencies 0 0 ⚪ ▲ = 0

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Commits — 2 commits

Base a39ca7e → head fa1d578, oldest first.

  • 74f557a perf(test): run the API unit coverage lane at four workers
  • fa1d578 docs(test): keep the integration lane's isolate gate on bun#39709
Full commit messages

74f557a perf(test): run the API unit coverage lane at four workers

perf(test): run the API unit coverage lane at four workers

Run `test:coverage:unit` at `--parallel=4` instead of one isolated
worker. Bun 1.4.3 carries oven-sh/bun#44581, which closed
oven-sh/bun#37968: the `EEXIST: epoll_ctl` abort that lost whole files
under in-process workers. The per-file stdio dup leak behind it is
still there (oven-sh/bun#38008 is unmerged); what the release removed
is the wrong-epoll release that turned the leak into a failure.

Pinned to four cores on 1.4.3, the unit lane at four workers was 12 of
12 clean where it failed 4 of 10 before, and the coverage lane with its
CI flags dropped from 65-69s to 19-20s per shard at four shards. Both
widths split the 437 files identically and cover the same 61,807 lines.
Coverable lines differ by 51 in the merged report, which moves line
coverage 0.05pp, inside the QA verdict's 0.1pp epsilon.

The lane stays one invocation, so it still writes one LCOV. The plain
`test:unit` worker processes, the unisolated integration lane and the
shard watchdog are unchanged: oven-sh/bun#39709 is still open.

Record the measurements and the upstream state in the testing
reference, and correct the comments that still described the fix as
pending.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>

fa1d578 docs(test): keep the integration lane's isolate gate on bun#39709

docs(test): keep the integration lane's isolate gate on bun#39709

The api lane comment tied leaving integration unisolated to the unit
lane soaking at four workers. Those are unrelated: the unit lane's
width rests on oven-sh/bun#44581, while integration stays out of
isolate mode because that machinery is what hangs the runner
(oven-sh/bun#39709, still open) and its files are spawn-heavy.
Restore the present tense and name the open issue as the gate.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>

📝 Changelog Preview

Entries this branch would add to the changelog on release:

[Unreleased]

⚡ Performance

  • (test) Run the API unit coverage lane at four workers

📚 Documentation

  • (test) Keep the integration lane's isolate gate on bun#39709

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Verdict: no merge blockers. One-commit PR (74f557a5) on perf/unit-coverage-parallel-workers → main. No prior reviews or threads.

The load-bearing change is apps/api test:coverage:unit --parallel=1 → --parallel=4. Plain test:unit stays multi-process --parallel=1, integration stays unisolated, shard count and watchdog stay. Lane tests pin --parallel=4; the qualification guard now accepts any positive --parallel count, which is the right split (width is not a coverage-set change). Docs and comments match Bun 1.4.3 / #44581 vs still-open #38008 leak and #39709 hang. This CI check suite is green (51 passed, 0 failed).

P0 / P1: none.

P2: one comment in scripts/lib/test-lanes.ts now ties keeping integration unisolated to “unit lane soak at four workers.” That soak is this PR’s experiment, not the unblock for isolate on spawn-heavy integration (#39709 / #38008). Restore the original gate so a green coverage soak does not read as permission to isolate that lane.

Watch the first few main-branch shard runs for epoll_ctl or watchdog kills; revert the flag if either returns. Not blocking.

Open in Web View Automation 

Sent by Cursor Automation: Mango Ecosystem CodeReview

Comment thread scripts/lib/test-lanes.ts Outdated
The api lane comment tied leaving integration unisolated to the unit
lane soaking at four workers. Those are unrelated: the unit lane's
width rests on oven-sh/bun#44581, while integration stays out of
isolate mode because that machinery is what hangs the runner
(oven-sh/bun#39709, still open) and its files are spawn-heavy.
Restore the present tense and name the open issue as the gate.

Signed-off-by: Julio Polycarpo <julio@polycarpo.dev>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: no merge blockers. Head fa1d578 on perf/unit-coverage-parallel-workers → main (a39ca7e). CI check suite green (51 passed, 0 failed, 20 skipped).

Since last review: fa1d578 (docs) addresses the P2 on scripts/lib/test-lanes.ts. Integration stays unisolated while oven-sh/bun#39709 is open; the comment no longer keys that on unit-lane soak. Present tense restored. Thread marked fully addressed.

The load-bearing change is still apps/api test:coverage:unit --parallel=1 → --parallel=4. Plain test:unit stays multi-process --parallel=1, integration stays unisolated, shard count and watchdog stay. Lane tests pin --parallel=4; the qualification guard accepts any positive --parallel count (width is not a coverage-set change). Docs match Bun 1.4.3 / #44581 vs still-open #38008 leak and #39709 hang.

P0 / P1 / P2: none remaining.

Watch the first few main-branch shard runs for epoll_ctl or watchdog kills; revert the flag if either returns. Not blocking.

Open in Web View Automation 

Sent by Cursor Automation: Mango Ecosystem CodeReview

@juliopolycarpo
juliopolycarpo merged commit 5c11163 into main Oct 12, 2026
72 checks passed
@juliopolycarpo
juliopolycarpo deleted the perf/unit-coverage-parallel-workers branch October 12, 2026 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: api Elysia routes, API modules, middleware, or backend services. area: build Binary build, runtime paths, packaging, or standalone output. area: docs Documentation tree, guides, reference docs, or contributor docs. type: ci CI, release, checks, automation, or GitHub workflow changes. type: perf Performance-focused changes (matches the perf commit type). type: test Test coverage, test infrastructure, or test reliability work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant