use descartes_core::{Execute, Executor, SimTime, Simulation, Task, TaskHandle};
use std::sync::{Arc, Mutex};
use std::time::Duration;
#[test]
fn test_task_execution_in_simulation() {
let mut sim = Simulation::default();
let executed = Arc::new(Mutex::new(false));
let executed_clone = executed.clone();
let _handle: TaskHandle<()> = sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(100)),
move |_scheduler| {
*executed_clone.lock().unwrap() = true;
},
);
Executor::timed(SimTime::from_duration(Duration::from_millis(200))).execute(&mut sim);
assert!(*executed.lock().unwrap());
}
#[test]
fn test_timeout_task_in_simulation() {
let mut sim = Simulation::default();
let timeout_fired = Arc::new(Mutex::new(false));
let timeout_clone = timeout_fired.clone();
let _handle = sim.timeout(
SimTime::from_duration(Duration::from_millis(50)),
move |_scheduler| {
*timeout_clone.lock().unwrap() = true;
},
);
Executor::timed(SimTime::from_duration(Duration::from_millis(100))).execute(&mut sim);
assert!(*timeout_fired.lock().unwrap());
}
#[test]
fn test_task_cancellation() {
let mut sim = Simulation::default();
let executed = Arc::new(Mutex::new(false));
let executed_clone = executed.clone();
let handle = sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(100)),
move |_scheduler| {
*executed_clone.lock().unwrap() = true;
},
);
let cancelled = sim.cancel_task(handle);
assert!(cancelled);
Executor::timed(SimTime::from_duration(Duration::from_millis(200))).execute(&mut sim);
assert!(!*executed.lock().unwrap());
}
#[test]
fn test_multiple_tasks_execution_order() {
let mut sim = Simulation::default();
let execution_order = Arc::new(Mutex::new(Vec::new()));
let order1 = execution_order.clone();
sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(100)),
move |_scheduler| {
order1.lock().unwrap().push(1);
},
);
let order2 = execution_order.clone();
sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(50)),
move |_scheduler| {
order2.lock().unwrap().push(2);
},
);
let order3 = execution_order.clone();
sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(150)),
move |_scheduler| {
order3.lock().unwrap().push(3);
},
);
Executor::timed(SimTime::from_duration(Duration::from_millis(200))).execute(&mut sim);
let order = execution_order.lock().unwrap();
assert_eq!(*order, vec![2, 1, 3]);
}
#[test]
fn test_task_scheduling_from_within_task() {
let mut sim = Simulation::default();
let execution_count = Arc::new(Mutex::new(0));
let count_clone = execution_count.clone();
sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(50)),
move |scheduler| {
*count_clone.lock().unwrap() += 1;
let count_inner = count_clone.clone();
scheduler.schedule_closure(
SimTime::from_duration(Duration::from_millis(50)),
move |_scheduler| {
*count_inner.lock().unwrap() += 1;
},
);
},
);
Executor::timed(SimTime::from_duration(Duration::from_millis(200))).execute(&mut sim);
assert_eq!(*execution_count.lock().unwrap(), 2);
}
#[test]
fn test_task_with_return_value() {
let mut sim = Simulation::default();
let handle = sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(50)),
|_scheduler| -> i32 { 42 },
);
Executor::timed(SimTime::from_duration(Duration::from_millis(100))).execute(&mut sim);
let result = sim.get_task_result(handle);
assert_eq!(result, Some(42));
}
#[test]
fn test_custom_task_implementation() {
struct CounterTask {
count: i32,
}
impl Task for CounterTask {
type Output = i32;
fn execute(self, _scheduler: &mut descartes_core::Scheduler) -> Self::Output {
self.count * 2
}
}
let mut sim = Simulation::default();
let task = CounterTask { count: 21 };
let handle = sim.schedule_task(SimTime::from_duration(Duration::from_millis(50)), task);
Executor::timed(SimTime::from_duration(Duration::from_millis(100))).execute(&mut sim);
let result = sim.get_task_result(handle);
assert_eq!(result, Some(42));
}
#[test]
fn test_tasks_mixed_with_components() {
use descartes_core::{Component, Key};
#[derive(Debug)]
enum TestEvent {
Ping,
}
struct TestComponent {
ping_count: i32,
}
impl Component for TestComponent {
type Event = TestEvent;
fn process_event(
&mut self,
_self_id: Key<Self::Event>,
event: &Self::Event,
scheduler: &mut descartes_core::Scheduler,
) {
match event {
TestEvent::Ping => {
self.ping_count += 1;
scheduler.schedule_closure(
SimTime::from_duration(Duration::from_millis(25)),
|_scheduler| {
},
);
}
}
}
}
let mut sim = Simulation::default();
let component = TestComponent { ping_count: 0 };
let component_key = sim.add_component(component);
sim.schedule(
SimTime::from_duration(Duration::from_millis(50)),
component_key,
TestEvent::Ping,
);
let task_executed = Arc::new(Mutex::new(false));
let task_clone = task_executed.clone();
sim.schedule_closure(
SimTime::from_duration(Duration::from_millis(100)),
move |_scheduler| {
*task_clone.lock().unwrap() = true;
},
);
Executor::timed(SimTime::from_duration(Duration::from_millis(200))).execute(&mut sim);
let final_component = sim
.remove_component::<TestEvent, TestComponent>(component_key)
.unwrap();
assert_eq!(final_component.ping_count, 1);
assert!(*task_executed.lock().unwrap());
}