@@ -66,7 +66,7 @@ async def callback(request):
66
66
callback .called = True
67
67
68
68
for response in responses :
69
- await asyncio .sleep (0.1 )
69
+ await asyncio .sleep (0.01 )
70
70
LOGGER .debug ("Replying to %s with %s" , request , response )
71
71
72
72
try :
@@ -86,7 +86,7 @@ async def callback(request):
86
86
callback .call_count += 1
87
87
88
88
for response in responses :
89
- await asyncio .sleep (0.1 )
89
+ await asyncio .sleep (0.01 )
90
90
LOGGER .debug ("Replying to %s with %s" , request , response )
91
91
92
92
try :
@@ -159,19 +159,55 @@ def application(znp_server):
159
159
],
160
160
)
161
161
162
+ active_eps = [100 , 12 , 11 , 8 , 1 ]
163
+
162
164
znp_server .reply_to (
163
165
request = c .ZDO .ActiveEpReq .Req (DstAddr = 0x0000 , NWKAddrOfInterest = 0x0000 ),
164
166
responses = [
165
167
c .ZDO .ActiveEpReq .Rsp (Status = t .Status .Success ),
166
168
c .ZDO .ActiveEpRsp .Callback (
167
- Src = 0x0000 , Status = t .ZDOStatus .SUCCESS , NWK = 0x0000 , ActiveEndpoints = []
169
+ Src = 0x0000 ,
170
+ Status = t .ZDOStatus .SUCCESS ,
171
+ NWK = 0x0000 ,
172
+ ActiveEndpoints = active_eps ,
168
173
),
169
174
],
170
175
)
171
176
172
177
znp_server .reply_to (
173
- request = c .AF .Register .Req (partial = True ),
174
- responses = [c .AF .Register .Rsp (Status = t .Status .Success )],
178
+ request = c .ZDO .ActiveEpReq .Req (DstAddr = 0x0000 , NWKAddrOfInterest = 0x0000 ),
179
+ responses = [
180
+ c .ZDO .ActiveEpReq .Rsp (Status = t .Status .Success ),
181
+ c .ZDO .ActiveEpRsp .Callback (
182
+ Src = 0x0000 ,
183
+ Status = t .ZDOStatus .SUCCESS ,
184
+ NWK = 0x0000 ,
185
+ ActiveEndpoints = active_eps ,
186
+ ),
187
+ ],
188
+ )
189
+
190
+ def on_endpoint_registration (req ):
191
+ assert req .Endpoint not in active_eps
192
+
193
+ active_eps .append (req .Endpoint )
194
+ active_eps .sort (reverse = True )
195
+
196
+ return c .AF .Register .Rsp (Status = t .Status .Success )
197
+
198
+ znp_server .reply_to (
199
+ request = c .AF .Register .Req (partial = True ), responses = [on_endpoint_registration ],
200
+ )
201
+
202
+ def on_endpoint_deletion (req ):
203
+ assert req .Endpoint in active_eps
204
+
205
+ active_eps .remove (req .Endpoint )
206
+
207
+ return c .AF .Delete .Rsp (Status = t .Status .Success )
208
+
209
+ znp_server .reply_to (
210
+ request = c .AF .Delete .Req (partial = True ), responses = [on_endpoint_deletion ],
175
211
)
176
212
177
213
znp_server .reply_to (
@@ -183,12 +219,7 @@ def application(znp_server):
183
219
c .AppConfig .BDBCommissioningNotification .Callback (
184
220
Status = c .app_config .BDBCommissioningStatus .Success ,
185
221
Mode = c .app_config .BDBCommissioningMode .NwkSteering ,
186
- RemainingModes = c .app_config .BDBRemainingCommissioningModes .NONE ,
187
- ),
188
- c .AppConfig .BDBCommissioningNotification .Callback (
189
- Status = c .app_config .BDBCommissioningStatus .NoNetwork ,
190
- Mode = c .app_config .BDBCommissioningMode .NwkSteering ,
191
- RemainingModes = c .app_config .BDBRemainingCommissioningModes .NONE ,
222
+ RemainingModes = c .app_config .BDBCommissioningMode .NONE ,
192
223
),
193
224
],
194
225
)
@@ -206,30 +237,71 @@ def application(znp_server):
206
237
responses = [c .Sys .OSALNVWrite .Rsp (Status = t .Status .Success )],
207
238
)
208
239
240
+ znp_server .reply_to (
241
+ request = c .Sys .OSALNVRead .Req (Id = NwkNvIds .HAS_CONFIGURED_ZSTACK3 , Offset = 0 ),
242
+ responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .Success , Value = b"\x55 " )],
243
+ )
244
+
245
+ znp_server .reply_to (
246
+ request = c .Util .GetDeviceInfo .Req (),
247
+ responses = [
248
+ c .Util .GetDeviceInfo .Rsp (
249
+ Status = t .Status .Success ,
250
+ IEEE = t .EUI64 ([0x00 , 0x12 , 0x4B , 0x00 , 0x1C , 0xAA , 0xAC , 0x5C ]),
251
+ NWK = t .NWK (0xFFFE ),
252
+ DeviceType = t .DeviceLogicalType (7 ),
253
+ DeviceState = t .DeviceState .InitializedNotStarted ,
254
+ AssociatedDevices = [],
255
+ )
256
+ ],
257
+ )
258
+
259
+ znp_server .reply_to (
260
+ request = c .ZDO .StartupFromApp .Req (partial = True ),
261
+ responses = [
262
+ c .ZDO .StartupFromApp .Rsp (State = c .zdo .StartupState .RestoredNetworkState ),
263
+ c .ZDO .StateChangeInd .Callback (State = t .DeviceState .StartedAsCoordinator ),
264
+ ],
265
+ )
266
+
209
267
return app , znp_server
210
268
211
269
212
270
@pytest_mark_asyncio_timeout (seconds = 5 )
213
- async def test_application_startup (application ):
271
+ async def test_application_startup_endpoints (application ):
214
272
app , znp_server = application
215
273
216
- num_endpoints = 5
217
274
endpoints = []
275
+ znp_server .callback_for_response (c .AF .Register .Req (partial = True ), endpoints .append )
218
276
219
- def register_endpoint (request ):
220
- nonlocal num_endpoints
221
- num_endpoints -= 1
277
+ await app .startup (auto_form = False )
222
278
223
- endpoints . append ( request )
279
+ assert len ( endpoints ) == 5
224
280
225
- if num_endpoints < 0 :
226
- raise RuntimeError ("Too many endpoints registered" )
227
281
228
- znp_server .callback_for_response (c .AF .Register .Req (partial = True ), register_endpoint )
282
+ @pytest_mark_asyncio_timeout (seconds = 5 )
283
+ async def test_application_startup_failure (application ):
284
+ app , znp_server = application
229
285
230
- await app .startup (auto_form = False )
286
+ # Prevent the fixture's default response
287
+ znp_server ._response_listeners [c .Sys .OSALNVRead .Req .header ].clear ()
231
288
232
- assert len (endpoints ) == 5
289
+ znp_server .reply_once_to (
290
+ request = c .Sys .OSALNVRead .Req (Id = NwkNvIds .HAS_CONFIGURED_ZSTACK3 , Offset = 0 ),
291
+ responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .InvalidParameter , Value = b"" )],
292
+ )
293
+
294
+ # We cannot start the application if Z-Stack is not configured and without auto_form
295
+ with pytest .raises (RuntimeError ):
296
+ await app .startup (auto_form = False )
297
+
298
+ znp_server .reply_once_to (
299
+ request = c .Sys .OSALNVRead .Req (Id = NwkNvIds .HAS_CONFIGURED_ZSTACK3 , Offset = 0 ),
300
+ responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .Success , Value = b"\x00 " )],
301
+ )
302
+
303
+ with pytest .raises (RuntimeError ):
304
+ await app .startup (auto_form = False )
233
305
234
306
235
307
@pytest_mark_asyncio_timeout (seconds = 3 )
@@ -858,17 +930,9 @@ async def test_force_remove(application, mocker):
858
930
async def test_auto_form_unnecessary (application , mocker ):
859
931
app , znp_server = application
860
932
861
- # b"\x55" means that Z-Stack is already configured?
862
- read_zstack_configured = znp_server .reply_once_to (
863
- request = c .Sys .OSALNVRead .Req (Id = NwkNvIds .HAS_CONFIGURED_ZSTACK3 , Offset = 0 ),
864
- responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .Success , Value = b"\x55 " )],
865
- )
866
-
867
933
mocker .patch .object (app , "form_network" )
868
934
869
935
await app .startup (auto_form = True )
870
-
871
- await read_zstack_configured
872
936
assert app .form_network .call_count == 0
873
937
874
938
@@ -881,22 +945,31 @@ async def test_auto_form_necessary(application, mocker):
881
945
mocker .patch .object (app , "_reset" , new = CoroutineMock ())
882
946
883
947
def nvram_writer (req ):
884
- if req .Id in nvram :
885
- raise ValueError ("Unexpected overwrite" )
886
-
887
948
nvram [req .Id ] = req .Value
888
949
889
950
return c .Sys .OSALNVWrite .Rsp (Status = t .Status .Success )
890
951
952
+ def nvram_init (req ):
953
+ nvram [req .Id ] = req .Value
954
+
955
+ return c .Sys .OSALNVItemInit .Rsp (Status = t .Status .Success )
956
+
957
+ # Prevent the fixture's default response
958
+ znp_server ._response_listeners [c .Sys .OSALNVRead .Req .header ].clear ()
959
+
891
960
read_zstack_configured = znp_server .reply_once_to (
892
961
request = c .Sys .OSALNVRead .Req (Id = NwkNvIds .HAS_CONFIGURED_ZSTACK3 , Offset = 0 ),
893
- responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .Success , Value = b"\x00 " )],
962
+ responses = [c .Sys .OSALNVRead .Rsp (Status = t .Status .InvalidParameter , Value = b"" )],
894
963
)
895
964
896
965
znp_server .reply_to (
897
966
request = c .Sys .OSALNVWrite .Req (Offset = 0 , partial = True ), responses = [nvram_writer ]
898
967
)
899
968
969
+ znp_server .reply_to (
970
+ request = c .Sys .OSALNVItemInit .Req (partial = True ), responses = [nvram_init ]
971
+ )
972
+
900
973
znp_server .reply_to (
901
974
request = c .AppConfig .BDBStartCommissioning .Req (
902
975
Mode = c .app_config .BDBCommissioningMode .NwkFormation
@@ -919,8 +992,9 @@ def nvram_writer(req):
919
992
await read_zstack_configured
920
993
921
994
assert app .update_network .call_count == 1
922
- assert app ._reset .call_count == 2
995
+ assert app ._reset .call_count == 1
923
996
997
+ assert nvram [NwkNvIds .HAS_CONFIGURED_ZSTACK3 ] == b"\x55 "
924
998
assert nvram [NwkNvIds .STARTUP_OPTION ] == t .StartupOptions .ClearState .serialize ()
925
999
assert nvram [NwkNvIds .LOGICAL_TYPE ] == t .DeviceLogicalType .Coordinator .serialize ()
926
1000
assert nvram [NwkNvIds .ZDO_DIRECT_CB ] == t .Bool (True ).serialize ()
0 commit comments