The router began as a port of FreeRouting and has grown its own engine (negotiated congestion, tree nets, exact checks, axis escapes), and 'freeroute' was one letter from the project it no longer follows. The package, module and command are now rpmroute; the freeroute command stays as an alias, and the RPMROUTE / RPMROUTE_ORACLE_JAVA variables fall back to the old FREEROUTE names. Version 2026.10.07. Routing is unchanged: a PCBench board routes to a byte-identical session either way.
79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
"""--orders: route several connection orders and keep the best."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from rpmroute.cli import main
|
|
from rpmroute.route.orders import (
|
|
best_of_orders,
|
|
candidate_seeds,
|
|
promote_failures,
|
|
route_once,
|
|
score,
|
|
)
|
|
|
|
FIXTURES = Path(__file__).resolve().parent.parent / "dsn" / "fixtures"
|
|
# Greedy (no rip-up), the default order strands a net here and seeds 1 to 3 do not.
|
|
RIPUP = (FIXTURES / "ripup_needed.dsn").read_text()
|
|
GREEDY = {"rip_up": False}
|
|
|
|
|
|
def test_the_default_order_is_always_a_candidate_without_a_seed():
|
|
assert candidate_seeds(1) == [None]
|
|
assert candidate_seeds(4) == [None, 0, 1, 2]
|
|
assert candidate_seeds(3, seed=7) == [7, 8, 9]
|
|
|
|
|
|
def test_keeps_the_order_that_leaves_the_fewest_unrouted():
|
|
assert score(route_once(RIPUP, "grid", GREEDY, None)) == (1, 0)
|
|
result, kept, tried = best_of_orders(RIPUP, "grid", GREEDY, orders=3, jobs=2)
|
|
assert kept == 1
|
|
assert score(result) == (0, 0)
|
|
assert tried == [(None, (1, 0)), (0, (1, 0)), (1, (0, 0))]
|
|
|
|
|
|
def test_ties_go_to_the_earlier_candidate():
|
|
# every order routes this board fully, so the default order is kept
|
|
_, kept, tried = best_of_orders(RIPUP, "grid", {}, orders=3, jobs=3)
|
|
assert kept is None
|
|
assert all(s == (0, 0) for _, s in tried)
|
|
|
|
|
|
def test_cli_orders_writes_the_best_session(tmp_path, capsys):
|
|
out = tmp_path / "best.ses"
|
|
rc = main([str(FIXTURES / "ripup_needed.dsn"), "--no-rip-up", "--orders", "3", "-do", str(out)])
|
|
assert rc == 0
|
|
err = capsys.readouterr().err
|
|
assert "tried 3 orders, kept --seed 1" in err
|
|
assert "not routed" not in err
|
|
assert out.read_text().startswith("(session")
|
|
|
|
|
|
def test_promoting_the_failed_connection_routes_it():
|
|
best, rounds = promote_failures(RIPUP, "grid", GREEDY, rounds=3)
|
|
assert rounds == [(1, 0), (0, 0)] # stops once nothing fails
|
|
assert score(best) == (0, 0)
|
|
|
|
|
|
def test_nothing_promoted_is_the_plain_order():
|
|
plain = route_once(RIPUP, "grid", {}, None)
|
|
empty = route_once(RIPUP, "grid", {"route_first": frozenset()}, None)
|
|
assert plain == empty
|
|
|
|
|
|
def test_cli_promote_failures(tmp_path, capsys):
|
|
out = tmp_path / "p.ses"
|
|
rc = main(
|
|
[
|
|
str(FIXTURES / "ripup_needed.dsn"),
|
|
"--no-rip-up",
|
|
"--promote-failures",
|
|
"3",
|
|
"-do",
|
|
str(out),
|
|
]
|
|
)
|
|
assert rc == 0
|
|
assert "2 rounds, unrouted 1, 0" in capsys.readouterr().err
|