Spooky / quantum /tests /test_pathformulation.py
JavideuS's picture
Deploy 7d1d5a0
a115eaf verified
Raw History Blame Contribute Delete
3.45 kB
"""
Coverage for PathfindingProblem's construction-time feasibility guards: a
robot's start/goal that is out of bounds, on an obstacle, or an unknown
graph node, or a start_time that leaves no time to plan within an explicit
horizon, must be rejected at construction time (InfeasibleProblemError),
not discovered later as a cryptic var_limit crash, a silently-unsatisfiable
QUBO, or a failed benchmark run.
"""
import pytest
from quantum.map import Grid, Graph
from quantum.robotConfiguration import RobotConfig
from quantum.pathFormulation import PathfindingProblem, InfeasibleProblemError
def _grid():
return Grid(3, 3, obstacles=[(1, 1)])
def test_valid_start_and_goal_construct_without_error():
robot = RobotConfig("a", start=(0, 0), goal=(2, 2))
problem = PathfindingProblem(robot, grid=_grid())
assert problem.robots["a"].start == (0, 0)
def test_start_on_obstacle_raises():
robot = RobotConfig("a", start=(1, 1), goal=(2, 2))
with pytest.raises(InfeasibleProblemError, match="obstacle"):
PathfindingProblem(robot, grid=_grid())
def test_goal_on_obstacle_raises():
robot = RobotConfig("a", start=(0, 0), goal=(1, 1))
with pytest.raises(InfeasibleProblemError, match="obstacle"):
PathfindingProblem(robot, grid=_grid())
@pytest.mark.parametrize("start", [(-1, 0), (3, 0), (0, -1), (0, 3)])
def test_out_of_bounds_start_raises(start):
robot = RobotConfig("a", start=start, goal=(2, 2))
with pytest.raises(InfeasibleProblemError, match="out of bounds"):
PathfindingProblem(robot, grid=_grid())
def test_out_of_bounds_goal_raises():
robot = RobotConfig("a", start=(0, 0), goal=(5, 5))
with pytest.raises(InfeasibleProblemError, match="out of bounds"):
PathfindingProblem(robot, grid=_grid())
def test_one_bad_robot_among_several_still_raises():
robots = [
RobotConfig("good", start=(0, 0), goal=(0, 2)),
RobotConfig("bad", start=(1, 1), goal=(2, 0)),
]
with pytest.raises(InfeasibleProblemError, match="'bad'"):
PathfindingProblem(robots, grid=_grid())
def _graph():
return Graph(nodes=[(0, 0), (0, 1), (1, 1)], edges=[(0, 1), (1, 2)])
def test_valid_graph_node_ids_construct_without_error():
robot = RobotConfig("a", start=0, goal=2)
problem = PathfindingProblem(robot, graph=_graph())
assert problem.robots["a"].goal == 2
@pytest.mark.parametrize("goal", [-1, 3, 999])
def test_out_of_range_graph_node_id_raises(goal):
robot = RobotConfig("a", start=0, goal=goal)
with pytest.raises(InfeasibleProblemError, match="does not exist"):
PathfindingProblem(robot, graph=_graph())
def test_start_time_beyond_horizon_raises():
robot = RobotConfig("a", start=(0, 0), goal=(2, 2), start_time=5)
with pytest.raises(InfeasibleProblemError, match="leaves no time"):
PathfindingProblem(robot, grid=_grid(), T=5)
def test_start_time_at_horizon_raises():
"""start_time == T leaves a zero-length window -- also infeasible, not
just start_time > T."""
robot = RobotConfig("a", start=(0, 0), goal=(2, 2), start_time=4)
with pytest.raises(InfeasibleProblemError, match="leaves no time"):
PathfindingProblem(robot, grid=_grid(), T=4)
def test_start_time_within_horizon_is_fine():
robot = RobotConfig("a", start=(0, 0), goal=(2, 2), start_time=2)
problem = PathfindingProblem(robot, grid=_grid(), T=6)
assert problem.robots["a"].T == 4