Skip to content

Commit 2e81f54

Browse files
authored
Sync-up with zigpy new initialization (#105)
* Update zigpy dependency. * Add barebone config schema. Make Watchdog TTL configurable via schema. * Use device config for UART connection. * Implment new zigpy initalization. * Update api tests. * Update application tests. * Update uart tests. * Fix logging formatting. * Update watchdog schema.
1 parent cd489ce commit 2e81f54

File tree

8 files changed

+145
-107
lines changed

8 files changed

+145
-107
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
author_email="[email protected]",
2222
license="GPL-3.0",
2323
packages=find_packages(exclude=["*.tests"]),
24-
install_requires=["pyserial-asyncio", "zigpy-homeassistant>=0.17.0"],
24+
install_requires=["pyserial-asyncio", "zigpy>=0.20.a1"],
2525
tests_require=["pytest", "pytest-asyncio", "asynctest"],
2626
)

tests/test_api.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,37 @@
44
from asynctest import CoroutineMock, mock
55
import pytest
66
import serial
7+
import zigpy.config
78

89
from zigpy_deconz import api as deconz_api, types as t, uart
910
import zigpy_deconz.exception
11+
import zigpy_deconz.zigbee.application
12+
13+
DEVICE_CONFIG = {zigpy.config.CONF_DEVICE_PATH: "/dev/null"}
1014

1115

1216
@pytest.fixture
1317
def api():
14-
api = deconz_api.Deconz()
18+
controller = mock.MagicMock(
19+
spec_set=zigpy_deconz.zigbee.application.ControllerApplication
20+
)
21+
api = deconz_api.Deconz(controller, {zigpy.config.CONF_DEVICE_PATH: "/dev/null"})
1522
api._uart = mock.MagicMock()
1623
return api
1724

1825

