atagen

monolith

public
Star0
Watch0

Commit 612b2f27111c

tarball

atagen <boss@atagen.co>2026-10-17 05:07 UTC

1 file changed+75-0
scripts: add a nested smoke harness

Every protocol so far was checked with a throwaway shell script against a nested instance. This one runs real clients through windows, the toplevel list, ext-workspace, both capture sources, wlr close, layer-shell and lock, and exits non-zero on any failure.
Added file: scripts/smoke.nu+75 additions
@@ -0,0 +1,75 @@
1+# Runs monolith nested on the host session with real clients and checks what
2+# they see. Run from the repo root inside `nix develop`, after
3+# `cargo build -p monolith && cargo build -p monolith-protocols --example workspaces`.
4+
5+const TOOLS = [foot xterm xwayland lswt grim swaybg swaylock wlrctl]
6+
7+def main [--log: path = /tmp/monolith-smoke.log] {
8+ let tools = $TOOLS | each {|t| $"nixpkgs#($t)" }
9+ let results = mktemp -t monolith-smoke.XXXXXX
10+ let script = $env.CURRENT_FILE
11+ let inner = $"nu -n ($script) inner ($results) ($log)"
12+ # Some parent shells hand down SIGTERM blocked, so only SIGKILL reliably ends a hung run.
13+ do -i { ^nix shell ...$tools -c sh -c $"unset VK_DRIVER_FILES; RUST_LOG=monolith=debug timeout -s KILL 60 target/debug/monolith run --backend nested ($inner) > ($log) 2>&1" }
14+ let rows = open --raw $results | lines | where $it != "" | each {|l| $l | from json }
15+ rm $results
16+ if ($rows | is-empty) {
17+ print $"no results, see ($log)"
18+ exit 1
19+ }
20+ print ($rows | table)
21+ if ($rows | any {|r| not $r.ok }) { exit 1 }
22+}
23+
24+def "main inner" [results: path, log: path] {
25+ try { scenarios $results $log } catch {|e| {name: "harness", ok: false, detail: $e.msg} | to json -r | $"($in)\n" | save -a $results }
26+ target/debug/monolith msg quit
27+}
28+
29+def scenarios [results: path, log: path] {
30+ let check = {|name: string, ok: bool, detail: any|
31+ {name: $name, ok: $ok, detail: ($detail | to text | str trim)} | to json -r | $"($in)\n" | save -a $results
32+ }
33+ let windows = {|| target/debug/monolith get state | from json | get windows | length }
34+
35+ job spawn { foot }
36+ job spawn { foot }
37+ job spawn { xterm -e sleep 60 }
38+ let n = wait-until 10sec {|| (do $windows) == 3 }
39+ do $check "three windows over ipc" ($n) (do $windows)
40+
41+ let listed = lswt | lines | skip 1 | length
42+ do $check "toplevel list shows them" ($listed == 3) $listed
43+
44+ let ws = do { timeout 1 target/debug/examples/workspaces } | complete | get stdout
45+ do $check "ext-workspace sends a snapshot" ($ws | str contains "workspace") ($ws | lines | length)
46+
47+ let shot = mktemp -t smoke-XXXXXX.png
48+ let full = grim $shot | complete
49+ do $check "output capture" ($full.exit_code == 0 and (ls $shot | get 0.size) > 0b) $full.stderr
50+ let id = lswt -j | from json | get toplevels.0.identifier
51+ let one = grim -T $id $shot | complete
52+ do $check "toplevel capture" ($one.exit_code == 0) $one.stderr
53+ rm $shot
54+
55+ wlrctl toplevel close app_id:XTerm
56+ let closed = wait-until 5sec {|| (do $windows) == 2 }
57+ do $check "wlr-foreign-toplevel close" $closed (do $windows)
58+
59+ job spawn { swaybg -c "#336699" }
60+ let layer = wait-until 5sec {|| open --raw $log | str contains 'namespace="wallpaper"' }
61+ do $check "layer surface mapped" $layer ""
62+
63+ job spawn { swaylock -c 000000 }
64+ let locked = wait-until 5sec {|| open --raw $log | str contains "session locked" }
65+ do $check "session lock" $locked ""
66+}
67+
68+def wait-until [limit: duration, cond: closure] {
69+ let until = (date now) + $limit
70+ loop {
71+ if (do $cond) { return true }
72+ if (date now) > $until { return false }
73+ sleep 100ms
74+ }
75+}