Address soundness hole in cycle prevention
This commit is contained in:
1 parent
4ad88bcd68
commit
f82205baf4
80 files changed
+730
-717
No files matched your search
@@ -12,7 +12,7 @@ async fn test_1000_level_deep_chain() -> DagResult<()> {
|
||||
let dag = DagRunner::new();
|
||||
|
||||
let first = dag.add_task(task_fn(|_: ()| async { 0 }));
|
||||
let mut current = (&first).into(); // Convert to TaskHandle
|
||||
let mut current = first.into(); // Convert to TaskHandle
|
||||
|
||||
for _i in 1..1000 {
|
||||
current = dag
|
||||
@@ -32,7 +32,7 @@ async fn test_deep_chain_with_branches() -> DagResult<()> {
|
||||
let dag = DagRunner::new();
|
||||
|
||||
let first = dag.add_task(task_fn(|_: ()| async { 0 }));
|
||||
let mut main_chain: dagx::TaskHandle<i32> = (&first).into();
|
||||
let mut main_chain: dagx::TaskHandle<i32> = first.into();
|
||||
let mut branches = Vec::new();
|
||||
|
||||
for i in 1..500 {
|
||||
@@ -72,7 +72,7 @@ async fn test_multiple_parallel_deep_chains() -> DagResult<()> {
|
||||
|
||||
for chain_id in 0..8 {
|
||||
let first = dag.add_task(task_fn(move |_: ()| async move { chain_id * 1000 }));
|
||||
let mut current: dagx::TaskHandle<i32> = (&first).into();
|
||||
let mut current: dagx::TaskHandle<i32> = first.into();
|
||||
|
||||
for _ in 0..500 {
|
||||
current = dag
|
||||
@@ -136,7 +136,7 @@ async fn test_deep_chain_execution_order() -> DagResult<()> {
|
||||
}
|
||||
}
|
||||
}));
|
||||
let mut current: dagx::TaskHandle<i32> = (&first).into();
|
||||
let mut current: dagx::TaskHandle<i32> = first.into();
|
||||
|
||||
for expected in 1..100 {
|
||||
current = dag
|
||||
@@ -169,7 +169,7 @@ async fn test_deep_binary_tree() -> DagResult<()> {
|
||||
fn build_tree(dag: &DagRunner, depth: usize, value: i32) -> dagx::TaskHandle<i32> {
|
||||
if depth == 0 {
|
||||
let task = dag.add_task(task_fn(move |_: ()| async move { value }));
|
||||
(&task).into() // Convert TaskBuilder to TaskHandle
|
||||
task.into() // Convert TaskBuilder to TaskHandle
|
||||
} else {
|
||||
let left = build_tree(dag, depth - 1, value * 2);
|
||||
let right = build_tree(dag, depth - 1, value * 2 + 1);
|
||||
@@ -199,8 +199,8 @@ async fn test_fibonacci_chain() -> DagResult<()> {
|
||||
let f0_builder = dag.add_task(task_fn(|_: ()| async { 0i64 }));
|
||||
let f1_builder = dag.add_task(task_fn(|_: ()| async { 1i64 }));
|
||||
|
||||
let mut prev2: dagx::TaskHandle<i64> = (&f0_builder).into();
|
||||
let mut prev1: dagx::TaskHandle<i64> = (&f1_builder).into();
|
||||
let mut prev2: dagx::TaskHandle<i64> = f0_builder.into();
|
||||
let mut prev1: dagx::TaskHandle<i64> = f1_builder.into();
|
||||
|
||||
for _ in 2..50 {
|
||||
let next = dag
|
||||
@@ -226,7 +226,7 @@ async fn test_deep_chain_with_accumulator() -> DagResult<()> {
|
||||
|
||||
// Use a simpler accumulation pattern - just sum
|
||||
let first = dag.add_task(task_fn(|_: ()| async { 0i64 }));
|
||||
let mut current: dagx::TaskHandle<i64> = (&first).into();
|
||||
let mut current: dagx::TaskHandle<i64> = first.into();
|
||||
|
||||
for i in 1..=200 {
|
||||
current = dag
|
||||
@@ -250,8 +250,8 @@ async fn test_zigzag_dependencies() -> DagResult<()> {
|
||||
let a_first = dag.add_task(task_fn(|_: ()| async { 1 }));
|
||||
let b_first = dag.add_task(task_fn(|_: ()| async { 2 }));
|
||||
|
||||
let mut chain_a: dagx::TaskHandle<i32> = (&a_first).into();
|
||||
let mut chain_b: dagx::TaskHandle<i32> = (&b_first).into();
|
||||
let mut chain_a: dagx::TaskHandle<i32> = a_first.into();
|
||||
let mut chain_b: dagx::TaskHandle<i32> = b_first.into();
|
||||
|
||||
for i in 0..100 {
|
||||
if i % 2 == 0 {
|
||||
@@ -287,7 +287,7 @@ async fn test_10000_level_chain_stress() -> DagResult<()> {
|
||||
let dag = DagRunner::new();
|
||||
|
||||
let first = dag.add_task(task_fn(|_: ()| async { 0u64 }));
|
||||
let mut current: dagx::TaskHandle<u64> = (&first).into();
|
||||
let mut current: dagx::TaskHandle<u64> = first.into();
|
||||
|
||||
for _ in 1..10_000 {
|
||||
current = dag
|
||||
|
||||
@@ -13,7 +13,7 @@ async fn test_10000_independent_tasks() -> DagResult<()> {
|
||||
|
||||
let counter = Arc::new(AtomicUsize::new(0));
|
||||
|
||||
let tasks: Vec<_> = (0..10_000)
|
||||
let mut tasks: Vec<_> = (0..10_000)
|
||||
.map(|i| {
|
||||
let counter = counter.clone();
|
||||
dag.add_task(task_fn(move |_: ()| {
|
||||
@@ -32,9 +32,9 @@ async fn test_10000_independent_tasks() -> DagResult<()> {
|
||||
assert_eq!(counter.load(Ordering::Relaxed), 10_000);
|
||||
|
||||
// Spot check some results
|
||||
assert_eq!(dag.get(&tasks[0])?, 0);
|
||||
assert_eq!(dag.get(&tasks[9_999])?, 9_999);
|
||||
assert_eq!(dag.get(&tasks[5_000])?, 5_000);
|
||||
assert_eq!(dag.get(tasks.swap_remove(9_999))?, 9_999);
|
||||
assert_eq!(dag.get(tasks.swap_remove(5_000))?, 5_000);
|
||||
assert_eq!(dag.get(tasks.swap_remove(0))?, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -55,7 +55,7 @@ async fn test_5000_node_pyramid() -> DagResult<()> {
|
||||
0
|
||||
}
|
||||
}));
|
||||
(&task).into()
|
||||
task.into()
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -126,7 +126,7 @@ async fn test_5000_node_pyramid_single_threaded() -> DagResult<()> {
|
||||
0
|
||||
}
|
||||
}));
|
||||
(&task).into()
|
||||
task.into()
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -188,7 +188,10 @@ async fn test_wide_dag_1000_sources_1000_sinks() -> DagResult<()> {
|
||||
|
||||
// Create 1000 source tasks
|
||||
let sources: Vec<_> = (0..1000)
|
||||
.map(|i| dag.add_task(task_fn(move |_: ()| async move { i % 10 })))
|
||||
.map(|i| {
|
||||
dag.add_task(task_fn(move |_: ()| async move { i % 10 }))
|
||||
.into()
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Create 1000 sink tasks, each depending on 3 random sources
|
||||
@@ -238,7 +241,7 @@ async fn test_10000_node_linear_chain_segments() -> DagResult<()> {
|
||||
}
|
||||
}
|
||||
}));
|
||||
let mut current: dagx::TaskHandle<i32> = (&first).into();
|
||||
let mut current: dagx::TaskHandle<i32> = first.into();
|
||||
|
||||
for _i in 1..100 {
|
||||
current = dag
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Tests for type system edge cases and limits
|
||||
|
||||
use crate::common::task_fn;
|
||||
use dagx::{DagResult, DagRunner};
|
||||
use dagx::{DagResult, DagRunner, TaskHandle};
|
||||
use futures::FutureExt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
@@ -22,7 +22,7 @@ async fn test_zero_sized_types_throughout() -> DagResult<()> {
|
||||
let t1 = dag.add_task(task_fn(|_: ()| async { Empty }));
|
||||
|
||||
// Task that also produces ZST (independent since we can't extract custom types)
|
||||
let t2 = dag.add_task(task_fn(|_: ()| async { 42 }));
|
||||
let t2: TaskHandle<_> = dag.add_task(task_fn(|_: ()| async { 42 })).into();
|
||||
|
||||
// Task with PhantomData
|
||||
let _t3 = dag.add_task(task_fn(|_: ()| async {
|
||||
@@ -37,7 +37,7 @@ async fn test_zero_sized_types_throughout() -> DagResult<()> {
|
||||
assert_eq!(val, 42);
|
||||
"success"
|
||||
}))
|
||||
.depends_on(&t2);
|
||||
.depends_on(t2);
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -72,7 +72,7 @@ async fn test_large_value_types() -> DagResult<()> {
|
||||
.add_task(task_fn(|val: usize| async move {
|
||||
val // Just pass through to verify
|
||||
}))
|
||||
.depends_on(&t1);
|
||||
.depends_on(t1);
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -86,12 +86,12 @@ async fn test_unit_type_chains() -> DagResult<()> {
|
||||
// Test chains of unit type operations
|
||||
let dag = DagRunner::new();
|
||||
|
||||
let t1 = dag.add_task(task_fn(|_: ()| async {}));
|
||||
let t2 = dag.add_task(task_fn(|_: ()| async {})).depends_on(&t1);
|
||||
let t1: TaskHandle<_> = dag.add_task(task_fn(|_: ()| async {})).into();
|
||||
let t2 = dag.add_task(task_fn(|_: ()| async {})).depends_on(t1);
|
||||
let t3 = dag.add_task(task_fn(|_: ()| async {})).depends_on(t2);
|
||||
let t4 = dag
|
||||
.add_task(task_fn(|_: ()| async { "done" }))
|
||||
.depends_on(&t3);
|
||||
.depends_on(t3);
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -122,7 +122,7 @@ async fn test_nested_option_result_types() -> DagResult<()> {
|
||||
_ => 0,
|
||||
}
|
||||
}))
|
||||
.depends_on(&t1);
|
||||
.depends_on(t1);
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -146,7 +146,7 @@ async fn test_tuple_of_tuples() -> DagResult<()> {
|
||||
a + b + c + d + e + f + g + h
|
||||
},
|
||||
))
|
||||
.depends_on((&t1, &t2));
|
||||
.depends_on((t1, t2));
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -180,7 +180,7 @@ async fn test_string_types_variety() -> DagResult<()> {
|
||||
std::sync::Arc<&str>,
|
||||
)| async move { format!("{} {} {} {} {} {}", s1, s2, s3, s4, s5, s6) },
|
||||
))
|
||||
.depends_on((&t1, &t2, &t3, &t4, &t5, &t6));
|
||||
.depends_on((t1, t2, t3, t4, t5, t6));
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -209,7 +209,7 @@ async fn test_generic_type_constraints() -> DagResult<()> {
|
||||
format!("{:?} {:?} {:?}", w1, w2, w3)
|
||||
},
|
||||
))
|
||||
.depends_on((&t1, &t2, &t3));
|
||||
.depends_on((t1, t2, t3));
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -235,7 +235,7 @@ async fn test_reference_wrapper_types() -> DagResult<()> {
|
||||
|
||||
let t2 = dag
|
||||
.add_task(task_fn(|val: i32| async move { val * 2 }))
|
||||
.depends_on(&t1);
|
||||
.depends_on(t1);
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -260,7 +260,7 @@ async fn test_array_types() -> DagResult<()> {
|
||||
}
|
||||
sum
|
||||
}))
|
||||
.depends_on((&t1, &t2));
|
||||
.depends_on((t1, t2));
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
@@ -299,7 +299,7 @@ async fn test_enum_variants() -> DagResult<()> {
|
||||
&& matches!(e4, MyEnum::LargeVariant(_))
|
||||
},
|
||||
))
|
||||
.depends_on((&t1, &t2, &t3, &t4));
|
||||
.depends_on((t1, t2, t3, t4));
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ async fn test_zero_sized_type_task() -> DagResult<()> {
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
assert_eq!(dag.get(&task)?, ZeroSized);
|
||||
assert_eq!(dag.get(task)?, ZeroSized);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ async fn test_dag_with_only_source_tasks() -> DagResult<()> {
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
for (i, task) in tasks.iter().enumerate() {
|
||||
for (i, task) in tasks.into_iter().enumerate() {
|
||||
assert_eq!(dag.get(task)?, i);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ async fn test_dag_with_never_type_simulation() -> DagResult<()> {
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
assert_eq!(dag.get(&task)?, Ok(42));
|
||||
assert_eq!(dag.get(task)?, Ok(42));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user