use crate::config::{BatchConfig, WheelConfig};
use crate::task::{CallbackWrapper, TimerTask, TimerTaskWithCompletionNotifier};
use crate::wheel::Wheel;
use std::time::Duration;
#[test]
fn test_insert_batch() {
let mut wheel = Wheel::new(WheelConfig::default(), BatchConfig::default());
let handles = wheel.allocate_handles(10);
let mut tasks = Vec::new();
for i in 0..10 {
let callback = CallbackWrapper::new(|| async {});
let task = TimerTask::new_oneshot(Duration::from_millis(100 + i * 10), Some(callback));
let (task_with_notifier, _completion_rx) =
TimerTaskWithCompletionNotifier::from_timer_task(task);
tasks.push(task_with_notifier);
}
wheel
.insert_batch(handles, tasks)
.expect("insert_batch should succeed");
assert!(!wheel.is_empty());
}
#[test]
fn test_cancel_batch() {
let mut wheel = Wheel::new(WheelConfig::default(), BatchConfig::default());
let mut task_ids = Vec::new();
for i in 0..10 {
let callback = CallbackWrapper::new(|| async {});
let task = TimerTask::new_oneshot(Duration::from_millis(100 + i * 10), Some(callback));
let (task_with_notifier, _completion_rx) =
TimerTaskWithCompletionNotifier::from_timer_task(task);
let handle = wheel.allocate_handle();
let task_id = handle.task_id();
wheel.insert(handle, task_with_notifier);
task_ids.push(task_id);
}
assert_eq!(task_ids.len(), 10);
let to_cancel = &task_ids[0..5];
let cancelled_count = wheel.cancel_batch(to_cancel);
assert_eq!(cancelled_count, 5);
let cancelled_again = wheel.cancel_batch(to_cancel);
assert_eq!(cancelled_again, 0);
let remaining = &task_ids[5..10];
let cancelled_remaining = wheel.cancel_batch(remaining);
assert_eq!(cancelled_remaining, 5);
assert!(wheel.is_empty());
}
#[test]
fn test_batch_operations_same_slot() {
let mut wheel = Wheel::new(WheelConfig::default(), BatchConfig::default());
let mut task_ids = Vec::new();
for _ in 0..20 {
let callback = CallbackWrapper::new(|| async {});
let task = TimerTask::new_oneshot(Duration::from_millis(100), Some(callback));
let (task_with_notifier, _completion_rx) =
TimerTaskWithCompletionNotifier::from_timer_task(task);
let handle = wheel.allocate_handle();
let task_id = handle.task_id();
wheel.insert(handle, task_with_notifier);
task_ids.push(task_id);
}
let cancelled_count = wheel.cancel_batch(&task_ids);
assert_eq!(cancelled_count, 20);
assert!(wheel.is_empty());
}
#[test]
fn test_batch_cancel_small_threshold() {
let batch_config = BatchConfig {
small_batch_threshold: 5,
};
let mut wheel = Wheel::new(WheelConfig::default(), batch_config);
let mut task_ids = Vec::new();
for _ in 0..10 {
let callback = CallbackWrapper::new(|| async {});
let task = TimerTask::new_oneshot(Duration::from_millis(100), Some(callback));
let (task_with_notifier, _rx) = TimerTaskWithCompletionNotifier::from_timer_task(task);
let handle = wheel.allocate_handle();
let task_id = handle.task_id();
wheel.insert(handle, task_with_notifier);
task_ids.push(task_id);
}
let cancelled = wheel.cancel_batch(&task_ids[0..3]);
assert_eq!(cancelled, 3);
let cancelled = wheel.cancel_batch(&task_ids[3..10]);
assert_eq!(cancelled, 7);
assert!(wheel.is_empty()); }
#[test]
fn test_empty_batch_operations() {
let mut wheel = Wheel::new(WheelConfig::default(), BatchConfig::default());
wheel
.insert_batch(vec![], vec![])
.expect("empty insert_batch should succeed");
let cancelled = wheel.cancel_batch(&[]);
assert_eq!(cancelled, 0);
let postponed = wheel.postpone_batch(vec![]);
assert_eq!(postponed, 0);
}
#[test]
fn test_insert_batch_length_mismatch() {
let mut wheel = Wheel::new(WheelConfig::default(), BatchConfig::default());
let mut handles = Vec::new();
let mut tasks = Vec::new();
for i in 0..3 {
let handle = wheel.allocate_handle();
handles.push(handle);
if i < 2 {
let callback = CallbackWrapper::new(|| async {});
let task = TimerTask::new_oneshot(Duration::from_millis(100), Some(callback));
let (task_with_notifier, _rx) = TimerTaskWithCompletionNotifier::from_timer_task(task);
tasks.push(task_with_notifier);
}
}
let result = wheel.insert_batch(handles, tasks);
assert!(result.is_err());
if let Err(crate::error::TimerError::BatchLengthMismatch {
handles_len,
tasks_len,
}) = result
{
assert_eq!(handles_len, 3);
assert_eq!(tasks_len, 2);
} else {
panic!("Expected BatchLengthMismatch error");
}
}