|
4 | 4 | inputs = { |
5 | 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; |
6 | 6 | flake-utils.url = "github:numtide/flake-utils"; |
| 7 | + # Packaged PTY fleet-observation gate: the exact `pty list --json` producer revision with |
| 8 | + # ambiguity-safe PID reads, EPERM handling, and one fleet-wide socket fallback budget. |
| 9 | + pty.url = "github:compoundingtech/pty/afeb3b6234b7010b7db802fd029766ad17c14219"; |
| 10 | + pty.inputs.nixpkgs.follows = "nixpkgs"; |
7 | 11 | }; |
8 | 12 |
|
9 | 13 | outputs = |
10 | 14 | { |
11 | 15 | self, |
12 | 16 | nixpkgs, |
13 | 17 | flake-utils, |
| 18 | + pty, |
14 | 19 | }: |
15 | 20 | flake-utils.lib.eachDefaultSystem ( |
16 | 21 | system: |
|
118 | 123 | }; |
119 | 124 | }; |
120 | 125 |
|
| 126 | + # Narrow sandbox-safe integration gate for the atomic snapshot boundary. The main package |
| 127 | + # deliberately omits the broad doctor suite because some doctor cases exercise facilities |
| 128 | + # unavailable in the Nix sandbox. A dedicated target containing exactly one test makes the |
| 129 | + # gate structurally non-vacuous: a missing target is a cargo error, never a zero-match pass. |
| 130 | + st2AtomicPtySnapshot = st2.overrideAttrs (_: { |
| 131 | + pname = "st2-atomic-pty-snapshot-check"; |
| 132 | + cargoTestFlags = [ |
| 133 | + "--test" |
| 134 | + "atomic_pty_snapshot" |
| 135 | + ]; |
| 136 | + }); |
| 137 | + |
121 | 138 | hookSuccessorSource = pkgs.runCommand "st2-hook-successor-source" { } '' |
122 | 139 | cp -R ${self} $out |
123 | 140 | chmod -R u+w $out |
|
150 | 167 | # commits on every rebase. The devShell ships rustfmt + clippy for whoever |
151 | 168 | # wants them. |
152 | 169 | checks.st2 = st2; |
| 170 | + checks.atomic-pty-snapshot = st2AtomicPtySnapshot; |
| 171 | + |
| 172 | + # Real producer-consumer contract: st2 consumes `pty list --json` from the exact pty |
| 173 | + # revision that owns fleet observation. Fake CLI fixtures below still cover malformed |
| 174 | + # output and a wedged child; this check proves the healthy 0/75/100/500-session path crosses |
| 175 | + # both packaged binaries within st2's short outer deadline. |
| 176 | + checks.pty-fleet-contract = pkgs.runCommand "st2-pty-fleet-contract-${version}" { |
| 177 | + nativeBuildInputs = [ |
| 178 | + pkgs.coreutils |
| 179 | + pkgs.jq |
| 180 | + pkgs.nodejs |
| 181 | + pty.packages.${system}.default |
| 182 | + st2 |
| 183 | + ]; |
| 184 | + } '' |
| 185 | + export HOME=$(mktemp -d) |
| 186 | + catalog=$(mktemp -d) |
| 187 | + mkdir -p "$catalog/agents/contract/gone" |
| 188 | + printf '%s\n' \ |
| 189 | + 'agent "gone" { host "contract"; retired #true; command "true" }' \ |
| 190 | + > "$catalog/agents/contract/gone/agent.kdl" |
| 191 | +
|
| 192 | + # Run the exact packaged producer's deterministic fault seams. These prove EPERM avoids |
| 193 | + # socket fallback and hundreds of indefinitely-hung ambiguous probes share one deadline. |
| 194 | + test_config=$(mktemp --suffix=.mjs) |
| 195 | + printf '%s\n' 'export default { test: {} }' > "$test_config" |
| 196 | + node \ |
| 197 | + ${pty.packages.${system}.default}/lib/pty/node_modules/vitest/vitest.mjs \ |
| 198 | + run tests/list-liveness-budget.test.ts \ |
| 199 | + --config "$test_config" \ |
| 200 | + --root ${pty.packages.${system}.default}/lib/pty |
| 201 | +
|
| 202 | + for fleet_size in 0 75 100 500; do |
| 203 | + root=$(mktemp -d) |
| 204 | + i=0 |
| 205 | + while test "$i" -lt "$fleet_size"; do |
| 206 | + session=$(printf 'session-%03d' "$i") |
| 207 | + : > "$root/$session.sock" |
| 208 | + printf '%s\n' "$$" > "$root/$session.pid" |
| 209 | + i=$((i + 1)) |
| 210 | + done |
| 211 | +
|
| 212 | + PTY_ROOT="$root" timeout 2s pty list --json > "pty-$fleet_size.json" |
| 213 | + jq -e --argjson size "$fleet_size" \ |
| 214 | + 'length == $size and all(.status == "running")' \ |
| 215 | + "pty-$fleet_size.json" >/dev/null |
| 216 | +
|
| 217 | + PTY_ROOT="$root" timeout 2s \ |
| 218 | + st2 doctor --catalog "$catalog" --host contract \ |
| 219 | + > "doctor-$fleet_size.out" |
| 220 | + grep -F 'contract.gone retirement complete' \ |
| 221 | + "doctor-$fleet_size.out" >/dev/null |
| 222 | + done |
| 223 | +
|
| 224 | + touch $out |
| 225 | + ''; |
153 | 226 |
|
154 | 227 | # Smoke test that the built binary actually runs and its command tree is |
155 | 228 | # wired, independent of the in-tree `cargo test`. |
|
0 commit comments