Skip to content

feat: mcpp test capability batch — isolation, parallel, filter, list, timeout, JSON (0.0.104)#274

Merged
Sunrisepeak merged 22 commits into
mainfrom
feat/test-isolation-json
Jul 23, 2026
Merged

feat: mcpp test capability batch — isolation, parallel, filter, list, timeout, JSON (0.0.104)#274
Sunrisepeak merged 22 commits into
mainfrom
feat/test-isolation-json

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

mcpp test 能力批次 — 0.0.104

mcpp test 从「单次构建 + 顺序运行」升级为练习级/CI 级可用的测试运行器。两轮批次合并交付,设计评审与路线图见 .agents/docs/2026-07-24-mcpp-test-design-review.md,实施计划见 .agents/docs/2026-07-23-test-isolation-json-plan.md2026-07-24-test-batch2-plan.md

新增

  • 逐测试编译隔离:两阶段构建,包级失败(lib/deps)是构建错误而非 N 个红测试;单个测试编译失败只标记该测试,其余照常编译运行
  • Phase B 并行化:keep-going 全量预构建(-k 0)+ 逐测试缓存命中验证——49 测试全量墙钟 29s → 3.7s
  • tests 相对路径命名:tests/00-a/0.cpp00-a/0,子目录布局可用
  • mcpp test <pattern>:按名字子串过滤(只作用于构建/运行,compile_commands 保持完整)
  • mcpp test --list:枚举测试不构建;JSON 记录供工具消费
  • mcpp test --timeout <secs>:每测试运行截止(POSIX)
  • --message-format json:逐测试 NDJSON(status/exit_code/signal/duration_ms/timed_out/compile_output/run_output)+ 包级错误记录 + summary
  • [build].flags glob 覆盖测试 TU;死 glob 警告改为查磁盘
  • BuildOptions::ninjaTargets/keepGoing:后端 goal 子集构建的通用接口

修复

  • 信号退出码规范化:WIFSIGNALED → 128+WTERMSIG(此前 SIGTERM 死亡伪装成 exit 15)
  • 嵌套 mcpp LD_LIBRARY_PATH 段错误根治:merged_environ 剥离私有 glibc loader 条目(下游 d2x/d2mcpp 的 unsetenv workaround 可删)
  • 输出交错:每测试 Compiling → 结果 → 诊断 连续块,删除误导性中场 Finished 横幅
  • docs:"(gtest style)" → 框架无关表述(zh+en);记录合成测试名含 / 的命名豁免

验证

  • e2e 新增 152–160 共 9 个脚本;全量回归 150+2(01 为版本常量同步后已修,22 为宿主 xlings 环境既有偶发,与本批次无关)
  • glibc 与 musl 静态双构建全绿;下游 d2mcpp「练习即测试」迁移(zh/en 各 52/52)与 d2x checker 链路已用本分支二进制端到端验证

… — nested mcpp no longer segfaults its tools
@Sunrisepeak
Sunrisepeak merged commit 5c33642 into main Jul 23, 2026
15 checks passed
Sunrisepeak added a commit that referenced this pull request Jul 25, 2026
….0.107 (#281)

A shared library that declares `soname` is written as bin/libX11.so but records
SONAME libX11.so.6. Both the linker resolving a transitive NEEDED and the loader
starting a binary look for the alias, never for the plain name — so the alias is
a prerequisite of anything that links the library, not a by-product of building
it.

It was modelled as a standalone ninja edge that nothing depends on, reachable
only through `default`. The 0.0.104 test batch (#274) made `mcpp test` pass
explicit goal targets so it could isolate per-test compiles, and that silently
stopped producing the alias. `mcpp build` and `mcpp run` drive `default` and
were unaffected, which is why this survived three releases: only a project
driven by `mcpp test` hits it.

The symptom lands three levels from the cause — a consumer failing to link with
`libX11.so: undefined reference to xcb_connect` (alongside `libxcb.so.1 ... not
found`), or a test binary exiting 127. mcpp-index CI has been failing this way
on gui-stack, imgui-module and imgui-window since 0.0.104; two probe PRs pinning
only MCPP_VERSION over unmodified descriptors reproduced it at both 0.0.104 and
0.0.106, which is what ruled out the package-identity migration as the cause.

Hang the alias off the consumer's implicit inputs, beside the .so it already
lists. Correct under `default` and under explicit goals alike, and it pulls in
nothing that was not already being built.

e2e 64 covered only `build` + `run` — precisely the two paths that still worked.
It now also runs `mcpp test` from a clean target dir and asserts the alias
exists; without the fix that test binary fails with exit 127.

Verified: unit 37/37; e2e 64 red before / green after; the three real mcpp-index
members pass with `mcpp test` alone (gui-stack 5/5, imgui-module 1/1,
imgui-window 1/1). Remaining local e2e failures (22, 98, 141) reproduce
identically on the released 0.0.106 binary under the same MCPP_HOME — they are
this machine's gcc 15.1.0, not this change.
Sunrisepeak added a commit that referenced this pull request Jul 25, 2026
… line (0.0.108) (#285)

`mcpp test` names every shared prerequisite as a ninja goal so a broken package
source fails once, as a package error, instead of N times as identical per-test
compile failures. For a large package that is thousands of object paths:
FFmpeg's 2281 translation units produced a 50,781-character argv. Windows joins
argv into a single command string for cmd.exe, which caps at 8191 characters, so
the command never ran at all — the 127 came back from cmd.exe, before ninja or
mcpp could print anything.

That silence is what made it hard to place. mcpp-index's Windows job has failed
on the ffmpeg member since 0.0.104, and the log's last line was an unrelated
download progress bar: no "build failed" diagnostic, no ninja output, and
target/.build_cache never written. ffmpeg is the only member large enough to
trip the limit, and `mcpp build` / `mcpp run` drive `default` with no goal
arguments, so both stayed green throughout.

Emit the goal set as a phony edge in build.ninja and pass its one-word name. The
manifest has no length limit, and ninja still builds the whole set in a single
invocation, so parallelism is unchanged.

Same origin as the soname-alias regression fixed in 0.0.107: both come from the
explicit-goal-targets change in #274 — one design change, two symptoms that only
appear under conditions the test suite did not cover.

e2e 164 asserts the mechanism (goals live in the manifest) rather than the 8191
limit: reproducing the limit needs a package far too slow to build here, and the
limit does not exist on Linux or macOS. It is red on 0.0.107 and green here.

Verified: unit 37/37; e2e 155 passed / 1 failed / 5 skipped, the one failure
(22_doctor_cache_publish) reproducing identically on the released binary under
the same MCPP_HOME.

Found by publishing an instrumented Windows build to a throwaway prerelease and
pinning it from a stripped-down mcpp-index probe PR — four rounds of black-box
probing could not see inside the process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant