Skip to content

Commit 964c1eb

Browse files
authored
[nexus] add test 7.1.3 Network data propagation - Border Router as Leader (openthread#12507)
This commit adds a new Nexus test case 7.1.3 which verifies that global prefix information can be set on the DUT (Leader) and that the DUT correctly sets and propagates the Network Data (stable/non-stable) to neighbors and children in an already formed network. The test setup uses a Leader (DUT) configured as a Border Router with both stable (2001::/64) and non-stable (2002::/64) prefixes. It verifies that neighbors and MED_1 (requesting complete data) receive both prefixes via MLE Data Response, while SED_1 (requesting only stable data) receives only the stable prefix via MLE Child Update Request. Summary of changes: - Created tests/nexus/test_7_1_3.cpp: - Implements test logic using direct core method calls. - Sets log level to note. - Configures AllowList for Leader-Router1, Leader-MED1, and Leader-SED1 links. - Includes 1-line log outputs for each test step. - Adheres to requested block comment formatting. - Created tests/nexus/verify_7_1_3.py: - Implements pcap-based verification of PASS criteria. - Validates selective prefix propagation based on child mode. - Verifies MLE Child ID and Child Update exchanges. - Follows requested Python filter formatting style. - Updated tests/nexus/CMakeLists.txt to build the new test. - Updated tests/nexus/run_nexus_tests.sh to add 7_1_3 to the default test list.
1 parent d4e2c64 commit 964c1eb

File tree

4 files changed

+440
-0
lines changed

4 files changed

+440
-0
lines changed

tests/nexus/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ ot_nexus_test(6_6_1 "cert;nexus")
183183
ot_nexus_test(6_6_2 "cert;nexus")
184184
ot_nexus_test(7_1_1 "cert;nexus")
185185
ot_nexus_test(7_1_2 "cert;nexus")
186+
ot_nexus_test(7_1_3 "cert;nexus")
186187

187188
# Misc tests
188189
ot_nexus_test(border_admitter "core;nexus")

tests/nexus/run_nexus_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ DEFAULT_TESTS=(
119119
"6_6_2"
120120
"7_1_1"
121121
"7_1_2"
122+
"7_1_3"
122123
)
123124

124125
# Use provided arguments or the default test list

tests/nexus/test_7_1_3.cpp

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
* Copyright (c) 2026, The OpenThread Authors.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* 3. Neither the name of the copyright holder nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#include <stdio.h>
30+
31+
#include "platform/nexus_core.hpp"
32+
#include "platform/nexus_node.hpp"
33+
34+
namespace ot {
35+
namespace Nexus {
36+
37+
/**
38+
* Time to advance for a node to form a network and become leader, in milliseconds.
39+
*/
40+
static constexpr uint32_t kFormNetworkTime = 13 * 1000;
41+
42+
/**
43+
* Time to advance for a node to join as a child and upgrade to a router, in milliseconds.
44+
*/
45+
static constexpr uint32_t kAttachToRouterTime = 200 * 1000;
46+
47+
/**
48+
* Time to advance for the network to stabilize after routers have attached.
49+
*/
50+
static constexpr uint32_t kStabilizationTime = 10 * 1000;
51+
52+
/**
53+
* Time to advance for a child to register its address.
54+
*/
55+
static constexpr uint32_t kChildUpdateWaitTime = 10 * 1000;
56+
57+
void Test7_1_3(const char *aJsonFile)
58+
{
59+
/**
60+
* 7.1.3 Network data propagation - Border Router as Leader of Thread network; advertises new network data
61+
* information after network is formed
62+
*
63+
* 7.1.3.1 Topology
64+
* - MED_1 is configured to require complete network data. (Mode TLV)
65+
* - SED_1 is configured to request only stable network data. (Mode TLV)
66+
*
67+
* 7.1.3.2 Purpose & Description
68+
* The purpose of this test case is to verify that global prefix information can be set on the DUT, which is acting
69+
* as a Leader in the Thread network. The DUT must also demonstrate that it correctly sets the Network Data
70+
* (stable/non-stable) and propagates it properly in an already formed network.
71+
*
72+
* Spec Reference | V1.1 Section | V1.3.0 Section
73+
* ---------------------------------------------------|--------------------|--------------------
74+
* Thread Network Data / Stable Thread Network Data / | 5.13 / 5.14 / 5.15 | 5.13 / 5.14 / 5.15
75+
* Network Data and Propagation | |
76+
*/
77+
78+
Core nexus;
79+
80+
Node &leader = nexus.CreateNode();
81+
Node &router1 = nexus.CreateNode();
82+
Node &med1 = nexus.CreateNode();
83+
Node &sed1 = nexus.CreateNode();
84+
85+
leader.SetName("LEADER");
86+
router1.SetName("ROUTER_1");
87+
med1.SetName("MED_1");
88+
sed1.SetName("SED_1");
89+
90+
/** Use AllowList to specify links between nodes. */
91+
leader.AllowList(router1);
92+
router1.AllowList(leader);
93+
94+
leader.AllowList(med1);
95+
med1.AllowList(leader);
96+
97+
leader.AllowList(sed1);
98+
sed1.AllowList(leader);
99+
100+
nexus.AdvanceTime(0);
101+
102+
Instance::SetLogLevel(kLogLevelNote);
103+
104+
/**
105+
* Step 1: All
106+
* - Description: Ensure topology is formed correctly.
107+
* - Pass Criteria: N/A
108+
*/
109+
Log("Step 1: Ensure topology is formed correctly.");
110+
leader.Form();
111+
nexus.AdvanceTime(kFormNetworkTime);
112+
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
113+
114+
router1.Join(leader, Node::kAsFtd);
115+
med1.Join(leader, Node::kAsMed);
116+
sed1.Join(leader, Node::kAsSed);
117+
nexus.AdvanceTime(kAttachToRouterTime);
118+
119+
VerifyOrQuit(router1.Get<Mle::Mle>().IsFullThreadDevice());
120+
VerifyOrQuit(med1.Get<Mle::Mle>().IsAttached());
121+
VerifyOrQuit(sed1.Get<Mle::Mle>().IsAttached());
122+
123+
nexus.AdvanceTime(kStabilizationTime);
124+
125+
/**
126+
* Step 2: Leader (DUT)
127+
* - Description: User configures the DUT with the following On-Mesh Prefix Set:
128+
* - Prefix 1: P_prefix=2001::/64 P_stable=1 P_on_mesh=1 P_preferred=1 P_slaac=1 P_default=1
129+
* - Prefix 2: P_prefix=2002::/64 P_stable=0 P_on_mesh=1 P_preferred=1 P_slaac=1 P_default=1
130+
* - Pass Criteria: N/A
131+
*/
132+
Log("Step 2: Leader (DUT) configures On-Mesh Prefixes.");
133+
{
134+
NetworkData::OnMeshPrefixConfig config;
135+
136+
config.Clear();
137+
SuccessOrQuit(config.GetPrefix().FromString("2001::/64"));
138+
config.mStable = true;
139+
config.mOnMesh = true;
140+
config.mPreferred = true;
141+
config.mSlaac = true;
142+
config.mDefaultRoute = true;
143+
SuccessOrQuit(leader.Get<NetworkData::Local>().AddOnMeshPrefix(config));
144+
145+
config.Clear();
146+
SuccessOrQuit(config.GetPrefix().FromString("2002::/64"));
147+
config.mStable = false;
148+
config.mOnMesh = true;
149+
config.mPreferred = true;
150+
config.mSlaac = true;
151+
config.mDefaultRoute = true;
152+
SuccessOrQuit(leader.Get<NetworkData::Local>().AddOnMeshPrefix(config));
153+
154+
leader.Get<NetworkData::Notifier>().HandleServerDataUpdated();
155+
}
156+
157+
/**
158+
* Step 3: Leader (DUT)
159+
* - Description: Automatically sends the new network data to neighbors and rx-on-while-idle Children (MED_1).
160+
* - Pass Criteria: The DUT MUST send a multicast MLE Data Response with the new network information, which includes
161+
* the following TLVs:
162+
* - Network Data TLV
163+
* - At least two Prefix TLVs (Prefix 1 and Prefix 2):
164+
* - 6LoWPAN ID sub-TLV
165+
* - Border Router sub-TLV
166+
*/
167+
Log("Step 3: Leader (DUT) automatically sends the new network data to neighbors and rx-on-while-idle Children.");
168+
nexus.AdvanceTime(kStabilizationTime);
169+
170+
/**
171+
* Step 4: MED_1
172+
* - Description: Automatically sends the global address configured to its parent (the DUT), via the Address
173+
* Registration TLV included in its Child Update Request keep-alive message.
174+
* - Pass Criteria: N/A
175+
*/
176+
Log("Step 4: MED_1 automatically sends the global address configured to its parent.");
177+
nexus.AdvanceTime(kChildUpdateWaitTime);
178+
179+
/**
180+
* Step 5: Leader (DUT)
181+
* - Description: Automatically sends MLE Child Update Response to MED_1.
182+
* - Pass Criteria: The DUT MUST unicast MLE Child Update Response to MED_1, containing the following TLVs:
183+
* - Source Address TLV
184+
* - Address Registration TLV (Echoes back the addresses MED_1 has configured)
185+
* - Mode TLV
186+
*/
187+
Log("Step 5: Leader (DUT) automatically sends MLE Child Update Response to MED_1.");
188+
nexus.AdvanceTime(kChildUpdateWaitTime);
189+
190+
/**
191+
* Step 6: Leader (DUT)
192+
* - Description: Automatically sends notification of new network data to SED_1. Depending upon the DUT's device
193+
* implementation, two different behavior paths (A,B) are allowable.
194+
* - Pass Criteria:
195+
* - Path A: The DUT MUST unicast MLE Child Update Request to SED_1, including the following TLVs:
196+
* - Source Address TLV
197+
* - Leader Data TLV
198+
* - Network Data TLV
199+
* - Active Timestamp TLV
200+
* - Goto step 7
201+
* - Path B: The DUT MUST unicast MLE Data Response to SED_1, including the following TLVs:
202+
* - Source Address TLV
203+
* - Leader Data TLV
204+
* - Network Data TLV
205+
* - Active Timestamp TLV
206+
* - Goto step 7
207+
*/
208+
Log("Step 6: Leader (DUT) automatically sends notification of new network data to SED_1.");
209+
nexus.AdvanceTime(kAttachToRouterTime);
210+
211+
/**
212+
* Step 7: SED_1
213+
* - Description: After receiving the MLE Data Response or MLE Child Update Request, automatically sends the global
214+
* address configured to its parent (DUT), via the Address Registration TLV as part of the Child Update Request
215+
* command.
216+
* - Pass Criteria: N/A
217+
*/
218+
Log("Step 7: SED_1 automatically sends the global address configured to its parent.");
219+
nexus.AdvanceTime(kChildUpdateWaitTime);
220+
221+
/**
222+
* Step 8: Leader (DUT)
223+
* - Description: Automatically sends MLE Child Update Response to SED_1.
224+
* - Pass Criteria: The DUT MUST unicast MLE Child Update Response to SED_1, including the following TLVs:
225+
* - Source Address TLV
226+
* - Address Registration TLV (Echoes back the addresses SED_1 has configured)
227+
* - Mode TLV
228+
*/
229+
Log("Step 8: Leader (DUT) automatically sends MLE Child Update Response to SED_1.");
230+
nexus.AdvanceTime(kChildUpdateWaitTime);
231+
232+
nexus.SaveTestInfo(aJsonFile);
233+
}
234+
235+
} /* namespace Nexus */
236+
} /* namespace ot */
237+
238+
int main(int argc, char *argv[])
239+
{
240+
ot::Nexus::Test7_1_3((argc > 2) ? argv[2] : "test_7_1_3.json");
241+
printf("All tests passed\n");
242+
return 0;
243+
}

0 commit comments

Comments
 (0)