Files
nixos-router/tests/lab.nix
T
nilsandClaude Sonnet 5.5 dcef7665b4 Add MVP router flake with VM test and tmux lab
router.* schema (wan, lans, dns.forwarders) compiled to systemd-networkd,
a generated nftables ruleset with NAT, Kea DHCPv4 and Unbound, plus build-time
assertions against lock-out and interface conflicts.

tests/basic.nix is a three-node VM test (upstream/router/client) covering WAN
DHCP, LAN DHCP and DNS, NAT, WAN-deny and LAN SSH/ping. `nix run .#lab` boots
the same topology in tmux with one console pane per VM and the driver REPL.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 13:38:41 +01:00

45 lines
2.0 KiB
Nix

# Shell script for `nix run .#lab` (see flake.nix).
{ lib, driver, nodes }:
''
sock=nixos-router-lab
log=$(mktemp -t nixos-router-lab.XXXXXX)
trap 'tmux -L $sock kill-server 2>/dev/null || true; rm -f "$log"' EXIT
tmux -L $sock kill-server 2>/dev/null || true
# Bottom pane: the test-driver REPL. `script` keeps it on a tty while
# logging everything it prints, which the per-VM panes below filter.
# When the REPL exits, take the whole session down.
repl=$(tmux -L $sock new-session -d -x 220 -y 60 -s lab -P -F '#{pane_id}' \
"script -qfc '${driver}/bin/nixos-test-driver --interactive' '$log'; tmux -L $sock kill-server")
tmux -L $sock set -g pane-border-status top
tmux -L $sock select-pane -t "$repl" -T repl
# Top row: one pane per VM, console lines only (prefixed "<name> #").
prev="$repl"
first=1
remaining=${toString (builtins.length nodes - 1)}
for node in ${lib.escapeShellArgs nodes}; do
cmd="tail -F '$log' 2>/dev/null | grep -a --line-buffered -E \"(^|\\[[0-9;]*m)$node #\""
if [ "$first" = 1 ]; then
prev=$(tmux -L $sock split-window -vb -l 65% -t "$prev" -P -F '#{pane_id}' "$cmd")
first=0
else
# Give the new pane its share of the pane being split, so the row ends up even.
prev=$(tmux -L $sock split-window -h -l "$((100 * remaining / (remaining + 1)))%" -t "$prev" -P -F '#{pane_id}' "$cmd")
remaining=$((remaining - 1))
fi
tmux -L $sock select-pane -t "$prev" -T "$node"
done
# Boot the VMs once the REPL is ready, and leave a reminder at the prompt.
for _ in $(seq 60); do
tmux -L $sock capture-pane -p -t "$repl" | grep -q CPython && break
sleep 0.5
done
tmux -L $sock send-keys -t "$repl" 'start_all()' Enter
tmux -L $sock send-keys -t "$repl" -l 'print("router.shell_interact() | client.succeed(\"ip a\") | test_script() | Ctrl-D quits, Ctrl-b d detaches")'
tmux -L $sock send-keys -t "$repl" Enter
tmux -L $sock select-pane -t "$repl"
tmux -L $sock attach -t lab
''