use std::sync::atomic::Ordering;
use std::time::Duration;
use phoxal::raw::{
Bus, BusConfig, BusMetadata, Codec, LogicalTime, MessagePack, OwnerCap, Publisher, Source,
Subscriber, encoding_string,
};
use phoxal_api::y2026_9;
use serial_test::serial;
use zenoh::bytes::{Encoding, ZBytes};
#[serial]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn y2026_9_process_subscription_counts_a_malformed_payload_as_a_decode_error() {
let bus = Bus::open(BusConfig::in_process("test/telemetry-decode", "robot"))
.await
.expect("bus should open");
let sub_topic = y2026_9::topic::new().telemetry().process();
let subscriber = Subscriber::<y2026_9::telemetry::Process>::new(&bus, &sub_topic, 8)
.await
.expect("subscription should declare");
let owner_topic = y2026_9::topic::internal::new(OwnerCap::__mint())
.telemetry()
.process();
let publisher = Publisher::<y2026_9::telemetry::Process>::new(bus.clone(), &owner_topic)
.expect("owner publisher should attach");
let good = y2026_9::telemetry::Process {
cpu_pct: 4.25,
rss_bytes: 33_554_432,
window_ns: 3_000_000_000,
};
publisher
.publish_at(LogicalTime::new(0, 1), good.clone())
.await
.expect("good sample should publish");
let received = tokio::time::timeout(Duration::from_secs(5), subscriber.recv())
.await
.expect("a well-formed sample should arrive before the deadline")
.expect("recv should not error");
assert_eq!(received.body, good);
assert_eq!(
bus.health().decode_errors.load(Ordering::Relaxed),
0,
"a well-formed sample must not be counted as a decode error"
);
let full_key = bus.full_key(sub_topic.key());
let metadata = BusMetadata {
codec: MessagePack::ID.as_u8(),
produced_at_ns: 2,
epoch: 0,
source: Source {
participant: "malformed-injector".to_string(),
incarnation: 0,
sequence: 0,
},
};
bus.session()
.put(full_key.as_str(), ZBytes::from(vec![0xc1u8, 0xc1, 0xc1]))
.encoding(Encoding::from(encoding_string(MessagePack::ID)))
.attachment(metadata.encode())
.await
.expect("raw malformed put should enqueue");
let deadline = tokio::time::Instant::now() + Duration::from_secs(5);
loop {
if bus.health().decode_errors.load(Ordering::Relaxed) >= 1 {
break;
}
assert!(
tokio::time::Instant::now() < deadline,
"the malformed payload was not counted as a decode error within the deadline"
);
tokio::time::sleep(Duration::from_millis(10)).await;
}
assert!(
subscriber.try_recv().is_none(),
"a payload that fails to decode must never be delivered to the subscriber"
);
bus.close().await.expect("bus should close");
}