#![cfg(test)]
#![cfg(feature = "metrics")]
use crate::Time;
use crate::observability::otel_structured_concurrency::{
EntityId, OtelStructuredConcurrencyConfig, SpanStorage, SpanType,
};
use std::time::Duration;
fn leak_audit_config() -> OtelStructuredConcurrencyConfig {
OtelStructuredConcurrencyConfig::default().with_global_sample_rate(1.0)
}
#[test]
fn audit_unended_spans_create_obligation_leaks() {
println!("🔍 AUDIT: Span lifecycle obligation leak detection");
let config = leak_audit_config();
let storage = SpanStorage::new(config);
let entity1 = EntityId::region_from_raw(1);
let entity2 = EntityId::region_from_raw(2);
let entity3 = EntityId::region_from_raw(3);
println!("📋 Creating spans without ending them (simulating forgotten .end() calls)");
assert!(storage.create_span(
SpanType::Task,
entity1,
"forgotten_task_span".to_string(),
Time::from_nanos(1000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
assert!(storage.create_span(
SpanType::Region,
entity2,
"forgotten_region_span".to_string(),
Time::from_nanos(2000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
assert!(storage.create_span(
SpanType::Task,
entity3,
"forgotten_task_span_2".to_string(),
Time::from_nanos(3000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
let (created, materialized, _, _, _, _) = storage.stats();
println!(
"📊 Created {} spans, materialized {}",
created, materialized
);
let leaked_spans = storage.detect_obligation_leaks(Duration::ZERO);
assert_eq!(
leaked_spans.len(),
3,
"OBLIGATION LEAK VIOLATION: Expected 3 leaked spans (unended obligations), got {}. \
Per AGENTS.md 'no obligation leaks' rule, unended spans MUST be detected as leaks.",
leaked_spans.len()
);
println!("✅ OBLIGATION LEAK DETECTION VERIFIED");
println!(
" ✓ {} unended spans detected as obligation leaks",
leaked_spans.len()
);
for leak in &leaked_spans {
println!(
" - Leaked span: {:?} (age: {:?})",
leak.entity_id, leak.age
);
}
}
#[test]
fn audit_properly_ended_spans_do_not_leak() {
println!("🔍 AUDIT: Properly ended spans do not create obligation leaks");
let config = leak_audit_config();
let storage = SpanStorage::new(config);
let entity1 = EntityId::region_from_raw(1);
let entity2 = EntityId::region_from_raw(2);
println!("📋 Creating and properly ending spans");
assert!(storage.create_span(
SpanType::Task,
entity1,
"properly_ended_span_1".to_string(),
Time::from_nanos(1000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
assert!(storage.create_span(
SpanType::Region,
entity2,
"properly_ended_span_2".to_string(),
Time::from_nanos(2000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
#[cfg(feature = "metrics")]
let tracer = opentelemetry::global::tracer("test");
#[cfg(not(feature = "metrics"))]
let tracer = ();
storage.end_span(entity1, &tracer);
storage.end_span(entity2, &tracer);
println!("📊 Spans properly ended");
let leaked_spans = storage.detect_obligation_leaks(Duration::ZERO);
assert_eq!(
leaked_spans.len(),
0,
"Properly ended spans should not appear as obligation leaks, got {}",
leaked_spans.len()
);
println!("✅ NO OBLIGATION LEAKS: Properly ended spans do not leak");
}
#[test]
fn audit_current_implementation_detects_leaked_span() {
println!("AUDIT: Verifying current obligation leak detection implementation");
let config = leak_audit_config();
let storage = SpanStorage::new(config);
let entity = EntityId::region_from_raw(1);
assert!(storage.create_span(
SpanType::Task,
entity,
"leaked_span".to_string(),
Time::from_nanos(1000),
#[cfg(feature = "metrics")]
None,
#[cfg(not(feature = "metrics"))]
None,
));
let leaked_spans = storage.detect_obligation_leaks(Duration::ZERO);
assert_eq!(
leaked_spans.len(),
1,
"one unended span should be reported as an obligation leak"
);
assert_eq!(leaked_spans[0].span_name, "leaked_span");
}