Skip to content

Commit cd18669

Browse files
test: an archive's tests run by mcpp test's own runner; the bootstrap knows [test] programs
- `mcpp test --archive` composes its tests as runnables and runs them through the runner a build's tests use: the protocol each implements (recorded in mcpp-tests.json as the build decided it), a process per file of its cases, the workers, the mtest store. The store is written for `--case` runs too. - A program of one file is not listed to be split by file. - The store records GITHUB_SHA as the run's commit; docs/08 states how mtest takes the store in (`mtest store import`, or `[project] store`). - The bootstrap is mcpp 2026.11.8.1, which reads `[test] programs`; the READMEs list the rows the tier check found missing. Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
1 parent 21537b6 commit cd18669

9 files changed

Lines changed: 163 additions & 122 deletions

File tree

‎.xlings.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"workspace": {
3-
"mcpp": "2026.11.5.1"
3+
"mcpp": "2026.11.8.1"
44
}
55
}

‎CHANGELOG.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@
5555
and tests link with `--gc-sections` (`[test] link = "objects"` keeps every
5656
object whole); a protocol marker nothing references is read from the objects
5757
the test was linked from. A run is kept in the mtest store's form under
58-
`target/mtest` (`[test] store`), which `mtest report`, `analyze` and `graph`
59-
read. mcpp's own unit tests are one program per directory: 166
58+
`target/mtest` (`[test] store`), which `mtest store import` takes in for
59+
`mtest report`, `analyze` and `graph`. The tests of an archive run by the
60+
same runner (`mcpp test --archive`): their protocol, recorded in
61+
`mcpp-tests.json`, a process per file of their cases, the workers and the
62+
store. mcpp's own unit tests are one program per directory: 166
6063
programs of 32 MB became one of 37 MB, run as 166 processes.
6164
- clang pairs with the MinGW-w64 payload for `x86_64-windows-gnu`: the payload
6265
is clang's sysroot and libstdc++ its C++ library, `import std` included.

