Files
codebase-memory-mcp/test-infrastructure
Martin VogelandClaude Fable 5.1 8134712dc4 ci(msan): repin Dockerfile.msan clang-22 -> clang-21 (apt.llvm.org rotated noble-22 out) (#2123)
The test-msan lane was red repo-wide: the Dockerfile.msan image build could
no longer install clang-22 from apt.llvm.org's noble-22 channel, failing with
"E: Unable to locate package clang-22 / libclang-rt-22-dev / llvm-22" after
the 5 apt retries, so the image never built and every PR's required test-msan
check could not go green (#2123).

apt.llvm.org keeps only the last few majors for noble and rotates newer ones
in and out; the -22 channel's package index was empty when CI fetched it (the
channel has since flapped back, confirming the transience). Rather than stay on
that volatile channel, repin to clang-21 - the highest well-established stable
noble channel apt.llvm.org currently serves (verified installable on both
amd64 and arm64):

  - apt source noble-22 -> noble-21, clang-22/libclang-rt-22-dev/llvm-22 ->
    clang-21/libclang-rt-21-dev/llvm-21, and the clang/clang++ symlinks
  - MSan runtimes clone llvmorg-22.1.0 -> llvmorg-21.1.8 (matches the apt
    clang 21.1.8, keeping the libc++/libc++abi/libunwind build at the
    compiler's major, as the layer requires)
  - MSAN_SYMBOLIZER_PATH /usr/lib/llvm-22 -> /usr/lib/llvm-21

Verified in an ubuntu:noble container that clang-21/libclang-rt-21-dev/llvm-21
install cleanly, the clang/clang++ symlinks resolve, libclang_rt.msan-*.a and
llvm-symbolizer are present, and the full image builds via Colima.

Infra only; the MSan lane's other files (docker-compose.yml, scripts/msan.sh)
use the version-agnostic clang/clang++ symlinks and need no change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-09 07:37:54 +02:00
..
2026-08-21 20:07:37 +08:00

test-infrastructure/ — the local venues

The local half of the 3-OS CI ladder. Every leg here runs the SAME canonical scripts CI runs (scripts/test.sh, build.sh, smoke-local.sh, soak-legs.sh, vm-smoke.sh — see scripts/README.md); this directory only provisions containers and the Windows VM. The venue-parity contract (tests/test_venue_parity_contract.sh, Step 0j of every test leg) fails the build if a venue grows its own harness logic — here or in the workflows.

Entry points

venue entry notes
Linux (arm64 + amd64) + cross-compile ./run.sh <leg> (--help for the leg list) Colima only — Docker Desktop is broken on this machine. A clean-disk preflight (scripts/ci/preflight-docker.sh) runs before every leg: GitHub runners are ephemeral with a known-free 14 GB disk, so the long-lived VM is swept back to that shape first.
Real Windows (UTM ARM64 VM) vm/win.sh <command> (win.sh help) Same preflight idea (scripts/ci/clean-test-residue.ps1), plus CI's protected per-user TEMP root. Wine (run.sh windows) is a compile check only — never a substitute for the VM.
macOS run the canonical scripts natively scripts/test.sh, scripts/build.sh, scripts/smoke-local.sh …

The ladder (before any push)

  1. scripts/test.sh — macOS native (or --suites … while iterating)
  2. ./test-infrastructure/run.sh full — Linux arm64 test/build/TSan/smoke/portable + mingw cross-compile (+ amd64, soak-linux as needed)
  3. vm/win.sh test-par · guards · smoke-install · soak — the real-Windows legs

Infra unavailable = a run blocker to escalate — never a silent bypass.

Fidelity guarantees (what makes local predictive of CI)

  • Same scripts, same sequence, same flags — platform specifics (e.g. the CLANGARM64 trap-UBSan default) live inside the canonical entries, applied identically everywhere.
  • Same environment shape — protected TEMP roots, sandboxed smoke, clean builds with the content-verified ccache (a hit is byte-identical to a cold compile; caches only accelerate, never change results).
  • Same starting disk — preflights sweep residue and BLOCK below the runner's 14 GB floor (a quietly full disk fails inside install paths and masquerades as a product bug).
  • Known, deliberate residuals — runner physics (4 vCPU vs local cores, shared tenancy), Defender ON in the VM vs OFF on GitHub runners, no TSan on Windows anywhere, no ASan runtime on native ARM64 Windows (trap-UBSan + PageHeap stand in).

See vm/README.md for VM provisioning and day-to-day VM mechanics.