19-
def test_set_application(api):
20-
api.set_application(mock.sentinel.app)
21-
assert api._app == mock.sentinel.app
22-
23-
2426
@pytest.mark.asyncio
25-
async def test_connect(monkeypatch):
26-
api = deconz_api.Deconz()
27-
dev = mock.MagicMock()
28-
monkeypatch.setattr(
29-
uart, "connect", mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
27+
async def test_connect():
28+
controller = mock.MagicMock(
29+
spec_set=zigpy_deconz.zigbee.application.ControllerApplication
3030
)
31-
await api.connect(dev, 115200)
31+
api = deconz_api.Deconz(controller, {zigpy.config.CONF_DEVICE_PATH: "/dev/null"})
32+
33+
with mock.patch.object(uart, "connect", new=CoroutineMock()) as conn_mck:
34+
await api.connect()
35+
assert conn_mck.call_count == 1
36+
assert conn_mck.await_count == 1
37+
assert api._uart == conn_mck.return_value
3238

3339

3440
def test_close(api):
@@ -437,14 +443,13 @@ def test_device_state_network_state(data, network_state):
437443

438444
@pytest.mark.asyncio
439445
async def test_reconnect_multiple_disconnects(monkeypatch, caplog):
440-
api = deconz_api.Deconz()
441-
dev = mock.sentinel.uart
446+
api = deconz_api.Deconz(None, DEVICE_CONFIG)
442447
connect_mock = CoroutineMock()
443448
connect_mock.return_value = asyncio.Future()
444449
connect_mock.return_value.set_result(True)
445450
monkeypatch.setattr(uart, "connect", connect_mock)
446451

447-
await api.connect(dev, 115200)
452+
await api.connect()
448453

449454
caplog.set_level(logging.DEBUG)
450455
connected = asyncio.Future()
@@ -463,14 +468,13 @@ async def test_reconnect_multiple_disconnects(monkeypatch, caplog):
463468

464469
@pytest.mark.asyncio
465470
async def test_reconnect_multiple_attempts(monkeypatch, caplog):
466-
api = deconz_api.Deconz()
467-
dev = mock.sentinel.uart
471+
api = deconz_api.Deconz(None, DEVICE_CONFIG)
468472
connect_mock = CoroutineMock()
469473
connect_mock.return_value = asyncio.Future()
470474
connect_mock.return_value.set_result(True)
471475
monkeypatch.setattr(uart, "connect", connect_mock)
472476

473-
await api.connect(dev, 115200)
477+
await api.connect()
474478

475479
caplog.set_level(logging.DEBUG)
476480
connected = asyncio.Future()
@@ -492,22 +496,22 @@ async def test_reconnect_multiple_attempts(monkeypatch, caplog):
492496
async def test_probe_success(mock_connect, mock_device_state):
493497
"""Test device probing."""
494498

495-
res = await deconz_api.Deconz.probe(mock.sentinel.uart, mock.sentinel.baud)
499+
res = await deconz_api.Deconz.probe(DEVICE_CONFIG)
496500
assert res is True
497501
assert mock_connect.call_count == 1
498502
assert mock_connect.await_count == 1
499-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
503+
assert mock_connect.call_args[0][0] is DEVICE_CONFIG
500504
assert mock_device_state.call_count == 1
501505
assert mock_connect.return_value.close.call_count == 1
502506

503507
mock_connect.reset_mock()
504508
mock_device_state.reset_mock()
505509
mock_connect.reset_mock()
506-
res = await deconz_api.Deconz.probe(mock.sentinel.uart, mock.sentinel.baud)
510+
res = await deconz_api.Deconz.probe(DEVICE_CONFIG)
507511
assert res is True
508512
assert mock_connect.call_count == 1
509513
assert mock_connect.await_count == 1
510-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
514+
assert mock_connect.call_args[0][0] is DEVICE_CONFIG
511515
assert mock_device_state.call_count == 1
512516
assert mock_connect.return_value.close.call_count == 1
513517

@@ -525,10 +529,10 @@ async def test_probe_fail(mock_connect, mock_device_state, exception):
525529
mock_device_state.side_effect = exception
526530
mock_device_state.reset_mock()
527531
mock_connect.reset_mock()
528-
res = await deconz_api.Deconz.probe(mock.sentinel.uart, mock.sentinel.baud)
532+
res = await deconz_api.Deconz.probe(DEVICE_CONFIG)
529533
assert res is False
530534
assert mock_connect.call_count == 1
531535
assert mock_connect.await_count == 1
532-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
536+
assert mock_connect.call_args[0][0] is DEVICE_CONFIG
533537
assert mock_device_state.call_count == 1
534538
assert mock_connect.return_value.close.call_count == 1

tests/test_application.py

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import asyncio
22
import logging
3-
from unittest import mock
43

5-
import asynctest
4+
from asynctest import CoroutineMock, mock
65
import pytest
6+
import zigpy.config
77
import zigpy.device
88
from zigpy.types import EUI64
99
import zigpy.zdo.types as zdo_t
@@ -15,10 +15,16 @@
1515

1616

1717
@pytest.fixture
18-
def app(monkeypatch, database_file=None):
19-
app = application.ControllerApplication(
20-
deconz_api.Deconz(), database_file=database_file
18+
def app(database_file=None):
19+
config = application.ControllerApplication.SCHEMA(
20+
{
21+
zigpy.config.CONF_DEVICE: {zigpy.config.CONF_DEVICE_PATH: "/dev/null"},
22+
zigpy.config.CONF_DATABASE: database_file,
23+
}
2124
)
25+
26+
app = application.ControllerApplication(config)
27+
app._api = deconz_api.Deconz(app, config[zigpy.config.CONF_DEVICE])
2228
return app
2329

2430

@@ -168,21 +174,24 @@ def test_rx_unknown_device(app, addr_ieee, addr_nwk, caplog):
168174

169175
@pytest.mark.asyncio
170176
async def test_form_network(app):
171-
app._api.change_network_state = mock.MagicMock(
172-
side_effect=asyncio.coroutine(mock.MagicMock())
173-
)
174-
app._api.device_state = mock.MagicMock(
175-
side_effect=asyncio.coroutine(mock.MagicMock())
177+
app._api.change_network_state = CoroutineMock()
178+
app._api.device_state = CoroutineMock(
179+
return_value=deconz_api.NetworkState.CONNECTED
176180
)
177181

178-
app._api._device_state = deconz_api.DeviceState(2)
182+
app._api._device_state = deconz_api.DeviceState(deconz_api.NetworkState.CONNECTED)
179183
await app.form_network()
180-
assert app._api.device_state.call_count == 0
184+
assert app._api.change_network_state.call_count == 0
185+
assert app._api.change_network_state.await_count == 0
186+
assert app._api.device_state.await_count == 0
181187

182-
app._api._device_state = deconz_api.DeviceState(0)
188+
app._api._device_state = deconz_api.DeviceState(deconz_api.NetworkState.OFFLINE)
183189
application.CHANGE_NETWORK_WAIT = 0.001
184190
with pytest.raises(Exception):
185191
await app.form_network()
192+
assert app._api.change_network_state.call_count == 1
193+
assert app._api.change_network_state.await_count == 1
194+
assert app._api.device_state.await_count == 10
186195
assert app._api.device_state.call_count == 10
187196

188197

@@ -195,26 +204,24 @@ async def _version():
195204
app._api._proto_ver = protocol_ver
196205
return [version]
197206

198-
app._reset_watchdog = mock.MagicMock(
199-
side_effect=asyncio.coroutine(mock.MagicMock())
200-
)
201-
app.form_network = mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
202-
app._api._command = mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
203-
app._api.read_parameter = mock.MagicMock(
204-
side_effect=asyncio.coroutine(mock.MagicMock(return_value=[[0]]))
205-
)
206-
app._api.version = mock.MagicMock(side_effect=_version)
207-
app._api.write_parameter = mock.MagicMock(
208-
side_effect=asyncio.coroutine(mock.MagicMock())
209-
)
207+
app._reset_watchdog = CoroutineMock()
208+
app.form_network = CoroutineMock()
209+
210+
app._api._command = CoroutineMock()
211+
api = deconz_api.Deconz(app, app._config[zigpy.config.CONF_DEVICE])
212+
api.connect = CoroutineMock()
213+
api._command = CoroutineMock()
214+
api.read_parameter = CoroutineMock(return_value=[[0]])
215+
api.version = mock.MagicMock(side_effect=_version)
216+
api.write_parameter = CoroutineMock()
210217

211-
new_mock = mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
212-
monkeypatch.setattr(application.ConBeeDevice, "new", new_mock)
213-
await app.startup(auto_form=False)
214-
assert app.form_network.call_count == 0
215-
assert app._reset_watchdog.call_count == watchdog_cc
216-
await app.startup(auto_form=True)
217-
assert app.form_network.call_count == 1
218+
monkeypatch.setattr(application.ConBeeDevice, "new", CoroutineMock())
219+
with mock.patch.object(application, "Deconz", return_value=api):
220+
await app.startup(auto_form=False)
221+
assert app.form_network.call_count == 0
222+
assert app._reset_watchdog.call_count == watchdog_cc
223+
await app.startup(auto_form=True)
224+
assert app.form_network.call_count == 1
218225

219226

220227
@pytest.mark.asyncio
@@ -514,16 +521,15 @@ async def test_mrequest_send_aps_data_error(app):
514521

515522

516523
@pytest.mark.asyncio
517-
@mock.patch.object(application, "WATCHDOG_TTL", new=1)
518524
async def test_reset_watchdog(app):
519525
"""Test watchdog."""
520-
with asynctest.patch.object(app._api, "write_parameter") as mock_api:
526+
with mock.patch.object(app._api, "write_parameter") as mock_api:
521527
dog = asyncio.ensure_future(app._reset_watchdog())
522528
await asyncio.sleep(0.3)
523529
dog.cancel()
524530
assert mock_api.call_count == 1
525531

526-
with asynctest.patch.object(app._api, "write_parameter") as mock_api:
532+
with mock.patch.object(app._api, "write_parameter") as mock_api:
527533
mock_api.side_effect = zigpy_deconz.exception.CommandError
528534
dog = asyncio.ensure_future(app._reset_watchdog())
529535
await asyncio.sleep(0.3)

tests/test_uart.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44
import serial_asyncio
5+
from zigpy.config import CONF_DEVICE_PATH
56

67
from zigpy_deconz import uart
78

@@ -16,7 +17,6 @@ def gw():
1617
@pytest.mark.asyncio
1718
async def test_connect(monkeypatch):
1819
api = mock.MagicMock()
19-
portmock = mock.MagicMock()
2020

2121
async def mock_conn(loop, protocol_factory, **kwargs):
2222
protocol = protocol_factory()
@@ -25,7 +25,7 @@ async def mock_conn(loop, protocol_factory, **kwargs):
2525

2626
monkeypatch.setattr(serial_asyncio, "create_serial_connection", mock_conn)
2727

28-
await uart.connect(portmock, 57600, api)
28+
await uart.connect({CONF_DEVICE_PATH: "/dev/null"}, api)
2929

3030

3131
def test_send(gw):

0 commit comments

Comments
 (0)