3
3
4
4
import pytest
5
5
6
- from zigpy .types import EUI64
6
+ from zigpy .types import EUI64 , uint16_t
7
7
from zigpy_xbee .api import ModemStatus , XBee
8
8
from zigpy_xbee .zigbee .application import ControllerApplication
9
9
@@ -20,19 +20,22 @@ def test_modem_status(app):
20
20
app .handle_modem_status (ModemStatus (0xEE ))
21
21
22
22
23
- def _test_rx (app , device , deserialized ):
23
+ def _test_rx (app , device , nwk , deserialized ,
24
+ dst_ep = mock .sentinel .dst_ep ,
25
+ cluster_id = mock .sentinel .cluster_id ,
26
+ data = b'' ):
24
27
app .get_device = mock .MagicMock (return_value = device )
25
28
app .deserialize = mock .MagicMock (return_value = deserialized )
26
29
27
30
app .handle_rx (
28
31
b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' ,
29
- mock . sentinel . src_nwk ,
32
+ nwk ,
30
33
mock .sentinel .src_ep ,
31
- mock . sentinel . dst_ep ,
32
- mock . sentinel . cluster_id ,
34
+ dst_ep ,
35
+ cluster_id ,
33
36
mock .sentinel .profile_id ,
34
37
mock .sentinel .rxopts ,
35
- b'' ,
38
+ data ,
36
39
)
37
40
38
41
assert app .deserialize .call_count == 1
@@ -41,7 +44,7 @@ def _test_rx(app, device, deserialized):
41
44
def test_rx (app ):
42
45
device = mock .MagicMock ()
43
46
app .handle_message = mock .MagicMock ()
44
- _test_rx (app , device , (1 , 2 , False , []))
47
+ _test_rx (app , device , mock . sentinel . src_nwk , (1 , 2 , False , []))
45
48
assert app .handle_message .call_count == 1
46
49
assert app .handle_message .call_args == ((
47
50
device ,
@@ -73,16 +76,43 @@ def test_rx_nwk_0000(app):
73
76
assert app ._handle_reply .call_count == 0
74
77
75
78
79
+ def test_rx_unknown_device (app ):
80
+ app ._handle_reply = mock .MagicMock ()
81
+ app .handle_message = mock .MagicMock ()
82
+ app .handle_join = mock .MagicMock ()
83
+ app .get_device = mock .MagicMock (side_effect = KeyError )
84
+ app .handle_rx (
85
+ b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' ,
86
+ 0x1234 ,
87
+ mock .sentinel .src_ep ,
88
+ mock .sentinel .dst_ep ,
89
+ mock .sentinel .cluster_id ,
90
+ mock .sentinel .profile_id ,
91
+ mock .sentinel .rxopts ,
92
+ b''
93
+ )
94
+ assert app .handle_join .call_count == 0
95
+ assert app .get_device .call_count == 1
96
+ assert app .handle_message .call_count == 0
97
+ assert app ._handle_reply .call_count == 0
98
+
99
+
76
100
def test_rx_reply (app ):
77
101
app ._handle_reply = mock .MagicMock ()
78
- _test_rx (app , mock .MagicMock (), (1 , 2 , True , []))
102
+ _test_rx (app , mock .MagicMock (), mock . sentinel . src_nwk , (1 , 2 , True , []))
79
103
assert app ._handle_reply .call_count == 1
80
104
81
105
82
106
def test_rx_failed_deserialize (app , caplog ):
107
+ from zigpy .device import Status as DeviceStatus
108
+
83
109
app ._handle_reply = mock .MagicMock ()
84
110
app .handle_message = mock .MagicMock ()
85
- app .get_device = mock .MagicMock (return_value = mock .sentinel .device )
111
+ nwk = 0x1234
112
+ ieee , _ = EUI64 .deserialize (b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' )
113
+ device = app .add_device (ieee , nwk )
114
+ device .status = DeviceStatus .ENDPOINTS_INIT
115
+ app .get_device = mock .MagicMock (return_value = device )
86
116
app .deserialize = mock .MagicMock (side_effect = ValueError )
87
117
88
118
app .handle_rx (
@@ -102,6 +132,91 @@ def test_rx_failed_deserialize(app, caplog):
102
132
assert app .handle_message .call_count == 0
103
133
104
134
135
+ @pytest .fixture
136
+ def device (app ):
137
+ def _device (new = False , zdo_init = False , nwk = uint16_t (0x1234 )):
138
+ from zigpy .device import Device , Status as DeviceStatus
139
+
140
+ ieee , _ = EUI64 .deserialize (b'\x08 \x07 \x06 \x05 \x04 \x03 \x02 \x01 ' )
141
+ dev = Device (app , ieee , nwk )
142
+ if new :
143
+ dev .status = DeviceStatus .NEW
144
+ elif zdo_init :
145
+ dev .status = DeviceStatus .ZDO_INIT
146
+ else :
147
+ dev .status = DeviceStatus .ENDPOINTS_INIT
148
+ return dev
149
+ return _device
150
+
151
+
152
+ def _device_join (app , dev , data ):
153
+ app .handle_message = mock .MagicMock ()
154
+ app .handle_join = mock .MagicMock ()
155
+
156
+ deserialized = (1 , 2 , False , [])
157
+ dst_ep = 0
158
+ cluster_id = 0x0013
159
+
160
+ _test_rx (app , dev , dev .nwk , deserialized , dst_ep , cluster_id , data )
161
+ assert app .handle_join .call_count == 1
162
+ assert app .handle_message .call_count == 1
163
+
164
+
165
+ def test_device_join_new (app , device ):
166
+ dev = device ()
167
+ data = b'\xee ' + dev .nwk .serialize () + dev .ieee .serialize ()
168
+
169
+ _device_join (app , dev , data )
170
+
171
+
172
+ def test_device_join_inconsistent_nwk (app , device ):
173
+ dev = device ()
174
+ data = b'\xee ' + b'\x01 \x02 ' + dev .ieee .serialize ()
175
+
176
+ _device_join (app , dev , data )
177
+
178
+
179
+ def test_device_join_inconsistent_ieee (app , device ):
180
+ dev = device ()
181
+ data = b'\xee ' + dev .nwk .serialize () + b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 '
182
+
183
+ _device_join (app , dev , data )
184
+
185
+
186
+ def _device_status_new (app , dev ):
187
+ app .handle_join = mock .MagicMock ()
188
+ app .handle_message = mock .MagicMock ()
189
+ app .handle_reply = mock .MagicMock ()
190
+ app .get_device = mock .MagicMock (return_value = dev )
191
+ app .deserialize = mock .MagicMock ()
192
+
193
+ app .handle_rx (
194
+ b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' ,
195
+ dev .nwk ,
196
+ mock .sentinel .src_ep ,
197
+ mock .sentinel .dst_ep ,
198
+ mock .sentinel .cluster_id ,
199
+ mock .sentinel .profile_id ,
200
+ mock .sentinel .rxopts ,
201
+ b'' ,
202
+ )
203
+
204
+ assert app .deserialize .call_count == 0
205
+ assert app .handle_join .call_count == 0
206
+ assert app .handle_message .call_count == 0
207
+ assert app .handle_reply .call_count == 0
208
+
209
+
210
+ def test_handle_rx_device_status_new (app , device ):
211
+ dev = device (new = True )
212
+ _device_status_new (app , dev )
213
+
214
+
215
+ def test_handle_rx_device_status_zdo (app , device ):
216
+ dev = device (zdo_init = True )
217
+ _device_status_new (app , dev )
218
+
219
+
105
220
@pytest .mark .asyncio
106
221
async def test_broadcast (app ):
107
222
(profile , cluster , src_ep , dst_ep , grpid , radius , tsn , data ) = (
@@ -295,7 +410,8 @@ async def test_permit(app):
295
410
async def _test_request (app , do_reply = True , expect_reply = True , ** kwargs ):
296
411
seq = 123
297
412
nwk = 0x2345
298
- app ._devices_by_nwk [nwk ] = 0x22334455
413
+ ieee = EUI64 (b'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' )
414
+ app .add_device (ieee , nwk )
299
415
300
416
def _mock_seq_command (cmdname , ieee , nwk , src_ep , dst_ep , cluster ,
301
417
profile , radius , options , data ):
0 commit comments