Add integration tests based on testcontainers

This commit is contained in:
2026-10-25 19:47:25 +02:00
parent 2ccd67d64c
commit f4a6540df9
24 changed files with 8693 additions and 68 deletions
+63 -5
View File
@@ -46,15 +46,73 @@ all native compilers/linkers needed by a cross build. Establish the musl linker
and any C dependency requirements before milestone 8, or build in a dedicated
Alpine/musl builder. Keep build tools out of the small runtime test image.
Once prerequisites and Cargo scaffolding exist, the planned cross-build check is:
The Alpine suite has two separate execution environments:
- The host runs the Rust Testcontainers harness and must have the pinned Rust
toolchain, approved development dependencies, and access to an explicitly
selected disposable Docker-compatible Linux daemon. Testcontainers manages
only scenario-owned networks/containers. Do not silently use a remote daemon
or the default local daemon before it has been selected as disposable.
- The daemon's Linux host must already provide kernel WireGuard support and
IPv4 networking. Server and client containers share that kernel but receive
only scoped `NET_ADMIN` in their own network namespaces. The suite verifies
support in disposable probe containers on a private internal IPv4 network. It
must not load modules, alter host sysctls, or create host interfaces. Missing
kernel, daemon, IPv4, or namespace prerequisites are an incomplete explicit
run, not a passing skip. IPv6 capability and traffic are intentionally not
tested by M8; production dual-stack behavior remains unchanged.
The fixture image is pinned to an Alpine release or digest and records the
resolved image identity and complete installed package closure. It contains
runtime utilities only (`wireguard-tools`, `iproute2`, BusyBox tools actually
used, and any justified additions). Driver
and fixture inputs are staged per fresh scenario container; keys and configs
must never enter the image build context or layers. The test-only server driver
must be built for `x86_64-unknown-linux-musl` or inside a pinned Alpine/musl
builder matching the repository toolchain, then checked for actual dynamic
requirements and executed in the fixture image. A successful cross build alone
does not establish Alpine compatibility.
The current host observation above records that the musl standard library is
missing. Do not install it or a linker implicitly. The fixture recipe now lives
in `tests/containers/alpine/` and the exact image commands are in
[TESTING.md](TESTING.md). The base is pinned to Alpine 3.22.7 for linux/amd64;
the selected disposable daemon built and cached the image, and the exact
installed closure is recorded in `packages.lock`. Compiler/toolchain layers stay
out of this runtime image.
M8.4 provides an in-crate `#[cfg(test)]` library test driver so that its fixture
command and restart seams stay inaccessible to the production executable. It
includes an ignored test named `container_driver::alpine_readiness`, selected
with libtest's `--ignored --exact` arguments. This harmless test checks only its
Linux x86_64 execution environment. Once the musl standard library and a
compatible linker are available, build the library test harness from the
repository root with:
```sh
cargo build --locked --release --target x86_64-unknown-linux-musl
cargo test --locked --lib --no-run --target x86_64-unknown-linux-musl
```
Then run the built executable in Alpine and inspect actual dynamic-library
requirements. A target name alone is not evidence that the binary runs there.
Musl readiness is a milestone 8 prerequisite, not a milestone 1 acceptance gate.
The host cannot run this build directly because its musl target is absent.
The digest-pinned official Rust 1.97.1 Alpine builder command in
[TESTING.md](TESTING.md) built the library test harness on 2026-10-23. `file`
identified a static PIE and `readelf -l` showed no interpreter; the ignored
readiness selector then passed 1/1 in the pinned Alpine runtime using a
read-only bind of the nonsecret binary. The selected-daemon M8.4 Testcontainers
smoke later copied the current binary into a fresh server container and passed
the test-only Create/Commit/first delivery/fixture Apply sequence with real
runtime observation. M8.5 traffic and remaining lifecycle scenarios remain
pending. The readiness wrapper
invokes the harness as
`PATH --ignored --exact container_driver::alpine_readiness --test-threads=1`.
Cargo printed the executable under
`/tmp/wga-m8-build-target/x86_64-unknown-linux-musl/debug/deps/wireguard_admin-<hash>`
for the builder command. Discover the current hash from each build; the driver
must be recopied after code changes. A target name or successful compilation
alone is not Alpine runtime evidence. Shell-tool readiness, Rust harness
readiness and the M8.4 Application smoke passed on the selected daemon. No
client tunnel traffic or systemd job has been tested. Musl readiness is a
milestone 8 prerequisite, not a milestone 1 acceptance gate.
## Observed preparation state