mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 00:50:46 +08:00
Stamp local_as on peer/route/evpn results and discover (local_as, neighbor/vrf) pairs from config_bgp_peer so each router bgp process is collected separately. Co-authored-by: Cursor <cursoragent@cursor.com>
112 lines
4.1 KiB
Python
112 lines
4.1 KiB
Python
"""Discover CLI/parse cache reuse across collect profiles."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from netx_api.biz_state import discover as disc_mod
|
|
from netx_api.biz_state.discover import clear_discover_cache, discover_params
|
|
from netx_api.biz_state.profiles import get_profile
|
|
|
|
|
|
class DiscoverCacheTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
clear_discover_cache()
|
|
|
|
def tearDown(self) -> None:
|
|
clear_discover_cache()
|
|
|
|
def test_shared_bgp_peer_discover_reuses_cli(self) -> None:
|
|
v4 = get_profile("zte.bgp_vpnv4_neighbor_in")
|
|
v6 = get_profile("zte.bgp_vpnv6_neighbor_in")
|
|
assert v4 is not None and v6 is not None
|
|
self.assertEqual(v4.placeholders[0].discover_profile_id, "zte.config_bgp_peer")
|
|
self.assertEqual(v6.placeholders[0].discover_profile_id, "zte.config_bgp_peer")
|
|
|
|
records = [
|
|
{
|
|
"local_as": "64900",
|
|
"afi": "vpnv4",
|
|
"vrf": "",
|
|
"neighbor": "10.0.0.1",
|
|
"remote_as": "65001",
|
|
},
|
|
{
|
|
"local_as": "64900",
|
|
"afi": "vpnv6",
|
|
"vrf": "",
|
|
"neighbor": "FC00::1",
|
|
"remote_as": "65002",
|
|
},
|
|
]
|
|
db = MagicMock()
|
|
|
|
with (
|
|
patch.object(disc_mod, "resolve_cli_target", return_value=({"vendor": "zte"}, {"vendor": "zte", "device_type": "zte_zxros"})),
|
|
patch.object(disc_mod, "cli_creds_skip_reason", return_value=None),
|
|
patch.object(disc_mod, "open_netmiko_connection", return_value=MagicMock()) as open_conn,
|
|
patch.object(disc_mod, "disable_target_paging"),
|
|
patch.object(disc_mod, "send_show_command", return_value="raw-bgp") as send_cmd,
|
|
patch.object(disc_mod, "close_netmiko_connection"),
|
|
patch.object(disc_mod, "get_parser", return_value=True),
|
|
patch.object(
|
|
disc_mod,
|
|
"run_parser",
|
|
return_value=(records, {}, ()),
|
|
) as run_parser,
|
|
):
|
|
first = discover_params(
|
|
db,
|
|
source="managed",
|
|
ne_id="ne1",
|
|
collect_profile_id="zte.bgp_vpnv4_neighbor_in",
|
|
placeholder="neighbor",
|
|
)
|
|
self.assertTrue(first["ok"])
|
|
self.assertFalse(first.get("cache_hit"))
|
|
self.assertTrue(first.get("pair_mode"))
|
|
self.assertEqual(len(first["candidates"]), 1)
|
|
self.assertEqual(
|
|
first["candidates"][0]["bindings"],
|
|
{"neighbor": "10.0.0.1", "local_as": "64900"},
|
|
)
|
|
self.assertEqual(open_conn.call_count, 1)
|
|
self.assertEqual(send_cmd.call_count, 1)
|
|
self.assertEqual(run_parser.call_count, 1)
|
|
|
|
second = discover_params(
|
|
db,
|
|
source="managed",
|
|
ne_id="ne1",
|
|
collect_profile_id="zte.bgp_vpnv6_neighbor_in",
|
|
placeholder="neighbor",
|
|
)
|
|
self.assertTrue(second["ok"])
|
|
self.assertTrue(second.get("cache_hit"))
|
|
self.assertEqual(len(second["candidates"]), 1)
|
|
self.assertEqual(
|
|
second["candidates"][0]["bindings"],
|
|
{"neighbor": "FC00::1", "local_as": "64900"},
|
|
)
|
|
# Same discover profile → no second SSH/parse
|
|
self.assertEqual(open_conn.call_count, 1)
|
|
self.assertEqual(send_cmd.call_count, 1)
|
|
self.assertEqual(run_parser.call_count, 1)
|
|
|
|
forced = discover_params(
|
|
db,
|
|
source="managed",
|
|
ne_id="ne1",
|
|
collect_profile_id="zte.bgp_vpnv4_neighbor_in",
|
|
placeholder="neighbor",
|
|
force_refresh=True,
|
|
)
|
|
self.assertTrue(forced["ok"])
|
|
self.assertFalse(forced.get("cache_hit"))
|
|
self.assertEqual(open_conn.call_count, 2)
|
|
self.assertEqual(send_cmd.call_count, 2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|