def test05_child_quick_re_attach_after_parent_reset(self):
        # Check the child recovery after a parent reset using quick re-attach
        # achieved via "Child Update" exchange.

        self.logger.info("Disable supervision check on the child {}.".format(
            self.child.name))
        self.child.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, "1000")
        self.child.set(wpan.WPAN_POLL_INTERVAL, "10000")
        time.sleep(0.1)

        # We use the "stat:ncp" wpantund property to verify that child does not
        # get detached.
        child_num_state_changes = len(
            wpan_table_parser.parse_list(self.child.get("stat:ncp")))

        # Reset parent and wait for it to be associated.
        self.parent.reset_thread_radio()
        self.wait_for_completion(self.device_list)

        def check_parent_is_associated():
            verify(is_associated(self.parent))

        verify_within(check_parent_is_associated, WAIT_TIME)

        self.child.set(wpan.WPAN_POLL_INTERVAL, "100")

        # Verify that we again see all the child addresses in the parent's child
        # table. Note that child should register its addresses using "Child Update
        # Request" exchange.
        verify_within(self.check_child_addresses_on_parent, WAIT_TIME)

        # Verify that there was no state change on child.
        self.assertEqual(
            child_num_state_changes,
            len(wpan_table_parser.parse_list(self.child.get("stat:ncp"))))
