[nexus] fix flaky nexus test router_downgrade_on_sec_policy_change (#12959)

The test was failing occasionally due to the unpredictable timing of
tick-aligned timers and dataset propagation in simulations.

Specifically:
1) The router's jittered timeout (minimum 1 second) could expire
   in as little as 1ms if an MLE TimeTick occurred immediately
   after the security policy update.
2) Dataset propagation via MLE Advertisements could take up to
   32 seconds, making immediate checks on the router's role
   unreliable.

This commit fixes the flakiness by:
- Replacing flaky router role checks with `IsRouterRoleAllowed()`
  assertions. This verifies that the security policy has been
  successfully propagated and applied, regardless of whether the
  actual role transition has completed.
- Increasing the propagation wait time to 5 seconds. This provides
  a safe margin for simulated radio propagation while remaining
  well within the leader's 10-second downgrade delay.
- Ensuring both the leader and router are verified for policy
  application in both phases of the test.
- Maintaining the final checks to ensure both nodes eventually
  become detached after the full downgrade delay (150 seconds).

The fix was verified with 1000 consecutive successful iterations.
This commit is contained in:
Jonathan Hui
2026-04-22 02:56:07 -05:00
committed by GitHub
parent 0a97d566de
commit 706e93f017
@@ -101,19 +101,20 @@ void TestRouterDowngradeOnSecPolicyChange(void)
leader.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
}
// Wait for the dataset to propagate to the router.
nexus.AdvanceTime(500);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
VerifyOrQuit(router.Get<Mle::Mle>().IsRouter());
Log("Leader should take at least 10 seconds before downgrading");
// Wait for the dataset to propagate and be processed.
nexus.AdvanceTime(5 * Time::kOneSecondInMsec);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
// We check that security policy is propagated to and applied on
// leader and router. This means `IsRouterRoleAllowed()` should be
// false on both.
VerifyOrQuit(!leader.Get<Mle::Mle>().IsRouterRoleAllowed());
VerifyOrQuit(!router.Get<Mle::Mle>().IsRouterRoleAllowed());
Log("Leader should stay as leader for at least 10 seconds");
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
Log("---------------------------------------------------------------------------------------");
Log("Change back security policy. This should cancel the ongoing downgrade delay");
@@ -170,14 +171,19 @@ void TestRouterDowngradeOnSecPolicyChange(void)
leader.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
}
nexus.AdvanceTime(500);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
Log("Leader should take at least 10 seconds before downgrading");
// Wait for the dataset to propagate and be processed.
nexus.AdvanceTime(5 * Time::kOneSecondInMsec);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
// We check that security policy is propagated to and applied on
// leader and router. This means `IsRouterRoleAllowed()` should be
// false on both.
VerifyOrQuit(!leader.Get<Mle::Mle>().IsRouterRoleAllowed());
VerifyOrQuit(!router.Get<Mle::Mle>().IsRouterRoleAllowed());
Log("Leader should stay as leader for at least 10 seconds");
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
Log("Make sure both leader and router are downgraded and are now `detached`.");