* [dts] [PATCH 1/2] test_plans: add test plan for userspace ethtool sample
@ 2016-01-26 1:48 Yong Liu
2016-01-26 1:48 ` [dts] [PATCH 2/2] tests: add test suite " Yong Liu
0 siblings, 1 reply; 2+ messages in thread
From: Yong Liu @ 2016-01-26 1:48 UTC (permalink / raw)
To: dts
This sample is designed to demo the rte_ethtool shim layer based on
rte_ethdev API.
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/test_plans/userspace_ethtool_test_plan.rst b/test_plans/userspace_ethtool_test_plan.rst
new file mode 100644
index 0000000..18f5314
--- /dev/null
+++ b/test_plans/userspace_ethtool_test_plan.rst
@@ -0,0 +1,246 @@
+.. Copyright (c) <2015> Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+
+==================
+ Userspace Ethtool
+==================
+
+This feature is designed to provide one rte_ethtool shim layer based on
+rte_ethdev API. The implementation also along with a command prompt driven
+demonstration application. It only contained of 18 popular used Ethtool and
+Netdevice ops as described in rte_ethtool.h.
+
+Prerequisites
+=============
+
+Assume port 0 and 1 are connected to the traffic generator, to run the test
+application in linuxapp environment with 4 lcores, 2 ports.
+
+ ethtool -c f -n 4
+
+The sample should be validated on Forville, Niantic and i350 Nics.
+
+Test Case: Dump driver infor test
+=================================
+User "drvinfo" command to dump driver information and then check that dumped
+information was exactly the same as fact.
+
+ EthApp> drvinfo
+ Port 0 driver: rte_ixgbe_pmd (ver: RTE 2.1.0)
+ Port 1 driver: rte_ixgbe_pmd (ver: RTE 2.1.0)
+
+Use "link" command to dump all ports link status.
+ EthApp> link
+ Port 0: Up
+ Port 1: Up
+
+Change tester port link status to down and re-check link status.
+ EthApp> link
+ Port 0: Down
+ Port 1: Down
+
+Send few packets to l2fwd and check that command "portstats" dumped correct
+port statistics.
+ EthApp> portstats 0
+ Port 0 stats
+ In: 1 (64 bytes)
+ Out: 1 (64 bytes)
+
+Test Case: Retrieve eeprom test
+===============================
+Unbind ports from igb_uio and bind them to default driver.
+Dump eeprom binary by ethtool.
+
+ethtool --eeprom-dump INTF_0 raw on > ethtool_eeprom_0.bin
+ethtool --eeprom-dump INTF_1 raw on > ethtool_eeprom_1.bin
+
+Retrieve eeprom on specified port and compare csum with the file dumped by ethtool.
+
+ EthApp> eeprom 0 eeprom_0.bin
+ EthApp> eeprom 1 eeprom_1.bin
+
+md5sum ethtool_eeprom_0.bin
+md5sum eeprom_0.bin > eeprom_0.bin
+
+diff ethtool_eeprom_0.hex eeprom_0.hex
+
+Test Case: Retrieve register test
+===============================
+Retrieve register on specified port, do not known how to check the binary?
+
+ EthApp> regs 0 reg_0.bin
+ EthApp> regs 1 reg_1.bin
+
+Unbind ports from igb_uio and bind them to default driver.
+Check that dumped register information is correct.
+
+ethtool -d INTF_0 raw on file reg_0.bin
+ethtool -d INTF_1 raw on file reg_0.bin
+
+Test Case: Ring param test
+==========================
+Dump port 0 ring size by ringparam command and check numbers are correct.
+
+EthApp> ringparam 0
+Port 0 ring paramaeters
+ Rx Pending: 128 (256 max)
+ Tx Pending: 4096 (4096 max)
+
+Change port 0 ring size by ringparam command and then verify Rx/Tx function.
+
+EthApp> ringparam 0 256 2048
+
+Recheck ring size by ringparam command.
+
+EthApp> ringparam 0
+Port 0 ring paramaeters
+ Rx Pending: 256 (256 max)
+ Tx Pending: 2048 (4096 max)
+
+Test Case: Pause test
+=====================
+Enable port 0 Rx pause frame and then create two packets flows in IXIA port.
+One flow is 100000 normally packet and the second flow is pause frame.
+Check that port 0 Rx speed dropped. For example, niantic will drop from
+14.8Mpps to 7.49Mpps.
+
+ EthApp> pause 0 rx
+
+Use "parse" command to print port pause status, check that port 0 rx has been
+paused.
+ EthApp> pause 0
+ Port 0: Rx Paused
+
+Unpause port 0 rx and then restart port0, check that packets Rx speed is normal.
+ EthApp> pause 0 none
+ EthApp>
+
+Pause port 0 TX pause frame.
+ EthApp> pause 0 tx
+
+Use "parse" command to print port pause status, check that port 1 tx has been
+paused.
+ EthApp> pause 0
+ Port 0: Tx Paused
+
+Enable flow control in IXIA port and send packets from IXIA with line rate.
+Check that IXIA receive flow control packets and IXIA transmit speed dropped.
+IXIA Rx packets more then Tx packets to check that received pause frame.
+
+Unpause port 0 tx and restart port 0. Then send packets to port0, check that
+packets forwarded normally from port 0.
+ EthApp> pause 0 none
+ EthApp> stop 0
+ EthApp> open 0
+
+Test Case: Vlan test
+====================
+Add vlan 0 to port 0 and vlan 1 to port1, send packet without vlan to port0,1
+Verify port0 and port1 recevied vlan packets
+ EthApp> vlan 0 add 0
+ VLAN vid 0 added
+
+ EthApp> vlan 1 add 1
+ VLAN vid 1 added
+
+Send packet with vlan0,1 to port0&1. Verify port0 and port1 received vlan
+packets
+
+Send packet with vlan1,0 to port0&1. Verify port0 and port1 can not receive
+vlan packets
+
+Remove vlan 0,1 from port0&1, send packet with vlan0,1 to port0,1. Verify
+port0 and port1 can not receive vlan packet.
+
+ EthApp> vlan 0 del 0
+ VLAN vid 0 removed
+ EthApp> vlan 1 del 1
+ VLAN vid 1 removed
+
+Test Case: Mac address test
+===========================
+Use "macaddr" command to dump port mac address and then check that dumped
+information is exactly the same as fact.
+ EthApp> macaddr 0
+ Port 0 MAC Address: XX:XX:XX:XX:XX:XX
+ EthApp> macaddr 1
+ Port 1 MAC Address: YY:YY:YY:YY:YY:YY
+
+Check mulitcast macaddress will not be valided.
+ EthApp> validate 01:00:00:00:00:00
+ Address is not unicast
+
+Check all zero macaddress will not be valided.
+ EthApp> validate 00:00:00:00:00:00
+ Address is not unicast
+
+Use "macaddr" command to change port mac address and then check mac changed.
+ EthApp> validate 00:10:00:00:00:00
+ Address is unicast
+
+ EthApp> macaddr 0 00:10:00:00:00:00
+ MAC address changed
+ EthApp> macaddr 0
+ Port 0 MAC Address: 00:10:00:00:00:00
+
+Verified mac adress in forwarded packets has been changed.
+
+Test Case: Port config test
+===========================
+Use "stop" command to stop port0. Send packets to port0 and verify no packet
+recevied.
+ EthApp> stop 0
+
+Use "open" command to re-enable port0. Send packets to port0 and verify
+packets received and forwarded.
+ EthApp> open 0
+
+
+Test case: Mtu config test
+==========================
+Use "mtu" command to change port 0 mtu from default 1518 to 1000.
+
+Send packet size over 1000 and check that packet will be detected as error.
+
+ EthApp> mtu 0 1000
+ Port 0 stats
+ In: 0 (0 bytes)
+ Out: 0 (0 bytes)
+ Err: 1
+
+Change mtu to default value and send packet size over 1000 and check that
+packet will normally received.
+
+Test Case: Rx mode test
+=======================
+Enable untagged vlan in VF devices and extended vlan support.
+Do not known how to test?
--
1.9.3
^ permalink raw reply [flat|nested] 2+ messages in thread
* [dts] [PATCH 2/2] tests: add test suite for userspace ethtool sample
2016-01-26 1:48 [dts] [PATCH 1/2] test_plans: add test plan for userspace ethtool sample Yong Liu
@ 2016-01-26 1:48 ` Yong Liu
0 siblings, 0 replies; 2+ messages in thread
From: Yong Liu @ 2016-01-26 1:48 UTC (permalink / raw)
To: dts
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/tests/TestSuite_userspace_ethtool.py b/tests/TestSuite_userspace_ethtool.py
new file mode 100644
index 0000000..c479093
--- /dev/null
+++ b/tests/TestSuite_userspace_ethtool.py
@@ -0,0 +1,586 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+DPDK Test suite.
+Test support of userspace ethtool feature
+"""
+
+import dts
+import time
+import re
+from test_case import TestCase
+from pmd_output import PmdOutput
+from packet import Packet, sniff_packets, load_sniff_packets
+import random
+from etgen import IxiaPacketGenerator
+from settings import HEADER_SIZE
+from settings import SCAPY2IXIA
+
+
+class TestUserspaceEthtool(TestCase, IxiaPacketGenerator):
+
+ def set_up_all(self):
+ """
+ Run at the start of each test suite.
+ """
+ self.ports = self.dut.get_ports()
+ self.verify(len(self.ports) >= 2, "No ports found for " + self.nic)
+
+ # build sample app
+ out = self.dut.send_expect("make -C examples/ethtool", "# ")
+ self.verify("Error" not in out, "compilation error 1")
+ self.verify("No such file" not in out, "compilation error 2")
+
+ path = "./examples/ethtool/ethtool-app/ethtool-app/%s/ethtool" % self.target
+ self.cmd = "%s -c f -n %d" % (path, self.dut.get_memory_channels())
+
+ # pause frame basic configuration
+ self.pause_time = 65535
+ self.frame_size = 64
+ self.pause_rate = 0.50
+
+ # update IxiaPacketGenerator function from local
+ self.tester.extend_external_packet_generator(TestUserspaceEthtool, self)
+
+ def set_up(self):
+ """
+ Run before each test case.
+ """
+ pass
+
+ def build_ethtool(self):
+ out = self.dut.send_expect("make -C examples/ethtool", "# ")
+ self.verify("Error" not in out, "compilation error 1")
+ self.verify("No such file" not in out, "compilation error 2")
+
+ def strip_portstats(self, portid):
+ out = self.dut.send_expect("portstats %d " % portid, "EthApp>")
+ stats_pattern = r"portstats (\d)(\s+)Port (\d+) stats(\s+)In: (\d+)" \
+ " \((\d+) bytes\)(\s+)Out: (\d+) \((\d+) bytes\)" \
+ "(\s+)Err: (\d+)"
+
+ m = re.match(stats_pattern, out)
+ if m:
+ return (int(m.group(5)), int(m.group(8)))
+ else:
+ return (0, 0)
+
+ def strip_ringparam(self, portid):
+ out = self.dut.send_expect("ringparam %d" % portid, "EthApp>")
+ ring_pattern = r"ringparam (\d)(\s+)Port (\d+) ring parameters(\s+)" \
+ "Rx Pending: (\d+) \((\d+) max\)(\s+)Tx Pending: " \
+ "(\d+) \((\d+) max\)"
+ m = re.match(ring_pattern, out)
+ if m:
+ return (int(m.group(5)), int(m.group(6)), int(m.group(8)),
+ int(m.group(9)))
+ else:
+ return (0, 0, 0, 0)
+
+ def strip_mac(self, portid):
+ out = self.dut.send_expect("macaddr %d" % portid, "EthApp>")
+ mac_pattern = r"macaddr (\d+)(\s+)Port (\d+) MAC Address: (.*)"
+ m = re.match(mac_pattern, out)
+ if m:
+ return m.group(4)
+ else:
+ return "00:00:00:00:00:00"
+
+ def strip_mtu(self, intf):
+ """
+ Strip tester port mtu
+ """
+ link_info = self.tester.send_expect("ip link show %s" % intf, "# ")
+ mtu_pattern = r".* mtu (\d+) .*"
+ m = re.match(mtu_pattern, link_info)
+ if m:
+ return int(m.group(1))
+ else:
+ return 1518
+
+ def strip_md5(self, filename):
+ md5_info = self.dut.send_expect("md5sum %s" % filename, "# ")
+ md5_pattern = r"(\w+) (\w+)"
+ m = re.match(md5_pattern, md5_info)
+ if m:
+ return m.group(1)
+ else:
+ return ""
+
+ def test_dump_driver_info(self):
+ """
+ Test ethtool can dump basic information
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ out = self.dut.send_expect("drvinfo", "EthApp>")
+ driver_pattern = r"Port (\d+) driver: rte_(.*)_pmd \(ver: RTE (.*)\)"
+ driver_infos = out.split("\r\n")
+ self.verify(len(driver_infos) > 1, "Userspace tool failed to dump driver infor")
+
+ # check dump driver info function
+ for driver_info in driver_infos:
+ m = re.match(driver_pattern, driver_info)
+ if m:
+ port = m.group(1)
+ driver = m.group(2)
+ version = m.group(3)
+ print dts.GREEN("Detect port %s with %s driver\n" % (port, driver))
+
+ # check link status dump function
+ for port in self.ports:
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ self.tester.send_expect("ip link set dev %s down" % intf, "# ")
+ # wait for link stable
+ time.sleep(5)
+
+ out = self.dut.send_expect("link", "EthApp>", 60)
+ link_pattern = r"Port (\d+): (.*)"
+ link_infos = out.split("\r\n")
+ for link_info in link_infos:
+ m = re.match(link_pattern, link_info)
+ if m:
+ port = m.group(1)
+ status = m.group(2)
+ self.verify(status == "Down", "Userspace tool failed to detect link down")
+
+ for port in self.ports:
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ self.tester.send_expect("ip link set dev %s up" % intf, "# ")
+ # wait for link stable
+ time.sleep(5)
+
+ # check port stats function
+ pkt = Packet(pkt_type='UDP')
+ for port in self.ports:
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ ori_rx_pkts, ori_tx_pkts = self.strip_portstats(port)
+ pkt.send_pkt(tx_port=intf)
+ time.sleep(1)
+ rx_pkts, tx_pkts = self.strip_portstats(port)
+ self.verify((rx_pkts == (ori_rx_pkts + 1)), "Failed to record Rx/Tx packets")
+
+ self.dut.send_expect("quit", "# ")
+
+ def test_retrieve_reg(self):
+ """
+ Test ethtool app can retrieve port register
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+
+ portsinfo = []
+ ori_drivers = []
+
+ for portid in range(len(self.ports)):
+ self.dut.send_expect("regs %d regs_%d.bin" % (portid, portid), "EthApp>")
+ portinfo = {'portid': portid, 'reg_file': 'regs_%d.bin' % portid}
+ portsinfo.append(portinfo)
+
+ self.dut.send_expect("quit", "# ")
+
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ netdev = self.dut.ports_info[port]['port']
+ portinfo = portsinfo[index]
+ # strip orignal driver
+ portinfo['ori_driver'] = netdev.get_nic_driver()
+ portinfo['net_dev'] = netdev
+ # bind to default driver
+ netdev.bind_driver()
+ # get linux interface
+ intf = netdev.get_interface_name()
+ out = self.dut.send_expect("ethtool -d %s raw off file %s" % (intf, portinfo['reg_file']), "# ")
+ self.verify(("LINKS" in out and "FCTRL" in out), "Failed to dump %s registers" % intf)
+
+ for index in range(len(self.ports)):
+ # bind to original driver
+ portinfo = portsinfo[index]
+ portinfo['net_dev'].bind_driver(portinfo['ori_driver'])
+
+ def test_retrieve_eeprom(self):
+ """
+ Test ethtool app dump eeprom function
+ """
+ # require md5sum to check file
+ out = self.dut.send_expect("whereis md5sum", "# ")
+ self.verify("/usr/bin/md5sum" in out, "This case required md5sum installed on DUT")
+
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+
+ portsinfo = []
+ ori_drivers = []
+
+ for portid in range(len(self.ports)):
+ # dump eemprom by userspace ethtool
+ self.dut.send_expect("eeprom %d eeprom_%d.bin" % (portid, portid), "EthApp>")
+ portinfo = {'portid': portid, 'eeprom_file': 'eeprom_%d.bin' % portid}
+ portsinfo.append(portinfo)
+
+ self.dut.send_expect("quit", "# ")
+
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ netdev = self.dut.ports_info[port]['port']
+ portinfo = portsinfo[index]
+ # strip orignal driver
+ portinfo['ori_driver'] = netdev.get_nic_driver()
+ portinfo['net_dev'] = netdev
+ # bind to default driver
+ netdev.bind_driver()
+ # get linux interface
+ intf = netdev.get_interface_name()
+ ethtool_eeprom = "ethtool_eeprom_%d.bin" % index
+ # dump eemprom by linux ethtool
+ self.dut.send_expect("ethtool --eeprom-dump %s raw on > %s" % (intf, ethtool_eeprom), "# ")
+ # wait for file ready
+ time.sleep(2)
+ portinfo['ethtool_eeprom'] = ethtool_eeprom
+ # bind to original driver
+ portinfo['net_dev'].bind_driver(portinfo['ori_driver'])
+
+ for index in range(len(self.ports)):
+ md5 = self.strip_md5(portsinfo[index]['eeprom_file'])
+ md5_ref = self.strip_md5(portsinfo[index]['ethtool_eeprom'])
+ print dts.GREEN("Reference eeprom md5 %s" % md5_ref)
+ self.verify(md5 == md5_ref, "Dumped eeprom not same as linux dumped")
+
+ def test_ring_parameter(self):
+ """
+ Test ethtool app ring parameter getting and setting
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ ori_rx_pkts, ori_tx_pkts = self.strip_portstats(port)
+ _, rx_max, _, tx_max = self.strip_ringparam(index)
+ self.dut.send_expect("ringparam %d %d %d" % (index, rx_max, tx_max), "EthApp>")
+ rx_ring, _, tx_ring, _ = self.strip_ringparam(index)
+ self.verify(rx_ring == rx_max, "Userspace tool failed to set Rx ring parameter")
+ self.verify(tx_ring == tx_max, "Userspace tool failed to set Tx ring parameter")
+ pkt = Packet()
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ pkt.send_pkt(tx_port=intf)
+ rx_pkts, tx_pkts = self.strip_portstats(index)
+ self.verify(rx_pkts == ori_rx_pkts + 1, "Failed to forward after ring parameter changed")
+
+ self.dut.send_expect("quit", "# ")
+
+ def test_ethtool_vlan(self):
+ """
+ Test ethtool app vlan add and delete
+ """
+ main_file = "examples/ethtool/ethtool-app/main.c"
+ # enable vlan filter
+ self.dut.send_expect("sed -i -e '/cfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;$/a\\cfg_port.rxmode.hw_vlan_filter=1;' %s" % main_file, "# ")
+
+ # build sample app
+ self.build_ethtool()
+
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ # generate random vlan
+ vlan = random.randrange(0, 4095)
+ # add vlan on port, record original statistic
+ self.dut.send_expect("vlan %d add %d" % (index, vlan), "EthApp>")
+ ori_rx_pkts, ori_tx_pkts = self.strip_portstats(port)
+
+ # send correct vlan packet to port
+ pkt = Packet(pkt_type='VLAN_UDP')
+ pkt.config_layer('dot1q', {'vlan': vlan})
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ pkt.send_pkt(tx_port=intf)
+ time.sleep(2)
+ rx_pkts, tx_pkts = self.strip_portstats(port)
+ self.verify(rx_pkts == ori_rx_pkts + 1, "Failed to Rx vlan packet")
+ self.verify(tx_pkts == ori_tx_pkts + 1, "Failed to Tx vlan packet")
+
+ # send incorrect vlan packet to port
+ wrong_vlan = (vlan + 1) % 4096
+ pkt.config_layer('dot1q', {'vlan': wrong_vlan})
+ pkt.send_pkt(tx_port=intf)
+ time.sleep(2)
+ rx_pkts_wrong, _ = self.strip_portstats(port)
+ self.verify(rx_pkts_wrong == rx_pkts, "Failed to filter Rx vlan packet")
+
+ # remove vlan
+ self.dut.send_expect("vlan %d del %d" % (index, vlan), "EthApp>")
+ # send same packet and make sure not received
+ pkt.config_layer('dot1q', {'vlan': vlan})
+ pkt.send_pkt(tx_port=intf)
+ time.sleep(2)
+ rx_pkts_del, _ = self.strip_portstats(port)
+ self.verify(rx_pkts_del == rx_pkts, "Failed to remove Rx vlan filter")
+
+ self.dut.send_expect("quit", "# ")
+ self.dut.send_expect("sed -i -e '/hw_vlan_filter=1;$/d' %s" % main_file, "# ")
+ # build sample app
+ self.build_ethtool()
+
+ def test_mac_address(self):
+ """
+ Test ethtool app mac function
+ """
+ valid_mac = "00:10:00:00:00:00"
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ mac = self.dut.ports_info[port]['mac']
+ dump_mac = self.strip_mac(index)
+ self.verify(mac == dump_mac, "Userspace tool failed to dump mac")
+ self.dut.send_expect("macaddr %d %s" % (port, valid_mac), "EthApp>")
+ dump_mac = self.strip_mac(index)
+ self.verify(dump_mac == valid_mac, "Userspace tool failed to set mac")
+ # check forwarded mac has been changed
+ pkt = Packet()
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ # send and sniff packet
+ inst = sniff_packets(intf, timeout=5)
+ pkt.send_pkt(tx_port=intf)
+ pkts = load_sniff_packets(inst)
+ self.verify(len(pkts) == 2, "Packet not forwarded as expected")
+ src_mac = pkts[1].strip_layer_element("layer2", "src")
+ self.verify(src_mac == valid_mac, "Forwarded packet not match default mac")
+
+ # check multicase will not be valid mac
+ invalid_mac = "01:00:00:00:00:00"
+ out = self.dut.send_expect("validate %s" % invalid_mac, "EthApp>")
+ self.verify("not unicast" in out, "Failed to detect incorrect unicast mac")
+ invalid_mac = "00:00:00:00:00:00"
+ out = self.dut.send_expect("validate %s" % invalid_mac, "EthApp>")
+ self.verify("not unicast" in out, "Failed to detect incorrect unicast mac")
+ out = self.dut.send_expect("validate %s" % valid_mac, "EthApp>")
+ self.verify("is unicast" in out, "Failed to detect correct unicast mac")
+ self.dut.send_expect("quit", "# ")
+
+ def test_port_config(self):
+ """
+ Test ethtool app port configure
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ ori_rx_pkts, _ = self.strip_portstats(index)
+ # stop port
+ self.dut.send_expect("stop %d" % index, "EthApp>")
+ # check packet not forwarded when port is stop
+ pkt = Packet()
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ pkt.send_pkt(tx_port=intf)
+ rx_pkts, tx_pkts = self.strip_portstats(index)
+ self.verify(rx_pkts == ori_rx_pkts, "Failed to stop port")
+ # restart port and check packet can normally forwarded
+ self.dut.send_expect("open %d" % index, "EthApp>")
+ # wait few time for port ready
+ time.sleep(0.5)
+ pkt.send_pkt(tx_port=intf)
+ rx_pkts_open, tx_pkts_open = self.strip_portstats(index)
+ self.verify(rx_pkts_open == rx_pkts + 1, "Failed to reopen port rx")
+ self.verify(tx_pkts_open == tx_pkts + 1, "Failed to reopen port tx")
+
+ self.dut.send_expect("quit", "# ")
+
+ def test_port_mtu(self):
+ """
+ Test ethtool app port mtu configure
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ mtus = [1519, 2048]
+ for index in range(len(self.ports)):
+ port = self.ports[index]
+ # change mtu
+ tester_port = self.tester.get_local_port(port)
+ intf = self.tester.get_interface(tester_port)
+ ori_mtu = self.strip_mtu(intf)
+ self.tester.send_expect("ifconfig %s mtu 9000" % (intf), "# ")
+ for mtu in mtus:
+ self.dut.send_expect("mtu %d %d" % (index, mtu), "EthApp>")
+ pkt_size = mtu + HEADER_SIZE['eth']
+ pkt = Packet(pkt_len=pkt_size)
+ pkt.send_pkt(tx_port=intf)
+ rx_pkts, _ = self.strip_portstats(index)
+ self.verify(rx_pkts == 1, "Packet match mtu not forwarded as expected")
+ pkt = Packet(pkt_len=mtu + 1)
+ pkt.send_pkt(tx_port=intf)
+ rx_pkts_over, _ = self.strip_portstats(index)
+ self.verify(rx_pkts == rx_pkts_over, "Packet over mtu should not be forwarded")
+
+ self.tester.send_expect("ifconfig %s mtu %d" % (intf, ori_mtu), "# ")
+
+ self.dut.send_expect("quit", "# ")
+
+ def test_perf_port_rx_pause(self):
+ """
+ Test ethtool app flow control configure
+ """
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ # enable pause rx
+ self.dut.send_expect("pause 0 rx", "EthApp")
+
+ # calculate number of packets
+ pps = self.wirespeed(self.nic, self.frame_size, 1) * 1000000.0
+ # get line rate
+ linerate = pps * (self.frame_size + 20) * 8
+ # calculate default sleep time for one pause frame
+ sleep = (1 / linerate) * self.pause_time * 512
+ # calculate packets dropped in sleep time
+ self.n_pkts = int((sleep / (1 / pps)) * (1 / self.pause_rate))
+
+ tgen_input = []
+ headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] + \
+ HEADER_SIZE['udp']
+ payload_size = self.frame_size - headers_size
+ self.tester.scapy_append('wrpcap("pause_rx.pcap", [Ether()/IP()/UDP()/("X"*%d)])' % payload_size)
+ self.tester.scapy_execute()
+ # rx and tx is the same port
+ tester_port = self.tester.get_local_port(self.ports[0])
+ tgen_input.append((tester_port, tester_port, "pause_rx.pcap"))
+
+ ori_func = self.config_stream
+ self.config_stream = self.config_stream_pause_rx
+ _, rx_pps = self.tester.traffic_generator_throughput(tgen_input)
+ self.config_stream = ori_func
+
+ rate = rx_pps / pps
+ # rate should same as expected rate
+ self.verify(rate > (self.pause_rate - 0.01) and
+ rate < (self.pause_rate + 0.01), "Failed to handle Rx pause frame")
+
+ self.dut.send_expect("quit", "# ")
+
+ def test_perf_port_tx_pause(self):
+ """
+ Test ethtool app flow control configure
+ """
+ # sleep a while when receive packets
+ main_file = "examples/ethtool/ethtool-app/main.c"
+ self.dut.send_expect("sed -i -e '/if (cnt_recv_frames > 0) {$/i\usleep(10);' %s" % main_file, "# ")
+ # build sample app
+ self.build_ethtool()
+ self.dut.send_expect(self.cmd, "EthApp>", 60)
+ # enable pause tx
+ self.dut.send_expect("pause 0 tx", "EthApp")
+
+ tgen_input = []
+ headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] + \
+ HEADER_SIZE['udp']
+ payload_size = self.frame_size - headers_size
+ self.tester.scapy_append('wrpcap("pause_tx.pcap", [Ether()/IP()/UDP()/("X"*%d)])' % payload_size)
+ self.tester.scapy_execute()
+ # rx and tx is the same port
+ tester_port = self.tester.get_local_port(self.ports[0])
+ tgen_input.append((tester_port, tester_port, "pause_tx.pcap"))
+
+ self.wirespeed(self.nic, self.frame_size, 1) * 1000000.0
+ _, tx_pps = self.tester.traffic_generator_throughput(tgen_input)
+
+ # verify ixia transmit line rate dropped
+ pps = self.wirespeed(self.nic, self.frame_size, 1) * 1000000.0
+ rate = tx_pps / pps
+ self.verify(rate < 0.1, "Failed to slow down transmit speed")
+
+ # verify received packets more than sent
+ self.stat_get_stat_all_stats(tester_port)
+ sent_pkts = self.get_frames_sent()
+ recv_pkts = self.get_frames_received()
+ self.verify((float(recv_pkts) / float(sent_pkts)) > 1.05, "Failed to transmit pause frame")
+
+ self.dut.send_expect("quit", "# ")
+ self.dut.send_expect("sed -i -e '/usleep(10);$/d' %s" % main_file, "# ")
+ # rebuild sample app
+ self.build_ethtool()
+
+ def config_stream_pause_rx(self, fpcap, txport, rate_percent, stream_id=1, latency=False):
+ """
+ Configure IXIA stream with pause frame and normal packet
+ """
+ # enable flow control on port
+ self.add_tcl_cmd("port config -flowControl true")
+ self.add_tcl_cmd("port config -flowControlType ieee8023x")
+ self.add_tcl_cmd("port set %d %d %d" % (self.chasId, txport['card'], txport['port']))
+
+ flows = self.parse_pcap(fpcap)
+
+ self.add_tcl_cmd("ixGlobalSetDefault")
+ self.add_tcl_cmd("stream config -rateMode usePercentRate")
+ self.add_tcl_cmd("stream config -percentPacketRate 100")
+ self.add_tcl_cmd("stream config -numBursts 1")
+ self.add_tcl_cmd("stream config -numFrames %d" % self.n_pkts)
+ self.add_tcl_cmd("stream config -dma advance")
+
+ pat = re.compile(r"(\w+)\((.*)\)")
+ for header in flows[0].split('/'):
+ match = pat.match(header)
+ params = eval('dict(%s)' % match.group(2))
+ method_name = match.group(1)
+ if method_name in SCAPY2IXIA:
+ method = getattr(self, method_name.lower())
+ method(txport, **params)
+
+ # stream id start from 1
+ self.add_tcl_cmd("stream set %d %d %d %d" % (self.chasId, txport['card'], txport['port'], 1))
+
+ # pause frame stream
+ self.add_tcl_cmd("stream config -rateMode usePercentRate")
+ self.add_tcl_cmd("stream config -percentPacketRate 100")
+ self.add_tcl_cmd("stream config -numBursts 1")
+ self.add_tcl_cmd("stream config -numFrames 1")
+ self.add_tcl_cmd("stream config -dma gotoFirst")
+
+ self.add_tcl_cmd("protocol setDefault")
+ self.add_tcl_cmd("protocol config -name pauseControl")
+ self.add_tcl_cmd("pauseControl setDefault")
+ self.add_tcl_cmd("pauseControl config -da \"01 80 C2 00 00 01\"")
+ self.add_tcl_cmd("pauseControl config -pauseTime %d" % self.pause_time)
+ self.add_tcl_cmd("pauseControl config -pauseControlType ieee8023x")
+ self.add_tcl_cmd("pauseControl set %d %d %d" % (self.chasId, txport['card'], txport['port']))
+ self.add_tcl_cmd("stream set %d %d %d %d" %
+ (self.chasId, txport['card'], txport['port'], 2))
+
+ def tear_down(self):
+ """
+ Run after each test case.
+ """
+ self.dut.kill_all()
+ pass
+
+ def tear_down_all(self):
+ """
+ Run after each test suite.
+ """
+ self.dut.kill_all()
--
1.9.3
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-01-26 1:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-26 1:48 [dts] [PATCH 1/2] test_plans: add test plan for userspace ethtool sample Yong Liu
2016-01-26 1:48 ` [dts] [PATCH 2/2] tests: add test suite " Yong Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).