Skip to content

Commit

Permalink
Modified tests/ipfwd/test_mtu.py testcase to run on T2 topology (#2860)
Browse files Browse the repository at this point in the history
What is the motivation for this PR?
Need the capability to run ipfwd/test_mtu.py testcase on T2 topology.

How did you do it?
ipfwd/test_mtu.py testcase is modified to run on multi-dut by taking dut related information from mg_facts and added support to run T2 topology.

Co-authored-by: falodiya <[email protected]>
  • Loading branch information
oxygen980 and falodiya authored Mar 3, 2021
1 parent db59b4f commit 5f18513
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 123 deletions.
29 changes: 15 additions & 14 deletions ansible/roles/test/files/ptftests/mtu_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,21 @@ def setUp(self):
self.router_mac = self.test_params['router_mac']
self.testbed_type = self.test_params['testbed_type']
self.testbed_mtu = self.test_params['testbed_mtu']
self.src_host_ip = self.test_params.get('src_host_ip')
self.src_router_ip = self.test_params.get('src_router_ip')
self.dst_host_ip = self.test_params.get('dst_host_ip')
self.src_ptf_port_list = self.test_params.get('src_ptf_port_list')
self.dst_ptf_port_list = self.test_params.get('dst_ptf_port_list')

#---------------------------------------------------------------------

def check_icmp_mtu(self):
'''
@summary: Check ICMP/Ping to DUT works for MAX MTU.
'''
ip_src = "10.0.0.1"
ip_dst = "10.0.0.0"
src_mac = self.dataplane.get_mac(0, 0)
ip_src = self.src_host_ip
ip_dst = self.src_router_ip
src_mac = self.dataplane.get_mac(0, self.src_ptf_port_list[0])
pktlen = self.pktlen

pkt = simple_icmp_packet(pktlen=pktlen,
Expand All @@ -82,10 +87,10 @@ def check_icmp_mtu(self):
masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
masked_exp_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum")

src_port = 0
src_port = self.src_ptf_port_list[0]
send_packet(self, src_port, pkt)
logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst)
dst_port_list = [0,1]
dst_port_list = self.src_ptf_port_list

(matched_index, received) = verify_packet_any_port(self, masked_exp_pkt, dst_port_list)

Expand All @@ -102,9 +107,9 @@ def check_ip_mtu(self):
'''
@summary: Check unicast IP forwarding in DUT works for MAX MTU.
'''
ip_src = "10.0.0.1"
ip_dst = "10.0.0.63"
src_mac = self.dataplane.get_mac(0, 0)
ip_src = self.src_host_ip
ip_dst = self.dst_host_ip
src_mac = self.dataplane.get_mac(0, self.src_ptf_port_list[0])

pkt = simple_ip_packet(pktlen=self.pktlen,
eth_dst=self.router_mac,
Expand All @@ -122,15 +127,11 @@ def check_ip_mtu(self):
masked_exp_pkt = Mask(exp_pkt)
masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

src_port = 0
src_port = self.src_ptf_port_list[0]
send_packet(self, src_port, pkt)
logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst)
dst_port_list = []
if self.testbed_type == 't1' or self.testbed_type == 't1-lag':
dst_port_list = [31]
elif self.testbed_type == 't1-64-lag' or self.testbed_type == 't1-64-lag-clet':
dst_port_list = [58]

dst_port_list = self.dst_ptf_port_list
(matched_index, received) = verify_packet_any_port(self, masked_exp_pkt, dst_port_list)

assert received
Expand Down
114 changes: 114 additions & 0 deletions tests/ipfwd/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import pytest
from ipaddress import ip_address
import logging
import json


logger = logging.getLogger(__name__)


'''
In case of multi-dut we need src_host_ip, src_router_ip, dst_host_ip, src_ptf_port_list, dst_ptf_port_list for the dut under test,
to take care of that made changes in the testcase
'''

def get_lag_facts(dut, lag_facts, switch_arptable, mg_facts, ignore_lags, key='src'):
if not mg_facts['minigraph_portchannels']:
pytest.fail("minigraph_portchannels is not defined")

# minigraph facts
selected_lag_facts = {}
up_lag = None
for a_lag_name, a_lag_data in lag_facts['lags'].items():
if a_lag_data['po_intf_stat'] == 'Up' and a_lag_name not in ignore_lags:
# We found a portchannel that is up.
up_lag = a_lag_name
selected_lag_facts[key + '_port_ids'] = [mg_facts['minigraph_ptf_indices'][intf] for intf in a_lag_data['po_config']['ports']]
selected_lag_facts[key + '_router_mac'] = dut.facts['router_mac']
for intf in mg_facts['minigraph_portchannel_interfaces']:
if intf['attachto'] == up_lag:
addr = ip_address(unicode(intf['addr']))
if addr.version == 4:
selected_lag_facts[key + '_router_ipv4'] = intf['addr']
selected_lag_facts[key + '_host_ipv4'] = intf['peer_addr']
selected_lag_facts[key + '_host_mac'] = switch_arptable['arptable']['v4'][intf['peer_addr']]['macaddress']
elif addr.version == 6:
selected_lag_facts[key + '_router_ipv6'] = intf['addr']
selected_lag_facts[key + '_host_ipv6'] = intf['peer_addr']
logger.info("{} lag is {}".format(key, up_lag))
break

return up_lag, selected_lag_facts


def get_port_facts(dut, mg_facts, port_status, switch_arptable, ignore_intfs, key='src'):
if not mg_facts['minigraph_interfaces']:
pytest.fail("minigraph_interfaces is not defined.")
selected_port_facts = {}
up_port = None
for a_intf_name, a_intf_data in port_status['int_status'].items():
if a_intf_data['oper_state'] == 'up' and a_intf_name not in ignore_intfs:
# Got a port that is up and not already used.
for intf in mg_facts['minigraph_interfaces']:
if intf['attachto'] == a_intf_name:
up_port = a_intf_name
selected_port_facts[key + '_port_ids'] = [mg_facts['minigraph_ptf_indices'][a_intf_name]]
selected_port_facts[key + '_router_mac'] = dut.facts['router_mac']
addr = ip_address(unicode(intf['addr']))
if addr.version == 4:
selected_port_facts[key + '_router_ipv4'] = intf['addr']
selected_port_facts[key + '_host_ipv4'] = intf['peer_addr']
selected_port_facts[key + '_host_mac'] = switch_arptable['arptable']['v4'][intf['peer_addr']]['macaddress']
elif addr.version == 6:
selected_port_facts[key + '_router_ipv6'] = intf['addr']
selected_port_facts[key + '_host_ipv6'] = intf['peer_addr']
if up_port:
logger.info("{} port is {}".format(key, up_port))
break
return up_port, selected_port_facts

@pytest.fixture(scope='function')
def gather_facts(tbinfo, duthosts, enum_rand_one_per_hwsku_frontend_hostname):
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
facts = {}

logger.info("Gathering facts on DUT ...")
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)

