Skip to content

Commit 69015e7

Browse files
authored
Ensure disconnect can be called multiple times (#129)
* Ensure `disconnect` can be called even when the radio is disconnected * Add unit tests
1 parent b741478 commit 69015e7

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

tests/test_application.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from .async_mock import AsyncMock, MagicMock, patch, sentinel
33

44
import pytest
5+
import logging
56
import zigpy.types as zigpy_types
67
import zigpy.exceptions
78

@@ -96,3 +97,41 @@ async def mock_get_network_state():
9697

9798
with pytest.raises(zigpy.exceptions.FormationFailure):
9899
await app.form_network()
100+
101+
102+
@pytest.mark.asyncio
103+
async def test_disconnect_success(app):
104+
api = MagicMock()
105+
106+
app._api = api
107+
await app.disconnect()
108+
109+
api.close.assert_called_once()
110+
assert app._api is None
111+
112+
113+
@pytest.mark.asyncio
114+
async def test_disconnect_failure(app, caplog):
115+
api = MagicMock()
116+
api.disconnect = MagicMock(side_effect=RuntimeError("Broken"))
117+
118+
app._api = api
119+
120+
with caplog.at_level(logging.WARNING):
121+
await app.disconnect()
122+
123+
assert "disconnect" in caplog.text
124+
125+
api.close.assert_called_once()
126+
assert app._api is None
127+
128+
129+
@pytest.mark.asyncio
130+
async def test_disconnect_multiple(app):
131+
app._api = None
132+
133+
await app.disconnect()
134+
await app.disconnect()
135+
await app.disconnect()
136+
137+
assert app._api is None

zigpy_zigate/zigbee/application.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,15 @@ async def connect(self):
4949

5050
async def disconnect(self):
5151
# TODO: how do you stop the network? Is it possible?
52-
await self._api.reset(wait=False)
5352

54-
if self._api:
55-
self._api.close()
56-
self._api = None
53+
if self._api is not None:
54+
try:
55+
await self._api.reset(wait=False)
56+
except Exception as e:
57+
LOGGER.warning("Failed to reset before disconnect: %s", e)
58+
finally:
59+
self._api.close()
60+
self._api = None
5761

5862
async def start_network(self):
5963
# TODO: how do you start the network? Is it always automatically started?

0 commit comments

Comments
 (0)