Пример #2
0
    def test03_Add_Multicast_Address(self):

        for node in self.device_list:
            node.add(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
            addrs = wpan_table_parser.parse_list(
                node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
            verify(MCAST_ADDR in addrs)

            node.remove(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
            addrs = wpan_table_parser.parse_list(
                node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
            verify(not MCAST_ADDR in addrs)
        def check_off_mesh_routes():
            # If a node itself adds a route, the route entry will be seen twice in
            # its WPAN_THREAD_OFF_MESH_ROUTES list (one time as part of network-wide
            # network data and again as part of the local network data). Note that
            # `r1 and `r2` each add a route, while `sed2` does not.
            r1_routes = wpan_table_parser.parse_list(
                self.r1.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))
            self.assertEqual(len(r1_routes), NUM_ROUTES + NUM_ROUTES_LOCAL)

            r2_routes = wpan_table_parser.parse_list(
                self.r2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))
            self.assertEqual(len(r2_routes), NUM_ROUTES + NUM_ROUTES_LOCAL)

            sed2_routes = wpan_table_parser.parse_list(
                self.sed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))
            self.assertEqual(len(sed2_routes), NUM_ROUTES)
 def check_ip6_addresses():
     # Verify that SLAAC addresses are removed on r2 and fed1
     wpan_util.verify_no_address([self.r2, self.fed1], PREFIX)
     # And that user-added address matching the prefix is not removed on r1
     r1_addrs = wpan_table_parser.parse_list(
         self.r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
     verify(IP_ADDRESS in r1_addrs)
Пример #5
0
    def test03_Change_Parent(self):
        # Remove the `child` from allowlist of `parent2` and add it to allowlist of `parent1` instead.
        self.child_num_state_changes = len(
            wpan_table_parser.parse_list(self.child1.get("stat:ncp")))

        print(self.child_num_state_changes)

        self.parent1.allowlist_node(self.child1)
        self.parent2.un_allowlist_node(self.child1)

        # Enable supervision check on the `child` and also on `parent1`.

        self.child1.setprop(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
                            str(CHILD_SUPERVISION_CHECK_TIMEOUT))
        self.parent1.setprop(wpan.WPAN_CHILD_SUPERVISION_INTERVAL,
                             str(PARENT_SUPERVISION_INTERVAL))

        # Since child supervision is not enabled on `parent2` and the `child` is
        # removed from allowlist on `parent2`, after the supervision check timeout
        # the `child` should realize that it can no longer talk to its current
        # parent (`parent2`) and try to reattach. All re-attach attempts to `parent2`
        # should fail (due to allowlist) and cause the `child` to get detached and
        # search for a new parent and then attach to `parent1`.
        #
        # To verify that the `child` does get detached and attach to a new parent, we
        # monitor the number of state changes using wpantund property "stat:ncp".

        verify_within(self.check_child_is_reattached, 60, 5)
Пример #6
0
    def check_child_is_reattached(self):
        child_stat_ncp_changes = len(
            wpan_table_parser.parse_list(self.child1.get("stat:ncp")))
        print(child_stat_ncp_changes)

        verify(child_stat_ncp_changes > self.child_num_state_changes)

        verify(is_associated(self.child1))
Пример #7
0
 def find_ip6_address_with_prefix(self, prefix):
     """Find an IPv6 address on node matching a given prefix.
     `prefix` should be an string containing the prefix.
     Returns a string containing the IPv6 address matching the prefix or
     empty string if no address found.
     """
     if len(prefix) > 2 and prefix[-1] == ":" and prefix[-2] == ":":
         prefix = prefix[:-1]
     all_addrs = wpan_table_parser.parse_list(
         self.get(wpan.WPAN_IP6_ALL_ADDRESSES))
     matched_addr = [addr for addr in all_addrs if addr.startswith(prefix)]
     return matched_addr[0] if len(matched_addr) >= 1 else ""
    def test03_Verify_Parent_Reset(self):
        # Remember number of NCP state changes (using "stat:ncp" property) per child
        child_num_state_changes = []
        for child in self.all_children:
            child_num_state_changes.append(len(wpan_table_parser.parse_list(child.get("stat:ncp"))))

        # Reset the parent
        self.router.reset_thread_radio()
        self.wait_for_completion(self.device_list)

        def check_parent_is_associated():
            verify(is_associated(self.router))

        verify_within(check_parent_is_associated, 20, 3)

        # Verify that all the children are recovered and present in the parent's child table again (within 30 seconds).
        verify_within(self.check_child_table, 30, 5)

        # Verify that number of state changes on all children stays as before (indicating they did not get detached).
        for i in range(len(self.all_children)):
            verify(
                child_num_state_changes[i] == len(wpan_table_parser.parse_list(self.all_children[i].get("stat:ncp"))))
Пример #9
0
    def test02_verify_router2_attaches_to_router1(self):
        # router2 is expected to attach to router1 and adopt the mesh-local prefix from router1
        verify(is_associated(self.router2))
        verify(
            self.router2.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX) ==
            self.router1.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX))

        # Ensure that no ipv6 address starting with ML_PREFIX_2 i.e. fd00:2:: is seen
        verify(self.router2.find_ip6_address_with_prefix(ML_PREFIX_2) == "")

        # There are only 3 addresses on the router2 (link-local and mesh-local address obtained from
        # ML_PREFIX_1 i.e. fd00:1:: and ipv6 address added on the router2 interface) and that RLOC
        # address is correctly filtered (by wpantund).
        self.assertEqual(
            len(
                wpan_table_parser.parse_list(
                    self.router2.get(wpan.WPAN_IP6_ALL_ADDRESSES))), 3)
    def test05_add_joiners_on_commissioner(self):
        self.commissioner.commissioner_start()
        self.wait_for_completion(self.device_list)

        # Add `joiner1` and `joiner2` using joiner discerner.
        self.commissioner.commissioner_add_joiner_with_discerner(
            DISCERNER1, D_LEN1, PSK1, JOINER_TIMOUT)
        self.commissioner.commissioner_add_joiner_with_discerner(
            DISCERNER2, D_LEN2, PSK2, JOINER_TIMOUT)

        # Add `joiner3` using EUI64 Hardware Address of joiner3.
        joiner3_hw_addr = self.joiner3.get(
            wpan.WPAN_HW_ADDRESS)[1:-1]  # Remove the `[]`
        self.commissioner.commissioner_add_joiner(joiner3_hw_addr, PSK3,
                                                  JOINER_TIMOUT)

        verify(
            len(
                wpan_table_parser.parse_list(
                    self.commissioner.get(
                        wpan.WPAN_THREAD_COMMISSIONER_JOINERS))) == 3)
    def test10_add_ipv6_address_for_same_prefix(self):
        # Explicitly add an ipv6 address with the prefix on r1, this should add the prefix on all nodes
        # but no ipv6 address should be added on other nodes
        self.r1.add_ip6_address_on_interface(IP_ADDRESS)

        # Add the prefix on r2 (with SLAAC flag), this should add SLAAC prefix on all nodes. And slaac related
        # ipv6 address on all nodes except r1 as it already has an address with SLAAC prefix
        self.r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
        self.wait_for_completion(self.device_list)
        verify_within(self.check_prefix_and_slaac_address_are_added,
                      WAIT_INTERVAL)

        # Verify that on r1 we do see the user-added address
        r1_addrs = wpan_table_parser.parse_list(
            self.r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
        verify(IP_ADDRESS in r1_addrs)

        # Also verify that adding the prefix on r2 did not add a SLAAC address for same prefix on r1
        r1_addrs.remove(IP_ADDRESS)
        self.logger.info("r1_addrs: {}".format(r1_addrs))
        self.wait_for_completion(self.device_list)
        verify(all([not addr.startswith(PREFIX[:-1]) for addr in r1_addrs]))
Пример #12
0
    def test04_verify_network_data_on_same_prefix_add_remove(self):
        # Repeat the `test_prefix_add_remove()` under different situations
        # where same prefix is added/removed by other nodes in the network
        # or added as an off-mesh route.

        num_routes = 0

        self.logger.info(
            f"========= Add same stable prefix {prefix1} on leader node ========="
        )
        self.leader.add_prefix(prefix1, stable=False)
        self.prefix_add_remove()

        self.logger.info(
            f"========= Add same temporary prefix {prefix2} on leader node ========="
        )
        self.leader.add_prefix(prefix2, stable=True)
        self.prefix_add_remove()

        self.logger.info(
            f"========= Remove stable prefix {prefix1} from leader node ========="
        )
        self.leader.remove_prefix(prefix1)
        self.prefix_add_remove()

        self.logger.info(
            f"========= Remove temporary prefix {prefix2} from leader node ========="
        )
        self.leader.remove_prefix(prefix2)
        self.prefix_add_remove()

        self.logger.info(
            f"-------- Add off-mesh route based on temporary prefix {prefix1} on leader node --------"
        )
        self.leader.add_route_using_prefix(prefix1, stable=False)
        # Wait till network data is updated and all nodes see all the added off-mesh routes.
        time.sleep(WAIT_TIME)
        num_routes += 1
        self.prefix_add_remove()
        verify(
            len(
                wpan_table_parser.parse_list(
                    self.ed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
            num_routes)

        self.logger.info(
            f"-------- Add off-mesh route based on stable prefix {prefix2} on leader node --------"
        )
        self.leader.add_route_using_prefix(prefix2, stable=True)
        # Wait till network data is updated and all nodes see all the added off-mesh routes.
        time.sleep(WAIT_TIME)
        num_routes += 1
        self.prefix_add_remove()
        verify(
            len(
                wpan_table_parser.parse_list(
                    self.ed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
            num_routes)

        self.logger.info(
            f"========= Add stable prefix {prefix3} on leader node =========")
        self.leader.add_prefix(prefix3, stable=True)
        # Wait till network data is updated and all nodes see all the added off-mesh routes.
        self.prefix_add_remove()
        verify(
            len(
                wpan_table_parser.parse_list(
                    self.ed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
            num_routes)

        self.logger.info(
            f"-------- Remove off-mesh route based on stable prefix {prefix2} on leader node --------"
        )
        self.leader.remove_route(prefix2)
        # Wait till network data is updated and all nodes see all the added off-mesh routes.
        time.sleep(WAIT_TIME)
        num_routes -= 1
        self.prefix_add_remove()
        verify(
            len(
                wpan_table_parser.parse_list(
                    self.ed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
            num_routes)

        self.logger.info(
            f"-------- Remove off-mesh route based on temporary prefix {prefix1} on leader node --------"
        )
        self.leader.remove_route(prefix1)
        # Wait till network data is updated and all nodes see all the added off-mesh routes.
        time.sleep(WAIT_TIME)
        num_routes -= 1
        self.prefix_add_remove()
        verify(
            len(
                wpan_table_parser.parse_list(
                    self.ed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
            num_routes)
Пример #13
0
 def check_child_is_removed_from_parent2_table(self):
     child_table = wpan_table_parser.parse_list(
         self.parent2.get(wpan.WPAN_THREAD_CHILD_TABLE))
     verify(len(child_table) == 0)
Пример #14
0
    def check_multicast_addresses(self, node, mcast_addr_list):
        addrs = wpan_table_parser.parse_list(
            node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))

        for addr in mcast_addr_list:
            verify(addr in addrs)