use std::collections::HashSet;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use tokio::time::timeout;
use trace_id::{get_trace_id, with_trace_id, TraceId};
#[tokio::test]
async fn test_concurrent_id_generation_uniqueness() {
const THREAD_COUNT: usize = 10;
const IDS_PER_THREAD: usize = 1000;
let ids = Arc::new(Mutex::new(HashSet::new()));
let mut handles = vec![];
for _ in 0..THREAD_COUNT {
let ids_clone = Arc::clone(&ids);
let handle = tokio::spawn(async move {
let mut local_ids = Vec::new();
for _ in 0..IDS_PER_THREAD {
let trace_id = TraceId::new();
local_ids.push(trace_id.as_str().to_string());
}
let mut global_ids = ids_clone.lock().unwrap();
for id in local_ids {
assert!(global_ids.insert(id), "发现重复的trace_id");
}
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap();
}
let final_ids = ids.lock().unwrap();
assert_eq!(final_ids.len(), THREAD_COUNT * IDS_PER_THREAD);
}
#[tokio::test]
async fn test_concurrent_context_management() {
const CONCURRENT_TASKS: usize = 100;
let mut handles = vec![];
for i in 0..CONCURRENT_TASKS {
let handle = tokio::spawn(async move {
let expected_id = format!("test-trace-id-{i:03}");
let trace_id = TraceId::from_string_validated(&format!(
"{:0<32}",
expected_id.chars().take(32).collect::<String>()
))
.unwrap_or_default();
let expected_trace_id_str = trace_id.as_str().to_string();
let result = with_trace_id(trace_id.clone(), async move {
let trace_id_clone = trace_id.clone();
let current_id = get_trace_id();
assert_eq!(current_id.as_str(), trace_id_clone.as_str());
tokio::time::sleep(Duration::from_millis(1)).await;
let current_id_after = get_trace_id();
assert_eq!(current_id_after.as_str(), trace_id_clone.as_str());
trace_id_clone.as_str().to_string()
})
.await;
assert_eq!(result, expected_trace_id_str);
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap();
}
}
#[tokio::test]
async fn test_high_frequency_validation() {
const VALIDATION_COUNT: usize = 10000;
const CONCURRENT_TASKS: usize = 10;
let valid_ids = vec![
"0af7651916cd43dd8448eb211c80319c",
"1234567890abcdef1234567890abcdef",
"fedcba0987654321fedcba0987654321",
];
let invalid_ids = vec![
"short",
"toolongtraceidentifierthatexceeds32chars",
"0AF7651916CD43DD8448EB211C80319C", "0af7651916cd43dd8448eb211c80319g", "00000000000000000000000000000000", ];
let mut handles = vec![];
for _ in 0..CONCURRENT_TASKS {
let valid_ids_clone = valid_ids.clone();
let invalid_ids_clone = invalid_ids.clone();
let handle = tokio::spawn(async move {
for _ in 0..VALIDATION_COUNT / CONCURRENT_TASKS {
for valid_id in &valid_ids_clone {
let result = TraceId::from_string_validated(valid_id);
assert!(result.is_some(), "有效ID验证失败: {valid_id}");
}
for invalid_id in &invalid_ids_clone {
let result = TraceId::from_string_validated(invalid_id);
assert!(result.is_none(), "无效ID验证应该失败: {invalid_id}");
}
}
});
handles.push(handle);
}
let timeout_result = timeout(Duration::from_secs(30), async {
for handle in handles {
handle.await.unwrap();
}
})
.await;
assert!(timeout_result.is_ok(), "高频验证测试超时");
}
#[tokio::test]
async fn test_memory_stability() {
const ITERATIONS: usize = 10000;
for _ in 0..ITERATIONS {
let _trace_id = TraceId::new();
let _valid = TraceId::from_string_validated("0af7651916cd43dd8448eb211c80319c");
let _invalid = TraceId::from_string_validated("invalid");
let test_id = TraceId::new();
let _result = with_trace_id(test_id, async { get_trace_id() }).await;
}
}
#[tokio::test]
async fn test_edge_cases() {
assert!(TraceId::from_string_validated("").is_none());
let max_length_str = "a".repeat(1000);
assert!(TraceId::from_string_validated(&max_length_str).is_none());
let special_chars = "0af7651916cd43dd8448eb211c80319\0";
assert!(TraceId::from_string_validated(special_chars).is_none());
let unicode_str = "0af7651916cd43dd8448eb211c80319中";
assert!(TraceId::from_string_validated(unicode_str).is_none());
let short_by_one = "0af7651916cd43dd8448eb211c80319";
let long_by_one = "0af7651916cd43dd8448eb211c80319ca";
assert!(TraceId::from_string_validated(short_by_one).is_none());
assert!(TraceId::from_string_validated(long_by_one).is_none());
}
#[test]
fn test_atomic_counter_thread_safety() {
const THREAD_COUNT: usize = 10;
const IDS_PER_THREAD: usize = 1000;
let handles: Vec<_> = (0..THREAD_COUNT)
.map(|_| {
thread::spawn(|| {
let mut ids = Vec::new();
for _ in 0..IDS_PER_THREAD {
ids.push(TraceId::new());
}
ids
})
})
.collect();
let mut all_ids = HashSet::new();
for handle in handles {
let thread_ids = handle.join().unwrap();
for id in thread_ids {
assert!(
all_ids.insert(id.as_str().to_string()),
"发现重复的trace_id"
);
}
}
assert_eq!(all_ids.len(), THREAD_COUNT * IDS_PER_THREAD);
}