‎README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,12 @@ list` reports for this machine):
446446
| `x86_64-windows-msvc` | `msvc@system` (detected VS/BuildTools) or llvm ¹ *(Windows default with Visual Studio)* | verified |
447447
| `x86_64-windows-musl` | llvm 23 — a PE with a musl C library, which no gcc emits; the system comes from the dependency graph | preview |
448448
| `aarch64-macos` | llvm *(macOS default)* | verified |
449+
| `aarch64-macos-musl` · `x86_64-macos-musl` | llvm 23 — a Mach-O with a musl C library from the dependency graph, built on any host *(what `aarch64-macos` is off macOS)* | preview |
449450
| `riscv64-none-elf` · `riscv32-none-elf` | llvm 23 — bare metal, `xim:picolibc-riscv` ² | verified |
450451
| `thumbv6m-none-eabi` · `thumbv7m-none-eabi` | llvm 23 — Cortex-M0/M0+/M1, Cortex-M3 ² | verified |
451452
| `thumbv7em-none-eabihf` · `thumbv8m.main-none-eabi` | llvm 23 — Cortex-M4F/M7F hard float, Cortex-M33/M55 soft float ² | verified |
452453
| `armv7a-none-eabi` · `armv7a-none-eabihf` | llvm 23 — Cortex-A 32-bit, the first row with an MMU ² | verified |
453-
| `aarch64-none-elf` · `x86_64-none-elf` | llvm 23 — bare metal, no C library by default ² | preview |
454+
| `aarch64-none-elf` · `x86_64-none-elf` · `i686-none-elf` | llvm 23 — bare metal, no C library by default ² | preview |
454455
| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 23 — Cortex-M4/M7 soft float, M23, M33F/M55F ² | preview |
455456
| `aarch64-linux-gnu` | `llvm@23.1.3` | preview |
456457
| `riscv64-linux-musl` · `x86_64-macos` | — | planned |

‎README.zh-CN.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,12 @@ mcpp 的身份模型有两条正交的轴:**工具链**是 `family@version`(
395395
| `x86_64-windows-msvc` | `msvc@system`(探测 VS/BuildTools)或 llvm ¹(*有 Visual Studio 时的 Windows 默认*) | verified |
396396
| `x86_64-windows-musl` | llvm 23;带 musl C 库的 PE,gcc 无法产出;系统部分由依赖图提供 | preview |
397397
| `aarch64-macos` | llvm(*macOS 默认*) | verified |
398+
| `aarch64-macos-musl` · `x86_64-macos-musl` | llvm 23;带 musl C 库的 Mach-O,系统部分由依赖图提供,任意宿主可构建(*非 macOS 宿主上的 `aarch64-macos`*) | preview |
398399
| `riscv64-none-elf` · `riscv32-none-elf` | llvm 23;裸机,`xim:picolibc-riscv` ² | verified |
399400
| `thumbv6m-none-eabi` · `thumbv7m-none-eabi` | llvm 23;Cortex-M0/M0+/M1、Cortex-M3 ² | verified |
400401
| `thumbv7em-none-eabihf` · `thumbv8m.main-none-eabi` | llvm 23;Cortex-M4F/M7F 硬浮点,Cortex-M33/M55 软浮点 ² | verified |
401402
| `armv7a-none-eabi` · `armv7a-none-eabihf` | llvm 23;Cortex-A 32 位,第一个带 MMU 的目标 ² | verified |
402-
| `aarch64-none-elf` · `x86_64-none-elf` | llvm 23;裸机,默认不带 C 库 ² | preview |
403+
| `aarch64-none-elf` · `x86_64-none-elf` · `i686-none-elf` | llvm 23;裸机,默认不带 C 库 ² | preview |
403404
| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 23;Cortex-M4/M7 软浮点、M23、M33F/M55F ² | preview |
404405
| `aarch64-linux-gnu` | `llvm@23.1.3` | preview |
405406
| `riscv64-linux-musl` · `x86_64-macos` | — | planned |

‎docs/08-testing.md‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ where a program per file is linked once per file, which is what a suite of many
6666
small files spends its build time on.
6767

6868
A program that speaks the test protocol runs as **one process per file of its
69-
cases** (2026.11.9.1+): mcpp lists the cases, and each file's run selects its
70-
own (P4) and is scheduled across the workers as a program is, named
69+
cases** (2026.11.9.1+): mcpp lists the cases of a program of several files, and
70+
each file's run selects its own (P4) and is scheduled across the workers as a program is, named
7171
`<program>/<file>` -- the isolation and the parallelism of a program per file,
7272
with one link. `[test] split = "case"` gives each case its own process, and
7373
`"none"` runs the program once.
@@ -82,10 +82,13 @@ object whole.
8282
A run is kept in the form of the mtest store (2026.11.9.1+): `target/mtest/`
8383
holds `runs/<id>/run.json`, a line per process in `programs.ndjson` (its
8484
status, duration, start, worker and selected cases) and a line per case in
85-
`cases.ndjson`, and `index.ndjson` lists the runs. `mtest report`, `analyze`
86-
and `graph --store target/mtest` read them as mtest's own runs: the report, the
87-
slowest cases and the run's schedule. `[test] store = "<dir>"` names another
88-
directory, relative to the project; `"none"` keeps nothing.
85+
`cases.ndjson`, and `index.ndjson` lists the runs. `mtest store import --from
86+
target/mtest` takes them into mtest's store, and an `mtest.toml` whose
87+
`[project] store` is `target/mtest` reads them where they are; `mtest report`,
88+
`analyze` and `graph` then read them as mtest's own runs (the Markdown report,
89+
the slowest cases, the critical path and the schedule). In CI, `commit` and
90+
`group` are `GITHUB_SHA` and `GITHUB_RUN_ID`. `[test] store = "<dir>"` names
91+
another directory, relative to the project; `"none"` keeps nothing.
8992

9093
A suite compiled from several sources of its own is also a package: a workspace
9194
member whose `[build] sources` carries the suite and whose one test program
@@ -297,9 +300,10 @@ mcpp test --archive tests.tar.gz # in a checkout: ru
297300
```
298301

