tests: apply KISS to retry fixture

This python fixture was way too complex for what is needed.

Eliminate gratuitous options/over-engineering:

- Change from non-deterministic `wait` and `attempts` to a single
`retry_timeout` value. This is both more deterministic, as well as
what the user should actually be thinking about.

- Use a fixed 2 second pause between executing the wrapped function
rather than a bunch of arbitrary choices of 2, 3 and 4 seconds
spread all over the test code.

- Get rid of the multiple variables for determining what "Positive" and
"Negative" results are. Instead just implement what all the user code
already wants, i.e., boolean False or a str (errormsg) means
"Negative" result otherwise it's a "Positive" result.

- As part of the above the inversion logic is much more comprehensible
in the fixture code (and more correct to boot).

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2021-06-19 12:09:06 +00:00
parent d8c3138cd9
commit ed776e38f6
No known key found for this signature in database
GPG key ID: 2E1D830ED7B83025
12 changed files with 168 additions and 136 deletions

View file

@ -989,7 +989,7 @@ def modify_bgp_config_when_bgpd_down(tgen, topo, input_dict):
############################################# #############################################
# Verification APIs # Verification APIs
############################################# #############################################
@retry(attempts=4, wait=2, return_is_str=True) @retry(retry_timeout=8)
def verify_router_id(tgen, topo, input_dict, expected=True): def verify_router_id(tgen, topo, input_dict, expected=True):
""" """
Running command "show ip bgp json" for DUT and reading router-id Running command "show ip bgp json" for DUT and reading router-id
@ -1061,7 +1061,7 @@ def verify_router_id(tgen, topo, input_dict, expected=True):
return True return True
@retry(attempts=50, wait=3, return_is_str=True) @retry(retry_timeout=150)
def verify_bgp_convergence(tgen, topo, dut=None, expected=True): def verify_bgp_convergence(tgen, topo, dut=None, expected=True):
""" """
API will verify if BGP is converged with in the given time frame. API will verify if BGP is converged with in the given time frame.
@ -1266,7 +1266,7 @@ def verify_bgp_convergence(tgen, topo, dut=None, expected=True):
return True return True
@retry(attempts=4, wait=4, return_is_str=True) @retry(retry_timeout=16)
def verify_bgp_community( def verify_bgp_community(
tgen, addr_type, router, network, input_dict=None, vrf=None, bestpath=False, expected=True tgen, addr_type, router, network, input_dict=None, vrf=None, bestpath=False, expected=True
): ):
@ -1427,7 +1427,7 @@ def modify_as_number(tgen, topo, input_dict):
return True return True
@retry(attempts=4, wait=2, return_is_str=True) @retry(retry_timeout=8)
def verify_as_numbers(tgen, topo, input_dict, expected=True): def verify_as_numbers(tgen, topo, input_dict, expected=True):
""" """
This API is to verify AS numbers for given DUT by running This API is to verify AS numbers for given DUT by running
@ -1527,7 +1527,7 @@ def verify_as_numbers(tgen, topo, input_dict, expected=True):
return True return True
@retry(attempts=50, wait=3, return_is_str=True) @retry(retry_timeout=150)
def verify_bgp_convergence_from_running_config(tgen, dut=None, expected=True): def verify_bgp_convergence_from_running_config(tgen, dut=None, expected=True):
""" """
API to verify BGP convergence b/w loopback and physical interface. API to verify BGP convergence b/w loopback and physical interface.
@ -2083,7 +2083,7 @@ def verify_bgp_timers_and_functionality(tgen, topo, input_dict):
return True return True
@retry(attempts=4, wait=4, return_is_str=True) @retry(retry_timeout=16)
def verify_bgp_attributes( def verify_bgp_attributes(
tgen, tgen,
addr_type, addr_type,
@ -2223,7 +2223,7 @@ def verify_bgp_attributes(
return True return True
@retry(attempts=4, wait=2, return_is_str=True) @retry(retry_timeout=8)
def verify_best_path_as_per_bgp_attribute( def verify_best_path_as_per_bgp_attribute(
tgen, addr_type, router, input_dict, attribute, expected=True tgen, addr_type, router, input_dict, attribute, expected=True
): ):
@ -2429,7 +2429,7 @@ def verify_best_path_as_per_bgp_attribute(
return True return True
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_best_path_as_per_admin_distance( def verify_best_path_as_per_admin_distance(
tgen, addr_type, router, input_dict, attribute, expected=True tgen, addr_type, router, input_dict, attribute, expected=True
): ):
@ -2543,7 +2543,7 @@ def verify_best_path_as_per_admin_distance(
return True return True
@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2) @retry(retry_timeout=10, initial_wait=2)
def verify_bgp_rib( def verify_bgp_rib(
tgen, addr_type, dut, input_dict, next_hop=None, aspath=None, multi_nh=None, expected=True tgen, addr_type, dut, input_dict, next_hop=None, aspath=None, multi_nh=None, expected=True
): ):
@ -2846,7 +2846,7 @@ def verify_bgp_rib(
return True return True
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer, expected=True): def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
""" """
This API is to verify verify_graceful_restart configuration of DUT and This API is to verify verify_graceful_restart configuration of DUT and
@ -3096,7 +3096,7 @@ def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer, expect
return True return True
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True): def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
""" """
This API is to verify r_bit in the BGP gr capability advertised This API is to verify r_bit in the BGP gr capability advertised
@ -3216,7 +3216,7 @@ def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True return True
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True): def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
""" """
This API is to verify EOR This API is to verify EOR
@ -3379,7 +3379,7 @@ def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True return True
@retry(attempts=4, wait=2, return_is_str=True) @retry(retry_timeout=8)
def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True): def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
""" """
This API is to verify f_bit in the BGP gr capability advertised This API is to verify f_bit in the BGP gr capability advertised
@ -3520,7 +3520,7 @@ def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True return True
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer): def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer):
""" """
This API is to verify graceful restart timers, configured and recieved This API is to verify graceful restart timers, configured and recieved
@ -3648,7 +3648,7 @@ def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer)
return True return True
@retry(attempts=4, wait=2, return_is_str=True) @retry(retry_timeout=8)
def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut, expected=True): def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut, expected=True):
""" """
This API is to verify gr_address_family in the BGP gr capability advertised This API is to verify gr_address_family in the BGP gr capability advertised
@ -3739,7 +3739,7 @@ def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut, expected=T
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_attributes_for_evpn_routes( def verify_attributes_for_evpn_routes(
tgen, tgen,
topo, topo,
@ -4139,7 +4139,7 @@ def verify_attributes_for_evpn_routes(
return False return False
@retry(attempts=5, wait=2, return_is_str=True) @retry(retry_timeout=10)
def verify_evpn_routes( def verify_evpn_routes(
tgen, topo, dut, input_dict, routeType=5, EthTag=0, next_hop=None, expected=True tgen, topo, dut, input_dict, routeType=5, EthTag=0, next_hop=None, expected=True
): ):

View file

@ -19,7 +19,7 @@
# #
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime from datetime import datetime, timedelta
from time import sleep from time import sleep
from copy import deepcopy from copy import deepcopy
from subprocess import call from subprocess import call
@ -37,12 +37,14 @@ import socket
import ipaddress import ipaddress
import platform import platform
if sys.version_info[0] > 2: try:
import io # Imports from python2
import configparser from StringIO import StringIO
else:
import StringIO
import ConfigParser as configparser import ConfigParser as configparser
except ImportError:
# Imports from python3
from io import StringIO
import configparser
from lib.topolog import logger, logger_config from lib.topolog import logger, logger_config
from lib.topogen import TopoRouter, get_topogen from lib.topogen import TopoRouter, get_topogen
@ -136,6 +138,12 @@ DEBUG_LOGS = {
], ],
} }
def is_string(value):
try:
return isinstance(value, basestring)
except NameError:
return isinstance(value, str)
if config.has_option("topogen", "verbosity"): if config.has_option("topogen", "verbosity"):
loglevel = config.get("topogen", "verbosity") loglevel = config.get("topogen", "verbosity")
loglevel = loglevel.upper() loglevel = loglevel.upper()
@ -448,16 +456,6 @@ def check_router_status(tgen):
return True return True
def getStrIO():
"""
Return a StringIO object appropriate for the current python version.
"""
if sys.version_info[0] > 2:
return io.StringIO()
else:
return StringIO.StringIO()
def reset_config_on_routers(tgen, routerName=None): def reset_config_on_routers(tgen, routerName=None):
""" """
Resets configuration on routers to the snapshot created using input JSON Resets configuration on routers to the snapshot created using input JSON
@ -529,7 +527,7 @@ def reset_config_on_routers(tgen, routerName=None):
raise InvalidCLIError("Unknown error in %s", output) raise InvalidCLIError("Unknown error in %s", output)
f = open(dname, "r") f = open(dname, "r")
delta = getStrIO() delta = StringIO()
delta.write("configure terminal\n") delta.write("configure terminal\n")
t_delta = f.read() t_delta = f.read()
@ -563,7 +561,7 @@ def reset_config_on_routers(tgen, routerName=None):
output = router.vtysh_multicmd(delta.getvalue(), pretty_output=False) output = router.vtysh_multicmd(delta.getvalue(), pretty_output=False)
delta.close() delta.close()
delta = getStrIO() delta = StringIO()
cfg = router.run("vtysh -c 'show running'") cfg = router.run("vtysh -c 'show running'")
for line in cfg.split("\n"): for line in cfg.split("\n"):
line = line.strip() line = line.strip()
@ -1619,60 +1617,99 @@ def interface_status(tgen, topo, input_dict):
return True return True
def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict=False): def retry(retry_timeout, initial_wait=0, expected=True, diag_pct=0.75):
""" """
Retries function execution, if return is an errormsg or exception Fixture: Retries function while it's return value is an errormsg (str), False, or it raises an exception.
* `attempts`: Number of attempts to make
* `wait`: Number of seconds to wait between each attempt
* `return_is_str`: Return val is an errormsg in case of failure
* `initial_wait`: Sleeps for this much seconds before executing function
* `retry_timeout`: Retry for at least this many seconds; after waiting initial_wait seconds
* `initial_wait`: Sleeps for this many seconds before first executing function
* `expected`: if False then the return logic is inverted, except for exceptions,
(i.e., a False or errmsg (str) function return ends the retry loop,
and returns that False or str value)
* `diag_pct`: Percentage of `retry_timeout` to keep testing after negative result would have
been returned in order to see if a positive result comes after. This is an
important diagnostic tool, and normally should not be disabled. Calls to wrapped
functions though, can override the `diag_pct` value to make it larger in case more
diagnostic retrying is appropriate.
""" """
def _retry(func): def _retry(func):
@wraps(func) @wraps(func)
def func_retry(*args, **kwargs): def func_retry(*args, **kwargs):
_wait = kwargs.pop("wait", wait) # We will continue to retry diag_pct of the timeout value to see if test would have passed with a
_attempts = kwargs.pop("attempts", attempts) # longer retry timeout value.
_attempts = int(_attempts) saved_failure = None
if _attempts < 0:
raise ValueError("attempts must be 0 or greater") retry_sleep = 2
# Allow the wrapped function's args to override the fixtures
_retry_timeout = kwargs.pop("retry_timeout", retry_timeout)
_expected = kwargs.pop("expected", expected)
_initial_wait = kwargs.pop("initial_wait", initial_wait)
_diag_pct = kwargs.pop("diag_pct", diag_pct)
start_time = datetime.now()
retry_until = datetime.now() + timedelta(seconds=_retry_timeout + _initial_wait)
if initial_wait > 0: if initial_wait > 0:
logger.info("Waiting for [%s]s as initial delay", initial_wait) logger.info("Waiting for [%s]s as initial delay", initial_wait)
sleep(initial_wait) sleep(initial_wait)
_return_is_str = kwargs.pop("return_is_str", return_is_str) invert_logic = not _expected
_return_is_dict = kwargs.pop("return_is_str", return_is_dict) while True:
_expected = kwargs.setdefault("expected", True) seconds_left = (retry_until - datetime.now()).total_seconds()
kwargs.pop("expected")
for i in range(1, _attempts + 1):
try: try:
ret = func(*args, **kwargs) ret = func(*args, **kwargs)
logger.debug("Function returned %s", ret) logger.debug("Function returned %s", ret)
if _return_is_str and isinstance(ret, bool) and _expected:
return ret
if (
isinstance(ret, str) or isinstance(ret, unicode)
) and _expected is False:
return ret
if _return_is_dict and isinstance(ret, dict):
return ret
if _attempts == i: negative_result = ret is False or is_string(ret)
generate_support_bundle() if negative_result == invert_logic:
return ret # Simple case, successful result in time
except Exception as err: if not saved_failure:
if _attempts == i: return ret
generate_support_bundle()
logger.info("Max number of attempts (%r) reached", _attempts) # Positive result, but happened after timeout failure, very important to
raise # note for fixing tests.
else: logger.warning("RETRY DIAGNOSTIC: SUCCEED after FAILED with requested timeout of %.1fs; however, succeeded in %.1fs, investigate timeout timing",
logger.info("Function returned %s", err) _retry_timeout, (datetime.now() - start_time).total_seconds())
if i < _attempts: if isinstance(saved_failure, Exception):
logger.info("Retry [#%r] after sleeping for %ss" % (i, _wait)) raise saved_failure # pylint: disable=E0702
sleep(_wait) return saved_failure
except Exception as error:
logger.info("Function raised exception: %s", str(error))
ret = error
if seconds_left < 0 and saved_failure:
logger.info("RETRY DIAGNOSTIC: Retry timeout reached, still failing")
if isinstance(saved_failure, Exception):
raise saved_failure # pylint: disable=E0702
return saved_failure
if seconds_left < 0:
logger.info("Retry timeout of %ds reached", _retry_timeout)
saved_failure = ret
retry_extra_delta = timedelta(seconds=seconds_left + _retry_timeout * _diag_pct)
retry_until = datetime.now() + retry_extra_delta
seconds_left = retry_extra_delta.total_seconds()
# Generate bundle after setting remaining diagnostic retry time
generate_support_bundle()
# If user has disabled diagnostic retries return now
if not _diag_pct:
if isinstance(saved_failure, Exception):
raise saved_failure
return saved_failure
if saved_failure:
logger.info("RETRY DIAG: [failure] Sleeping %ds until next retry with %.1f retry time left - too see if timeout was too short",
retry_sleep, seconds_left)
else:
logger.info("Sleeping %ds until next retry with %.1f retry time left",
retry_sleep, seconds_left)
sleep(retry_sleep)
func_retry._original = func func_retry._original = func
return func_retry return func_retry
@ -2881,7 +2918,7 @@ def configure_interface_mac(tgen, input_dict):
############################################# #############################################
# Verification APIs # Verification APIs
############################################# #############################################
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_rib( def verify_rib(
tgen, tgen,
addr_type, addr_type,
@ -3290,7 +3327,7 @@ def verify_rib(
return True return True
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None): def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
""" """
Data will be read from input_dict or input JSON file, API will generate Data will be read from input_dict or input JSON file, API will generate
@ -3694,7 +3731,7 @@ def verify_prefix_lists(tgen, input_dict):
return True return True
@retry(attempts=3, wait=4, return_is_str=True) @retry(retry_timeout=12)
def verify_route_maps(tgen, input_dict): def verify_route_maps(tgen, input_dict):
""" """
Running "show route-map" command and verifying given route-map Running "show route-map" command and verifying given route-map
@ -3746,7 +3783,7 @@ def verify_route_maps(tgen, input_dict):
return True return True
@retry(attempts=4, wait=4, return_is_str=True) @retry(retry_timeout=16)
def verify_bgp_community(tgen, addr_type, router, network, input_dict=None): def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
""" """
API to veiryf BGP large community is attached in route for any given API to veiryf BGP large community is attached in route for any given
@ -3982,7 +4019,7 @@ def verify_cli_json(tgen, input_dict):
return True return True
@retry(attempts=3, wait=4, return_is_str=True) @retry(retry_timeout=12)
def verify_evpn_vni(tgen, input_dict): def verify_evpn_vni(tgen, input_dict):
""" """
API to verify evpn vni details using "show evpn vni detail json" API to verify evpn vni details using "show evpn vni detail json"
@ -4100,7 +4137,7 @@ def verify_evpn_vni(tgen, input_dict):
return False return False
@retry(attempts=3, wait=4, return_is_str=True) @retry(retry_timeout=12)
def verify_vrf_vni(tgen, input_dict): def verify_vrf_vni(tgen, input_dict):
""" """
API to verify vrf vni details using "show vrf vni json" API to verify vrf vni details using "show vrf vni json"

View file

@ -579,7 +579,7 @@ def redistribute_ospf(tgen, topo, dut, route_type, **kwargs):
################################ ################################
# Verification procs # Verification procs
################################ ################################
@retry(attempts=40, wait=2, return_is_str=True) @retry(retry_timeout=80)
def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False, expected=True): def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False, expected=True):
""" """
This API is to verify ospf neighborship by running This API is to verify ospf neighborship by running
@ -774,7 +774,7 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False, expec
################################ ################################
# Verification procs # Verification procs
################################ ################################
@retry(attempts=10, wait=2, return_is_str=True) @retry(retry_timeout=20)
def verify_ospf6_neighbor(tgen, topo, dut=None, input_dict=None, lan=False): def verify_ospf6_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
""" """
This API is to verify ospf neighborship by running This API is to verify ospf neighborship by running
@ -959,7 +959,7 @@ def verify_ospf6_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
return result return result
@retry(attempts=21, wait=2, return_is_str=True) @retry(retry_timeout=40)
def verify_ospf_rib( def verify_ospf_rib(
tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None, expected=True tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None, expected=True
): ):
@ -1236,7 +1236,7 @@ def verify_ospf_rib(
return result return result
@retry(attempts=10, wait=2, return_is_str=True) @retry(retry_timeout=20)
def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None, expected=True): def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None, expected=True):
""" """
This API is to verify ospf routes by running This API is to verify ospf routes by running
@ -1326,7 +1326,7 @@ def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None, expe
return result return result
@retry(attempts=11, wait=2, return_is_str=True) @retry(retry_timeout=20)
def verify_ospf_database(tgen, topo, dut, input_dict, expected=True): def verify_ospf_database(tgen, topo, dut, input_dict, expected=True):
""" """
This API is to verify ospf lsa's by running This API is to verify ospf lsa's by running
@ -1490,7 +1490,7 @@ def verify_ospf_database(tgen, topo, dut, input_dict, expected=True):
return result return result
@retry(attempts=10, wait=2, return_is_str=True) @retry(retry_timeout=20)
def verify_ospf_summary(tgen, topo, dut, input_dict, expected=True): def verify_ospf_summary(tgen, topo, dut, input_dict, expected=True):
""" """
This API is to verify ospf routes by running This API is to verify ospf routes by running
@ -1571,7 +1571,7 @@ def verify_ospf_summary(tgen, topo, dut, input_dict, expected=True):
@retry(attempts=10, wait=3, return_is_str=True) @retry(retry_timeout=30)
def verify_ospf6_rib(tgen, dut, input_dict, next_hop=None, def verify_ospf6_rib(tgen, dut, input_dict, next_hop=None,
tag=None, metric=None, fib=None): tag=None, metric=None, fib=None):
""" """
@ -1811,7 +1811,7 @@ def verify_ospf6_rib(tgen, dut, input_dict, next_hop=None,
return result return result
@retry(attempts=3, wait=2, return_is_str=True) @retry(retry_timeout=6)
def verify_ospf6_interface(tgen, topo, dut=None,lan=False, input_dict=None): def verify_ospf6_interface(tgen, topo, dut=None,lan=False, input_dict=None):
""" """
This API is to verify ospf routes by running This API is to verify ospf routes by running
@ -1905,7 +1905,7 @@ def verify_ospf6_interface(tgen, topo, dut=None,lan=False, input_dict=None):
return result return result
@retry(attempts=11, wait=2, return_is_str=True) @retry(retry_timeout=20)
def verify_ospf6_database(tgen, topo, dut, input_dict): def verify_ospf6_database(tgen, topo, dut, input_dict):
""" """
This API is to verify ospf lsa's by running This API is to verify ospf lsa's by running
@ -2176,9 +2176,9 @@ def config_ospf6_interface (tgen, topo, input_dict=None, build=False,
config_data = [] config_data = []
for lnk in input_dict[router]['links'].keys(): for lnk in input_dict[router]['links'].keys():
if "ospf6" not in input_dict[router]['links'][lnk]: if "ospf6" not in input_dict[router]['links'][lnk]:
logger.debug("Router %s: ospf6 configs is not present in" logger.debug("Router %s: ospf6 config is not present in"
"input_dict, passed input_dict", router, "input_dict, passed input_dict %s", router,
input_dict) str(input_dict))
continue continue
ospf_data = input_dict[router]['links'][lnk]['ospf6'] ospf_data = input_dict[router]['links'][lnk]['ospf6']
data_ospf_area = ospf_data.setdefault("area", None) data_ospf_area = ospf_data.setdefault("area", None)

View file

@ -495,7 +495,7 @@ def configure_pim_force_expire(tgen, topo, input_dict, build=False):
############################################# #############################################
# Verification APIs # Verification APIs
############################################# #############################################
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected=True): def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected=True):
""" """
Verify all PIM neighbors are up and running, config is verified Verify all PIM neighbors are up and running, config is verified
@ -619,7 +619,7 @@ def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected
return True return True
@retry(attempts=21, wait=2, return_is_str=True) @retry(retry_timeout=40)
def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True): def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
""" """
Verify IGMP groups are received from an intended interface Verify IGMP groups are received from an intended interface
@ -693,7 +693,7 @@ def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
return True return True
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_upstream_iif( def verify_upstream_iif(
tgen, dut, iif, src_address, group_addresses, joinState=None, refCount=1, expected=True tgen, dut, iif, src_address, group_addresses, joinState=None, refCount=1, expected=True
): ):
@ -847,7 +847,7 @@ def verify_upstream_iif(
return True return True
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_join_state_and_timer(tgen, dut, iif, src_address, group_addresses, expected=True): def verify_join_state_and_timer(tgen, dut, iif, src_address, group_addresses, expected=True):
""" """
Verify join state is updated correctly and join timer is Verify join state is updated correctly and join timer is
@ -966,7 +966,7 @@ def verify_join_state_and_timer(tgen, dut, iif, src_address, group_addresses, ex
return True return True
@retry(attempts=41, wait=2, return_is_dict=True) @retry(retry_timeout=80)
def verify_ip_mroutes( def verify_ip_mroutes(
tgen, dut, src_address, group_addresses, iif, oil, return_uptime=False, mwait=0, expected=True tgen, dut, src_address, group_addresses, iif, oil, return_uptime=False, mwait=0, expected=True
): ):
@ -1163,7 +1163,7 @@ def verify_ip_mroutes(
return True if return_uptime == False else uptime_dict return True if return_uptime == False else uptime_dict
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_pim_rp_info( def verify_pim_rp_info(
tgen, topo, dut, group_addresses, oif=None, rp=None, source=None, iamrp=None, expected=True tgen, topo, dut, group_addresses, oif=None, rp=None, source=None, iamrp=None, expected=True
): ):
@ -1320,7 +1320,7 @@ def verify_pim_rp_info(
return True return True
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_pim_state( def verify_pim_state(
tgen, dut, iif, oil, group_addresses, src_address=None, installed_fl=None, expected=True tgen, dut, iif, oil, group_addresses, src_address=None, installed_fl=None, expected=True
): ):
@ -1490,7 +1490,7 @@ def verify_pim_interface_traffic(tgen, input_dict):
return output_dict return output_dict
@retry(attempts=21, wait=2, return_is_str=True) @retry(retry_timeout=40)
def verify_pim_interface(tgen, topo, dut, interface=None, interface_ip=None, expected=True): def verify_pim_interface(tgen, topo, dut, interface=None, interface_ip=None, expected=True):
""" """
Verify all PIM interface are up and running, config is verified Verify all PIM interface are up and running, config is verified
@ -1797,7 +1797,7 @@ def clear_ip_igmp_interfaces(tgen, dut):
return True return True
@retry(attempts=10, wait=2, return_is_str=True) @retry(retry_timeout=20)
def clear_ip_mroute_verify(tgen, dut, expected=True): def clear_ip_mroute_verify(tgen, dut, expected=True):
""" """
Clear ip mroute by running "clear ip mroute" cli and verify Clear ip mroute by running "clear ip mroute" cli and verify
@ -2173,7 +2173,7 @@ def find_rp_from_bsrp_info(tgen, dut, bsr, grp=None):
return rp_details return rp_details
@retry(attempts=6, wait=2, return_is_str=True) @retry(retry_timeout=12)
def verify_pim_grp_rp_source(tgen, topo, dut, grp_addr, rp_source, rpadd=None, expected=True): def verify_pim_grp_rp_source(tgen, topo, dut, grp_addr, rp_source, rpadd=None, expected=True):
""" """
Verify pim rp info by running "show ip pim rp-info" cli Verify pim rp info by running "show ip pim rp-info" cli
@ -2276,7 +2276,7 @@ def verify_pim_grp_rp_source(tgen, topo, dut, grp_addr, rp_source, rpadd=None, e
return errormsg return errormsg
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True): def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
""" """
Verify all PIM interface are up and running, config is verified Verify all PIM interface are up and running, config is verified
@ -2332,7 +2332,7 @@ def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
return True return True
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_ip_pim_upstream_rpf(tgen, topo, dut, interface, group_addresses, rp=None, expected=True): def verify_ip_pim_upstream_rpf(tgen, topo, dut, interface, group_addresses, rp=None, expected=True):
""" """
Verify IP PIM upstream rpf, config is verified Verify IP PIM upstream rpf, config is verified
@ -2530,7 +2530,7 @@ def enable_disable_pim_bsm(tgen, router, intf, enable=True):
return result return result
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_ip_pim_join(tgen, topo, dut, interface, group_addresses, src_address=None, expected=True): def verify_ip_pim_join(tgen, topo, dut, interface, group_addresses, src_address=None, expected=True):
""" """
Verify ip pim join by running "show ip pim join" cli Verify ip pim join by running "show ip pim join" cli
@ -2621,7 +2621,7 @@ def verify_ip_pim_join(tgen, topo, dut, interface, group_addresses, src_address=
return True return True
@retry(attempts=31, wait=2, return_is_dict=True) @retry(retry_timeout=60)
def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True): def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
""" """
Verify igmp interface details, verifying following configs: Verify igmp interface details, verifying following configs:
@ -2911,7 +2911,7 @@ def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
return True if stats_return == False else igmp_stats return True if stats_return == False else igmp_stats
@retry(attempts=31, wait=2, return_is_str=True) @retry(retry_timeout=60)
def verify_pim_config(tgen, input_dict, expected=True): def verify_pim_config(tgen, input_dict, expected=True):
""" """
Verify pim interface details, verifying following configs: Verify pim interface details, verifying following configs:
@ -3037,7 +3037,7 @@ def verify_pim_config(tgen, input_dict, expected=True):
return True return True
@retry(attempts=21, wait=2, return_is_dict=True) @retry(retry_timeout=40)
def verify_multicast_traffic(tgen, input_dict, return_traffic=False, expected=True): def verify_multicast_traffic(tgen, input_dict, return_traffic=False, expected=True):
""" """
Verify multicast traffic by running Verify multicast traffic by running
@ -3280,7 +3280,7 @@ def get_refCount_for_mroute(tgen, dut, iif, src_address, group_addresses):
return refCount return refCount
@retry(attempts=21, wait=2, return_is_str=True) @retry(retry_timeout=40)
def verify_multicast_flag_state(tgen, dut, src_address, group_addresses, flag, expected=True): def verify_multicast_flag_state(tgen, dut, src_address, group_addresses, flag, expected=True):
""" """
Verify flag state for mroutes and make sure (*, G)/(S, G) are having Verify flag state for mroutes and make sure (*, G)/(S, G) are having
@ -3375,7 +3375,7 @@ def verify_multicast_flag_state(tgen, dut, src_address, group_addresses, flag, e
return True return True
@retry(attempts=21, wait=2, return_is_str=True) @retry(retry_timeout=40)
def verify_igmp_interface(tgen, topo, dut, igmp_iface, interface_ip, expected=True): def verify_igmp_interface(tgen, topo, dut, igmp_iface, interface_ip, expected=True):
""" """
Verify all IGMP interface are up and running, config is verified Verify all IGMP interface are up and running, config is verified

View file

@ -456,7 +456,7 @@ def test_starg_mroute_p0(request):
# Verify mroute not installed # Verify mroute not installed
step("Verify mroute not installed in l1") step("Verify mroute not installed in l1")
result = verify_ip_mroutes( result = verify_ip_mroutes(
tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, wait=20, expected=False tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, retry_timeout=20, expected=False
) )
assert ( assert (
result is not True result is not True
@ -705,6 +705,7 @@ def test_RP_priority_p0(request):
), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format( ), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format(
tc_name, tc_name,
rp_add1, rp_add1,
rp2[group] if group in rp2 else None
) )
# Verify if that rp is installed # Verify if that rp is installed

View file

@ -257,7 +257,7 @@ def test_ospf_authentication_simple_pass_tc28_p1(request):
sleep(6) sleep(6)
dut = "r2" dut = "r2"
ospf_covergence = verify_ospf_neighbor( ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, attempts=5 tgen, topo, dut=dut, expected=False, retry_timeout=10
) )
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence ospf_covergence
@ -395,7 +395,7 @@ def test_ospf_authentication_md5_tc29_p1(request):
sleep(6) sleep(6)
dut = "r1" dut = "r1"
ospf_covergence = verify_ospf_neighbor( ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, attempts=3 tgen, topo, dut=dut, expected=False, retry_timeout=6
) )
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence ospf_covergence
@ -460,7 +460,7 @@ def test_ospf_authentication_md5_tc29_p1(request):
sleep(6) sleep(6)
dut = "r2" dut = "r2"
ospf_covergence = verify_ospf_neighbor( ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, attempts=5 tgen, topo, dut=dut, expected=False, retry_timeout=10
) )
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence ospf_covergence
@ -610,7 +610,7 @@ def test_ospf_authentication_different_auths_tc30_p1(request):
step("Verify that the neighbour is not FULL between R1 and R2.") step("Verify that the neighbour is not FULL between R1 and R2.")
dut = "r1" dut = "r1"
ospf_covergence = verify_ospf_neighbor( ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, attempts=5 tgen, topo, dut=dut, expected=False, retry_timeout=10
) )
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format( assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence ospf_covergence

View file

@ -326,7 +326,7 @@ def test_ospf_ecmp_tc16_p0(request):
step("Verify that route is withdrawn from R2.") step("Verify that route is withdrawn from R2.")
dut = "r1" dut = "r1"
result = verify_ospf_rib( result = verify_ospf_rib(
tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
) )
assert ( assert (
result is not True result is not True
@ -342,7 +342,7 @@ def test_ospf_ecmp_tc16_p0(request):
input_dict, input_dict,
protocol=protocol, protocol=protocol,
next_hop=nh, next_hop=nh,
attempts=5, retry_timeout=10,
expected=False, expected=False,
) )
assert ( assert (
@ -434,7 +434,7 @@ def test_ospf_ecmp_tc17_p0(request):
step("Verify that route is withdrawn from R2.") step("Verify that route is withdrawn from R2.")
dut = "r1" dut = "r1"
result = verify_ospf_rib( result = verify_ospf_rib(
tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
) )
assert ( assert (
result is not True result is not True
@ -450,7 +450,7 @@ def test_ospf_ecmp_tc17_p0(request):
input_dict, input_dict,
protocol=protocol, protocol=protocol,
next_hop=nh, next_hop=nh,
attempts=5, retry_timeout=10,
expected=False, expected=False,
) )
assert ( assert (

View file

@ -305,7 +305,7 @@ def test_ospf_lan_ecmp_tc18_p0(request):
step("Verify that all the routes are withdrawn from R0") step("Verify that all the routes are withdrawn from R0")
dut = "r1" dut = "r1"
result = verify_ospf_rib( result = verify_ospf_rib(
tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
) )
assert ( assert (
result is not True result is not True
@ -321,7 +321,7 @@ def test_ospf_lan_ecmp_tc18_p0(request):
input_dict, input_dict,
protocol=protocol, protocol=protocol,
next_hop=nh, next_hop=nh,
attempts=5, retry_timeout=10,
expected=False, expected=False,
) )
assert ( assert (

View file

@ -501,7 +501,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request):
dut = "r1" dut = "r1"
protocol = "ospf" protocol = "ospf"
result = verify_ospf_rib(tgen, dut, input_dict, attempts=2, expected=False) result = verify_ospf_rib(tgen, dut, input_dict, retry_timeout=4, expected=False)
assert ( assert (
result is not True result is not True
), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
@ -509,7 +509,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request):
) )
result = verify_rib( result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, attempts=2, expected=False tgen, "ipv4", dut, input_dict, protocol=protocol, retry_timeout=4, expected=False
) )
assert ( assert (
result is not True result is not True

View file

@ -263,7 +263,7 @@ def test_ospf_redistribution_tc5_p0(request):
input_dict, input_dict,
protocol=protocol, protocol=protocol,
next_hop=nh, next_hop=nh,
attempts=5, retry_timeout=10,
expected=False, expected=False,
) )
assert result is not True, ( assert result is not True, (

View file

@ -690,9 +690,8 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ebgp(request):
next_hop=nh, next_hop=nh,
protocol=protocol, protocol=protocol,
fib=True, fib=True,
retry_timeout=6,
expected=False, expected=False,
wait=2,
attempts=3,
) )
assert ( assert (
result is not True result is not True
@ -804,8 +803,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ebgp(request):
protocol=protocol, protocol=protocol,
fib=True, fib=True,
expected=False, expected=False,
wait=2, retry_timeout=6,
attempts=3,
) )
assert ( assert (
result is not True result is not True
@ -1283,8 +1281,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ebgp(request):
protocol=protocol, protocol=protocol,
fib=True, fib=True,
expected=False, expected=False,
wait=2, retry_timeout=6,
attempts=3,
) )
assert ( assert (
result is not True result is not True

View file

@ -695,12 +695,11 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request):
protocol=protocol, protocol=protocol,
fib=True, fib=True,
expected=False, expected=False,
wait=2, retry_timeout=6,
attempts=3,
) )
assert ( assert (
result is not True result is not True
), "Testcase {} : Failed \nError: Routes " " are missing in RIB".format(tc_name) ), "Testcase {} : Failed \nError: Routes " " are present in RIB".format(tc_name)
step( step(
"Remove the static route configured with nexthop N1 to N8, one" "Remove the static route configured with nexthop N1 to N8, one"
@ -808,8 +807,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request):
protocol=protocol, protocol=protocol,
fib=True, fib=True,
expected=False, expected=False,
wait=2, retry_timeout=6,
attempts=3,
) )
assert ( assert (
result is not True result is not True
@ -1512,8 +1510,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ibgp(request):
protocol=protocol, protocol=protocol,
fib=True, fib=True,
expected=False, expected=False,
wait=2, retry_timeout=6,
attempts=3,
) )
assert ( assert (
result is not True result is not True