term_test_support/naming.rs
1//! Collision-free IPC channel names for tests.
2
3use std::sync::atomic::{AtomicU64, Ordering};
4
5/// Namespace segment shared by all test gateway channel names. Matches the
6/// convention already used by the root integration harness and daemon tests.
7const GATEWAY_TEST_NAMESPACE: &str = "term-wm";
8
9/// Per-process monotonic counter distinguishing names within one test binary.
10static NEXT_ID: AtomicU64 = AtomicU64::new(1);
11
12/// Build a unique gateway channel name: `term-wm/{tag}-{pid}-{n}`.
13///
14/// The pid component is what makes this safe beyond a single process: plain
15/// per-process counters restart at 1 in every test binary, so two concurrent
16/// runs (or a leftover daemon from a crashed prior run) could otherwise claim
17/// the same name. Embedding the pid makes collisions require both same-name
18/// reuse AND process-id reuse on the same machine within the leftover's
19/// lifetime.
20pub fn unique_gateway_name(tag: &str) -> String {
21 let n = NEXT_ID.fetch_add(1, Ordering::Relaxed);
22 format!("{GATEWAY_TEST_NAMESPACE}/{tag}-{}-{n}", std::process::id())
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 #[test]
30 fn names_embed_tag_pid_and_counter() {
31 let name = unique_gateway_name("probe");
32 let expected_prefix = format!("{GATEWAY_TEST_NAMESPACE}/probe-{}-", std::process::id());
33 assert!(
34 name.starts_with(&expected_prefix),
35 "unexpected name shape: {name}"
36 );
37 }
38
39 #[test]
40 fn successive_names_differ() {
41 let a = unique_gateway_name("dup");
42 let b = unique_gateway_name("dup");
43 assert_ne!(a, b);
44 }
45}