From bdd425e6c90840c4a7cdaab55776168aacd07da2 Mon Sep 17 00:00:00 2001 From: Nail Sharipov Date: Wed, 30 Sep 2026 15:07:17 +0300 Subject: [PATCH 1/2] reduce tests time execution --- iOverlay/src/core/point_location.rs | 2 +- iOverlay/src/mesh/float/outline/offset.rs | 8 ++--- iOverlay/tests/critical_hypotheses_tests.rs | 4 +-- iOverlay/tests/dynamic_tests.rs | 35 +++++++++---------- iOverlay/tests/ocg_tests.rs | 2 +- iOverlay/tests/output_consistency_tests.rs | 2 +- iOverlay/tests/predicate_cell_oracle_tests.rs | 2 +- iOverlay/tests/resolved_geometry_tests.rs | 5 +++ iOverlay/tests/slice_tests.rs | 2 +- iOverlay/tests/stroke_coverage_tests.rs | 6 ++-- 10 files changed, 36 insertions(+), 32 deletions(-) diff --git a/iOverlay/src/core/point_location.rs b/iOverlay/src/core/point_location.rs index ce1d58a6..54faf000 100644 --- a/iOverlay/src/core/point_location.rs +++ b/iOverlay/src/core/point_location.rs @@ -318,7 +318,7 @@ mod tests { #[test] fn random_simplified_contours_match_contains_point_in_50_by_50_space() { - for iteration in 0..256_u64 { + for iteration in 0..96_u64 { let seed = next_test_seed(iteration); let mut rng = TestRng::new(seed); let contour_count = rng.range_usize(1, 4); diff --git a/iOverlay/src/mesh/float/outline/offset.rs b/iOverlay/src/mesh/float/outline/offset.rs index 9444425e..b53cc364 100644 --- a/iOverlay/src/mesh/float/outline/offset.rs +++ b/iOverlay/src/mesh/float/outline/offset.rs @@ -1140,7 +1140,7 @@ mod tests { #[test] fn test_random_0() { let style = OutlineStyle::new(10.0); - for _ in 0..100 { + for _ in 0..16 { let shapes = random_float(100.0, 100).simplify_shape(FillRule::NonZero); let base_area = shapes.area(); let outline_shapes = shapes.outline(&style); @@ -1153,7 +1153,7 @@ mod tests { fn test_random_1() { let join_angle = core::f64::consts::PI / 3.0; let style = OutlineStyle::new(10.0).line_join(LineJoin::Round(join_angle)); - for _ in 0..100 { + for _ in 0..16 { let shapes = random_float(100.0, 100).simplify_shape(FillRule::NonZero); let base_area = shapes.area(); let outline_shapes = shapes.outline(&style); @@ -1165,7 +1165,7 @@ mod tests { #[test] fn test_random_2() { let style = OutlineStyle::new(-10.0); - for _ in 0..100 { + for _ in 0..16 { let shapes = random_float(100.0, 100).simplify_shape(FillRule::NonZero); let base_area = shapes.area(); let outline_shapes = shapes.outline(&style); @@ -1178,7 +1178,7 @@ mod tests { fn test_random_3() { let join_angle = core::f64::consts::PI / 3.0; let style = OutlineStyle::new(-10.0).line_join(LineJoin::Round(join_angle)); - for _ in 0..100 { + for _ in 0..16 { let shapes = random_float(100.0, 100).simplify_shape(FillRule::NonZero); let base_area = shapes.area(); let outline_shapes = shapes.outline(&style); diff --git a/iOverlay/tests/critical_hypotheses_tests.rs b/iOverlay/tests/critical_hypotheses_tests.rs index 07e0472e..81867b29 100644 --- a/iOverlay/tests/critical_hypotheses_tests.rs +++ b/iOverlay/tests/critical_hypotheses_tests.rs @@ -100,7 +100,7 @@ fn hypothesis_integer_engines_agree_near_i16_limits() { state = state.wrapping_mul(6364136223846793005).wrapping_add(1); ((state >> 32) % 32768) as i32 - 16384 }; - for case in 0..2000 { + for case in 0..512 { let subj: Vec<_> = (0..3 + case % 8).map(|_| [next(), next()]).collect(); let clip: Vec<_> = (0..3 + case % 7).map(|_| [next(), next()]).collect(); for rule in [ @@ -171,7 +171,7 @@ fn hypothesis_predicates_agree_with_boolean_results_on_dense_inputs() { state = state.wrapping_mul(6364136223846793005).wrapping_add(1); ((state >> 32) % 17) as i32 - 8 }; - for case in 0..5000 { + for case in 0..1500 { let subj: Vec<_> = (0..3 + case % 8).map(|_| IntPoint::new(next(), next())).collect(); let clip: Vec<_> = (0..3 + case % 7).map(|_| IntPoint::new(next(), next())).collect(); for fill_rule in [ diff --git a/iOverlay/tests/dynamic_tests.rs b/iOverlay/tests/dynamic_tests.rs index 6dcf6e46..2894c039 100644 --- a/iOverlay/tests/dynamic_tests.rs +++ b/iOverlay/tests/dynamic_tests.rs @@ -45,7 +45,7 @@ mod tests { let result = graph.extract_shapes(OverlayRule::Union, &mut Default::default()); assert!(!result.is_empty()); } - a += 0.01 + a += 0.1 } r += 0.02 } @@ -73,7 +73,7 @@ mod tests { graph.validate(); let _ = graph.extract_shapes(OverlayRule::Xor, &mut Default::default()); } - a += 0.005 + a += 0.05 } } } @@ -100,7 +100,7 @@ mod tests { graph.validate(); let _ = graph.extract_shapes(OverlayRule::Xor, &mut Default::default()); } - a += 0.005 + a += 0.05 } } } @@ -127,7 +127,7 @@ mod tests { graph.validate(); let _ = graph.extract_shapes(OverlayRule::Xor, &mut Default::default()); } - a += 0.005 + a += 0.05 } } } @@ -257,7 +257,7 @@ mod tests { assert!(!result.is_empty()); } } - r += 0.001; + r += 0.005; } } } @@ -288,7 +288,7 @@ mod tests { let result = graph.extract_shapes(OverlayRule::Union, &mut Default::default()); assert!(!result.is_empty()); } - a += 0.005 + a += 0.05 } r += 0.01 * s } @@ -329,20 +329,19 @@ mod tests { fn test_11_as() { let n = 6; let scale = scale_for::(100.0); + // random_polygon is deterministic; one case per solver and integer type is enough. + let subj_path = random_polygon::(100.0, 0.0, n, scale); + let clip_path = random_polygon::(100.0, 0.5 * PI, n, scale); for &solver in SOLVERS.iter() { - for _ in 0..2000 { - let subj_path = random_polygon::(100.0, 0.0, n, scale); - let clip_path = random_polygon::(100.0, 0.5 * PI, n, scale); - let mut overlay = Overlay::new_custom(2 * n, Default::default(), solver); + let mut overlay = Overlay::new_custom(2 * n, Default::default(), solver); - overlay.add_contour(&subj_path, ShapeType::Subject); - overlay.add_contour(&clip_path, ShapeType::Clip); + overlay.add_contour(&subj_path, ShapeType::Subject); + overlay.add_contour(&clip_path, ShapeType::Clip); - if let Some(graph) = overlay.build_graph_view(FillRule::NonZero) { - graph.validate(); - let result = graph.extract_shapes(OverlayRule::Union, &mut Default::default()); - assert!(!result.is_empty()); - } + if let Some(graph) = overlay.build_graph_view(FillRule::NonZero) { + graph.validate(); + let result = graph.extract_shapes(OverlayRule::Union, &mut Default::default()); + assert!(!result.is_empty()); } } } @@ -403,7 +402,7 @@ mod tests { let paths_count = 3; let mut subj_paths = Vec::with_capacity(paths_count); - for _ in 0..100_000 { + for _ in 0..10_000 { subj_paths.clear(); let x_range = 0..=8; let y_range = -8..=8; diff --git a/iOverlay/tests/ocg_tests.rs b/iOverlay/tests/ocg_tests.rs index 127a41f5..82a20ff2 100644 --- a/iOverlay/tests/ocg_tests.rs +++ b/iOverlay/tests/ocg_tests.rs @@ -710,7 +710,7 @@ mod tests { #[test] fn test_random_self_intersections() { - for seed in 0..128 { + for seed in (0..128).step_by(8) { random_self_intersections(seed, 1, 12); random_self_intersections(seed ^ 0x9e37_79b9_7f4a_7c15, 2, 20); random_self_intersections(seed ^ 0xd1b5_4a32_d192_ed03, 3, 28); diff --git a/iOverlay/tests/output_consistency_tests.rs b/iOverlay/tests/output_consistency_tests.rs index d424e453..b54bc2d9 100644 --- a/iOverlay/tests/output_consistency_tests.rs +++ b/iOverlay/tests/output_consistency_tests.rs @@ -26,7 +26,7 @@ fn flat_and_vector_outputs_match_shapes_with_area_filtering() { seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); ((seed >> 32) % 41) as i32 - 20 }; - for case in 0..1000 { + for case in 0..750 { let a: Vec<_> = (0..3 + case % 8).map(|_| IntPoint::new(next(), next())).collect(); let b: Vec<_> = (0..3 + case % 9).map(|_| IntPoint::new(next(), next())).collect(); for threshold in [0, 1, 10, 50] { diff --git a/iOverlay/tests/predicate_cell_oracle_tests.rs b/iOverlay/tests/predicate_cell_oracle_tests.rs index 62309825..05ef0bc3 100644 --- a/iOverlay/tests/predicate_cell_oracle_tests.rs +++ b/iOverlay/tests/predicate_cell_oracle_tests.rs @@ -39,7 +39,7 @@ fn predicates_match_filled_cells_after_contour_cancellation() { seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); (seed >> 32) as usize }; - for case in 0..1200 { + for case in 0..600 { let mut contours = [Vec::new(), Vec::new()]; let mut counts = [[0_i32; 64]; 2]; for side in 0..2 { diff --git a/iOverlay/tests/resolved_geometry_tests.rs b/iOverlay/tests/resolved_geometry_tests.rs index da028134..0f544724 100644 --- a/iOverlay/tests/resolved_geometry_tests.rs +++ b/iOverlay/tests/resolved_geometry_tests.rs @@ -48,6 +48,11 @@ fn dense_boolean_output_has_resolved_edges_and_correct_point_locations() { let b: Vec<_> = (0..20 + case % 40) .map(|_| IntPoint::new(next(), next())) .collect(); + // Keep 48 original inputs across the full size range. A stride of five + // retains all 3 solvers x 4 overlay rules x 4 fill rules. + if case % 5 != 0 { + continue; + } let mut overlay = Overlay::from_subj_and_clip(&a, &b); overlay.solver = [Solver::LIST, Solver::TREE, Solver::FRAG][case % 3]; overlay.options.ogc = true; diff --git a/iOverlay/tests/slice_tests.rs b/iOverlay/tests/slice_tests.rs index c19671ff..f3914235 100644 --- a/iOverlay/tests/slice_tests.rs +++ b/iOverlay/tests/slice_tests.rs @@ -474,7 +474,7 @@ mod tests { #[test] fn test_random_4() { - for _ in 0..50000 { + for _ in 0..10_000 { let path = random_polygon(8, 8); let lines = random_lines(8, 8); diff --git a/iOverlay/tests/stroke_coverage_tests.rs b/iOverlay/tests/stroke_coverage_tests.rs index 1df61d37..4109e6f7 100644 --- a/iOverlay/tests/stroke_coverage_tests.rs +++ b/iOverlay/tests/stroke_coverage_tests.rs @@ -51,7 +51,7 @@ fn round_strokes_cover_vertex_disks() { seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); ((seed >> 32) % 21) as f64 - 10.0 }; - for case in 0..2000 { + for case in 0..1000 { let path: Vec<_> = (0..3 + case % 8).map(|_| [next(), next()]).collect(); let style = StrokeStyle::new(4.0) .math(math) @@ -142,7 +142,7 @@ fn variable_strokes_cover_interpolated_disks() { seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); ((seed >> 32) % 41) as f64 - 20.0 }; - for case in 0..3000 { + for case in 0..1800 { let path: Vec<_> = (0..2 + case % 8) .map(|_| StrokeVertex::new([next(), next()], next() + 20.0)) .collect(); @@ -202,7 +202,7 @@ fn variable_strokes_do_not_fill_outside_interpolated_disks() { seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); ((seed >> 32) % 41) as f64 - 20.0 }; - for case in 0..500 { + for case in 0..350 { let path: Vec<_> = (0..2 + case % 8) .map(|_| StrokeVertex::new([next(), next()], next() + 20.0)) .collect(); From be2b1fbe70e1acde5268002c3002babae8c428a2 Mon Sep 17 00:00:00 2001 From: Nail Sharipov Date: Sat, 3 Oct 2026 09:55:43 +0300 Subject: [PATCH 2/2] add multithreading test to ci --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 95b9a4be..334f556a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,7 +47,7 @@ jobs: tool: cargo-tarpaulin - name: Run coverage working-directory: iOverlay - run: cargo tarpaulin --out Lcov + run: cargo tarpaulin --features allow_multithreading --out Lcov - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 with: