use super::*;
use super::*;
use std::thread;
use std::time::Duration;
#[test]
fn test_trace_context_creation() {
let context = TraceContext::new();
assert!(context.is_sampled());
assert!(context.parent_spanid.is_none());
let child = context.child();
assert_eq!(child.trace_id, context.trace_id);
assert_eq!(child.parent_spanid, Some(context.spanid));
assert_ne!(child.spanid, context.spanid);
}
#[test]
fn test_tracingsystem_creation() {
let config = TracingConfig::default();
let tracing = TracingSystem::new(config).expect("Failed to create tracing system");
let metrics = tracing.get_metrics().expect("Failed to get metrics");
assert_eq!(metrics.spans_started, 0);
assert_eq!(metrics.active_spans, 0);
}
#[test]
fn test_span_lifecycle() {
let config = TracingConfig::default();
let tracing = TracingSystem::new(config).expect("Failed to create tracing system");
{
let span = tracing
.start_span("test_operation")
.expect("Failed to start span");
span.add_attribute("test", "value")
.expect("Failed to add attribute");
span.add_event("test_event", HashMap::new())
.expect("Failed to add event");
let context = span.context().expect("Failed to get context");
assert!(context.is_sampled());
}
thread::sleep(Duration::from_millis(10));
let metrics = tracing.get_metrics().expect("Failed to get metrics");
assert_eq!(metrics.spans_started, 1);
}
#[test]
fn test_span_builder() {
let config = TracingConfig::default();
let tracing = TracingSystem::new(config).expect("Failed to create tracing system");
let span = SpanBuilder::new("test_operation")
.with_kind(SpanKind::Server)
.with_attribute("method", "GET")
.with_component("web_server")
.start(&tracing)
.expect("Failed to start span");
let context = span.context().expect("Failed to get context");
assert!(context.is_sampled());
}
#[test]
fn test_probability_sampler() {
let sampler = ProbabilitySampler::new(0.0);
let context = TraceContext::new();
assert!(!sampler.should_sample(&context, "test"));
let sampler = ProbabilitySampler::new(1.0);
assert!(sampler.should_sample(&context, "test"));
}
#[test]
fn test_console_exporter() {
let exporter = ConsoleExporter::new(false);
let context = TraceContext::new();
let span = Span {
context,
name: "test".to_string(),
kind: SpanKind::Internal,
start_time: SystemTime::now(),
end_time: Some(SystemTime::now()),
status: SpanStatus::Ok,
attributes: HashMap::new(),
events: Vec::new(),
metrics: SpanMetrics::default(),
component: None,
error: None,
};
exporter.export_span(&span).expect("Failed to export span");
}
#[test]
fn test_nested_spans() {
let config = TracingConfig::default();
let tracing = TracingSystem::new(config).expect("Failed to create tracing system");
let parent_span = tracing
.start_span("parent_operation")
.expect("Failed to start parent span");
let parent_context = parent_span.context().expect("Failed to get parent context");
let child_span = SpanBuilder::new("child_operation")
.with_parent(parent_context.clone())
.start(&tracing)
.expect("Failed to start child span");
let child_context = child_span.context().expect("Failed to get child context");
assert_eq!(child_context.trace_id, parent_context.trace_id);
assert_eq!(child_context.parent_spanid, Some(parent_context.spanid));
}
#[test]
fn test_w3c_trace_context() {
let context = TraceContext::new();
let traceparent = context.to_traceparent();
let parts: Vec<&str> = traceparent.split('-').collect();
assert_eq!(parts.len(), 4);
assert_eq!(parts[0], "00"); assert_eq!(parts[3], "01");
let parsed_context =
TraceContext::from_traceparent(&traceparent).expect("Failed to parse traceparent");
assert_eq!(parsed_context.trace_id, context.trace_id);
assert!(parsed_context.is_remote);
assert!(parsed_context.is_sampled());
}
#[test]
fn test_adaptive_sampler() {
let sampler = AdaptiveSampler::new(0.5, 100.0);
let context = TraceContext::new();
for _ in 0..10 {
sampler.should_sample(&context, "test");
}
let (total, sampled, rate) = sampler.get_stats();
assert_eq!(total, 10);
assert!((0.0..=1.0).contains(&rate));
}
#[test]
fn test_rate_limiting_sampler() {
let sampler = RateLimitingSampler::new(5); let context = TraceContext::new();
for i in 0..5 {
assert!(
sampler.should_sample(&context, "test"),
"Sample {i} should be accepted"
);
}
assert!(!sampler.should_sample(&context, "test"));
assert!(!sampler.should_sample(&context, "test"));
}
#[test]
fn test_batch_exporter() {
let console_exporter = ConsoleExporter::new(false);
let batch_exporter = BatchExporter::new(
Box::new(console_exporter),
3, Duration::from_secs(1), );
let context = TraceContext::new();
let span = Span {
context,
name: "test".to_string(),
kind: SpanKind::Internal,
start_time: SystemTime::now(),
end_time: Some(SystemTime::now()),
status: SpanStatus::Ok,
attributes: HashMap::new(),
events: Vec::new(),
metrics: SpanMetrics::default(),
component: None,
error: None,
};
batch_exporter
.export_span(&span)
.expect("Failed to export span");
batch_exporter
.export_span(&span)
.expect("Failed to export span");
batch_exporter
.export_span(&span)
.expect("Failed to export span");
batch_exporter.flush().expect("Failed to flush");
}
#[test]
fn test_resource_attribution() {
let mut attribution = ResourceAttribution::new()
.with_cpu_time(1_000_000) .with_memory_allocation(1024) .with_io_stats(5, 100, 200);
let other = ResourceAttribution::new()
.with_cpu_time(500_000) .with_memory_allocation(512);
attribution.merge(&other);
assert_eq!(attribution.cpu_timens, Some(1_500_000));
assert_eq!(attribution.memory_allocated_bytes, Some(1536));
assert_eq!(attribution.io_operations, Some(5));
}
#[test]
fn test_enhanced_span_metrics() {
let mut metrics = EnhancedSpanMetrics::new();
metrics.add_performance_counter("cache_hits", 150);
metrics.add_performance_counter("cache_misses", 25);
metrics.add_performance_counter("cache_hits", 50);
assert_eq!(metrics.performance_counters.get("cache_hits"), Some(&200));
assert_eq!(metrics.performance_counters.get("cache_misses"), Some(&25));
metrics.resources.cpu_timens = Some(1_000_000); metrics.resources.memory_allocated_bytes = Some(1_048_576); metrics.resources.io_operations = Some(5);
let cost = metrics.get_total_resource_cost();
assert!(cost > 0.0);
}
#[test]
fn test_tracing_version_compatibility() {
let v1_0 = TracingVersion::new(1, 0, 0);
let v1_1 = TracingVersion::new(1, 1, 0);
let v2_0 = TracingVersion::new(2, 0, 0);
assert!(v1_0.is_compatible(&v1_1));
assert!(!v1_1.is_compatible(&v1_0)); assert!(!v1_0.is_compatible(&v2_0));
assert_eq!(v1_0.to_string(), "1.0.0");
}