1#!/usr/bin/env python3 2# 3# Copyright (c) 2021, 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# 29 30import config 31import ipaddress 32import unittest 33 34import command 35import config 36import thread_cert 37 38# Test description: 39# This test verifies Anycast Locator functionality 40# 41# Topology: 42# 43# LEADER -- ROUTER1 -- ROUTER2 -- ROUTER3 -- ROUTER4 44# 45 46LEADER = 1 47ROUTER1 = 2 48ROUTER2 = 3 49ROUTER3 = 4 50ROUTER4 = 5 51 52SRV_ENT_NUMBER = '44970' 53SRV_SERVICE_DATA = '571234' 54SRV_SERVER_DATA = '00' 55 56 57class AnycastLocator(thread_cert.TestCase): 58 USE_MESSAGE_FACTORY = False 59 SUPPORT_NCP = False 60 61 TOPOLOGY = { 62 LEADER: { 63 'name': 'LEADER', 64 'mode': 'rdn', 65 'allowlist': [ROUTER1] 66 }, 67 ROUTER1: { 68 'name': 'ROUTER1', 69 'mode': 'rdn', 70 'allowlist': [LEADER, ROUTER2] 71 }, 72 ROUTER2: { 73 'name': 'ROUTER2', 74 'mode': 'rdn', 75 'allowlist': [ROUTER1, ROUTER3] 76 }, 77 ROUTER3: { 78 'name': 'ROUTER3', 79 'mode': 'rdn', 80 'allowlist': [ROUTER2, ROUTER4] 81 }, 82 ROUTER4: { 83 'name': 'ROUTER4', 84 'mode': 'rdn', 85 'allowlist': [ROUTER3] 86 }, 87 } 88 89 def test(self): 90 leader = self.nodes[LEADER] 91 router1 = self.nodes[ROUTER1] 92 router2 = self.nodes[ROUTER2] 93 router3 = self.nodes[ROUTER3] 94 router4 = self.nodes[ROUTER4] 95 nodes = [leader, router1, router2, router3, router4] 96 97 # 98 # 0. Start the leader and routers 99 # 100 101 leader.start() 102 self.simulator.go(config.LEADER_STARTUP_DELAY) 103 self.assertEqual(leader.get_state(), 'leader') 104 105 for node in nodes[1:]: 106 node.start() 107 self.simulator.go(config.ROUTER_STARTUP_DELAY) 108 self.assertEqual(node.get_state(), 'router') 109 110 # 111 # 1. Locate leader ALOC from all nodes 112 # 113 114 leader_aloc = leader.get_addr_leader_aloc() 115 116 for node in nodes: 117 result = node.locate(leader_aloc) 118 self.assertEqual(result[0], leader.get_mleid()) 119 self.assertEqual(int(result[1], 0), leader.get_addr16()) 120 121 # 122 # 2. Add a service on router4 and locate its ALOC 123 # 124 125 router4.add_service(SRV_ENT_NUMBER, SRV_SERVICE_DATA, SRV_SERVER_DATA) 126 router4.register_netdata() 127 self.simulator.go(5) 128 services = leader.get_services() 129 self.assertEqual(len(services), 1) 130 131 service_aloc = router4.get_ip6_address(config.ADDRESS_TYPE.ALOC)[0] 132 133 for node in nodes: 134 result = node.locate(service_aloc) 135 self.assertEqual(result[0], router4.get_mleid()) 136 self.assertEqual(int(result[1], 0), router4.get_addr16()) 137 138 # 139 # 3. Add same service on leader and ensure we locate the closest ALOC destination 140 # 141 142 leader.add_service(SRV_ENT_NUMBER, SRV_SERVICE_DATA, SRV_SERVER_DATA) 143 leader.register_netdata() 144 self.simulator.go(5) 145 services = leader.get_services() 146 self.assertEqual(len(services), 2) 147 148 # leader and router1 should locate leader as closest service ALOC, 149 # router3 and router4 should locate router4. router2 is in middle 150 # and can locate either one. 151 for node in [leader, router1]: 152 result = node.locate(service_aloc) 153 self.assertEqual(result[0], leader.get_mleid()) 154 self.assertEqual(int(result[1], 0), leader.get_addr16()) 155 156 for node in [router3, router4]: 157 result = node.locate(service_aloc) 158 self.assertEqual(result[0], router4.get_mleid()) 159 self.assertEqual(int(result[1], 0), router4.get_addr16()) 160 161 result = router2.locate(service_aloc) 162 self.assertTrue(result[0] in [leader.get_mleid(), router4.get_mleid()]) 163 self.assertTrue(int(result[1], 0) in [leader.get_addr16(), router4.get_addr16()]) 164 165 166if __name__ == '__main__': 167 unittest.main() 168