test(adr-115): diagnostic dump + wider subscription on state-test failure
After 4 surgical fixes the state_messages_published_on_snapshot_broadcast
test still reports 'expected ON state, got []' on CI — and we can't
tell whether the publisher is publishing nothing, or publishing the
wrong topic, or publishing to a session the subscriber lost.
Two changes to surface what's actually happening:
1. Widen subscription from `homeassistant/binary_sensor/+/presence/state`
to `homeassistant/#`. Now the captured-message dump shows every
topic the publisher emitted under the homeassistant prefix —
discovery configs, availability heartbeats, state messages,
anything else. A narrow filter was hiding which side of the
pipeline was broken.
2. Add stderr `[diag]` lines that dump every captured (retain, topic,
payload-prefix) on test failure. CI runs `--nocapture` so the lines
land in the workflow log. From the next failed-CI log we'll know
whether:
- publisher isn't emitting state at all (no /state topics in dump)
- publisher is emitting to a different topic shape (typo in
topic format string)
- subscriber connected to a stale session and missed messages
(would see discovery + no state but dump would have count > 0)
- subscriber is connecting after publisher disconnected (count = 0
even after widening)
This is a debugging commit, not a production fix — once we know the
exact failure mode from the next CI log we can ship a real fix.
Refs PR #778, issue #776.
Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
967cede74d
commit
636ca7b52f
|
|
@ -261,11 +261,13 @@ async fn privacy_mode_suppresses_biometric_discovery() {
|
||||||
async fn state_messages_published_on_snapshot_broadcast() {
|
async fn state_messages_published_on_snapshot_broadcast() {
|
||||||
let Some(port) = should_run() else { return; };
|
let Some(port) = should_run() else { return; };
|
||||||
|
|
||||||
let (sub, mut sub_loop) = subscribe_client(
|
// Subscribe to the entire homeassistant tree so the diagnostic
|
||||||
port,
|
// capture shows EVERYTHING the publisher is doing, not just
|
||||||
&["homeassistant/binary_sensor/+/presence/state"],
|
// the narrow presence/state filter — narrow filters can hide
|
||||||
)
|
// ordering issues (e.g., if the publisher is publishing only
|
||||||
.await;
|
// discovery and not state, a narrow filter on state can't tell
|
||||||
|
// us that).
|
||||||
|
let (sub, mut sub_loop) = subscribe_client(port, &["homeassistant/#"]).await;
|
||||||
|
|
||||||
let cfg = make_cfg(port, false, "state");
|
let cfg = make_cfg(port, false, "state");
|
||||||
let builder = make_builder("inttest3");
|
let builder = make_builder("inttest3");
|
||||||
|
|
@ -306,6 +308,19 @@ async fn state_messages_published_on_snapshot_broadcast() {
|
||||||
let msgs = collect_published(&mut sub_loop, Duration::from_secs(8)).await;
|
let msgs = collect_published(&mut sub_loop, Duration::from_secs(8)).await;
|
||||||
let _ = sub.disconnect().await;
|
let _ = sub.disconnect().await;
|
||||||
|
|
||||||
|
// Diagnostic: dump every captured topic so we can see what (if
|
||||||
|
// anything) the subscriber received. CI runs with --nocapture, so
|
||||||
|
// this lands in the workflow log when the test fails.
|
||||||
|
eprintln!("[diag] subscriber captured {} messages:", msgs.len());
|
||||||
|
for (t, p, retain) in &msgs {
|
||||||
|
eprintln!(
|
||||||
|
"[diag] retain={} topic={} payload={}",
|
||||||
|
retain,
|
||||||
|
t,
|
||||||
|
String::from_utf8_lossy(p).chars().take(80).collect::<String>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let presence_states: Vec<String> = msgs
|
let presence_states: Vec<String> = msgs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(t, _, _)| t.contains("/inttest3/presence/state"))
|
.filter(|(t, _, _)| t.contains("/inttest3/presence/state"))
|
||||||
|
|
@ -314,8 +329,9 @@ async fn state_messages_published_on_snapshot_broadcast() {
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
presence_states.iter().any(|p| p == "ON"),
|
presence_states.iter().any(|p| p == "ON"),
|
||||||
"expected ON state, got {:?}",
|
"expected ON state, got {:?} (of {} total captured)",
|
||||||
presence_states
|
presence_states,
|
||||||
|
msgs.len(),
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
presence_states.iter().any(|p| p == "OFF"),
|
presence_states.iter().any(|p| p == "OFF"),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue