- Vagrantfile: don't `dnf install rsync/curl` on RHEL boxes — it upgrades openssl-libs and breaks the box's sshd (same ABI issue as install.sh). rsync/curl ship preinstalled on generic/rocky9; fail loudly if a future box lacks them rather than silently corrupting the run. - full-stack-test.ps1: drop fedora from the default distro set (Vagrant Cloud's generic/fedora is EOL at f39; opt in via -Only fedora). - vm-install.sh (new): run install.sh from uploaded local source, overlay the working tree, rebuild, and probe health — so the harness tests the exact local code (incl. uncommitted) with sshd/firewall snapshots on every exit path for post-mortems. Recovered from a local stash. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ServerKit E2E Test Harness
One-click full-stack test that spins up fresh Linux VMs on your Windows box, installs ServerKit from your local working tree (uncommitted changes included), and runs an API harness against the live panel. Aggregates everything into a single HTML report.
Designed for the "I'm about to merge a huge PR and want to be sure the installer actually works on multiple distros" use case.
Prerequisites (one-time)
- Multipass — Ubuntu 22.04 + 24.04 VMs
winget install Canonical.Multipass - Vagrant — Debian 12, Fedora, Rocky 9 VMs (uses Hyper-V provider, no VirtualBox)
Note: Vagrant + Hyper-V requires running the script from an elevated PowerShell (right-click → Run as Administrator). If you run as a normal user, the script will tell you and exit cleanly. Multipass-only runs (Ubuntu) don't need admin.
winget install Hashicorp.Vagrant - Python 3 on PATH (for the HTML report generator; tests run inside the VMs).
- Hyper-V enabled (both Multipass and Vagrant use it on Windows).
You can install only Multipass if Ubuntu coverage is enough — the harness auto-detects which backends are available and skips distros it can't run.
Usage
From the repo root, in PowerShell:
.\scripts\test\full-stack-test.ps1
That's it. Goes and makes coffee. ~1-2 hours on first run (cloud images download), 15-30 min after that. When it finishes, your browser opens to the HTML report.
Options
# Full default suite: ubuntu22, ubuntu24, debian12, fedora, rocky9
.\scripts\test\full-stack-test.ps1
# Subset
.\scripts\test\full-stack-test.ps1 -Only "ubuntu24,debian12"
# Keep VMs running so you can shell in and poke around
.\scripts\test\full-stack-test.ps1 -Keep
# Bigger VMs (default 2 CPU / 4 GB RAM / 15 GB disk)
.\scripts\test\full-stack-test.ps1 -Cpus 4 -MemoryGB 8
# Re-run harness against an already-installed Multipass VM (fast iteration)
.\scripts\test\full-stack-test.ps1 -ReuseVm sk-test-ubuntu24-<id>
Distro coverage
| Distro | Backend | Box / Image |
|---|---|---|
| Ubuntu 22.04 | Multipass | 22.04 |
| Ubuntu 24.04 | Multipass | 24.04 |
| Debian 12 | Vagrant | generic/debian12 |
| Fedora | Vagrant | generic/fedora39 |
| Rocky 9 | Vagrant | generic/rocky9 |
Agent pairing test (optional)
After running with -Keep:
.\scripts\test\agent-test.ps1
Exercises the agent <-> panel pairing API end-to-end (enroll → claim).
What it does
- Tar your local repo (excluding
.git,node_modules, venvs,dist/). multipass launchthree VMs in parallel: Ubuntu 22.04, Ubuntu 24.04, Debian 12.- On each VM, in parallel:
- Upload the tarball +
vm-install.sh. - Run
install.sh(real public installer — clones from GitHub, installs Python, Node, Docker, nginx, builds frontend, starts systemd unit). - Overlay your local working tree on top of
/opt/serverkit, rebuild frontend, restartserverkitsystemd unit. This is what makes us test your code, not what's onmain. - Wait for
/api/v1/system/healthto return 200. - Push the pytest harness and run it against the live panel.
- Capture install log + journalctl regardless of outcome.
- Upload the tarball +
- Generate one self-contained
report.htmlwith green/red per VM, per test, plus full logs inline. - Tear down VMs (unless
-Keep).
Output
scripts/test/output/<run-id>/
report.html <- open this
serverkit-src.tar.gz
sk-test-ubuntu22-<id>/
install.log
vm-install.log
journalctl.log
install-status ("OK" or "FAIL")
pytest.log
pytest-report.json
sk-test-ubuntu24-<id>/ ...
sk-test-debian12-<id>/ ...
Extending the harness
Add new tests under harness/test_*.py — they're plain pytest using a
session-scoped admin_token fixture and a base_url fixture. The orchestrator
auto-copies every file in harness/ to each VM, so just dropping in a new
test_05_whatever.py is enough.
Currently covered:
test_01_health.py— backend health, frontend reachabletest_02_auth.py— setup-status, register, login, JWT-authed requesttest_03_plugins.py— list plugins (install-from-URL test is@skipif'd until a stable test plugin repo exists; flip when ready)test_04_smoke.py— sample of authed endpoints must not return 5xx
Limitations
- Doesn't test bare-metal-only stuff (hardware drivers, real partitioning).
- Agent ARM64 MSI installer isn't exercised (no ARM hardware).
- UI smoke (Playwright) is not wired up yet — easy to add as a follow-up if the API surface stops catching everything.
- Fedora/Rocky not in the default distro list because Multipass focuses on Ubuntu; add via Vagrant + libvirt if you need those.
Troubleshooting
"multipass: command not found" — install Multipass and restart PowerShell.
Launch fails with timeout — first launch downloads ~600 MB per distro
image; let it run. If it times out repeatedly, increase Multipass timeout:
multipass set local.driver=hyperv.
Health check never passes — open report.html, expand "Install log" and
"journalctl" for that VM. Most common: missing system package on a distro the
installer doesn't handle, or frontend build OOM (bump -MemoryGB).
Want to debug a failing VM — re-run with -Keep, then:
multipass shell sk-test-ubuntu24-<id>
sudo journalctl -u serverkit -f