"""--rollback: a rip-up that loses connections is undone, leaving no trace.""" from __future__ import annotations from pathlib import Path import pytest from rpmroute.board import build_board from rpmroute.dsn import parse_dsn from rpmroute.route.grid_router import GridRouter from rpmroute.route.pipeline import _rule_clearance_dsn, _rule_width_dsn, route_dsn_board FIXTURES = Path(__file__).resolve().parent.parent / "dsn" / "fixtures" def _routed_router(name): dsn = parse_dsn((FIXTURES / name).read_text()) s = dsn.resolution.value router = GridRouter( build_board(dsn), trace_width=round(_rule_width_dsn(dsn) * s), clearance=round(_rule_clearance_dsn(dsn) * s), rollback=True, ) return router, router.route() @pytest.mark.parametrize("name", ["ripup_needed.dsn", "true_density.dsn", "kicad_routable.dsn"]) def test_occupancy_only_holds_routed_connections(name): router, _ = _routed_router(name) conns = router._conns assert all(conns[i].routed for i in router._cell_owner.values()) assert all(conns[i].routed for claims in router._via_claims.values() for i in claims) assert all(conns[i].routed for claims in router._halo.values() for i in claims) @pytest.mark.parametrize("name", ["ripup_needed.dsn", "true_density.dsn", "kicad_routable.dsn"]) def test_rollback_never_routes_fewer_than_plain_rip_up(name): text = (FIXTURES / name).read_text() plain, _, _ = route_dsn_board(parse_dsn(text), rollback=False) undo, _, _ = route_dsn_board(parse_dsn(text)) assert undo.unrouted <= plain.unrouted