Skip to main content

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}