use std::collections::HashMap;
use std::sync::{Mutex, OnceLock};
use provide_telemetry::{
reconfigure_telemetry, reload_runtime_from_env, setup_telemetry, shutdown_telemetry,
update_runtime_config, BackpressureConfig, ExporterPolicyConfig, RuntimeOverrides, SLOConfig,
SamplingConfig, SecurityConfig, TelemetryConfig,
};
static ENV_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
static RUNTIME_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
fn env_lock() -> &'static Mutex<()> {
ENV_LOCK.get_or_init(|| Mutex::new(()))
}
fn runtime_lock() -> &'static Mutex<()> {
RUNTIME_LOCK.get_or_init(|| Mutex::new(()))
}
fn restore_env(snapshot: &HashMap<String, Option<String>>) {
for (key, value) in snapshot {
match value {
Some(value) => std::env::set_var(key, value),
None => std::env::remove_var(key),
}
}
}
fn with_env(vars: &[(&str, &str)], test: impl FnOnce()) {
let _guard = env_lock().lock().expect("env lock poisoned");
let mut snapshot = HashMap::new();
for (key, _) in vars {
snapshot.insert((*key).to_string(), std::env::var(key).ok());
}
for (key, value) in vars {
std::env::set_var(key, value);
}
test();
restore_env(&snapshot);
}
fn reset_runtime() {
let _ = shutdown_telemetry();
provide_telemetry::otel::_reset_otel_for_tests();
}
#[test]
fn runtime_test_get_runtime_config_none_before_setup() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
assert!(provide_telemetry::get_runtime_config().is_none());
}
#[test]
fn runtime_test_setup_is_idempotent() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
let first = setup_telemetry().expect("first setup should succeed");
let second = setup_telemetry().expect("second setup should succeed");
assert_eq!(first.service_name, second.service_name);
assert!(provide_telemetry::get_runtime_config().is_some());
}
#[test]
fn runtime_test_get_runtime_config_returns_defensive_copy() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
setup_telemetry().expect("setup should succeed");
let mut local = provide_telemetry::get_runtime_config().expect("config should exist");
local.service_name = "mutated-locally".to_string();
let again = provide_telemetry::get_runtime_config().expect("config should still exist");
assert_ne!(again.service_name, "mutated-locally");
}
#[test]
fn runtime_test_update_runtime_config_applies_hot_fields() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
setup_telemetry().expect("setup should succeed");
let updated = update_runtime_config(RuntimeOverrides {
sampling: Some(SamplingConfig {
logs_rate: 0.25,
traces_rate: 1.0,
metrics_rate: 1.0,
}),
backpressure: Some(BackpressureConfig {
logs_maxsize: 9,
traces_maxsize: 0,
metrics_maxsize: 0,
}),
exporter: Some(ExporterPolicyConfig {
logs_retries: 2,
traces_retries: 0,
metrics_retries: 0,
logs_backoff_seconds: 0.5,
traces_backoff_seconds: 0.0,
metrics_backoff_seconds: 0.0,
logs_timeout_seconds: 7.5,
traces_timeout_seconds: 10.0,
metrics_timeout_seconds: 10.0,
logs_fail_open: false,
traces_fail_open: true,
metrics_fail_open: true,
}),
security: Some(SecurityConfig {
max_attr_value_length: 2048,
max_attr_count: 32,
}),
slo: Some(SLOConfig {
enable_red_metrics: true,
enable_use_metrics: false,
}),
pii_max_depth: Some(3),
strict_schema: Some(true),
})
.expect("update should succeed");
assert_eq!(updated.sampling.logs_rate, 0.25);
assert_eq!(updated.backpressure.logs_maxsize, 9);
assert_eq!(updated.exporter.logs_retries, 2);
assert_eq!(updated.security.max_attr_value_length, 2048);
assert!(updated.slo.enable_red_metrics);
assert_eq!(updated.pii_max_depth, 3);
assert!(updated.strict_schema);
}
#[test]
fn runtime_test_reload_runtime_from_env_preserves_cold_fields_and_updates_hot_fields() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
with_env(
&[
("PROVIDE_TELEMETRY_SERVICE_NAME", "initial-service"),
("PROVIDE_SAMPLING_LOGS_RATE", "1.0"),
],
|| {
reset_runtime();
let initial = setup_telemetry().expect("setup should succeed");
assert_eq!(initial.service_name, "initial-service");
std::env::set_var("PROVIDE_TELEMETRY_SERVICE_NAME", "reloaded-service");
std::env::set_var("PROVIDE_SAMPLING_LOGS_RATE", "0.5");
let reloaded = reload_runtime_from_env().expect("reload should succeed");
assert_eq!(reloaded.service_name, "initial-service");
assert_eq!(reloaded.sampling.logs_rate, 0.5);
},
);
}
#[test]
fn runtime_test_reconfigure_telemetry_applies_cold_fields() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
#[cfg(not(feature = "otel"))]
setup_telemetry().expect("setup should succeed");
let target = TelemetryConfig {
service_name: "reconfigured-service".to_string(),
environment: "prod".to_string(),
..TelemetryConfig::default()
};
let updated = reconfigure_telemetry(Some(target)).expect("reconfigure should succeed");
assert_eq!(updated.service_name, "reconfigured-service");
assert_eq!(updated.environment, "prod");
}
#[test]
fn runtime_test_shutdown_clears_setup_state() {
let _guard = runtime_lock().lock().expect("runtime lock poisoned");
reset_runtime();
setup_telemetry().expect("setup should succeed");
shutdown_telemetry().expect("shutdown should succeed");
assert!(provide_telemetry::get_runtime_config().is_none());
}