Summary
The PTY test harness already explains a missing expect clearly, but only the first test to hit it ever sees that message. That panic happens while holding PTY_GATE, so the mutex is poisoned and every later PTY test panics on the lock instead, reporting only PTY test gate poisoned: PoisonError { .. }. On a machine without expect this turns one legible failure into 32 illegible ones spread across five test binaries.
Steps to reproduce
- On a Linux machine without
expect installed, from a clean checkout:
cargo test --workspace --locked --no-fail-fast
- Observe 33 failures across
clean, disablement, responsive, scan, and trash, of which exactly one names the real cause.
Expected behavior
Every test that cannot run because expect is absent says so, or is skipped with that reason. A reader should not have to search the full log for the single test that reported the true cause.
Actual behavior
crates/degu/tests/support/pty.rs:53 takes PTY_GATE with .expect("PTY test gate poisoned"). The dependency check at :85 panics inside that critical section, so the guard is dropped while panicking and the mutex is poisoned. Subsequent tests fail at :53 with a poisoning message that says nothing about expect, and the failure count makes it look like a broad product regression.
Environment
degu version: 0.1.7 (workspace, from source)
installation method: built from source
OS/kernel/architecture: x86_64 Linux
filesystem type: local ext4
byte or inode quota involved: no
Reproduced against an unmodified checkout.
Relevant output or logs
# the one test that reports the real cause
thread '...' panicked at crates/degu/tests/support/pty.rs:85:13:
`expect` is required for PTY integration tests; install it and ensure it is on PATH
# what the other 32 report
thread '...' panicked at crates/degu/tests/support/pty.rs:53:39:
PTY test gate poisoned: PoisonError { .. }
Suggested direction
The gate only serializes PTY use; it guards no invariant that a panic could leave broken, so recovering from poisoning is safe — .unwrap_or_else(|poisoned| poisoned.into_inner()). Checking for expect before taking the lock would also keep the diagnosis intact for every test, and would let the whole group be skipped with one reason rather than failed.
Summary
The PTY test harness already explains a missing
expectclearly, but only the first test to hit it ever sees that message. That panic happens while holdingPTY_GATE, so the mutex is poisoned and every later PTY test panics on the lock instead, reporting onlyPTY test gate poisoned: PoisonError { .. }. On a machine withoutexpectthis turns one legible failure into 32 illegible ones spread across five test binaries.Steps to reproduce
expectinstalled, from a clean checkout:cargo test --workspace --locked --no-fail-fastclean,disablement,responsive,scan, andtrash, of which exactly one names the real cause.Expected behavior
Every test that cannot run because
expectis absent says so, or is skipped with that reason. A reader should not have to search the full log for the single test that reported the true cause.Actual behavior
crates/degu/tests/support/pty.rs:53takesPTY_GATEwith.expect("PTY test gate poisoned"). The dependency check at:85panics inside that critical section, so the guard is dropped while panicking and the mutex is poisoned. Subsequent tests fail at:53with a poisoning message that says nothing aboutexpect, and the failure count makes it look like a broad product regression.Environment
degu version: 0.1.7 (workspace, from source)
installation method: built from source
OS/kernel/architecture: x86_64 Linux
filesystem type: local ext4
byte or inode quota involved: no
Reproduced against an unmodified checkout.
Relevant output or logs
Suggested direction
The gate only serializes PTY use; it guards no invariant that a panic could leave broken, so recovering from poisoning is safe —
.unwrap_or_else(|poisoned| poisoned.into_inner()). Checking forexpectbefore taking the lock would also keep the diagnosis intact for every test, and would let the whole group be skipped with one reason rather than failed.