Skip to content

Commit

Permalink
Gracefully handle neighbors table filling up on startup (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly authored Dec 8, 2023
1 parent ecaf376 commit 83872b1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
31 changes: 26 additions & 5 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ async def test_force_remove(app):
await app.force_remove(sentinel.device)


async def test_restore_neighbours(app):
async def test_restore_neighbours(app, caplog):
"""Test neighbour restoration."""

# FFD, Rx on when idle
Expand All @@ -372,6 +372,10 @@ async def test_restore_neighbours(app):
device_5 = app.add_device(nwk=0x0005, ieee=EUI64.convert("00:00:00:00:00:00:00:05"))
device_5.node_desc = zdo_t.NodeDescriptor(2, 64, 128, 0xBEEF, 82, 82, 0, 82, 0)

# RFD, Rx off when idle (duplicate)
device_6 = app.add_device(nwk=0x0005, ieee=EUI64.convert("00:00:00:00:00:00:00:06"))
device_6.node_desc = zdo_t.NodeDescriptor(2, 64, 128, 0xBEEF, 82, 82, 0, 82, 0)

coord = MagicMock()
coord.ieee = EUI64.convert("aa:aa:aa:aa:aa:aa:aa:aa")

Expand All @@ -384,16 +388,33 @@ async def test_restore_neighbours(app):
zdo_t.Neighbor(ieee=device_3.ieee),
zdo_t.Neighbor(ieee=EUI64.convert("00:00:00:00:00:00:00:04")),
zdo_t.Neighbor(ieee=device_5.ieee),
zdo_t.Neighbor(ieee=device_6.ieee),
]

max_neighbors = 1

def mock_add_neighbour(nwk, ieee, mac_capability_flags):
nonlocal max_neighbors
max_neighbors -= 1

if max_neighbors < 0:
raise zigpy_deconz.exception.CommandError(
deconz_api.Status.FAILURE, "Failure"
)

p = patch.object(app, "_api", spec_set=zigpy_deconz.api.Deconz(None, None))

with p as api_mock:
api_mock.add_neighbour = AsyncMock()
await app.restore_neighbours()
err = zigpy_deconz.exception.CommandError(deconz_api.Status.FAILURE, "Failure")
api_mock.add_neighbour = AsyncMock(side_effect=[None, err, err, err])

with caplog.at_level(logging.DEBUG):
await app.restore_neighbours()

assert caplog.text.count("Failed to add device to neighbor table") == 1

assert api_mock.add_neighbour.call_count == 1
assert api_mock.add_neighbour.await_count == 1
assert api_mock.add_neighbour.call_count == 2
assert api_mock.add_neighbour.await_count == 2


@patch("zigpy_deconz.zigbee.application.DELAY_NEIGHBOUR_SCAN_S", 0)
Expand Down
22 changes: 12 additions & 10 deletions zigpy_deconz/zigbee/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,16 +573,18 @@ async def restore_neighbours(self) -> None:
or descr.is_receiver_on_when_idle
):
continue
LOGGER.debug(
"Restoring %s/0x%04x device as direct child",
device.ieee,
device.nwk,
)
await self._api.add_neighbour(
nwk=device.nwk,
ieee=device.ieee,
mac_capability_flags=descr.mac_capability_flags,
)

LOGGER.debug("Restoring %s as direct child", device)

try:
await self._api.add_neighbour(
nwk=device.nwk,
ieee=device.ieee,
mac_capability_flags=descr.mac_capability_flags,
)
except zigpy_deconz.exception.CommandError as ex:
assert ex.status == Status.FAILURE
LOGGER.debug("Failed to add device to neighbor table: %s", ex)

async def _delayed_neighbour_scan(self) -> None:
"""Scan coordinator's neighbours."""
Expand Down

0 comments on commit 83872b1

Please sign in to comment.