test: add reproducible Windows VM bundle harness

This commit is contained in:
2026-09-09 06:44:54 +00:00
parent 2abf0bf19b
commit a9aec8d9a8
7 changed files with 685 additions and 55 deletions
+70 -17
View File
@@ -15,6 +15,30 @@ Run focused unit tests with:
scripts/test-unit --package ./internal/domain --run UUIDv7 --race
```
Build all supported binaries without installing `make` or Go on the host:
```sh
scripts/build build
```
For a native Windows run, create the immutable per-run test bundle with the
pinned toolchain. Supply a test-specific config whose endpoint and CA path are
valid for that run; the command refuses to replace an existing bundle.
```sh
scripts/windows/build-test-bundle \
--run-id windows-smoke \
--config .test-runs/windows-smoke/client.toml \
--ca .test-runs/windows-smoke/ca.pem
scripts/windows/test-host prepare --run-id windows-smoke
scripts/windows/test-host stage --run-id windows-smoke \
--bundle .test-runs/windows-smoke/windows-bundle
```
The bundle manifest records the source commit and SHA-256 of every bundled
file. It is a test artifact, not a signed release package; release signing,
version resources, and publication are Phase 8 gates.
The integration harness provides the Phase 0 `sample` suite, the incremental
Phase 2 `store` suite, and the incremental Phase 3 `server-session` suite.
The resumable E2E harness adds `smoke`, `script`, `recovery`, and `all`
@@ -97,20 +121,49 @@ than treating it as a stable endpoint. VRDE is enabled at
`192.168.50.162:3389` for diagnostics, while native Windows RDP is disabled in
the baseline.
The exact headless VirtualBox/Guest Control adapter is
`scripts/windows/test-host.ps1`; it takes the VM name, baseline snapshot, and
guest identity/password-file only from host environment variables, acquires an
exclusive lease, and never writes secrets to the repository. Set
`RVBOX_WINDOWS_GUEST_PASSWORD_FILE` to a mode-600 file outside the repository;
the adapter passes it with VirtualBox `--passwordfile` and never accepts an
inline password. Use `Prepare`, `Run`,
`Collect`, `Stop`, and `Reset` in that order for a native run. The VM is the
minimum smoke lane, so deferred native multi-session/ambiguous-session, Server
Core, and older-build entries remain explicitly blocked until their own
fixtures exist. A previous Windows 10 fixture probe found that VirtualBox Guest
Control 7.2.16 rejects the GUI-subsystem `rvbox.exe` as a directly runnable
guest executable; wrapping it through `cmd.exe` exited the RVBox process but
left the Guest Control wrapper waiting. This remains an adapter completion-path
limitation: native runtime coverage needs a service-driven or
console-compatible guest runner. Wine or a protocol stub is not treated as
equivalent coverage.
The canonical headless VirtualBox/Guest Control adapter is
`scripts/windows/test-host`. It is a POSIX controller script because the
fixture's VirtualBox host is Arch Linux and has no PowerShell runtime. The
controller connects to Helium over SSH; `VBoxManage` and the host-only password
file never need to exist on the Linux development controller. It takes the VM
identity, baseline snapshot, guest identity, and password-file only from host
environment variables, acquires an exclusive remote lease, and never writes
secrets to the repository, run manifest, or command line. Set
`RVBOX_TEST_GUEST_PASSWORD_FILE` to the mode-600 host-side file; the adapter
passes it only as VirtualBox `--passwordfile`.
The provisioned fixture's non-secret identity values, including the host-local
password-file path, are safe defaults in that script and may be overridden for
another documented fixture; the password itself is never embedded.
The native lifecycle is `status`, `prepare`, `stage`, `run`, `collect`,
`stop`, and `reset`. `prepare` verifies the VM and snapshot UUIDs, restores the
baseline, starts headless, waits for Guest Additions, and records the selected
login fixture. `stage` copies a versioned non-secret test bundle through a
run-specific host directory to a run-specific guest directory. `run` starts
the real RVBox SCM service and observes it through SCM, the local health/tray
pipe, durable artifacts, and the test agent endpoint; it must not invoke the
GUI-subsystem `rvbox.exe` directly through Guest Control. `collect` obtains
only bounded/redacted artifacts, and `reset` restores the exact baseline and
leaves the VM powered off.
This service-driven protocol is required because VirtualBox Guest Control
7.2.16 does not reliably complete a direct GUI-subsystem `rvbox.exe` run;
wrapping it in `cmd.exe` can leave the Guest Control wrapper waiting. Guest
Control is therefore limited to console-safe setup tools (`sc.exe`, `whoami`,
`query`, bounded file operations) and artifact collection. A native E2E run
also performs a bounded guest-to-nginx HTTPS/TCP readiness probe before it
starts the service. Wine and protocol stubs are not equivalent Windows
coverage.
The fixture needs a one-time operator-approved service bootstrap before the
SCM smoke lane can run: Guest Control supplies the split-token administrator's
medium UAC token, so it cannot safely install services. The bootstrap installs
the test service in the reset baseline and grants the test account only the SCM
query/change-config/start/stop rights plus access to its dedicated test subtree.
Each run then reconfigures and starts that one service. This does not add a
product broker or use Task Scheduler; it is fixture setup. See
[testing-vm.md](testing-vm.md) for the exact boundary.
The VM is the minimum smoke lane, so native multi-session/ambiguous-session,
Server Core, and older-build entries remain explicitly blocked until their own
fixtures exist. Their pure selector tests remain mandatory.