Fix the 5 failing netx-topology-mcp tests.

Stale tests (behavior changed intentionally on 2026-08-12):
- Tool count is 16: suggestSinkHubs and classifyTopologyFabricNodes are
  documented public tools; assert them by name.
- compose_views is no longer a public layout action; assert it is
  rejected, and cover the background-job path via orbit_sweep instead.
- Dual-unit petals are nested ellipse bands with a hollow eye, not
  parallel lanes; assert side split, ordering inside the portals and
  zero crossings instead of portal-aligned lane ends.

Real bug (test failed since it was added on 2026-08-09):
press_hot_edges could never reel a long spoke in to its r_use target,
because max_disp (r0*0.55) is smaller than r0 - r_use. Inward pulls along
the spoke cannot fling a leaf across the bbox, so give them a cap of
r0 - r_use. On a 1483-node dev view crossings after the op drop
25501 -> 25346; a 500-node view is unchanged; runtime unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
oliver 2026-10-12 22:16:37 +08:00
parent f301544b99
commit ed820126df
4 changed files with 63 additions and 23 deletions

View file

@ -105,26 +105,54 @@ def test_slim_layout_payload_drops_guide() -> None:
assert len(slim["crossing"]["top_nodes"]) <= 5
def test_compose_background_returns_job_id() -> None:
src = [f"s{i:02d}" for i in range(12)]
def test_compose_views_is_not_public() -> None:
# compose_* was retired from the public surface (dual-unit drain is the main path).
out = _layout_topology_view(
{
"view_id": "full",
"action": "compose_views",
"mode": "apply",
"params": {"source_view_ids": [f"s{i:02d}" for i in range(12)]},
}
)
assert out.get("ok") is False
assert out.get("error") == "unknown_action:compose_views"
def test_orbit_background_returns_job_id() -> None:
graph = {
"ok": True,
"nodes": [
{"fabric_node_id": f"n{i}", "x": float(i * 100), "y": 0.0, "label": f"N{i}"}
for i in range(6)
],
"edges": [
{"id": f"e{i}", "a_node_id": f"n{i}", "b_node_id": f"n{i + 1}"} for i in range(5)
],
}
def fake_start(**kwargs):
assert kwargs["action"] == "compose_views"
assert kwargs["action"] == "orbit_sweep"
assert kwargs["view_id"] == "full"
assert isinstance(kwargs.get("tool_args"), dict)
assert kwargs["tool_args"].get("action") == "compose_views"
tool_args = kwargs.get("tool_args")
assert isinstance(tool_args, dict)
# The worker re-runs the same call synchronously.
assert tool_args["params"].get("_force_sync") is True
assert "background" not in tool_args["params"]
return "abc123job"
with patch("netx_topology_mcp.http_tools.start_job", side_effect=fake_start):
with patch("netx_topology_mcp.http_tools.http_json", return_value={"ok": True, "data": graph}), patch(
"netx_topology_mcp.http_tools.start_job", side_effect=fake_start
):
out = _layout_topology_view(
{
"view_id": "full",
"action": "compose_views",
"action": "orbit_sweep",
"mode": "apply",
"params": {"source_view_ids": src},
"params": {"background": True},
}
)
assert out.get("ok") is True
assert out.get("ok") is True, out
assert out.get("status") == "running"
assert out.get("job_id") == "abc123job"
assert out.get("applied") is False