Skip to content

Commit 96d4cb4

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

1 file changed

Lines changed: 273 additions & 0 deletions

File tree

bottlecap/src/lifecycle/invocation/processor.rs

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

Comments
 (0)