#![allow(missing_docs)]
use iceoryx2::prelude::*;
use std::sync::Arc;
use taktora_executor::Channel;
static SEQ: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
fn unique(prefix: &str) -> String {
let n = SEQ.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
format!("{prefix}.{}.{n}", std::process::id())
}
#[derive(Debug, Default, Clone, Copy, ZeroCopySend)]
#[repr(C)]
struct Msg(u64);
#[test]
fn publisher_send_notifies_subscriber_listener() {
let node = NodeBuilder::new().create::<ipc::Service>().unwrap();
let channel: Arc<Channel<Msg>> =
Channel::open_or_create(&node, &unique("taktora.test.chan")).unwrap();
let publisher = channel.publisher().unwrap();
let subscriber = channel.subscriber().unwrap();
let outcome = publisher.send_copy(Msg(42)).unwrap();
assert!(outcome.sent);
assert_eq!(outcome.listeners_notified, 1, "1 subscriber attached");
let listener = subscriber.listener_handle();
let mut woke = 0_u32;
while let Ok(Some(_)) = listener.try_wait_one() {
woke += 1;
}
assert!(woke >= 1, "subscriber listener did not fire");
let sample = subscriber.take().unwrap().expect("payload");
assert_eq!(sample.payload().0, 42);
}
#[test]
fn opening_same_channel_twice_does_not_panic() {
let node = NodeBuilder::new().create::<ipc::Service>().unwrap();
let chan_name = unique("taktora.test.chan2");
let _a: Arc<Channel<Msg>> = Channel::open_or_create(&node, &chan_name).unwrap();
let _b: Arc<Channel<Msg>> = Channel::open_or_create(&node, &chan_name).unwrap();
}
#[test]
fn publisher_loan_zero_copy_round_trip() {
use core::mem::MaybeUninit;
let node = NodeBuilder::new().create::<ipc::Service>().unwrap();
let channel: Arc<Channel<Msg>> =
Channel::open_or_create(&node, &unique("taktora.test.loan")).unwrap();
let publisher = channel.publisher().unwrap();
let subscriber = channel.subscriber().unwrap();
let outcome = publisher
.loan(|slot: &mut MaybeUninit<Msg>| {
slot.write(Msg(99));
true
})
.unwrap();
assert!(
outcome.delivered_to_any_listener(),
"expected delivery to at least one listener"
);
let sample = subscriber.take().unwrap().expect("payload");
assert_eq!(sample.payload().0, 99);
}
#[test]
fn publisher_loan_skip_returns_false() {
use core::mem::MaybeUninit;
let node = NodeBuilder::new().create::<ipc::Service>().unwrap();
let channel: Arc<Channel<Msg>> =
Channel::open_or_create(&node, &unique("taktora.test.loan_skip")).unwrap();
let publisher = channel.publisher().unwrap();
let subscriber = channel.subscriber().unwrap();
let outcome = publisher
.loan(|_slot: &mut MaybeUninit<Msg>| {
false
})
.unwrap();
assert!(!outcome.sent);
assert_eq!(outcome.listeners_notified, 0);
let received = subscriber.take().unwrap();
assert!(received.is_none(), "no message should have been sent");
}