use std::time::Duration; use crank_observability::{OtlpBatchConfig, OtlpTraceConfig, OtlpTraceConfigError}; #[test] fn absent_endpoint_disables_export_without_background_resources() { let config = OtlpTraceConfig::try_new( None, None, Duration::from_secs(10), OtlpBatchConfig::default(), ) .expect("missing endpoint must be valid"); assert!(!config.is_enabled()); } #[test] fn explicit_config_accepts_only_bounded_http_protobuf() { let config = OtlpTraceConfig::try_new( Some("https://collector.example.test/v1/traces".to_owned()), Some("http/protobuf".to_owned()), Duration::from_secs(3), OtlpBatchConfig::try_new(256, 64, Duration::from_millis(500), Duration::from_secs(3)) .unwrap(), ) .expect("bounded HTTP protobuf config must be valid"); assert!(config.is_enabled()); assert_eq!(config.export_timeout(), Duration::from_secs(3)); assert_eq!(config.batch().max_queue_size(), 256); assert_eq!(config.batch().max_export_batch_size(), 64); } #[test] fn invalid_values_return_safe_typed_errors() { let secret_endpoint = "https://user:canary-secret@collector.example.test/v1/traces"; let error = OtlpTraceConfig::try_new( Some(secret_endpoint.to_owned()), Some("grpc".to_owned()), // community-scope: allow=grpc Duration::ZERO, OtlpBatchConfig::default(), ) .expect_err("credentials in endpoint must be rejected"); assert!(matches!( error, OtlpTraceConfigError::InvalidEndpoint { .. } )); assert!(!error.to_string().contains(secret_endpoint)); assert!(!error.to_string().contains("canary-secret")); let error = OtlpBatchConfig::try_new(8, 9, Duration::from_millis(1), Duration::from_secs(1)) .expect_err("batch cannot exceed queue"); assert!(matches!(error, OtlpTraceConfigError::InvalidBatchLimits)); }