299302
The archive holds each leg's test programs and `mcpp-tests.json`, which names
300-
each test's leg, arguments and working directory. Reading it builds nothing;
301-
the tests run in the checkout, through this machine's runner or system, and the
302-
report is `mcpp test`'s. A failed test exits 1, and so does an archive of which
303+
each test's leg, arguments, working directory and the test protocol it
304+
implements. Reading it builds nothing; the tests run in the checkout, through
305+
this machine's runner or system, by `mcpp test`'s own runner: its cases, a
306+
process per file of them, the workers and the store (2026.11.9.1+). A failed test exits 1, and so does an archive of which
303307
no test ran. Legs this machine does not reach are reported as not run
304308
([SPEC-015 §4](specs/target-sets.md)). The archive is a tar compressed as its
305309
name states: `.tar.gz` (or `.tgz`), `.tar.zst`, `.tar.xz` or `.tar`; another

‎docs/specs/target-sets.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
|---|---|
55
| 规范编号 | SPEC-015 |
66
| 标题 | 目标集合与腿:集合的写法与展开,命令对集合的语义,腿的规划与构建,测试归档,机器输出 |
7-
| 状态 | 评审中 v1.0 |
8-
| 版本 | 1.0 |
9-
| 最后修改 | 2026-10-30 |
7+
| 状态 | 评审中 v1.1 |
8+
| 版本 | 1.1 |
9+
| 最后修改 | 2026-11-09 |
1010
| 对应实现 | mcpp >= 2026.10.30.1 |
1111
| 相关设计文档 | `.agents/docs/2026-10-29-ecosystem-target-sets-packaging-and-editors-design.md`(§3) |
1212
| 相关 issue | mcpp#847 |
@@ -85,10 +85,10 @@
8585
## 4. 测试归档
8686

8787
- **写**:`mcpp test [--target <t>...] --no-run --archive <file>` 构建各腿的测试程序,与清单 `mcpp-tests.json`(每个测试的腿、
88-
参数、工作目录)一起写为一个 tar 归档。归档是引擎的格式,与平台的容器无关。压缩方式由文件名决定
88+
参数、工作目录、所实现的测试协议与其自身的文件数)一起写为一个 tar 归档。测试协议按构建时的规则确定一次,写入清单。归档是引擎的格式,与平台的容器无关。压缩方式由文件名决定
8989
(`.tar.gz`/`.tgz`、`.tar.zst`、`.tar.xz`、`.tar`),读写同一规则;其他名称在构建前拒绝(退出码 2)。
90-
- **读**:`mcpp test --archive <file>` 在同一项目的检出中运行归档内本机能到达的测试,不构建;工作目录为项目检出;报告与
91-
`mcpp test` 相同。
90+
- **读**:`mcpp test --archive <file>` 在同一项目的检出中运行归档内本机能到达的测试,不构建;工作目录为项目检出;归档的测试由 `mcpp test` 自身的运行器运行:
91+
测试协议、按用例所在文件分进程、工作线程与 mtest 存储与构建所得的测试**必须**相同。
9292
- 读取时:有测试失败则退出码 1;一个测试都没有运行则退出码 1 并写明;本机到达不了的腿报告为"未运行"。
9393
- 原生交叉同样适用:在 Linux 上构建的 `x86_64-windows-gnu` 测试可以在 Windows 上运行。
9494

@@ -121,3 +121,4 @@
121121
| 版本 | 日期 | 变更 |
122122
|---|---|---|
123123
| 1.0 | 2026-10-30 | 首版(mcpp 2026.10.30.1,设计 2026-10-29 §3):集合的识别、补全与展开,一条命令的腿,`build`、`run`、`test`、`self env` 对多条腿的语义,串行规划与一起构建,测试归档,机器输出;判据 1–8(e2e 963、964,unit `TargetSet`、`BuildLegs`)。 |
124+
| 1.1 | 2026-11-09 | mcpp 2026.11.9.1:归档清单记录每个测试的协议与自身文件数;读取时由 `mcpp test` 的运行器运行(协议、分进程、工作线程、存储)。 |

