Skip to content

Commit f410bd9

Browse files
chore(agent-tunnel): gate _for_test helpers behind test-utils feature
Address CBenoit's review on #1741: in addition to the `#[doc(hidden)]` marker and the `_for_test` naming, gate `AgentPeer::set_last_seen_for_test` and `set_received_at_for_test` behind `#[cfg(any(test, feature = "test-utils"))]` so production builds of `devolutions-gateway` and `devolutions-agent` don't compile these methods at all. Cross-crate test consumers (the workspace `testsuite` crate carrying the agent-tunnel integration tests, in #1772) opt in via `features = ["test-utils"]` on their `agent-tunnel` dev-dep.
1 parent a2b2ff5 commit f410bd9

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

crates/agent-tunnel/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ publish = false
88
[lints]
99
workspace = true
1010

11+
[features]
12+
# Exposes `_for_test` helpers (e.g. `AgentPeer::set_last_seen_for_test`) so
13+
# integration tests in other crates can force specific peer states without
14+
# wall-clock sleeps. Production builds must not enable this.
15+
test-utils = []
16+
1117
[dependencies]
1218
# Internal crates
1319
agent-tunnel-proto = { path = "../agent-tunnel-proto", features = ["serde"] }

crates/agent-tunnel/src/registry.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,15 @@ impl AgentPeer {
111111
/// Set `last_seen` to an explicit timestamp (milliseconds since UNIX epoch).
112112
///
113113
/// Test-only API — the `_for_test` suffix is the project's signal that
114-
/// production code must not call this. Used by integration tests in
115-
/// `devolutions-gateway/tests/agent_tunnel_*` to force an agent into the
114+
/// production code must not call this. Used by integration tests in other
115+
/// crates (e.g. the workspace `testsuite`) to force an agent into the
116116
/// "offline" state without waiting for the real timeout to elapse;
117-
/// production code should use [`touch`](Self::touch) instead. We deliberately
118-
/// keep this `pub` instead of `cfg(test)` because the consumer is a
119-
/// different crate's tests, and `cfg(test)` is only set within the
120-
/// declaring crate's own test build.
117+
/// production code should use [`touch`](Self::touch) instead. Gated behind
118+
/// `test-utils` (and `cfg(test)` for this crate's own unit tests) so
119+
/// production builds cannot link against it; cross-crate consumers must
120+
/// opt in via `features = ["test-utils"]` on their `agent-tunnel`
121+
/// dev-dependency.
122+
#[cfg(any(test, feature = "test-utils"))]
121123
#[doc(hidden)]
122124
pub fn set_last_seen_for_test(&self, last_seen_ms: u64) {
123125
self.last_seen.store(last_seen_ms, Ordering::Release);
@@ -128,8 +130,9 @@ impl AgentPeer {
128130
/// Test-only API. Intended for tests that need to assert ordering by
129131
/// arrival time without relying on wall-clock `thread::sleep` — which is
130132
/// flaky on platforms with coarse timer resolution (e.g. Windows ~16 ms).
131-
/// See the note on [`set_last_seen_for_test`](Self::set_last_seen_for_test)
132-
/// for why this is `pub` rather than `cfg(test)`.
133+
/// See [`set_last_seen_for_test`](Self::set_last_seen_for_test) for the
134+
/// gating rationale.
135+
#[cfg(any(test, feature = "test-utils"))]
133136
#[doc(hidden)]
134137
pub fn set_received_at_for_test(&self, received_at: SystemTime) {
135138
let mut state = self.route_state.write();

0 commit comments

Comments
 (0)