# Use the arp table to get the mac address of the host (VM's) instead of lldp_facts as that is was is used
# by the DUT to forward traffic - regardless of lag or port.
switch_arptable = duthost.switch_arptable()['ansible_facts']
used_intfs = set()
src = None # Name of lag or interface that is is up
dst = None # Name of lag or interface that is is up

# if minigraph_portchannel_interfaces is not empty - topology with lag - check if we have 2 lags that are 'Up'
if mg_facts['minigraph_portchannel_interfaces']:
# Get lag facts from the DUT to check which ag is up
lag_facts = duthost.lag_facts(host=duthost.hostname)['ansible_facts']['lag_facts']
src, src_lag_facts = get_lag_facts(duthost, lag_facts, switch_arptable, mg_facts, used_intfs, key='src')
used_intfs.add(src)
if src:
facts.update(src_lag_facts)
# We found a src lag, let see if we can find a dst lag
dst, dst_lag_facts = get_lag_facts(duthost, lag_facts, switch_arptable, mg_facts, used_intfs, key='dst')
used_intfs.add(dst)
facts.update(dst_lag_facts)

if src is None or dst is None:
# We didn't find 2 lags, lets check up interfaces
port_status = duthost.show_interface(command='status')['ansible_facts']
if src is None:
src, src_port_facts = get_port_facts(duthost, mg_facts, port_status, switch_arptable, used_intfs, key='src')
used_intfs.add(src)
facts.update(src_port_facts)

