Skip to content

Commit

Permalink
Added support for running T2 applicable tests using vsonic(KVM) for n… (
Browse files Browse the repository at this point in the history
sonic-net#6022)

* Added support for running T2 applicable tests using vsonic(KVM) for neighbors

1. Fix for test_lldp testcase:
  KVM neighbors do not advertise port ifname. They instead advertise 'descr'.  We will use ifname for EosHost and descr for KVM
2. Fix for test_snmp_loopback testcase:
  snmpget command requires running in snmp docker
3. voq tests
  BGP:
    - Use vtysh for BGP configuration on vsonic
  Interface up/down:
    - Use shut/no shut commands

  Interface name and numbering:
    - Neighbors interface name is difference on vsonic vs Eos.
      - On Eos, inerfaces are named 'eth' (Ex. eth1) and portchannels are named po (Ex. po1).
      - On vsonic, interfaces are named Ethernet (Ex. Ethernet1) and portchannels are named PortChannel (PortChannel1).
  • Loading branch information
mannytaheri authored and mssonicbld committed Mar 4, 2024
1 parent b488684 commit 5e310b0
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 61 deletions.
33 changes: 22 additions & 11 deletions tests/lldp/test_lldp.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def lldp_setup(duthosts, enum_rand_one_per_hwsku_frontend_hostname, patch_lldpct


def test_lldp(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost,
collect_techsupport_all_duts, enum_frontend_asic_index):
collect_techsupport_all_duts, enum_frontend_asic_index, request):
""" verify the LLDP message on DUT """
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]

Expand All @@ -33,11 +33,15 @@ def test_lldp(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost,
# Compare the LLDP neighbor name with minigraph neigbhor name (exclude the management port)
assert v['chassis']['name'] == config_facts['DEVICE_NEIGHBOR'][k]['name']
# Compare the LLDP neighbor interface with minigraph neigbhor interface (exclude the management port)
assert v['port']['ifname'] == config_facts['DEVICE_NEIGHBOR'][k]['port']
if request.config.getoption("--neighbor_type") == 'eos':
assert v['port']['ifname'] == config_facts['DEVICE_NEIGHBOR'][k]['port']
else:
# Dealing with KVM that advertises port description
assert v['port']['descr'] == config_facts['DEVICE_NEIGHBOR'][k]['port']


def test_lldp_neighbor(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, eos,
collect_techsupport_all_duts, loganalyzer, enum_frontend_asic_index, tbinfo):
def test_lldp_neighbor(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, eos, sonic,
collect_techsupport_all_duts, loganalyzer, enum_frontend_asic_index, tbinfo, request):
""" verify LLDP information on neighbors """
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]

Expand Down Expand Up @@ -80,16 +84,23 @@ def test_lldp_neighbor(duthosts, enum_rand_one_per_hwsku_frontend_hostname, loca
logger.info("Neighbor device {} does not sent management IP via lldp".format(v['chassis']['name']))
hostip = nei_meta[v['chassis']['name']]['mgmt_addr']

nei_lldp_facts = localhost.lldp_facts(
host=hostip, version='v2c', community=eos['snmp_rocommunity'])['ansible_facts']
neighbor_interface = v['port']['ifname']
logger.info("lldp facts for interface {}:{}".format(neighbor_interface,
nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]))
if request.config.getoption("--neighbor_type") == 'eos':
nei_lldp_facts = localhost.lldp_facts(host=hostip, version='v2c', community=eos['snmp_rocommunity'])[
'ansible_facts']
neighbor_interface = v['port']['ifname']
else:
nei_lldp_facts = localhost.lldp_facts(host=hostip, version='v2c', community=sonic['snmp_rocommunity'])[
'ansible_facts']
neighbor_interface = v['port']['local']
# Verify the published DUT system name field is correct
assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_sys_name'] == duthost.hostname
# Verify the published DUT chassis id field is not empty
assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_chassis_id'] == \
"0x%s" % (switch_mac.replace(':', ''))
if request.config.getoption("--neighbor_type") == 'eos':
assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_chassis_id'] == \
"0x%s" % (switch_mac.replace(':', ''))
else:
assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_chassis_id'] == switch_mac

