Allow blank MT when parsing ZTE ISIS adjacency.

IPv4 rows often omit MT; requiring a token skipped the whole line.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-20 14:03:28 +08:00
parent 5ab08bb9b3
commit d900aca633
2 changed files with 33 additions and 3 deletions

View file

@ -5,10 +5,11 @@ from __future__ import annotations
import re import re
from typing import Any from typing import Any
# MT may be blank (common on IPv4 adjacencies); NSF/AF still follow.
_ISIS_ROW_RE = re.compile( _ISIS_ROW_RE = re.compile(
r"^(?P<iface>\S+)\s+(?P<sys>\S+)\s+(?P<state>\S+)\s+(?P<lev>\S+)\s+" r"^(?P<iface>\S+)\s+(?P<sys>\S+)\s+(?P<state>\S+)\s+(?P<lev>\S+)\s+"
r"(?P<holds>\S+)\s+(?P<snpa>\S+)\s+(?P<pri>\S+)\s+(?P<mt>\S+)\s+" r"(?P<holds>\S+)\s+(?P<snpa>\S+)\s+(?P<pri>\S+)\s+"
r"(?P<nsf>\S+)\s+(?P<af>\S+)\s*$", r"(?:(?P<mt>\S+)\s+)?(?P<nsf>\S+)\s+(?P<af>\S+)\s*$",
re.I, re.I,
) )
_PROCESS_RE = re.compile(r"(?i)^\s*Process\s+ID\s*:\s*(\d+)\s*$") _PROCESS_RE = re.compile(r"(?i)^\s*Process\s+ID\s*:\s*(\d+)\s*$")
@ -51,11 +52,12 @@ def normalize_isis_adjacency(
"holds": m.group("holds")[:32], "holds": m.group("holds")[:32],
"snpa": m.group("snpa")[:64], "snpa": m.group("snpa")[:64],
"pri": m.group("pri")[:16], "pri": m.group("pri")[:16],
"mt": m.group("mt")[:16], "mt": (m.group("mt") or "")[:16],
"nsf": m.group("nsf")[:32], "nsf": m.group("nsf")[:32],
"af": m.group("af")[:64], "af": m.group("af")[:64],
} }
) )
return out return out
normalize_isis_adjacency.RULE_KEYS = RULE_KEYS normalize_isis_adjacency.RULE_KEYS = RULE_KEYS

View file

@ -75,6 +75,34 @@ class ZteStatusParserTests(unittest.TestCase):
up = [r for r in rows if r["state"].upper() == "UP"] up = [r for r in rows if r["state"].upper() == "UP"]
self.assertEqual(len(up), len(rows)) self.assertEqual(len(up), len(rows))
def test_isis_adjacency_empty_mt_ipv4(self) -> None:
"""IPv4 rows often leave MT blank; must still parse NSF/AF."""
text = """
Process ID: 0
Process ID: 1
Interface System id State Lev Holds SNPA(802.2) Pri MT NSF AF
smartgroup107 PAG7_6120HS UP L1 26 PPP - Disable IPv4
smartgroup32766.1 AG4 UP/UP L1L2 27/27 PPP -/- Disable IPv4
smartgroup4501 C3 UP/UP L1L2 30/30 PPP -/- Disable IPv4
smartgroup11 MDN-SGI-P-ZM8SP UP L2 24 PPP - M Disable IPv6
"""
rows = normalize_isis_adjacency(raw_text=text)
self.assertEqual(len(rows), 4)
self.assertTrue(all(r["process_id"] == "1" for r in rows))
v4 = [r for r in rows if r["af"] == "IPv4"]
self.assertEqual(len(v4), 3)
self.assertTrue(all(r["mt"] == "" for r in v4))
self.assertEqual(v4[0]["interface"], "smartgroup107")
self.assertEqual(v4[0]["system_id"], "PAG7_6120HS")
self.assertEqual(v4[0]["state"], "UP")
self.assertEqual(v4[0]["nsf"], "Disable")
self.assertEqual(v4[1]["state"], "UP/UP")
self.assertEqual(v4[1]["pri"], "-/-")
v6 = next(r for r in rows if r["af"] == "IPv6")
self.assertEqual(v6["mt"], "M")
self.assertEqual(v6["nsf"], "Disable")
def test_interface_brief(self) -> None: def test_interface_brief(self) -> None:
text = _section( text = _section(
self.log, self.log,