From 69cf70157279833ad2c3f52614f645f2d4865906 Mon Sep 17 00:00:00 2001 From: Duncan Harvey Date: Tue, 10 Mar 2026 16:41:29 -0400 Subject: [PATCH 1/2] upgrade rust edition to 2024 for workspace --- Cargo.lock | 10 + Cargo.toml | 2 +- crates/datadog-agent-config/Cargo.toml | 2 +- crates/datadog-trace-agent/Cargo.toml | 1 + crates/datadog-trace-agent/src/config.rs | 451 +++++++++++------- .../datadog-trace-agent/src/env_verifier.rs | 36 +- .../src/trace_processor.rs | 16 +- 7 files changed, 313 insertions(+), 205 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5056e700..c625dfba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,6 +473,7 @@ dependencies = [ "serde", "serde_json", "serial_test", + "temp-env", "tempfile", "tokio", "tracing", @@ -2606,6 +2607,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "temp-env" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" +dependencies = [ + "parking_lot", +] + [[package]] name = "tempfile" version = "3.24.0" diff --git a/Cargo.toml b/Cargo.toml index cb438b99..0ce470ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -edition = "2021" +edition = "2024" license = "Apache-2.0" homepage = "https://github.com/DataDog/serverless-components" repository = "https://github.com/DataDog/serverless-components" diff --git a/crates/datadog-agent-config/Cargo.toml b/crates/datadog-agent-config/Cargo.toml index f5d15d88..50678993 100644 --- a/crates/datadog-agent-config/Cargo.toml +++ b/crates/datadog-agent-config/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "datadog-agent-config" version = "0.1.0" -edition = "2024" +edition.workspace = true license.workspace = true [lib] diff --git a/crates/datadog-trace-agent/Cargo.toml b/crates/datadog-trace-agent/Cargo.toml index aec60c93..4cc5ed73 100644 --- a/crates/datadog-trace-agent/Cargo.toml +++ b/crates/datadog-trace-agent/Cargo.toml @@ -38,6 +38,7 @@ bytes = "1.10.1" rmp-serde = "1.1.1" serial_test = "2.0.0" duplicate = "0.4.1" +temp-env = "0.3.6" tempfile = "3.3.0" libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "d52ee90209cb12a28bdda0114535c1a985a29d95", features = [ "test-utils", diff --git a/crates/datadog-trace-agent/src/config.rs b/crates/datadog-trace-agent/src/config.rs index 2d94b4f3..f18a9ede 100644 --- a/crates/datadog-trace-agent/src/config.rs +++ b/crates/datadog-trace-agent/src/config.rs @@ -260,54 +260,57 @@ mod tests { use duplicate::duplicate_item; use serial_test::serial; use std::collections::HashMap; - use std::env; use crate::config; #[test] #[serial] fn test_error_if_unable_to_identify_env() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - - let config = config::Config::new(); - assert!(config.is_err()); - assert_eq!( - config.unwrap_err().to_string(), - "Unable to identify environment. Shutting down Mini Agent." - ); - env::remove_var("DD_API_KEY"); + temp_env::with_vars([("DD_API_KEY", Some("_not_a_real_key_"))], || { + let config = config::Config::new(); + assert!(config.is_err()); + assert_eq!( + config.unwrap_err().to_string(), + "Unable to identify environment. Shutting down Mini Agent." + ); + }); } #[test] #[serial] fn test_error_if_no_api_key_env_var() { - env::remove_var("DD_API_KEY"); - let config = config::Config::new(); - assert!(config.is_err()); - assert_eq!( - config.unwrap_err().to_string(), - "DD_API_KEY environment variable is not set" - ); + temp_env::with_vars([("DD_API_KEY", None::<&str>)], || { + let config = config::Config::new(); + assert!(config.is_err()); + assert_eq!( + config.unwrap_err().to_string(), + "DD_API_KEY environment variable is not set" + ); + }); } #[test] #[serial] fn test_default_trace_and_trace_stats_urls() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("K_SERVICE", "function_name"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!( - config.trace_intake.url, - "https://trace.agent.datadoghq.com/api/v0.2/traces" - ); - assert_eq!( - config.trace_stats_intake.url, - "https://trace.agent.datadoghq.com/api/v0.2/stats" + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("K_SERVICE", Some("function_name")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!( + config.trace_intake.url, + "https://trace.agent.datadoghq.com/api/v0.2/traces" + ); + assert_eq!( + config.trace_stats_intake.url, + "https://trace.agent.datadoghq.com/api/v0.2/stats" + ); + }, ); - env::remove_var("DD_API_KEY"); - env::remove_var("K_SERVICE"); } #[duplicate_item( @@ -322,16 +325,19 @@ mod tests { #[test] #[serial] fn test_name() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("K_SERVICE", "function_name"); - env::set_var("DD_SITE", dd_site); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.trace_intake.url, expected_url); - env::remove_var("DD_API_KEY"); - env::remove_var("DD_SITE"); - env::remove_var("K_SERVICE"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("K_SERVICE", Some("function_name")), + ("DD_SITE", Some(dd_site)), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.trace_intake.url, expected_url); + }, + ); } #[duplicate_item( @@ -346,193 +352,240 @@ mod tests { #[test] #[serial] fn test_name() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("K_SERVICE", "function_name"); - env::set_var("DD_SITE", dd_site); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.trace_stats_intake.url, expected_url); - env::remove_var("DD_API_KEY"); - env::remove_var("DD_SITE"); - env::remove_var("K_SERVICE"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("K_SERVICE", Some("function_name")), + ("DD_SITE", Some(dd_site)), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.trace_stats_intake.url, expected_url); + }, + ); } #[test] #[serial] fn test_set_custom_trace_and_trace_stats_intake_url() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("K_SERVICE", "function_name"); - env::set_var("DD_APM_DD_URL", "http://127.0.0.1:3333"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!( - config.trace_intake.url, - "http://127.0.0.1:3333/api/v0.2/traces" - ); - assert_eq!( - config.trace_stats_intake.url, - "http://127.0.0.1:3333/api/v0.2/stats" + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("K_SERVICE", Some("function_name")), + ("DD_APM_DD_URL", Some("http://127.0.0.1:3333")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!( + config.trace_intake.url, + "http://127.0.0.1:3333/api/v0.2/traces" + ); + assert_eq!( + config.trace_stats_intake.url, + "http://127.0.0.1:3333/api/v0.2/stats" + ); + }, ); - env::remove_var("DD_API_KEY"); - env::remove_var("DD_APM_DD_URL"); - env::remove_var("K_SERVICE"); } #[test] #[serial] #[cfg(any(all(windows, feature = "windows-pipes"), test))] fn test_apm_windows_pipe_name() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - env::set_var("DD_APM_WINDOWS_PIPE_NAME", r"test_pipe"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!( - config.dd_apm_windows_pipe_name, - Some(r"\\.\pipe\test_pipe".to_string()) + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_APM_WINDOWS_PIPE_NAME", Some(r"test_pipe")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!( + config.dd_apm_windows_pipe_name, + Some(r"\\.\pipe\test_pipe".to_string()) + ); + + // Port should be overridden to 0 when pipe is set + assert_eq!(config.dd_apm_receiver_port, 0); + }, ); - - // Port should be overridden to 0 when pipe is set - assert_eq!(config.dd_apm_receiver_port, 0); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); - env::remove_var("DD_APM_WINDOWS_PIPE_NAME"); } #[test] #[serial] #[cfg(any(all(windows, feature = "windows-pipes"), test))] fn test_dogstatsd_windows_pipe_name() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - env::set_var("DD_DOGSTATSD_WINDOWS_PIPE_NAME", r"test_pipe"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!( - config.dd_dogstatsd_windows_pipe_name, - Some(r"\\.\pipe\test_pipe".to_string()) + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_DOGSTATSD_WINDOWS_PIPE_NAME", Some(r"test_pipe")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!( + config.dd_dogstatsd_windows_pipe_name, + Some(r"\\.\pipe\test_pipe".to_string()) + ); + + // Port should be overridden to 0 when pipe is set + assert_eq!(config.dd_dogstatsd_port, 0); + }, ); - - // Port should be overridden to 0 when pipe is set - assert_eq!(config.dd_dogstatsd_port, 0); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); - env::remove_var("DD_DOGSTATSD_WINDOWS_PIPE_NAME"); } #[test] #[serial] fn test_default_dogstatsd_port() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.dd_dogstatsd_port, 8125); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.dd_dogstatsd_port, 8125); + }, + ); } #[test] #[serial] fn test_custom_dogstatsd_port() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - env::set_var("DD_DOGSTATSD_PORT", "18125"); - let config_res = config::Config::new(); - println!("{:?}", config_res); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.dd_dogstatsd_port, 18125); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); - env::remove_var("DD_DOGSTATSD_PORT"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_DOGSTATSD_PORT", Some("18125")), + ], + || { + let config_res = config::Config::new(); + println!("{:?}", config_res); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.dd_dogstatsd_port, 18125); + }, + ); } #[test] #[serial] fn test_default_apm_receiver_port() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.dd_apm_receiver_port, 8126); - #[cfg(any(all(windows, feature = "windows-pipes"), test))] - assert_eq!(config.dd_apm_windows_pipe_name, None); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.dd_apm_receiver_port, 8126); + #[cfg(any(all(windows, feature = "windows-pipes"), test))] + assert_eq!(config.dd_apm_windows_pipe_name, None); + }, + ); } #[test] #[serial] fn test_custom_apm_receiver_port() { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - env::set_var("DD_APM_RECEIVER_PORT", "18126"); - let config_res = config::Config::new(); - assert!(config_res.is_ok()); - let config = config_res.unwrap(); - assert_eq!(config.dd_apm_receiver_port, 18126); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); - env::remove_var("DD_APM_RECEIVER_PORT"); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_APM_RECEIVER_PORT", Some("18126")), + ], + || { + let config_res = config::Config::new(); + assert!(config_res.is_ok()); + let config = config_res.unwrap(); + assert_eq!(config.dd_apm_receiver_port, 18126); + }, + ); } - fn test_config_with_dd_tags(dd_tags: &str) -> config::Config { - env::set_var("DD_API_KEY", "_not_a_real_key_"); - env::set_var("ASCSVCRT_SPRING__APPLICATION__NAME", "test-spring-app"); - env::set_var("DD_TAGS", dd_tags); + /// Call from within temp_env::with_vars that set DD_API_KEY, ASCSVCRT_SPRING__APPLICATION__NAME, and DD_TAGS. + fn test_config_with_dd_tags() -> config::Config { let config_res = config::Config::new(); assert!(config_res.is_ok()); - let config = config_res.unwrap(); - env::remove_var("DD_API_KEY"); - env::remove_var("ASCSVCRT_SPRING__APPLICATION__NAME"); - env::remove_var("DD_TAGS"); - config + config_res.unwrap() } #[test] #[serial] fn test_dd_tags_comma_separated() { - let config = test_config_with_dd_tags("some:tag,another:thing,invalid:thing:here"); - let expected_tags = HashMap::from([ - ("some".to_string(), "tag".to_string()), - ("another".to_string(), "thing".to_string()), - ]); - assert_eq!(config.tags.tags(), &expected_tags); - assert_eq!(config.tags.function_tags(), Some("another:thing,some:tag")); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some("some:tag,another:thing,invalid:thing:here")), + ], + || { + let config = test_config_with_dd_tags(); + let expected_tags = HashMap::from([ + ("some".to_string(), "tag".to_string()), + ("another".to_string(), "thing".to_string()), + ]); + assert_eq!(config.tags.tags(), &expected_tags); + assert_eq!(config.tags.function_tags(), Some("another:thing,some:tag")); + }, + ); } #[test] #[serial] fn test_dd_tags_space_separated() { - let config = test_config_with_dd_tags("some:tag another:thing invalid:thing:here"); - let expected_tags = HashMap::from([ - ("some".to_string(), "tag".to_string()), - ("another".to_string(), "thing".to_string()), - ]); - assert_eq!(config.tags.tags(), &expected_tags); - assert_eq!(config.tags.function_tags(), Some("another:thing,some:tag")); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some("some:tag another:thing invalid:thing:here")), + ], + || { + let config = test_config_with_dd_tags(); + let expected_tags = HashMap::from([ + ("some".to_string(), "tag".to_string()), + ("another".to_string(), "thing".to_string()), + ]); + assert_eq!(config.tags.tags(), &expected_tags); + assert_eq!(config.tags.function_tags(), Some("another:thing,some:tag")); + }, + ); } #[test] #[serial] fn test_dd_tags_mixed_separators() { - let config = test_config_with_dd_tags("some:tag,another:thing extra:value"); - let expected_tags = HashMap::from([ - ("some".to_string(), "tag".to_string()), - ("another".to_string(), "thing".to_string()), - ("extra".to_string(), "value".to_string()), - ]); - assert_eq!(config.tags.tags(), &expected_tags); - assert_eq!( - config.tags.function_tags(), - Some("another:thing,extra:value,some:tag") + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some("some:tag,another:thing extra:value")), + ], + || { + let config = test_config_with_dd_tags(); + let expected_tags = HashMap::from([ + ("some".to_string(), "tag".to_string()), + ("another".to_string(), "thing".to_string()), + ("extra".to_string(), "value".to_string()), + ]); + assert_eq!(config.tags.tags(), &expected_tags); + assert_eq!( + config.tags.function_tags(), + Some("another:thing,extra:value,some:tag") + ); + }, ); } @@ -540,24 +593,60 @@ mod tests { #[serial] fn test_dd_tags_no_valid_tags() { // Test with only invalid tags - let config = test_config_with_dd_tags("invalid:thing:here,also-bad"); - assert_eq!(config.tags.tags(), &HashMap::new()); - assert_eq!(config.tags.function_tags(), None); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some("invalid:thing:here,also-bad")), + ], + || { + let config = test_config_with_dd_tags(); + assert_eq!(config.tags.tags(), &HashMap::new()); + assert_eq!(config.tags.function_tags(), None); + }, + ); // Test with empty string - let config = test_config_with_dd_tags(""); - assert_eq!(config.tags.tags(), &HashMap::new()); - assert_eq!(config.tags.function_tags(), None); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some("")), + ], + || { + let config = test_config_with_dd_tags(); + assert_eq!(config.tags.tags(), &HashMap::new()); + assert_eq!(config.tags.function_tags(), None); + }, + ); // Test with just whitespace - let config = test_config_with_dd_tags(" "); - assert_eq!(config.tags.tags(), &HashMap::new()); - assert_eq!(config.tags.function_tags(), None); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some(" ")), + ], + || { + let config = test_config_with_dd_tags(); + assert_eq!(config.tags.tags(), &HashMap::new()); + assert_eq!(config.tags.function_tags(), None); + }, + ); // Test with just commas and spaces - let config = test_config_with_dd_tags(" , , "); - assert_eq!(config.tags.tags(), &HashMap::new()); - assert_eq!(config.tags.function_tags(), None); + temp_env::with_vars( + [ + ("DD_API_KEY", Some("_not_a_real_key_")), + ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ("DD_TAGS", Some(" , , ")), + ], + || { + let config = test_config_with_dd_tags(); + assert_eq!(config.tags.tags(), &HashMap::new()); + assert_eq!(config.tags.function_tags(), None); + }, + ); } } diff --git a/crates/datadog-trace-agent/src/env_verifier.rs b/crates/datadog-trace-agent/src/env_verifier.rs index 74bed2cb..98154308 100644 --- a/crates/datadog-trace-agent/src/env_verifier.rs +++ b/crates/datadog-trace-agent/src/env_verifier.rs @@ -359,7 +359,7 @@ mod tests { use libdd_trace_utils::trace_utils; use serde_json::json; use serial_test::serial; - use std::{env, fs, path::Path, time::Duration}; + use std::{fs, path::Path, time::Duration}; use crate::env_verifier::{ ensure_azure_function_environment, ensure_gcp_function_environment, @@ -642,28 +642,36 @@ mod tests { #[test] #[serial] fn test_is_azure_flex_without_resource_group_true() { - env::remove_var(DD_AZURE_RESOURCE_GROUP); - env::set_var(WEBSITE_SKU, "FlexConsumption"); - assert!(is_azure_flex_without_resource_group()); - env::remove_var(WEBSITE_SKU); + temp_env::with_vars( + [ + (DD_AZURE_RESOURCE_GROUP, None::<&str>), + (WEBSITE_SKU, Some("FlexConsumption")), + ], + || assert!(is_azure_flex_without_resource_group()), + ); } #[test] #[serial] fn test_is_azure_flex_without_resource_group_false_resource_group_set() { - env::set_var(DD_AZURE_RESOURCE_GROUP, "test-resource-group"); - env::set_var(WEBSITE_SKU, "FlexConsumption"); - assert!(!is_azure_flex_without_resource_group()); - env::remove_var(DD_AZURE_RESOURCE_GROUP); - env::remove_var(WEBSITE_SKU); + temp_env::with_vars( + [ + (DD_AZURE_RESOURCE_GROUP, Some("test-resource-group")), + (WEBSITE_SKU, Some("FlexConsumption")), + ], + || assert!(!is_azure_flex_without_resource_group()), + ); } #[test] #[serial] fn test_is_azure_flex_without_resource_group_false_not_flex() { - env::remove_var(DD_AZURE_RESOURCE_GROUP); - env::set_var(WEBSITE_SKU, "ElasticPremium"); - assert!(!is_azure_flex_without_resource_group()); - env::remove_var(WEBSITE_SKU); + temp_env::with_vars( + [ + (DD_AZURE_RESOURCE_GROUP, None::<&str>), + (WEBSITE_SKU, Some("ElasticPremium")), + ], + || assert!(!is_azure_flex_without_resource_group()), + ); } } diff --git a/crates/datadog-trace-agent/src/trace_processor.rs b/crates/datadog-trace-agent/src/trace_processor.rs index 41f6e9e8..b41d114e 100644 --- a/crates/datadog-trace-agent/src/trace_processor.rs +++ b/crates/datadog-trace-agent/src/trace_processor.rs @@ -128,14 +128,14 @@ impl TraceProcessor for ServerlessTraceProcessor { }; // Add function_tags to payload if we can - if let Some(function_tags) = config.tags.function_tags() { - if let TracerPayloadCollection::V07(ref mut tracer_payloads) = payload { - for tracer_payload in tracer_payloads { - tracer_payload.tags.insert( - TRACER_PAYLOAD_FUNCTION_TAGS_TAG_KEY.to_string(), - function_tags.to_string(), - ); - } + if let Some(function_tags) = config.tags.function_tags() + && let TracerPayloadCollection::V07(ref mut tracer_payloads) = payload + { + for tracer_payload in tracer_payloads { + tracer_payload.tags.insert( + TRACER_PAYLOAD_FUNCTION_TAGS_TAG_KEY.to_string(), + function_tags.to_string(), + ); } } From 1d7caaa12f73d388ede158b0dcd106667e68acbb Mon Sep 17 00:00:00 2001 From: Duncan Harvey Date: Tue, 10 Mar 2026 16:46:09 -0400 Subject: [PATCH 2/2] apply formatting --- crates/datadog-serverless-compat/src/main.rs | 4 +- crates/datadog-trace-agent/src/config.rs | 65 ++++++++++++++---- .../datadog-trace-agent/src/env_verifier.rs | 24 ++++--- crates/datadog-trace-agent/src/http_utils.rs | 5 +- crates/datadog-trace-agent/src/mini_agent.rs | 2 +- .../datadog-trace-agent/src/stats_flusher.rs | 2 +- .../src/stats_processor.rs | 2 +- .../datadog-trace-agent/src/trace_flusher.rs | 4 +- .../src/trace_processor.rs | 8 +-- .../tests/common/mock_server.rs | 2 +- .../tests/integration_test.rs | 2 +- crates/dogstatsd/src/aggregator/core.rs | 66 ++++++++++++------- crates/dogstatsd/src/aggregator/service.rs | 2 +- crates/dogstatsd/src/api_key.rs | 2 +- crates/dogstatsd/src/dogstatsd.rs | 18 +++-- crates/dogstatsd/src/flusher.rs | 11 +++- crates/dogstatsd/src/metric.rs | 22 ++++--- crates/dogstatsd/src/util.rs | 3 +- crates/dogstatsd/tests/integration_test.rs | 8 +-- 19 files changed, 164 insertions(+), 88 deletions(-) diff --git a/crates/datadog-serverless-compat/src/main.rs b/crates/datadog-serverless-compat/src/main.rs index 6d764815..d50798f0 100644 --- a/crates/datadog-serverless-compat/src/main.rs +++ b/crates/datadog-serverless-compat/src/main.rs @@ -10,7 +10,7 @@ use std::{env, sync::Arc}; use tokio::{ sync::Mutex as TokioMutex, - time::{interval, Duration}, + time::{Duration, interval}, }; use tracing::{debug, error, info}; use tracing_subscriber::EnvFilter; @@ -36,7 +36,7 @@ use dogstatsd::{ util::parse_metric_namespace, }; -use dogstatsd::metric::{SortedTags, EMPTY_TAGS}; +use dogstatsd::metric::{EMPTY_TAGS, SortedTags}; use tokio_util::sync::CancellationToken; const DOGSTATSD_FLUSH_INTERVAL: u64 = 10; diff --git a/crates/datadog-trace-agent/src/config.rs b/crates/datadog-trace-agent/src/config.rs index f18a9ede..5a7b8a8c 100644 --- a/crates/datadog-trace-agent/src/config.rs +++ b/crates/datadog-trace-agent/src/config.rs @@ -399,7 +399,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_APM_WINDOWS_PIPE_NAME", Some(r"test_pipe")), ], || { @@ -424,7 +427,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_DOGSTATSD_WINDOWS_PIPE_NAME", Some(r"test_pipe")), ], || { @@ -448,7 +454,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ], || { let config_res = config::Config::new(); @@ -465,7 +474,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_DOGSTATSD_PORT", Some("18125")), ], || { @@ -484,7 +496,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ], || { let config_res = config::Config::new(); @@ -503,7 +518,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_APM_RECEIVER_PORT", Some("18126")), ], || { @@ -528,7 +546,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some("some:tag,another:thing,invalid:thing:here")), ], || { @@ -549,7 +570,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some("some:tag another:thing invalid:thing:here")), ], || { @@ -570,7 +594,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some("some:tag,another:thing extra:value")), ], || { @@ -596,7 +623,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some("invalid:thing:here,also-bad")), ], || { @@ -610,7 +640,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some("")), ], || { @@ -624,7 +657,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some(" ")), ], || { @@ -638,7 +674,10 @@ mod tests { temp_env::with_vars( [ ("DD_API_KEY", Some("_not_a_real_key_")), - ("ASCSVCRT_SPRING__APPLICATION__NAME", Some("test-spring-app")), + ( + "ASCSVCRT_SPRING__APPLICATION__NAME", + Some("test-spring-app"), + ), ("DD_TAGS", Some(" , , ")), ], || { diff --git a/crates/datadog-trace-agent/src/env_verifier.rs b/crates/datadog-trace-agent/src/env_verifier.rs index 98154308..29fcc5c7 100644 --- a/crates/datadog-trace-agent/src/env_verifier.rs +++ b/crates/datadog-trace-agent/src/env_verifier.rs @@ -110,12 +110,16 @@ impl ServerlessEnvVerifier { metadata } Err(err) => { - error!("The Mini Agent can only be run in Google Cloud Functions & Azure Functions. Verification has failed, shutting down now. Error: {err}"); + error!( + "The Mini Agent can only be run in Google Cloud Functions & Azure Functions. Verification has failed, shutting down now. Error: {err}" + ); process::exit(1); } }, Err(_) => { - error!("Google Metadata request timeout of {verify_env_timeout} ms exceeded. Using default values."); + error!( + "Google Metadata request timeout of {verify_env_timeout} ms exceeded. Using default values." + ); GCPMetadata::default() } }; @@ -262,7 +266,9 @@ async fn verify_azure_environment_or_exit(os: &str) { debug!("Successfully verified Azure Function Environment."); } Err(e) => { - error!("The Mini Agent can only be run in Google Cloud Functions & Azure Functions. Verification has failed, shutting down now. Error: {e}"); + error!( + "The Mini Agent can only be run in Google Cloud Functions & Azure Functions. Verification has failed, shutting down now. Error: {e}" + ); process::exit(1); } } @@ -354,7 +360,7 @@ async fn ensure_azure_function_environment( #[cfg(test)] mod tests { use async_trait::async_trait; - use hyper::{body::Bytes, Response, StatusCode}; + use hyper::{Response, StatusCode, body::Bytes}; use libdd_common::hyper_migration; use libdd_trace_utils::trace_utils; use serde_json::json; @@ -362,11 +368,11 @@ mod tests { use std::{fs, path::Path, time::Duration}; use crate::env_verifier::{ - ensure_azure_function_environment, ensure_gcp_function_environment, - get_region_from_gcp_region_string, is_azure_flex_without_resource_group, - AzureVerificationClient, AzureVerificationClientWrapper, GCPInstance, GCPMetadata, - GCPProject, GoogleMetadataClient, AZURE_FUNCTION_JSON_NAME, AZURE_HOST_JSON_NAME, - DD_AZURE_RESOURCE_GROUP, WEBSITE_SKU, + AZURE_FUNCTION_JSON_NAME, AZURE_HOST_JSON_NAME, AzureVerificationClient, + AzureVerificationClientWrapper, DD_AZURE_RESOURCE_GROUP, GCPInstance, GCPMetadata, + GCPProject, GoogleMetadataClient, WEBSITE_SKU, ensure_azure_function_environment, + ensure_gcp_function_environment, get_region_from_gcp_region_string, + is_azure_flex_without_resource_group, }; use super::{EnvVerifier, ServerlessEnvVerifier}; diff --git a/crates/datadog-trace-agent/src/http_utils.rs b/crates/datadog-trace-agent/src/http_utils.rs index c330cf20..74bc5103 100644 --- a/crates/datadog-trace-agent/src/http_utils.rs +++ b/crates/datadog-trace-agent/src/http_utils.rs @@ -4,9 +4,8 @@ use core::time::Duration; use datadog_fips::reqwest_adapter::create_reqwest_client_builder; use hyper::{ - header, + Response, StatusCode, header, http::{self, HeaderMap}, - Response, StatusCode, }; use libdd_common::hyper_migration; use serde_json::json; @@ -130,9 +129,9 @@ pub fn build_client( #[cfg(test)] mod tests { use http_body_util::BodyExt; - use hyper::header; use hyper::HeaderMap; use hyper::StatusCode; + use hyper::header; use libdd_common::hyper_migration; use super::verify_request_content_length; diff --git a/crates/datadog-trace-agent/src/mini_agent.rs b/crates/datadog-trace-agent/src/mini_agent.rs index 6af32b12..855290c7 100644 --- a/crates/datadog-trace-agent/src/mini_agent.rs +++ b/crates/datadog-trace-agent/src/mini_agent.rs @@ -3,7 +3,7 @@ use http_body_util::BodyExt; use hyper::service::service_fn; -use hyper::{http, Method, Response, StatusCode}; +use hyper::{Method, Response, StatusCode, http}; use libdd_common::hyper_migration; use serde_json::json; use std::io; diff --git a/crates/datadog-trace-agent/src/stats_flusher.rs b/crates/datadog-trace-agent/src/stats_flusher.rs index 573bbeb0..6c6e5805 100644 --- a/crates/datadog-trace-agent/src/stats_flusher.rs +++ b/crates/datadog-trace-agent/src/stats_flusher.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use std::{sync::Arc, time}; -use tokio::sync::{mpsc::Receiver, Mutex}; +use tokio::sync::{Mutex, mpsc::Receiver}; use tracing::{debug, error}; use libdd_trace_protobuf::pb; diff --git a/crates/datadog-trace-agent/src/stats_processor.rs b/crates/datadog-trace-agent/src/stats_processor.rs index d15be854..889e5f2c 100644 --- a/crates/datadog-trace-agent/src/stats_processor.rs +++ b/crates/datadog-trace-agent/src/stats_processor.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use std::time::UNIX_EPOCH; use async_trait::async_trait; -use hyper::{http, StatusCode}; +use hyper::{StatusCode, http}; use libdd_common::hyper_migration; use tokio::sync::mpsc::Sender; use tracing::debug; diff --git a/crates/datadog-trace-agent/src/trace_flusher.rs b/crates/datadog-trace-agent/src/trace_flusher.rs index 03b78224..cf2619e0 100644 --- a/crates/datadog-trace-agent/src/trace_flusher.rs +++ b/crates/datadog-trace-agent/src/trace_flusher.rs @@ -3,10 +3,10 @@ use async_trait::async_trait; use std::{error::Error, sync::Arc, time}; -use tokio::sync::{mpsc::Receiver, Mutex}; +use tokio::sync::{Mutex, mpsc::Receiver}; use tracing::{debug, error}; -use libdd_common::{hyper_migration, GenericHttpClient}; +use libdd_common::{GenericHttpClient, hyper_migration}; use libdd_trace_utils::trace_utils; use libdd_trace_utils::trace_utils::SendData; diff --git a/crates/datadog-trace-agent/src/trace_processor.rs b/crates/datadog-trace-agent/src/trace_processor.rs index b41d114e..16851371 100644 --- a/crates/datadog-trace-agent/src/trace_processor.rs +++ b/crates/datadog-trace-agent/src/trace_processor.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use async_trait::async_trait; -use hyper::{http, StatusCode}; +use hyper::{StatusCode, http}; use libdd_common::hyper_migration; use tokio::sync::mpsc::Sender; use tracing::debug; @@ -123,7 +123,7 @@ impl TraceProcessor for ServerlessTraceProcessor { return log_and_create_traces_success_http_response( &format!("Error processing trace chunks: {err}"), StatusCode::INTERNAL_SERVER_ERROR, - ) + ); } }; @@ -168,9 +168,9 @@ mod tests { use crate::{ config::{Config, Tags}, - trace_processor::{self, TraceProcessor, TRACER_PAYLOAD_FUNCTION_TAGS_TAG_KEY}, + trace_processor::{self, TRACER_PAYLOAD_FUNCTION_TAGS_TAG_KEY, TraceProcessor}, }; - use libdd_common::{hyper_migration, Endpoint}; + use libdd_common::{Endpoint, hyper_migration}; use libdd_trace_protobuf::pb; use libdd_trace_utils::test_utils::{create_test_gcp_json_span, create_test_gcp_span}; use libdd_trace_utils::trace_utils::MiniAgentMetadata; diff --git a/crates/datadog-trace-agent/tests/common/mock_server.rs b/crates/datadog-trace-agent/tests/common/mock_server.rs index 5e0b485d..b78b96c0 100644 --- a/crates/datadog-trace-agent/tests/common/mock_server.rs +++ b/crates/datadog-trace-agent/tests/common/mock_server.rs @@ -4,7 +4,7 @@ //! Simple mock HTTP server for testing flushers use http_body_util::BodyExt; -use hyper::{body::Incoming, Request, Response}; +use hyper::{Request, Response, body::Incoming}; use hyper_util::rt::TokioIo; use libdd_common::hyper_migration; use std::net::SocketAddr; diff --git a/crates/datadog-trace-agent/tests/integration_test.rs b/crates/datadog-trace-agent/tests/integration_test.rs index a240b812..bf28d4f8 100644 --- a/crates/datadog-trace-agent/tests/integration_test.rs +++ b/crates/datadog-trace-agent/tests/integration_test.rs @@ -7,7 +7,7 @@ use common::helpers::{create_test_trace_payload, send_tcp_request}; use common::mock_server::MockServer; use common::mocks::{MockEnvVerifier, MockStatsFlusher, MockStatsProcessor, MockTraceFlusher}; use datadog_trace_agent::{ - config::{test_helpers::create_tcp_test_config, Config}, + config::{Config, test_helpers::create_tcp_test_config}, mini_agent::MiniAgent, proxy_flusher::ProxyFlusher, trace_flusher::TraceFlusher, diff --git a/crates/dogstatsd/src/aggregator/core.rs b/crates/dogstatsd/src/aggregator/core.rs index 15799e59..62b53a0e 100644 --- a/crates/dogstatsd/src/aggregator/core.rs +++ b/crates/dogstatsd/src/aggregator/core.rs @@ -153,7 +153,10 @@ impl Aggregator { || (this_batch_size + next_chunk_size >= self.max_batch_bytes_sketch_metric) { if this_batch_size == 0 { - warn!("Only one distribution exceeds max batch size, adding it anyway: {:?} with {}", sketch.metric, next_chunk_size); + warn!( + "Only one distribution exceeds max batch size, adding it anyway: {:?} with {}", + sketch.metric, next_chunk_size + ); } else { batched_payloads.push(sketch_payload); sketch_payload = SketchPayload::new(); @@ -218,7 +221,10 @@ impl Aggregator { >= self.max_batch_bytes_single_metric) { if this_batch_size == 0 { - warn!("Only one metric exceeds max batch size, adding it anyway: {:?} with {}", metric.metric, serialized_metric_size); + warn!( + "Only one metric exceeds max batch size, adding it anyway: {:?} with {}", + metric.metric, serialized_metric_size + ); } else { batched_payloads.push(series_payload); series_payload = Series { @@ -320,7 +326,7 @@ fn build_metric(entry: &Metric, mut base_tag_vec: SortedTags) -> Option { if series_failed.is_empty() && sketches_failed.is_empty() { - debug!("Successfully flushed {n_series} series and {n_distributions} distributions"); + debug!( + "Successfully flushed {n_series} series and {n_distributions} distributions" + ); None // Return None to indicate success } else if series_had_error || sketches_had_error { // Only return the metrics if there was an actual shipping error - error!("Failed to flush some metrics due to shipping errors: {} series and {} sketches", - series_failed.len(), sketches_failed.len()); + error!( + "Failed to flush some metrics due to shipping errors: {} series and {} sketches", + series_failed.len(), + sketches_failed.len() + ); // Return the failed metrics for potential retry Some((series_failed, sketches_failed)) } else { diff --git a/crates/dogstatsd/src/metric.rs b/crates/dogstatsd/src/metric.rs index 72fe630e..7698e163 100644 --- a/crates/dogstatsd/src/metric.rs +++ b/crates/dogstatsd/src/metric.rs @@ -406,7 +406,7 @@ mod tests { use proptest::{collection, option, strategy::Strategy, string::string_regex}; use ustr::Ustr; - use crate::metric::{id, parse, timestamp_to_bucket, MetricValue, SortedTags}; + use crate::metric::{MetricValue, SortedTags, id, parse, timestamp_to_bucket}; use super::ParseError; @@ -629,15 +629,19 @@ mod tests { #[test] fn parse_tag_no_value() { - let result = parse("datadog.tracer.flush_triggered:1|c|#lang:go,lang_version:go1.22.10,_dd.origin:lambda,runtime-id:d66f501c-d09b-4d0d-970f-515235c4eb56,v1.65.1,service:aws.lambda,reason:scheduled"); + let result = parse( + "datadog.tracer.flush_triggered:1|c|#lang:go,lang_version:go1.22.10,_dd.origin:lambda,runtime-id:d66f501c-d09b-4d0d-970f-515235c4eb56,v1.65.1,service:aws.lambda,reason:scheduled", + ); assert!(result.is_ok()); - assert!(result - .unwrap() - .tags - .unwrap() - .values - .iter() - .any(|(k, v)| k == "v1.65.1" && v.is_empty())); + assert!( + result + .unwrap() + .tags + .unwrap() + .values + .iter() + .any(|(k, v)| k == "v1.65.1" && v.is_empty()) + ); } #[test] diff --git a/crates/dogstatsd/src/util.rs b/crates/dogstatsd/src/util.rs index c0137383..8a16ef0b 100644 --- a/crates/dogstatsd/src/util.rs +++ b/crates/dogstatsd/src/util.rs @@ -58,7 +58,8 @@ pub fn parse_metric_namespace(namespace: &str) -> Option { { tracing::error!( "DD_STATSD_METRIC_NAMESPACE contains invalid character '{}' in '{}'. Only ASCII alphanumerics, underscores, and periods are allowed. Ignoring namespace.", - invalid_char, trimmed + invalid_char, + trimmed ); return None; } diff --git a/crates/dogstatsd/tests/integration_test.rs b/crates/dogstatsd/tests/integration_test.rs index 49a6f1c2..3155ef87 100644 --- a/crates/dogstatsd/tests/integration_test.rs +++ b/crates/dogstatsd/tests/integration_test.rs @@ -15,7 +15,7 @@ use mockito::Server; use std::sync::Arc; use tokio::{ net::UdpSocket, - time::{sleep, timeout, Duration}, + time::{Duration, sleep, timeout}, }; use tokio_util::sync::CancellationToken; use zstd::zstd_safe::CompressionLevel; @@ -133,7 +133,7 @@ async fn start_dogstatsd_on_port( #[tokio::test] async fn test_send_with_retry_immediate_failure() { use dogstatsd::datadog::{DdApi, DdDdUrl, RetryStrategy}; - use dogstatsd::metric::{parse, SortedTags}; + use dogstatsd::metric::{SortedTags, parse}; let mut server = Server::new_async().await; let mock = server @@ -182,7 +182,7 @@ async fn test_send_with_retry_immediate_failure() { #[tokio::test] async fn test_send_with_retry_linear_backoff_success() { use dogstatsd::datadog::{DdApi, DdDdUrl, RetryStrategy}; - use dogstatsd::metric::{parse, SortedTags}; + use dogstatsd::metric::{SortedTags, parse}; let mut server = Server::new_async().await; let mock = server @@ -246,7 +246,7 @@ async fn test_send_with_retry_linear_backoff_success() { async fn test_send_with_retry_immediate_failure_after_one_attempt() { use dogstatsd::datadog::{DdApi, DdDdUrl, RetryStrategy}; use dogstatsd::flusher::ShippingError; - use dogstatsd::metric::{parse, SortedTags}; + use dogstatsd::metric::{SortedTags, parse}; let mut server = Server::new_async().await; let mock = server