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: 36# 37# Verifies `ChannelManager` channel change process. 38# 39# Network Topology: 40# 41# r1 --- r2 --- r3 42# /\ | | 43# / \ | | 44# sc1 ec1 sc2 sc3 45# 46 47test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 48print('-' * 120) 49print('Starting \'{}\''.format(test_name)) 50 51# ----------------------------------------------------------------------------------------------------------------------- 52# Creating `cli.Node` instances 53 54speedup = 20 55cli.Node.set_time_speedup_factor(speedup) 56 57r1 = cli.Node() 58r2 = cli.Node() 59r3 = cli.Node() 60sc1 = cli.Node() 61ec1 = cli.Node() 62sc2 = cli.Node() 63sc3 = cli.Node() 64 65nodes = [r1, r2, r3, sc1, ec1, sc2, sc3] 66 67# ----------------------------------------------------------------------------------------------------------------------- 68# Form topology 69 70r1.allowlist_node(r2) 71r1.allowlist_node(sc1) 72r1.allowlist_node(ec1) 73 74r2.allowlist_node(r1) 75r2.allowlist_node(r3) 76r2.allowlist_node(sc2) 77 78r3.allowlist_node(r2) 79r3.allowlist_node(sc3) 80 81sc1.allowlist_node(r1) 82ec1.allowlist_node(r1) 83sc2.allowlist_node(r2) 84sc3.allowlist_node(r3) 85 86r1.form('chan-man', channel=11) 87r2.join(r1) 88r3.join(r1) 89sc1.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE) 90ec1.join(r1, cli.JOIN_TYPE_END_DEVICE) 91sc2.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE) 92sc3.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE) 93 94sc1.set_pollperiod(500) 95sc2.set_pollperiod(500) 96sc3.set_pollperiod(500) 97 98verify(r1.get_state() == 'leader') 99verify(r2.get_state() == 'router') 100verify(r3.get_state() == 'router') 101verify(ec1.get_state() == 'child') 102verify(sc1.get_state() == 'child') 103verify(sc2.get_state() == 'child') 104verify(sc3.get_state() == 'child') 105 106# ----------------------------------------------------------------------------------------------------------------------- 107# Test Implementation 108 109result = cli.Node.parse_list(r1.cli('channel manager')) 110verify(result['channel'] == '0') 111verify(result['auto'] == '0') 112 113r1.cli('channel manager delay 4') 114verify(int(r1.cli('channel manager delay')[0]) == 4) 115 116channel = 11 117 118 119def check_channel_on_all_nodes(): 120 verify(all(int(node.get_channel()) == channel for node in nodes)) 121 122 123verify_within(check_channel_on_all_nodes, 10) 124 125# Request a channel change to channel 13 from router r1. Verify 126# that all nodes switch to the new channel. 127 128channel = 13 129r1.cli('channel manager change', channel) 130verify_within(check_channel_on_all_nodes, 10) 131 132# Request same channel change on multiple routers at the same time. 133 134channel = 14 135r1.cli('channel manager change', channel) 136r2.cli('channel manager change', channel) 137r3.cli('channel manager change', channel) 138verify_within(check_channel_on_all_nodes, 10) 139 140# Request different channel changes from same router back-to-back. 141 142channel = 15 143r1.cli('channel manager change', channel) 144time.sleep(1 / speedup) 145channel = 16 146r1.cli('channel manager change', channel) 147verify_within(check_channel_on_all_nodes, 10) 148 149# Request different channels from two routers (r1 and r2). 150# We increase delay on r1 to make sure r1 is in middle of 151# channel when new change is requested from r2. 152 153r1.cli('channel manager delay 20') 154r1.cli('channel manager change 17') 155time.sleep(5 / speedup) 156verify_within(check_channel_on_all_nodes, 10) 157channel = 18 158r2.cli('channel manager change', channel) 159verify_within(check_channel_on_all_nodes, 10) 160 161# ----------------------------------------------------------------------------------------------------------------------- 162# Test finished 163 164cli.Node.finalize_all_nodes() 165 166print('\'{}\' passed.'.format(test_name)) 167