diff options
Diffstat (limited to 'tests/topotests/lib/common_config.py')
| -rw-r--r-- | tests/topotests/lib/common_config.py | 199 |
1 files changed, 189 insertions, 10 deletions
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 5ee59070cc..72ee28c1c6 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -179,7 +179,7 @@ def run_frr_cmd(rnode, cmd, isjson=False): raise InvalidCLIError("No actual cmd passed") -def create_common_configuration(tgen, router, data, config_type=None, build=False): +def create_common_configuration(tgen, router, data, config_type=None, build=False, load_config=True): """ API to create object of class FRRConfig and also create frr_json.conf file. It will create interface and common configurations and save it to @@ -216,6 +216,8 @@ def create_common_configuration(tgen, router, data, config_type=None, build=Fals if build: mode = "a" + elif not load_config: + mode = "a" else: mode = "w" @@ -236,12 +238,128 @@ def create_common_configuration(tgen, router, data, config_type=None, build=Fals frr_cfg_fd.close() # If configuration applied from build, it will done at last - if not build: + if not build and load_config: load_config_to_router(tgen, router) return True +def kill_router_daemons(tgen, router, daemons): + """ + Router's current config would be saved to /etc/frr/ for each deamon + and deamon would be killed forcefully using SIGKILL. + + * `tgen` : topogen object + * `router`: Device under test + * `daemons`: list of daemons to be killed + """ + + logger.debug("Entering lib API: kill_router_daemons()") + + try: + router_list = tgen.routers() + + # Saving router config to /etc/frr, which will be loaded to router + # when it starts + router_list[router].vtysh_cmd("write memory") + + # Kill Daemons + result = router_list[router].killDaemons(daemons) + if len(result) > 0: + assert "Errors found post shutdown - details follow:" == 0, result + return result + + except Exception as e: + errormsg = traceback.format_exc() + logger.error(errormsg) + return errormsg + + +def start_router_daemons(tgen, router, daemons): + """ + Daemons defined by user would be started + + * `tgen` : topogen object + * `router`: Device under test + * `daemons`: list of daemons to be killed + """ + + logger.debug("Entering lib API: start_router_daemons()") + + try: + router_list = tgen.routers() + + # Start daemons + result = router_list[router].startDaemons(daemons) + sleep(5) + return result + + except Exception as e: + errormsg = traceback.format_exc() + logger.error(errormsg) + return errormsg + + logger.debug("Exiting lib API: start_router_daemons()") + return True + + +def kill_mininet_routers_process(tgen): + """ + Kill all mininet stale router' processes + + * `tgen` : topogen object + """ + + router_list = tgen.routers() + for rname, router in router_list.iteritems(): + daemon_list = [ + "zebra", + "ospfd", + "ospf6d", + "bgpd", + "ripd", + "ripngd", + "isisd", + "pimd", + "ldpd", + "staticd", + ] + for daemon in daemon_list: + router.run("killall -9 {}".format(daemon)) + + +def check_router_status(tgen): + """ + Check if all daemons are running for all routers in topology + + * `tgen` : topogen object + """ + + logger.debug("Entering lib API: start_router_daemons()") + + try: + router_list = tgen.routers() + for router, rnode in router_list.iteritems(): + + result = rnode.check_router_running() + if result != "": + daemons = [] + if "bgpd" in result: + daemons.append("bgpd") + if "zebra" in result: + daemons.append("zebra") + + rnode.startDaemons(daemons) + + except Exception as e: + errormsg = traceback.format_exc() + logger.error(errormsg) + return errormsg + + logger.debug("Exiting lib API: start_router_daemons()") + return True + + def reset_config_on_routers(tgen, routerName=None): """ Resets configuration on routers to the snapshot created using input JSON @@ -414,6 +532,69 @@ def load_config_to_router(tgen, routerName, save_bkup=False): return True +def get_frr_ipv6_linklocal(tgen, router, intf=None): + """ + API to get the link local ipv6 address of a perticular interface using + FRR command 'show interface' + + * `tgen`: tgen onject + * `router` : router for which hightest interface should be + calculated + * `intf` : interface for which linklocal address needs to be taken + + Usage + ----- + linklocal = get_frr_ipv6_linklocal(tgen, router, "intf1", RED_A) + + Returns + ------- + 1) array of interface names to link local ips. + """ + + router_list = tgen.routers() + for rname, rnode in router_list.iteritems(): + if rname != router: + continue + + linklocal = [] + + cmd = "show interface" + + ifaces = router_list[router].run('vtysh -c "{}"'.format(cmd)) + + # Fix newlines (make them all the same) + ifaces = ("\n".join(ifaces.splitlines()) + "\n").splitlines() + + interface = None + ll_per_if_count = 0 + for line in ifaces: + # Interface name + m = re_search("Interface ([a-zA-Z0-9-]+) is", line) + if m: + interface = m.group(1).split(" ")[0] + ll_per_if_count = 0 + + # Interface ip + m1 = re_search("inet6 (fe80[:a-fA-F0-9]+[\/0-9]+)", line) + if m1: + local = m1.group(1) + ll_per_if_count += 1 + if ll_per_if_count > 1: + linklocal += [["%s-%s" % (interface, ll_per_if_count), local]] + else: + linklocal += [[interface, local]] + + if linklocal: + if intf: + return [_linklocal[1] for _linklocal in linklocal if _linklocal[0] == intf][ + 0 + ].split("/")[0] + return linklocal + else: + errormsg = "Link local ip missing on router {}" + return errormsg + + def start_topology(tgen): """ Starting topology, create tmp files which are loaded to routers @@ -1741,15 +1922,13 @@ def verify_rib(tgen, addr_type, dut, input_dict, next_hop=None, protocol=None): if type(next_hop) is not list: next_hop = [next_hop] - for index, nh in enumerate(next_hop): - if ( - rib_routes_json[st_rt][0]["nexthops"][ - index - ]["ip"] - == nh - ): + for nh in next_hop: + for nh_json in rib_routes_json[st_rt][0]["nexthops"]: + if nh != nh_json["ip"]: + continue nh_found = True - else: + + if not nh_found: errormsg = ( "Nexthop {} is Missing" " for {} route {} in " |
