From 29ba58430dd03f25c5e44f6b02978f1ff1285fe2 Mon Sep 17 00:00:00 2001 From: bingwang Date: Tue, 17 Nov 2020 01:46:50 +0000 Subject: [PATCH 1/5] Implement test_traffic_shift Signed-off-by: bingwang --- ansible/library/exabgp.py | 27 ++-- tests/bgp/bgp_monitor_dump.py | 23 +++ tests/bgp/templates/bgpmon.j2 | 15 ++ tests/bgp/test_traffic_shift.py | 268 ++++++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+), 11 deletions(-) create mode 100644 tests/bgp/bgp_monitor_dump.py create mode 100644 tests/bgp/templates/bgpmon.j2 create mode 100644 tests/bgp/test_traffic_shift.py diff --git a/ansible/library/exabgp.py b/ansible/library/exabgp.py index 1c8f938237d..84e04128812 100644 --- a/ansible/library/exabgp.py +++ b/ansible/library/exabgp.py @@ -41,6 +41,8 @@ import jinja2 from ansible.module_utils.basic import * +DEFAULT_DUMP_SCRIPT = "/usr/share/exabgp/dump.py" + dump_py = '''\ #!/usr/bin/env python @@ -94,7 +96,7 @@ def run_command(): parsed; update; } - run /usr/bin/python /usr/share/exabgp/dump.py; + run /usr/bin/python {{ dump_script }}; } process http-api { @@ -165,7 +167,7 @@ def restart_exabgp(module, name): def stop_exabgp(module, name): exec_command(module, cmd="supervisorctl stop exabgp-%s" % name, ignore_error=True) -def setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port, auto_flush=True, group_updates=True): +def setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port, auto_flush=True, group_updates=True, dump_script=DEFAULT_DUMP_SCRIPT): try: os.mkdir("/etc/exabgp", 0755) except OSError: @@ -180,7 +182,8 @@ def setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, p peer_asn=peer_asn, \ port=port, \ auto_flush=auto_flush, \ - group_updates=group_updates) + group_updates=group_updates, \ + dump_script=dump_script) with open("/etc/exabgp/%s.conf" % name, 'w') as out_file: out_file.write(data) @@ -203,14 +206,14 @@ def remove_exabgp_supervisord_conf(name): except Exception: pass -def setup_exabgp_processor(): +def setup_exabgp_processor(default_dump_script): try: os.mkdir("/usr/share/exabgp", 0755) except OSError: pass - - with open("/usr/share/exabgp/dump.py", 'w') as out_file: - out_file.write(dump_py) + if default_dump_script: + with open(DEFAULT_DUMP_SCRIPT, 'w') as out_file: + out_file.write(dump_py) with open("/usr/share/exabgp/http_api.py", 'w') as out_file: out_file.write(http_api_py) @@ -225,6 +228,7 @@ def main(): local_asn=dict(required=False, type='int'), peer_asn=dict(required=False, type='int'), port=dict(required=False, type='int', default=5000), + dump_script=dict(required=False, type='str', default=DEFAULT_DUMP_SCRIPT) ), supports_check_mode=False) @@ -236,21 +240,22 @@ def main(): local_asn = module.params['local_asn'] peer_asn = module.params['peer_asn'] port = module.params['port'] + dump_script = module.params['dump_script'] - setup_exabgp_processor() + setup_exabgp_processor(dump_script==DEFAULT_DUMP_SCRIPT) result = {} try: if state == 'started': - setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port) + setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port, dump_script=dump_script) setup_exabgp_supervisord_conf(name) start_exabgp(module, name) elif state == 'restarted': - setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port) + setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port, dump_script=dump_script) setup_exabgp_supervisord_conf(name) restart_exabgp(module, name) elif state == 'present': - setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port) + setup_exabgp_conf(name, router_id, local_ip, peer_ip, local_asn, peer_asn, port, dump_script=dump_script) setup_exabgp_supervisord_conf(name) refresh_supervisord(module) elif state == 'stopped': diff --git a/tests/bgp/bgp_monitor_dump.py b/tests/bgp/bgp_monitor_dump.py new file mode 100644 index 00000000000..e54c1f4d3fd --- /dev/null +++ b/tests/bgp/bgp_monitor_dump.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +from sys import stdin +import json + +DUMP_FILE = "/tmp/bgp_monitor_dump.log" + +while True: + try: + line = stdin.readline() + obj = json.loads(line) + if 'update' not in obj['neighbor']['message']: + continue + f = open(DUMP_FILE, "a") + announce = obj['neighbor']['message']['update']['announce'] + keys = ('ipv4 unicast', 'ipv6 unicast') + for key in keys: + if key in announce: + for _, route in announce[key].items(): + for ip, _ in route.items(): + f.write(ip + "\n") + finally: + f.close() diff --git a/tests/bgp/templates/bgpmon.j2 b/tests/bgp/templates/bgpmon.j2 new file mode 100644 index 00000000000..0bd74768bda --- /dev/null +++ b/tests/bgp/templates/bgpmon.j2 @@ -0,0 +1,15 @@ +{ + "BGP_MONITORS": { + "{{ peer_addr }}": { + "admin_status": "up", + "asn": "{{ asn }}", + "holdtime": "10", + "keepalive": "3", + "local_addr": "{{ local_addr }}", + "name": "{{ peer_name }}", + "nhopself": "0", + "rrclient": "0" + } + } +} + diff --git a/tests/bgp/test_traffic_shift.py b/tests/bgp/test_traffic_shift.py new file mode 100644 index 00000000000..5c5acc93106 --- /dev/null +++ b/tests/bgp/test_traffic_shift.py @@ -0,0 +1,268 @@ +import pytest +import logging +import json +import time +import ipaddr as ipaddress +from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_tcp_connection +from jinja2 import Template +import re + +pytestmark = [ + pytest.mark.topology('t1') +] + +logger = logging.getLogger(__name__) + +TS_NORMAL = "System Mode: Normal" +TS_MAINTENANCE = "System Mode: Maintenance" +TS_ERROR = "System Mode: Not consistent" + +DUMP_FILE = "/tmp/bgp_monitor_dump.log" +CUSTOM_DUMP_SCRIPT = "bgp/bgp_monitor_dump.py" +CUSTOM_DUMP_SCRIPT_DEST = "/usr/share/exabgp/bgp_monitor_dump.py" +BGP_MONITOR_PORT = 7000 +BGP_MONITOR_NAME = "bgp_monitor" +BGP_ANNOUNCE_TIME = 30 #should be enough to receive and parse bgp updates + +# TODO: remove me +BGPMON_TEMPLATE_FILE = 'bgp/templates/bgpmon.j2' +BGPMON_CONFIG_FILE = '/tmp/bgpmon.json' + +@pytest.fixture +def traffic_shift_community(duthost): + community = duthost.shell('sonic-cfggen -y /etc/sonic/constants.yml -v constants.bgp.traffic_shift_community')['stdout'] + return community + +@pytest.fixture +def common_setup_teardown(ptfhost, duthost, localhost): + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + dut_lo_addr = mg_facts['minigraph_lo_interfaces'][0]['addr'] + dut_mgmt_ip = mg_facts['minigraph_mgmt_interface']['addr'] + asn = mg_facts['minigraph_bgp_asn'] + peer_addr = ptfhost.mgmt_ip + # TODO: Add a common method to load BGPMON config for test_bgpmon and test_traffic_shift + logger.info("Configuring bgp monitor session on DUT") + bgpmon_args = { + 'peer_addr': peer_addr, + 'asn': asn, + 'local_addr': dut_lo_addr, + 'peer_name': BGP_MONITOR_NAME + } + bgpmon_template = Template(open(BGPMON_TEMPLATE_FILE).read()) + duthost.copy(content=bgpmon_template.render(**bgpmon_args), + dest=BGPMON_CONFIG_FILE) + + # Add a static route via mgmt interface on ptf + ptfhost.shell('ip route add {}/32 via {} dev mgmt'.format(dut_lo_addr, dut_mgmt_ip)) + logger.info("Starting bgp monitor session on PTF") + ptfhost.file(path=DUMP_FILE, state="absent") + ptfhost.copy(src=CUSTOM_DUMP_SCRIPT, dest=CUSTOM_DUMP_SCRIPT_DEST) + ptfhost.exabgp(name=BGP_MONITOR_NAME, + state="started", + local_ip=peer_addr, + router_id=peer_addr, + peer_ip=dut_lo_addr, + local_asn=asn, + peer_asn=asn, + port=BGP_MONITOR_PORT, + dump_script=CUSTOM_DUMP_SCRIPT_DEST) + pytest_assert(wait_tcp_connection(localhost, ptfhost.mgmt_ip, BGP_MONITOR_PORT), + "Failed to start bgp monitor session on PTF") + yield + # Cleanup bgp monitor + duthost.shell("redis-cli -n 4 -c DEL 'BGP_MONITORS|{}'".format(peer_addr)) + ptfhost.exabgp(name=BGP_MONITOR_NAME, state="absent") + ptfhost.file(path=CUSTOM_DUMP_SCRIPT_DEST, state="absent") + ptfhost.file(path=DUMP_FILE, state="absent") + ptfhost.shell('ip route flush {}/32'.format(dut_lo_addr)) + +def get_traffic_shift_state(host): + outputs = host.shell('TSC')['stdout_lines'] + for out in outputs: + if TS_NORMAL == out.strip(): + return TS_NORMAL + if TS_MAINTENANCE == out.strip(): + return TS_MAINTENANCE + return TS_ERROR + +def parse_exabgp_dump(host): + """ + Parse the dump file of exabgp, and build a set for checking routes + """ + routes = set() + output_lines = host.shell("cat {}".format(DUMP_FILE))['stdout_lines'] + for line in output_lines: + routes.add(line) + return routes + +def parse_rib(host, ip_ver): + """ + Parse output of 'show bgp ipv4/6' and parse into a dict for checking routes + """ + routes = {} + cmd = "vtysh -c \"show bgp ipv%d json\"" % ip_ver + route_data = json.loads(host.shell(cmd)['stdout']) + for ip, nexthops in route_data['routes'].iteritems(): + aspath = set() + for nexthop in nexthops: + aspath.add(nexthop['aspath']) + routes[ip] = aspath + return routes + +def verify_all_routes_announce_to_bgpmon(routes_bgpmon, routes_dut): + logger.info("Verifying all routes are announced to BGPMON") + for route in routes_dut.keys(): + if route not in routes_bgpmon: + return False + return True + +def parse_routes_on_eos(dut_host, neigh_hosts, ip_ver): + """ + Parse the output of 'show ip bgp neigh received-routes' on eos, and store in a dict + """ + mg_facts = dut_host.minigraph_facts(host=dut_host.hostname)['ansible_facts'] + asn = mg_facts['minigraph_bgp_asn'] + all_routes = {} + BGP_ENTRY_HEADING = r"BGP routing table entry for " + BGP_COMMUNITY_HEADING = r"Community: " + for hostname, host_conf in neigh_hosts.items(): + host = host_conf['host'] + peer_ips = host_conf['conf']['bgp']['peers'][asn] + for ip in peer_ips: + if ipaddress.IPNetwork(ip).version == 4: + peer_ip_v4 = ip + else: + peer_ip_v6 = ip + # The json formatter on EOS consumes too much time (over 40 seconds). + # So we have to parse the raw output instead json. + if 4 == ip_ver: + cmd = "show ip bgp neighbors {} received-routes detail | grep -E \"{}|{}\"".format(peer_ip_v4, BGP_ENTRY_HEADING, BGP_COMMUNITY_HEADING) + else: + cmd = "show ipv6 bgp peers {} received-routes detail | grep -E \"{}|{}\"".format(peer_ip_v6, BGP_ENTRY_HEADING, BGP_COMMUNITY_HEADING) + output_lines = host.eos_command(commands=[cmd])['stdout_lines'][0] + routes = {} + entry = None + for line in output_lines: + addr = re.findall(BGP_ENTRY_HEADING + r"(.+)", line) + if addr: + if entry: + routes[entry] = "" + entry = None + entry = addr[0] + community = re.findall(BGP_COMMUNITY_HEADING + r"(.+)", line) + if community: + if entry: + routes[entry] = community[0] + entry = None + community = "" + if entry: + routes[entry] = community + all_routes[hostname] = routes + return all_routes + +def verify_all_routes_announce_to_neighs(dut_host, neigh_hosts, routes_dut, ip_ver): + """ + Verify all routes are announced to neighbors in TSB + """ + logger.info("Verifying all routes(ipv{}) are announced to bgp neighbors".format(ip_ver)) + routes_on_all_eos = parse_routes_on_eos(dut_host, neigh_hosts, ip_ver) + # Check routes on all neigh + for hostname, routes in routes_on_all_eos.iteritems(): + logger.info("Verifying all routes(ipv{}) are announced to {}".format(ip_ver, hostname)) + for route, aspaths in routes_dut.iteritems(): + # Filter out routes announced by this neigh + skip = False + for aspath in aspaths: + if str(neigh_hosts[hostname]['conf']['bgp']['asn']) in aspath: + skip = True + break + if skip: + continue + if route not in routes.keys(): + logger.warn("{} not found on {}".format(route, hostname)) + return False + return True + +def verify_loopback_route_with_community(dut_host, neigh_hosts, ip_ver, community): + logger.info("Verifying only loopback routes are announced to bgp neighbors") + mg_facts = dut_host.minigraph_facts(host=dut_host.hostname)['ansible_facts'] + for i in range(0, 2): + addr = mg_facts['minigraph_lo_interfaces'][i]['addr'] + if ipaddress.IPNetwork(addr).version == 4: + lo_addr_v4 = addr + else: + lo_addr_v6 = addr + if 4 == ip_ver: + lo_addr = lo_addr_v4 + else: + lo_addr = lo_addr_v6 + routes_on_all_eos = parse_routes_on_eos(dut_host, neigh_hosts, ip_ver) + for hostname, routes in routes_on_all_eos.iteritems(): + logger.info("Verifying only loopback routes(ipv{}) are announced to {}".format(ip_ver, hostname)) + for prefix, received_community in routes.iteritems(): + if ipaddress.IPNetwork(prefix) != ipaddress.IPNetwork(lo_addr): + logger.warn("route for {} is found on {}, which is not in loopback address".format(prefix, hostname)) + return False + if received_community != community: + logger.warn("community for route {} is unexpected {}".format(prefix, received_community)) + return False + return True + +def verify_only_loopback_routes_are_announced_to_neighs(dut_host, neigh_hosts, community): + """ + Verify only loopback routes with certain community are announced to neighs in TSA + """ + return verify_loopback_route_with_community(dut_host, neigh_hosts, 4, community) and \ + verify_loopback_route_with_community(dut_host, neigh_hosts, 6, community) + +def test_TSA(duthost, ptfhost, nbrhosts, common_setup_teardown, traffic_shift_community): + """ + Test TSA + Verify all routes are announced to bgp monitor, and only loopback routes are announced to neighs + """ + try: + # Issue TSA on DUT + duthost.shell("TSA") + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(duthost), + "DUT is not in maintenance state") + # Start bgpmon on DUT + logger.info("Starting bgpmon on DUT") + duthost.command("sonic-cfggen -j {} -w".format(BGPMON_CONFIG_FILE)) + time.sleep(BGP_ANNOUNCE_TIME) + bgpmon_routes = parse_exabgp_dump(ptfhost) + rib_v4 = parse_rib(duthost, 4) + rib_v6 = parse_rib(duthost, 6) + pytest_assert(verify_all_routes_announce_to_bgpmon(bgpmon_routes, dict(rib_v4.items() + rib_v6.items())), + "Not all routes are announced to bgpmon") + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs(duthost, nbrhosts, traffic_shift_community), + "Failed to verify routes on eos in TSA") + finally: + # Recover to Normal state + duthost.shell("TSB") + +def test_TSB(duthost, ptfhost, nbrhosts, common_setup_teardown): + """ + Test TSB. + Establish BGP session between PTF and DUT, and verify all routes are announced to bgp monitor, + and all routes are announced to neighbors + """ + # Issue TSB on DUT + duthost.shell("TSB") + # Verify DUT is in normal state. + pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), + "DUT is not in normal state") + # Start bgpmon on DUT + logger.info("Starting bgpmon on DUT") + duthost.command("sonic-cfggen -j {} -w".format(BGPMON_CONFIG_FILE)) + time.sleep(BGP_ANNOUNCE_TIME) + bgpmon_routes = parse_exabgp_dump(ptfhost) + rib_v4 = parse_rib(duthost, 4) + rib_v6 = parse_rib(duthost, 6) + pytest_assert(verify_all_routes_announce_to_bgpmon(bgpmon_routes, dict(rib_v4.items() + rib_v6.items())), + "Not all routes are announced to bgpmon") + pytest_assert(verify_all_routes_announce_to_neighs(duthost, nbrhosts, rib_v4, 4), + "Not all ipv4 routes are announced to neighbors") + pytest_assert(verify_all_routes_announce_to_neighs(duthost, nbrhosts, rib_v6, 6), + "Not all ipv6 routes are announced to neighbors") From 9e9161466f19b4d980ebb313ed4569544e1bf6c9 Mon Sep 17 00:00:00 2001 From: bingwang Date: Wed, 18 Nov 2020 10:08:52 +0000 Subject: [PATCH 2/5] Remove bgpmon.j2 Signed-off-by: bingwang --- tests/bgp/templates/bgpmon.j2 | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 tests/bgp/templates/bgpmon.j2 diff --git a/tests/bgp/templates/bgpmon.j2 b/tests/bgp/templates/bgpmon.j2 deleted file mode 100644 index 0bd74768bda..00000000000 --- a/tests/bgp/templates/bgpmon.j2 +++ /dev/null @@ -1,15 +0,0 @@ -{ - "BGP_MONITORS": { - "{{ peer_addr }}": { - "admin_status": "up", - "asn": "{{ asn }}", - "holdtime": "10", - "keepalive": "3", - "local_addr": "{{ local_addr }}", - "name": "{{ peer_name }}", - "nhopself": "0", - "rrclient": "0" - } - } -} - From c3f2fbaa253f6596769ff832ac767be2c504871b Mon Sep 17 00:00:00 2001 From: bingwang Date: Thu, 19 Nov 2020 02:51:46 +0000 Subject: [PATCH 3/5] Update Loopback ipv6 address Signed-off-by: bingwang --- tests/bgp/test_traffic_shift.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/bgp/test_traffic_shift.py b/tests/bgp/test_traffic_shift.py index 5c5acc93106..0397b2b37c2 100644 --- a/tests/bgp/test_traffic_shift.py +++ b/tests/bgp/test_traffic_shift.py @@ -138,9 +138,15 @@ def parse_routes_on_eos(dut_host, neigh_hosts, ip_ver): # So we have to parse the raw output instead json. if 4 == ip_ver: cmd = "show ip bgp neighbors {} received-routes detail | grep -E \"{}|{}\"".format(peer_ip_v4, BGP_ENTRY_HEADING, BGP_COMMUNITY_HEADING) + cmd_backup = "" else: cmd = "show ipv6 bgp peers {} received-routes detail | grep -E \"{}|{}\"".format(peer_ip_v6, BGP_ENTRY_HEADING, BGP_COMMUNITY_HEADING) + # For compatibility on EOS of old version + cmd_backup = "show ipv6 bgp neighbors {} received-routes detail | grep -E \"{}|{}\"".format(peer_ip_v6, BGP_ENTRY_HEADING, BGP_COMMUNITY_HEADING) output_lines = host.eos_command(commands=[cmd])['stdout_lines'][0] + if len(output_lines) == 0 and cmd_backup != "": + output_lines = host.eos_command(commands=[cmd])['stdout_lines'][0] + pytest_assert(len(output_lines) != 0, "Failed to retrieve routes from VM {}".format(hostname)) routes = {} entry = None for line in output_lines: @@ -190,9 +196,10 @@ def verify_loopback_route_with_community(dut_host, neigh_hosts, ip_ver, communit for i in range(0, 2): addr = mg_facts['minigraph_lo_interfaces'][i]['addr'] if ipaddress.IPNetwork(addr).version == 4: - lo_addr_v4 = addr + lo_addr_v4 = ipaddress.IPNetwork(addr) else: - lo_addr_v6 = addr + # The IPv6 Loopback announced to neighbors is /64 + lo_addr_v6 = ipaddress.IPNetwork(addr + "/64") if 4 == ip_ver: lo_addr = lo_addr_v4 else: @@ -201,7 +208,7 @@ def verify_loopback_route_with_community(dut_host, neigh_hosts, ip_ver, communit for hostname, routes in routes_on_all_eos.iteritems(): logger.info("Verifying only loopback routes(ipv{}) are announced to {}".format(ip_ver, hostname)) for prefix, received_community in routes.iteritems(): - if ipaddress.IPNetwork(prefix) != ipaddress.IPNetwork(lo_addr): + if ipaddress.IPNetwork(prefix) != lo_addr: logger.warn("route for {} is found on {}, which is not in loopback address".format(prefix, hostname)) return False if received_community != community: From f2e18a67372d9b6fe2f6a0e46bee93ebe65fd137 Mon Sep 17 00:00:00 2001 From: bingwang Date: Thu, 19 Nov 2020 04:41:44 +0000 Subject: [PATCH 4/5] Update dump script to with Signed-off-by: bingwang --- tests/bgp/bgp_monitor_dump.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/bgp/bgp_monitor_dump.py b/tests/bgp/bgp_monitor_dump.py index e54c1f4d3fd..1a049339494 100644 --- a/tests/bgp/bgp_monitor_dump.py +++ b/tests/bgp/bgp_monitor_dump.py @@ -6,12 +6,11 @@ DUMP_FILE = "/tmp/bgp_monitor_dump.log" while True: - try: + with open(DUMP_FILE, "a") as f: line = stdin.readline() obj = json.loads(line) if 'update' not in obj['neighbor']['message']: continue - f = open(DUMP_FILE, "a") announce = obj['neighbor']['message']['update']['announce'] keys = ('ipv4 unicast', 'ipv6 unicast') for key in keys: @@ -19,5 +18,3 @@ for _, route in announce[key].items(): for ip, _ in route.items(): f.write(ip + "\n") - finally: - f.close() From 30a076a48a448815aed9837325f57ef1a749189d Mon Sep 17 00:00:00 2001 From: bingwang Date: Fri, 20 Nov 2020 02:10:11 +0000 Subject: [PATCH 5/5] Update after review 1. Rename 'default_dump_script' to 'use_default_dump_script' 2. Rename 'TS_ERROR' to 'TS_INCONSISTENT' 3. Raise exception for unexpected state of 'TSC' Signed-off-by: bingwang --- ansible/library/exabgp.py | 4 ++-- tests/bgp/test_traffic_shift.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ansible/library/exabgp.py b/ansible/library/exabgp.py index 84e04128812..5b05be4b401 100644 --- a/ansible/library/exabgp.py +++ b/ansible/library/exabgp.py @@ -206,12 +206,12 @@ def remove_exabgp_supervisord_conf(name): except Exception: pass -def setup_exabgp_processor(default_dump_script): +def setup_exabgp_processor(use_default_dump_script): try: os.mkdir("/usr/share/exabgp", 0755) except OSError: pass - if default_dump_script: + if use_default_dump_script: with open(DEFAULT_DUMP_SCRIPT, 'w') as out_file: out_file.write(dump_py) with open("/usr/share/exabgp/http_api.py", 'w') as out_file: diff --git a/tests/bgp/test_traffic_shift.py b/tests/bgp/test_traffic_shift.py index 0397b2b37c2..fcce0956629 100644 --- a/tests/bgp/test_traffic_shift.py +++ b/tests/bgp/test_traffic_shift.py @@ -16,7 +16,7 @@ TS_NORMAL = "System Mode: Normal" TS_MAINTENANCE = "System Mode: Maintenance" -TS_ERROR = "System Mode: Not consistent" +TS_INCONSISTENT = "System Mode: Not consistent" DUMP_FILE = "/tmp/bgp_monitor_dump.log" CUSTOM_DUMP_SCRIPT = "bgp/bgp_monitor_dump.py" @@ -84,7 +84,9 @@ def get_traffic_shift_state(host): return TS_NORMAL if TS_MAINTENANCE == out.strip(): return TS_MAINTENANCE - return TS_ERROR + if TS_INCONSISTENT == out.strip(): + return TS_INCONSISTENT + pytest.fail("TSC return unexpected state {}".format(out)) def parse_exabgp_dump(host): """