use freenet_stdlib::prelude::*;
use crate::client_events::ClientId;
use crate::contract::executor::mock_wasm_runtime::MockWasmRuntime;
use crate::contract::executor::{
ContractExecutor, Executor, MAX_SUBSCRIBERS_PER_CONTRACT, MAX_SUBSCRIPTIONS_PER_CLIENT,
SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE,
};
use crate::wasm_runtime::MockStateStorage;
async fn create_executor() -> Executor<MockWasmRuntime, MockStateStorage> {
let storage = MockStateStorage::new();
Executor::new_mock_wasm("subscriber_limit_test", storage, None, None)
.await
.expect("create executor")
}
fn test_contract(seed: &[u8]) -> ContractContainer {
crate::contract::executor::mock_runtime::test::create_test_contract(seed)
}
async fn store_contract(
executor: &mut Executor<MockWasmRuntime, MockStateStorage>,
seed: &[u8],
) -> ContractKey {
let contract = test_contract(seed);
let key = contract.key();
let state = WrappedState::new(vec![1]);
executor
.upsert_contract_state(
key,
either::Either::Left(state),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
key
}
#[tokio::test(flavor = "current_thread")]
async fn test_per_contract_subscriber_limit_enforced() {
let mut executor = create_executor().await;
let key = store_contract(&mut executor, b"sub_limit_test").await;
let instance_id = *key.id();
let mut receivers = Vec::new();
for _ in 0..MAX_SUBSCRIBERS_PER_CONTRACT {
let client_id = ClientId::next();
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(instance_id, client_id, tx, None)
.expect("registration should succeed within limit");
receivers.push(rx);
}
let extra_client = ClientId::next();
let (tx, _rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
let result = executor.register_contract_notifier(instance_id, extra_client, tx, None);
assert!(
result.is_err(),
"Registration beyond MAX_SUBSCRIBERS_PER_CONTRACT must fail"
);
let err = result.unwrap_err();
let err_msg = err.to_string();
assert!(
err_msg.contains("subscriber limit"),
"Error should mention subscriber limit, got: {err_msg}"
);
}
#[tokio::test(flavor = "current_thread")]
async fn test_per_client_subscription_limit_enforced() {
let mut executor = create_executor().await;
let client_id = ClientId::next();
let mut receivers = Vec::new();
for i in 0..MAX_SUBSCRIPTIONS_PER_CLIENT {
let seed = format!("client_limit_test_{i}");
let key = store_contract(&mut executor, seed.as_bytes()).await;
let instance_id = *key.id();
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(instance_id, client_id, tx, None)
.expect("registration should succeed within per-client limit");
receivers.push(rx);
}
let extra_key = store_contract(&mut executor, b"client_limit_extra").await;
let (tx, _rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
let result = executor.register_contract_notifier(*extra_key.id(), client_id, tx, None);
assert!(
result.is_err(),
"Registration beyond MAX_SUBSCRIPTIONS_PER_CLIENT must fail"
);
let err = result.unwrap_err();
let err_msg = err.to_string();
assert!(
err_msg.contains("per-client subscription limit"),
"Error should mention per-client limit, got: {err_msg}"
);
}
#[tokio::test(flavor = "current_thread")]
async fn test_per_client_limit_does_not_affect_other_clients() {
let mut executor = create_executor().await;
let saturated_client = ClientId::next();
let other_client = ClientId::next();
let mut receivers = Vec::new();
for i in 0..MAX_SUBSCRIPTIONS_PER_CLIENT {
let seed = format!("other_client_test_{i}");
let key = store_contract(&mut executor, seed.as_bytes()).await;
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(*key.id(), saturated_client, tx, None)
.expect("registration should succeed");
receivers.push(rx);
}
let key = store_contract(&mut executor, b"other_client_contract").await;
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(*key.id(), other_client, tx, None)
.expect("other client should not be affected by first client's limit");
receivers.push(rx);
}
#[tokio::test(flavor = "current_thread")]
async fn test_sorted_insert_maintains_order() {
let mut executor = create_executor().await;
let key = store_contract(&mut executor, b"sorted_insert_test").await;
let instance_id = *key.id();
let clients: Vec<ClientId> = (0..10).map(|_| ClientId::next()).collect();
let mut receivers = Vec::new();
for &client_id in clients.iter().rev() {
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(instance_id, client_id, tx, None)
.expect("registration should succeed");
receivers.push(rx);
}
let subs = executor.get_subscription_info();
let contract_client_ids: Vec<ClientId> = subs
.iter()
.filter(|info| info.instance_id == instance_id)
.map(|info| info.client_id)
.collect();
assert_eq!(contract_client_ids.len(), 10, "Should have 10 subscribers");
let mut sorted = contract_client_ids.clone();
sorted.sort();
assert_eq!(
contract_client_ids, sorted,
"Client IDs should be in sorted order from the internal storage"
);
}
#[tokio::test(flavor = "current_thread")]
async fn test_reconnection_updates_channel_not_count() {
let mut executor = create_executor().await;
let key = store_contract(&mut executor, b"reconnect_test").await;
let instance_id = *key.id();
let client_id = ClientId::next();
let (tx1, _rx1) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(instance_id, client_id, tx1, None)
.expect("first registration should succeed");
let (tx2, _rx2) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(instance_id, client_id, tx2, None)
.expect("reconnection should succeed");
let subs = executor.get_subscription_info();
let contract_sub_count = subs
.iter()
.filter(|info| info.instance_id == instance_id)
.count();
assert_eq!(
contract_sub_count, 1,
"Reconnection should update channel, not add duplicate"
);
}
#[tokio::test(flavor = "current_thread")]
async fn test_reconnection_does_not_inflate_client_count() {
let mut executor = create_executor().await;
let client_id = ClientId::next();
let key = store_contract(&mut executor, b"reconnect_count_test").await;
let (tx1, _rx1) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(*key.id(), client_id, tx1, None)
.expect("registration should succeed");
for _ in 0..5 {
let (tx, _rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(*key.id(), client_id, tx, None)
.expect("reconnection should succeed");
}
let mut receivers = Vec::new();
for i in 1..MAX_SUBSCRIPTIONS_PER_CLIENT {
let seed = format!("reconnect_count_extra_{i}");
let extra_key = store_contract(&mut executor, seed.as_bytes()).await;
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
executor
.register_contract_notifier(*extra_key.id(), client_id, tx, None)
.unwrap_or_else(|e| {
panic!("Registration {i} should succeed (reconnections didn't inflate count): {e}")
});
receivers.push(rx);
}
}
#[cfg(feature = "trace")]
fn install_log_capture() -> (
std::sync::Arc<std::sync::Mutex<Vec<String>>>,
tracing::subscriber::DefaultGuard,
) {
use std::sync::{Arc, Mutex};
use tracing_subscriber::Layer;
use tracing_subscriber::layer::SubscriberExt;
#[derive(Default, Clone)]
struct Capture(Arc<Mutex<Vec<String>>>);
impl<S: tracing::Subscriber> Layer<S> for Capture {
fn on_event(
&self,
event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
struct V(String);
impl tracing::field::Visit for V {
fn record_debug(
&mut self,
field: &tracing::field::Field,
value: &dyn std::fmt::Debug,
) {
use std::fmt::Write;
write!(self.0, " {}={value:?}", field.name()).ok();
}
}
let mut v = V(String::new());
event.record(&mut v);
self.0
.lock()
.unwrap()
.push(format!("{}{}", event.metadata().level(), v.0));
}
}
let capture = Capture::default();
let messages = capture.0.clone();
let subscriber = tracing_subscriber::registry().with(capture);
let guard = tracing::subscriber::set_default(subscriber);
(messages, guard)
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn send_update_notification_absent_local_snapshot_does_not_warn() {
let mut executor = create_executor().await;
let contract = test_contract(b"warn_no_subscribers_4681");
let key = contract.key();
let instance_id = *key.id();
let (messages, guard) = install_log_capture();
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![1, 2, 3])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
drop(guard);
let logs = messages.lock().unwrap();
let id_str = instance_id.to_string();
assert!(
!logs
.iter()
.any(|l| l.starts_with("WARN") && l.contains("no subscriber snapshot")),
"an ABSENT local snapshot must not WARN (nothing is owed locally); \
captured: {logs:?}"
);
assert!(
logs.iter().any(|l| l.starts_with("DEBUG")
&& l.contains("no local subscriber")
&& l.contains("local storage")
&& l.contains(&id_str)),
"expected a local-storage DEBUG naming instance_id {id_str}; captured: {logs:?}"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn send_update_notification_empty_local_snapshot_emits_warn() {
let mut executor = create_executor().await;
let contract = test_contract(b"warn_empty_local_4681");
let key = contract.key();
let instance_id = *key.id();
executor
.update_notifications
.insert(instance_id, Vec::new());
executor
.subscriber_summaries
.insert(instance_id, std::collections::HashMap::new());
let (messages, guard) = install_log_capture();
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![9, 9, 9])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
drop(guard);
let logs = messages.lock().unwrap();
let id_str = instance_id.to_string();
assert!(
logs.iter().any(|l| l.starts_with("WARN")
&& l.contains("no subscriber snapshot")
&& l.contains("local storage")
&& l.contains(&id_str)),
"an empty (present) local snapshot must still WARN naming instance_id \
{id_str}; captured: {logs:?}"
);
drop(logs);
assert!(
!executor.update_notifications.contains_key(&instance_id),
"the emptied local entry must also be dropped"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn send_update_notification_absent_shared_snapshot_does_not_warn() {
let mut executor = create_executor().await;
executor.set_shared_notifications(
std::sync::Arc::new(dashmap::DashMap::new()),
std::sync::Arc::new(dashmap::DashMap::new()),
std::sync::Arc::new(dashmap::DashMap::new()),
);
let contract = test_contract(b"warn_missing_shared_4681");
let key = contract.key();
let instance_id = *key.id();
let (messages, guard) = install_log_capture();
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![1, 2, 3])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
drop(guard);
let logs = messages.lock().unwrap();
let id_str = instance_id.to_string();
assert!(
!logs
.iter()
.any(|l| l.starts_with("WARN") && l.contains("no subscriber snapshot")),
"an ABSENT shared snapshot must not WARN (nothing is owed locally); \
captured: {logs:?}"
);
assert!(
logs.iter().any(|l| l.starts_with("DEBUG")
&& l.contains("no local subscriber")
&& l.contains("shared storage")
&& l.contains(&id_str)),
"expected a shared-storage DEBUG naming instance_id {id_str}; captured: {logs:?}"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn send_update_notification_empty_shared_snapshot_emits_warn() {
let mut executor = create_executor().await;
let shared_notifications = std::sync::Arc::new(dashmap::DashMap::new());
executor.set_shared_notifications(
shared_notifications.clone(),
std::sync::Arc::new(dashmap::DashMap::new()),
std::sync::Arc::new(dashmap::DashMap::new()),
);
let contract = test_contract(b"warn_empty_shared_4681");
let key = contract.key();
let instance_id = *key.id();
shared_notifications.insert(instance_id, Vec::new());
let (messages, guard) = install_log_capture();
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![7, 7, 7])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
drop(guard);
let logs = messages.lock().unwrap();
let id_str = instance_id.to_string();
assert!(
logs.iter().any(|l| l.starts_with("WARN")
&& l.contains("no subscriber snapshot")
&& l.contains("shared storage")
&& l.contains(&id_str)),
"an empty (present) shared snapshot must still WARN naming instance_id \
{id_str}; captured: {logs:?}"
);
assert!(
logs.iter()
.any(|l| l.starts_with("WARN") && l.contains("stale entry dropped")),
"the WARN must say the entry was stale, not that a delivery was just \
dropped; captured: {logs:?}"
);
drop(logs);
assert!(
!shared_notifications.contains_key(&instance_id),
"the emptied shared entry must also be dropped"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn empty_shared_snapshot_warns_once_not_on_every_update() {
let mut executor = create_executor().await;
let shared_notifications = std::sync::Arc::new(dashmap::DashMap::new());
let shared_summaries = std::sync::Arc::new(dashmap::DashMap::new());
executor.set_shared_notifications(
shared_notifications.clone(),
shared_summaries.clone(),
std::sync::Arc::new(dashmap::DashMap::new()),
);
let contract = test_contract(b"warn_once_5040");
let key = contract.key();
let instance_id = *key.id();
let dead_client = ClientId::next();
shared_notifications.insert(instance_id, Vec::new());
shared_summaries.insert(
instance_id,
std::collections::HashMap::from([(dead_client, None)]),
);
let (messages, guard) = install_log_capture();
for state in [vec![1u8, 1, 1], vec![2u8, 2, 2]] {
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(state)),
RelatedContracts::default(),
Some(contract.clone()),
)
.await
.expect("store contract");
}
drop(guard);
let logs = messages.lock().unwrap();
let warns = logs
.iter()
.filter(|l| l.starts_with("WARN") && l.contains("no subscriber snapshot"))
.count();
assert_eq!(
warns, 1,
"an emptied subscriber entry must WARN exactly once, not once per \
committed update (#5040); captured: {logs:?}"
);
assert!(
!shared_notifications.contains_key(&instance_id),
"the emptied subscriber entry must be removed once observed"
);
assert!(
!shared_summaries.contains_key(&instance_id),
"the emptied summaries sibling must be removed alongside it"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn closed_subscriber_channel_drops_entry_at_point_of_loss() {
let mut executor = create_executor().await;
let shared_notifications = std::sync::Arc::new(dashmap::DashMap::new());
let shared_summaries = std::sync::Arc::new(dashmap::DashMap::new());
executor.set_shared_notifications(
shared_notifications.clone(),
shared_summaries.clone(),
std::sync::Arc::new(dashmap::DashMap::new()),
);
let contract = test_contract(b"closed_channel_5040");
let key = contract.key();
let instance_id = *key.id();
let client_id = ClientId::next();
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
drop(rx);
shared_notifications.insert(instance_id, vec![(client_id, tx)]);
shared_summaries.insert(
instance_id,
std::collections::HashMap::from([(client_id, None)]),
);
let (messages, guard) = install_log_capture();
for state in [vec![1u8, 1, 1], vec![2u8, 2, 2]] {
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(state)),
RelatedContracts::default(),
Some(contract.clone()),
)
.await
.expect("store contract");
}
drop(guard);
let logs = messages.lock().unwrap();
assert_eq!(
logs.iter()
.filter(|l| l.starts_with("ERROR") && l.contains("channel closed"))
.count(),
1,
"a closed subscriber channel must be reported once as an ERROR; \
captured: {logs:?}"
);
assert!(
!logs
.iter()
.any(|l| l.starts_with("WARN") && l.contains("no subscriber snapshot")),
"dropping the entry at the point of loss must leave nothing for a later \
update to warn about; captured: {logs:?}"
);
assert!(
!shared_notifications.contains_key(&instance_id),
"the subscriber entry must be removed as it empties"
);
assert!(
!shared_summaries.contains_key(&instance_id),
"the summaries sibling must be removed alongside it"
);
}
#[cfg(feature = "trace")]
#[tokio::test(flavor = "current_thread")]
async fn closed_subscriber_channel_drops_entry_at_point_of_loss_local() {
let mut executor = create_executor().await;
let contract = test_contract(b"closed_channel_local_5040");
let key = contract.key();
let instance_id = *key.id();
let client_id = ClientId::next();
let (tx, rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
drop(rx);
executor
.update_notifications
.insert(instance_id, vec![(client_id, tx)]);
executor.subscriber_summaries.insert(
instance_id,
std::collections::HashMap::from([(client_id, None)]),
);
let (messages, guard) = install_log_capture();
for state in [vec![1u8, 1, 1], vec![2u8, 2, 2]] {
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(state)),
RelatedContracts::default(),
Some(contract.clone()),
)
.await
.expect("store contract");
}
drop(guard);
let logs = messages.lock().unwrap();
assert_eq!(
logs.iter()
.filter(|l| l.starts_with("ERROR") && l.contains("channel closed"))
.count(),
1,
"a closed subscriber channel must be reported once as an ERROR on the \
local branch too; captured: {logs:?}"
);
assert!(
!logs
.iter()
.any(|l| l.starts_with("WARN") && l.contains("no subscriber snapshot")),
"the local branch must also drop the entry at the point of loss, leaving \
nothing for the next update to warn about; captured: {logs:?}"
);
assert!(
!executor.update_notifications.contains_key(&instance_id),
"the local subscriber entry must be removed as it empties"
);
assert!(
!executor.subscriber_summaries.contains_key(&instance_id),
"the local summaries sibling must be removed alongside it"
);
}
#[tokio::test(flavor = "current_thread")]
async fn partial_failure_prunes_only_the_dead_subscriber_local() {
let mut executor = create_executor().await;
let contract = test_contract(b"partial_failure_5040");
let key = contract.key();
let instance_id = *key.id();
let dead_client = ClientId::next();
let live_client = ClientId::next();
let (dead_tx, dead_rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
let (live_tx, mut live_rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
drop(dead_rx);
let mut subs = vec![(dead_client, dead_tx), (live_client, live_tx)];
subs.sort_by_key(|(c, _)| *c);
executor.update_notifications.insert(instance_id, subs);
executor.subscriber_summaries.insert(
instance_id,
std::collections::HashMap::from([(dead_client, None), (live_client, None)]),
);
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![5, 5, 5])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
let notifiers = executor
.update_notifications
.get(&instance_id)
.expect("entry must survive — a live subscriber remains");
assert_eq!(
notifiers.len(),
1,
"only the dead subscriber may be removed from the notifier list"
);
assert_eq!(
notifiers[0].0, live_client,
"the surviving subscriber must be the live one"
);
let summaries = executor
.subscriber_summaries
.get(&instance_id)
.expect("summaries entry must survive alongside the notifier entry");
assert!(
!summaries.contains_key(&dead_client),
"the dead subscriber's summary must be pruned — otherwise it leaks for \
the lifetime of the contract, which is exactly what the per-client \
prune exists to prevent"
);
assert!(
summaries.contains_key(&live_client),
"the live subscriber's summary must NOT be collaterally removed"
);
match live_rx.try_recv() {
Ok(Ok(resp)) => {
let as_str = format!("{resp:?}");
assert!(
as_str.contains("UpdateNotification"),
"the live subscriber must receive an UpdateNotification; got: {as_str}"
);
}
other => panic!("the live subscriber must receive its notification; got: {other:?}"),
}
}
#[tokio::test(flavor = "current_thread")]
async fn partial_failure_prunes_only_the_dead_subscriber_shared() {
let mut executor = create_executor().await;
let shared_notifications = std::sync::Arc::new(dashmap::DashMap::new());
let shared_summaries = std::sync::Arc::new(dashmap::DashMap::new());
executor.set_shared_notifications(
shared_notifications.clone(),
shared_summaries.clone(),
std::sync::Arc::new(dashmap::DashMap::new()),
);
let contract = test_contract(b"partial_failure_shared_5040");
let key = contract.key();
let instance_id = *key.id();
let dead_client = ClientId::next();
let live_client = ClientId::next();
let (dead_tx, dead_rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
let (live_tx, mut live_rx) = tokio::sync::mpsc::channel(SUBSCRIBER_NOTIFICATION_CHANNEL_SIZE);
drop(dead_rx);
let mut subs = vec![(dead_client, dead_tx), (live_client, live_tx)];
subs.sort_by_key(|(c, _)| *c);
shared_notifications.insert(instance_id, subs);
shared_summaries.insert(
instance_id,
std::collections::HashMap::from([(dead_client, None), (live_client, None)]),
);
executor
.upsert_contract_state(
key,
either::Either::Left(WrappedState::new(vec![6, 6, 6])),
RelatedContracts::default(),
Some(contract),
)
.await
.expect("store contract");
let notifiers = shared_notifications
.get(&instance_id)
.expect("entry must survive — a live subscriber remains");
assert_eq!(
notifiers.len(),
1,
"only the dead subscriber may be removed from the notifier list"
);
assert_eq!(
notifiers[0].0, live_client,
"the surviving subscriber must be the live one"
);
drop(notifiers);
let summaries = shared_summaries
.get(&instance_id)
.expect("summaries entry must survive alongside the notifier entry");
assert!(
!summaries.contains_key(&dead_client),
"the dead subscriber's summary must be pruned on the shared branch too"
);
assert!(
summaries.contains_key(&live_client),
"the live subscriber's summary must NOT be collaterally removed"
);
drop(summaries);
match live_rx.try_recv() {
Ok(Ok(resp)) => {
let as_str = format!("{resp:?}");
assert!(
as_str.contains("UpdateNotification"),
"the live subscriber must receive an UpdateNotification; got: {as_str}"
);
}
other => panic!("the live subscriber must receive its notification; got: {other:?}"),
}
}
#[test]
fn register_contract_notifier_takes_one_guard_for_search_and_write() {
let src = include_str!("../runtime/pool.rs");
let start = src
.find("let already_registered =")
.expect("`already_registered` binding not found in pool.rs");
let after = &src[start..];
let end = after
.find("if let Some(same_channel)")
.expect("`if let Some(same_channel)` not found after the binding");
let already_registered: String = after[..end]
.chars()
.filter(|c| !c.is_whitespace())
.collect();
assert_eq!(
already_registered
.matches("self.shared_notifications")
.count(),
1,
"the already-registered path must touch `shared_notifications` exactly \
once; a second acquisition reopens the TOCTOU #5040 closed"
);
assert!(
already_registered.contains("self.shared_notifications.get_mut("),
"the single acquisition must be a WRITE guard (`get_mut`), so the \
binary search and the channel write happen under it"
);
assert!(
already_registered.contains("channels[idx]=(cli_id,notification_ch.clone())"),
"the reconnect path must actually REFRESH the stored channel; without \
the write a reconnected client keeps its dead sender and silently \
receives nothing"
);
}