10
10
import zigpy_znp .types as t
11
11
import zigpy_znp .config as conf
12
12
import zigpy_znp .commands as c
13
- from zigpy_znp .exceptions import InvalidCommandResponse
14
13
15
14
from ..conftest import (
16
15
FORMED_DEVICES ,
@@ -145,10 +144,10 @@ async def test_zigpy_request_failure(device, make_application, mocker):
145
144
mocker .spy (app , "send_packet" )
146
145
147
146
# Fail to turn on the light
148
- with pytest .raises (InvalidCommandResponse ):
147
+ with pytest .raises (DeliveryError ):
149
148
await device .endpoints [1 ].on_off .on ()
150
149
151
- assert app .send_packet .call_count = = 1
150
+ assert app .send_packet .call_count > = 1
152
151
await app .shutdown ()
153
152
154
153
@@ -425,7 +424,7 @@ async def inner():
425
424
426
425
asyncio .create_task (inner ())
427
426
428
- data_req = znp_server .reply_once_to (
427
+ znp_server .reply_to (
429
428
c .AF .DataRequestExt .Req (partial = True ),
430
429
responses = [
431
430
c .AF .DataRequestExt .Rsp (Status = t .Status .SUCCESS ),
@@ -444,7 +443,6 @@ async def inner():
444
443
data = b"\x00 " ,
445
444
)
446
445
447
- await data_req
448
446
await delayed_reply_sent
449
447
450
448
assert app ._znp ._unhandled_command .call_count == 0
@@ -532,9 +530,6 @@ def set_route_discovered(req):
532
530
await was_route_discovered
533
531
await zdo_req
534
532
535
- # 6 accounts for the loopback requests
536
- assert sum (c .value for c in app .state .counters ["Retry_NONE" ].values ()) == 6 + 1
537
-
538
533
await app .shutdown ()
539
534
540
535
@@ -583,15 +578,6 @@ def set_route_discovered(req):
583
578
],
584
579
)
585
580
586
- # Ignore the source routing request as well
587
- znp_server .reply_to (
588
- c .AF .DataRequestSrcRtg .Req (partial = True ),
589
- responses = [
590
- c .AF .DataRequestSrcRtg .Rsp (Status = t .Status .SUCCESS ),
591
- data_confirm_replier ,
592
- ],
593
- )
594
-
595
581
await app .request (
596
582
device = device ,
597
583
profile = 260 ,
@@ -603,75 +589,6 @@ def set_route_discovered(req):
603
589
)
604
590
605
591
await was_route_discovered
606
- assert (
607
- sum (c .value for c in app .state .counters ["Retry_RouteDiscovery" ].values ()) == 1
608
- )
609
-
610
- await app .shutdown ()
611
-
612
-
613
- @pytest .mark .parametrize ("device" , [FormedLaunchpadCC26X2R1 ])
614
- async def test_request_recovery_use_ieee_addr (device , make_application , mocker ):
615
- app , znp_server = make_application (server_cls = device )
616
-
617
- await app .startup (auto_form = False )
618
-
619
- # The data confirm timeout must be shorter than the ARSP timeout
620
- mocker .patch ("zigpy_znp.zigbee.application.DATA_CONFIRM_TIMEOUT" , new = 0.1 )
621
- app ._znp ._config [conf .CONF_ZNP_CONFIG ][conf .CONF_ARSP_TIMEOUT ] = 1
622
-
623
- device = app .add_initialized_device (ieee = t .EUI64 (range (8 )), nwk = 0xABCD )
624
-
625
- was_ieee_addr_used = False
626
-
627
- def data_confirm_replier (req ):
628
- nonlocal was_ieee_addr_used
629
-
630
- if req .DstAddrModeAddress .mode == t .AddrMode .IEEE :
631
- status = t .Status .SUCCESS
632
- was_ieee_addr_used = True
633
- else :
634
- status = t .Status .MAC_NO_ACK
635
-
636
- return c .AF .DataConfirm .Callback (Status = status , Endpoint = 1 , TSN = 1 )
637
-
638
- znp_server .reply_once_to (
639
- c .ZDO .ExtRouteDisc .Req (
640
- Dst = device .nwk , Options = c .zdo .RouteDiscoveryOptions .UNICAST , partial = True
641
- ),
642
- responses = [c .ZDO .ExtRouteDisc .Rsp (Status = t .Status .SUCCESS )],
643
- )
644
-
645
- znp_server .reply_to (
646
- c .AF .DataRequestExt .Req (partial = True ),
647
- responses = [
648
- c .AF .DataRequestExt .Rsp (Status = t .Status .SUCCESS ),
649
- data_confirm_replier ,
650
- ],
651
- )
652
-
653
- # Ignore the source routing request as well
654
- znp_server .reply_to (
655
- c .AF .DataRequestSrcRtg .Req (partial = True ),
656
- responses = [
657
- c .AF .DataRequestSrcRtg .Rsp (Status = t .Status .SUCCESS ),
658
- c .AF .DataConfirm .Callback (Status = t .Status .MAC_NO_ACK , Endpoint = 1 , TSN = 1 ),
659
- ],
660
- )
661
-
662
- await app .request (
663
- device = device ,
664
- profile = 260 ,
665
- cluster = 1 ,
666
- src_ep = 1 ,
667
- dst_ep = 1 ,
668
- sequence = 1 ,
669
- data = b"\x00 " ,
670
- )
671
-
672
- assert was_ieee_addr_used
673
- assert sum (c .value for c in app .state .counters ["Retry_IEEEAddress" ].values ()) == 1
674
-
675
592
await app .shutdown ()
676
593
677
594
@@ -686,7 +603,6 @@ async def test_request_recovery_assoc_remove(
686
603
await app .startup (auto_form = False )
687
604
688
605
mocker .patch ("zigpy_znp.zigbee.application.DATA_CONFIRM_TIMEOUT" , new = 0.1 )
689
- mocker .patch ("zigpy_znp.zigbee.application.REQUEST_ERROR_RETRY_DELAY" , new = 0 )
690
606
691
607
app ._znp ._config [conf .CONF_ZNP_CONFIG ][conf .CONF_ARSP_TIMEOUT ] = 1
692
608
@@ -713,14 +629,6 @@ def data_confirm_replier(req):
713
629
],
714
630
)
715
631
716
- znp_server .reply_to (
717
- c .AF .DataRequestSrcRtg .Req (partial = True ),
718
- responses = [
719
- c .AF .DataRequestSrcRtg .Rsp (Status = t .Status .SUCCESS ),
720
- data_confirm_replier ,
721
- ],
722
- )
723
-
724
632
def assoc_get_with_addr (req ):
725
633
nonlocal assoc_device
726
634
@@ -730,7 +638,7 @@ def assoc_get_with_addr(req):
730
638
731
639
return c .UTIL .AssocGetWithAddress .Rsp (Device = assoc_device )
732
640
733
- did_assoc_get = znp_server .reply_once_to (
641
+ did_assoc_get = znp_server .reply_to (
734
642
c .UTIL .AssocGetWithAddress .Req (IEEE = device .ieee , partial = True ),
735
643
responses = [assoc_get_with_addr ],
736
644
)
@@ -750,12 +658,12 @@ def assoc_remove(req):
750
658
assoc_device = None
751
659
return c .UTIL .AssocRemove .Rsp (Status = t .Status .SUCCESS )
752
660
753
- did_assoc_remove = znp_server .reply_once_to (
661
+ did_assoc_remove = znp_server .reply_to (
754
662
c .UTIL .AssocRemove .Req (IEEE = device .ieee ),
755
663
responses = [assoc_remove ],
756
664
)
757
665
758
- did_assoc_add = znp_server .reply_once_to (
666
+ did_assoc_add = znp_server .reply_to (
759
667
c .UTIL .AssocAdd .Req (
760
668
NWK = device .nwk ,
761
669
IEEE = device .ieee ,
@@ -791,102 +699,23 @@ def assoc_remove(req):
791
699
await req
792
700
793
701
if fw_assoc_remove :
794
- await did_assoc_remove
702
+ assert len ( did_assoc_remove . mock_calls ) >= 1
795
703
796
704
if final_status != t .Status .SUCCESS :
797
705
# The association is re-added on failure
798
- await did_assoc_add
706
+ assert len ( did_assoc_add . mock_calls ) >= 1
799
707
else :
800
- assert not did_assoc_add .done ()
708
+ assert len ( did_assoc_add .mock_calls ) == 0
801
709
elif issubclass (device_cls , FormedLaunchpadCC26X2R1 ):
802
- await did_assoc_get
803
- assert was_route_discovered .call_count >= 1
710
+ assert len (did_assoc_get .mock_calls ) >= 1
804
711
else :
805
712
# Don't even attempt this with older firmwares
806
- assert not did_assoc_get .done ()
713
+ assert len ( did_assoc_get .mock_calls ) == 0
807
714
assert was_route_discovered .call_count == 0
808
715
809
716
await app .shutdown ()
810
717
811
718
812
- @pytest .mark .parametrize ("device" , [FormedLaunchpadCC26X2R1 ])
813
- @pytest .mark .parametrize ("succeed" , [True , False ])
814
- @pytest .mark .parametrize ("relays" , [[0x1111 , 0x2222 , 0x3333 ], []])
815
- async def test_request_recovery_manual_source_route (
816
- device , succeed , relays , make_application , mocker
817
- ):
818
- app , znp_server = make_application (server_cls = device )
819
-
820
- await app .startup (auto_form = False )
821
-
822
- mocker .patch ("zigpy_znp.zigbee.application.DATA_CONFIRM_TIMEOUT" , new = 0.1 )
823
- mocker .patch ("zigpy_znp.zigbee.application.REQUEST_ERROR_RETRY_DELAY" , new = 0 )
824
-
825
- app ._znp ._config [conf .CONF_ZNP_CONFIG ][conf .CONF_ARSP_TIMEOUT ] = 1
826
-
827
- device = app .add_initialized_device (ieee = t .EUI64 (range (8 )), nwk = 0xABCD )
828
- device .relays = relays
829
-
830
- def data_confirm_replier (req ):
831
- if isinstance (req , c .AF .DataRequestExt .Req ) or not succeed :
832
- return c .AF .DataConfirm .Callback (
833
- Status = t .Status .MAC_NO_ACK ,
834
- Endpoint = 1 ,
835
- TSN = 1 ,
836
- )
837
- else :
838
- return c .AF .DataConfirm .Callback (
839
- Status = t .Status .SUCCESS ,
840
- Endpoint = 1 ,
841
- TSN = 1 ,
842
- )
843
-
844
- normal_data_request = znp_server .reply_to (
845
- c .AF .DataRequestExt .Req (partial = True ),
846
- responses = [
847
- c .AF .DataRequestExt .Rsp (Status = t .Status .SUCCESS ),
848
- data_confirm_replier ,
849
- ],
850
- )
851
-
852
- source_routing_data_request = znp_server .reply_to (
853
- c .AF .DataRequestSrcRtg .Req (partial = True ),
854
- responses = [
855
- c .AF .DataRequestSrcRtg .Rsp (Status = t .Status .SUCCESS ),
856
- data_confirm_replier ,
857
- ],
858
- )
859
-
860
- znp_server .reply_to (
861
- c .ZDO .ExtRouteDisc .Req (
862
- Dst = device .nwk , Options = c .zdo .RouteDiscoveryOptions .UNICAST , partial = True
863
- ),
864
- responses = [c .ZDO .ExtRouteDisc .Rsp (Status = t .Status .SUCCESS )],
865
- )
866
-
867
- req = app .request (
868
- device = device ,
869
- profile = 260 ,
870
- cluster = 1 ,
871
- src_ep = 1 ,
872
- dst_ep = 1 ,
873
- sequence = 1 ,
874
- data = b"\x00 " ,
875
- )
876
-
877
- if succeed :
878
- await req
879
- else :
880
- with pytest .raises (DeliveryError ):
881
- await req
882
-
883
- # In either case only one source routing attempt is performed
884
- assert source_routing_data_request .call_count == 1
885
- assert normal_data_request .call_count >= 1
886
-
887
- await app .shutdown ()
888
-
889
-
890
719
@pytest .mark .parametrize ("device" , [FormedLaunchpadCC26X2R1 ])
891
720
async def test_route_discovery_concurrency (device , make_application ):
892
721
app , znp_server = make_application (server_cls = device )
0 commit comments