@@ -1846,4 +1846,295 @@ 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, 1_234_567_890 ) ;
1878+ assert_eq ! ( context. span_id, 9_876_543_210 ) ;
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 ! (
1945+ context. trace_id, 333 ,
1946+ "Should prioritize event.headers over other sources"
1947+ ) ;
1948+ }
1949+
1950+ #[ test]
1951+ fn test_extract_span_context_fallback_to_request_headers ( ) {
1952+ let config = Arc :: new ( config:: Config {
1953+ trace_propagation_style_extract : vec ! [
1954+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1955+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1956+ ] ,
1957+ ..config:: Config :: default ( )
1958+ } ) ;
1959+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1960+ let headers = HashMap :: new ( ) ;
1961+
1962+ let payload = json ! ( {
1963+ "argumentsMap" : {
1964+ "id" : "123"
1965+ } ,
1966+ "request" : {
1967+ "headers" : {
1968+ "x-datadog-trace-id" : "7777" ,
1969+ "x-datadog-parent-id" : "8888" ,
1970+ "x-datadog-sampling-priority" : "1"
1971+ }
1972+ }
1973+ } ) ;
1974+
1975+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
1976+
1977+ assert ! ( result. is_some( ) , "Should fallback to event.request.headers" ) ;
1978+ let context = result. unwrap ( ) ;
1979+ assert_eq ! ( context. trace_id, 7777 ) ;
1980+ assert_eq ! ( context. span_id, 8888 ) ;
1981+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 1 ) ) ;
1982+ }
1983+
1984+ #[ test]
1985+ fn test_extract_span_context_no_request_headers ( ) {
1986+ let config = Arc :: new ( config:: Config {
1987+ trace_propagation_style_extract : vec ! [
1988+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
1989+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
1990+ ] ,
1991+ ..config:: Config :: default ( )
1992+ } ) ;
1993+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
1994+ let headers = HashMap :: new ( ) ;
1995+
1996+ let payload = json ! ( {
1997+ "argumentsMap" : {
1998+ "id" : "123"
1999+ } ,
2000+ "request" : {
2001+ "body" : "some body"
2002+ }
2003+ } ) ;
2004+
2005+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2006+
2007+ assert ! (
2008+ result. is_none( ) ,
2009+ "Should return None when no trace context found"
2010+ ) ;
2011+ }
2012+
2013+ #[ test]
2014+ fn test_extract_span_context_empty_request_headers ( ) {
2015+ let config = Arc :: new ( config:: Config {
2016+ trace_propagation_style_extract : vec ! [
2017+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2018+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2019+ ] ,
2020+ ..config:: Config :: default ( )
2021+ } ) ;
2022+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2023+ let headers = HashMap :: new ( ) ;
2024+
2025+ let payload = json ! ( {
2026+ "request" : {
2027+ "headers" : { }
2028+ }
2029+ } ) ;
2030+
2031+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2032+
2033+ assert ! (
2034+ result. is_none( ) ,
2035+ "Should return None when request.headers is empty"
2036+ ) ;
2037+ }
2038+
2039+ #[ test]
2040+ fn test_extract_span_context_invalid_request_headers ( ) {
2041+ let config = Arc :: new ( config:: Config {
2042+ trace_propagation_style_extract : vec ! [
2043+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2044+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2045+ ] ,
2046+ ..config:: Config :: default ( )
2047+ } ) ;
2048+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2049+ let headers = HashMap :: new ( ) ;
2050+
2051+ let payload = json ! ( {
2052+ "request" : {
2053+ "headers" : {
2054+ "x-datadog-trace-id" : "not-a-number" ,
2055+ "x-datadog-parent-id" : "also-not-a-number"
2056+ }
2057+ }
2058+ } ) ;
2059+
2060+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2061+
2062+ assert ! (
2063+ result. is_none( ) ,
2064+ "Should return None when headers are invalid"
2065+ ) ;
2066+ }
2067+
2068+ #[ test]
2069+ fn test_extract_span_context_appsync_real_world_example ( ) {
2070+ let config = Arc :: new ( config:: Config {
2071+ trace_propagation_style_extract : vec ! [
2072+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2073+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2074+ ] ,
2075+ ..config:: Config :: default ( )
2076+ } ) ;
2077+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2078+ let headers = HashMap :: new ( ) ;
2079+
2080+ let payload = json ! ( {
2081+ "arguments" : {
2082+ "userId" : "12345"
2083+ } ,
2084+ "identity" : {
2085+ "sub" : "user-sub-id"
2086+ } ,
2087+ "request" : {
2088+ "headers" : {
2089+ "x-datadog-trace-id" : "123456789012345" ,
2090+ "x-datadog-parent-id" : "98765432109876" ,
2091+ "x-datadog-sampling-priority" : "2" ,
2092+ "x-datadog-origin" : "rum" ,
2093+ "x-datadog-tags" : "_dd.p.dm=-0" ,
2094+ "user-agent" : "Mozilla/5.0" ,
2095+ "content-type" : "application/json"
2096+ }
2097+ } ,
2098+ "info" : {
2099+ "fieldName" : "getUser" ,
2100+ "parentTypeName" : "Query"
2101+ }
2102+ } ) ;
2103+
2104+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2105+
2106+ assert ! (
2107+ result. is_some( ) ,
2108+ "Should extract from real-world AppSync event"
2109+ ) ;
2110+ let context = result. unwrap ( ) ;
2111+ assert_eq ! ( context. trace_id, 123_456_789_012_345 ) ;
2112+ assert_eq ! ( context. span_id, 98_765_432_109_876 ) ;
2113+ assert_eq ! ( context. sampling. unwrap( ) . priority, Some ( 2 ) ) ;
2114+ assert_eq ! ( context. origin, Some ( "rum" . to_string( ) ) ) ;
2115+ }
2116+
2117+ #[ test]
2118+ fn test_extract_span_context_request_not_an_object ( ) {
2119+ let config = Arc :: new ( config:: Config {
2120+ trace_propagation_style_extract : vec ! [
2121+ config:: trace_propagation_style:: TracePropagationStyle :: Datadog ,
2122+ config:: trace_propagation_style:: TracePropagationStyle :: TraceContext ,
2123+ ] ,
2124+ ..config:: Config :: default ( )
2125+ } ) ;
2126+ let propagator = Arc :: new ( DatadogCompositePropagator :: new ( Arc :: clone ( & config) ) ) ;
2127+ let headers = HashMap :: new ( ) ;
2128+
2129+ let payload = json ! ( {
2130+ "request" : "invalid-not-an-object"
2131+ } ) ;
2132+
2133+ let result = Processor :: extract_span_context ( & headers, & payload, propagator) ;
2134+
2135+ assert ! (
2136+ result. is_none( ) ,
2137+ "Should handle gracefully when request is not an object"
2138+ ) ;
2139+ }
18492140}
0 commit comments