From 92db989165f7be4c457009cc9d8fed43ea530519 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 5 Mar 2026 13:17:28 -0600 Subject: [PATCH] [nexus] fix flaky test 1.2.LP.5.3.2 and related verification issues (#12627) - Fix pktverify index synchronization issues in Nexus tests. Previously, some verification scripts used (pkt.number, 0) as indices in pkts.range() calls. In Nexus tests where WPAN and ETH indices are synchronized, this could cause the advanced index to exceed the stop index of 0, resulting in a flaky AssertionError. Updated scripts to use (pkt.number, pkt.number) consistently. - Reduce kAttachAsSsedTime from 20s to 5s in test_1_2_LP_5_3_2.cpp. The 20s wait was exactly matching the CSL Synchronized Timeout, causing SSED_1 to trigger an auto-synchronization Data Request immediately after the wait ended, violating test constraints. Providing more margin ensures stable test execution. --- tests/nexus/test_1_2_LP_5_3_2.cpp | 2 +- tests/nexus/verify_1_2_LP_5_3_2.py | 28 ++++++++++++++-------------- tests/nexus/verify_1_2_LP_5_3_3.py | 4 ++-- tests/nexus/verify_1_2_LP_5_3_7.py | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/nexus/test_1_2_LP_5_3_2.cpp b/tests/nexus/test_1_2_LP_5_3_2.cpp index c6d87ba13..8d8cd80c8 100644 --- a/tests/nexus/test_1_2_LP_5_3_2.cpp +++ b/tests/nexus/test_1_2_LP_5_3_2.cpp @@ -55,7 +55,7 @@ static constexpr uint32_t kAttachToRouterTime = 200 * kMsPerSecond; /** * Time to advance for a node to join as a SSED. */ -static constexpr uint32_t kAttachAsSsedTime = 20 * kMsPerSecond; +static constexpr uint32_t kAttachAsSsedTime = 5 * kMsPerSecond; /** * Time to wait in the test, in milliseconds. diff --git a/tests/nexus/verify_1_2_LP_5_3_2.py b/tests/nexus/verify_1_2_LP_5_3_2.py index 07e17c118..28082b04e 100644 --- a/tests/nexus/verify_1_2_LP_5_3_2.py +++ b/tests/nexus/verify_1_2_LP_5_3_2.py @@ -49,7 +49,8 @@ def _has_csl_ie(p): def _must_not_have_data_request_from_ssed1(pkts, start_pkt, end_pkt, ssed_1, router_1_rloc16): - pkts.range((start_pkt.number if start_pkt else 1, 0), (end_pkt.number, 0)).\ + start_num = start_pkt.number if start_pkt else 1 + pkts.range((start_num, start_num), (end_pkt.number, end_pkt.number)).\ filter_wpan_src64(ssed_1).\ filter_wpan_dst16(router_1_rloc16).\ filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\ @@ -125,7 +126,7 @@ def verify(pv): # - Pass Criteria: SSED_1 MUST NOT send a MAC Data Request prior to receiving the UDP message from the Leader. print("Step 4: Leader sends UDP to SSED_1") - udp_pkt = pkts.range((child_update_resp.number, 0)).\ + udp_pkt = pkts.range((child_update_resp.number, child_update_resp.number)).\ filter_wpan_src64(LEADER).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter(lambda p: p.udp).\ @@ -141,7 +142,7 @@ def verify(pv): print("Step 5: SSED_1 responds with Enhanced ACK containing CSL IEs") # Enhanced ACK for the forwarded UDP message (Router 1 to SSED_1) - udp_fwd = pkts.range((udp_pkt.number, 0)).\ + udp_fwd = pkts.range((udp_pkt.number, udp_pkt.number)).\ filter_wpan_src64(ROUTER_1).\ filter_wpan_dst16(SSED_1_RLOC16).\ filter(lambda p: p.udp).\ @@ -150,7 +151,7 @@ def verify(pv): must_next() # The DUT MUST receive an Enhanced ACK from SSED_1 - ack_step5 = pkts.range((udp_fwd.number, 0)).\ + ack_step5 = pkts.range((udp_fwd.number, udp_fwd.number)).\ filter_wpan_ack().\ filter(_has_csl_ie).\ must_next() @@ -168,7 +169,7 @@ def verify(pv): # - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1. print("Step 7: Leader sends Echo Request to SSED_1") - echo_req_1 = pkts.range((ack_step5.number, 0)).\ + echo_req_1 = pkts.range((ack_step5.number, ack_step5.number)).\ filter_ping_request().\ filter_wpan_src64(LEADER).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ @@ -178,7 +179,7 @@ def verify(pv): # SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader. _must_not_have_data_request_from_ssed1(pkts, udp_fwd, echo_req_1, SSED_1, ROUTER_1_RLOC16) - echo_reply_1 = pkts.range((echo_req_1.number, 0)).\ + echo_reply_1 = pkts.range((echo_req_1.number, echo_req_1.number)).\ filter_ping_reply(identifier=echo_req_1.icmpv6.echo.identifier).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ @@ -195,7 +196,7 @@ def verify(pv): print("Step 9: SSED_1 sends MAC Data Request with CSL IEs") # We look for the Data Request starting from echo_req_1 because it could be delayed until Step 9. - step9_data_req = pkts.range((echo_req_1.number, 0)).\ + step9_data_req = pkts.range((echo_req_1.number, echo_req_1.number)).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\ @@ -217,7 +218,7 @@ def verify(pv): # Start search from whichever packet was later: echo_reply_1 or step9_data_req. last_pkt_step9 = echo_reply_1 if echo_reply_1.number > step9_data_req.number else step9_data_req - echo_req_2 = pkts.range((last_pkt_step9.number, 0)).\ + echo_req_2 = pkts.range((last_pkt_step9.number, last_pkt_step9.number)).\ filter_ping_request().\ filter_wpan_src64(LEADER).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ @@ -227,7 +228,7 @@ def verify(pv): # SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader. _must_not_have_data_request_from_ssed1(pkts, step9_data_req, echo_req_2, SSED_1, ROUTER_1_RLOC16) - echo_reply_2 = pkts.range((echo_req_2.number, 0)).\ + echo_reply_2 = pkts.range((echo_req_2.number, echo_req_2.number)).\ filter_ping_reply(identifier=echo_req_2.icmpv6.echo.identifier).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ @@ -249,7 +250,7 @@ def verify(pv): print("Step 13: SSED_1 sends UDP to DUT with CSL IEs") # UDP could also be delayed until Step 13 if Echo Request 2 was delayed. - step13_udp = pkts.range((echo_req_2.number, 0)).\ + step13_udp = pkts.range((echo_req_2.number, echo_req_2.number)).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter(lambda p: p.udp).\ @@ -263,7 +264,7 @@ def verify(pv): # - The Enhanced ACK must occur within the ACK timeout. print("Step 14: Router sends Enhanced ACK (no IEs)") - ack_step14 = pkts.range((step13_udp.number, 0)).\ + ack_step14 = pkts.range((step13_udp.number, step13_udp.number)).\ filter_wpan_ack().\ filter(lambda p: p.wpan.version == 2 and p.wpan.ie_present == 0).\ must_next() @@ -283,17 +284,16 @@ def verify(pv): # Ensure we search after both echo_reply_2 and ack_step14. last_pkt_step14 = echo_reply_2 if echo_reply_2.number > ack_step14.number else ack_step14 - echo_req_3 = pkts.range((last_pkt_step14.number, 0)).\ + echo_req_3 = pkts.range((last_pkt_step14.number, last_pkt_step14.number)).\ filter_ping_request().\ filter_wpan_src64(LEADER).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter_ipv6_dst(SSED_1_ML_EID).\ must_next() - # SSED1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader. _must_not_have_data_request_from_ssed1(pkts, last_pkt_step14, echo_req_3, SSED_1, ROUTER_1_RLOC16) - pkts.range((echo_req_3.number, 0)).\ + pkts.range((echo_req_3.number, echo_req_3.number)).\ filter_ping_reply(identifier=echo_req_3.icmpv6.echo.identifier).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ diff --git a/tests/nexus/verify_1_2_LP_5_3_3.py b/tests/nexus/verify_1_2_LP_5_3_3.py index 767c17893..11e9a48d0 100644 --- a/tests/nexus/verify_1_2_LP_5_3_3.py +++ b/tests/nexus/verify_1_2_LP_5_3_3.py @@ -189,7 +189,7 @@ def verify(pv): must_next() # Verify that the frame was NOT relayed before the Data Request/re-sync (Step 8 Pass Criteria) - pkts.range((echo_req_2.number, 0), (data_req.number, 0)).\ + pkts.range((echo_req_2.number, echo_req_2.number), (data_req.number, data_req.number)).\ filter_ping_request().\ filter_wpan_src64(DUT).\ filter_wpan_dst16(SSED_1_RLOC16).\ @@ -253,7 +253,7 @@ def verify(pv): filter(lambda p: p.wpan.version == 2).\ must_next() - pkts.range((echo_req_3.number, 0), (relay_req_3.number, 0)).\ + pkts.range((echo_req_3.number, echo_req_3.number), (relay_req_3.number, relay_req_3.number)).\ filter_wpan_src64(SSED_1).\ filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\ must_not_next() diff --git a/tests/nexus/verify_1_2_LP_5_3_7.py b/tests/nexus/verify_1_2_LP_5_3_7.py index 0ed918320..0ba6ca4c4 100644 --- a/tests/nexus/verify_1_2_LP_5_3_7.py +++ b/tests/nexus/verify_1_2_LP_5_3_7.py @@ -110,7 +110,7 @@ def verify(pv): must_next() # Skip first 10 packets after Step 2 to ignore initial resync polls - pkts.range((_step2_pkt.number + 10, 0), (_pkt.number, 0)).\ + pkts.range((_step2_pkt.number + 10, _step2_pkt.number + 10), (_pkt.number, _pkt.number)).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\ @@ -162,7 +162,7 @@ def verify(pv): filter(lambda p: p.wpan.version == 2).\ must_next() - pkts.range((_step6_pkt.number + 5, 0), (_pkt.number, 0)).\ + pkts.range((_step6_pkt.number + 5, _step6_pkt.number + 5), (_pkt.number, _pkt.number)).\ filter_wpan_src64(SSED_1).\ filter_wpan_dst16(ROUTER_1_RLOC16).\ filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\ @@ -220,7 +220,7 @@ def verify(pv): must_next() # Verify Step 12.1: DUT MUST NOT relay the frame between Step 12 and Step 13. - pkts.range((_pkt12.number, 0), (_pkt13.number, 0)).\ + pkts.range((_pkt12.number, _pkt12.number), (_pkt13.number, _pkt13.number)).\ filter_ping_request(identifier=_pkt12.icmpv6.echo.identifier).\ filter_wpan_src64(ROUTER_1).\ filter_wpan_dst16(SSED_1_RLOC16).\