use crate::{ConformanceTest, RuntimeInterface, TestCategory, TestMeta, TestResult, checkpoint};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::time::Duration;
pub fn all_tests<RT: RuntimeInterface + Sync>() -> Vec<ConformanceTest<RT>> {
vec![
cp_001_request_phase_continues::<RT>(),
cp_002_drain_phase_cleanup::<RT>(),
]
}
pub fn cp_001_request_phase_continues<RT: RuntimeInterface + Sync>() -> ConformanceTest<RT> {
ConformanceTest::new(
TestMeta {
id: "cp-001".to_string(),
name: "Cancel request phase - task continues until checkpoint".to_string(),
description: "Task should continue executing after cancel request until checkpoint"
.to_string(),
category: TestCategory::Cancel,
tags: vec![
"cancel".to_string(),
"protocol".to_string(),
"request".to_string(),
"checkpoint".to_string(),
],
expected: "Task continues work until timeout cancels it".to_string(),
},
|rt| {
rt.block_on(async {
checkpoint("Starting cancel request phase test", serde_json::json!({}));
let work_done = Arc::new(AtomicUsize::new(0));
let work_done_clone = work_done.clone();
let long_sleep = rt.sleep(Duration::from_millis(100));
let result = rt
.timeout(Duration::from_millis(30), async move {
checkpoint("Task started", serde_json::json!({}));
work_done_clone.store(1, Ordering::Release);
long_sleep.await;
work_done_clone.store(10, Ordering::Release);
"Task completed normally"
})
.await;
let final_work_done = work_done.load(Ordering::Acquire);
checkpoint(
"Request phase test completed",
serde_json::json!({
"work_done": final_work_done,
"task_result": match result {
Ok(_) => "completed",
Err(_) => "timeout"
}
}),
);
if final_work_done == 0 {
return TestResult::failed("Task should have done some work before cancel");
}
match result {
Ok(_) => TestResult::failed("Task should have been cancelled by timeout"),
Err(_) => {
if (1..10).contains(&final_work_done) {
TestResult::passed()
} else {
TestResult::failed("Task should have done partial work before cancel")
}
}
}
})
},
)
}
pub fn cp_002_drain_phase_cleanup<RT: RuntimeInterface + Sync>() -> ConformanceTest<RT> {
ConformanceTest::new(
TestMeta {
id: "cp-002".to_string(),
name: "Cancel drain phase - cleanup execution".to_string(),
description: "Task can perform cleanup after cancel acknowledgment".to_string(),
category: TestCategory::Cancel,
tags: vec![
"cancel".to_string(),
"protocol".to_string(),
"drain".to_string(),
"cleanup".to_string(),
],
expected: "Cleanup can be performed after cancel signal".to_string(),
},
|rt| {
rt.block_on(async {
checkpoint("Starting cancel drain phase test", serde_json::json!({}));
let cleanup_completed = Arc::new(AtomicBool::new(false));
let resource_freed = Arc::new(AtomicBool::new(false));
let cleanup_completed_clone = cleanup_completed.clone();
let resource_freed_clone = resource_freed.clone();
let work_sleep = rt.sleep(Duration::from_millis(100));
let cleanup_sleep = rt.sleep(Duration::from_millis(5));
let result = rt
.timeout(Duration::from_millis(20), async move {
checkpoint("Task started with resources", serde_json::json!({}));
let _simulated_resource = "critical_resource";
work_sleep.await;
"Normal completion"
})
.await;
if result.is_err() {
checkpoint("Cancel detected, starting drain", serde_json::json!({}));
checkpoint("Performing resource cleanup", serde_json::json!({}));
cleanup_sleep.await; resource_freed_clone.store(true, Ordering::Release);
cleanup_completed_clone.store(true, Ordering::Release);
checkpoint("Cleanup completed", serde_json::json!({}));
}
let cleanup_done = cleanup_completed.load(Ordering::Acquire);
let resource_cleaned = resource_freed.load(Ordering::Acquire);
checkpoint(
"Drain phase test completed",
serde_json::json!({
"cleanup_completed": cleanup_done,
"resource_freed": resource_cleaned,
"task_result": match result {
Ok(_) => "completed",
Err(_) => "timeout"
}
}),
);
if !cleanup_done {
return TestResult::failed("Cleanup should have completed");
}
if !resource_cleaned {
return TestResult::failed("Resources should have been freed");
}
if result.is_err() {
TestResult::passed()
} else {
TestResult::failed("Task should have been cancelled")
}
})
},
)
}