Use tmux for test runner — detachable SSH sessions
Tests now run inside a tmux session so you can disconnect and reconnect without interrupting multi-hour test runs. Changes: - create-vm.sh: cloud-init no longer auto-runs tests, just provisions packages and clones the repo. Installs a `darkforge-test` command in /usr/local/bin that wraps run-in-vm.sh in tmux. - run-in-vm.sh: detects when called as `darkforge-test` and re-execs inside a tmux session named "darkforge". --tmux flag for internal use. - README updated with tmux workflow (detach/reattach instructions). Workflow: ssh darkforge@<ip> darkforge-test --quick # starts in tmux Ctrl+B D # detach, go do other things tmux attach -t darkforge # come back later Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,33 +40,63 @@ Without the target hardware (9950X3D / RTX 5090), we can still test:
|
|||||||
### 1. Create the test VM (run on Proxmox host)
|
### 1. Create the test VM (run on Proxmox host)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Copy scripts to Proxmox host
|
# Copy the script to Proxmox and run it
|
||||||
scp tests/proxmox/create-vm.sh root@proxmox:/root/
|
scp tests/proxmox/create-vm.sh root@your-proxmox:/root/
|
||||||
scp tests/proxmox/run-in-vm.sh root@proxmox:/root/
|
ssh root@your-proxmox bash /root/create-vm.sh
|
||||||
|
|
||||||
# Create the VM
|
|
||||||
ssh root@proxmox bash /root/create-vm.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Run the tests (automated via cloud-init or manual SSH)
|
This creates the VM and cloud-init installs all packages + clones the repo. Wait ~5 minutes for provisioning to complete.
|
||||||
|
|
||||||
|
### 2. SSH in and run tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Option A: wait for cloud-init to finish (fully automated)
|
# Get the VM IP from Proxmox
|
||||||
# The VM runs tests automatically on first boot.
|
ssh root@your-proxmox "qm guest cmd 900 network-get-interfaces" | grep ip-address
|
||||||
|
|
||||||
# Option B: SSH in and run manually
|
# SSH into the VM
|
||||||
ssh darkforge@<vm-ip> bash /home/darkforge/run-in-vm.sh
|
ssh darkforge@<VM_IP> # password: darkforge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then start the tests. They run inside a **tmux session** so you can disconnect and reconnect without interrupting them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full test suite (~2-6 hours) — runs in tmux, safe to disconnect
|
||||||
|
darkforge-test
|
||||||
|
|
||||||
|
# Fast mode (~30 min) — skips toolchain/kernel/ISO builds
|
||||||
|
darkforge-test --quick
|
||||||
|
|
||||||
|
# Medium mode (~1 hour) — skips only toolchain bootstrap
|
||||||
|
darkforge-test --no-build
|
||||||
|
```
|
||||||
|
|
||||||
|
**tmux controls:**
|
||||||
|
- `Ctrl+B` then `D` — detach (tests keep running in background)
|
||||||
|
- `tmux attach -t darkforge` — reattach to see progress
|
||||||
|
- `tmux ls` — list running sessions
|
||||||
|
|
||||||
### 3. Collect the report
|
### 3. Collect the report
|
||||||
|
|
||||||
|
Once tests finish (check with `tmux attach -t darkforge`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scp darkforge@<vm-ip>:/home/darkforge/darkforge/tests/report.json ./
|
# From your local machine
|
||||||
scp darkforge@<vm-ip>:/home/darkforge/darkforge/tests/report.txt ./
|
scp darkforge@<VM_IP>:~/darkforge/tests/report.json ./
|
||||||
|
scp darkforge@<VM_IP>:~/darkforge/tests/report.txt ./
|
||||||
|
```
|
||||||
|
|
||||||
|
The `report.txt` is a human-readable summary. The `report.json` is machine-readable and can be given to the development process for automated debugging.
|
||||||
|
|
||||||
|
### 4. Re-run after code changes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh darkforge@<VM_IP>
|
||||||
|
cd ~/darkforge
|
||||||
|
git pull --recurse-submodules
|
||||||
|
darkforge-test --quick # re-run tests
|
||||||
```
|
```
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
|
|
||||||
- `create-vm.sh` — runs on the Proxmox host, creates and configures the VM
|
- `create-vm.sh` — runs on the Proxmox host, creates and configures the VM
|
||||||
- `run-in-vm.sh` — runs inside the VM, clones the project and runs all tests
|
- `run-in-vm.sh` — runs inside the VM, executes all test suites, generates reports
|
||||||
- `cloud-init-user.yaml` — cloud-init user-data for automated first-boot testing
|
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ packages:
|
|||||||
- bc
|
- bc
|
||||||
- rsync
|
- rsync
|
||||||
- openssh
|
- openssh
|
||||||
|
- tmux
|
||||||
|
|
||||||
runcmd:
|
runcmd:
|
||||||
# Grow the partition to fill the disk
|
# Grow the partition to fill the disk
|
||||||
@@ -159,21 +160,26 @@ runcmd:
|
|||||||
echo "CLONE FAILED — manually clone the repo"
|
echo "CLONE FAILED — manually clone the repo"
|
||||||
'
|
'
|
||||||
|
|
||||||
# Copy the test runner
|
# Create the darkforge-test convenience command
|
||||||
- |
|
- |
|
||||||
if [ -f /home/darkforge/darkforge/tests/proxmox/run-in-vm.sh ]; then
|
cat > /usr/local/bin/darkforge-test << 'DTEOF'
|
||||||
cp /home/darkforge/darkforge/tests/proxmox/run-in-vm.sh /home/darkforge/
|
#!/bin/bash
|
||||||
chown darkforge:darkforge /home/darkforge/run-in-vm.sh
|
SCRIPT="/home/darkforge/darkforge/tests/proxmox/run-in-vm.sh"
|
||||||
chmod +x /home/darkforge/run-in-vm.sh
|
if [ ! -f "$SCRIPT" ]; then
|
||||||
|
echo "ERROR: Test script not found. Is the repo cloned?"
|
||||||
|
echo " git clone --recurse-submodules https://git.dannyhaslund.dk/danny8632/darkforge.git ~/darkforge"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
ARGS="$*"
|
||||||
|
exec tmux new-session -d -s darkforge \
|
||||||
|
"bash ${SCRIPT} --tmux ${ARGS}; echo ''; echo 'Tests finished. Press Enter to close.'; read" \; \
|
||||||
|
attach-session -t darkforge
|
||||||
|
DTEOF
|
||||||
|
chmod +x /usr/local/bin/darkforge-test
|
||||||
|
|
||||||
# Run the test suite automatically
|
# Signal that provisioning is done
|
||||||
- |
|
- touch /home/darkforge/.provisioned
|
||||||
su - darkforge -c '
|
- chown darkforge:darkforge /home/darkforge/.provisioned
|
||||||
if [ -f /home/darkforge/run-in-vm.sh ]; then
|
|
||||||
bash /home/darkforge/run-in-vm.sh 2>&1 | tee /home/darkforge/test-output.log
|
|
||||||
fi
|
|
||||||
'
|
|
||||||
CLOUDINIT
|
CLOUDINIT
|
||||||
|
|
||||||
qm set "${VMID}" --cicustom "user=local:snippets/darkforge-test-init.yaml"
|
qm set "${VMID}" --cicustom "user=local:snippets/darkforge-test-init.yaml"
|
||||||
@@ -187,23 +193,22 @@ echo ""
|
|||||||
echo "═══════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════"
|
||||||
echo " VM ${VMID} created and starting."
|
echo " VM ${VMID} created and starting."
|
||||||
echo ""
|
echo ""
|
||||||
echo " The VM will:"
|
echo " Cloud-init will install packages and clone the repo."
|
||||||
echo " 1. Boot Arch Linux"
|
echo " Wait ~5 min for provisioning, then SSH in to run tests."
|
||||||
echo " 2. Install required packages via cloud-init"
|
|
||||||
echo " 3. Clone the DarkForge repository"
|
|
||||||
echo " 4. Run the full test suite"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " Monitor progress:"
|
echo " Get the VM IP:"
|
||||||
echo " qm terminal ${VMID} (serial console)"
|
echo " qm guest cmd ${VMID} network-get-interfaces | grep -oP '\"ip-address\":\\s*\"\\K[0-9.]+'"
|
||||||
echo ""
|
echo ""
|
||||||
echo " SSH access (after boot):"
|
echo " SSH in:"
|
||||||
echo " ssh darkforge@\$(qm guest cmd ${VMID} network-get-interfaces | grep -oP '\"ip-address\":\\s*\"\\K[0-9.]+')"
|
echo " ssh darkforge@<IP> (password: darkforge)"
|
||||||
echo " Password: darkforge"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " Or get IP:"
|
echo " Run tests in a tmux session (detachable):"
|
||||||
echo " qm guest cmd ${VMID} network-get-interfaces"
|
echo " darkforge-test # starts tests in tmux"
|
||||||
|
echo " darkforge-test --quick # fast mode (30 min)"
|
||||||
echo ""
|
echo ""
|
||||||
echo " Collect report after tests finish:"
|
echo " Detach from tmux: Ctrl+B then D"
|
||||||
echo " VM_IP=\$(qm guest cmd ${VMID} network-get-interfaces | grep -oP '\"ip-address\":\\s*\"\\K[0-9.]+')"
|
echo " Reattach later: tmux attach -t darkforge"
|
||||||
echo " scp darkforge@\$VM_IP:/home/darkforge/darkforge/tests/report.* ./"
|
echo ""
|
||||||
|
echo " Collect report:"
|
||||||
|
echo " scp darkforge@<IP>:~/darkforge/tests/report.* ./"
|
||||||
echo "═══════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════"
|
||||||
|
|||||||
@@ -18,11 +18,33 @@
|
|||||||
# 10. Generates a JSON + text report
|
# 10. Generates a JSON + text report
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# bash run-in-vm.sh # full run (2-6 hours depending on hardware)
|
# darkforge-test # runs in tmux (detachable)
|
||||||
# bash run-in-vm.sh --quick # skip toolchain/kernel/ISO (30 min)
|
# darkforge-test --quick # fast mode in tmux
|
||||||
# bash run-in-vm.sh --no-build # skip toolchain bootstrap (1 hour)
|
# bash run-in-vm.sh # direct run (2-6 hours)
|
||||||
|
# bash run-in-vm.sh --quick # direct, skip toolchain/kernel/ISO (30 min)
|
||||||
|
# bash run-in-vm.sh --no-build # direct, skip toolchain bootstrap (1 hour)
|
||||||
|
#
|
||||||
|
# tmux controls:
|
||||||
|
# Ctrl+B then D — detach (tests keep running)
|
||||||
|
# tmux attach -t darkforge — reattach
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
# --- If called as "darkforge-test", wrap in tmux ----------------------------
|
||||||
|
TMUX_MODE=false
|
||||||
|
for arg in "$@"; do
|
||||||
|
[ "$arg" = "--tmux" ] && TMUX_MODE=true
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$TMUX_MODE" = false ] && [ "$(basename "$0")" = "darkforge-test" ]; then
|
||||||
|
# Re-exec ourselves inside a tmux session
|
||||||
|
ARGS="$*"
|
||||||
|
exec tmux new-session -d -s darkforge \
|
||||||
|
"bash $(readlink -f "$0") --tmux ${ARGS}; echo ''; echo 'Tests finished. Press Enter to close.'; read" \; \
|
||||||
|
attach-session -t darkforge
|
||||||
|
fi
|
||||||
|
# Strip --tmux from args for the actual test run
|
||||||
|
set -- $(echo "$@" | sed 's/--tmux//g')
|
||||||
|
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|||||||
Reference in New Issue
Block a user