1#!/usr/bin/env python3 2# 3# Copyright (c) 2022, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28 29from cli import verify 30from cli import verify_within 31import cli 32import time 33 34# ----------------------------------------------------------------------------------------------------------------------- 35# Test description: Network Data update and version changes (stable only vs. full version). 36# 37# Network topology 38# 39# r1 ---- r2 ---- r3 40# | 41# | 42# sed 43# 44# 45# sed is sleepy-end node and also configured to request stable Network Data only 46# 47# Test covers the following steps: 48# - Adding/removing prefixes (stable or temporary) on r1 49# - Verifying that Network Data is updated on all nodes 50# - Ensuring correct update to version and stable version 51# 52# The above steps are repeated over many different situations: 53# - Where the same prefixes are also added by other nodes 54# - Or the same prefixes are added as off-mesh routes by other nodes 55 56test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 57print('-' * 120) 58print('Starting \'{}\''.format(test_name)) 59 60# ----------------------------------------------------------------------------------------------------------------------- 61# Creating `cli.Node` instances 62 63speedup = 10 64cli.Node.set_time_speedup_factor(speedup) 65 66r1 = cli.Node() 67r2 = cli.Node() 68r3 = cli.Node() 69sed = cli.Node() 70 71# ----------------------------------------------------------------------------------------------------------------------- 72# Form topology 73 74r1.allowlist_node(r2) 75 76r2.allowlist_node(r1) 77r2.allowlist_node(r3) 78r2.allowlist_node(sed) 79 80r2.allowlist_node(r2) 81 82sed.allowlist_node(r2) 83 84r1.form('netdata') 85r2.join(r1) 86r3.join(r1) 87sed.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE) 88 89sed.set_mode('-') 90sed.set_pollperiod(400) 91 92# ----------------------------------------------------------------------------------------------------------------------- 93# Test Implementation 94 95r1_rloc = r1.get_rloc16() 96r2_rloc = r2.get_rloc16() 97r3_rloc = r3.get_rloc16() 98 99versions = r1.get_netdata_versions() 100 101# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 102 103 104def verify_versions_incremented(): 105 global versions 106 new_versions = r1.get_netdata_versions() 107 verify(new_versions[0] == ((versions[0] + 1) % 256)) 108 verify(new_versions[1] == ((versions[1] + 1) % 256)) 109 versions = new_versions 110 111 112def verify_stabe_version_incremented(): 113 global versions 114 new_versions = r1.get_netdata_versions() 115 verify(new_versions[0] == ((versions[0] + 1) % 256)) 116 verify(new_versions[1] == versions[1]) 117 versions = new_versions 118 119 120# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 121 122# Add prefix `fd00:1::/64` on r1 as stable and validate 123# that entries are updated on all nodes and versions are changed. 124 125r1.add_prefix('fd00:1::/64', 'os') 126r1.register_netdata() 127 128 129def check_r1_prefix_added_on_all_nodes(): 130 for node in [r1, r2, r3]: 131 verify('fd00:1:0:0::/64 os med ' + r1_rloc in node.get_netdata_prefixes()) 132 verify('fd00:1:0:0::/64 os med fffe' in sed.get_netdata_prefixes()) 133 134 135verify_within(check_r1_prefix_added_on_all_nodes, 2) 136verify_versions_incremented() 137 138# Add prefix `fd00:2::/64` on r2 as temporary and ensure it is seen on 139# all nodes and not seen on sed. 140 141r2.add_prefix('fd00:2::/64', 'po', 'high') 142r2.register_netdata() 143 144 145def check_r2_prefix_added_on_all_nodes(): 146 for node in [r1, r2, r3]: 147 verify('fd00:2:0:0::/64 po high ' + r2_rloc in node.get_netdata_prefixes()) 148 verify(not 'fd00:2:0:0::/64 po high fffe' in sed.get_netdata_prefixes()) 149 150 151verify_within(check_r2_prefix_added_on_all_nodes, 2) 152verify_stabe_version_incremented() 153 154# Remove prefix `fd00:1::/64` from r1. 155 156r1.remove_prefix('fd00:1::/64') 157r1.register_netdata() 158 159 160def check_r1_prefix_removed_on_all_nodes(): 161 for node in [r1, r2, r3]: 162 verify(not 'fd00:1:0:0::/64 os med ' + r1_rloc in node.get_netdata_prefixes()) 163 verify(not 'fd00:1:0:0::/64 os med fffe' in sed.get_netdata_prefixes()) 164 165 166verify_within(check_r1_prefix_removed_on_all_nodes, 2) 167verify_versions_incremented() 168 169# Remove prefix `fd00:2::/64` from r2. 170 171r2.remove_prefix('fd00:2::/64') 172r2.register_netdata() 173 174 175def check_r2_prefix_removed_on_all_nodes(): 176 for node in [r1, r2, r3]: 177 verify(not 'fd00:2:0:0::/64 po high ' + r2_rloc in node.get_netdata_prefixes()) 178 verify(not 'fd00:2:0:0::/64 po high fffe' in sed.get_netdata_prefixes()) 179 180 181verify_within(check_r2_prefix_removed_on_all_nodes, 2) 182verify_stabe_version_incremented() 183 184# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 185# Repeat the same checks but now r3 also adds ``fd00:1::/64` with different 186# flags. 187 188r3.add_prefix('fd00:1::/64', 'paos') 189r3.register_netdata() 190 191 192def check_r3_prefix_added_on_all_nodes(): 193 for node in [r1, r2, r3]: 194 verify('fd00:1:0:0::/64 paos med ' + r3_rloc in node.get_netdata_prefixes()) 195 verify('fd00:1:0:0::/64 paos med fffe' in sed.get_netdata_prefixes()) 196 197 198verify_within(check_r3_prefix_added_on_all_nodes, 2) 199verify_versions_incremented() 200 201r1.add_prefix('fd00:1::/64', 'os') 202r1.register_netdata() 203verify_within(check_r1_prefix_added_on_all_nodes, 2) 204verify_versions_incremented() 205 206r2.add_prefix('fd00:2::/64', 'po', 'high') 207r2.register_netdata() 208verify_within(check_r2_prefix_added_on_all_nodes, 2) 209verify_stabe_version_incremented() 210 211r1.remove_prefix('fd00:1::/64') 212r1.register_netdata() 213verify_within(check_r1_prefix_removed_on_all_nodes, 2) 214verify_versions_incremented() 215 216r2.remove_prefix('fd00:2::/64') 217r2.register_netdata() 218verify_within(check_r2_prefix_removed_on_all_nodes, 2) 219verify_stabe_version_incremented() 220 221# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 222# Repeat the same checks with r3 also adding ``fd00:2::/64` 223 224r3.add_prefix('fd00:2::/64', 'paos') 225r3.register_netdata() 226 227 228def check_new_r3_prefix_added_on_all_nodes(): 229 for node in [r1, r2, r3]: 230 verify('fd00:2:0:0::/64 paos med ' + r3_rloc in node.get_netdata_prefixes()) 231 verify('fd00:2:0:0::/64 paos med fffe' in sed.get_netdata_prefixes()) 232 233 234verify_within(check_new_r3_prefix_added_on_all_nodes, 2) 235verify_versions_incremented() 236 237r1.add_prefix('fd00:1::/64', 'os') 238r1.register_netdata() 239verify_within(check_r1_prefix_added_on_all_nodes, 2) 240verify_versions_incremented() 241 242r2.add_prefix('fd00:2::/64', 'po', 'high') 243r2.register_netdata() 244verify_within(check_r2_prefix_added_on_all_nodes, 2) 245verify_stabe_version_incremented() 246 247r1.remove_prefix('fd00:1::/64') 248r1.register_netdata() 249verify_within(check_r1_prefix_removed_on_all_nodes, 2) 250verify_versions_incremented() 251 252r2.remove_prefix('fd00:2::/64') 253r2.register_netdata() 254verify_within(check_r2_prefix_removed_on_all_nodes, 2) 255verify_stabe_version_incremented() 256 257# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 258# Repeat the same checks with r3 adding the two prefixes as temporary. 259 260r3.remove_prefix('fd00:1::/64') 261r3.remove_prefix('fd00:2::/64') 262r3.add_prefix('fd00:1::/64', 'pao') 263r3.add_prefix('fd00:2::/64', 'pao') 264r3.register_netdata() 265 266 267def check_r3_prefixes_as_temp_added_on_all_nodes(): 268 for node in [r1, r2, r3]: 269 prefixes = node.get_netdata_prefixes() 270 verify('fd00:1:0:0::/64 pao med ' + r3_rloc in prefixes) 271 verify('fd00:1:0:0::/64 pao med ' + r3_rloc in prefixes) 272 verify(len(sed.get_netdata_prefixes()) == 0) 273 274 275verify_within(check_r3_prefixes_as_temp_added_on_all_nodes, 2) 276verify_versions_incremented() 277 278r1.add_prefix('fd00:1::/64', 'os') 279r1.register_netdata() 280verify_within(check_r1_prefix_added_on_all_nodes, 2) 281verify_versions_incremented() 282 283r2.add_prefix('fd00:2::/64', 'po', 'high') 284r2.register_netdata() 285verify_within(check_r2_prefix_added_on_all_nodes, 2) 286verify_stabe_version_incremented() 287 288r1.remove_prefix('fd00:1::/64') 289r1.register_netdata() 290verify_within(check_r1_prefix_removed_on_all_nodes, 2) 291verify_versions_incremented() 292 293r2.remove_prefix('fd00:2::/64') 294r2.register_netdata() 295verify_within(check_r2_prefix_removed_on_all_nodes, 2) 296verify_stabe_version_incremented() 297 298# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 299# Finally repeat the same checks with r3 adding the two prefixes 300# as off-mesh route prefix. 301 302r3.remove_prefix('fd00:1::/64') 303r3.remove_prefix('fd00:2::/64') 304r3.add_route('fd00:1::/64', 's') 305r3.add_route('fd00:2::/64', '-') 306r3.register_netdata() 307 308 309def check_r3_routes_added_on_all_nodes(): 310 for node in [r1, r2, r3]: 311 routes = node.get_netdata_routes() 312 verify('fd00:1:0:0::/64 s med ' + r3_rloc in routes) 313 verify('fd00:2:0:0::/64 med ' + r3_rloc in routes) 314 verify('fd00:1:0:0::/64 s med fffe' in sed.get_netdata_routes()) 315 verify(not 'fd00:1:0:0::/64 med fffe' in sed.get_netdata_routes()) 316 317 318verify_within(check_r3_routes_added_on_all_nodes, 2) 319verify_versions_incremented() 320 321r1.add_prefix('fd00:1::/64', 'os') 322r1.register_netdata() 323verify_within(check_r1_prefix_added_on_all_nodes, 2) 324verify_versions_incremented() 325 326r2.add_prefix('fd00:2::/64', 'po', 'high') 327r2.register_netdata() 328verify_within(check_r2_prefix_added_on_all_nodes, 2) 329verify_stabe_version_incremented() 330 331r1.remove_prefix('fd00:1::/64') 332r1.register_netdata() 333verify_within(check_r1_prefix_removed_on_all_nodes, 2) 334verify_versions_incremented() 335 336r2.remove_prefix('fd00:2::/64') 337r2.register_netdata() 338verify_within(check_r2_prefix_removed_on_all_nodes, 2) 339verify_stabe_version_incremented() 340 341# ----------------------------------------------------------------------------------------------------------------------- 342# Test finished 343 344cli.Node.finalize_all_nodes() 345 346print('\'{}\' passed.'.format(test_name)) 347