#![cfg(test)]
use crate::observability::otlp_trace_exporter::{
InMemoryOtlpHttpExporter, LoadSheddingTraceExporter, OtlpSpan, SpanBatch, TraceExporter,
};
use crate::observability::w3c_trace_context::extract_from_http;
use std::collections::HashMap;
use std::time::{Duration, Instant};
#[derive(Debug)]
struct LocalSamplerFixture {
should_sample: bool,
}
impl LocalSamplerFixture {
fn new(should_sample: bool) -> Self {
Self { should_sample }
}
fn sample_root(&self, _span_name: &str) -> bool {
self.should_sample
}
fn sample_child(&self, parent_sampled: bool) -> bool {
parent_sampled }
}
struct HeaderFixtureRequest {
headers: HashMap<String, String>,
}
impl HeaderFixtureRequest {
fn with_traceparent(traceparent: &str) -> Self {
let mut headers = HashMap::new();
headers.insert("traceparent".to_string(), traceparent.to_string());
Self { headers }
}
}
#[test]
fn audit_upstream_sampling_decision_honored() {
println!("🔍 AUDIT: Upstream sampling decision propagation (W3C compliance)");
println!("📋 W3C trace-context requirements:");
println!(" • Upstream traceparent sampled=1 must be honored");
println!(" • Local sampler decisions apply to ROOT spans only");
println!(" • Child spans preserve parent sampling for trace integrity");
println!(" • No override of upstream decisions");
let memory_exporter = InMemoryOtlpHttpExporter::new(Duration::from_millis(1));
let exporter = LoadSheddingTraceExporter::new(
Box::new(memory_exporter.clone()),
100,
Duration::from_secs(1),
);
let local_sampler = LocalSamplerFixture::new(false);
println!("📊 Phase 1: Extract upstream traceparent with sampled=1");
let upstream_sampled_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01";
let request = HeaderFixtureRequest::with_traceparent(upstream_sampled_traceparent);
let upstream_context = extract_from_http(&request.headers)
.expect("valid traceparent")
.expect("context present");
assert!(
upstream_context.flags.is_sampled(),
"Upstream context should indicate sampled=1"
);
println!(" Upstream decision: sampled=1");
println!(" Local sampler decision: drop (don't sample)");
println!("📊 Phase 2: Create child span (W3C compliant sampling)");
let w3c_compliant_flags = if upstream_context.flags.is_sampled() {
println!(" W3C compliance: honoring upstream sampled=1");
0x01 } else {
u8::from(local_sampler.sample_child(false))
};
let compliant_span = OtlpSpan::new_with_flags(
upstream_context.span_id.to_hex(),
"child_operation".to_string(),
1000000000,
1000001000,
vec![
("upstream_sampled".to_string(), "true".to_string()),
("local_decision".to_string(), "drop".to_string()),
("w3c_decision".to_string(), "honor_upstream".to_string()),
],
w3c_compliant_flags, );
assert!(
compliant_span.is_sampled(),
"Span should be sampled per W3C compliance (honor upstream sampled=1)"
);
println!("📊 Phase 3: Export span and verify W3C compliant behavior");
let batch = SpanBatch {
batch_id: 1,
spans: vec![compliant_span],
created_at: Instant::now(),
};
exporter.export(&batch).expect("export should succeed");
let processed = exporter.process_queue().expect("processing should succeed");
let exported_batches = memory_exporter.exported_batches();
println!("📊 W3C compliance verification:");
println!(" Processed batches: {}", processed);
println!(" Exported batches: {}", exported_batches.len());
assert_eq!(
exported_batches.len(),
1,
"W3C COMPLIANCE: Upstream sampled=1 must be honored, span should be exported. \
Exported {} batches but expected 1.",
exported_batches.len()
);
if !exported_batches.is_empty() {
let exported_batch = &exported_batches[0];
assert_eq!(exported_batch.spans.len(), 1);
let exported_span = &exported_batch.spans[0];
assert!(
exported_span.is_sampled(),
"Exported span should maintain sampled state per W3C"
);
}
println!("✅ W3C TRACE-CONTEXT COMPLIANCE: SOUND");
println!(" • Upstream sampled=1 decision honored");
println!(" • Local sampler drop decision ignored (correct)");
println!(" • Distributed trace integrity preserved");
}
#[test]
fn audit_local_sampling_applies_to_root_spans_only() {
println!("🔍 AUDIT: Local sampling for ROOT spans vs W3C propagation for children");
let memory_exporter = InMemoryOtlpHttpExporter::new(Duration::from_millis(1));
let exporter = LoadSheddingTraceExporter::new(
Box::new(memory_exporter.clone()),
100,
Duration::from_secs(1),
);
let local_sampler = LocalSamplerFixture::new(false);
println!("📊 Case 1: ROOT span - local sampler decision applies");
let root_decision = local_sampler.sample_root("root_operation");
let root_flags = u8::from(root_decision);
let root_span = OtlpSpan::new_with_flags(
"root123456789".to_string(),
"root_operation".to_string(),
1000000000,
1000001000,
vec![("span_type".to_string(), "root".to_string())],
root_flags, );
println!(
" Local sampler decision: {}",
if root_decision { "sample" } else { "drop" }
);
println!(" Root span sampled: {}", root_span.is_sampled());
println!("📊 Case 2: CHILD span - honors parent decision (W3C)");
let parent_sampled = true; let child_decision = local_sampler.sample_child(parent_sampled);
let child_flags = u8::from(child_decision);
let child_span = OtlpSpan::new_with_flags(
"child123456789".to_string(),
"child_operation".to_string(),
1000002000,
1000003000,
vec![
("span_type".to_string(), "child".to_string()),
("parent_sampled".to_string(), parent_sampled.to_string()),
],
child_flags, );
println!(" Parent sampled: {}", parent_sampled);
println!(" Child span sampled: {}", child_span.is_sampled());
assert!(
!root_span.is_sampled(),
"Root span should follow local sampler (drop)"
);
assert!(
child_span.is_sampled(),
"Child span should honor parent decision (W3C)"
);
let batch = SpanBatch {
batch_id: 1,
spans: vec![root_span, child_span],
created_at: Instant::now(),
};
exporter.export(&batch).expect("export should succeed");
exporter.process_queue().expect("processing should succeed");
let exported_batches = memory_exporter.exported_batches();
if !exported_batches.is_empty() {
let exported_batch = &exported_batches[0];
println!("📊 Export verification:");
println!(" Exported spans: {}", exported_batch.spans.len());
assert_eq!(
exported_batch.spans.len(),
1,
"Only sampled child span should be exported"
);
assert_eq!(
exported_batch.spans[0].name, "child_operation",
"Child span (W3C compliant) should be exported"
);
}
println!("✅ LOCAL vs W3C SAMPLING: SOUND");
println!(" • Local sampler applies to ROOT spans");
println!(" • W3C propagation applies to CHILD spans");
println!(" • Distributed consistency preserved");
}
#[test]
fn audit_defective_local_override_scenario() {
println!("🚨 AUDIT: Defective local override scenario (anti-pattern)");
println!("📋 DEFECTIVE anti-pattern:");
println!(" • Upstream traceparent sampled=1");
println!(" • Local sampler override to drop");
println!(" • Result: broken distributed trace");
let memory_exporter = InMemoryOtlpHttpExporter::new(Duration::from_millis(1));
let exporter = LoadSheddingTraceExporter::new(
Box::new(memory_exporter.clone()),
100,
Duration::from_secs(1),
);
let upstream_sampled_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4738-00f067aa0ba902b9-01";
let request = HeaderFixtureRequest::with_traceparent(upstream_sampled_traceparent);
let upstream_context = extract_from_http(&request.headers)
.expect("valid traceparent")
.expect("context present");
assert!(upstream_context.flags.is_sampled());
let local_sampler = LocalSamplerFixture::new(false);
println!("🚨 Exercising DEFECTIVE behavior: local override of upstream decision");
let defective_flags = u8::from(local_sampler.sample_root("defective_operation"));
let defective_span = OtlpSpan::new_with_flags(
upstream_context.span_id.to_hex(),
"defective_operation".to_string(),
1000000000,
1000001000,
vec![
("upstream_sampled".to_string(), "true".to_string()),
("local_override".to_string(), "drop".to_string()),
("behavior".to_string(), "DEFECTIVE".to_string()),
],
defective_flags, );
println!(" Upstream decision: sampled=1");
println!(" Local override: drop");
println!(" Defective span sampled: {}", defective_span.is_sampled());
assert!(
!defective_span.is_sampled(),
"Defective behavior: span dropped despite upstream sampled=1"
);
let batch = SpanBatch {
batch_id: 1,
spans: vec![defective_span],
created_at: Instant::now(),
};
exporter.export(&batch).expect("export should succeed");
exporter.process_queue().expect("processing should succeed");
let exported_batches = memory_exporter.exported_batches();
println!("🚨 Defective result analysis:");
println!(" Exported batches: {}", exported_batches.len());
println!(" Expected behavior: 1 batch (honor upstream)");
println!(" Defective behavior: 0 batches (local override)");
assert_eq!(
exported_batches.len(),
0,
"DEFECTIVE: No spans exported despite upstream sampled=1"
);
println!("🚨 DEFECT DEMONSTRATED: Local override breaks trace integrity");
println!("💡 SOLUTION: Always honor upstream sampling decisions per W3C");
}
#[test]
fn audit_current_implementation_w3c_compliance() {
println!("✅ AUDIT: Current implementation W3C compliance verification");
println!("📋 W3C compliance test matrix:");
println!(" 1. Upstream sampled=1 → should export");
println!(" 2. Upstream sampled=0 → should drop");
println!(" 3. No upstream context → apply local sampling");
let memory_exporter = InMemoryOtlpHttpExporter::new(Duration::from_millis(1));
let exporter = LoadSheddingTraceExporter::new(
Box::new(memory_exporter.clone()),
100,
Duration::from_secs(1),
);
let mut test_spans = Vec::new();
let sampled_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4739-00f067aa0ba902ba-01";
let sampled_request = HeaderFixtureRequest::with_traceparent(sampled_traceparent);
let sampled_context = extract_from_http(&sampled_request.headers)
.expect("valid traceparent")
.expect("context present");
test_spans.push(OtlpSpan::new_with_flags(
sampled_context.span_id.to_hex(),
"test_upstream_sampled".to_string(),
1000000000,
1000001000,
vec![("test_case".to_string(), "upstream_sampled".to_string())],
sampled_context.flags.bits(), ));
let unsampled_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e473a-00f067aa0ba902bb-00";
let unsampled_request = HeaderFixtureRequest::with_traceparent(unsampled_traceparent);
let unsampled_context = extract_from_http(&unsampled_request.headers)
.expect("valid traceparent")
.expect("context present");
test_spans.push(OtlpSpan::new_with_flags(
unsampled_context.span_id.to_hex(),
"test_upstream_unsampled".to_string(),
1000002000,
1000003000,
vec![("test_case".to_string(), "upstream_unsampled".to_string())],
unsampled_context.flags.bits(), ));
test_spans.push(OtlpSpan::new_with_flags(
"local_root_span".to_string(),
"test_local_root".to_string(),
1000004000,
1000005000,
vec![("test_case".to_string(), "local_root".to_string())],
0x01, ));
let batch = SpanBatch {
batch_id: 1,
spans: test_spans,
created_at: Instant::now(),
};
exporter.export(&batch).expect("export should succeed");
exporter.process_queue().expect("processing should succeed");
let exported_batches = memory_exporter.exported_batches();
println!("📊 W3C compliance results:");
if !exported_batches.is_empty() {
let exported_batch = &exported_batches[0];
println!(" Exported spans: {}", exported_batch.spans.len());
for span in &exported_batch.spans {
println!(" - {} (sampled: {})", span.name, span.is_sampled());
}
assert_eq!(
exported_batch.spans.len(),
2,
"Should export 2 spans: upstream_sampled + local_root"
);
let exported_names: Vec<&str> = exported_batch
.spans
.iter()
.map(|s| s.name.as_str())
.collect();
assert!(
exported_names.contains(&"test_upstream_sampled"),
"Should export upstream sampled span"
);
assert!(
exported_names.contains(&"test_local_root"),
"Should export local root span"
);
assert!(
!exported_names.contains(&"test_upstream_unsampled"),
"Should NOT export upstream unsampled span"
);
}
println!("✅ W3C COMPLIANCE VERIFIED: Current implementation is SOUND");
println!(" • Honors upstream sampled=1 decisions");
println!(" • Honors upstream sampled=0 decisions");
println!(" • Applies local sampling to root spans only");
println!(" • No incorrect override of upstream decisions");
}