#![cfg(target_os = "linux")]
use monocoque::rt::{LocalRuntime, TcpListener};
use monocoque::zmq::{PullSocket, PushSocket, SocketOptions};
use std::sync::mpsc;
use std::thread;
const PAIRS: usize = 200;
const MAX_GROWTH_PER_PAIR_KB: u64 = 96;
fn vmhwm_kb() -> u64 {
let status = std::fs::read_to_string("/proc/self/status").expect("read /proc/self/status");
for line in status.lines() {
if let Some(rest) = line.strip_prefix("VmHWM:") {
return rest
.trim()
.trim_end_matches("kB")
.trim()
.parse()
.expect("parse VmHWM");
}
}
panic!("VmHWM not found in /proc/self/status");
}
#[test]
fn idle_connected_pairs_stay_under_per_socket_footprint_bound() {
let (port_tx, port_rx) = mpsc::channel::<u16>();
let (base_tx, base_rx) = mpsc::channel::<u64>();
let (srv_ready_tx, srv_ready_rx) = mpsc::channel::<()>();
let (cli_ready_tx, cli_ready_rx) = mpsc::channel::<()>();
let (srv_done_tx, srv_done_rx) = mpsc::channel::<()>();
let (cli_done_tx, cli_done_rx) = mpsc::channel::<()>();
let server = thread::spawn(move || {
let rt = LocalRuntime::new().unwrap();
rt.block_on(async move {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
port_tx.send(listener.local_addr().unwrap().port()).unwrap();
base_tx.send(vmhwm_kb()).unwrap();
let mut pulls = Vec::with_capacity(PAIRS);
for _ in 0..PAIRS {
let (stream, _) = listener.accept().await.unwrap();
pulls.push(
PullSocket::from_tcp_with_options(stream, SocketOptions::default())
.await
.unwrap(),
);
}
srv_ready_tx.send(()).unwrap();
srv_done_rx.recv().unwrap(); drop(pulls);
});
});
let port = port_rx.recv().unwrap();
let baseline = base_rx.recv().unwrap();
let client = thread::spawn(move || {
let rt = LocalRuntime::new().unwrap();
rt.block_on(async move {
let mut pushes = Vec::with_capacity(PAIRS);
for _ in 0..PAIRS {
pushes.push(
PushSocket::connect_with_options(("127.0.0.1", port), SocketOptions::default())
.await
.unwrap(),
);
}
cli_ready_tx.send(()).unwrap();
cli_done_rx.recv().unwrap(); drop(pushes);
});
});
srv_ready_rx.recv().unwrap();
cli_ready_rx.recv().unwrap();
let peak = vmhwm_kb();
srv_done_tx.send(()).unwrap();
cli_done_tx.send(()).unwrap();
server.join().unwrap();
client.join().unwrap();
let growth = peak.saturating_sub(baseline);
let bound = PAIRS as u64 * MAX_GROWTH_PER_PAIR_KB;
assert!(
growth < bound,
"idle-socket peak RSS growth {growth} KiB exceeded bound {bound} KiB for \
{PAIRS} connected pairs (baseline {baseline} KiB, peak {peak} KiB, \
{} KiB/pair vs ceiling {MAX_GROWTH_PER_PAIR_KB}). A per-socket resident \
buffer grew: check for an eager read slab or a larger write buffer.",
growth / PAIRS as u64,
);
}