‎docs/zh/08-testing.md‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ discover = ["checks/**/*.cpp", "!checks/fixtures/**"]
5757
目录中的文件仍各自是一个程序。多文件的程序只链接一次,而每文件一个程序时每个文件链接
5858
一次,后者正是由许多小文件组成的套件在构建上花费的时间。
5959

60-
使用测试协议的程序**按其用例所在文件各起一个进程**运行(2026.11.9.1+):mcpp 先列出用例,
60+
使用测试协议的程序**按其用例所在文件各起一个进程**运行(2026.11.9.1+):mcpp 先列出多文件程序的用例,
6161
每个文件的那次运行只选取自己的用例(P4),像一个程序一样在各工作线程间调度,名为
6262
`<程序>/<文件>`——兼得每文件一个程序的隔离与并行,而只链接一次。`[test] split = "case"`
6363
使每个用例一个进程,`"none"` 只运行一次。
@@ -69,9 +69,10 @@ discover = ["checks/**/*.cpp", "!checks/fixtures/**"]
6969

7070
一次运行以 mtest 存储的形式保存(2026.11.9.1+):`target/mtest/` 中有 `runs/<id>/run.json`,
7171
`programs.ndjson` 每个进程一行(状态、用时、开始时刻、工作线程与所选用例),`cases.ndjson`
72-
每个用例一行,`index.ndjson` 列出各次运行。`mtest report`、`analyze` 与 `graph --store target/mtest`
73-
像读取 mtest 自身的运行一样读取它们:报告、最慢的用例与运行的调度。`[test] store = "<dir>"`
74-
另指一个目录,相对项目;`"none"` 不保存。
72+
每个用例一行,`index.ndjson` 列出各次运行。`mtest store import --from target/mtest` 把它们取入 mtest 的存储,
73+
`[project] store` 为 `target/mtest` 的 `mtest.toml` 则就地读取;`mtest report`、`analyze` 与 `graph` 随之像读取
74+
mtest 自身的运行一样读取它们(Markdown 报告、最慢的用例、关键路径与调度)。在 CI 中 `commit` 与 `group` 取
75+
`GITHUB_SHA` 与 `GITHUB_RUN_ID`。`[test] store = "<dir>"` 另指一个目录,相对项目;`"none"` 不保存。
7576

7677
由自身多个源文件编译而成的测试套件也可以是一个包:一个工作区成员,它的
7778
`[build] sources` 承载整套套件,其唯一的测试程序驱动套件,用
@@ -247,8 +248,9 @@ mcpp test --target openkal --no-run --archive tests.tar.gz # 构建各腿的
247248
mcpp test --archive tests.tar.gz # 在检出中运行本机能到达的部分
248249
```
249250

250-
归档含各腿的测试程序与 `mcpp-tests.json`(每个测试的腿、参数与工作目录)。读取
251-
时不构建;测试在检出中经本机的运行器或系统运行,报告与 `mcpp test` 相同。有测试
251+
归档含各腿的测试程序与 `mcpp-tests.json`(每个测试的腿、参数、工作目录与所实现的测试协议)。读取
252+
时不构建;测试在检出中经本机的运行器或系统,由 `mcpp test` 自身的运行器运行:用例、按用例所在文件分进程、
253+
工作线程与存储(2026.11.9.1+)。有测试
252254
失败时退出码为 1,一个测试都没运行的归档也是 1。本机到达不了的腿报告为未运行
253255
([SPEC-015 §4](../specs/target-sets.md))。归档是 tar,压缩方式由文件名决定:`.tar.gz`(或
254256
`.tgz`)、`.tar.zst`、`.tar.xz` 或 `.tar`;其他名称在构建前即被拒绝。

0 commit comments

Comments
 (0)