From 6f320bafc6aac4ca8b513a29e86aa088ca0d2df6 Mon Sep 17 00:00:00 2001 From: mickaelbegon Date: Wed, 22 Jul 2026 09:52:46 -0400 Subject: [PATCH] Track variational solver convergence --- tests/shard4/test_variational_integrator_examples.py | 2 ++ tests/utils.py | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/shard4/test_variational_integrator_examples.py b/tests/shard4/test_variational_integrator_examples.py index ba7333e57..c90786939 100644 --- a/tests/shard4/test_variational_integrator_examples.py +++ b/tests/shard4/test_variational_integrator_examples.py @@ -30,6 +30,7 @@ def test_variational_pendulum(use_sx): # --- Solve the ocp --- # sol = ocp.solve(Solver.IPOPT()) + TestUtils.assert_solver_success(sol, max_iterations=100) states = sol.decision_states(to_merge=SolutionMerge.NODES) controls = sol.decision_controls(to_merge=SolutionMerge.NODES) @@ -64,6 +65,7 @@ def test_variational_pendulum_with_holonomic_constraints(use_sx): # --- Solve the ocp --- # sol = ocp.solve(Solver.IPOPT()) + TestUtils.assert_solver_success(sol, max_iterations=100) states = sol.decision_states(to_merge=SolutionMerge.NODES) controls = sol.decision_controls(to_merge=SolutionMerge.NODES) diff --git a/tests/utils.py b/tests/utils.py index ecc56c923..ae211261c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -30,6 +30,18 @@ class TestUtils: + @staticmethod + def assert_solver_success(solution: Solution, max_iterations: int | None = None): + """Assert convergence and optionally guard against a large iteration-count regression.""" + assert solution.status == 0, ( + f"Solver did not converge (status={solution.status}, iterations={solution.iterations})" + ) + assert isinstance(solution.iterations, int) and solution.iterations >= 0 + if max_iterations is not None: + assert solution.iterations <= max_iterations, ( + f"Solver iteration regression: {solution.iterations} iterations, expected at most {max_iterations}" + ) + @staticmethod def bioptim_folder() -> str: return TestUtils._capitalize_folder_drive(str(Path(__file__).parent / "../bioptim"))