diff --git a/docs/testplan/BGP-queue-test-plan.md b/docs/testplan/BGP-queue-test-plan.md new file mode 100644 index 0000000000..4895c2dd62 --- /dev/null +++ b/docs/testplan/BGP-queue-test-plan.md @@ -0,0 +1,31 @@ +# BGP-queue test plan + +* [Overview](#Overview) + * [Scope](#Scope) + * [Testbed](#Testbed) +* [Setup configuration](#Setup%20configuration) +* [Test cases](#Test%20cases) + +## Overview +The purpose is to make sure that BGP control packets use unicast queue 7 by default on all SONiC platforms. +The test expects that basic BGP configuration for the test is pre-configured on SONiC device before test run. + +### Scope +The test is targeting a running SONiC system with fully functioning configuration. The purpose of the test is to verify BGP control packets use egress queue 7 on SONiC platforms. + +### Testbed +The test could run on any testbed. + +## Setup configuration +This test requires BGP neighbors to be configured and established before the test run. + +## Test +The test will verify that all BGP packets use unicast queue 7 by default. It is to be noted that if BGP sessions are established over PortChannels, LACP packets will also use the same unicast queue 7, but that does not impact the test functionality. + +## Test cases +### Test case test_bgp_queue +#### Test steps +* Clear all queue counters using "sonic-clear counters" command +* Generate a mapping of neighbors to the corresponding interfaces/ports using ARP/NDP entries +* For all "established" BGP sessions, run "show queue counters" on the corresponding port +* Verify that unicast queue 7 counters are non-zero and that unicast queue 0 counters are zero diff --git a/tests/bgp/test_bgp_queue.py b/tests/bgp/test_bgp_queue.py new file mode 100644 index 0000000000..2e83a074c1 --- /dev/null +++ b/tests/bgp/test_bgp_queue.py @@ -0,0 +1,77 @@ +import time +import pytest +import logging + +logger = logging.getLogger(__name__) + +pytestmark = [ + pytest.mark.topology('any'), + pytest.mark.device_type('vs') +] + + +def clear_queue_counters(duthost): + duthost.shell("sonic-clear queuecounters") + + +def get_queue_counters(duthost, port, queue): + """ + Return the counter for a given queue in given port + """ + cmd = "show queue counters {}".format(port) + output = duthost.shell(cmd)['stdout_lines'] + txq = "UC{}".format(queue) + for line in output: + fields = line.split() + if fields[1] == txq: + return int(fields[2]) + return -1 + + +def test_bgp_queues(duthosts, enum_frontend_dut_hostname, enum_asic_index, tbinfo): + duthost = duthosts[enum_frontend_dut_hostname] + clear_queue_counters(duthost) + time.sleep(10) + bgp_facts = duthost.bgp_facts(instance_id=enum_asic_index)['ansible_facts'] + mg_facts = duthost.get_extended_minigraph_facts(tbinfo) + + arp_dict = {} + ndp_dict = {} + processed_intfs = set() + show_arp = duthost.command('show arp') + show_ndp = duthost.command('show ndp') + for arp_entry in show_arp['stdout_lines']: + items = arp_entry.split() + if (len(items) != 4): + continue + ip = items[0] + iface = items[2] + arp_dict[ip] = iface + for ndp_entry in show_ndp['stdout_lines']: + items = ndp_entry.split() + if (len(items) != 5): + continue + ip = items[0] + iface = items[2] + ndp_dict[ip] = iface + + for k, v in list(bgp_facts['bgp_neighbors'].items()): + # Only consider established bgp sessions + if v['state'] == 'established': + assert (k in arp_dict.keys() or k in ndp_dict.keys()) + if k in arp_dict: + ifname = arp_dict[k].split('.', 1)[0] + else: + ifname = ndp_dict[k].split('.', 1)[0] + if ifname in processed_intfs: + continue + if (ifname.startswith("PortChannel")): + for port in mg_facts['minigraph_portchannels'][ifname]['members']: + logger.info("PortChannel '{}' : port {}".format(ifname, port)) + for q in range(0, 7): + assert(get_queue_counters(duthost, port, q) == 0) + else: + logger.info(ifname) + for q in range(0, 7): + assert(get_queue_counters(duthost, ifname, q) == 0) + processed_intfs.add(ifname)