From a21dc1c75d0e30c0b8d3e114d4e69769846e59ff Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Thu, 10 Jul 2025 11:02:50 -0400 Subject: [PATCH 1/8] implement with_endpoint for SendData --- datadog-trace-utils/src/send_data/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 4d70c4486d..332ae504f1 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -205,13 +205,16 @@ impl SendData { self.retry_strategy = retry_strategy; } - /// Overrides the set target Endpoint. + /// Returns a copy of the SendData with the user-defined endpoint. /// /// # Arguments /// /// * `endpoint`: The new endpoint to be used. - pub fn set_target(&mut self, endpoint: Endpoint) { - self.target = endpoint; + pub fn with_endpoint(&self, endpoint: Endpoint) -> SendData{ + SendData { + target: endpoint, + ..self.clone() + } } /// Sends the data to the target endpoint. From c649d1d5369461c48608b5a8018983fad23b600e Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Thu, 10 Jul 2025 11:10:09 -0400 Subject: [PATCH 2/8] lint --- datadog-trace-utils/src/send_data/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 332ae504f1..1a46298cfd 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -210,7 +210,7 @@ impl SendData { /// # Arguments /// /// * `endpoint`: The new endpoint to be used. - pub fn with_endpoint(&self, endpoint: Endpoint) -> SendData{ + pub fn with_endpoint(&self, endpoint: Endpoint) -> SendData { SendData { target: endpoint, ..self.clone() From 5610c65786cb7c7e24eab40b214251424a9ae3fb Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Thu, 10 Jul 2025 11:25:14 -0400 Subject: [PATCH 3/8] take endpoint as ref --- datadog-trace-utils/src/send_data/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 1a46298cfd..2cd9f9c2b4 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -210,9 +210,9 @@ impl SendData { /// # Arguments /// /// * `endpoint`: The new endpoint to be used. - pub fn with_endpoint(&self, endpoint: Endpoint) -> SendData { + pub fn with_endpoint(&self, endpoint: &Endpoint) -> SendData { SendData { - target: endpoint, + target: endpoint.clone(), ..self.clone() } } From 34be67ff3fd1f5d6a0df658f75c29c760d8fb3a3 Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Fri, 11 Jul 2025 09:03:31 -0400 Subject: [PATCH 4/8] take Endpoint param --- datadog-trace-utils/src/send_data/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 2cd9f9c2b4..1a46298cfd 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -210,9 +210,9 @@ impl SendData { /// # Arguments /// /// * `endpoint`: The new endpoint to be used. - pub fn with_endpoint(&self, endpoint: &Endpoint) -> SendData { + pub fn with_endpoint(&self, endpoint: Endpoint) -> SendData { SendData { - target: endpoint.clone(), + target: endpoint, ..self.clone() } } From d058fb78406669a7ec139f5693ae6864cd94d876 Mon Sep 17 00:00:00 2001 From: Edmund Kump Date: Fri, 11 Jul 2025 09:47:26 -0400 Subject: [PATCH 5/8] add unit test for SendData.with_endpoint function --- datadog-trace-protobuf/src/remoteconfig.rs | 30 ++++++++----- datadog-trace-utils/src/send_data/mod.rs | 42 +++++++++++++++++++ .../src/send_with_retry/retry_strategy.rs | 2 + 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/datadog-trace-protobuf/src/remoteconfig.rs b/datadog-trace-protobuf/src/remoteconfig.rs index a8a4b66524..fdc89ee871 100644 --- a/datadog-trace-protobuf/src/remoteconfig.rs +++ b/datadog-trace-protobuf/src/remoteconfig.rs @@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize}; // This file is @generated by prost-build. -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct File { #[prost(string, tag = "1")] pub path: ::prost::alloc::string::String, @@ -11,7 +12,8 @@ pub struct File { #[serde(with = "serde_bytes")] pub raw: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Client { #[prost(message, optional, tag = "1")] pub state: ::core::option::Option, @@ -33,7 +35,8 @@ pub struct Client { #[prost(bytes = "vec", tag = "11")] pub capabilities: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientTracer { #[prost(string, tag = "1")] pub runtime_id: ::prost::alloc::string::String, @@ -52,7 +55,8 @@ pub struct ClientTracer { #[prost(string, repeated, tag = "7")] pub tags: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientAgent { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, @@ -65,7 +69,8 @@ pub struct ClientAgent { #[prost(string, repeated, tag = "5")] pub cws_workloads: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ConfigState { #[prost(string, tag = "1")] pub id: ::prost::alloc::string::String, @@ -78,7 +83,8 @@ pub struct ConfigState { #[prost(string, tag = "5")] pub apply_error: ::prost::alloc::string::String, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientState { #[prost(uint64, tag = "1")] pub root_version: u64, @@ -93,14 +99,16 @@ pub struct ClientState { #[prost(bytes = "vec", tag = "6")] pub backend_client_state: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct TargetFileHash { #[prost(string, tag = "1")] pub algorithm: ::prost::alloc::string::String, #[prost(string, tag = "3")] pub hash: ::prost::alloc::string::String, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct TargetFileMeta { #[prost(string, tag = "1")] pub path: ::prost::alloc::string::String, @@ -109,14 +117,16 @@ pub struct TargetFileMeta { #[prost(message, repeated, tag = "3")] pub hashes: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientGetConfigsRequest { #[prost(message, optional, tag = "1")] pub client: ::core::option::Option, #[prost(message, repeated, tag = "2")] pub cached_target_files: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientGetConfigsResponse { #[prost(bytes = "vec", repeated, tag = "1")] #[serde(with = "crate::serde")] diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 1a46298cfd..9bd0fa3c92 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -980,4 +980,46 @@ mod tests { assert_eq!(res.bytes_sent, 0); assert_eq!(res.responses_count_per_code.len(), 0); } + + #[test] + fn test_with_endpoint() { + let header_tags = HEADER_TAGS; + let payload = setup_payload(&header_tags); + let original_endpoint = Endpoint { + api_key: Some(std::borrow::Cow::Borrowed("original-key")), + url: "http://originalexample.com/".parse::().unwrap(), + timeout_ms: 1000, + ..Endpoint::default() + }; + + let original_data = SendData::new( + 100, + TracerPayloadCollection::V07(vec![payload]), + header_tags, + &original_endpoint, + ); + + let new_endpoint = Endpoint { + api_key: Some(std::borrow::Cow::Borrowed("new-key")), + url: "http://newexample.com/".parse::().unwrap(), + timeout_ms: 2000, + ..Endpoint::default() + }; + + let new_data = original_data.with_endpoint(new_endpoint.clone()); + + assert_eq!(new_data.target.api_key, new_endpoint.api_key); + assert_eq!(new_data.target.url, new_endpoint.url); + assert_eq!(new_data.target.timeout_ms, new_endpoint.timeout_ms); + + assert_eq!(new_data.size, original_data.size); + assert_eq!(new_data.headers, original_data.headers); + assert_eq!(new_data.retry_strategy, original_data.retry_strategy); + assert_eq!( + new_data.tracer_payloads.size(), + original_data.tracer_payloads.size() + ); + #[cfg(feature = "compression")] + assert!(matches!(new_data.compression, Compression::None)); + } } diff --git a/datadog-trace-utils/src/send_with_retry/retry_strategy.rs b/datadog-trace-utils/src/send_with_retry/retry_strategy.rs index 4111cea94f..bdd3f074ff 100644 --- a/datadog-trace-utils/src/send_with_retry/retry_strategy.rs +++ b/datadog-trace-utils/src/send_with_retry/retry_strategy.rs @@ -9,6 +9,7 @@ use tokio::time::sleep; /// Enum representing the type of backoff to use for the delay between retries. /// ``` #[derive(Debug, Clone)] +#[cfg_attr(test, derive(PartialEq))] pub enum RetryBackoffType { /// Increases the delay by a fixed increment each attempt. Linear, @@ -24,6 +25,7 @@ pub enum RetryBackoffType { /// It includes the maximum number of retries, the delay between retries, the type of backoff to /// use, and an optional jitter to add randomness to the delay. #[derive(Debug, Clone)] +#[cfg_attr(test, derive(PartialEq))] pub struct RetryStrategy { /// The maximum number of retries to attempt. max_retries: u32, From a3f10109bba44d5f2f06967e5be0ae00f55f897a Mon Sep 17 00:00:00 2001 From: Edmund Kump Date: Fri, 11 Jul 2025 09:50:36 -0400 Subject: [PATCH 6/8] FIXUP: reformatted the protobuf file by mistake --- datadog-trace-protobuf/src/remoteconfig.rs | 30 ++++++++-------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/datadog-trace-protobuf/src/remoteconfig.rs b/datadog-trace-protobuf/src/remoteconfig.rs index fdc89ee871..a8a4b66524 100644 --- a/datadog-trace-protobuf/src/remoteconfig.rs +++ b/datadog-trace-protobuf/src/remoteconfig.rs @@ -3,8 +3,7 @@ use serde::{Deserialize, Serialize}; // This file is @generated by prost-build. -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct File { #[prost(string, tag = "1")] pub path: ::prost::alloc::string::String, @@ -12,8 +11,7 @@ pub struct File { #[serde(with = "serde_bytes")] pub raw: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct Client { #[prost(message, optional, tag = "1")] pub state: ::core::option::Option, @@ -35,8 +33,7 @@ pub struct Client { #[prost(bytes = "vec", tag = "11")] pub capabilities: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ClientTracer { #[prost(string, tag = "1")] pub runtime_id: ::prost::alloc::string::String, @@ -55,8 +52,7 @@ pub struct ClientTracer { #[prost(string, repeated, tag = "7")] pub tags: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ClientAgent { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, @@ -69,8 +65,7 @@ pub struct ClientAgent { #[prost(string, repeated, tag = "5")] pub cws_workloads: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ConfigState { #[prost(string, tag = "1")] pub id: ::prost::alloc::string::String, @@ -83,8 +78,7 @@ pub struct ConfigState { #[prost(string, tag = "5")] pub apply_error: ::prost::alloc::string::String, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ClientState { #[prost(uint64, tag = "1")] pub root_version: u64, @@ -99,16 +93,14 @@ pub struct ClientState { #[prost(bytes = "vec", tag = "6")] pub backend_client_state: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct TargetFileHash { #[prost(string, tag = "1")] pub algorithm: ::prost::alloc::string::String, #[prost(string, tag = "3")] pub hash: ::prost::alloc::string::String, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct TargetFileMeta { #[prost(string, tag = "1")] pub path: ::prost::alloc::string::String, @@ -117,16 +109,14 @@ pub struct TargetFileMeta { #[prost(message, repeated, tag = "3")] pub hashes: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ClientGetConfigsRequest { #[prost(message, optional, tag = "1")] pub client: ::core::option::Option, #[prost(message, repeated, tag = "2")] pub cached_target_files: ::prost::alloc::vec::Vec, } -#[derive(Deserialize, Serialize)] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Deserialize, Serialize, Clone, PartialEq, ::prost::Message)] pub struct ClientGetConfigsResponse { #[prost(bytes = "vec", repeated, tag = "1")] #[serde(with = "crate::serde")] From 79c54b178bbb66ed9ef0716f62d5a333891e613e Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Fri, 11 Jul 2025 10:25:32 -0400 Subject: [PATCH 7/8] PR fixes --- datadog-trace-utils/src/send_data/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 9bd0fa3c92..0c5de306fa 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -205,7 +205,7 @@ impl SendData { self.retry_strategy = retry_strategy; } - /// Returns a copy of the SendData with the user-defined endpoint. + /// Returns a clone of the SendData with the user-defined endpoint. /// /// # Arguments /// @@ -1019,6 +1019,11 @@ mod tests { new_data.tracer_payloads.size(), original_data.tracer_payloads.size() ); + + assert_eq!(original_data.target.api_key, original_endpoint.api_key); + assert_eq!(original_data.target.url, original_endpoint.url); + assert_eq!(original_data.target.timeout_ms, original_endpoint.timeout_ms); + #[cfg(feature = "compression")] assert!(matches!(new_data.compression, Compression::None)); } From 27aef153bf1bb4c02b62e154bdd51bf1ef36d414 Mon Sep 17 00:00:00 2001 From: shreyamalpani Date: Fri, 11 Jul 2025 10:28:56 -0400 Subject: [PATCH 8/8] fmt --- datadog-trace-utils/src/send_data/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/datadog-trace-utils/src/send_data/mod.rs b/datadog-trace-utils/src/send_data/mod.rs index 0c5de306fa..acc4fb2ff7 100644 --- a/datadog-trace-utils/src/send_data/mod.rs +++ b/datadog-trace-utils/src/send_data/mod.rs @@ -1022,7 +1022,10 @@ mod tests { assert_eq!(original_data.target.api_key, original_endpoint.api_key); assert_eq!(original_data.target.url, original_endpoint.url); - assert_eq!(original_data.target.timeout_ms, original_endpoint.timeout_ms); + assert_eq!( + original_data.target.timeout_ms, + original_endpoint.timeout_ms + ); #[cfg(feature = "compression")] assert!(matches!(new_data.compression, Compression::None));