@@ -8,30 +8,39 @@ use hyper::body::Incoming;
88use hyper:: { Request , Response , Uri } ;
99use libdd_common:: hyper_migration:: { self , Body } ;
1010use std:: collections:: HashMap ;
11+ use std:: fmt:: Write ;
1112use std:: path:: Path ;
1213use std:: str:: FromStr ;
1314use std:: time:: Duration ;
1415
1516const 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 " ;
1718const 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+
2125const SAMPLE_RATE_QUERY_PARAM_KEY : & str = "agent_sample_rate_by_service" ;
2226const SESSION_TEST_TOKEN_QUERY_PARAM_KEY : & str = "test_session_token" ;
2327const SESSION_START_ENDPOINT : & str = "test/session/start" ;
28+ const SESSION_ASSERT_SNAPSHOT : & str = "test/session/snapshot" ;
2429const SET_REMOTE_CONFIG_RESPONSE_PATH_ENDPOINT : & str = "test/session/responses/config/path" ;
2530
2631struct 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
3239struct 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/// ```
232250pub struct DatadogTestAgent {
233251 container : DatadogTestAgentContainer ,
252+ socket_path : Option < String > ,
234253}
235254
236255impl 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