# Verify the published DUT system description field is correct
assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_sys_desc'] == dut_system_description
# Verify the published DUT port id field is correct
Expand Down
7 changes: 6 additions & 1 deletion tests/pc/test_lag_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,18 @@ def has_lags(dut):
"lacp_rate",
"fallback"])
def test_lag(common_setup_teardown, duthosts, tbinfo, nbrhosts, fanouthosts,
conn_graph_facts, enum_dut_portchannel_with_completeness_level, testcase): # noqa F811
conn_graph_facts, enum_dut_portchannel_with_completeness_level, testcase, request): # noqa F811
# We can't run single_lag test on vtestbed since there is no leaffanout
if testcase == "single_lag" and is_vtestbed(duthosts[0]):
pytest.skip("Skip single_lag test on vtestbed")
if 'PortChannel201' in enum_dut_portchannel_with_completeness_level:
pytest.skip("PortChannel201 is a specific configuration of t0-56-po2vlan topo, which is not supported by test")

# Skip lacp_rate testcases on KVM since setting lacp rate it is not supported on KVM
if testcase == "lacp_rate":
if request.config.getoption("--neighbor_type") == 'sonic':
pytest.skip("lacp_rate is not supported in vsonic")

ptfhost = common_setup_teardown

dut_name, dut_lag = decode_dut_port_name(enum_dut_portchannel_with_completeness_level)
Expand Down
115 changes: 71 additions & 44 deletions tests/voq/test_voq_nbr.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from .voq_helpers import get_inband_info
from .voq_helpers import get_ptf_port
from .voq_helpers import get_vm_with_ip
from tests.common.devices.eos import EosHost

from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -127,16 +128,13 @@ def restore_bgp(duthosts, nbrhosts, all_cfg_facts):

for peer in nbr['conf']['bgp']['peers']:
for neighbor in nbr['conf']['bgp']['peers'][peer]:
nbr['host'].eos_config(
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(nbr['conf']['bgp']['asn'])])

if ":" in address:
if isinstance(nbr['host'], EosHost):
nbr['host'].eos_config(
lines=["no ipv6 route ::/0 %s " % neighbor])
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(nbr['conf']['bgp']['asn'])])
else:
nbr['host'].eos_config(
lines=["no ip route 0.0.0.0/0 %s " % neighbor])
nbr['host'].shell("sudo vtysh -c 'configure terminal' -c 'router bgp " + str(
nbr['conf']['bgp']['asn']) + "' -c 'no neighbor {} shutdown'".format(neighbor))


@pytest.fixture(scope="module", autouse=True)
Expand Down Expand Up @@ -219,21 +217,25 @@ def disable_nbr_bgp_neighs(node=None, results=None):
'disable neighbors {} on neighbor host {}'.format(node['conf']['bgp']['peers'], node['host'].hostname))
for peer in node['conf']['bgp']['peers']:
for neighbor in node['conf']['bgp']['peers'][peer]:
node_results.append(node['host'].eos_config(
lines=["neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])],
module_ignore_errors=True)
)
if ":" in neighbor:
if isinstance(node['host'], EosHost):
node_results.append(node['host'].eos_config(
lines=["ipv6 route ::/0 %s " % neighbor],
lines=["neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])],
module_ignore_errors=True)
)
if ":" in neighbor:
node_results.append(node['host'].eos_config(
lines=["ipv6 route ::/0 %s " % neighbor],
module_ignore_errors=True)
)
else:
node_results.append(node['host'].eos_config(
lines=["ip route 0.0.0.0/0 %s " % neighbor],
module_ignore_errors=True)
)
else:
node_results.append(node['host'].eos_config(
lines=["ip route 0.0.0.0/0 %s " % neighbor],
module_ignore_errors=True)
)
node_results.append(node['host'].shell("sudo vtysh -c 'configure terminal' -c 'router bgp " + str(
node['conf']['bgp']['asn']) + "' -c 'neighbor {} shutdown'".format(neighbor)))

results[node['host'].hostname] = node_results

Expand Down Expand Up @@ -310,36 +312,47 @@ def enable_nbr_bgp_neighs(node=None, results=None):
for peer in node['conf']['bgp']['peers']:
for neighbor in node['conf']['bgp']['peers'][peer]:
try:
node_results.append(node['host'].eos_config(
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])])
)
if ":" in neighbor:
if isinstance(node['host'], EosHost):
node_results.append(node['host'].eos_config(
lines=["no ipv6 route ::/0 %s " % neighbor])
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])])
)
if ":" in neighbor:
node_results.append(node['host'].eos_config(
lines=["no ipv6 route ::/0 %s " % neighbor])
)
else:
node_results.append(node['host'].eos_config(
lines=["no ip route 0.0.0.0/0 %s " % neighbor],
)
)
else:
node_results.append(node['host'].eos_config(
lines=["no ip route 0.0.0.0/0 %s " % neighbor],
)
)
node_results.append(node['host'].shell(
"sudo vtysh -c 'configure terminal' -c 'router bgp " + str(
node['conf']['bgp']['asn']) + "' -c 'no neighbor {} shutdown'".format(neighbor)))

