test(vdisplay): bound the 3.2 case's creates, and what it found on glass
A hang must fail the case, not wedge the box. The first attempt at this case hung inside `create`; killing the harness skipped every `Drop` and leaked an IddCx monitor, and a few of those exhaust the driver's slot pool — after which every later run wedges too and only a reboot clears it. Both creates now run on a worker thread with a 45 s budget, so the harness exits NORMALLY, which is what lets the driver reap the session. Re-run with matched host+drivers: no hang, no leak, and the box came back with the panel lit. ⭐ With that guard in, §5 3.2 REPRODUCED ON GLASS for the first time (.173, LG TV attached, host 0.21.0 + drivers 9.9.728.2241, first isolate injected to fail): physicals before : [(4352, "LG TV SSCR2 [HDMI]")] after member 1 (isolate INJECTED to fail): [(260, "punktfunk [punktfunk-virtual]")] after member 2 (isolate REAL) : [(260, …), (264, …)] physicals during : [] physicals after teardown : [] <-- the operator's panel, still dark So the shipped 3.2 fix — adopt the first SUCCESSFUL isolate as the group's restore snapshot — is necessary but NOT sufficient. Two candidate reasons, both worth checking before changing code: * The adopted snapshot is already POISONED. The panel went dark at member 1's create even though our isolate never ran (the injected failure), because the arriving IddCx monitor took the desktop on its own. Member 2's isolate then snapshotted a topology in which the physical was ALREADY inactive, so restoring it faithfully restores "TV off". This is the same poisoned-snapshot chain §5 already records from the field logs. * `restore_displays_ccd`'s dark-desk backstop did not rescue it either. Worth its own look, since21eda37ais what first made that condition evaluable at all (before it, our own display counted as a lit physical and the guard could never fire). ⚠️ Not yet distinguished, because this case installs no tracing subscriber: whether the adoption arm fired at all, and whether the backstop ran and failed or never ran. That is the next diagnostic — `live_inplace_resize` shows the pattern for wiring a subscriber into a live case. Also confirms21eda37ain the field: the virtual displays report `tech=punktfunk-virtual` and are correctly absent from the physicals list, which is what makes "physicals after teardown: []" mean what it says rather than counting our own output as the operator's panel.
This commit is contained in:
@@ -960,6 +960,32 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run `f` on a worker thread and give up after `budget`, so a HANG fails the case instead of
|
||||||
|
/// wedging the box.
|
||||||
|
///
|
||||||
|
/// Earned the hard way: this file's 3.2 case hung inside `create`, and killing the harness
|
||||||
|
/// skipped every `Drop`, leaking an IddCx monitor. A few of those exhaust the driver's slot
|
||||||
|
/// pool, after which every later run wedges too and only a reboot clears it. A bounded wait
|
||||||
|
/// lets the harness exit NORMALLY, which is what lets the driver reap the session.
|
||||||
|
fn within<T: Send + 'static>(
|
||||||
|
budget: Duration,
|
||||||
|
what: &str,
|
||||||
|
f: impl FnOnce() -> T + Send + 'static,
|
||||||
|
) -> T {
|
||||||
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let _ = tx.send(f());
|
||||||
|
});
|
||||||
|
match rx.recv_timeout(budget) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => panic!(
|
||||||
|
"{what} did not finish within {budget:?} — failing rather than hanging, so the \
|
||||||
|
harness can exit and the driver can reap. Check for a leaked punktfunk monitor \
|
||||||
|
before the next run."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// §5 3.2 on glass: when the FIRST member's isolate fails, a later member's isolate must be
|
/// §5 3.2 on glass: when the FIRST member's isolate fails, a later member's isolate must be
|
||||||
/// ADOPTED as the group's restore snapshot — otherwise it deactivates the operator's panels
|
/// ADOPTED as the group's restore snapshot — otherwise it deactivates the operator's panels
|
||||||
/// with nothing able to put them back.
|
/// with nothing able to put them back.
|
||||||
|
|||||||
Reference in New Issue
Block a user