Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/switchyard-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ mod routing_log;
mod shutdown;
mod sse;
mod stats;
#[cfg(test)]
mod testing;
mod usage_metrics;

use std::collections::BTreeMap;
Expand Down Expand Up @@ -1943,7 +1945,7 @@ mod tests {

let captured = CapturedEvents::default();
let subscriber = tracing_subscriber::registry().with(captured.clone());
tracing::subscriber::with_default(subscriber, run);
crate::testing::with_subscriber(subscriber, run);
captured.0.lock().clone()
}

Expand Down
2 changes: 1 addition & 1 deletion crates/switchyard-server/src/observability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ mod tests {
HeaderValue::from_static("vendor=opaque-value"),
);

tracing::subscriber::with_default(subscriber, || {
crate::testing::with_subscriber(subscriber, || {
let span = request_span(&headers);
let context = span.context();
let current = context.span();
Expand Down
2 changes: 1 addition & 1 deletion crates/switchyard-server/src/sse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ mod tests {
.enable_all()
.build()?;

let body = tracing::subscriber::with_default(subscriber, || {
let body = crate::testing::with_subscriber(subscriber, || {
runtime.block_on(chat_body(vec![Err(LlmStreamError::Client(
LlmClientError::UpstreamHttp {
status: axum::http::StatusCode::BAD_GATEWAY,
Expand Down
31 changes: 31 additions & 0 deletions crates/switchyard-server/src/testing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! Helpers shared by this crate's unit tests.

use std::sync::Once;

/// Runs `run` with `subscriber` as this thread's default subscriber, so the test
/// sees the events and spans that `run` creates.
///
/// For each call site, such as one `warn!` line, `tracing` caches whether any
/// subscriber wants its events. While `subscriber` is the only registered
/// subscriber, `tracing` fills that cache by asking the default subscriber of
/// the first thread that reaches the call site. If that thread belongs to a
/// parallel test with no subscriber, the cache says "never", and this test
/// captures nothing from that call site. To prevent this, the first call to
/// this helper in a test binary also sets a global `Registry` with no layers.
/// That `Registry` wants every call site and writes no output, so the cache can
/// no longer say "never".
pub(crate) fn with_subscriber<T>(
subscriber: impl tracing::Subscriber + Send + Sync + 'static,
run: impl FnOnce() -> T,
) -> T {
static GLOBAL_SUBSCRIBER: Once = Once::new();
GLOBAL_SUBSCRIBER.call_once(|| {
// An error means that another global subscriber is already set. That
// subscriber also keeps the cache from saying "never".
let _ = tracing::subscriber::set_global_default(tracing_subscriber::registry());
});
tracing::subscriber::with_default(subscriber, run)
}
Loading