def test05_Verify_r4_Router_Table(self): r3_id = int(self.r3.get(wpan.WPAN_THREAD_ROUTER_ID), 0) r3_ext_addr = self.r3.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r1_rloc = int(self.r1.get(wpan.WPAN_THREAD_RLOC16), 16) r2_rloc = int(self.r2.get(wpan.WPAN_THREAD_RLOC16), 16) r3_rloc = int(self.r3.get(wpan.WPAN_THREAD_RLOC16), 16) r4_rloc = int(self.r4.get(wpan.WPAN_THREAD_RLOC16), 16) def check_r4_router_table(): router_table = wpan_table_parser.parse_router_table_result(self.r4.get(wpan.WPAN_THREAD_ROUTER_TABLE)) verify(len(router_table) == 4) for entry in router_table: if entry.rloc16 == r1_rloc: # r4's next hop towards r1 should be through r3. verify(not entry.is_link_established()) verify(entry.next_hop == r3_id) elif entry.rloc16 == r2_rloc: # r4's next hop towards r2 should be through r3. verify(not entry.is_link_established()) verify(entry.next_hop == r3_id) elif entry.rloc16 == r3_rloc: # r4 should be directly connected to r3. verify(entry.is_link_established()) verify(entry.ext_address == r3_ext_addr) elif entry.rloc16 == r4_rloc: pass else: raise (VerifyError("unknown entry in the router table of r4")) verify_within(check_r4_router_table, WAIT_TIME)
def test03_Reset_NCP(self): # Reset the nodes and verify that all addresses/prefixes are preserved. self.fed1.reset_thread_radio() self.sed2.reset_thread_radio() self.wait_for_completion(self.device_list) wpan_util.verify_within(self.check_addresses_and_prefixes, wait_time=60, delay_time=10) # Remove address from `r2` self.r2.remove_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) self.wait_for_completion(self.device_list) def check_address_prefix_removed(): # Verify that address is removed from r2 verify(self.r2.find_ip6_address_with_prefix(IP6_PREFIX_1) == '') # Verify that the related prefix is also removed on all nodes for node in self.all_nodes: prefixes = wpan_table_parser.parse_on_mesh_prefix_result( node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: verify(p.prefix != IP6_PREFIX_1) # Check the addresses and prefixes (wait time 15 seconds) wpan_util.verify_within(check_address_prefix_removed, wait_time=60, delay_time=10)
def test03_Change_Parent(self): # Remove the `child` from whitelist of `parent2` and add it to whitelist 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.whitelist_node(self.child1) self.parent2.un_whitelist_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 whitelist 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 whitelist) 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)
def test04_Verify_r3_Router_Table(self): r1_ext_addr = self.r1.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r2_ext_addr = self.r2.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r4_ext_addr = self.r4.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r1_rloc = int(self.r1.get(wpan.WPAN_THREAD_RLOC16), 16) r2_rloc = int(self.r2.get(wpan.WPAN_THREAD_RLOC16), 16) r3_rloc = int(self.r3.get(wpan.WPAN_THREAD_RLOC16), 16) r4_rloc = int(self.r4.get(wpan.WPAN_THREAD_RLOC16), 16) def check_r3_router_table(): router_table = wpan_table_parser.parse_router_table_result(self.r3.get(wpan.WPAN_THREAD_ROUTER_TABLE)) verify(len(router_table) == 4) for entry in router_table: if entry.rloc16 == r1_rloc: # r3 should be directly connected to r1. verify(entry.is_link_established()) verify(entry.ext_address == r1_ext_addr) elif entry.rloc16 == r2_rloc: # r3 should be directly connected to r2. verify(entry.is_link_established()) verify(entry.ext_address == r2_ext_addr) elif entry.rloc16 == r3_rloc: pass elif entry.rloc16 == r4_rloc: # r3 should be directly connected to r4. verify(entry.is_link_established()) verify(entry.ext_address == r4_ext_addr) else: raise (VerifyError("unknown entry in the router table of r3")) verify_within(check_r3_router_table, WAIT_TIME)
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")))) print child_num_state_changes # 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"))))
def test02_Verify_Add_IPV6(self): # On `r2` add `IP6_ADDR_1` with prefix `IP6_PREFIX_1` # On `fed1` add `IP6_ADDR_2` with prefix `IP6_PREFIX_2` # On `sed2` add `IP6_ADDR_3` with prefix `IP6_PREFIX_3` self.r2.add_ip6_address_on_interface(IP6_ADDR_2, prefix_len=64) self.wait_for_completion(self.device_list) # Check the addresses and prefixes (wait time 60 seconds) verify_within(self.check_prefix, 5)
def test04_Verify_New_Parent(self): # Verify that the `child` is now attached to `parent1` child_table = self.parent1.wpanctl( "get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_result(child_table) verify(len(child_table) == 1) # Finally verify that the `child` is removed from previous parent's child # table (which indicates that the `child` did indeed inform its previous # parent). verify_within(self.check_child_is_removed_from_parent2_table, 1)
def test02_Verify_Child_Mode(self): # Disable child supervision on all devices self.parent.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, '0') self.child1.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, '0') self.child2.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, '0') # Verify Thread Device Mode on both children verify( int(self.child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE) verify( int(self.child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_SLEEPY_END_DEVICE) verify_within(self.check_child_table, WAIT_INTERVAL)
def test04_Verify_Child_Mode_Change(self): # Change mode on both children (make child1 sleepy, and child2 non-sleepy) self.child1.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_SLEEPY_END_DEVICE)) verify( int(self.child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_SLEEPY_END_DEVICE) self.child2.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_END_DEVICE)) verify( int(self.child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVICE) # Verify that the child table on parent is also updated verify_within(self.check_child_table, WAIT_INTERVAL)
def test04_Remove_Prefix_Reset_NCP(self): # Save prefix length before removing prefixes_len_before_remove = {} for node in [self.r1, self.r2]: prefixes_len_before_remove[node] = len( wpan_table_parser.parse_on_mesh_prefix_result( node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))) print prefixes_len_before_remove # Remove the address from r2 which should remove the corresponding the prefix as well # After this since r1 still has the address, the prefix should be present on both nodes. self.r2.remove_ip6_address_on_interface(IP6_ADDR_2, prefix_len=64) verify_within(self.check_prefix, 5) # Reset r1 and verify that the prefix is retained correctly (by wpantund). self.r1.reset_thread_radio() self.wait_for_completion(self.device_list) verify_within(self.check_prefix, 8) # Remove the address on r1. Verify that prefix list has been decreased by 3. self.r1.remove_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) def check_empty_prefix_list(): for node in [self.r1, self.r2]: prefixes = wpan_table_parser.parse_on_mesh_prefix_result( node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) print len(prefixes), prefixes_len_before_remove[node] verify(len(prefixes) == prefixes_len_before_remove[node] - 3) verify_within(check_empty_prefix_list, 5)
def test09_verify_supervision_message(self): self.router.setprop(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL)) self.child_supervision_msg = 'Sending supervision message to child' result = verify_within(self.find_string_in_log_file, PARENT_SUPERVISION_INTERVAL * 10) self.assertTrue( result, 'Cannot find the expected string:{} in log file !!!'.format( self.child_supervision_msg))
def test05_Verify_Parent_Reset(self): # Reset parent and verify all children are recovered self.parent.reset_thread_radio() verify_within(self.check_child_table, WAIT_INTERVAL)
def test05_Add_Prefix_Back_To_Back(self): # Add both addresses back-to-back and check the prefix list to contain the prefix. self.r1.add_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) self.r2.add_ip6_address_on_interface(IP6_ADDR_2, prefix_len=64) verify_within(self.check_prefix, 5)
def test03_Add_same_Prefix(self): # After prefix is seen on r1, add an address with same prefix on r1. self.r1.add_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) # Verify that the prefix is still seen on both nodes. verify_within(self.check_prefix, 5)