195 lines
9.6 KiB
Markdown
195 lines
9.6 KiB
Markdown
# RVBox implementation test workflow
|
|
|
|
All Go, protobuf, and harness work runs in the pinned toolchain container. No
|
|
host Go installation is used.
|
|
|
|
Run the normal pre-commit gate with:
|
|
|
|
```sh
|
|
make verify
|
|
```
|
|
|
|
Run focused unit tests with:
|
|
|
|
```sh
|
|
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
|
|
```
|
|
|
|
`scripts/build doctor` reports the exact owned builder image, Go cache volumes,
|
|
and ignored `bin/` artifact directory. To reclaim space, cleanup is dry-run by
|
|
default and never performs a global Docker prune:
|
|
|
|
```sh
|
|
scripts/build clean --all
|
|
scripts/build clean --all --execute --yes
|
|
scripts/build recover
|
|
```
|
|
|
|
The second command removes only `bin/`, `rvbox-dev-toolchain:latest`, and the
|
|
two named RVBox Go-cache volumes. `recover` rebuilds the pinned toolchain and
|
|
all binaries from source. It intentionally does not remove `.test-runs/`, which
|
|
may contain resumable environments; use the exact-run `scripts/test-env purge`
|
|
workflow for those.
|
|
|
|
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
|
|
scripts/windows/test-host install --run-id windows-smoke
|
|
```
|
|
|
|
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`
|
|
scenarios. Each run writes its manifest and run ID before starting work.
|
|
The storage suite uses a real temporary SQLite database in WAL mode and a real
|
|
segment/audit filesystem. The session suite uses a real HTTP/WebSocket listener,
|
|
binary protobuf frames, SQLite fencing, and the race detector; neither mocks its
|
|
respective durability or wire boundary:
|
|
|
|
```sh
|
|
scripts/test-env doctor
|
|
scripts/test-integration --suite sample --run-id my-sample
|
|
scripts/test-env status --run-id my-sample
|
|
scripts/test-env collect --run-id my-sample
|
|
scripts/test-env reset --run-id my-sample
|
|
scripts/test-env reuse --run-id my-sample
|
|
scripts/test-integration --suite sample --run-id my-sample --resume
|
|
scripts/test-env reset --run-id my-sample
|
|
scripts/test-env purge --run-id my-sample
|
|
|
|
scripts/test-integration --suite store --run-id store-smoke
|
|
scripts/test-env logs --run-id store-smoke
|
|
scripts/test-env collect --run-id store-smoke
|
|
scripts/test-env reset --run-id store-smoke
|
|
scripts/test-env purge --run-id store-smoke
|
|
|
|
scripts/test-integration --suite server-session --run-id session-smoke
|
|
scripts/test-env logs --run-id session-smoke
|
|
scripts/test-env collect --run-id session-smoke
|
|
scripts/test-env reset --run-id session-smoke
|
|
scripts/test-env purge --run-id session-smoke
|
|
|
|
scripts/test-e2e --scenario smoke --run-id e2e-smoke
|
|
scripts/test-env status --run-id e2e-smoke
|
|
scripts/test-env recover --run-id e2e-smoke
|
|
scripts/test-e2e --scenario smoke --run-id e2e-smoke --resume
|
|
scripts/test-env reset --run-id e2e-smoke
|
|
scripts/test-env purge --run-id e2e-smoke
|
|
```
|
|
|
|
The client runtime unit lane also exercises a real child process through the
|
|
portable supervisor adapter. `internal/client/agent/executor_test.go` verifies
|
|
that command text is accepted once, output is journaled, lifecycle/terminal
|
|
events are durable, and a script cannot launch before its contiguous upload is
|
|
committed. The Windows build uses the same executor contract with the
|
|
platform-native adapter: a verified token is selected, the child is created
|
|
suspended, assigned to a kill-on-close Job, and held behind an authenticated
|
|
per-command launcher pipe. The daemon records `launch_prepared`, then the
|
|
durable `launch_authorized` transition sends the launcher's release frame; the
|
|
launcher resumes the shell only after that acknowledgement. The durable
|
|
`launch_phase` barrier is recovered as `interrupted` after a daemon restart, so
|
|
an uncertain release is never redispatched.
|
|
|
|
The Windows artifact is linked with the GUI subsystem (`-H=windowsgui`) so
|
|
service, launcher, and tray startup do not flash a console. Human-facing modes
|
|
still attach to a parent console explicitly when one exists.
|
|
|
|
Suite output is capped at 1 MiB and stored as `artifacts/suite.log`. A failed
|
|
run remains inspectable and can be moved back to `ready` with `recover`, then
|
|
resumed with the same run ID and deterministic shuffle seed. Test-run cleanup
|
|
never removes the shared Go module or build-cache volumes.
|
|
|
|
Each run owns only `.test-runs/<run-id>` and resources explicitly recorded in
|
|
that run's versioned manifest. The journal is append-only and fsynced. `purge`
|
|
validates the run ID and manifest identity, refuses symlink targets or manifests
|
|
that still list runtime resources, and then removes only that exact run. Purged
|
|
artifacts are not recoverable. Dependency cache volumes are never part of run
|
|
cleanup.
|
|
|
|
`test/coverage.toml` is the incremental requirement-to-test inventory. The
|
|
`make verify` lint stage checks unique stable IDs and verifies every implemented
|
|
test reference against source. A resettable Windows smoke VM is now available.
|
|
The authoritative fixture record is
|
|
[testing-vm.md](testing-vm.md): it lists the VM/host UUIDs, Windows build,
|
|
hardware and device profile, NAT and VRDE endpoints, snapshot UUIDs,
|
|
credential-file contract, and the required reset sequence. At the last check
|
|
the VM was powered off with `baseline-disk-first` selected. The guest address
|
|
`10.0.2.15` is DHCP state only; use SSH plus VirtualBox Guest Control rather
|
|
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 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 VM identity, fixed test-only account names, and
|
|
password-file path are safe defaults in that script and may be overridden for
|
|
another documented fixture. The fixed disposable-VM password remains only in
|
|
that mode-600 file; the controller never puts it on a command line, manifest,
|
|
log, or artifact.
|
|
|
|
The native lifecycle is `status`, `prepare`, `stage`, `install`, `run`,
|
|
`collect`, `stop`, and `reset`. `prepare` verifies the VM and snapshot UUIDs,
|
|
restores the clean baseline, starts headless, waits for Guest Additions, and
|
|
proves that `RVBoxClient` is absent. `stage` copies a versioned non-secret test
|
|
bundle through a run-specific host directory to a run-specific guest directory.
|
|
`install` uses the fixture-only high-integrity automation principal to invoke
|
|
the real `rvbox.exe --install-service` path and proves completion through SCM.
|
|
`run` is for reconfiguration/restart scenarios after that first installation.
|
|
Neither action invokes the GUI-subsystem executable directly with the normal
|
|
Guest Control account. `collect` obtains only bounded/redacted artifacts, and
|
|
`reset` restores the exact clean 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 clean baseline intentionally contains no RVBox service, tray registration,
|
|
or RVBox state. Guest Control supplies `rvboxtest` with a filtered medium UAC
|
|
token, so it cannot safely perform the first machine-wide install. The fixture
|
|
therefore uses its separately enabled built-in `Administrator` account as a
|
|
test-only full-token automation principal. Its `FilterAdministratorToken` must
|
|
remain `0`, preserving UAC for `rvboxtest` rather than disabling it machine-wide.
|
|
Its username and mode-600 host-side password-file are provided only as
|
|
`RVBOX_TEST_PROVISIONER_USER` and `RVBOX_TEST_PROVISIONER_PASSWORD_FILE` for
|
|
the `install`/machine-mutation actions. It is not an RVBox process, service,
|
|
broker, or Task Scheduler dependency, and it is never used to choose a command
|
|
execution context. The normal `rvboxtest` console session remains the subject
|
|
of active-user and elevation tests. See [testing-vm.md](testing-vm.md) for the
|
|
exact fixture contract.
|
|
|
|
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.
|