except Exception:
logger.warning("Enable of neighbor on VM: %s failed, retrying", node['host'].hostname)
time.sleep(10)
node_results.append(node['host'].eos_config(
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])])
)
if ":" in neighbor:
if isinstance(node['host'], EosHost):
node_results.append(node['host'].eos_config(
lines=["no ipv6 route ::/0 %s " % neighbor],
)
lines=["no neighbor %s shutdown" % neighbor],
parents=['router bgp {}'.format(node['conf']['bgp']['asn'])])
)
if ":" in neighbor:
node_results.append(node['host'].eos_config(
lines=["no ipv6 route ::/0 %s " % neighbor],
)
)
else:
node_results.append(node['host'].eos_config(
lines=["no ip route 0.0.0.0/0 %s " % neighbor],
)
)
else:
node_results.append(node['host'].eos_config(
lines=["no ip route 0.0.0.0/0 %s " % neighbor],
)
)
node_results.append(node['host'].shell(
"sudo vtysh -c 'configure terminal' -c 'router bgp " + str(
node['conf']['bgp']['asn']) + "' -c 'no neighbor {} shutdown'".format(neighbor)))

results[node['host'].hostname] = node_results

Expand Down Expand Up @@ -435,12 +448,26 @@ def _change_vm_interface_on_vm(nbrhosts, state="up", node=None, results=None):
for eos_intf in list(nbr['conf']['interfaces'].keys()):
if "Loopback" in eos_intf:
continue

if state == "up":
logger.info("Startup EOS %s interface %s", node, eos_intf)
node_results.append(nbr['host'].eos_config(lines=["no shutdown"], parents=["interface %s" % eos_intf]))
logger.info("Startup Nbr %s interface %s", node, eos_intf)
if isinstance(nbr['host'], EosHost):
node_results.append(
nbr['host'].eos_config(lines=["no shutdown"], parents=["interface %s" % eos_intf]))
else:
if "port-channel" in eos_intf.lower():
# convert PortChannel-1 to PortChannel1
eos_intf = "PortChannel" + eos_intf[-1]
node_results.append(nbr['host'].shell("config interface startup {}".format(eos_intf)))
else:
logger.info("Shutdown EOS %s interface %s", node, eos_intf)
node_results.append(nbr['host'].eos_config(lines=["shutdown"], parents=["interface %s" % eos_intf]))
logger.info("Shutdown Nbr %s interface %s", node, eos_intf)
if isinstance(nbr['host'], EosHost):
node_results.append(nbr['host'].eos_config(lines=["shutdown"], parents=["interface %s" % eos_intf]))
else:
if "port-channel" in eos_intf.lower():
# convert PortChannel-1 to PortChannel1
eos_intf = "PortChannel" + eos_intf[-1]
node_results.append(nbr['host'].shell("config interface shutdown {}".format(eos_intf)))

results[node] = node_results

Expand Down
19 changes: 14 additions & 5 deletions tests/voq/voq_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from tests.common.utilities import wait_until
from tests.common.helpers.assertions import pytest_assert
from tests.common.helpers.sonic_db import AsicDbCli, AppDbCli, VoqDbCli, SonicDbKeyNotFound
from tests.common.devices.eos import EosHost

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -410,12 +411,20 @@ def get_eos_mac(nbr, nbr_intf):
Returns:
A dictionary with the mac address and shell interface name.
"""
if "port-channel" in nbr_intf.lower():
# convert Port-Channel1 to po1
shell_intf = "po" + nbr_intf[-1]

if isinstance(nbr['host'], EosHost):
if "port-channel" in nbr_intf.lower():
# convert Port-Channel1 to po1
shell_intf = "po" + nbr_intf[-1]
else:
# convert Ethernet1 to eth1
shell_intf = "eth" + nbr_intf[-1]
else:
# convert Ethernet1 to eth1
shell_intf = "eth" + nbr_intf[-1]
if "port-channel" in nbr_intf.lower():
# convert Port-Channel1 to PortChannel1
shell_intf = "PortChannel" + nbr_intf[-1]
else:
shell_intf = nbr_intf

output = nbr['host'].command("ip addr show dev %s" % shell_intf)
# 8: Ethernet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9100 ...
Expand Down

0 comments on commit 5e310b0

Please sign in to comment.