diff --git a/src/zino/tasks/linkstatetask.py b/src/zino/tasks/linkstatetask.py index 44c0ef7ea..6f2e2af8a 100644 --- a/src/zino/tasks/linkstatetask.py +++ b/src/zino/tasks/linkstatetask.py @@ -49,13 +49,15 @@ async def run(self): def _update_interfaces(self, new_attrs: SparseWalkResponse): for index, row in new_attrs.items(): - self._update_single_interface(row) + try: + self._update_single_interface(row) + except CollectedInterfaceDataIsNotSaneError as error: + _logger.error(error) def _update_single_interface(self, row: dict[str, Any]): data = BaseInterfaceRow(*(row.get(attr) for attr in BASE_POLL_LIST)) if not data.is_sane(): - _logger.info("%s: skipping unknown interface for lack of complete data set: %r", self.device.name, data) - return + raise CollectedInterfaceDataIsNotSaneError(self.device.name, data) port = self._get_or_create_port(data.index) port.ifdescr = data.descr @@ -140,3 +142,10 @@ def _update_ifalias(self, port: Port, data: BaseInterfaceRow): class MissingInterfaceTableData(Exception): def __init__(self, router, port, variable): super().__init__(f"No {variable} from {router} for port {port}") + + +class CollectedInterfaceDataIsNotSaneError(Exception): + def __init__(self, device: str, interface: BaseInterfaceRow): + self.device = device + self.interface = interface + super().__init__(f"Collected interface data from {device} is not sane enough to process: {interface!r}") diff --git a/tests/tasks/test_linkstatetask.py b/tests/tasks/test_linkstatetask.py index cc5d930ff..a093c4b01 100644 --- a/tests/tasks/test_linkstatetask.py +++ b/tests/tasks/test_linkstatetask.py @@ -1,10 +1,12 @@ import pytest from zino.config.models import PollDevice +from zino.oid import OID from zino.state import ZinoState from zino.statemodels import Port from zino.tasks.linkstatetask import ( BaseInterfaceRow, + CollectedInterfaceDataIsNotSaneError, LinkStateTask, MissingInterfaceTableData, ) @@ -58,6 +60,22 @@ def test_when_interface_state_is_missing_update_state_should_raise_exception(sel with pytest.raises(MissingInterfaceTableData): task_with_dummy_device._update_state(data=row, port=port, row=empty_state_row) + def test_when_interface_data_is_empty_update_single_interface_should_raise_exception(self, task_with_dummy_device): + with pytest.raises(CollectedInterfaceDataIsNotSaneError): + task_with_dummy_device._update_single_interface({}) + + def test_when_interface_data_is_empty_update_interfaces_should_keep_processing(self, task_with_dummy_device): + assert ( + task_with_dummy_device._update_interfaces( + { + OID(".1"): {}, + OID(".2"): {}, + OID(".3"): {}, + } + ) + is None + ) + class TestBaseInterfaceRow: def test_when_index_is_missing_is_sane_should_return_false(self):