def check_cache_entry_switch_to_query_state(): cache_table = wpan.parse_address_cache_table_result( r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)) for index in range(NUM_QUERY_ADDRS): verify( cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_QUERY) verify(cache_table[index].can_evict() == True)
def verify_child_table(parent, children): """ This function verifies that child table on `parent` node contains all the entries in `children` list and the child table entry's mode value matches the children Thread mode. """ child_table = wpan.parse_child_table_result( parent.get(wpan.WPAN_THREAD_CHILD_TABLE)) verify(len(child_table) == len(children)) for child in children: ext_addr = child.get(wpan.WPAN_EXT_ADDRESS)[1:-1] for entry in child_table: if entry.ext_address == ext_addr: break else: raise wpan.VerifyError( 'Failed to find a child entry for extended address {} in table' .format(ext_addr)) exit(1) verify( int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)) mode = int(child.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) verify(entry.is_rx_on_when_idle() == ( mode & wpan.THREAD_MODE_FLAG_RX_ON_WHEN_IDLE != 0)) verify(entry.is_ftd() == ( mode & wpan.THREAD_MODE_FLAG_FULL_THREAD_DEV != 0)) verify(entry.is_full_net_data() == ( mode & wpan.THREAD_MODE_FLAG_FULL_NETWORK_DATA != 0))
def check_cache_entry_in_retry_state_to_get_to_zero_timeout(): cache_table = wpan.parse_address_cache_table_result( r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)) for index in range(NUM_QUERY_ADDRS): verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY) verify(cache_table[index].timeout == 0)
def verify_address(node_list, prefix): """ This function verifies that all nodes in the `node_list` contain an IPv6 address with the given `prefix`. """ for node in node_list: all_addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_ALL_ADDRESSES)) verify(any([addr.startswith(prefix[:-1]) for addr in all_addrs]))
def check_r1_router_table(): router_table = wpan.parse_router_table_result( r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)) verify(len(router_table) == 3) for entry in router_table: verify(entry.rloc16 == r1_rloc or entry.is_link_established() or entry.next_hop != INVALID_ROUTER_ID)
def verify_no_address(node_list, prefix): """ This function verifies that none of nodes in the `node_list` contain an IPv6 address with the given `prefix`. """ for node in node_list: all_addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_ALL_ADDRESSES)) verify(all([not addr.startswith(prefix[:-1]) for addr in all_addrs]))
def check_r1_r2_roles(): r1_type = r1.get(wpan.WPAN_NODE_TYPE) r2_type = r2.get(wpan.WPAN_NODE_TYPE) verify( (r1_type == wpan.NODE_TYPE_LEADER and r2_type == wpan.NODE_TYPE_ROUTER) or (r2_type == wpan.NODE_TYPE_LEADER and r1_type == wpan.NODE_TYPE_ROUTER))
def check_cache_entry_switch_to_retry_state(): cache_table = wpan.parse_address_cache_table_result( r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)) for index in range(NUM_QUERY_ADDRS): verify(cache_table[index].state == wpan.ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY) verify(cache_table[index].retry_delay == 2 * INITIAL_RETRY_DELAY)
def check_address_prefix_removed(): # Verify that address is removed from r2 verify(r2.find_ip6_address_with_prefix(IP6_PREFIX_1) == '') # Verify that the related prefix is also removed on all nodes for node in all_nodes: prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: verify(p.prefix != IP6_PREFIX_1)
def verify_no_prefix(node_list, prefix): """ This function verifies that the `prefix` is NOT present on any node in the `node_list`. """ for node in node_list: prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: verify(not p.prefix == prefix)
def verify_interface_routes(node, route_list): """ This function verifies that node has the same interface routes as given by `route_list` which is an array of tuples of (route, prefix_len, metric). """ node_routes = wpan.parse_interface_routes_result(node.get(wpan.WPAN_IP6_INTERFACE_ROUTES)) verify(len(route_list) == len(node_routes)) for route in route_list: for node_route in node_routes: if (node_route.route_prefix, node_route.prefix_len, node_route.metric) == route: break else: raise wpan.VerifyError( 'Did not find route {} on node {}'.format(route, node) )
def send_mcast(src_node, src_addr, mcast_addr, recving_nodes, non_recving_nodes=[], msg_len=30, mcast_hops=5): """ Send a multicast message with given `len` from `src_node` using `src_addr` to the multicast address `mcast_addr`. Verify that the message is received on all nodes in `recving_nodes` list and that it is not received on all nodes in `non_recving_nodes` list. """ sender = src_node.prepare_tx(src_addr, mcast_addr, msg_len, mcast_hops=mcast_hops) recvers = [node.prepare_rx(sender) for node in recving_nodes] listeners = [ node.preapre_listener(sender.dst_port, timeout=0.5) for node in non_recving_nodes ] wpan.Node.perform_async_tx_rx() verify(sender.was_successful) for recvr in recvers: verify(recvr.was_successful) for lsnr in listeners: # `all_rx_msg` contains a list of (msg_content, (src_addr, src_port)). verify( len(lsnr.all_rx_msg) == 0 or all([ msg[1][0] != sender.src_addr and msg[1][1] != sender.src_port for msg in lsnr.all_rx_msg ]))
def check_r1_again_prefers_trel_for_r2(): r1_neighbor_radios = wpan.parse_multi_radio_result( r1.get(wpan.WPAN_OT_NEIGHBOR_TABLE_MULTI_RADIO_INFO)) verify(len(r1_neighbor_radios) == 1) r2_radio_info = r1_neighbor_radios[0] verify(r2_radio_info.supports(wpan.RADIO_LINK_TREL_UDP6)) verify( r2_radio_info.preference(wpan.RADIO_LINK_TREL_UDP6) >= HIGH_PREFERENCE_THRESHOLD)
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. verify( len(wpan.parse_list(r1.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) == NUM_ROUTES + NUM_ROUTES_LOCAL) verify( len(wpan.parse_list(r2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) == NUM_ROUTES + NUM_ROUTES_LOCAL) verify( len(wpan.parse_list(sed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) == NUM_ROUTES)
def send_mcast(src_node, src_addr, mcast_addr, recving_nodes, non_recving_nodes=[], msg_len=30, mcast_hops=5): """ Send a multicast message with given `len` from `src_node` using `src_addr` to the multicast address `mcast_addr`. Verify that the message is received on all nodes in `recving_nodes` list and that it is not received on all nodes in `non_recving_nodes` list. """ sender = src_node.prepare_tx(src_addr, mcast_addr, msg_len, mcast_hops=mcast_hops) recvers = [node.prepare_rx(sender) for node in recving_nodes] listeners = [node.preapre_listener(sender.dst_port, timeout=0.5) for node in non_recving_nodes] wpan.Node.perform_async_tx_rx() verify(sender.was_successful) for recvr in recvers: verify(recvr.was_successful) for lsnr in listeners: # `all_rx_msg` contains a list of (msg_content, (src_addr, src_port)). verify(len(lsnr.all_rx_msg) == 0 or all([msg[1][0] != sender.src_addr and msg[1][1] != sender.src_port for msg in lsnr.all_rx_msg]))
def check_ip6_addresses(): # Verify that SLAAC addresses are removed on r2 and c2 verify_no_address([r2, c2], PREFIX) # And that user-added address matching the prefix is not removed on r1 r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES)) verify(IP_ADDRESS in r1_addrs)
r3.add_ip6_address_on_interface(PREFIX + "3:" + str(num)) c2.add_ip6_address_on_interface(PREFIX + "c2:" + str(num)) c3.add_ip6_address_on_interface(PREFIX + "c3:" + str(num)) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # From r1 send msg to a group of addresses (not provided by any nodes in network). NUM_QUERY_ADDRS = 5 MAX_STAGGER_INTERVAL = 2.5 for num in range(NUM_QUERY_ADDRS): sender = r1.prepare_tx((r1_address, PORT), (PREFIX + "800:" + str(num), PORT), "hi nobody!", 1) wpan.Node.perform_async_tx_rx() verify(sender.was_successful) # Wait before next tx to stagger the address queries # request ensuring different timeouts time.sleep(MAX_STAGGER_INTERVAL / (NUM_QUERY_ADDRS * speedup)) r2_rloc = int(r2.get(wpan.WPAN_THREAD_RLOC16), 16) c2_rloc = int(c2.get(wpan.WPAN_THREAD_RLOC16), 16) r3_rloc = int(r3.get(wpan.WPAN_THREAD_RLOC16), 16) # Verify that we do see entries in cache table for all the addresses and all are in "query" state addr_cache_table = wpan.parse_address_cache_table_result( r1.get(wpan.WPAN_THREAD_ADDRESS_CACHE_TABLE)) verify(len(addr_cache_table) == NUM_QUERY_ADDRS) for entry in addr_cache_table:
r2.add_route(OFF_MESH_ROUTE_2) r2.add_ip6_address_on_interface(OFF_MESH_ADDR_2) fed1.add_route(OFF_MESH_ROUTE_3) fed1.add_ip6_address_on_interface(OFF_MESH_ADDR_3) time.sleep(0.5) # Traffic from `sed2` to `OFF_MESH_ADDR_1` (verify that it is received on # `r1`). src = sed2.find_ip6_address_with_prefix(ON_MESH_PREFIX) sender = sed2.prepare_tx(src, OFF_MESH_ADDR_1, "Hello Route1") recver = r1.prepare_rx(sender) wpan.Node.perform_async_tx_rx() verify(sender.was_successful) verify(recver.was_successful) # Traffic from `r1` to `OFF_MESH_ADDR_2` (verify that it is received on `r2`), src = r1.find_ip6_address_with_prefix(ON_MESH_PREFIX) sender = r1.prepare_tx(src, OFF_MESH_ADDR_2, "Hello Route2") recver = r2.prepare_rx(sender) wpan.Node.perform_async_tx_rx() verify(sender.was_successful) verify(recver.was_successful) # Traffic from `r2` to `OFF_MESH_ADDR_3` (verify that it is received on `fed1`) src = r2.find_ip6_address_with_prefix(ON_MESH_PREFIX) sender = r2.prepare_tx(src, OFF_MESH_ADDR_3, "Hello Route3")
def joiner_is_asscoated(): verify(j.is_associated())
node2 = wpan.Node() #----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Build network topology # Two-node network (node1 leader/router, node2 sleepy-end-device) node1.form('test-PAN') node2.join_node(node1, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE) verify(node2.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED) verify(node2.get(wpan.WPAN_NAME) == node1.get(wpan.WPAN_NAME)) verify(node2.get(wpan.WPAN_PANID) == node1.get(wpan.WPAN_PANID)) verify(node2.get(wpan.WPAN_XPANID) == node1.get(wpan.WPAN_XPANID)) #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Get the link local addresses ll1 = node1.get(wpan.WPAN_IP6_LINK_LOCAL_ADDRESS)[1:-1] ll2 = node2.get(wpan.WPAN_IP6_LINK_LOCAL_ADDRESS)[1:-1] # Get the mesh-local addresses ml1 = node1.get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
def check_r1_neighbor_table(): verify(r1.is_associated()) verify_neighbor_table(r1, [r2])
def check_r2_become_leader(): verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER)
def check_r3_router_table(): router_table = wpan.parse_router_table_result(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(wpan.VerifyError("unknown entry in the router table of r3"))
#----------------------------------------------------------------------------------------------------------------------- # Creating `wpan.Nodes` instances node = wpan.Node() #----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Verify that state is ON after a reset verify(node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_ON) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Check power state wpantund property get and set node.form("mcu-power-state") verify(node.is_associated()) node.set(wpan.WPAN_NCP_MCU_POWER_STATE, 'low-power') verify(node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_LOW_POWER) verify(node.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED) node.set(wpan.WPAN_NCP_MCU_POWER_STATE, 'on') verify(node.get(wpan.WPAN_NCP_MCU_POWER_STATE) == wpan.MCU_POWER_STATE_ON) node.set(wpan.WPAN_NCP_MCU_POWER_STATE, 'lp') # special short-form string for low-power
# Wait for on-mesh prefix to be updated time.sleep(0.5) verify_prefix(all_nodes, prefix1, stable=True, on_mesh=True, slaac=True) verify_address(all_nodes, prefix1) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Test `add-prefix` and `remove-prefix` r1.add_prefix(prefix4, 48, priority="1", stable=False, on_mesh=True, slaac=False, dhcp=True, configure=False, default_route=True, preferred=False) verify_prefix([r1], prefix4, 48, priority="high", stable=False, on_mesh=True, slaac=False, dhcp=True, configure=False, default_route=True, preferred=False) # Remove prefix and verify that it is removed from list r1.remove_prefix(prefix4, 48) time.sleep(0.5) verify(r1.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES).find(prefix4) < 0) r1.add_prefix(prefix4, 48, priority="-1", stable=True, on_mesh=False, slaac=True, dhcp=False, configure=True, default_route=False, preferred=True) verify_prefix([r1], prefix4, 48, priority="low", stable=True, on_mesh=False, slaac=True, dhcp=False, configure=True, default_route=False, preferred=True) #----------------------------------------------------------------------------------------------------------------------- # Test finished wpan.Node.finalize_all_nodes() print '\'{}\' passed.'.format(test_name)
print 'Starting \'{}\''.format(test_name) #----------------------------------------------------------------------------------------------------------------------- # Creating `wpan.Nodes` instances node = wpan.Node() #----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Test implementation verify(node.get(wpan.WPAN_STATE) == wpan.STATE_OFFLINE) # set some of properties and check and verify that the value is indeed changed... node.set(wpan.WPAN_NAME, 'test-network') verify(node.get(wpan.WPAN_NAME) == '"test-network"') node.set(wpan.WPAN_NAME, 'a') verify(node.get(wpan.WPAN_NAME) == '"a"') node.set(wpan.WPAN_PANID, '0xABBA') verify(node.get(wpan.WPAN_PANID) == '0xABBA') node.set(wpan.WPAN_XPANID, '1020031510006016', binary_data=True) verify(node.get(wpan.WPAN_XPANID) == '0x1020031510006016')
#----------------------------------------------------------------------------------------------------------------------- # Build network topology for node in nodes: node.form(node.interface_name) #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Perform active scan and check that all nodes are seen in the scan result. scan_result = wpan.parse_scan_result(scanner.discover_scan()) for node in nodes: verify(node.is_in_scan_result(scan_result)) # Scan from an already associated node. scan_result = wpan.parse_scan_result(nodes[0].discover_scan()) for node in nodes[1:]: verify(node.is_in_scan_result(scan_result)) # TODO: add tests for the joiner only and filtering #----------------------------------------------------------------------------------------------------------------------- # Test finished print '\'{}\' passed.'.format(test_name)
# Test implementation # Reset c2 and keep it in detached state c2.set('Daemon:AutoAssociateAfterReset', 'false') c2.reset(); # Switch the rest of network to channel 26 router.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '26') verify_channel([router, c1], 26) # Now re-enable c2 and verify that it does attach to router and is on channel 26 # c2 would go through the ML Announce recovery. c2.set('Daemon:AutoAssociateAfterReset', 'true') c2.reset(); verify(int(c2.get(wpan.WPAN_CHANNEL), 0) == 11) # wait for 20s for c2 to be attached/associated def check_c2_is_associated(): verify(c2.is_associated()) wpan.verify_within(check_c2_is_associated, 20) # Check that c2 is now on channel 26. verify(int(c2.get(wpan.WPAN_CHANNEL), 0) == 26) #----------------------------------------------------------------------------------------------------------------------- # Test finished wpan.Node.finalize_all_nodes()
def check_r2_neighbor_table(): verify(r2.is_associated()) verify_neighbor_table(r2, [r1])
def verify_prefix( node_list, prefix, prefix_len=64, stable=True, priority='med', on_mesh=False, slaac=False, dhcp=False, configure=False, default_route=False, preferred=False, ): """ This function verifies that the `prefix` is present on all the nodes in the `node_list`. """ for node in node_list: prefixes = wpan.parse_on_mesh_prefix_result( node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES) ) for p in prefixes: if p.prefix == prefix: verify(int(p.prefix_len) == prefix_len) verify(p.is_stable() == stable) verify(p.is_on_mesh() == on_mesh) verify(p.is_def_route() == default_route) verify(p.is_slaac() == slaac) verify(p.is_dhcp() == dhcp) verify(p.is_config() == configure) verify(p.is_preferred() == preferred) verify(p.priority == priority) break else: raise wpan.VerifyError( "Did not find prefix {} on node {}".format(prefix, node) )
r3.whitelist_node(r4) r4.whitelist_node(r3) r4.join_node(r3, wpan.JOIN_TYPE_ROUTER) # c4 is attached to r4 so that it quickly gets promoted to a router role. c4.whitelist_node(r4) r4.whitelist_node(c4) c4.join_node(r4, wpan.JOIN_TYPE_SLEEPY_END_DEVICE) c4.set(wpan.WPAN_POLL_INTERVAL, '2000') #----------------------------------------------------------------------------------------------------------------------- # Test implementation # verify(r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(r3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(r4.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) r1_id = int(r1.get(wpan.WPAN_THREAD_ROUTER_ID), 0) r2_id = int(r2.get(wpan.WPAN_THREAD_ROUTER_ID), 0) r3_id = int(r3.get(wpan.WPAN_THREAD_ROUTER_ID), 0) r4_id = int(r4.get(wpan.WPAN_THREAD_ROUTER_ID), 0) r1_ext_addr = r1.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r2_ext_addr = r2.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r3_ext_addr = r3.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r4_ext_addr = r4.get(wpan.WPAN_EXT_ADDRESS)[1:-1] r1_rloc = int(r1.get(wpan.WPAN_THREAD_RLOC16), 16)
r1.allowlist_node(r3) r3.join_node(r1, wpan.JOIN_TYPE_ROUTER) c3.allowlist_node(r3) r3.allowlist_node(c3) c3.join_node(r3, wpan.JOIN_TYPE_END_DEVICE) # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # ROUTER_TABLE_WAIT_TIME = 30 / speedup + 5 INVALID_ROUTER_ID = 63 verify(r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(r3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(c.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_SLEEPY_END_DEVICE) verify(c3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_END_DEVICE) r1_address = r1.find_ip6_address_with_prefix(PREFIX) r2_address = r2.find_ip6_address_with_prefix(PREFIX) c_address = c.find_ip6_address_with_prefix(PREFIX) # Send a single UDP message from r1 to c # # This adds an address cache entry on r1 for c pointing to r2 (the current parent of c). sender = r1.prepare_tx(r1_address, c_address, "Hi from r1 to c") recver = c.prepare_rx(sender)
def check_r4_router_table(): router_table = wpan.parse_router_table_result(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(wpan.VerifyError("unknown entry in the router table of r4"))
#----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Build network topology node.form("channel-manager", channel=11) #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Check default property values verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 0) verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'false') verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) == 0) verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_FAVORED_CHANNEL_MASK), 0) == 0) # Set different wpan Channel Manager properties and get and check the output node.set(wpan.WPAN_CHANNEL_MANAGER_DELAY, '180') verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_DELAY), 0) == 180) node.set(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED, '1') verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'true') node.set(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED, '0') verify(node.get(wpan.WPAN_CHANNEL_MANAGER_AUTO_SELECT_ENABLED) == 'false')
for router in routers[1:]: router.join_node(routers[0], wpan.JOIN_TYPE_ROUTER) for num in range(1, NUM_ROUTERS): ed[num].join_node(routers[num], wpan.JOIN_TYPE_END_DEVICE) for num in range(NUM_CHILDREN): children[num].join_node(routers[0], wpan.JOIN_TYPE_SLEEPY_END_DEVICE) children[num].set(wpan.WPAN_POLL_INTERVAL,'300') #----------------------------------------------------------------------------------------------------------------------- # Test implementation for router in routers[1:]: verify(router.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) # Get and parse the neighbor table on routers[0]. neighbor_table = wpan.parse_neighbor_table_result(routers[0].get(wpan.WPAN_THREAD_NEIGHBOR_TABLE)) verify(len(neighbor_table) == NUM_ROUTERS - 1 + NUM_CHILDREN) # Verify that all children are seen in the neighbor table for child in children: ext_addr = child.get(wpan.WPAN_EXT_ADDRESS)[1:-1] for entry in neighbor_table: if entry.ext_address == ext_addr: break; else: raise wpan.VerifyError('Failed to find a child entry for extended address {} in table'.format(ext_addr))
def check_empty_prefix_list(): for node in [r1, r2]: prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) verify(len(prefixes) == 0)
def check_paritition_id_macth(): verify(r1.get(wpan.WPAN_PARTITION_ID) == r2.get(wpan.WPAN_PARTITION_ID))
def verify_prefix(node_list, prefix, prefix_len=64, stable=True, priority='med', on_mesh=False, slaac=False, dhcp=False, configure=False, default_route=False, preferred=True): """ This function verifies that the `prefix` is present on all the nodes in the `node_list`. """ for node in node_list: prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: if p.prefix == prefix: verify(int(p.prefix_len) == prefix_len) verify(p.is_stable() == stable) verify(p.is_on_mesh() == on_mesh) verify(p.is_def_route() == default_route) verify(p.is_slaac() == slaac) verify(p.is_dhcp() == dhcp) verify(p.is_config() == configure) verify(p.is_preferred() == preferred) verify(p.priority == priority) break else: print "Did not find prefix {} on node {}".format(prefix, node) exit(1)
# ----------------------------------------------------------------------------------------------------------------------- # Build network topology for node in nodes: node.form(node.interface_name) # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # Perform active scan and check that all nodes are seen in the scan result. scan_result = wpan.parse_scan_result(scanner.active_scan()) for node in nodes: verify(node.is_in_scan_result(scan_result)) # Make every other network joinable, scan and check the result. make_joinable = False for node in nodes: make_joinable = not make_joinable if make_joinable: node.permit_join() scan_result = wpan.parse_scan_result(scanner.active_scan()) for node in nodes: verify(node.is_in_scan_result(scan_result)) # Scan from an already associated node.
#----------------------------------------------------------------------------------------------------------------------- # Test implementation NUM_MSGS = 3 MSG_LENS = [40, 100, 400, 800, 1000] # Send from the first router in the chain to the last one. src = routers[0].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1] dst = routers[-1].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1] for msg_length in MSG_LENS: sender = routers[0].prepare_tx(src, dst, msg_length, NUM_MSGS) recver = routers[-1].prepare_rx(sender) wpan.Node.perform_async_tx_rx() verify(sender.was_successful) verify(recver.was_successful) # Send from the SED child of the last router to the SED child of the first router. src = sed_children[-1].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1] dst = sed_children[0].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1] for msg_length in MSG_LENS: sender = sed_children[-1].prepare_tx(src, dst, msg_length, NUM_MSGS) recver = sed_children[0].prepare_rx(sender) wpan.Node.perform_async_tx_rx() verify(sender.was_successful) verify(recver.was_successful) # Send from the FED child of the first router to the FED child of the last router.
def check_c_is_removed_from_r1_child_table(): child_table = wpan.parse_list(r1.get(wpan.WPAN_THREAD_CHILD_TABLE)) verify(len(child_table) == 0)
# Creating `wpan.Nodes` instances node1 = wpan.Node() node2 = wpan.Node() #----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Form a network on node1 node1.form('PAN-aB71n') verify(node1.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED) verify(node1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) # Join from node2 as a router node2.join_node(node1, node_type=wpan.JOIN_TYPE_ROUTER) verify(node2.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED) verify(node2.get(wpan.WPAN_NAME) == node1.get(wpan.WPAN_NAME)) verify(node2.get(wpan.WPAN_PANID) == node1.get(wpan.WPAN_PANID)) verify(node2.get(wpan.WPAN_XPANID) == node1.get(wpan.WPAN_XPANID)) verify(node2.get(wpan.WPAN_KEY) == node1.get(wpan.WPAN_KEY)) node2.leave() # Join from node2 as an end-device node2.join_node(node1, node_type=wpan.JOIN_TYPE_END_DEVICE) verify(node2.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED)
# ----------------------------------------------------------------------------------------------------------------------- # Build network topology n1.form("n1", channel='20') n2.form("n2", channel='21') n3.form("n3", channel='22') # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Scan by scanner nodes (no network) # Scan by s1 (15.4 only), expect to see n1(15.4) and n3(15.4+trel) result = wpan.parse_scan_result(s1.discover_scan()) verify(n1.is_in_scan_result(result)) verify(not n2.is_in_scan_result(result)) verify(n3.is_in_scan_result(result)) # Scan by s2 (trel only), expect to see n2(trel) and n3(15.4+trel) result = wpan.parse_scan_result(s2.discover_scan()) verify(not n1.is_in_scan_result(result)) verify(n2.is_in_scan_result(result)) verify(n3.is_in_scan_result(result)) # Scan by s3 (trel+15.4), expect to see all nodes result = wpan.parse_scan_result(s3.discover_scan()) verify(n1.is_in_scan_result(result)) verify(n2.is_in_scan_result(result)) verify(n3.is_in_scan_result(result))
def check_c2_is_removed_from_r2_child_table(): child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE)) verify(len(child_table) == 0)
WAIT_TIME = 2 # seconds PSKd = '123456' joiner_hw_addr = j.get(wpan.WPAN_HW_ADDRESS)[1:-1] # Remove the `[]` # Start the commissioner and add joiner hw address along with PSKd c.commissioner_start() c.commissioner_add_joiner(joiner_hw_addr, PSKd) # Start Joiner j.joiner_join(PSKd) # Verify that Joiner succeeded verify(j.get(wpan.WPAN_STATE) == wpan.STATE_COMMISSIONED) j.joiner_attach() def joiner_is_asscoated(): verify(j.is_associated()) wpan.verify_within(joiner_is_asscoated, WAIT_TIME) # ----------------------------------------------------------------------------------------------------------------------- # Test finished wpan.Node.finalize_all_nodes()
def check_addresses_and_prefixes(): # Verify that the addresses are present in "IPv6:AllAddresses" wpantund property on the corresponding node. verify(r2.find_ip6_address_with_prefix(IP6_PREFIX_1) == IP6_ADDR_1) verify(fed1.find_ip6_address_with_prefix(IP6_PREFIX_2) == IP6_ADDR_2) verify(sed2.find_ip6_address_with_prefix(IP6_PREFIX_3) == IP6_ADDR_3) # Verify that all prefixes are present in network data on all nodes (with correct flags). for prefix in [IP6_PREFIX_1, IP6_PREFIX_2, IP6_PREFIX_3]: for node in all_nodes: prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: if p.prefix == prefix: verify(p.prefix_len == '64') verify(p.is_stable()) verify(p.is_on_mesh() == True) verify(p.is_preferred() == True) verify(p.is_def_route() == False) verify(p.is_slaac() == False) verify(p.is_dhcp() == False) verify(p.is_config() == False) verify(p.priority == "med") break else: # `for` loop finished without finding the prefix. raise wpan.VerifyError('Did not find prefix {} on node {}'.format(prefix, node)) # Verify that IPv6 address of `sed2` is present on `r2` (its parent) "Thread:ChildTable:Addresses". addr_str = r2.get(wpan.WPAN_THREAD_CHILD_TABLE_ADDRESSES) # search for index on address in the `addr_str` and ensure it is non-negative. verify(addr_str.find(IP6_ADDR_3) >= 0)
r2.join_node(r1, node_type=wpan.JOIN_TYPE_ROUTER) c2.whitelist_node(r2) r2.whitelist_node(c2) c2.join_node(r2, node_type=wpan.JOIN_TYPE_END_DEVICE) # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # This test covers the SLAAC address management by NCP. So before starting the test we ensure that SLAAC module # on NCP is enabled on all nodes, and disable it on wpantund. for node in all_nodes: verify(node.get(wpan.WPAN_OT_SLAAC_ENABLED) == 'true') node.set("Daemon:IPv6:AutoAddSLAACAddress", 'false') verify(node.get("Daemon:IPv6:AutoAddSLAACAddress") == 'false') WAIT_INTERVAL = 5 PREFIX = 'fd00:1234::' # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Add prefix and check all nodes get the prefix and add a corresponding # SLAAC address. r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) def check_prefix_and_slaac_address_are_added():
#----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Test implementation # default values after reset DEFAULT_KEY = '[00112233445566778899AABBCCDDEEFF]' DEFAULT_NAME = '"OpenThread"' DEFAULT_PANID = '0xFFFF' DEFAULT_XPANID = '0xDEAD00BEEF00CAFE' verify(node.get(wpan.WPAN_STATE) == wpan.STATE_OFFLINE) verify(node.get(wpan.WPAN_KEY) == DEFAULT_KEY) verify(node.get(wpan.WPAN_NAME) == DEFAULT_NAME) verify(node.get(wpan.WPAN_PANID) == DEFAULT_PANID) verify(node.get(wpan.WPAN_XPANID) == DEFAULT_XPANID) # Form a network node.form('asha') verify(node.get(wpan.WPAN_STATE) == wpan.STATE_ASSOCIATED) verify(node.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) verify(node.get(wpan.WPAN_NAME) == '"asha"') verify(node.get(wpan.WPAN_KEY) != DEFAULT_KEY) verify(node.get(wpan.WPAN_PANID) != DEFAULT_PANID) verify(node.get(wpan.WPAN_XPANID) != DEFAULT_XPANID)
r3.whitelist_node(r2) r3.join_node(r2, wpan.JOIN_TYPE_ROUTER) c3.whitelist_node(r3) r3.whitelist_node(c3) c3.join_node(r3, wpan.JOIN_TYPE_END_DEVICE) #----------------------------------------------------------------------------------------------------------------------- # Test implementation # ROUTER_TABLE_WAIT_TIME = 30 / speedup + 5 INVALID_ROUTER_ID = 63 verify(r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(r3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) verify(c1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_END_DEVICE) verify(c2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_SLEEPY_END_DEVICE) verify(c3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_END_DEVICE) r2_rloc = int(r2.get(wpan.WPAN_THREAD_RLOC16), 16) r3_rloc = int(r3.get(wpan.WPAN_THREAD_RLOC16), 16) c3_rloc = int(c3.get(wpan.WPAN_THREAD_RLOC16), 16) # Wait till we have a valid "next hop" route on r1 towards r3 def check_r1_router_table(): router_table = wpan.parse_router_table_result(r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)) verify(len(router_table) == 3) for entry in router_table:
def check_r1_router_table(): router_table = wpan.parse_router_table_result(r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)) verify(len(router_table) == 3) for entry in router_table: if entry.rloc16 == r3_rloc: verify(entry.next_hop != INVALID_ROUTER_ID)
print('Starting \'{}\''.format(test_name)) # ----------------------------------------------------------------------------------------------------------------------- # Creating `wpan.Nodes` instances node = wpan.Node() # ----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() # ----------------------------------------------------------------------------------------------------------------------- # Test implementation verify(node.get(wpan.WPAN_STATE) == wpan.STATE_OFFLINE) # set some of properties and check and verify that the value is indeed # changed... node.set(wpan.WPAN_NAME, 'test-network') verify(node.get(wpan.WPAN_NAME) == '"test-network"') node.set(wpan.WPAN_NAME, 'a') verify(node.get(wpan.WPAN_NAME) == '"a"') node.set(wpan.WPAN_PANID, '0xABBA') verify(node.get(wpan.WPAN_PANID) == '0xABBA') node.set(wpan.WPAN_XPANID, '1020031510006016', binary_data=True) verify(node.get(wpan.WPAN_XPANID) == '0x1020031510006016')
def check_c2_is_associated(): verify(c2.is_associated())
#----------------------------------------------------------------------------------------------------------------------- # Build network topology node.form('channel-manager', channel=24) #----------------------------------------------------------------------------------------------------------------------- # Test implementation all_channls_mask = int('0x7fff800', 0) chan_12_to_15_mask = int('0x000f000', 0) chan_15_to_17_mask = int('0x0038000', 0) # Set supported channel mask to be all channels node.set(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK, str(all_channls_mask)) verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) == all_channls_mask) # Sleep for 4 second with speedup factor of 10,000 this is more than 11 hours. time.sleep(4) verify(int(node.get(wpan.WPAN_CHANNEL_MONITOR_SAMPLE_COUNT), 0) > 970) # Verify the initial value of `NEW_CHANNEL` (should be zero if there has been no channel change so far). verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 0) # Issue a channel-select with quality check enabled, and verify that no action is taken. node.set(wpan.WPAN_CHANNEL_MANAGER_CHANNEL_SELECT, 'false') verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 0)
# Build network topology node.form('channel-manager', channel=24) # ----------------------------------------------------------------------------------------------------------------------- # Test implementation all_channls_mask = int('0x7fff800', 0) chan_12_to_15_mask = int('0x000f000', 0) chan_15_to_17_mask = int('0x0038000', 0) # Set supported channel mask to be all channels node.set(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK, str(all_channls_mask)) verify( int(node.get(wpan.WPAN_CHANNEL_MANAGER_SUPPORTED_CHANNEL_MASK), 0) == all_channls_mask) # Sleep for 4.5 second with speedup factor of 10,000 this is more than 12 # hours. time.sleep(4.5) verify(int(node.get(wpan.WPAN_CHANNEL_MONITOR_SAMPLE_COUNT), 0) > 970) # Verify the initial value of `NEW_CHANNEL` (should be zero if there has # been no channel change so far). verify(int(node.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 0) # Issue a channel-select with quality check enabled, and verify that no # action is taken.
sc1.join_node(r1, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE) ec1.join_node(r1, node_type=wpan.JOIN_TYPE_END_DEVICE) sc2.join_node(r2, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE) sc3.join_node(r3, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE) sc1.set(wpan.WPAN_POLL_INTERVAL, '500') sc2.set(wpan.WPAN_POLL_INTERVAL, '500') sc3.set(wpan.WPAN_POLL_INTERVAL, '500') # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # The channel manager delay is set from "openthread-core-toranj-config.h". # Verify that it is 2 seconds. verify(int(r1.get(wpan.WPAN_CHANNEL_MANAGER_DELAY), 0) == 2) verify_channel(all_nodes, 12) # Request a channel change to channel 13 from router r1 r1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '13') verify(int(r1.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 13) verify_channel(all_nodes, 13) # Request same channel change on multiple routers at the same time r1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14') r2.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14') r3.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14') verify_channel(all_nodes, 14)
node = wpan.Node() #----------------------------------------------------------------------------------------------------------------------- # Init all nodes wpan.Node.init_all_nodes() #----------------------------------------------------------------------------------------------------------------------- # Build network topology node.form("permit-join-test") #----------------------------------------------------------------------------------------------------------------------- # Test implementation verify(node.get(wpan.WPAN_NETWORK_ALLOW_JOIN) == 'false') node.permit_join() verify(node.get(wpan.WPAN_NETWORK_ALLOW_JOIN) == 'true') node.permit_join('0') verify(node.get(wpan.WPAN_NETWORK_ALLOW_JOIN) == 'false') node.permit_join(port='1234') verify(node.get(wpan.WPAN_NETWORK_ALLOW_JOIN) == 'true') node.permit_join('0') verify(node.get(wpan.WPAN_NETWORK_ALLOW_JOIN) == 'false') # check the timeout node.permit_join('1')
# ----------------------------------------------------------------------------------------------------------------------- # Build network topology # parent.form("poll-interval") child.join_node(parent, wpan.JOIN_TYPE_SLEEPY_END_DEVICE) # ----------------------------------------------------------------------------------------------------------------------- # Test implementation # Verify the default poll interval is smaller than child_timeout child_timeout = int(child.get(wpan.WPAN_THREAD_CHILD_TIMEOUT), 0) * 1000 default_poll_interval = int(child.get(wpan.WPAN_POLL_INTERVAL), 0) verify(0 < default_poll_interval <= child_timeout) WAIT_TIME = 0.36 # in seconds # Check number of data polls with different poll intervals for poll_interval in [100, 200, 500, 50]: # in milliseconds poll_count_before = int(child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL), 0) child.set(wpan.WPAN_POLL_INTERVAL, str(poll_interval)) verify(int(child.get(wpan.WPAN_POLL_INTERVAL), 0) == poll_interval) time.sleep(WAIT_TIME) poll_count_after = int(child.get(wpan.WPAN_NCP_COUNTER_TX_PKT_DATA_POLL),
#----------------------------------------------------------------------------------------------------------------------- # Build network topology router.form('child-table') for child in children: child.join_node(router, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE) child.set(wpan.WPAN_POLL_INTERVAL, '1000') #----------------------------------------------------------------------------------------------------------------------- # Test implementation # Get the child table and verify all children are in the table. child_table = wpan.parse_child_table_result(router.get(wpan.WPAN_THREAD_CHILD_TABLE)) verify(len(child_table) == len(children)) for child in children: ext_addr = child.get(wpan.WPAN_EXT_ADDRESS)[1:-1] for entry in child_table: if entry.ext_address == ext_addr: break; else: print 'Failed to find a child entry for extended address {} in table'.format(ext_addr) exit(1) verify(int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)) verify(int(entry.timeout, 0) == 120) verify(entry.is_rx_on_when_idle() == False) verify(entry.is_ffd() == False)