1#!/usr/bin/env python3 2# 3# Copyright (c) 2024, 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: 36# 37# Network with two BRs, none of them acting as leader. Removing BR1 ensuring BR2 taking over. 38# 39# ________________ 40# / \ 41# br1 --- leader --- br2 42# / / \ \ 43# c1 c2 c3 c4 44# 45 46test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 47print('-' * 120) 48print('Starting \'{}\''.format(test_name)) 49 50# ----------------------------------------------------------------------------------------------------------------------- 51# Creating `cli.Nodes` instances 52 53speedup = 60 54cli.Node.set_time_speedup_factor(speedup) 55 56leader = cli.Node() 57br1 = cli.Node() 58br2 = cli.Node() 59c1 = cli.Node() 60c2 = cli.Node() 61c3 = cli.Node() 62c4 = cli.Node() 63 64IF_INDEX = 1 65 66# ----------------------------------------------------------------------------------------------------------------------- 67# Form topology 68 69leader.allowlist_node(br1) 70leader.allowlist_node(br2) 71leader.allowlist_node(c2) 72leader.allowlist_node(c3) 73 74br1.allowlist_node(leader) 75br1.allowlist_node(br2) 76br1.allowlist_node(c1) 77 78br2.allowlist_node(leader) 79br2.allowlist_node(br1) 80br2.allowlist_node(c4) 81 82c1.allowlist_node(br1) 83 84c2.allowlist_node(leader) 85c3.allowlist_node(leader) 86 87c4.allowlist_node(br2) 88 89leader.form("multi-br") 90br1.join(leader) 91br2.join(leader) 92c1.join(leader, cli.JOIN_TYPE_END_DEVICE) 93c2.join(leader, cli.JOIN_TYPE_END_DEVICE) 94c3.join(leader, cli.JOIN_TYPE_END_DEVICE) 95c4.join(leader, cli.JOIN_TYPE_END_DEVICE) 96 97verify(leader.get_state() == 'leader') 98verify(br1.get_state() == 'router') 99verify(br2.get_state() == 'router') 100verify(c1.get_state() == 'child') 101verify(c2.get_state() == 'child') 102verify(c3.get_state() == 'child') 103verify(c4.get_state() == 'child') 104 105nodes_non_br = [leader, c1, c2, c3, c4] 106 107# ----------------------------------------------------------------------------------------------------------------------- 108# Test implementation 109 110# Start the first BR 111 112br1.srp_server_set_addr_mode('unicast') 113br1.srp_server_auto_enable() 114 115br1.br_init(IF_INDEX, 1) 116br1.br_enable() 117 118time.sleep(1) 119verify(br1.br_get_state() == 'running') 120 121br1_local_omr = br1.br_get_local_omrprefix() 122br1_favored_omr = br1.br_get_favored_omrprefix().split()[0] 123verify(br1_local_omr == br1_favored_omr) 124 125br1_local_onlink = br1.br_get_local_onlinkprefix() 126br1_favored_onlink = br1.br_get_favored_onlinkprefix().split()[0] 127verify(br1_local_onlink == br1_favored_onlink) 128 129# Start the second BR 130 131br2.br_init(IF_INDEX, 1) 132br2.br_enable() 133 134time.sleep(1) 135verify(br2.br_get_state() == 'running') 136 137br2_local_omr = br2.br_get_local_omrprefix() 138br2_favored_omr = br2.br_get_favored_omrprefix().split()[0] 139verify(br2_favored_omr == br1_favored_omr) 140 141br2_favored_onlink = br2.br_get_favored_onlinkprefix().split()[0] 142verify(br2_favored_onlink == br1_favored_onlink) 143 144verify(br1.srp_server_get_state() == 'running') 145verify(br2.srp_server_get_state() == 'disabled') 146 147# Register SRP services on all nodes 148 149for node in nodes_non_br: 150 node.srp_client_enable_auto_start_mode() 151 verify(node.srp_client_get_auto_start_mode() == 'Enabled') 152 node.srp_client_set_host_name('host' + str(node.index)) 153 node.srp_client_enable_auto_host_address() 154 node.srp_client_add_service('srv' + str(node.index), '_test._udp', 777, 0, 0) 155 156time.sleep(1) 157 158hosts = br1.srp_server_get_hosts() 159verify(len(hosts) == len(nodes_non_br)) 160 161services = br1.srp_server_get_services() 162verify(len(services) == len(nodes_non_br)) 163 164# Ensure that all registered addresses are derived from BR1 OMR. 165 166for host in hosts: 167 verify(host['addresses'][0].startswith(br1_local_omr[:-4])) 168 169# Start SRP server on BR2 170 171br2.srp_server_set_addr_mode('unicast') 172br2.srp_server_auto_enable() 173 174time.sleep(1) 175 176verify(br2.srp_server_get_state() == 'running') 177 178# De-activate BR1 179 180br1.br_disable() 181br1.thread_stop() 182br1.interface_down() 183del br1 184 185c1.allowlist_node(br2) 186br2.allowlist_node(c1) 187 188# Wait long enough for BR2 to take over 189 190time.sleep(5) 191 192# Validate that everything is registered with BR2 193 194hosts = br2.srp_server_get_hosts() 195verify(len(hosts) == len(nodes_non_br)) 196 197services = br2.srp_server_get_services() 198verify(len(services) == len(nodes_non_br)) 199 200# Ensure that all registered addresses are now derived from BR2 201# OMR prefix. 202 203for host in hosts: 204 verify(host['addresses'][0].startswith(br2_local_omr[:-4])) 205 206# ----------------------------------------------------------------------------------------------------------------------- 207# Test finished 208 209cli.Node.finalize_all_nodes() 210 211print('\'{}\' passed.'.format(test_name)) 212