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
+55 -19
View File
@@ -24,7 +24,7 @@ observation.
| Snapshot folder | `/home/cabbage/VirtualBox VMs/RVBox/Tests/rvbox-win10-test/Snapshots` |
| Guest OS | Windows 10 Pro 22H2, build `19045.2006`, en-US, BIOS boot |
| Guest account | Local `rvboxtest`; split-token local administrator; console session 1 was observed during provisioning |
| Guest Additions | `7.2.16r174877`; Guest Control readiness requires `GuestAdditionsRunLevel=3` |
| Guest Additions | `7.2.16r174877`; readiness requires published Guest Additions version and Windows OS-release properties (this build does not publish a RunLevel property) |
| Last observed state | `poweroff`; current snapshot `baseline-disk-first` |
The Guest Control credential is test-only. The account name is safe to record,
@@ -108,35 +108,71 @@ the stale unregistered `win10_dev` configuration (its disk is missing).
## Harness contract
The checked-in PowerShell adapter is [`scripts/windows/test-host.ps1`](../scripts/windows/test-host.ps1).
Its actions are `Prepare`, `Status`, `Run`, `Collect`, `Stop`, and `Reset`.
The adapter takes identity and credentials only from the host environment:
The canonical adapter is the POSIX controller script
[`scripts/windows/test-host`](../scripts/windows/test-host). It runs from the
Linux controller and invokes `VBoxManage` only through SSH on Helium; the
fixture host is Arch Linux and does not provide PowerShell. Its actions are
`status`, `prepare`, `stage`, `run`, `collect`, `stop`, `reset`, and `recover`.
The legacy [`test-host.ps1`](../scripts/windows/test-host.ps1) is retained only
as a reference for a future Windows-hosted fixture and is not the Helium lane.
```powershell
$env:RVBOX_WINDOWS_VM = 'rvbox-win10-test'
$env:RVBOX_WINDOWS_BASELINE_SNAPSHOT = 'baseline-disk-first'
$env:RVBOX_WINDOWS_GUEST_USER = 'rvboxtest'
$env:RVBOX_WINDOWS_GUEST_PASSWORD_FILE = 'C:\secure\rvbox-win10-test.password'
```
The implementation plan also uses the equivalent `RVBOX_TEST_*` names for
controllers that run the lifecycle over SSH:
The adapter takes identity and credentials only from its environment:
```sh
export RVBOX_TEST_VBOX_HOST=helium-remote
export RVBOX_TEST_VBOX_VM=rvbox-win10-test
export RVBOX_TEST_VBOX_VM_UUID=6cdc114f-71e5-4167-a394-e922e14e6f5c
export RVBOX_TEST_VBOX_SNAPSHOT=baseline-disk-first
export RVBOX_TEST_VBOX_SNAPSHOT_UUID=9430a9a4-754a-4b22-beaa-8dfd90043f5b
export RVBOX_TEST_GUEST_USER=rvboxtest
export RVBOX_TEST_GUEST_PASSWORD_FILE=/home/cabbage/.local/share/rvbox-secrets/rvbox-win10-test.password
```
Those values are the controller defaults for this one documented fixture, so a
normal Helium run does not need to export them. They remain overrideable for a
separately recorded fixture. The default contains only the host-local password
*file path*, never the password value.
The provisioned lane's backend is SSH plus `VBoxManage` plus Guest Control; it
does not require WinRM, OpenSSH inside Windows, or a stable guest IP. Guest
commands must pass explicit paths and argument vectors. With this VirtualBox
build, `--wait-stdout` and `--wait-stderr` are supported but `--wait-exit` is
not; use `closeprocess` when a process wait cannot complete. For `cmd.exe`
payloads, include `--unquoted-args` so Windows backslashes and the single `/c`
payload are preserved.
does not require WinRM, OpenSSH inside Windows, or a stable guest IP. The
adapter first validates the VM and snapshot UUIDs, acquires its exclusive lease
on Helium, and writes a non-secret step report to the run directory. Guest
commands use exact console-safe executable paths and argument vectors. With
this VirtualBox build, `--wait-stdout` and `--wait-stderr` are supported but
`--wait-exit` is not; use `closeprocess` when a process wait cannot complete.
For `cmd.exe` payloads, include `--unquoted-args` so Windows backslashes and
the single `/c` payload are preserved.
`stage` accepts one versioned non-secret test bundle and copies it first to an
exact host staging directory, then to
`C:\\ProgramData\\RVBox\\test-runs\\<run-id>`. `run` never directly executes the
GUI-subsystem `rvbox.exe` through Guest Control. It uses `sc.exe` and other
console-safe management tools to start/query/stop the installed RVBox service,
then checks the service's real health endpoint, named-pipe response, durable
state, and agent-server results. Before a WSS scenario it performs a bounded
guest-to-nginx connectivity and CA-trust probe. The resulting service and
artifact paths are recorded in the run report and reclaimed by the snapshot
reset rather than broad guest deletion.
### Required one-time service bootstrap
Guest Control launches `rvboxtest` with its filtered, medium-integrity UAC
token: the Administrators SID is deny-only. The harness must not bypass UAC to
create services. Before native service tests can run, an operator must use a
trusted interactive elevated session to install one test-only `RVBoxClient`
service in the baseline and grant only `rvboxtest` the service rights required
by the harness: query status/configuration, change its image/configuration,
start, and stop. The test account also needs write access only to the dedicated
`C:\\ProgramData\\RVBox\\test-runs` subtree; SYSTEM retains ownership of normal
RVBox state and logs. Record the resulting service SDDL and subtree ACL in this
document before taking a new reset snapshot.
Each run then stages an exact bundle, changes the bootstrapped service image to
that run's explicit `--service --config` command line, and starts it through
SCM. The one-time bootstrap is fixture administration, not a second RVBox
process, runtime elevation broker, or Task Scheduler mechanism. Native tests
for the production installer/UAC flow remain a separately interactive test;
they cannot be automated through this filtered Guest Control token.
## Scope and known limitations