diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 6b7d900e35..c6eed602a5 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -2540,8 +2540,7 @@ Optionally, you can specify an IP address in order to display only that particul Click [here](#Quagga-BGP-Show-Commands) to see the example for "show ip bgp neighbors" for Quagga. - -**show ip bgp network [[|] [(bestpath | multipath | longer-prefixes | json)]] +**show ip bgp network [[|] [(bestpath | multipath | longer-prefixes | json)]]** This command displays all the details of IPv4 Border Gateway Protocol (BGP) prefixes. diff --git a/show/bgp_frr_v4.py b/show/bgp_frr_v4.py index ddcd688581..1c83bf7914 100644 --- a/show/bgp_frr_v4.py +++ b/show/bgp_frr_v4.py @@ -20,7 +20,10 @@ def bgp(): """Show IPv4 BGP (Border Gateway Protocol) information""" if device_info.is_supervisor(): - subcommand = sys.argv[3] + if sys.argv[3] in "vrf": + subcommand = sys.argv[5] + else: + subcommand = sys.argv[3] if subcommand not in "network": # the command will be executed directly by rexec if it is not "show ip bgp network" click.echo("Since the current device is a chassis supervisor, " + @@ -33,9 +36,7 @@ def bgp(): @bgp.command() @multi_asic_util.multi_asic_click_options def summary(namespace, display): - bgp_summary = bgp_util.get_bgp_summary_from_all_bgp_instances( - constants.IPV4, namespace, display) - bgp_util.display_bgp_summary(bgp_summary=bgp_summary, af=constants.IPV4) + summary_helper(namespace, display) # 'neighbors' subcommand ("show ip bgp neighbors") @@ -46,17 +47,119 @@ def summary(namespace, display): ['routes', 'advertised-routes', 'received-routes']), required=False) @click.option('--namespace', - '-n', - 'namespace', - default=None, - type=str, - show_default=True, - help='Namespace name or all', - callback=multi_asic_util.multi_asic_namespace_validation_callback) + '-n', + 'namespace', + default=None, + type=str, + show_default=True, + help='Namespace name or all', + callback=multi_asic_util.multi_asic_namespace_validation_callback) def neighbors(ipaddress, info_type, namespace): """Show IP (IPv4) BGP neighbors""" + neighbors_helper(ipaddress, info_type, namespace) + + +# 'network' subcommand ("show ip bgp network") +@bgp.command() +@click.argument('ipaddress', + metavar='[|]', + required=True if device_info.is_supervisor() else False) +@click.argument('info_type', + metavar='[bestpath|json|longer-prefixes|multipath]', + type=click.Choice( + ['bestpath', 'json', 'longer-prefixes', 'multipath']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + type=str, + show_default=True, + required=False, + help='Namespace name or all', + default="all", + callback=multi_asic_util.multi_asic_namespace_validation_callback) +def network(ipaddress, info_type, namespace): + """Show IP (IPv4) BGP network""" + network_helper(ipaddress, info_type, namespace) + + +@bgp.group(cls=clicommon.AliasedGroup) +@click.argument('vrf', required=True) +@click.pass_context +def vrf(ctx, vrf): + """Show IPv4 BGP information for a given VRF""" + pass + + +# 'summary' subcommand ("show ip bgp vrf summary") +@vrf.command('summary') +@multi_asic_util.multi_asic_click_options +@click.pass_context +def vrf_summary(ctx, namespace, display): + vrf = ctx.parent.params['vrf'] + summary_helper(namespace, display, vrf) + + +# 'neighbors' subcommand ("show ip bgp vrf neighbors") +@vrf.command('neighbors') +@click.argument('ipaddress', required=False) +@click.argument('info_type', + type=click.Choice( + ['routes', 'advertised-routes', 'received-routes']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + default=None, + type=str, + show_default=True, + help='Namespace name or all', + callback=multi_asic_util.multi_asic_namespace_validation_callback) +@click.pass_context +def vrf_neighbors(ctx, ipaddress, info_type, namespace): + """Show IP (IPv4) BGP neighbors""" + vrf = ctx.parent.params['vrf'] + neighbors_helper(ipaddress, info_type, namespace, vrf) + + +# 'network' subcommand ("show ip bgp vrf network") +@vrf.command('network') +@click.argument('ipaddress', + metavar='[|]', + required=True if device_info.is_supervisor() else False) +@click.argument('info_type', + metavar='[bestpath|json|longer-prefixes|multipath]', + type=click.Choice( + ['bestpath', 'json', 'longer-prefixes', 'multipath']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + type=str, + show_default=True, + required=False, + help='Namespace name or all', + default="all", + callback=multi_asic_util.multi_asic_namespace_validation_callback) +@click.pass_context +def vrf_network(ctx, ipaddress, info_type, namespace): + """Show IP (IPv4) BGP network""" + vrf = ctx.parent.params['vrf'] + network_helper(ipaddress, info_type, namespace, vrf) + + +def summary_helper(namespace, display, vrf=None): + bgp_summary = bgp_util.get_bgp_summary_from_all_bgp_instances( + constants.IPV4, namespace, display, vrf) + bgp_util.display_bgp_summary(bgp_summary=bgp_summary, af=constants.IPV4) + + +def neighbors_helper(ipaddress, info_type, namespace, vrf=None): + command = 'show ip bgp' + if vrf is not None: + command += ' vrf {}'.format(vrf) + command += ' neighbor' - command = 'show ip bgp neighbor' if ipaddress is not None: if not bgp_util.is_ipv4_address(ipaddress): ctx = click.get_current_context() @@ -89,27 +192,10 @@ def neighbors(ipaddress, info_type, namespace): click.echo(output.rstrip('\n')) -# 'network' subcommand ("show ip bgp network") -@bgp.command() -@click.argument('ipaddress', - metavar='[|]', - required=True if device_info.is_supervisor() else False) -@click.argument('info_type', - metavar='[bestpath|json|longer-prefixes|multipath]', - type=click.Choice( - ['bestpath', 'json', 'longer-prefixes', 'multipath']), - required=False) -@click.option('--namespace', - '-n', - 'namespace', - type=str, - show_default=True, - required=False, - help='Namespace name or all', - default="all", - callback=multi_asic_util.multi_asic_namespace_validation_callback) -def network(ipaddress, info_type, namespace): - """Show IP (IPv4) BGP network""" +def network_helper(ipaddress, info_type, namespace, vrf=None): + command = 'show ip bgp' + if vrf is not None: + command += ' vrf {}'.format(vrf) if device_info.is_supervisor(): # the command will be executed by rexec @@ -125,7 +211,6 @@ def network(ipaddress, info_type, namespace): ctx.fail('invalid namespace {}. provide namespace from list {}' .format(namespace, multi_asic.get_namespace_list())) - command = 'show ip bgp' if ipaddress is not None: if '/' in ipaddress: # For network prefixes then this all info_type(s) are available diff --git a/show/bgp_frr_v6.py b/show/bgp_frr_v6.py index 6efe44bcd9..f64b6f081f 100644 --- a/show/bgp_frr_v6.py +++ b/show/bgp_frr_v6.py @@ -25,8 +25,7 @@ def bgp(): @multi_asic_util.multi_asic_click_options def summary(namespace, display): """Show summarized information of IPv6 BGP state""" - bgp_summary = bgp_util.get_bgp_summary_from_all_bgp_instances(constants.IPV6, namespace,display) - bgp_util.display_bgp_summary(bgp_summary=bgp_summary, af=constants.IPV6) + summary_helper(namespace, display) # 'neighbors' subcommand ("show ipv6 bgp neighbors") @@ -37,15 +36,117 @@ def summary(namespace, display): ['routes', 'advertised-routes', 'received-routes']), required=False) @click.option('--namespace', - '-n', - 'namespace', - default=None, - type=str, - show_default=True, - help='Namespace name or all', - callback=multi_asic_util.multi_asic_namespace_validation_callback) + '-n', + 'namespace', + default=None, + type=str, + show_default=True, + help='Namespace name or all', + callback=multi_asic_util.multi_asic_namespace_validation_callback) def neighbors(ipaddress, info_type, namespace): """Show IPv6 BGP neighbors""" + neighbors_helper(ipaddress, info_type, namespace) + + +# 'network' subcommand ("show ipv6 bgp network") +@bgp.command() +@click.argument('ipaddress', + metavar='[|]', + required=False) +@click.argument('info_type', + metavar='[bestpath|json|longer-prefixes|multipath]', + type=click.Choice( + ['bestpath', 'json', 'longer-prefixes', 'multipath']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + type=str, + show_default=True, + required=True if multi_asic.is_multi_asic is True else False, + help='Namespace name or all', + default=multi_asic.DEFAULT_NAMESPACE, + callback=multi_asic_util.multi_asic_namespace_validation_callback) +def network(ipaddress, info_type, namespace): + """Show BGP ipv6 network""" + network_helper(ipaddress, info_type, namespace) + + +@bgp.group(cls=clicommon.AliasedGroup) +@click.argument('vrf', required=True) +@click.pass_context +def vrf(ctx, vrf): + """Show IPv4 BGP information for a given VRF""" + pass + + +# 'summary' subcommand ("show ipv6 bgp summary") +@vrf.command('summary') +@multi_asic_util.multi_asic_click_options +@click.pass_context +def vrf_summary(ctx, namespace, display): + """Show summarized information of IPv6 BGP state""" + vrf = ctx.parent.params['vrf'] + summary_helper(namespace, display, vrf) + + +# 'neighbors' subcommand ("show ipv6 bgp vrf neighbors") +@vrf.command('neighbors') +@click.argument('ipaddress', required=False) +@click.argument('info_type', + type=click.Choice( + ['routes', 'advertised-routes', 'received-routes']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + default=None, + type=str, + show_default=True, + help='Namespace name or all', + callback=multi_asic_util.multi_asic_namespace_validation_callback) +@click.pass_context +def vrf_neighbors(ctx, ipaddress, info_type, namespace): + """Show IPv6 BGP neighbors""" + vrf = ctx.parent.params['vrf'] + neighbors_helper(ipaddress, info_type, namespace, vrf) + + +# 'network' subcommand ("show ipv6 bgp network") +@vrf.command('network') +@click.argument('ipaddress', + metavar='[|]', + required=False) +@click.argument('info_type', + metavar='[bestpath|json|longer-prefixes|multipath]', + type=click.Choice( + ['bestpath', 'json', 'longer-prefixes', 'multipath']), + required=False) +@click.option('--namespace', + '-n', + 'namespace', + type=str, + show_default=True, + required=True if multi_asic.is_multi_asic is True else False, + help='Namespace name or all', + default=multi_asic.DEFAULT_NAMESPACE, + callback=multi_asic_util.multi_asic_namespace_validation_callback) +@click.pass_context +def vrf_network(ctx, ipaddress, info_type, namespace): + """Show BGP ipv6 network""" + vrf = ctx.parent.params['vrf'] + network_helper(ipaddress, info_type, namespace, vrf) + + +def summary_helper(namespace, display, vrf=None): + bgp_summary = bgp_util.get_bgp_summary_from_all_bgp_instances(constants.IPV6, namespace, display, vrf) + bgp_util.display_bgp_summary(bgp_summary=bgp_summary, af=constants.IPV6) + + +def neighbors_helper(ipaddress, info_type, namespace, vrf=None): + command = 'show bgp' + if vrf is not None: + command += ' vrf {}'.format(vrf) if ipaddress is not None: if not bgp_util.is_ipv6_address(ipaddress): @@ -68,7 +169,7 @@ def neighbors(ipaddress, info_type, namespace): ipaddress = "" info_type = "" if info_type is None else info_type - command = 'show bgp ipv6 neighbor {} {}'.format( + command += ' ipv6 neighbor {} {}'.format( ipaddress, info_type) ns_list = multi_asic.get_namespace_list(namespace) @@ -79,29 +180,11 @@ def neighbors(ipaddress, info_type, namespace): click.echo(output.rstrip('\n')) -# 'network' subcommand ("show ipv6 bgp network") -@bgp.command() -@click.argument('ipaddress', - metavar='[|]', - required=False) -@click.argument('info_type', - metavar='[bestpath|json|longer-prefixes|multipath]', - type=click.Choice( - ['bestpath', 'json', 'longer-prefixes', 'multipath']), - required=False) -@click.option('--namespace', - '-n', - 'namespace', - type=str, - show_default=True, - required=True if multi_asic.is_multi_asic is True else False, - help='Namespace name or all', - default=multi_asic.DEFAULT_NAMESPACE, - callback=multi_asic_util.multi_asic_namespace_validation_callback) -def network(ipaddress, info_type, namespace): - """Show BGP ipv6 network""" - - command = 'show bgp ipv6' +def network_helper(ipaddress, info_type, namespace, vrf=None): + command = 'show bgp' + if vrf is not None: + command += ' vrf {}'.format(vrf) + command += ' ipv6' if multi_asic.is_multi_asic() and namespace not in multi_asic.get_namespace_list(): ctx = click.get_current_context() diff --git a/tests/bgp_commands_input/bgp_neighbor_test_vector.py b/tests/bgp_commands_input/bgp_neighbor_test_vector.py index a5766c2a5c..7e80965682 100644 --- a/tests/bgp_commands_input/bgp_neighbor_test_vector.py +++ b/tests/bgp_commands_input/bgp_neighbor_test_vector.py @@ -74,6 +74,11 @@ Read thread: on Write thread: on FD used: 28 """ +bgp_v4_neighbors_output_invalid_vrf = \ + """ + % No BGP neighbors found + """ + bgp_v4_neighbor_invalid = \ """Error: Bgp neighbor 20.1.1.1 not configured""" @@ -229,6 +234,11 @@ Read thread: on Write thread: on FD used: 30 """ +bgp_v6_neighbors_output_invalid_vrf = \ + """ + % No BGP neighbors found + """ + bgp_v6_neighbor_output_adv_routes = \ """ BGP table version is 6407, local router ID is 10.1.0.32, vrf id 0 @@ -633,6 +643,10 @@ def mock_show_bgp_neighbor_single_asic(request): return bgp_v4_neighbors_output elif request.param == 'bgp_v6_neighbors_output': return bgp_v6_neighbors_output + elif request.param == 'bgp_v4_neighbors_output_invalid_vrf': + return bgp_v4_neighbors_output_invalid_vrf + elif request.param == 'bgp_v6_neighbors_output_invalid_vrf': + return bgp_v6_neighbors_output_invalid_vrf elif request.param == 'bgp_v4_neighbor_output_adv_routes': return bgp_v4_neighbor_output_adv_routes elif request.param == 'bgp_v4_neighbor_output_recv_routes': @@ -647,106 +661,151 @@ def mock_show_bgp_neighbor_single_asic(request): testData = { 'bgp_v4_neighbors': { + 'vrf': 'default', + 'args': [], + 'rc': 0, + 'rc_output': bgp_v4_neighbors_output + }, + 'bgp_v4_neighbors_vrf': { + 'vrf': 'Vnet_90', 'args': [], 'rc': 0, 'rc_output': bgp_v4_neighbors_output }, + 'bgp_v4_neighbors_invalid_vrf': { + 'vrf': 'Vnet_invalid', + 'args': [], + 'rc': 2, + 'rc_output': bgp_v4_neighbors_output_invalid_vrf + }, 'bgp_v4_neighbor_ip_address': { + 'vrf': 'default', 'args': ['10.0.0.57'], 'rc': 0, 'rc_output': bgp_v4_neighbors_output }, 'bgp_v4_neighbor_invalid': { + 'vrf': 'default', 'args': ['20.1.1.1'], 'rc': 2, 'rc_err_msg': bgp_v4_neighbor_invalid }, 'bgp_v4_neighbor_invalid_address': { + 'vrf': 'default', 'args': ['invalid_address'], 'rc': 2, 'rc_err_msg': bgp_v4_neighbor_invalid_address }, 'bgp_v4_neighbor_adv_routes': { + 'vrf': 'default', 'args': ["10.0.0.57", "advertised-routes"], 'rc': 0, 'rc_output': bgp_v4_neighbor_output_adv_routes }, 'bgp_v4_neighbor_recv_routes': { + 'vrf': 'default', 'args': ["10.0.0.57", "received-routes"], 'rc': 0, 'rc_output': bgp_v4_neighbor_output_recv_routes }, 'bgp_v6_neighbors': { + 'vrf': 'default', + 'args': [], + 'rc': 0, + 'rc_output': bgp_v6_neighbors_output + }, + 'bgp_v6_neighbors_vrf': { + 'vrf': 'Vnet_90', 'args': [], 'rc': 0, 'rc_output': bgp_v6_neighbors_output }, + 'bgp_v6_neighbors_invalid_vrf': { + 'vrf': 'Vnet_invalid', + 'args': [], + 'rc': 2, + 'rc_output': bgp_v6_neighbors_output_invalid_vrf + }, 'bgp_v6_neighbor_ip_address': { + 'vrf': 'default', 'args': ['fc00::72'], 'rc': 0, 'rc_output': bgp_v6_neighbors_output }, 'bgp_v6_neighbor_invalid': { + 'vrf': 'default', 'args': ['aa00::72'], 'rc': 2, 'rc_err_msg': bgp_v6_neighbor_invalid }, 'bgp_v6_neighbor_invalid_address': { + 'vrf': 'default', 'args': ['20.1.1.1'], 'rc': 2, 'rc_err_msg': bgp_v6_neighbor_invalid_address }, 'bgp_v6_neighbor_adv_routes': { + 'vrf': 'default', 'args': ["fc00::72", "advertised-routes"], 'rc': 0, 'rc_output': bgp_v6_neighbor_output_adv_routes }, 'bgp_v6_neighbor_recv_routes': { + 'vrf': 'default', 'args': ["fc00::72", "received-routes"], 'rc': 0, 'rc_output': bgp_v6_neighbor_output_recv_routes }, 'bgp_v4_neighbors_multi_asic' : { + 'vrf': 'default', 'args': [], 'rc': 0, 'rc_output': bgp_v4_neighbors_output_all_asics }, 'bgp_v4_neighbors_asic' : { + 'vrf': 'default', 'args': ['-nasic1'], 'rc': 0, 'rc_output': bgp_v4_neighbors_output_asic1 }, 'bgp_v4_neighbors_external' : { + 'vrf': 'default', 'args': ['10.0.0.1'], 'rc': 0, 'rc_output': bgp_v4_neighbors_output_asic0 }, 'bgp_v4_neighbors_internal' : { + 'vrf': 'default', 'args': ['10.1.0.1'], 'rc': 0, 'rc_output': bgp_v4_neighbors_output_asic1 }, 'bgp_v6_neighbors_multi_asic' : { + 'vrf': 'default', 'args': [], 'rc': 0, 'rc_output': bgp_v6_neighbors_output_all_asics }, 'bgp_v6_neighbors_asic' : { + 'vrf': 'default', 'args': ['-nasic0'], 'rc': 0, 'rc_output': bgp_v6_neighbors_output_asic0 }, 'bgp_v6_neighbors_external' : { + 'vrf': 'default', 'args': ['fc00::2'], 'rc': 0, 'rc_output': bgp_v6_neighbors_output_asic0 }, 'bgp_v6_neighbors_internal' : { + 'vrf': 'default', 'args': ['2603:10e2:400:1::2'], 'rc': 0, 'rc_output': bgp_v6_neighbors_output_asic1 }, 'bgp_v6_neighbor_warning' : { + 'vrf': 'default', 'args': ['2603:10e2:400:1::2', '-nasic0'], 'rc': 0, 'rc_warning_msg': bgp_v6_neighbor_output_warning diff --git a/tests/bgp_commands_input/bgp_network_test_vector.py b/tests/bgp_commands_input/bgp_network_test_vector.py index f9edd66fa2..e9917aadef 100644 --- a/tests/bgp_commands_input/bgp_network_test_vector.py +++ b/tests/bgp_commands_input/bgp_network_test_vector.py @@ -50,6 +50,26 @@ *> 10.0.0.57 0 64600 65504 i """ +bgp_v4_network_vrf = \ + """ + BGP table version is 6327, local router ID is 10.1.0.32, vrf id 81 + Default local pref 100, local AS 65100 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *= 10.1.0.32/32 10.0.0.62 0 0 65100 i + *= 100.1.0.32/32 0.0.0.0 0 32768 i + *= 192.168.0.0/21 10.0.0.62 0 0 65100 i + """ + +bgp_v4_network_invalid_vrf = \ + """ + View/Vrf Vnet_invalid is unknown + """ + bgp_v4_network_ip_address = \ """ BGP routing table entry for 193.11.248.128/25 @@ -153,6 +173,26 @@ *> fc00::72 0 64600 65504 i """ +bgp_v6_network_vrf = \ + """ + BGP table version is 6407, local router ID is 10.1.0.32, vrf id 81 + Default local pref 100, local AS 65100 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 2064:100::1d/128 fc00::72 0 64600 i + *= 20c0:a810::/64 fc00::7e 0 64600 65502 i + *= 20c0:a820::/64 fc00::7e 0 64600 65504 i + """ + +bgp_v6_network_invalid_vrf = \ + """ + View/Vrf Vnet_invalid is unknown + """ + bgp_v6_network_ip_address = \ """ BGP routing table entry for 20c0:a820:0:80::/64 @@ -508,12 +548,20 @@ def mock_show_bgp_network_single_asic(request): param = request.param if param == 'bgp_v4_network': return bgp_v4_network + elif param == 'bgp_v4_network_vrf': + return bgp_v4_network_vrf + elif param == 'bgp_v4_network_invalid_vrf': + return bgp_v4_network_invalid_vrf elif param == 'bgp_v4_network_ip_address': return bgp_v4_network_ip_address elif param == 'bgp_v4_network_bestpath': return bgp_v4_network_bestpath elif param == 'bgp_v6_network': return bgp_v6_network + elif param == 'bgp_v6_network_vrf': + return bgp_v6_network_vrf + elif param == 'bgp_v6_network_invalid_vrf': + return bgp_v6_network_invalid_vrf elif param == 'bgp_v6_network_ip_address': return bgp_v6_network_ip_address elif param == 'bgp_v6_network_longer_prefixes': @@ -546,101 +594,145 @@ def mock_show_bgp_network_multi_asic(param): testData = { 'bgp_v4_network': { + 'vrf': 'default', 'args': [], 'rc': 0, 'rc_output': bgp_v4_network }, + 'bgp_v4_network_vrf': { + 'vrf': 'Vnet_90', + 'args': [], + 'rc': 0, + 'rc_output': bgp_v4_network_vrf + }, + 'bgp_v4_network_invalid_vrf': { + 'vrf': 'Vnet_invalid', + 'args': [], + 'rc': 2, + 'rc_err_msg': bgp_v4_network_invalid_vrf + }, 'bgp_v4_network_ip_address': { + 'vrf': 'default', 'args': [' 193.11.248.128/25'], 'rc': 0, 'rc_output': bgp_v4_network_ip_address }, 'bgp_v4_network_bestpath': { + 'vrf': 'default', 'args': [' 193.11.248.128/25', 'bestpath'], 'rc': 0, 'rc_output': bgp_v4_network_bestpath }, 'bgp_v4_network_longer_prefixes_error': { + 'vrf': 'default', 'args': [' 193.11.248.128', 'longer-prefixes'], 'rc': 1, 'rc_output': bgp_v4_network_longer_prefixes_error }, 'bgp_v4_network_all_asic_on_single_asic': { + 'vrf': 'default', 'args': ['-nall'], 'rc': 0, 'rc_output': bgp_v4_network }, 'bgp_v6_network': { + 'vrf': 'default', 'args': [], 'rc': 0, 'rc_output': bgp_v6_network }, + 'bgp_v6_network_vrf': { + 'vrf': 'Vnet_90', + 'args': [], + 'rc': 0, + 'rc_output': bgp_v6_network_vrf + }, + 'bgp_v6_network_invalid_vrf': { + 'vrf': 'Vnet_invalid', + 'args': [], + 'rc': 2, + 'rc_err_msg': bgp_v6_network_invalid_vrf + }, 'bgp_v6_network_ip_address': { + 'vrf': 'default', 'args': [' 20c0:a820:0:80::/64'], 'rc': 0, 'rc_output': bgp_v6_network_ip_address }, 'bgp_v6_network_bestpath': { + 'vrf': 'default', 'args': [' 20c0:a820:0:80::/64', 'bestpath'], 'rc': 0, 'rc_output': bgp_v6_network_bestpath }, 'bgp_v6_network_longer_prefixes_error': { + 'vrf': 'default', 'args': [' 20c0:a820:0:80::', 'longer-prefixes'], 'rc': 1, 'rc_output': bgp_v6_network_longer_prefixes_error }, 'bgp_v6_network_longer_prefixes': { + 'vrf': 'default', 'args': [' 20c0:a820:0:80::/64', 'longer-prefixes'], 'rc': 0, 'rc_output': bgp_v6_network_longer_prefixes }, 'bgp_v4_network_default_multi_asic': { + 'vrf': 'default', 'args': [], 'rc': 0, 'rc_output': bgp_v4_network_all_asic }, 'bgp_v4_network_asic0': { + 'vrf': 'default', 'args': ['-nasic0'], 'rc': 0, 'rc_output': bgp_v4_network_asic0 }, 'bgp_v4_network_ip_address_asic0': { + 'vrf': 'default', 'args': ['-nasic0', '10.0.0.44'], 'rc': 0, 'rc_output': bgp_v4_network_ip_address_asic0 }, 'bgp_v4_network_bestpath_asic0': { + 'vrf': 'default', 'args': ['-nasic0', '10.0.0.44', 'bestpath'], 'rc': 0, 'rc_output': bgp_v4_network_bestpath_asic0 }, 'bgp_v4_network_all_asic': { + 'vrf': 'default', 'args': ['-nall'], 'rc': 0, 'rc_output': bgp_v4_network_all_asic }, 'bgp_v4_network_asic_unknown': { + 'vrf': 'default', 'args': ['-nasic_unknown'], 'rc': 2, 'rc_err_msg': multi_asic_bgp_network_asic_unknown_err }, 'bgp_v6_network_multi_asic': { + 'vrf': 'default', 'args': [], 'rc': 2, 'rc_err_msg': multi_asic_bgp_network_err }, 'bgp_v6_network_asic0': { + 'vrf': 'default', 'args': ['-nasic0'], 'rc': 0, 'rc_output': bgp_v4_network_asic0 }, 'bgp_v6_network_ip_address_asic0': { + 'vrf': 'default', 'args': ['-nasic0', '20c0:a808:0:80::/64'], 'rc': 0, 'rc_output': bgp_v6_network_ip_address_asic0 }, 'bgp_v6_network_bestpath_asic0': { + 'vrf': 'default', 'args': ['-nasic0', '20c0:a808:0:80::/64', 'bestpath'], 'rc': 0, 'rc_output': bgp_v6_network_ip_address_asic0_bestpath diff --git a/tests/bgp_commands_test.py b/tests/bgp_commands_test.py index 3b10539687..6715da1693 100644 --- a/tests/bgp_commands_test.py +++ b/tests/bgp_commands_test.py @@ -26,6 +26,46 @@ Peer groups 4, using 256 bytes of memory +Neighbhor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName +----------- --- ----- --------- --------- -------- ----- ------ --------- -------------- -------------- +10.0.0.1 4 65200 5919 2717 0 0 0 1d21h11m 6402 ARISTA01T2 +10.0.0.5 4 65200 5916 2714 0 0 0 1d21h10m 6402 ARISTA03T2 +10.0.0.9 4 65200 5915 2713 0 0 0 1d21h09m 6402 ARISTA05T2 +10.0.0.13 4 65200 5917 2716 0 0 0 1d21h11m 6402 ARISTA07T2 +10.0.0.17 4 65200 5916 2713 0 0 0 1d21h09m 6402 ARISTA09T2 +10.0.0.21 4 65200 5917 2716 0 0 0 1d21h11m 6402 ARISTA11T2 +10.0.0.25 4 65200 5917 2716 0 0 0 1d21h11m 6402 ARISTA13T2 +10.0.0.29 4 65200 5916 2714 0 0 0 1d21h10m 6402 ARISTA15T2 +10.0.0.33 4 64001 0 0 0 0 0 never Active ARISTA01T0 +10.0.0.35 4 64002 0 0 0 0 0 never Active ARISTA02T0 +10.0.0.37 4 64003 0 0 0 0 0 never Active ARISTA03T0 +10.0.0.39 4 64004 0 0 0 0 0 never Active ARISTA04T0 +10.0.0.41 4 64005 0 0 0 0 0 never Active ARISTA05T0 +10.0.0.43 4 64006 0 0 0 0 0 never Active ARISTA06T0 +10.0.0.45 4 64007 0 0 0 0 0 never Active ARISTA07T0 +10.0.0.47 4 64008 0 0 0 0 0 never Active ARISTA08T0 +10.0.0.49 4 64009 0 0 0 0 0 never Active ARISTA09T0 +10.0.0.51 4 64010 0 0 0 0 0 never Active ARISTA10T0 +10.0.0.53 4 64011 0 0 0 0 0 never Active ARISTA11T0 +10.0.0.55 4 64012 0 0 0 0 0 never Active ARISTA12T0 +10.0.0.57 4 64013 0 0 0 0 0 never Active ARISTA13T0 +10.0.0.59 4 64014 0 0 0 0 0 never Active ARISTA14T0 +10.0.0.61 4 64015 0 0 0 0 0 never Active INT_NEIGH0 +10.0.0.63 4 64016 0 0 0 0 0 never Active INT_NEIGH1 + +Total number of neighbors 24 +""" + +show_bgp_summary_v4_vrf = """\ + +IPv4 Unicast Summary: +BGP router identifier 10.1.0.32, local AS number 65100 vrf-id 81 +BGP table version 43 +RIB entries 12817, using 2358328 bytes of memory +Peers 24, using 502080 KiB of memory +Peer groups 4, using 256 bytes of memory + + Neighbhor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName ----------- --- ----- --------- --------- -------- ----- ------ --------- -------------- -------------- 10.0.0.1 4 65200 5919 2717 0 0 0 1d21h11m 6402 ARISTA01T2 @@ -66,6 +106,46 @@ Peer groups 4, using 256 bytes of memory +Neighbhor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName +----------- --- ----- --------- --------- -------- ----- ------ --------- -------------- -------------- +fc00::1a 4 65200 6665 6672 0 0 0 2d09h39m 6402 ARISTA07T2 +fc00::2 4 65200 6666 7913 0 0 0 2d09h39m 6402 ARISTA01T2 +fc00::2a 4 65200 6666 7913 0 0 0 2d09h39m 6402 ARISTA11T2 +fc00::3a 4 65200 6666 7912 0 0 0 2d09h39m 6402 ARISTA15T2 +fc00::4a 4 64003 0 0 0 0 0 never Active ARISTA03T0 +fc00::4e 4 64004 0 0 0 0 0 never Active ARISTA04T0 +fc00::5a 4 64007 0 0 0 0 0 never Active ARISTA07T0 +fc00::5e 4 64008 0 0 0 0 0 never Active ARISTA08T0 +fc00::6a 4 64011 0 0 0 0 0 never Connect ARISTA11T0 +fc00::6e 4 64012 0 0 0 0 0 never Active ARISTA12T0 +fc00::7a 4 64015 0 0 0 0 0 never Active ARISTA15T0 +fc00::7e 4 64016 0 0 0 0 0 never Active ARISTA16T0 +fc00::12 4 65200 6666 7915 0 0 0 2d09h39m 6402 ARISTA05T2 +fc00::22 4 65200 6667 7915 0 0 0 2d09h39m 6402 ARISTA09T2 +fc00::32 4 65200 6663 6669 0 0 0 2d09h36m 6402 ARISTA13T2 +fc00::42 4 64001 0 0 0 0 0 never Active ARISTA01T0 +fc00::46 4 64002 0 0 0 0 0 never Active ARISTA02T0 +fc00::52 4 64005 0 0 0 0 0 never Active ARISTA05T0 +fc00::56 4 64006 0 0 0 0 0 never Active ARISTA06T0 +fc00::62 4 64009 0 0 0 0 0 never Active ARISTA09T0 +fc00::66 4 64010 0 0 0 0 0 never Active ARISTA10T0 +fc00::72 4 64013 0 0 0 0 0 never Active ARISTA13T0 +fc00::76 4 64014 0 0 0 0 0 never Active INT_NEIGH0 +fc00::a 4 65200 6665 6671 0 0 0 2d09h38m 6402 INT_NEIGH1 + +Total number of neighbors 24 +""" + +show_bgp_summary_v6_vrf = """\ + +IPv6 Unicast Summary: +BGP router identifier 10.1.0.32, local AS number 65100 vrf-id 81 +BGP table version 43 +RIB entries 12817, using 2358328 bytes of memory +Peers 24, using 502080 KiB of memory +Peer groups 4, using 256 bytes of memory + + Neighbhor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName ----------- --- ----- --------- --------- -------- ----- ------ --------- -------------- -------------- fc00::1a 4 65200 6665 6672 0 0 0 2d09h39m 6402 ARISTA07T2 @@ -103,6 +183,13 @@ Error: bgp summary from bgp container not in json format """ +show_vrf_error_invalid_json = """\ +Usage: vrf summary [OPTIONS] +Try "vrf summary --help" for help. + +Error: bgp summary from bgp container not in json format +""" + show_error_no_v6_neighbor_single_asic = """\ IPv6 Unicast Summary: @@ -363,6 +450,34 @@ def test_bgp_summary_v4( assert result.exit_code == 0 assert result.output == show_bgp_summary_v4 + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v4'], indirect=['setup_single_bgp_instance']) + def test_bgp_default_vrf_summary_v4( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v4 + + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v4_vrf'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_v4( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['Vnet_90', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v4_vrf + @pytest.mark.parametrize('setup_single_bgp_instance', ['v6'], indirect=['setup_single_bgp_instance']) def test_bgp_summary_v6( @@ -377,6 +492,34 @@ def test_bgp_summary_v6( assert result.exit_code == 0 assert result.output == show_bgp_summary_v6 + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v6'], indirect=['setup_single_bgp_instance']) + def test_bgp_default_vrf_summary_v6( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v6 + + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v6_vrf'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_v6( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['Vnet_90', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v6_vrf + @pytest.mark.parametrize('setup_single_bgp_instance', [' '], indirect=['setup_single_bgp_instance']) def test_bgp_summary_error( @@ -391,6 +534,20 @@ def test_bgp_summary_error( assert result.exit_code == 2 assert result.output == show_error_invalid_json + @pytest.mark.parametrize('setup_single_bgp_instance', + [' '], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_error( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 2 + assert result.output == show_vrf_error_invalid_json + def display_external(self): return constants.DISPLAY_EXTERNAL @@ -416,6 +573,25 @@ def test_bgp_summary_v4_chassis( assert result.exit_code == 0 assert result.output == show_bgp_summary_v4_chassis + @pytest.mark.parametrize( + 'setup_single_bgp_instance_chassis', ['v4'], + indirect=['setup_single_bgp_instance_chassis'] + ) + @patch.object(multi_asic.MultiAsic, 'get_display_option', display_external) + @patch('sonic_py_common.device_info.get_platform_info') + def test_bgp_vrf_summary_v4_chassis( + self, mock_is_chassis, setup_bgp_commands, + setup_single_bgp_instance_chassis + ): + mock_is_chassis.return_value = {'switch_type': 'voq'} + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v4_chassis + @pytest.mark.parametrize( 'setup_single_bgp_instance_chassis', ['v6'], indirect=['setup_single_bgp_instance_chassis'] @@ -435,6 +611,25 @@ def test_bgp_summary_v6_chassis( assert result.exit_code == 0 assert result.output == show_bgp_summary_v6_chassis + @pytest.mark.parametrize( + 'setup_single_bgp_instance_chassis', ['v6'], + indirect=['setup_single_bgp_instance_chassis'] + ) + @patch.object(multi_asic.MultiAsic, 'get_display_option', display_external) + @patch('sonic_py_common.device_info.get_platform_info') + def test_bgp_vrf_summary_v6_chassis( + self, mock_is_chassis, setup_bgp_commands, + setup_single_bgp_instance_chassis + ): + mock_is_chassis.return_value = {'switch_type': 'voq'} + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v6_chassis + @pytest.mark.parametrize( 'setup_single_bgp_instance_chassis', ['v4'], indirect=['setup_single_bgp_instance_chassis'] @@ -454,6 +649,25 @@ def test_bgp_summary_v4_all_chassis( assert result.exit_code == 0 assert result.output == show_bgp_summary_v4_all_chassis + @pytest.mark.parametrize( + 'setup_single_bgp_instance_chassis', ['v4'], + indirect=['setup_single_bgp_instance_chassis'] + ) + @patch.object(multi_asic.MultiAsic, 'get_display_option', display_all) + @patch('sonic_py_common.device_info.get_platform_info') + def test_bgp_vrf_summary_v4_all_chassis( + self, mock_is_chassis, setup_bgp_commands, + setup_single_bgp_instance_chassis + ): + mock_is_chassis.return_value = {'switch_type': 'voq'} + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_bgp_summary_v4_all_chassis + @pytest.mark.parametrize('setup_single_bgp_instance', ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance']) def test_bgp_summary_no_v4_neigh( @@ -468,6 +682,20 @@ def test_bgp_summary_no_v4_neigh( assert result.exit_code == 0 assert result.output == show_error_no_v4_neighbor_single_asic + @pytest.mark.parametrize('setup_single_bgp_instance', + ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_no_v4_neigh( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_error_no_v4_neighbor_single_asic + @pytest.mark.parametrize('setup_single_bgp_instance', ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance']) def test_bgp_summary_no_v6_neigh( @@ -482,6 +710,20 @@ def test_bgp_summary_no_v6_neigh( assert result.exit_code == 0 assert result.output == show_error_no_v6_neighbor_single_asic + @pytest.mark.parametrize('setup_single_bgp_instance', + ['show_bgp_summary_no_neigh'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_no_v6_neigh( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_error_no_v6_neighbor_single_asic + @pytest.mark.parametrize('setup_single_bgp_instance', ['v4'], indirect=['setup_single_bgp_instance']) def test_bgp_summary_raw_missing_peergroup_count( @@ -534,6 +776,58 @@ def test_bgp_summary_raw_missing_peergroup_count( assert result.exit_code == 0 assert "Peer groups 0, using 0 bytes of memory" in result.output + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v4'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_raw_missing_peergroup_count( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + # mock vtysh cli output that does not have peergroup count + mock_json = { + "ipv4Unicast": { + "routerId": "10.1.0.32", + "as": 65100, + "localAS": 65100, + "vrfId": 0, + "tableVersion": 1, + "totalPeers": 0, + "dynamicPeers": 0, + "bestPaths": 0, + "peerCount": 2, + "peerMemory": 2048, + "ribCount": 10, + "ribMemory": 1024, + "peers": { + "10.0.0.33": { + "remoteAs": 64001, + "version": 4, + "msgRcvd": 0, + "msgSent": 0, + "tableVersion": 0, + "outq": 0, + "inq": 0, + "peerUptime": "never", + "peerUptimeMsec": 0, + "prefixReceivedCount": 0, + "pfxRcd": 0, + "state": "Active", + "connectionsEstablished": 0, + "connectionsDropped": 0, + "idType": "ipv4" + } + } + } + } + + with patch('utilities_common.bgp_util.run_bgp_command', return_value=json.dumps(mock_json)): + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + # verify that the CLI handles missing peergroup count gracefully + assert result.exit_code == 0 + assert "Peer groups 0, using 0 bytes of memory" in result.output + @pytest.mark.parametrize('setup_single_bgp_instance', ['v6'], indirect=['setup_single_bgp_instance']) def test_bgp_summary_raw_missing_peergroup_count_v6( @@ -586,6 +880,58 @@ def test_bgp_summary_raw_missing_peergroup_count_v6( assert result.exit_code == 0 assert "Peer groups 0, using 0 bytes of memory" in result.output + @pytest.mark.parametrize('setup_single_bgp_instance', + ['v6'], indirect=['setup_single_bgp_instance']) + def test_bgp_vrf_summary_raw_missing_peergroup_count_v6( + self, + setup_bgp_commands, + setup_single_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + # mock vtysh cli output that does not have peergroup count + mock_json = { + "ipv6Unicast": { + "routerId": "10.1.0.32", + "as": 65100, + "localAS": 65100, + "vrfId": 0, + "tableVersion": 1, + "totalPeers": 0, + "dynamicPeers": 0, + "bestPaths": 0, + "peerCount": 2, + "peerMemory": 2048, + "ribCount": 10, + "ribMemory": 1024, + "peers": { + "fc00::42": { + "remoteAs": 64001, + "version": 4, + "msgRcvd": 0, + "msgSent": 0, + "tableVersion": 0, + "outq": 0, + "inq": 0, + "peerUptime": "never", + "peerUptimeMsec": 0, + "prefixReceivedCount": 0, + "pfxRcd": 0, + "state": "Active", + "connectionsEstablished": 0, + "connectionsDropped": 0, + "idType": "ipv6" + } + } + } + } + + with patch('utilities_common.bgp_util.run_bgp_command', return_value=json.dumps(mock_json)): + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + # verify that the CLI handles missing peergroup count gracefully + assert result.exit_code == 0 + assert "Peer groups 0, using 0 bytes of memory" in result.output + @classmethod def teardown_class(cls): print("TEARDOWN") @@ -622,6 +968,20 @@ def test_bgp_summary_multi_asic_no_v4_neigh( assert result.exit_code == 0 assert result.output == show_error_no_v4_neighbor_multi_asic + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', + ['show_bgp_summary_no_neigh'], indirect=['setup_multi_asic_bgp_instance']) + def test_bgp_vrf_summary_multi_asic_no_v4_neigh( + self, + setup_bgp_commands, + setup_multi_asic_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_error_no_v4_neighbor_multi_asic + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', ['show_bgp_summary_no_neigh'], indirect=['setup_multi_asic_bgp_instance']) @@ -637,6 +997,21 @@ def test_bgp_summary_multi_asic_no_v6_neigh( assert result.exit_code == 0 assert result.output == show_error_no_v6_neighbor_multi_asic + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', + ['show_bgp_summary_no_neigh'], indirect=['setup_multi_asic_bgp_instance']) + def test_bgp_vrf_summary_multi_asic_no_v6_neigh( + self, + setup_bgp_commands, + setup_multi_asic_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ipv6"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == show_error_no_v6_neighbor_multi_asic + + @patch.object(bgp_util, 'get_external_bgp_neighbors_dict', mock.MagicMock(return_value={})) @patch.object(multi_asic.MultiAsic, 'get_ns_list_based_on_options', mock.Mock(return_value=['asic0', 'asic1'])) @patch.object(multi_asic.MultiAsic, 'get_display_option', mock.MagicMock(return_value=constants.DISPLAY_EXTERNAL)) @@ -654,7 +1029,26 @@ def test_bgp_summary_multi_asic_no_external_neighbors_on_all_asic( show.cli.commands["ip"].commands["bgp"].commands["summary"], []) print("{}".format(result.output)) assert result.exit_code == 0 - assert result.output == SHOW_BGP_SUMMARY_V4_NO_EXT_NEIGHBORS_ON_ALL_ASIC + assert result.output == SHOW_BGP_SUMMARY_V4_NO_EXT_NEIGHBORS_ON_ALL_ASIC + + @patch.object(bgp_util, 'get_external_bgp_neighbors_dict', mock.MagicMock(return_value={})) + @patch.object(multi_asic.MultiAsic, 'get_ns_list_based_on_options', mock.Mock(return_value=['asic0', 'asic1'])) + @patch.object(multi_asic.MultiAsic, 'get_display_option', mock.MagicMock(return_value=constants.DISPLAY_EXTERNAL)) + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', + ['show_bgp_summary_no_ext_neigh_on_all_asic'], + indirect=['setup_multi_asic_bgp_instance']) + @patch.object(device_info, 'is_chassis', mock.MagicMock(return_value=True)) + def test_bgp_vrf_summary_multi_asic_no_external_neighbors_on_all_asic( + self, + setup_bgp_commands, + setup_multi_asic_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == SHOW_BGP_SUMMARY_V4_NO_EXT_NEIGHBORS_ON_ALL_ASIC @patch.object(multi_asic.MultiAsic, 'get_ns_list_based_on_options', mock.Mock(return_value=['asic0', 'asic1'])) @@ -674,8 +1068,26 @@ def test_bgp_summary_multi_asic_no_external_neighbor_on_asic1( print("{}".format(result.output)) assert result.exit_code == 0 assert result.output == SHOW_BGP_SUMMARY_V4_NO_EXT_NEIGHBORS_ON_ASIC1 - + @patch.object(multi_asic.MultiAsic, 'get_ns_list_based_on_options', mock.Mock(return_value=['asic0', 'asic1'])) + @patch.object(multi_asic.MultiAsic, 'get_display_option', mock.MagicMock(return_value=constants.DISPLAY_EXTERNAL)) + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', + ['show_bgp_summary_no_ext_neigh_on_asic1'], + indirect=['setup_multi_asic_bgp_instance']) + @patch.object(device_info, 'is_chassis', mock.MagicMock(return_value=True)) + def test_bgp_vrf_summary_multi_asic_no_external_neighbor_on_asic1( + self, + setup_bgp_commands, + setup_multi_asic_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ['default', 'summary']) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == SHOW_BGP_SUMMARY_V4_NO_EXT_NEIGHBORS_ON_ASIC1 + + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', ['show_bgp_summary_no_ext_neigh_on_all_asic'], indirect=['setup_multi_asic_bgp_instance']) def test_bgp_summary_multi_asic_display_with_no_external_neighbor( @@ -689,7 +1101,22 @@ def test_bgp_summary_multi_asic_display_with_no_external_neighbor( print("{}".format(result.output)) assert result.exit_code == 0 assert result.output == SHOW_BGP_SUMMARY_ALL_V4_NO_EXT_NEIGHBORS - + + @pytest.mark.parametrize('setup_multi_asic_bgp_instance', + ['show_bgp_summary_no_ext_neigh_on_all_asic'], indirect=['setup_multi_asic_bgp_instance']) + def test_bgp_vrf_summary_multi_asic_display_with_no_external_neighbor( + self, + setup_bgp_commands, + setup_multi_asic_bgp_instance): + show = setup_bgp_commands + runner = CliRunner() + result = runner.invoke( + show.cli.commands["ip"].commands["bgp"].commands["vrf"], ["default", "summary", "-dall"]) + print("{}".format(result.output)) + assert result.exit_code == 0 + assert result.output == SHOW_BGP_SUMMARY_ALL_V4_NO_EXT_NEIGHBORS + + def teardown_class(cls): print("TEARDOWN") from .mock_tables import mock_single_asic diff --git a/tests/conftest.py b/tests/conftest.py index 3874668a67..a859b81c51 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -174,9 +174,15 @@ def setup_single_bgp_instance(request): if request.param == 'v4': bgp_mocked_json = os.path.join( test_path, 'mock_tables', 'ipv4_bgp_summary.json') + elif request.param == 'v4_vrf': + bgp_mocked_json = os.path.join( + test_path, 'mock_tables', 'ipv4_bgp_summary_vrf.json') elif request.param == 'v6': bgp_mocked_json = os.path.join( test_path, 'mock_tables', 'ipv6_bgp_summary.json') + elif request.param == 'v6_vrf': + bgp_mocked_json = os.path.join( + test_path, 'mock_tables', 'ipv6_bgp_summary_vrf.json') elif request.param == 'show_bgp_summary_no_neigh': bgp_neigh_mocked_json = os.path.join( test_path, 'mock_tables', 'no_bgp_neigh.json') @@ -364,7 +370,7 @@ def mock_run_show_sum_bgp_command( def mock_run_show_summ_bgp_command_no_ext_neigh_on_all_asic( vtysh_cmd, bgp_namespace, vtysh_shell_cmd=constants.VTYSH_COMMAND, exit_on_fail=True): - if vtysh_cmd == "show ip bgp summary json": + if vtysh_cmd == "show ip bgp summary json" or vtysh_cmd == "show ip bgp vrf default summary json": m_asic_json_file = 'no_ext_bgp_neigh.json' else: m_asic_json_file = 'device_bgp_info.json' @@ -380,7 +386,7 @@ def mock_run_show_summ_bgp_command_no_ext_neigh_on_all_asic( def mock_run_show_summ_bgp_command_no_ext_neigh_on_asic1( vtysh_cmd, bgp_namespace, vtysh_shell_cmd=constants.VTYSH_COMMAND, exit_on_fail=True): - if vtysh_cmd == "show ip bgp summary json": + if vtysh_cmd == "show ip bgp summary json" or vtysh_cmd == "show ip bgp vrf default summary json": if bgp_namespace == "asic1": m_asic_json_file = 'no_ext_bgp_neigh.json' else: diff --git a/tests/mock_tables/ipv4_bgp_summary_vrf.json b/tests/mock_tables/ipv4_bgp_summary_vrf.json new file mode 100644 index 0000000000..39ddfadecc --- /dev/null +++ b/tests/mock_tables/ipv4_bgp_summary_vrf.json @@ -0,0 +1,448 @@ +{ + "ipv4Unicast":{ + "routerId":"10.1.0.32", + "as":65100, + "vrfId":81, + "vrfName":"Vnet_90", + "tableVersion":43, + "ribCount":12817, + "ribMemory":2358328, + "peerCount":24, + "peerMemory":502080, + "peerGroupCount":4, + "peerGroupMemory":256, + "peers":{ + "10.0.0.33":{ + "remoteAs":64001, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.35":{ + "remoteAs":64002, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.37":{ + "remoteAs":64003, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.39":{ + "remoteAs":64004, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.41":{ + "remoteAs":64005, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.43":{ + "remoteAs":64006, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.45":{ + "remoteAs":64007, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.47":{ + "remoteAs":64008, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.49":{ + "remoteAs":64009, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.51":{ + "remoteAs":64010, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.53":{ + "remoteAs":64011, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.55":{ + "remoteAs":64012, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.57":{ + "remoteAs":64013, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.59":{ + "remoteAs":64014, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.61":{ + "remoteAs":64015, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.63":{ + "remoteAs":64016, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.1":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5919, + "msgSent":2717, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h11m", + "peerUptimeMsec":162683000, + "peerUptimeEstablishedEpoch":1597732920, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.5":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5916, + "msgSent":2714, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h10m", + "peerUptimeMsec":162638000, + "peerUptimeEstablishedEpoch":1597732965, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.9":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5915, + "msgSent":2713, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h09m", + "peerUptimeMsec":162580000, + "peerUptimeEstablishedEpoch":1597733023, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.13":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5917, + "msgSent":2716, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h11m", + "peerUptimeMsec":162683000, + "peerUptimeEstablishedEpoch":1597732920, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.17":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5916, + "msgSent":2713, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h09m", + "peerUptimeMsec":162594000, + "peerUptimeEstablishedEpoch":1597733009, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.21":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5917, + "msgSent":2716, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h11m", + "peerUptimeMsec":162682000, + "peerUptimeEstablishedEpoch":1597732921, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.25":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5917, + "msgSent":2716, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h11m", + "peerUptimeMsec":162682000, + "peerUptimeEstablishedEpoch":1597732921, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "10.0.0.29":{ + "remoteAs":65200, + "version":4, + "msgRcvd":5916, + "msgSent":2714, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"1d21h10m", + "peerUptimeMsec":162658000, + "peerUptimeEstablishedEpoch":1597732945, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":1, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + } + }, + "failedPeers":16, + "totalPeers":24, + "dynamicPeers":0, + "bestPath":{ + "multiPathRelax":"true" + } + } +} + \ No newline at end of file diff --git a/tests/mock_tables/ipv6_bgp_summary_vrf.json b/tests/mock_tables/ipv6_bgp_summary_vrf.json new file mode 100644 index 0000000000..38f90ce500 --- /dev/null +++ b/tests/mock_tables/ipv6_bgp_summary_vrf.json @@ -0,0 +1,447 @@ +{ + "ipv6Unicast":{ + "routerId":"10.1.0.32", + "as":65100, + "vrfId":81, + "vrfName":"Vnet_90", + "tableVersion":43, + "ribCount":12817, + "ribMemory":2358328, + "peerCount":24, + "peerMemory":502080, + "peerGroupCount":4, + "peerGroupMemory":256, + "peers":{ + "fc00::42":{ + "remoteAs":64001, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::46":{ + "remoteAs":64002, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::4a":{ + "remoteAs":64003, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::4e":{ + "remoteAs":64004, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::52":{ + "remoteAs":64005, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::56":{ + "remoteAs":64006, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::5a":{ + "remoteAs":64007, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::5e":{ + "remoteAs":64008, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::62":{ + "remoteAs":64009, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::66":{ + "remoteAs":64010, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::6a":{ + "remoteAs":64011, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Connect", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::6e":{ + "remoteAs":64012, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::72":{ + "remoteAs":64013, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::76":{ + "remoteAs":64014, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::7a":{ + "remoteAs":64015, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::7e":{ + "remoteAs":64016, + "version":4, + "msgRcvd":0, + "msgSent":0, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"never", + "peerUptimeMsec":0, + "prefixReceivedCount":0, + "pfxRcd":0, + "state":"Active", + "connectionsEstablished":0, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::2":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6666, + "msgSent":7913, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207559000, + "peerUptimeEstablishedEpoch":1597732922, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::a":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6665, + "msgSent":6671, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h38m", + "peerUptimeMsec":207508000, + "peerUptimeEstablishedEpoch":1597732973, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::12":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6666, + "msgSent":7915, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207559000, + "peerUptimeEstablishedEpoch":1597732922, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::1a":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6665, + "msgSent":6672, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207543000, + "peerUptimeEstablishedEpoch":1597732938, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::22":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6667, + "msgSent":7915, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207560000, + "peerUptimeEstablishedEpoch":1597732921, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::2a":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6666, + "msgSent":7913, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207559000, + "peerUptimeEstablishedEpoch":1597732922, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::32":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6663, + "msgSent":6669, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h36m", + "peerUptimeMsec":207403000, + "peerUptimeEstablishedEpoch":1597733078, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + }, + "fc00::3a":{ + "remoteAs":65200, + "version":4, + "msgRcvd":6666, + "msgSent":7912, + "tableVersion":0, + "outq":0, + "inq":0, + "peerUptime":"2d09h39m", + "peerUptimeMsec":207559000, + "peerUptimeEstablishedEpoch":1597732922, + "prefixReceivedCount":6402, + "pfxRcd":6402, + "pfxSnt":6410, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv6" + } + }, + "failedPeers":16, + "totalPeers":24, + "dynamicPeers":0, + "bestPath":{ + "multiPathRelax":"true" + } + } +} diff --git a/tests/show_bgp_neighbor_test.py b/tests/show_bgp_neighbor_test.py index de84223060..2bc66db881 100644 --- a/tests/show_bgp_neighbor_test.py +++ b/tests/show_bgp_neighbor_test.py @@ -4,19 +4,34 @@ import pytest from click.testing import CliRunner -from .bgp_commands_input.bgp_neighbor_test_vector import * +from .bgp_commands_input import bgp_neighbor_test_vector def executor(test_vector, show): runner = CliRunner() - input = testData[test_vector] + input = bgp_neighbor_test_vector.testData[test_vector] if test_vector.startswith('bgp_v6'): exec_cmd = show.cli.commands["ipv6"].commands["bgp"].commands["neighbors"] else: exec_cmd = show.cli.commands["ip"].commands["bgp"].commands["neighbors"] result = runner.invoke(exec_cmd, input['args']) + check_result(result, input) + +def executor_vrf(test_vector, show): + runner = CliRunner() + input = bgp_neighbor_test_vector.testData[test_vector] + if test_vector.startswith('bgp_v6'): + exec_cmd = show.cli.commands["ipv6"].commands["bgp"].commands["vrf"] + else: + exec_cmd = show.cli.commands["ip"].commands["bgp"].commands["vrf"] + + result = runner.invoke(exec_cmd, [input['vrf'], 'neighbors'] + input['args']) + check_result(result, input) + + +def check_result(result, input): print(result.exit_code) print(result.output) @@ -50,6 +65,7 @@ def setup_class(cls): @pytest.mark.parametrize('setup_single_bgp_instance, test_vector', [ ('bgp_v4_neighbors_output', 'bgp_v4_neighbors'), + ('bgp_v4_neighbors_output', 'bgp_v4_neighbors_vrf'), ('bgp_v4_neighbors_output', 'bgp_v4_neighbor_ip_address'), ('bgp_v4_neighbor_invalid_neigh', @@ -61,6 +77,7 @@ def setup_class(cls): ('bgp_v4_neighbor_output_recv_routes', 'bgp_v4_neighbor_recv_routes'), ('bgp_v6_neighbors_output', 'bgp_v6_neighbors'), + ('bgp_v6_neighbors_output', 'bgp_v6_neighbors_vrf'), ('bgp_v6_neighbors_output', 'bgp_v6_neighbor_ip_address'), ('bgp_v6_neighbor_invalid', @@ -79,6 +96,7 @@ def test_bgp_neighbors(self, test_vector): show = setup_bgp_commands executor(test_vector, show) + executor_vrf(test_vector, show) class TestBgpNeighborsMultiAsic(object): @@ -118,6 +136,7 @@ def test_bgp_neighbors(self, test_vector): show = setup_bgp_commands executor(test_vector, show) + executor_vrf(test_vector, show) @classmethod def teardown_class(cls): diff --git a/tests/show_bgp_network_test.py b/tests/show_bgp_network_test.py index bfc23d8912..158dad8df9 100644 --- a/tests/show_bgp_network_test.py +++ b/tests/show_bgp_network_test.py @@ -16,7 +16,22 @@ def executor(test_vector, show): exec_cmd = show.cli.commands["ip"].commands["bgp"].commands["network"] result = runner.invoke(exec_cmd, input['args']) + check_result(result, input) + +def executor_vrf(test_vector, show): + runner = CliRunner() + input = bgp_network_test_vector.testData[test_vector] + if test_vector.startswith('bgp_v6'): + exec_cmd = show.cli.commands["ipv6"].commands["bgp"].commands["vrf"] + else: + exec_cmd = show.cli.commands["ip"].commands["bgp"].commands["vrf"] + + result = runner.invoke(exec_cmd, [input['vrf'], 'network'] + input['args']) + check_result(result, input) + + +def check_result(result, input): print(result.exit_code) print(result.output) @@ -36,7 +51,6 @@ def executor(test_vector, show): output = result.output.strip().split("\n")[0] assert input['rc_warning_msg'] in output - class TestBgpNetwork(object): @classmethod @@ -64,6 +78,7 @@ def test_bgp_network(self, setup_bgp_commands, test_vector, setup_single_bgp_instance): show = setup_bgp_commands executor(test_vector, show) + executor_vrf(test_vector, show) class TestMultiAsicBgpNetwork(object): @@ -93,6 +108,7 @@ def test_bgp_network(self, setup_bgp_commands, test_vector, setup_multi_asic_bgp_instance): show = setup_bgp_commands executor(test_vector, show) + executor_vrf(test_vector, show) @classmethod def teardown_class(cls): diff --git a/utilities_common/bgp_util.py b/utilities_common/bgp_util.py index 1844ef0d87..defd8e5f9d 100644 --- a/utilities_common/bgp_util.py +++ b/utilities_common/bgp_util.py @@ -262,15 +262,21 @@ def run_bgp_show_command(vtysh_cmd, bgp_namespace=multi_asic.DEFAULT_NAMESPACE, return output -def get_bgp_summary_from_all_bgp_instances(af, namespace, display): +def get_bgp_summary_from_all_bgp_instances(af, namespace, display, vrf): device = multi_asic_util.MultiAsic(display, namespace) ctx = click.get_current_context() if af is constants.IPV4: - vtysh_cmd = "show ip bgp summary json" + vtysh_cmd = "show ip bgp" + if vrf is not None: + vtysh_cmd += ' vrf {}'.format(vrf) + vtysh_cmd += " summary json" key = 'ipv4Unicast' else: - vtysh_cmd = "show bgp ipv6 summary json" + vtysh_cmd = "show bgp" + if vrf is not None: + vtysh_cmd += ' vrf {}'.format(vrf) + vtysh_cmd += " ipv6 summary json" key = 'ipv6Unicast' bgp_summary = {} @@ -301,7 +307,10 @@ def get_bgp_summary_from_all_bgp_instances(af, namespace, display): has_bgp_neighbors = False if not has_bgp_neighbors: - vtysh_bgp_json_cmd = "show ip bgp json" + vtysh_bgp_json_cmd = "show ip bgp" + if vrf is not None: + vtysh_bgp_json_cmd += " vrf {}".format(vrf) + vtysh_bgp_json_cmd += " json" no_neigh_cmd_output = run_bgp_show_command(vtysh_bgp_json_cmd, ns) try: no_neigh_cmd_output_json = json.loads(no_neigh_cmd_output)