if dst is None:
dst, dst_port_facts = get_port_facts(duthost, mg_facts, port_status, switch_arptable, used_intfs, key='dst')
facts.update(dst_port_facts)

if src is None or dst is None:
pytest.fail("Did not find 2 lag or interfaces that are up on host {}".duthost.hostname)
logger.info("gathered_new_facts={}".format(json.dumps(facts, indent=2)))

yield facts
112 changes: 7 additions & 105 deletions tests/ipfwd/test_dip_sip.py
Original file line number Diff line number Diff line change
@@ -1,128 +1,26 @@
import pytest
import ptf.testutils as testutils
from ipaddress import ip_address
import logging
import json

from tests.common.fixtures.ptfhost_utils import change_mac_addresses # lgtm[py/unused-import]
from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # lgtm[py/unused-import]

DEFAULT_HLIM_TTL = 64
WAIT_EXPECTED_PACKET_TIMEOUT = 5

logger = logging.getLogger(__name__)

pytestmark = [
pytest.mark.topology('t0', 't1', 't2')
]

logger = logging.getLogger(__name__)


@pytest.fixture(scope="module", autouse="True")
def lldp_setup(duthosts, enum_rand_one_per_hwsku_frontend_hostname, patch_lldpctl, unpatch_lldpctl, localhost):
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
patch_lldpctl(localhost, duthost)
yield
unpatch_lldpctl(localhost, duthost)


def lag_facts(dut, mg_facts):
facts = {}

if not mg_facts['minigraph_portchannels']:
pytest.fail("minigraph_portchannels is not defined")

# minigraph facts
src_lag = mg_facts['minigraph_portchannel_interfaces'][2]['attachto']
dst_lag = mg_facts['minigraph_portchannel_interfaces'][0]['attachto']
logger.info("src_lag is {}, dst_lag is {}".format(src_lag, dst_lag))

# lldp facts
lldp_facts = dut.lldp()['ansible_facts']['lldp']
facts['dst_host_mac'] = lldp_facts[mg_facts['minigraph_portchannels'][dst_lag]['members'][0]]['chassis']['mac']
facts['src_host_mac'] = lldp_facts[mg_facts['minigraph_portchannels'][src_lag]['members'][0]]['chassis']['mac']

facts['dst_router_mac'] = dut.facts['router_mac']
facts['src_router_mac'] = dut.facts['router_mac']

for intf in mg_facts['minigraph_portchannel_interfaces']:
if intf['attachto'] == dst_lag:
addr = ip_address(unicode(intf['addr']))
if addr.version == 4:
facts['dst_router_ipv4'] = intf['addr']
facts['dst_host_ipv4'] = intf['peer_addr']
elif addr.version == 6:
facts['dst_router_ipv6'] = intf['addr']
facts['dst_host_ipv6'] = intf['peer_addr']

facts['dst_port_ids'] = []
for intf in mg_facts['minigraph_portchannels'][dst_lag]['members']:
facts['dst_port_ids'].append(mg_facts['minigraph_ptf_indices'][intf])

facts['src_port_ids'] = []
for intf in mg_facts['minigraph_portchannels'][src_lag]['members']:
facts['src_port_ids'].append(mg_facts['minigraph_ptf_indices'][intf])

return facts


def port_facts(dut, mg_facts):
facts = {}

if not mg_facts['minigraph_interfaces']:
pytest.fail("minigraph_interfaces is not defined.")

# minigraph facts
src_port = mg_facts['minigraph_interfaces'][2]['attachto']
dst_port = mg_facts['minigraph_interfaces'][0]['attachto']
logger.info("src_port is {}, dst_port is {}".format(src_port, dst_port))

