diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index 1c7f5e2cc..dc48eafe1 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -62,7 +62,7 @@ Local::Local(Instance &aInstance) // Primary Backbone Router Aloc mBackboneRouterPrimaryAloc.InitAsThreadOriginRealmLocalScope(); - mBackboneRouterPrimaryAloc.GetAddress().GetIid().SetLocator(Mle::kAloc16BackboneRouterPrimary); + mBackboneRouterPrimaryAloc.GetAddress().GetIid().SetToLocator(Mle::kAloc16BackboneRouterPrimary); // All Network Backbone Routers Multicast Address. mAllNetworkBackboneRouters.Clear(); diff --git a/tests/scripts/thread-cert/test_pbbr_aloc.py b/tests/scripts/thread-cert/test_pbbr_aloc.py new file mode 100755 index 000000000..be55cb63f --- /dev/null +++ b/tests/scripts/thread-cert/test_pbbr_aloc.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2021, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +import re +import unittest + +import thread_cert +from config import MESH_LOCAL_PREFIX_REGEX_PATTERN, ROUTING_LOCATOR_REGEX_PATTERN +from pktverify.packet_verifier import PacketVerifier + +# Test description: +# The purpose of this test is to verify ALOC connectivity. +# +# Topology: +# +# +# PBBR ----- LEADER ---- ROUTER +# +# + +LEADER = 1 +PBBR = 2 +ROUTER = 3 + + +class TestPing(thread_cert.TestCase): + USE_MESSAGE_FACTORY = False + SUPPORT_NCP = False + SUPPORT_THREAD_1_1 = False + + TOPOLOGY = { + LEADER: { + 'name': 'Router_1', + 'allowlist': [PBBR, ROUTER], + 'router_selection_jitter': 2, + }, + PBBR: { + 'name': 'Router_2', + 'allowlist': [LEADER], + 'router_selection_jitter': 2, + 'is_bbr': True, + }, + ROUTER: { + 'name': 'Router_3', + 'allowlist': [LEADER], + 'router_selection_jitter': 2, + }, + } + + def test(self): + leader = self.nodes[LEADER] + pbbr = self.nodes[PBBR] + router = self.nodes[ROUTER] + + leader.start() + self.simulator.go(5) + self.assertEqual('leader', leader.get_state()) + + pbbr.enable_backbone_router() + pbbr.start() + self.simulator.go(10) + self.assertEqual('router', pbbr.get_state()) + self.assertTrue(pbbr.is_primary_backbone_router) + + router.start() + self.simulator.go(10) + self.assertEqual('router', router.get_state()) + + for node in (leader, pbbr): + for addr in self.get_alocs(node): + self.assertTrue(router.ping(addr)) + + def verify(self, pv: PacketVerifier): + pkts = pv.pkts + # Must sure no ADDR_QUERY.qry is ever sent + pkts.filter_coap_request('/a/aq').must_not_next() + + def get_alocs(self, node): + mleid = node.get_mleid() + for ip in node.get_addrs(): + if not re.match(MESH_LOCAL_PREFIX_REGEX_PATTERN, ip): + continue + + if ip == mleid: + continue + + self.assertIsNotNone(re.match(ROUTING_LOCATOR_REGEX_PATTERN, ip), ip) + locator = int(ip.split(':')[-1], 16) + if locator >= 0xfc00: + yield ip + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/scripts/thread-cert/thread_cert.py b/tests/scripts/thread-cert/thread_cert.py index 6d61a5c56..de4dab564 100644 --- a/tests/scripts/thread-cert/thread_cert.py +++ b/tests/scripts/thread-cert/thread_cert.py @@ -93,6 +93,7 @@ class TestCase(NcpSupportMixin, unittest.TestCase): USE_MESSAGE_FACTORY = True TOPOLOGY = None CASE_WIRESHARK_PREFS = None + SUPPORT_THREAD_1_1 = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -103,6 +104,9 @@ class TestCase(NcpSupportMixin, unittest.TestCase): self._do_packet_verification = PACKET_VERIFICATION and hasattr(self, 'verify') def setUp(self): + if ENV_THREAD_VERSION == '1.1' and not self.SUPPORT_THREAD_1_1: + self.skipTest('Thread 1.1 not supported.') + try: self._setUp() except: @@ -246,7 +250,7 @@ class TestCase(NcpSupportMixin, unittest.TestCase): f'{self.test_name}: Packet Verification not available on {os.uname().sysname} (Linux only).') if self._do_packet_verification: - time.sleep(3) + self.simulator.go(3) if self._has_backbone_traffic(): # Stop Backbone sniffer before stopping nodes so that we don't capture Codecov Uploading traffic diff --git a/third_party/openthread-test-driver/test-driver b/third_party/openthread-test-driver/test-driver index 03ae4fe5e..96f6db86f 100755 --- a/third_party/openthread-test-driver/test-driver +++ b/third_party/openthread-test-driver/test-driver @@ -116,7 +116,7 @@ while true; do done # Run a test -TEST_NAME="${test_name}" PORT_OFFSET=$OFFSET "$@" >$log_file 2>&1 +TEST_NAME="${test_name}" PORT_OFFSET=$OFFSET python3 "$@" >$log_file 2>&1 estatus=$? # Return the offset