From 8690ba69573a9d79538192362ec7f0e3063b3306 Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Tue, 8 Sep 2026 12:44:58 -0400 Subject: [PATCH 1/3] chore: dedupe test preamble in trace_processor tests Extract repeated Config, tags-provider, ServerlessTraceProcessor, and TracerHeaderTags construction from eight trace-processor tests into shared test helpers. No behavior change; the enriched-payload body-size test keeps its default configuration with local stats disabled. --- bottlecap/src/traces/trace_processor.rs | 330 +++++------------------- 1 file changed, 70 insertions(+), 260 deletions(-) diff --git a/bottlecap/src/traces/trace_processor.rs b/bottlecap/src/traces/trace_processor.rs index b75286220..106dee410 100644 --- a/bottlecap/src/traces/trace_processor.rs +++ b/bottlecap/src/traces/trace_processor.rs @@ -778,6 +778,51 @@ mod tests { let provider = Provider::new(config, LAMBDA_RUNTIME_SLUG.to_string(), &metadata); Arc::new(provider) } + + fn error_sampler_test_config() -> Arc { + Arc::new(Config { + apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), + ext: crate::config::LambdaConfig { + lambda_extension_compute_stats: true, + ..Default::default() + }, + ..Config::default() + }) + } + + fn error_sampler_test_setup( + config: &Arc, + error_sampler: Arc>, + ) -> (Arc, ServerlessTraceProcessor) { + let tags_provider = Arc::new(Provider::new( + config.clone(), + "lambda".to_string(), + &std::collections::HashMap::from([( + "function_arn".to_string(), + "test-arn".to_string(), + )]), + )); + let processor = ServerlessTraceProcessor { + obfuscation_config: Arc::new( + ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), + ), + error_sampler, + }; + (tags_provider, processor) + } + + fn error_sampler_test_header_tags() -> tracer_header_tags::TracerHeaderTags<'static> { + tracer_header_tags::TracerHeaderTags { + lang: "rust", + lang_version: "1.0", + lang_interpreter: "", + lang_vendor: "", + tracer_version: "1.0", + container_id: "", + generic: tracer_header_tags::TracerGenericTags::default(), + } + } + fn create_test_span( trace_id: u64, span_id: u64, @@ -1313,40 +1358,9 @@ mod tests { #[test] #[allow(clippy::unwrap_used)] fn test_process_traces_filters_sampled_out_chunks() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let make_span = |trace_id: u64, priority: Option| -> pb::Span { let mut metrics = HashMap::new(); @@ -1409,40 +1423,9 @@ mod tests { /// non-errored P0 chunks and explicit user drops are still dropped. #[test] fn test_error_sampler_rescues_errored_p0_chunks() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let make_span = |trace_id: u64, priority: f64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1506,40 +1489,9 @@ mod tests { /// candidate, matching the Go agent's `traceContainsError`. #[test] fn test_error_sampler_rescues_chunk_with_errored_child_span() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let make_span = |span_id: u64, parent_id: u64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1586,40 +1538,10 @@ mod tests { /// chunks are dropped: no rescue, no `_dd.errors_sr`. #[test] fn test_disabled_error_sampler_drops_errored_p0_chunks() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: new_error_sampler(false), - }; - - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = + error_sampler_test_setup(&config, new_error_sampler(false)); + let header_tags = error_sampler_test_header_tags(); let mut metrics = HashMap::new(); metrics.insert("_sampling_priority_v1".to_string(), 0.0); @@ -1648,40 +1570,10 @@ mod tests { /// are counted. #[test] fn test_disabled_error_sampler_keeps_dropped_errored_p0_chunk_in_stats() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: new_error_sampler(false), - }; - - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = + error_sampler_test_setup(&config, new_error_sampler(false)); + let header_tags = error_sampler_test_header_tags(); let make_span = |trace_id: u64, priority: f64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1746,39 +1638,9 @@ mod tests { /// traces are sampled out and `lambda_extension_compute_stats` is true. #[test] fn test_process_traces_returns_none_when_all_sampled_out() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let make_dropped_span = |trace_id: u64| -> pb::Span { let mut metrics = HashMap::new(); @@ -1824,40 +1686,11 @@ mod tests { /// protobuf-encoded size of the filtered payload, not the original request body. #[test] fn test_process_traces_body_size_reflects_filtered_payload() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; use prost::Message as _; - let config = Arc::new(Config { - apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), - ext: crate::config::LambdaConfig { - lambda_extension_compute_stats: true, - ..Default::default() - }, - ..Config::default() - }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let config = error_sampler_test_config(); + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let make_span = |trace_id: u64, priority: f64| -> pb::Span { let mut metrics = HashMap::new(); @@ -1935,35 +1768,12 @@ mod tests { /// reach the backend and get a 413. This is the default config (no local stats). #[test] fn test_process_traces_body_size_reflects_enriched_payload() { - use libdd_trace_obfuscation::obfuscation_config::ObfuscationConfig; - let config = Arc::new(Config { apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), ..Config::default() }); - let tags_provider = Arc::new(Provider::new( - config.clone(), - "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), - )); - let processor = ServerlessTraceProcessor { - obfuscation_config: Arc::new( - ObfuscationConfig::new().expect("Failed to create ObfuscationConfig"), - ), - error_sampler: enabled_error_sampler(), - }; - let header_tags = tracer_header_tags::TracerHeaderTags { - lang: "rust", - lang_version: "1.0", - lang_interpreter: "", - lang_vendor: "", - tracer_version: "1.0", - container_id: "", - generic: tracer_header_tags::TracerGenericTags::default(), - }; + let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); + let header_tags = error_sampler_test_header_tags(); let span = pb::Span { trace_id: 1, From 921633be842e302b67eac4ef69703a4bbed2b198 Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Tue, 8 Sep 2026 13:49:44 -0400 Subject: [PATCH 2/3] chore: clarify names of shared trace_processor test helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The helpers are used by tests beyond the error sampler ones, so name them after what they build instead, matching the existing create_* convention in the module. 🤖 --- bottlecap/src/traces/trace_processor.rs | 59 +++++++++++-------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/bottlecap/src/traces/trace_processor.rs b/bottlecap/src/traces/trace_processor.rs index 106dee410..982a659c8 100644 --- a/bottlecap/src/traces/trace_processor.rs +++ b/bottlecap/src/traces/trace_processor.rs @@ -779,7 +779,7 @@ mod tests { Arc::new(provider) } - fn error_sampler_test_config() -> Arc { + fn create_compute_stats_config() -> Arc { Arc::new(Config { apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), ext: crate::config::LambdaConfig { @@ -790,17 +790,14 @@ mod tests { }) } - fn error_sampler_test_setup( + fn create_test_processor( config: &Arc, error_sampler: Arc>, ) -> (Arc, ServerlessTraceProcessor) { let tags_provider = Arc::new(Provider::new( config.clone(), "lambda".to_string(), - &std::collections::HashMap::from([( - "function_arn".to_string(), - "test-arn".to_string(), - )]), + &HashMap::from([("function_arn".to_string(), "test-arn".to_string())]), )); let processor = ServerlessTraceProcessor { obfuscation_config: Arc::new( @@ -811,7 +808,7 @@ mod tests { (tags_provider, processor) } - fn error_sampler_test_header_tags() -> tracer_header_tags::TracerHeaderTags<'static> { + fn create_test_header_tags() -> tracer_header_tags::TracerHeaderTags<'static> { tracer_header_tags::TracerHeaderTags { lang: "rust", lang_version: "1.0", @@ -1358,9 +1355,9 @@ mod tests { #[test] #[allow(clippy::unwrap_used)] fn test_process_traces_filters_sampled_out_chunks() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let make_span = |trace_id: u64, priority: Option| -> pb::Span { let mut metrics = HashMap::new(); @@ -1423,9 +1420,9 @@ mod tests { /// non-errored P0 chunks and explicit user drops are still dropped. #[test] fn test_error_sampler_rescues_errored_p0_chunks() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let make_span = |trace_id: u64, priority: f64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1489,9 +1486,9 @@ mod tests { /// candidate, matching the Go agent's `traceContainsError`. #[test] fn test_error_sampler_rescues_chunk_with_errored_child_span() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let make_span = |span_id: u64, parent_id: u64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1538,10 +1535,9 @@ mod tests { /// chunks are dropped: no rescue, no `_dd.errors_sr`. #[test] fn test_disabled_error_sampler_drops_errored_p0_chunks() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = - error_sampler_test_setup(&config, new_error_sampler(false)); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, new_error_sampler(false)); + let header_tags = create_test_header_tags(); let mut metrics = HashMap::new(); metrics.insert("_sampling_priority_v1".to_string(), 0.0); @@ -1570,10 +1566,9 @@ mod tests { /// are counted. #[test] fn test_disabled_error_sampler_keeps_dropped_errored_p0_chunk_in_stats() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = - error_sampler_test_setup(&config, new_error_sampler(false)); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, new_error_sampler(false)); + let header_tags = create_test_header_tags(); let make_span = |trace_id: u64, priority: f64, error: i32| -> pb::Span { let mut metrics = HashMap::new(); @@ -1638,9 +1633,9 @@ mod tests { /// traces are sampled out and `lambda_extension_compute_stats` is true. #[test] fn test_process_traces_returns_none_when_all_sampled_out() { - let config = error_sampler_test_config(); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let make_dropped_span = |trace_id: u64| -> pb::Span { let mut metrics = HashMap::new(); @@ -1688,9 +1683,9 @@ mod tests { fn test_process_traces_body_size_reflects_filtered_payload() { use prost::Message as _; - let config = error_sampler_test_config(); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let config = create_compute_stats_config(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let make_span = |trace_id: u64, priority: f64| -> pb::Span { let mut metrics = HashMap::new(); @@ -1772,8 +1767,8 @@ mod tests { apm_dd_url: "https://trace.agent.datadoghq.com".to_string(), ..Config::default() }); - let (tags_provider, processor) = error_sampler_test_setup(&config, enabled_error_sampler()); - let header_tags = error_sampler_test_header_tags(); + let (tags_provider, processor) = create_test_processor(&config, enabled_error_sampler()); + let header_tags = create_test_header_tags(); let span = pb::Span { trace_id: 1, From f662f00f30f7fed831177908b4e807e1ab33981a Mon Sep 17 00:00:00 2001 From: Lucas Pimentel Date: Thu, 10 Sep 2026 10:47:00 -0400 Subject: [PATCH 3/3] Update tags provider to use LAMBDA_RUNTIME_SLUG Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- bottlecap/src/traces/trace_processor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlecap/src/traces/trace_processor.rs b/bottlecap/src/traces/trace_processor.rs index 982a659c8..9fc07480f 100644 --- a/bottlecap/src/traces/trace_processor.rs +++ b/bottlecap/src/traces/trace_processor.rs @@ -796,7 +796,7 @@ mod tests { ) -> (Arc, ServerlessTraceProcessor) { let tags_provider = Arc::new(Provider::new( config.clone(), - "lambda".to_string(), + LAMBDA_RUNTIME_SLUG.to_string(), &HashMap::from([("function_arn".to_string(), "test-arn".to_string())]), )); let processor = ServerlessTraceProcessor {