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: Partition formation and merge 36# 37# Network Topology: 38# 39# r1 ---- / ---- r2 40# | \ | 41# | / | 42# c1 \ c2 43# 44# 45# Test covers the following situations: 46# 47# - r2 forming its own partition when it can no longer hear r1 48# - Partitions merging into one once r1 and r2 can talk again 49# - Adding on-mesh prefixes on each partition and ensuring after 50# merge the info in combined. 51# 52 53test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 54print('-' * 120) 55print('Starting \'{}\''.format(test_name)) 56 57# ----------------------------------------------------------------------------------------------------------------------- 58# Creating `cli.Nodes` instances 59 60speedup = 25 61cli.Node.set_time_speedup_factor(speedup) 62 63r1 = cli.Node() 64r2 = cli.Node() 65c1 = cli.Node() 66c2 = cli.Node() 67 68# ----------------------------------------------------------------------------------------------------------------------- 69# Form topology 70 71r1.allowlist_node(r2) 72r1.allowlist_node(c1) 73 74r2.allowlist_node(r1) 75r2.allowlist_node(c2) 76 77r1.form("partmrge") 78r2.join(r1) 79c1.join(r1, cli.JOIN_TYPE_END_DEVICE) 80c2.join(r2, cli.JOIN_TYPE_END_DEVICE) 81 82verify(r1.get_state() == 'leader') 83verify(r2.get_state() == 'router') 84verify(c1.get_state() == 'child') 85verify(c2.get_state() == 'child') 86 87nodes = [r1, r2, c1, c2] 88 89# ----------------------------------------------------------------------------------------------------------------------- 90# Test Implementation 91 92# Force the two routers to form their own partition 93# by removing them from each other's allowlist table 94 95r1.un_allowlist_node(r2) 96r2.un_allowlist_node(r1) 97 98# Add a prefix before r2 realizes it can no longer talk 99# to leader (r1). 100 101r2.add_prefix('fd00:abba::/64', 'paros', 'med') 102r2.register_netdata() 103 104# Check that r2 forms its own partition 105 106 107def check_r2_become_leader(): 108 verify(r2.get_state() == 'leader') 109 110 111verify_within(check_r2_become_leader, 20) 112 113# While we have two partition, add a prefix on r1 114r1.add_prefix('fd00:1234::/64', 'paros', 'med') 115r1.register_netdata() 116 117# Update allowlist and wait for partitions to merge. 118r1.allowlist_node(r2) 119r2.allowlist_node(r1) 120 121 122def check_partition_id_match(): 123 verify(r1.get_partition_id() == r2.get_partition_id()) 124 125 126verify_within(check_partition_id_match, 20) 127 128# Check that partitions merged successfully 129 130 131def check_r1_r2_roles(): 132 verify(r1.get_state() in ['leader', 'router']) 133 verify(r2.get_state() in ['leader', 'router']) 134 135 136verify_within(check_r1_r2_roles, 10) 137 138# Verify all nodes see both prefixes 139 140 141def check_netdata_on_all_nodes(): 142 for node in nodes: 143 netdata = node.get_netdata() 144 verify(len(netdata['prefixes']) == 2) 145 146 147verify_within(check_netdata_on_all_nodes, 10) 148 149# ----------------------------------------------------------------------------------------------------------------------- 150# Test finished 151 152cli.Node.finalize_all_nodes() 153 154print('\'{}\' passed.'.format(test_name)) 155