@@ -1846,4 +1846,277 @@ mod tests {
18461846 "Should be snapstart span (id=3), not cold start span (id=2)"
18471847 ) ;
18481848 }
1849+
1850+ #[ test]
1851+ fn test_extract_span_context_from_event_request_headers_datadog ( ) {
1852+ let config = Arc :: new ( config:: Config {
1853+ trace_propagation_style_extract : vec ! [
1854+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1855+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1856+ ] ,
1857+ ..config:: Config :: default ( )
1858+ } ) ;
1859+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1860+ let headers = HashMap :: new ( ) ;
1861+
1862+ let payload = json ! ( {
1863+ "request" : {
1864+ "headers" : {
1865+ "x-datadog-trace-id" : "1234567890" ,
1866+ "x-datadog-parent-id" : "9876543210" ,
1867+ "x-datadog-sampling-priority" : "2" ,
1868+ "x-datadog-origin" : "rum"
1869+ }
1870+ }
1871+ } ) ;
1872+
1873+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
1874+
1875+ assert ! ( result. is_some( ) ) ;
1876+ let context = result. unwrap ( ) ;
1877+ assert_eq ! ( context. trace_id, 1234567890 ) ;
1878+ assert_eq ! ( context. span_id, 9876543210 ) ;
1879+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 2 ) ) ;
1880+ assert_eq ! ( context. origin, Some ( "rum" . to_string( ) ) ) ;
1881+ }
1882+
1883+ #[ test]
1884+ fn test_extract_span_context_from_event_request_headers_tracecontext ( ) {
1885+ let config = Arc :: new ( config:: Config {
1886+ trace_propagation_style_extract : vec ! [
1887+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1888+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1889+ ] ,
1890+ ..config:: Config :: default ( )
1891+ } ) ;
1892+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1893+ let headers = HashMap :: new ( ) ;
1894+
1895+ let payload = json ! ( {
1896+ "request" : {
1897+ "headers" : {
1898+ "traceparent" : "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" ,
1899+ "tracestate" : "dd=s:2;o:rum"
1900+ }
1901+ }
1902+ } ) ;
1903+
1904+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
1905+
1906+ assert ! ( result. is_some( ) ) ;
1907+ let context = result. unwrap ( ) ;
1908+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 2 ) ) ;
1909+ assert_eq ! ( context. origin, Some ( "rum" . to_string( ) ) ) ;
1910+ }
1911+
1912+ #[ test]
1913+ fn test_extract_span_context_priority_order ( ) {
1914+ let config = Arc :: new ( config:: Config {
1915+ trace_propagation_style_extract : vec ! [
1916+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1917+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1918+ ] ,
1919+ ..config:: Config :: default ( )
1920+ } ) ;
1921+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1922+
1923+ let mut headers = HashMap :: new ( ) ;
1924+ headers. insert ( DATADOG_TRACE_ID_KEY . to_string ( ) , "111" . to_string ( ) ) ;
1925+ headers. insert ( DATADOG_PARENT_ID_KEY . to_string ( ) , "222" . to_string ( ) ) ;
1926+
1927+ let payload = json ! ( {
1928+ "headers" : {
1929+ "x-datadog-trace-id" : "333" ,
1930+ "x-datadog-parent-id" : "444"
1931+ } ,
1932+ "request" : {
1933+ "headers" : {
1934+ "x-datadog-trace-id" : "555" ,
1935+ "x-datadog-parent-id" : "666"
1936+ }
1937+ }
1938+ } ) ;
1939+
1940+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
1941+
1942+ assert ! ( result. is_some( ) ) ;
1943+ let context = result. unwrap ( ) ;
1944+ assert_eq ! ( context. trace_id, 333 , "Should prioritize event.headers over other sources" ) ;
1945+ }
1946+
1947+ #[ test]
1948+ fn test_extract_span_context_fallback_to_request_headers ( ) {
1949+ let config = Arc :: new ( config:: Config {
1950+ trace_propagation_style_extract : vec ! [
1951+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1952+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1953+ ] ,
1954+ ..config:: Config :: default ( )
1955+ } ) ;
1956+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1957+ let headers = HashMap :: new ( ) ;
1958+
1959+ let payload = json ! ( {
1960+ "argumentsMap" : {
1961+ "id" : "123"
1962+ } ,
1963+ "request" : {
1964+ "headers" : {
1965+ "x-datadog-trace-id" : "7777" ,
1966+ "x-datadog-parent-id" : "8888" ,
1967+ "x-datadog-sampling-priority" : "1"
1968+ }
1969+ }
1970+ } ) ;
1971+
1972+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
1973+
1974+ assert ! ( result. is_some( ) , "Should fallback to event.request.headers" ) ;
1975+ let context = result. unwrap ( ) ;
1976+ assert_eq ! ( context. trace_id, 7777 ) ;
1977+ assert_eq ! ( context. span_id, 8888 ) ;
1978+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 1 ) ) ;
1979+ }
1980+
1981+ #[ test]
1982+ fn test_extract_span_context_no_request_headers ( ) {
1983+ let config = Arc :: new ( config:: Config {
1984+ trace_propagation_style_extract : vec ! [
1985+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1986+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1987+ ] ,
1988+ ..config:: Config :: default ( )
1989+ } ) ;
1990+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1991+ let headers = HashMap :: new ( ) ;
1992+
1993+ let payload = json ! ( {
1994+ "argumentsMap" : {
1995+ "id" : "123"
1996+ } ,
1997+ "request" : {
1998+ "body" : "some body"
1999+ }
2000+ } ) ;
2001+
2002+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2003+
2004+ assert ! ( result. is_none( ) , "Should return None when no trace context found" ) ;
2005+ }
2006+
2007+ #[ test]
2008+ fn test_extract_span_context_empty_request_headers ( ) {
2009+ let config = Arc :: new ( config:: Config {
2010+ trace_propagation_style_extract : vec ! [
2011+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2012+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2013+ ] ,
2014+ ..config:: Config :: default ( )
2015+ } ) ;
2016+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2017+ let headers = HashMap :: new ( ) ;
2018+
2019+ let payload = json ! ( {
2020+ "request" : {
2021+ "headers" : { }
2022+ }
2023+ } ) ;
2024+
2025+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2026+
2027+ assert ! ( result. is_none( ) , "Should return None when request.headers is empty" ) ;
2028+ }
2029+
2030+ #[ test]
2031+ fn test_extract_span_context_invalid_request_headers ( ) {
2032+ let config = Arc :: new ( config:: Config {
2033+ trace_propagation_style_extract : vec ! [
2034+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2035+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2036+ ] ,
2037+ ..config:: Config :: default ( )
2038+ } ) ;
2039+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2040+ let headers = HashMap :: new ( ) ;
2041+
2042+ let payload = json ! ( {
2043+ "request" : {
2044+ "headers" : {
2045+ "x-datadog-trace-id" : "not-a-number" ,
2046+ "x-datadog-parent-id" : "also-not-a-number"
2047+ }
2048+ }
2049+ } ) ;
2050+
2051+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2052+
2053+ assert ! ( result. is_none( ) , "Should return None when headers are invalid" ) ;
2054+ }
2055+
2056+ #[ test]
2057+ fn test_extract_span_context_appsync_real_world_example ( ) {
2058+ let config = Arc :: new ( config:: Config {
2059+ trace_propagation_style_extract : vec ! [
2060+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2061+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2062+ ] ,
2063+ ..config:: Config :: default ( )
2064+ } ) ;
2065+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2066+ let headers = HashMap :: new ( ) ;
2067+
2068+ let payload = json ! ( {
2069+ "arguments" : {
2070+ "userId" : "12345"
2071+ } ,
2072+ "identity" : {
2073+ "sub" : "user-sub-id"
2074+ } ,
2075+ "request" : {
2076+ "headers" : {
2077+ "x-datadog-trace-id" : "123456789012345" ,
2078+ "x-datadog-parent-id" : "98765432109876" ,
2079+ "x-datadog-sampling-priority" : "2" ,
2080+ "x-datadog-origin" : "rum" ,
2081+ "x-datadog-tags" : "_dd.p.dm=-0" ,
2082+ "user-agent" : "Mozilla/5.0" ,
2083+ "content-type" : "application/json"
2084+ }
2085+ } ,
2086+ "info" : {
2087+ "fieldName" : "getUser" ,
2088+ "parentTypeName" : "Query"
2089+ }
2090+ } ) ;
2091+
2092+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2093+
2094+ assert ! ( result. is_some( ) , "Should extract from real-world AppSync event" ) ;
2095+ let context = result. unwrap ( ) ;
2096+ assert_eq ! ( context. trace_id, 123456789012345 ) ;
2097+ assert_eq ! ( context. span_id, 98765432109876 ) ;
2098+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 2 ) ) ;
2099+ assert_eq ! ( context. origin, Some ( "rum" . to_string( ) ) ) ;
2100+ }
2101+
2102+ #[ test]
2103+ fn test_extract_span_context_request_not_an_object ( ) {
2104+ let config = Arc :: new ( config:: Config {
2105+ trace_propagation_style_extract : vec ! [
2106+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2107+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2108+ ] ,
2109+ ..config:: Config :: default ( )
2110+ } ) ;
2111+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2112+ let headers = HashMap :: new ( ) ;
2113+
2114+ let payload = json ! ( {
2115+ "request" : "invalid-not-an-object"
2116+ } ) ;
2117+
2118+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2119+
2120+ assert ! ( result. is_none( ) , "Should handle gracefully when request is not an object" ) ;
2121+ }
18492122}
0 commit comments