Update tests, examples, benches
This commit is contained in:
1 parent
bacac903b3
commit
85ccd7e507
89 files changed
+942
-1785
No files matched your search
+18
-35
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::common::task_fn;
|
||||
use dagx::{DagError, DagRunner};
|
||||
use futures::FutureExt;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_result_not_found_error() {
|
||||
@@ -14,11 +15,9 @@ async fn test_result_not_found_error() {
|
||||
assert!(matches!(result, Err(DagError::ResultNotFound { .. })));
|
||||
|
||||
// Run and verify it works after
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(dag.get(&t1).unwrap(), 42);
|
||||
}
|
||||
@@ -34,11 +33,9 @@ async fn test_nested_result_error_handling() {
|
||||
|
||||
let task2 = dag.add_task(task_fn(|_: ()| async { Result::<i32, String>::Ok(42) }));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Both tasks complete successfully (they return Results)
|
||||
assert_eq!(dag.get(&task1).unwrap(), Err("Internal error".to_string()));
|
||||
@@ -51,11 +48,9 @@ async fn test_option_none_not_error() {
|
||||
|
||||
let task = dag.add_task(task_fn(|_: ()| async { None::<i32> }));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// None is a valid result, not an error
|
||||
assert_eq!(dag.get(&task).unwrap(), None);
|
||||
@@ -82,11 +77,9 @@ async fn test_custom_error_types() {
|
||||
})
|
||||
}));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Check custom errors are preserved
|
||||
match dag.get(&task1).unwrap() {
|
||||
@@ -113,11 +106,7 @@ async fn test_error_in_tuple_dependency() {
|
||||
.add_task(task_fn(|(a, b): (i32, i32)| async move { a + b }))
|
||||
.depends_on((&ok_task, &err_task));
|
||||
|
||||
let result = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let result = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert!(dag.get(dependent).is_err());
|
||||
@@ -135,11 +124,7 @@ async fn test_string_panic_vs_structured_panic() {
|
||||
panic!("Formatted panic: value={}, code={}", 42, "ERROR");
|
||||
}));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// Both should result in errors
|
||||
assert!(dag.get(&string_panic).is_err());
|
||||
@@ -159,11 +144,9 @@ async fn test_anyhow_like_error_chain() {
|
||||
outer
|
||||
}));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Get the chained error
|
||||
let result = dag.get(&task).unwrap();
|
||||
|
||||
+13
-40
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::common::task_fn;
|
||||
use dagx::DagRunner;
|
||||
use futures::FutureExt;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -22,11 +23,7 @@ async fn test_linear_error_propagation() {
|
||||
.add_task(task_fn(|x: i32| async move { x * 2 }))
|
||||
.depends_on(t3);
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// t1 succeeds
|
||||
assert_eq!(dag.get(&t1).unwrap(), 1);
|
||||
@@ -65,11 +62,7 @@ async fn test_diamond_error_propagation() {
|
||||
.add_task(task_fn(|(l, r): (i32, i32)| async move { l + r }))
|
||||
.depends_on((&left, &right));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
assert_eq!(dag.get(&source).unwrap(), 100);
|
||||
assert_eq!(dag.get(left).unwrap(), 50);
|
||||
@@ -119,11 +112,7 @@ async fn test_error_stops_at_boundary() {
|
||||
}
|
||||
}));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// Error branch: source runs but dependent doesn't
|
||||
assert!(dag.get(&error_source).is_err());
|
||||
@@ -156,11 +145,7 @@ async fn test_multiple_error_sources_convergence() {
|
||||
.add_task(task_fn(|(_, _, _): (i32, i32, i32)| async { 100 }))
|
||||
.depends_on((&error1, &error2, &success));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// All error sources fail
|
||||
assert!(dag.get(&error1).is_err());
|
||||
@@ -189,11 +174,7 @@ async fn test_error_in_wide_fanout() {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// Source fails
|
||||
assert!(dag.get(&source).is_err());
|
||||
@@ -234,11 +215,9 @@ async fn test_selective_error_propagation() {
|
||||
}))
|
||||
.depends_on(handler);
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Source returns an Err variant (not a panic)
|
||||
assert_eq!(dag.get(&source).unwrap(), Err("Source error".to_string()));
|
||||
@@ -294,11 +273,7 @@ async fn test_error_propagation_timing() {
|
||||
}))
|
||||
.depends_on(&t2);
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
let order = propagation_order.lock().clone();
|
||||
|
||||
@@ -373,11 +348,9 @@ async fn test_partial_branch_failure_propagation() {
|
||||
))
|
||||
.depends_on((&a3, &b3, &c3));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await
|
||||
.ok();
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap))
|
||||
.await
|
||||
.ok();
|
||||
|
||||
// Branch A succeeds
|
||||
assert_eq!(dag.get(a3).unwrap(), 106);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::common::task_fn;
|
||||
use dagx::{DagResult, DagRunner};
|
||||
use futures::FutureExt;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -23,11 +24,7 @@ async fn test_fallback_on_error() -> DagResult<()> {
|
||||
let _selector = dag.add_task(task_fn(|_: ()| async {}));
|
||||
|
||||
// Run DAG
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// Primary should fail
|
||||
assert!(dag.get(&primary).is_err());
|
||||
@@ -63,10 +60,7 @@ async fn test_retry_pattern_simulation() -> DagResult<()> {
|
||||
}
|
||||
}));
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await?;
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// Task completes with error on first "attempt"
|
||||
assert_eq!(dag.get(&task)?, Err("Simulated failure"));
|
||||
@@ -109,10 +103,7 @@ async fn test_circuit_breaker_pattern() -> DagResult<()> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await?;
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// First few tasks fail and open circuit
|
||||
for task in &tasks[0..3] {
|
||||
@@ -144,11 +135,7 @@ async fn test_partial_recovery_with_defaults() -> DagResult<()> {
|
||||
vec![0, 10, 20, 0, 40, 50, 0, 70, 80, 0] // 0 for failed tasks
|
||||
}));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
let result = dag.get(&aggregator)?;
|
||||
assert_eq!(result.len(), 10);
|
||||
@@ -178,10 +165,7 @@ async fn test_error_accumulation_pattern() -> DagResult<()> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await?;
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// Check accumulated errors
|
||||
let error_list = errors.lock().clone();
|
||||
@@ -215,10 +199,7 @@ async fn test_graceful_degradation() -> DagResult<()> {
|
||||
}))
|
||||
.depends_on(&critical);
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await?;
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// Critical path works
|
||||
assert_eq!(dag.get(final_task)?, 15);
|
||||
@@ -249,10 +230,7 @@ async fn test_error_boundary_isolation() -> DagResult<()> {
|
||||
.add_task(task_fn(|x: i32| async move { x + 5 }))
|
||||
.depends_on(b2);
|
||||
|
||||
dag.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await?;
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// Group A fails (returns Err)
|
||||
assert_eq!(dag.get(a2)?, Err("Group A error"));
|
||||
@@ -287,11 +265,7 @@ async fn test_compensation_action() -> DagResult<()> {
|
||||
}
|
||||
}));
|
||||
|
||||
let _ = dag
|
||||
.run(|fut| {
|
||||
tokio::spawn(fut);
|
||||
})
|
||||
.await;
|
||||
let _ = dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await;
|
||||
|
||||
// Action failed
|
||||
assert!(dag.get(&action).is_err());
|
||||
|
||||
Reference in new issue
Block a user