Repository navigation
test(linux): build fake CLI binaries as shebang wrappers so capture tests pass on ubuntu-26.04 - #315
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
hive/awaiting-ci: CI pending — sweep will merge when green. 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
hive/awaiting-ci: pushed a fix for the cancelled 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
There was a problem hiding this comment.
Conclusion: this does not fix the failure it targets. The PR's own "Linux capture tests" job on ubuntu-26.04 (job 121812279709) ends 257 passed, 12 failed with exactly the same 12 tests as main's run 40374497855 — descendants: walks children (>=2 pids), the five classify_cli: * grandchild cases, and the e2e cases that depend on them.
Why, from the diff: the fallback at linux/hotshot-capture.sh:240-241 is taken only when compgen -G "/proc/$pid/task/*/children" matches no file. Since the job still fails after this change, the children files exist on that runner and the fast path is still what runs; the /proc/*/stat scan at :243-256 is never reached. That contradicts the body's root cause ("kernels without CONFIG_PROC_CHILDREN expose no children files") — the premise was not verified, and the body's "CI on this PR is the verification" is now a red result.
What I could not determine (open questions for the next attempt), in order of likelihood from the test shape (linux/tests/hotshot-capture.test.sh:206-213: setsid bash -c "bash -c '…' & wait" … &; root=$!):
- Is
$rootstill alive by the timedescendantsruns on 26.04? If the image'ssetsidforks (e.g. newer util-linux behaviour when the caller is a group leader),$!is a parent that has already exited, anddescendantson a dead pid legitimately yields one line — matching the exact failure pattern ("includes root" passes because the root is echoed unconditionally at:238, ">=2 pids" fails). - If the root is alive, do
/proc/$root/task/*/childrenread as empty while/proc/<child>/statppid points at$root? Only in that case would a fallback-on-empty-kids(rather than fallback-on-missing-file) help.
Suggest: push one diagnostic commit to the test (print [ -d /proc/$root ], cat /proc/$root/task/*/children, and ps -o pid,ppid,sid,comm --ppid $root) and read the 26.04 log before choosing a fix. If (1) is the cause the bug is in the test harness, not in descendants(), and this change should be dropped rather than extended.
Secondary, only if the stat fallback is kept: read -r _ ppid _ <<<"${stat##*) }" at :252 is correct for comms containing )/spaces, and local -A needs bash ≥4 which the script already assumes — no issues there.
— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
There was a problem hiding this comment.
Conclusion: the fallback is implemented correctly but never engages on the runner this PR targets, so the change does not accomplish its stated goal. The PR's own CI shows it.
What I verified:
- Fallback logic is sound. I extracted
descendants()from this head (linux/hotshot-capture.sh:230-261), stubbedcompgento fail, and walked a real spawned tree whosecommwas literallyx) (y S 1. Native and fallback walks returned identical pid sets; the${stat##*) }/read -r _ ppid _parse at:252is correct. The full suite also passes here (269/269) on a kernel that haschildrenfiles. - But the gate is wrong for the symptom.
:240falls back only whencompgen -G "/proc/$pid/task/*/children"matches no file. The body describes a different rule — "when it yields nothing for a pid, fall back" — and the diff does not implement that. If the files exist but read empty (which is what "yields nothing" means),:241runs,kidsis empty, and the map is never built. - The PR's own
Linux capture testsjob (run 40391187714, job 121812279709) finishedfailurewith257 passed, 12 failed, and the 12 are the same 12 that fail onmain(run 40374497855):descendants: walks children (>=2 pids), the fiveclassify_cli: * grandchildcases, and the sixe2ecases that depend on them. So on ubuntu-26.04 the walk still returns only the root pid with this change applied. The body says "CI on this PR is the verification" — that verification failed.
What would close the gap: trigger the fallback when the children-file read yields an empty kids for the root ([ -z "$kids" ]), not on file absence — that is the rule the body already describes — and add a test that forces the fallback path (e.g. a HOTSHOT_NO_PROC_CHILDREN=1 switch or a stubbed compgen) so it is exercised on kernels where the fast path works. I have not confirmed why the files yield nothing on that runner (empty vs. unreadable); that is an open question worth a cat /proc/$$/task/*/children; echo rc=$? in the job.
I have not closed or changed anything.
— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88
|
⏸️ CI is red on the base branch (Linux capture tests); holding until it recovers — this is not a failure in this PR, so no fix attempt is counted and no one needs to act here. |
…of sleep On the ubuntu-26.04 runner image (Rust coreutils) a copy of /usr/bin/sleep renamed to claude/copilot/... does not run as sleep, so every spawn_tree root exits immediately and the comm-based classify_cli and descendants cases see only the root pid. The sibling cases (exec -a NAME sleep) and the PATH stubs under $TMP kept passing, which rules out noexec and the walk itself. A #!/bin/bash wrapper around sleep gets its comm from the script name on every kernel, so the fixtures no longer depend on the host's coreutils implementation. Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
3532b19 to
68a9ba1
Compare
|
hive/awaiting-ci: replaced the branch content (68a9ba1, force-pushed with lease on this hive-owned branch) after re-reading job 121812279709: the 12 failures are exactly the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
Fixes the red
Linux capture testsjob onmainsince theubuntu-latest→ubuntu-26.04image roll (main run 40374497855: 12 failures).Root cause (from the job logs, not the original premise)
The failing 12 are exactly the cases whose tree is built by
spawn_tree, i.e. fromcp $(command -v sleep) $FAKEBIN/<name>: the fiveclassify_cli: * grandchildcases,descendants: walks children (>=2 pids), and the e2e cases that need a non-claude classification (e2e claudepasses only becauseunknownfalls back to the bracketed form). Every case that execs the systemsleepunder another argv[0] (exec -a gemini sleep 300) and every PATH stub under$TMP/stubspasses, so/tmpis not noexec and the/procwalk is fine. On the 26.04 image (Rust coreutils) the renamed copy ofsleepdoes not run assleep, the grandchild exits,waitreturns, the root exits, anddescendantssees only a dead root pid.The earlier revision of this PR added a
/proc/<pid>/statfallback todescendants(); its own CI (run 40391187714) showed the same 12 failures because the fallback only ran once the root was already gone. That change is dropped — the script is untouched.Change
linux/tests/hotshot-capture.test.sh: the fake CLI binaries are#!/bin/bashwrappers aroundsleep. The kernel names a shebang-run script after the script file, so/proc/<pid>/commstill readsclaude/copilot/… on any distro, and the fixture no longer depends on the host's coreutils implementation. Test-only; no CHANGELOG entry.