diff --git a/.github/workflows/simulation-1.4.yml b/.github/workflows/simulation-1.4.yml index 26c40237d..ff7bf9e38 100644 --- a/.github/workflows/simulation-1.4.yml +++ b/.github/workflows/simulation-1.4.yml @@ -121,59 +121,6 @@ jobs: path: tmp/coverage.info retention-days: 1 - packet-verification-1-1-on-1-4: - runs-on: ubuntu-24.04 - env: - REFERENCE_DEVICE: 1 - VIRTUAL_TIME: 1 - OT_VT_USE_UNIX_SOCKET: 1 - PACKET_VERIFICATION: 1 - THREAD_VERSION: 1.4 - INTER_OP_BBR: 1 - MULTIPLY: 3 - steps: - - name: Harden Runner - uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2 - with: - egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - submodules: recursive - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: '3.12' - cache: pip - - name: Bootstrap - run: | - sudo apt-get update - sudo apt-get --no-install-recommends install -y ninja-build lcov - python3 -m pip install -r tests/scripts/thread-cert/requirements.txt - - name: Build - run: | - ./script/test build - - name: Get Thread-Wireshark - run: | - ./script/test get_thread_wireshark - - name: Run - run: | - ./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - if: ${{ failure() }} - with: - name: packet-verification-1.1-on-1.4-pcaps - path: | - *.pcap - *.json - - name: Generate Coverage - run: | - ./script/test generate_coverage gcc - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - with: - name: cov-packet-verification-1-1-on-1-4 - path: tmp/coverage.info - retention-days: 1 - channel-manager-csl: runs-on: ubuntu-24.04 env: @@ -276,7 +223,6 @@ jobs: upload-coverage: needs: - thread-1-4 - - packet-verification-1-1-on-1-4 - expects runs-on: ubuntu-22.04 steps: diff --git a/tests/scripts/thread-cert/v1_2_router_5_1_1.py b/tests/scripts/thread-cert/v1_2_router_5_1_1.py deleted file mode 100755 index 146b2b55b..000000000 --- a/tests/scripts/thread-cert/v1_2_router_5_1_1.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2019, 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 unittest - -import config -import thread_cert -import mle -import network_layer - -LEADER = 1 -ROUTER_1 = 2 - - -class Router_5_1_01(thread_cert.TestCase): - TOPOLOGY = { - LEADER: { - 'version': '1.2' - }, - ROUTER_1: { - 'version': '1.2' - }, - } - """All nodes are created with default configurations""" - - def test(self): - self.nodes[ROUTER_1].set_router_selection_jitter(1) - - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER_1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER_1].get_state(), 'router') - - leader_messages = self.simulator.get_messages_sent_by(LEADER) - router_messages = self.simulator.get_messages_sent_by(ROUTER_1) - - # 1 - Leader transmits MLE advertisements - msg = leader_messages.next_mle_message(mle.CommandType.ADVERTISEMENT) - msg.assertSentWithHopLimit(255) - msg.assertSentToDestinationAddress('ff02::1') - msg.assertMleMessageContainsTlv(mle.SourceAddress) - msg.assertMleMessageContainsTlv(mle.LeaderData) - msg.assertMleMessageContainsTlv(mle.Route64) - - # 2 - Router_1 begins attach process by sending a multicast MLE Parent Request - msg = router_messages.next_mle_message(mle.CommandType.PARENT_REQUEST) - msg.assertSentWithHopLimit(255) - msg.assertSentToDestinationAddress('ff02::2') - msg.assertMleMessageContainsTlv(mle.Mode) - msg.assertMleMessageContainsTlv(mle.Challenge) - msg.assertMleMessageContainsTlv(mle.ScanMask) - msg.assertMleMessageContainsTlv(mle.Version) - self.assertGreaterEqual(msg.get_mle_message_tlv(mle.Version).version, config.THREAD_VERSION_1_2) - - scan_mask_tlv = msg.get_mle_message_tlv(mle.ScanMask) - self.assertEqual(1, scan_mask_tlv.router) - self.assertEqual(0, scan_mask_tlv.end_device) - - # 3 - Leader sends a MLE Parent Response - msg = leader_messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - msg.assertSentToNode(self.nodes[ROUTER_1]) - msg.assertMleMessageContainsTlv(mle.SourceAddress) - msg.assertMleMessageContainsTlv(mle.LeaderData) - msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter) - msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter) - msg.assertMleMessageContainsTlv(mle.Response) - msg.assertMleMessageContainsTlv(mle.Challenge) - msg.assertMleMessageContainsTlv(mle.LinkMargin) - msg.assertMleMessageContainsTlv(mle.Connectivity) - msg.assertMleMessageContainsTlv(mle.Version) - self.assertGreaterEqual(msg.get_mle_message_tlv(mle.Version).version, config.THREAD_VERSION_1_2) - - # 4 - Router_1 receives the MLE Parent Response and sends a Child ID Request - msg = router_messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[LEADER]) - msg.assertMleMessageContainsTlv(mle.Response) - msg.assertMleMessageContainsTlv(mle.LinkLayerFrameCounter) - msg.assertMleMessageContainsOptionalTlv(mle.MleFrameCounter) - msg.assertMleMessageContainsTlv(mle.Mode) - msg.assertMleMessageContainsTlv(mle.Timeout) - msg.assertMleMessageContainsTlv(mle.Version) - msg.assertMleMessageContainsTlv(mle.TlvRequest) - msg.assertMleMessageDoesNotContainTlv(mle.AddressRegistration) - self.assertGreaterEqual(msg.get_mle_message_tlv(mle.Version).version, config.THREAD_VERSION_1_2) - - # 5 - Leader responds with a Child ID Response - msg = leader_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE) - msg.assertSentToNode(self.nodes[ROUTER_1]) - msg.assertMleMessageContainsTlv(mle.SourceAddress) - msg.assertMleMessageContainsTlv(mle.LeaderData) - msg.assertMleMessageContainsTlv(mle.Address16) - msg.assertMleMessageContainsOptionalTlv(mle.NetworkData) - msg.assertMleMessageContainsOptionalTlv(mle.Route64) - msg.assertMleMessageContainsOptionalTlv(mle.AddressRegistration) - - # 6 - Router_1 sends an Address Solicit Request - msg = router_messages.next_coap_message('0.02') - msg.assertCoapMessageRequestUriPath('/a/as') - msg.assertCoapMessageContainsTlv(network_layer.MacExtendedAddress) - msg.assertCoapMessageContainsTlv(network_layer.Status) - - # 7 - Leader sends an Address Solicit Response - msg = leader_messages.next_coap_message('2.04') - msg.assertCoapMessageContainsTlv(network_layer.Status) - msg.assertCoapMessageContainsOptionalTlv(network_layer.RouterMask) - - status_tlv = msg.get_coap_message_tlv(network_layer.Status) - self.assertEqual(network_layer.StatusValues.SUCCESS, status_tlv.status) - - # 8 - Router_1 Transmit MLE advertisements - msg = router_messages.next_mle_message(mle.CommandType.ADVERTISEMENT) - msg.assertSentWithHopLimit(255) - msg.assertSentToDestinationAddress('ff02::1') - msg.assertMleMessageContainsTlv(mle.SourceAddress) - msg.assertMleMessageContainsTlv(mle.LeaderData) - msg.assertMleMessageContainsTlv(mle.Route64) - - # 9 - Verify connectivity by sending an ICMPv6 Echo Request to the DUT link local address - self.assertTrue(self.nodes[LEADER].ping(self.nodes[ROUTER_1].get_linklocal())) - self.assertTrue(self.nodes[ROUTER_1].ping(self.nodes[LEADER].get_linklocal())) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/v1_2_test_parent_selection.py b/tests/scripts/thread-cert/v1_2_test_parent_selection.py deleted file mode 100755 index caf979f19..000000000 --- a/tests/scripts/thread-cert/v1_2_test_parent_selection.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2019, 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 unittest - -import thread_cert -import config -import mle - -LEADER_1_2 = 1 -ROUTER_1_1 = 2 -REED_1_2 = 3 -ROUTER_1_2 = 4 -REED_1_1 = 5 -MED_1_1 = 6 -MED_1_2 = 7 - -# Topology -# (lq:2) (pp:1) -# REED_1_2 ----- ROUTER_1_2 -# | \ / | \ -# | \/ REED_1_1 \ -# (lq:2) | / \ / `router` \ -# | (lq:2) \ \ -# | / / \ \ -# LEADER_1_2 --- ROUTER_1_1 -- MED_1_2 -# \ | -# \ | -# \ | -# MED_1_1 -# -# 1) Bring up LEADER_1_2 and ROUTER_1_1, -# 2) Config link quality (LEADER_1_2->REED_1_2) as 2, bring up REED_1_2 which would attach to ROUTER_1_1 -# due to higher two-way link quality, -# 3) Config link quality(LEADER_1_2->ROUTER_1_2) and link quality(REED_1_2->ROUTER_1_2) as 2, bring up -# ROUTER_1_2 which would attach to LEADER_1_2 due to active router is preferred, -# 4) Config parent priority as 1 on ROUTER_1_2, bring up REED_1_1 which would attach to ROUTER_1_2 due to -# higher parent priority, -# 5) Upgrade REED_1_1 to `router` role, bring up MED_1_1 which would attach to LEADER_1_2 which has higher -# link quality of 3, -# 6) Config parent priority as 1 on ROUTER_1_1, bring up MED_1_2 which would attach to ROUTER_1_2 due to -# higher version -# - - -class TestParentSelection(thread_cert.TestCase): - TOPOLOGY = { - LEADER_1_2: { - 'version': '1.2', - 'allowlist': [REED_1_2, ROUTER_1_2, REED_1_1, ROUTER_1_1, MED_1_1], - }, - ROUTER_1_1: { - 'version': '1.1', - 'allowlist': [LEADER_1_2, REED_1_2, MED_1_2, MED_1_1], - }, - REED_1_2: { - 'version': '1.2', - 'allowlist': [ROUTER_1_2, ROUTER_1_1, LEADER_1_2], - }, - ROUTER_1_2: { - 'version': '1.2', - 'allowlist': [REED_1_2, MED_1_2, REED_1_1, LEADER_1_2], - }, - REED_1_1: { - 'version': '1.1', - 'allowlist': [ROUTER_1_2, LEADER_1_2] - }, - MED_1_1: { - 'mode': 'r', - 'version': '1.1', - 'allowlist': [LEADER_1_2, ROUTER_1_1], - }, - MED_1_2: { - 'mode': 'r', - 'version': '1.2', - 'allowlist': [ROUTER_1_1, ROUTER_1_2], - }, - } - """All nodes are created with default configurations""" - - def test(self): - - self.nodes[LEADER_1_2].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER_1_2].get_state(), 'leader') - - self.nodes[ROUTER_1_1].set_router_selection_jitter(1) - self.nodes[ROUTER_1_1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router') - - # Mesh Impacting Criteria - Highest Two-way link quality - # REED_1_2 would attach to ROUTER_1_1 - # Attach to ROUTER_1_1 which has highest two-way link quality - - # Flush relative message queues - self.flush_nodes([LEADER_1_2, ROUTER_1_1]) - - self.nodes[LEADER_1_2].set_link_quality(self.nodes[REED_1_2].get_addr64(), 2) - self.nodes[REED_1_2].set_router_selection_jitter(1) - self.nodes[REED_1_2].set_router_upgrade_threshold(1) - self.nodes[REED_1_2].start() - self.simulator.go(5) - self.assertEqual(self.nodes[REED_1_2].get_state(), 'child') - - # Check Parent Response - messages = self.simulator.get_messages_sent_by(ROUTER_1_1) - parent_prefer = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_prefer), "Error: Expected parent response not found" - - messages = self.simulator.get_messages_sent_by(LEADER_1_2) - parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_cmp), "Error: Expected parent response not found" - - # Known that link margin for link quality 3 is 80 and link quality 2 is 15 - self.assertGreater((parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin - - parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin), 20) - - # Check Child Id Request - messages = self.simulator.get_messages_sent_by(REED_1_2) - msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[ROUTER_1_1]) - - # Mesh Impacting Criteria - Active Routers over REEDs - # ROUTER_1_2 would attach to LEADER_1_2 - # Link quality configuration, so that REED_1_2 has the chance to respond - - # Flush relative message queues - self.flush_nodes([LEADER_1_2, REED_1_2]) - - self.nodes[LEADER_1_2].set_link_quality(self.nodes[ROUTER_1_2].get_addr64(), 2) - self.nodes[REED_1_2].set_link_quality(self.nodes[ROUTER_1_2].get_addr64(), 2) - self.nodes[ROUTER_1_2].set_router_selection_jitter(1) - self.nodes[ROUTER_1_2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER_1_2].get_state(), 'router') - - # Check Parent Response - messages = self.simulator.get_messages_sent_by(LEADER_1_2) - - # Skip first response for first parent request - assert messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - - parent_prefer = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_prefer), "Error: Expected parent response not found" - - messages = self.simulator.get_messages_sent_by(REED_1_2) - parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_cmp), "Error: Expected parent response not found" - - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin, - parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin) - - # Check Child Id Request - messages = self.simulator.get_messages_sent_by(ROUTER_1_2) - msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[LEADER_1_2]) - - # Mesh Impacting Criteria - Highest Parent Priority value in the Connectivity TLV - # REED_1_1 would attach to ROUTER_1_2 - - # Flush relative message queues - self.flush_nodes([LEADER_1_2, ROUTER_1_2]) - - self.nodes[ROUTER_1_2].set_parent_priority(1) - self.nodes[REED_1_1].set_router_selection_jitter(1) - self.nodes[REED_1_1].set_router_upgrade_threshold(1) - self.nodes[REED_1_1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[REED_1_1].get_state(), 'child') - - # Check Parent Response - messages = self.simulator.get_messages_sent_by(ROUTER_1_2) - parent_prefer = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_prefer), "Error: Expected parent response not found" - - messages = self.simulator.get_messages_sent_by(LEADER_1_2) - parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_cmp), "Error: Expected parent response not found" - - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin, - parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin) - - self.assertGreater( - parent_prefer.get_mle_message_tlv(mle.Connectivity).pp, - parent_cmp.get_mle_message_tlv(mle.Connectivity).pp) - - # Check Child Id Request - messages = self.simulator.get_messages_sent_by(REED_1_1) - msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[ROUTER_1_2]) - - # Mesh Impacting Criteria - Router with the most high-quality neighbors - # (Link Quality 3 field in the Connectivity TLV) - # MED_1_1 would attach to LEADER_1_2 - - self.nodes[REED_1_1].set_state('router') - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[REED_1_1].get_state(), 'router') - - # Flush relative message queues - self.flush_nodes([LEADER_1_2, ROUTER_1_1]) - - self.nodes[MED_1_1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED_1_1].get_state(), 'child') - - # Check Parent Response - messages = self.simulator.get_messages_sent_by(LEADER_1_2) - parent_prefer = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_prefer), "Error: Expected parent response not found" - - messages = self.simulator.get_messages_sent_by(ROUTER_1_1) - parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_cmp), "Error: Expected parent response not found" - - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin, - parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin) - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.Connectivity).pp, - parent_cmp.get_mle_message_tlv(mle.Connectivity).pp) - self.assertGreater( - parent_prefer.get_mle_message_tlv(mle.Connectivity).link_quality_3, - parent_cmp.get_mle_message_tlv(mle.Connectivity).link_quality_3) - - # Check Child Id Request - messages = self.simulator.get_messages_sent_by(MED_1_1) - msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[LEADER_1_2]) - - # Child Impacting Criteria - A Version number in the Version TLV - # equal to or higher than the version that implements features - # desirable to the Child MED_1_2 would attach to ROUTER_1_2 - - # Flush relative message queues - self.flush_nodes([ROUTER_1_2, ROUTER_1_1]) - - self.nodes[ROUTER_1_1].set_parent_priority(1) - self.nodes[MED_1_2].start() - self.simulator.go(15) - self.assertEqual(self.nodes[MED_1_2].get_state(), 'child') - - # Check Parent Response - messages = self.simulator.get_messages_sent_by(ROUTER_1_2) - parent_prefer = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_prefer), "Error: Expected parent response not found" - - messages = self.simulator.get_messages_sent_by(ROUTER_1_1) - parent_cmp = messages.next_mle_message(mle.CommandType.PARENT_RESPONSE) - assert (parent_cmp), "Error: Expected parent response not found" - - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.LinkMargin).link_margin, - parent_cmp.get_mle_message_tlv(mle.LinkMargin).link_margin) - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.Connectivity).pp, - parent_cmp.get_mle_message_tlv(mle.Connectivity).pp) - self.assertEqual( - parent_prefer.get_mle_message_tlv(mle.Connectivity).link_quality_3, - parent_cmp.get_mle_message_tlv(mle.Connectivity).link_quality_3) - self.assertGreater( - parent_prefer.get_mle_message_tlv(mle.Version).version, - parent_cmp.get_mle_message_tlv(mle.Version).version) - - # Check Child Id Request - messages = self.simulator.get_messages_sent_by(MED_1_2) - msg = messages.next_mle_message(mle.CommandType.CHILD_ID_REQUEST) - msg.assertSentToNode(self.nodes[ROUTER_1_2]) - - -if __name__ == '__main__': - unittest.main()