mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 03:10:46 +08:00
Allow compare templates to split one collected metric into filtered sheets.
BGP/ISIS (and any other metric) can share a metric_id with distinct sheet_id + row_filters; drop conflicting bgp state_or_pfx and keep state/pfx_rcd. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
88b7558a48
commit
a65c9fc420
17 changed files with 745 additions and 230 deletions
|
|
@ -27,6 +27,55 @@ PORT_OVERRIDE = {
|
|||
|
||||
|
||||
class ParseExpectSetTests(unittest.TestCase):
|
||||
def test_items_sheet_id_bucket(self):
|
||||
got = parse_expect_set(
|
||||
{
|
||||
"items": [
|
||||
{"metric_id": "bgp_peer", "sheet_id": "bgp_peer.vpnv4", "key": "1.1.1.1"},
|
||||
{"metric_id": "bgp_peer", "sheet_id": "bgp_peer.ipv4", "key": "2.2.2.2"},
|
||||
]
|
||||
}
|
||||
)
|
||||
self.assertEqual(got["bgp_peer.vpnv4"], {"1.1.1.1"})
|
||||
self.assertEqual(got["bgp_peer.ipv4"], {"2.2.2.2"})
|
||||
self.assertNotIn("bgp_peer", got)
|
||||
|
||||
def test_expect_keys_prefer_sheet_id(self):
|
||||
expect = parse_expect_set(
|
||||
{
|
||||
"items": [
|
||||
{"metric_id": "bgp_peer", "sheet_id": "bgp_peer.vpnv4", "key": "1.1.1.1"},
|
||||
{"metric_id": "bgp_peer", "key": "9.9.9.9"},
|
||||
]
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
expect_keys_for_metric(
|
||||
expect, metric_id="bgp_peer", iface_fields=[], sheet_id="bgp_peer.vpnv4"
|
||||
),
|
||||
{"1.1.1.1"},
|
||||
)
|
||||
self.assertEqual(
|
||||
expect_keys_for_metric(expect, metric_id="bgp_peer", iface_fields=[]),
|
||||
{"9.9.9.9"},
|
||||
)
|
||||
|
||||
def test_override_for_sheet_prefers_sheet_id(self):
|
||||
from netx_api.biz_migration.evaluate import override_for_sheet
|
||||
|
||||
overrides = [
|
||||
{"metric_id": "bgp_peer", "status_fields": ["state"]},
|
||||
{"metric_id": "bgp_peer", "sheet_id": "bgp_peer.vpnv4", "status_fields": ["state", "pfx_rcd"]},
|
||||
]
|
||||
hit = override_for_sheet(
|
||||
overrides, sheet_id="bgp_peer.vpnv4", metric_id="bgp_peer"
|
||||
)
|
||||
self.assertEqual(hit["status_fields"], ["state", "pfx_rcd"])
|
||||
legacy = override_for_sheet(
|
||||
overrides, sheet_id="bgp_peer.ipv4", metric_id="bgp_peer"
|
||||
)
|
||||
self.assertEqual(legacy["status_fields"], ["state"])
|
||||
|
||||
def test_ports_go_to_interface_brief(self):
|
||||
got = parse_expect_set({"ports": ["gei-1", "gei-2", ""]})
|
||||
self.assertEqual(got["interface_brief"], {"gei-1", "gei-2"})
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from netx_api.biz_state.compare_rules import (
|
|||
arp_dynamic_row_filters,
|
||||
effective_compare_fields,
|
||||
effective_display_fields,
|
||||
eval_leaf_filter,
|
||||
normalize_value,
|
||||
values_equal,
|
||||
)
|
||||
|
|
@ -314,6 +315,57 @@ class CompareDiffPagingTests(unittest.TestCase):
|
|||
|
||||
|
||||
class CompareSheetDefaultsTests(unittest.TestCase):
|
||||
def test_contains_filter_op(self) -> None:
|
||||
row = {"af": "IPv4,IPv6"}
|
||||
self.assertTrue(eval_leaf_filter(row, {"field": "af", "op": "contains", "value": "IPv4"}))
|
||||
self.assertTrue(eval_leaf_filter(row, {"field": "af", "op": "contains", "value": "ipv6"}))
|
||||
self.assertFalse(eval_leaf_filter(row, {"field": "af", "op": "contains", "value": "vpn"}))
|
||||
|
||||
def test_zte_default_splits_bgp_and_isis(self) -> None:
|
||||
from netx_api.biz_state.compare_service import _default_zte_status_sheets, sheet_key
|
||||
|
||||
sheets = _default_zte_status_sheets()
|
||||
ids = [sheet_key(s) for s in sheets]
|
||||
self.assertIn("bgp_peer.ipv4", ids)
|
||||
self.assertIn("bgp_peer.vpnv4", ids)
|
||||
self.assertIn("bgp_peer.vpnv6", ids)
|
||||
self.assertIn("isis_adjacency.ipv4", ids)
|
||||
self.assertIn("isis_adjacency.ipv6", ids)
|
||||
# Same source metric may appear multiple times
|
||||
self.assertEqual(sum(1 for s in sheets if s["metric_id"] == "bgp_peer"), 4)
|
||||
vpnv4 = next(s for s in sheets if sheet_key(s) == "bgp_peer.vpnv4")
|
||||
self.assertEqual(vpnv4["row_filters"], [{"field": "afi", "op": "eq", "value": "vpnv4"}])
|
||||
isis4 = next(s for s in sheets if sheet_key(s) == "isis_adjacency.ipv4")
|
||||
self.assertEqual(isis4["row_filters"][0]["op"], "contains")
|
||||
|
||||
def test_normalize_allows_duplicate_metric_with_distinct_sheet_id(self) -> None:
|
||||
from netx_api.biz_state.compare_service import _normalize_sheet, sheet_key
|
||||
|
||||
a = _normalize_sheet(
|
||||
{
|
||||
"sheet_id": "bgp_peer.vpnv4",
|
||||
"title": "BGP VPNv4",
|
||||
"metric_id": "bgp_peer",
|
||||
"key_fields": ["afi", "neighbor"],
|
||||
"compare_fields": ["state"],
|
||||
"row_filters": [{"field": "afi", "op": "eq", "value": "vpnv4"}],
|
||||
}
|
||||
)
|
||||
b = _normalize_sheet(
|
||||
{
|
||||
"sheet_id": "bgp_peer.ipv4",
|
||||
"title": "BGP IPv4",
|
||||
"metric_id": "bgp_peer",
|
||||
"key_fields": ["afi", "neighbor"],
|
||||
"compare_fields": ["state"],
|
||||
"row_filters": [{"field": "afi", "op": "eq", "value": "ipv4"}],
|
||||
}
|
||||
)
|
||||
self.assertIsNotNone(a)
|
||||
self.assertIsNotNone(b)
|
||||
self.assertEqual(a["metric_id"], b["metric_id"])
|
||||
self.assertNotEqual(sheet_key(a), sheet_key(b))
|
||||
|
||||
def test_arp_default_sheet_has_row_filters(self) -> None:
|
||||
from netx_api.biz_state.compare_service import _default_sheet_for_metric
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,12 @@ class ZteStatusParserTests(unittest.TestCase):
|
|||
conn = [r for r in rows if r["state"] == "Connect"]
|
||||
self.assertGreaterEqual(len(est), 3)
|
||||
self.assertGreaterEqual(len(conn), 3)
|
||||
self.assertTrue(all("state_or_pfx" not in r for r in rows))
|
||||
self.assertTrue(all(r["pfx_rcd"].isdigit() for r in est))
|
||||
self.assertTrue(all(r["pfx_rcd"] == "" for r in conn))
|
||||
one = next(r for r in rows if r["neighbor"] == "10.206.63.205")
|
||||
self.assertEqual(one["state"], "Established")
|
||||
self.assertEqual(one["pfx_rcd"], "642")
|
||||
|
||||
ipv4 = _section(self.log, "show bgp ipv4 unicast summary", ("show bgp vpnv6",))
|
||||
rows2 = normalize_bgp_peer(raw_text=ipv4, command="show bgp ipv4 unicast summary")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue