[toranj] adding verify_within and updating test-014-ip-address-add. (#2871)

This commit adds a new function `verify_within` in `toranj` wpan
library. This function verifies that certain conditions (given as
function handler) pass within a given wait time interval. The
`verify` function is also changed to raise an exception (instead
of immediate `exit(1)`).

The new function is then used in `test-014` to allow faster checks
after device reset while giving longer wait time for test to pass.
This commit is contained in:
Abtin Keshavarzian
2018-07-10 12:13:11 -05:00
committed by Jonathan Hui
parent b8181ce76d
commit 8c8a953d29
2 changed files with 54 additions and 27 deletions
+19 -23
View File
@@ -122,18 +122,13 @@ r2.add_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64)
fed1.add_ip6_address_on_interface(IP6_ADDR_2, prefix_len=64)
sed2.add_ip6_address_on_interface(IP6_ADDR_3, prefix_len=64)
for iter in range(2):
time.sleep(1.5)
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))
@@ -150,35 +145,36 @@ for iter in range(2):
verify(p.priority == "med")
break
else: # `for` loop finished without finding the prefix.
print 'Did not find prefix {} on node {}'.format(prefix, node)
exit(1)
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)
if iter == 0:
# Reset the nodes and verify that all addresses/prefixes are preserved.
fed1.reset()
sed2.reset()
# Check the addresses and prefixes (wait time 20 seconds)
wpan.verify_within(check_addresses_and_prefixes, 15)
# Reset the nodes and verify that all addresses/prefixes are preserved.
fed1.reset()
sed2.reset()
wpan.verify_within(check_addresses_and_prefixes, 20)
# Remove address from `r2`
r2.remove_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64)
time.sleep(1.5)
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)
# 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)
# Check the addresses and prefixes (wait time 15 seconds)
wpan.verify_within(check_address_prefix_removed, 15)
#-----------------------------------------------------------------------------------------------------------------------
# Test finished
+35 -4
View File
@@ -514,7 +514,7 @@ class Node(object):
#------------------------------------------------------------------------------------------------------------------
# IPv6 message Sender and Receiver class
class _NodeError(BaseException):
class _NodeError(Exception):
pass
def prepare_tx(self, src, dst, data=40, count=1):
@@ -799,14 +799,45 @@ class AsyncReceiver(asyncore.dispatcher):
self._node._remove_recver(self)
#-----------------------------------------------------------------------------------------------------------------------
class VerifyError(Exception):
pass
_is_in_verify_within = False
def verify(condition):
"""Verifies that a `condition` is true, otherwise exits"""
"""Verifies that a `condition` is true, otherwise raises a VerifyError"""
global _is_in_verify_within
if not condition:
calling_frame = inspect.currentframe().f_back
print 'verify() failed at line {} in "{}"'.format(calling_frame.f_lineno, calling_frame.f_code.co_filename)
exit(1)
error_message = 'verify() failed at line {} in "{}"'.format(calling_frame.f_lineno, calling_frame.f_code.co_filename)
if not _is_in_verify_within:
print error_message
raise VerifyError(error_message)
def verify_within(condition_checker_func, wait_time, delay_time=0.1):
"""Verifies that a given function `condition_checker_func` passes successfully within a given wait timeout.
`wait_time` is maximum time waiting for condition_checker to pass (in seconds).
`delay_time` specifies a delay interval added between failed attempts (in seconds).
"""
global _is_in_verify_within
start_time = time.time()
old_is_in_verify_within = _is_in_verify_within
_is_in_verify_within = True
while True:
try:
condition_checker_func()
except VerifyError as e:
if time.time() - start_time > wait_time:
print 'Took too long to pass the condition ({}>{} sec)'.format(time.time() - start_time, wait_time)
print e.message
raise e
except:
raise
else:
break
if delay_time != 0:
time.sleep(delay_time)
_is_in_verify_within = old_is_in_verify_within
#-----------------------------------------------------------------------------------------------------------------------
# Parsing `wpanctl` output