Skip to content

Commit e7c2ff8

Browse files
chore(trace-utils): bump the test agent version used for integration tests (#1417)
# Changes * Bump test-agent version from 1.31 to 1.39 * Use the APM socket to talk to test API when it is provided # Motivation The version that we currently have doesn't expose OTLP metrics and logs endpoints, which we'd like to test. The new version doesn't start the tcp trace agent API if a socket directory is provided, which breaks the current client * fix:
1 parent b9320a3 commit e7c2ff8

File tree

3 files changed

+92
-43
lines changed

3 files changed

+92
-43
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libdd-trace-utils/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ path = "benches/main.rs"
2020
[dependencies]
2121
anyhow = "1.0"
2222
hyper = { workspace = true}
23+
"http" = "1"
2324
http-body-util = "0.1"
2425
serde = { version = "1.0.145", features = ["derive"] }
2526
prost = "0.13.5"

libdd-trace-utils/src/test_utils/datadog_test_agent.rs

Lines changed: 90 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,39 @@ use hyper::body::Incoming;
88
use hyper::{Request, Response, Uri};
99
use libdd_common::hyper_migration::{self, Body};
1010
use std::collections::HashMap;
11+
use std::fmt::Write;
1112
use std::path::Path;
1213
use std::str::FromStr;
1314
use std::time::Duration;
1415

1516
const TEST_AGENT_IMAGE_NAME: &str = "ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent";
16-
const TEST_AGENT_IMAGE_TAG: &str = "v1.31.1";
17+
const TEST_AGENT_IMAGE_TAG: &str = "v1.39.0";
1718
const TEST_AGENT_READY_MSG: &str =
1819
"INFO:ddapm_test_agent.agent:Trace request stall seconds setting set to 0.0.";
1920

20-
const TEST_AGENT_PORT: u16 = 8126;
21+
const TRACE_AGENT_API_PORT: u16 = 8126;
22+
const OTEL_HTTP_PORT: u16 = 4318;
23+
const OTEL_PROTO_PORT: u16 = 4317;
24+
2125
const SAMPLE_RATE_QUERY_PARAM_KEY: &str = "agent_sample_rate_by_service";
2226
const SESSION_TEST_TOKEN_QUERY_PARAM_KEY: &str = "test_session_token";
2327
const SESSION_START_ENDPOINT: &str = "test/session/start";
28+
const SESSION_ASSERT_SNAPSHOT: &str = "test/session/snapshot";
2429
const SET_REMOTE_CONFIG_RESPONSE_PATH_ENDPOINT: &str = "test/session/responses/config/path";
2530

2631
struct DatadogAgentContainerBuilder {
2732
mounts: Vec<(String, String)>,
2833
env_vars: Vec<(String, String)>,
29-
exposed_port: u16,
34+
trace_agent_port: u16,
35+
otlp_http_port: u16,
36+
otlp_proto_port: u16,
3037
}
3138

3239
struct DatadogTestAgentContainer {
3340
container_id: String,
34-
container_port: u16,
41+
trace_agent_port: u16,
42+
otlp_http_port: u16,
43+
otlp_proto_port: u16,
3544
}
3645

3746
/// Run the command passed and returns an error if the return code is not
@@ -69,23 +78,26 @@ impl DatadogTestAgentContainer {
6978
anyhow::bail!("waiting for test container timed out")
7079
}
7180

72-
fn host_port(&self) -> anyhow::Result<String> {
81+
fn host_port(&self, container_port: u16) -> anyhow::Result<String> {
7382
use std::process::*;
7483
let output = run_command(
7584
Command::new("docker")
7685
.args(["inspect", "--format"])
7786
.arg(format!(
7887
r##"{{{{(index (index .NetworkSettings.Ports "{}/tcp") 0).HostPort}}}}"##,
79-
self.container_port
88+
container_port
8089
))
8190
.arg(&self.container_id),
8291
)
8392
.context("docker inspect mapped host port")?;
8493
Ok(String::from_utf8(output.stdout)?.trim().to_owned())
8594
}
8695

87-
fn base_uri(&self) -> anyhow::Result<String> {
88-
Ok(format!("http://localhost:{}", self.host_port()?))
96+
fn trace_agent_uri(&self) -> anyhow::Result<String> {
97+
Ok(format!(
98+
"http://localhost:{}",
99+
self.host_port(self.trace_agent_port)?
100+
))
89101
}
90102
}
91103

@@ -115,17 +127,21 @@ impl DatadogAgentContainerBuilder {
115127

116128
let output = run_command(
117129
Command::new("docker")
118-
.args(["run", "--rm", "-d"])
130+
.args(["run", /* "--rm", */ "-d"])
119131
.args(mounts)
120132
.args(envs)
121-
.args(["-p".to_owned(), format!("{}", self.exposed_port)])
133+
.args(["-p".to_owned(), format!("{}", self.trace_agent_port)])
134+
.args(["-p".to_owned(), format!("{}", self.otlp_http_port)])
135+
.args(["-p".to_owned(), format!("{}", self.otlp_proto_port)])
122136
.arg(format!("{TEST_AGENT_IMAGE_NAME}:{TEST_AGENT_IMAGE_TAG}",)),
123137
)
124138
.context("docker run container")?;
125139
let container_id = String::from_utf8(output.stdout)?.trim().to_owned();
126140
let container = DatadogTestAgentContainer {
127141
container_id,
128-
container_port: self.exposed_port,
142+
trace_agent_port: self.trace_agent_port,
143+
otlp_http_port: self.otlp_http_port,
144+
otlp_proto_port: self.otlp_proto_port,
129145
};
130146
container.wait_ready()?;
131147
Ok(container)
@@ -154,7 +170,9 @@ impl DatadogAgentContainerBuilder {
154170
DatadogAgentContainerBuilder {
155171
mounts,
156172
env_vars,
157-
exposed_port: TEST_AGENT_PORT,
173+
trace_agent_port: TRACE_AGENT_API_PORT,
174+
otlp_http_port: OTEL_HTTP_PORT,
175+
otlp_proto_port: OTEL_PROTO_PORT,
158176
}
159177
}
160178

@@ -231,6 +249,7 @@ impl DatadogAgentContainerBuilder {
231249
/// ```
232250
pub struct DatadogTestAgent {
233251
container: DatadogTestAgentContainer,
252+
socket_path: Option<String>,
234253
}
235254

236255
impl DatadogTestAgent {
@@ -268,11 +287,17 @@ impl DatadogTestAgent {
268287
container: container
269288
.start()
270289
.expect("Unable to start DatadogTestAgent, is the Docker Daemon running?"),
290+
socket_path: absolute_socket_path.map(|p: &str| format!("{}/apm.socket", p)),
271291
}
272292
}
273293

274-
async fn get_base_uri_string(&self) -> String {
275-
self.container.base_uri().unwrap()
294+
pub async fn get_base_uri(&self) -> http::Uri {
295+
libdd_common::parse_uri(&if let Some(path) = &self.socket_path {
296+
format!("unix://{path}")
297+
} else {
298+
self.container.trace_agent_uri().unwrap()
299+
})
300+
.unwrap()
276301
}
277302

278303
/// Constructs the URI for a provided endpoint of the Datadog Test Agent by concatenating the
@@ -289,33 +314,35 @@ impl DatadogTestAgent {
289314
///
290315
/// A `Uri` object representing the URI of the specified endpoint.
291316
pub async fn get_uri_for_endpoint(&self, endpoint: &str, snapshot_token: Option<&str>) -> Uri {
292-
let base_uri_string = self.get_base_uri_string().await;
293-
let uri_string = match snapshot_token {
294-
Some(token) => format!("{base_uri_string}/{endpoint}?test_session_token={token}"),
295-
None => format!("{base_uri_string}/{endpoint}"),
296-
};
297-
298-
Uri::from_str(&uri_string).expect("Invalid URI")
317+
self.get_uri_for_endpoint_and_params(
318+
endpoint,
319+
snapshot_token.map(|t| ("test_session_token", t)),
320+
)
321+
.await
299322
}
300323

301-
async fn get_uri_for_endpoint_and_params(
324+
async fn get_uri_for_endpoint_and_params<'a, I: IntoIterator<Item = (&'a str, &'a str)>>(
302325
&self,
303326
endpoint: &str,
304-
query_params: HashMap<&str, &str>,
327+
query_params: I,
305328
) -> Uri {
306329
let base_uri = self.get_base_uri().await;
307330
let mut parts = base_uri.into_parts();
308331

309-
let query_string = if !query_params.is_empty() {
310-
let query = query_params
311-
.iter()
312-
.map(|(k, v)| format!("{}={}", urlencoding::encode(k), urlencoding::encode(v)))
313-
.collect::<Vec<_>>()
314-
.join("&");
315-
format!("?{query}")
316-
} else {
317-
String::new()
318-
};
332+
let mut query_string = String::new();
333+
for (i, (k, v)) in query_params.into_iter().enumerate() {
334+
if i == 0 {
335+
query_string.push('?');
336+
} else {
337+
query_string.push('&');
338+
}
339+
let _ = write!(
340+
&mut query_string,
341+
"{}={}",
342+
urlencoding::encode(k),
343+
urlencoding::encode(v)
344+
);
345+
}
319346

320347
parts.path_and_query = Some(
321348
format!("/{}{}", endpoint.trim_start_matches('/'), query_string)
@@ -326,15 +353,36 @@ impl DatadogTestAgent {
326353
Uri::from_parts(parts).expect("Invalid URI")
327354
}
328355

329-
/// Returns the URI for the Datadog Test Agent's base URL and port.
330-
/// The docker-image dynamically assigns what port the test-agent's 8126 port is forwarded to.
356+
/// Returns the URI for the OTLP HTTP endpoint.
357+
/// The docker-image dynamically assigns what port the test-agent's OTLP HTTP port is forwarded
358+
/// to.
331359
///
332360
/// # Returns
333361
///
334-
/// A `Uri` object representing the URI of the specified endpoint.
335-
pub async fn get_base_uri(&self) -> Uri {
336-
let base_uri_string = self.get_base_uri_string().await;
337-
Uri::from_str(&base_uri_string).expect("Invalid URI")
362+
/// A `Uri` object representing the URI of the OTLP HTTP endpoint.
363+
pub async fn get_otlp_http_uri(&self) -> Uri {
364+
let host_port = self
365+
.container
366+
.host_port(self.container.otlp_http_port)
367+
.expect("Failed to get OTLP HTTP host port");
368+
let uri_string = format!("http://localhost:{}", host_port);
369+
Uri::from_str(&uri_string).expect("Invalid URI")
370+
}
371+
372+
/// Returns the URI for the OTLP gRPC endpoint.
373+
/// The docker-image dynamically assigns what port the test-agent's OTLP gRPC port is forwarded
374+
/// to.
375+
///
376+
/// # Returns
377+
///
378+
/// A `Uri` object representing the URI of the OTLP gRPC endpoint.
379+
pub async fn get_otlp_grpc_uri(&self) -> Uri {
380+
let host_port = self
381+
.container
382+
.host_port(self.container.otlp_proto_port)
383+
.expect("Failed to get OTLP gRPC host port");
384+
let uri_string = format!("http://localhost:{}", host_port);
385+
Uri::from_str(&uri_string).expect("Invalid URI")
338386
}
339387

340388
/// Asserts that the snapshot for a given token matches the expected snapshot. This should be
@@ -345,7 +393,7 @@ impl DatadogTestAgent {
345393
/// * `snapshot_token` - A string slice that holds the snapshot token.
346394
pub async fn assert_snapshot(&self, snapshot_token: &str) {
347395
let uri = self
348-
.get_uri_for_endpoint("test/session/snapshot", Some(snapshot_token))
396+
.get_uri_for_endpoint(SESSION_ASSERT_SNAPSHOT, Some(snapshot_token))
349397
.await;
350398

351399
let req = Request::builder()
@@ -466,9 +514,8 @@ impl DatadogTestAgent {
466514

467515
let mut query_params_map = HashMap::new();
468516
query_params_map.insert(SESSION_TEST_TOKEN_QUERY_PARAM_KEY, session_token);
469-
if let Some(agent_sample_rates_by_service) = agent_sample_rates_by_service {
470-
query_params_map.insert(SAMPLE_RATE_QUERY_PARAM_KEY, agent_sample_rates_by_service);
471-
}
517+
query_params_map
518+
.extend(agent_sample_rates_by_service.map(|r| (SAMPLE_RATE_QUERY_PARAM_KEY, r)));
472519

473520
let uri = self
474521
.get_uri_for_endpoint_and_params(SESSION_START_ENDPOINT, query_params_map)

0 commit comments

Comments
 (0)