mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 02:37:47 +00:00
[nexus] fix flakiness in history_tracker test (#13070)
This commit resolves the flaky test failures occasionally observed in the history_tracker Nexus test during ping verification. The flakiness was caused by two primary issues: 1. Concurrent background Thread control traffic (e.g. multicast Hop-by-Hop Options packets) sometimes interleaving with the Echo Request pings, polluting the HistoryTracker queues and causing the strict chronological checks to fail. 2. The FTD child node upgrading to a Router due to the TooFewRouters network threshold rule, which dynamically changed its RLOC16 and caused NeighborRloc16 history checks to fail. To fix these, we: 1. Set the child node's router eligibility to false after joining to prevent any unwanted topology changes or Rloc16 updates. 2. Refactored the strict Leader TX and Child RX chronological checks with robust iterative loops filtering specifically for the OT_ICMP6_TYPE_ECHO_REQUEST packets. Verified 100% stable after executing a loop of 50 successful runs.
This commit is contained in:
@@ -146,6 +146,7 @@ void TestHistoryTracker(void)
|
||||
Mle::DeviceMode::kModeFullNetworkData);
|
||||
|
||||
SuccessOrQuit(child.Get<Mle::Mle>().SetDeviceMode(mode));
|
||||
SuccessOrQuit(child.Get<Mle::Mle>().SetRouterEligible(false));
|
||||
nexus.AdvanceTime(kJoinChildTimeMsec);
|
||||
|
||||
iter.Init();
|
||||
@@ -166,42 +167,50 @@ void TestHistoryTracker(void)
|
||||
const HistoryTracker::MessageInfo *msgInfo;
|
||||
|
||||
iter.Init();
|
||||
for (int i = 2; i >= 0; --i)
|
||||
uint8_t txRequestsFound = 0;
|
||||
while ((msgInfo = leader.Get<HistoryTracker::Local>().IterateTxHistory(iter, age)) != nullptr)
|
||||
{
|
||||
uint16_t size = kPingSizes[i];
|
||||
msgInfo = leader.Get<HistoryTracker::Local>().IterateTxHistory(iter, age);
|
||||
VerifyOrQuit(msgInfo != nullptr);
|
||||
VerifyOrQuit(msgInfo->mIcmp6Type == OT_ICMP6_TYPE_ECHO_REQUEST);
|
||||
VerifyOrQuit(msgInfo->mIpProto == OT_IP6_PROTO_ICMP6);
|
||||
VerifyOrQuit(msgInfo->mPayloadLength == size + sizeof(Ip6::Icmp::Header));
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mSource.mAddress) == leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mDestination.mAddress) == child.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(msgInfo->mLinkSecurity);
|
||||
VerifyOrQuit(msgInfo->mRadioIeee802154);
|
||||
VerifyOrQuit(msgInfo->mPriority == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL);
|
||||
VerifyOrQuit(msgInfo->mNeighborRloc16 == child.Get<Mle::Mle>().GetRloc16());
|
||||
VerifyOrQuit(msgInfo->mChecksum != 0);
|
||||
VerifyOrQuit(msgInfo->mTxSuccess);
|
||||
if (msgInfo->mIcmp6Type == OT_ICMP6_TYPE_ECHO_REQUEST)
|
||||
{
|
||||
VerifyOrQuit(txRequestsFound < 3);
|
||||
uint16_t expectedSize = kPingSizes[2 - txRequestsFound];
|
||||
VerifyOrQuit(msgInfo->mIpProto == OT_IP6_PROTO_ICMP6);
|
||||
VerifyOrQuit(msgInfo->mPayloadLength == expectedSize + sizeof(Ip6::Icmp::Header));
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mSource.mAddress) == leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mDestination.mAddress) == child.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(msgInfo->mLinkSecurity);
|
||||
VerifyOrQuit(msgInfo->mRadioIeee802154);
|
||||
VerifyOrQuit(msgInfo->mPriority == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL);
|
||||
VerifyOrQuit(msgInfo->mNeighborRloc16 == child.Get<Mle::Mle>().GetRloc16());
|
||||
VerifyOrQuit(msgInfo->mChecksum != 0);
|
||||
VerifyOrQuit(msgInfo->mTxSuccess);
|
||||
txRequestsFound++;
|
||||
}
|
||||
}
|
||||
VerifyOrQuit(txRequestsFound == 3);
|
||||
|
||||
// Now check the RX history of the child (should have received the 3 Echo Requests)
|
||||
iter.Init();
|
||||
for (int i = 2; i >= 0; --i)
|
||||
uint8_t rxRequestsFound = 0;
|
||||
while ((msgInfo = child.Get<HistoryTracker::Local>().IterateRxHistory(iter, age)) != nullptr)
|
||||
{
|
||||
uint16_t size = kPingSizes[i];
|
||||
msgInfo = child.Get<HistoryTracker::Local>().IterateRxHistory(iter, age);
|
||||
VerifyOrQuit(msgInfo != nullptr);
|
||||
VerifyOrQuit(msgInfo->mIcmp6Type == OT_ICMP6_TYPE_ECHO_REQUEST);
|
||||
VerifyOrQuit(msgInfo->mIpProto == OT_IP6_PROTO_ICMP6);
|
||||
VerifyOrQuit(msgInfo->mPayloadLength == size + sizeof(Ip6::Icmp::Header));
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mSource.mAddress) == leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mDestination.mAddress) == child.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(msgInfo->mLinkSecurity);
|
||||
VerifyOrQuit(msgInfo->mRadioIeee802154);
|
||||
VerifyOrQuit(msgInfo->mPriority == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL);
|
||||
VerifyOrQuit(msgInfo->mNeighborRloc16 == leader.Get<Mle::Mle>().GetRloc16());
|
||||
VerifyOrQuit(msgInfo->mChecksum != 0);
|
||||
if (msgInfo->mIcmp6Type == OT_ICMP6_TYPE_ECHO_REQUEST)
|
||||
{
|
||||
VerifyOrQuit(rxRequestsFound < 3);
|
||||
uint16_t expectedSize = kPingSizes[2 - rxRequestsFound];
|
||||
VerifyOrQuit(msgInfo->mIpProto == OT_IP6_PROTO_ICMP6);
|
||||
VerifyOrQuit(msgInfo->mPayloadLength == expectedSize + sizeof(Ip6::Icmp::Header));
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mSource.mAddress) == leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(AsCoreType(&msgInfo->mDestination.mAddress) == child.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
VerifyOrQuit(msgInfo->mLinkSecurity);
|
||||
VerifyOrQuit(msgInfo->mRadioIeee802154);
|
||||
VerifyOrQuit(msgInfo->mPriority == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL);
|
||||
VerifyOrQuit(msgInfo->mNeighborRloc16 == leader.Get<Mle::Mle>().GetRloc16());
|
||||
VerifyOrQuit(msgInfo->mChecksum != 0);
|
||||
rxRequestsFound++;
|
||||
}
|
||||
}
|
||||
VerifyOrQuit(rxRequestsFound == 3);
|
||||
|
||||
// The child then replied, so let's check the RX history of the leader for the 3 Echo Replies
|
||||
iter.Init();
|
||||
|
||||
Reference in New Issue
Block a user