# lldp facts
lldp_facts = dut.lldp()['ansible_facts']['lldp']
facts['dst_host_mac'] = lldp_facts[dst_port]['chassis']['mac']
facts['src_host_mac'] = lldp_facts[src_port]['chassis']['mac']

facts['dst_router_mac'] = dut.facts['router_mac']
facts['src_router_mac'] = dut.facts['router_mac']

for intf in mg_facts['minigraph_interfaces']:
if intf['attachto'] == dst_port:
addr = ip_address(unicode(intf['addr']))
if addr.version == 4:
facts['dst_router_ipv4'] = intf['addr']
facts['dst_host_ipv4'] = intf['peer_addr']
elif addr.version == 6:
facts['dst_router_ipv6'] = intf['addr']
facts['dst_host_ipv6'] = intf['peer_addr']

facts['dst_port_ids'] = [mg_facts['minigraph_ptf_indices'][dst_port]]
facts['src_port_ids'] = [mg_facts['minigraph_ptf_indices'][src_port]]

return facts


@pytest.fixture(scope='function')
def gather_facts(tbinfo, duthosts, enum_rand_one_per_hwsku_frontend_hostname):
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
facts = {}

topo_type = tbinfo['topo']['type']
if topo_type not in ('t0', 't1', 't2'):
pytest.skip("Unsupported topology")

logger.info("Gathering facts on DUT ...")
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)

# if minigraph_portchannel_interfaces is not empty - topology with lag
if mg_facts['minigraph_portchannel_interfaces']:
facts = lag_facts(duthost, mg_facts)
else:
facts = port_facts(duthost, mg_facts)

logger.info("gathered_facts={}".format(json.dumps(facts, indent=2)))

yield facts


def run_test_ipv6(ptfadapter, facts):
logger.info("Running test with ipv6 packets")

Expand Down Expand Up @@ -183,7 +81,11 @@ def run_test_ipv4(ptfadapter, facts):
testutils.verify_packet_any_port(ptfadapter, exp_pkt, facts['dst_port_ids'], timeout=WAIT_EXPECTED_PACKET_TIMEOUT)


def test_dip_sip(ptfadapter, gather_facts):
def test_dip_sip(tbinfo, ptfadapter, gather_facts):
topo_type = tbinfo['topo']['type']
if topo_type not in ('t0', 't1', 't2'):
pytest.skip("Unsupported topology")

ptfadapter.reinit()
run_test_ipv4(ptfadapter, gather_facts)
run_test_ipv6(ptfadapter, gather_facts)
18 changes: 14 additions & 4 deletions tests/ipfwd/test_mtu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
from datetime import datetime

pytestmark = [
pytest.mark.topology('t1')
pytest.mark.topology('t1', 't2')
]

@pytest.mark.parametrize("mtu", [1514,9114])
def test_mtu(tbinfo, duthosts, rand_one_dut_hostname, ptfhost, mtu):
duthost = duthosts[rand_one_dut_hostname]
def test_mtu(tbinfo, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, mtu, gather_facts):
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]

topo_type = tbinfo['topo']['type']
if topo_type not in ('t1', 't2'):
pytest.skip("Unsupported topology")

testbed_type = tbinfo['topo']['name']
router_mac = duthost.shell('sonic-cfggen -d -v \'DEVICE_METADATA.localhost.mac\'')["stdout_lines"][0].decode("utf-8")
Expand All @@ -27,6 +31,12 @@ def test_mtu(tbinfo, duthosts, rand_one_dut_hostname, ptfhost, mtu):
platform_dir="ptftests",
params={"testbed_type": testbed_type,
"router_mac": router_mac,
"testbed_mtu": mtu },
"testbed_mtu": mtu,
"src_host_ip": gather_facts['src_host_ipv4'],
"src_router_ip": gather_facts['src_router_ipv4'],
"dst_host_ip": gather_facts['dst_host_ipv4'],
"src_ptf_port_list": gather_facts['src_port_ids'],
"dst_ptf_port_list": gather_facts['dst_port_ids']
},
log_file=log_file,
socket_recv_size=16384)

0 comments on commit 5f18513

Please sign in to comment.