Skip to content

Commit 391f38c

Browse files
committed
[APMSVLS-197] test: Add unit tests for event.request.headers trace context extraction
1 parent 8a2baca commit 391f38c

1 file changed

Lines changed: 291 additions & 0 deletions

File tree

bottlecap/src/lifecycle/invocation/processor.rs

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)