From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E8A81A0353; Wed, 13 Nov 2019 07:42:38 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AFA334C99; Wed, 13 Nov 2019 07:42:38 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id BBFE8493D for ; Wed, 13 Nov 2019 07:42:36 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Nov 2019 22:42:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,299,1569308400"; d="scan'208";a="355387099" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga004.jf.intel.com with ESMTP; 12 Nov 2019 22:42:35 -0800 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 12 Nov 2019 22:42:35 -0800 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 12 Nov 2019 22:42:34 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 12 Nov 2019 22:42:34 -0800 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.213]) by shsmsx102.ccr.corp.intel.com ([169.254.2.108]) with mapi id 14.03.0439.000; Wed, 13 Nov 2019 14:42:33 +0800 From: "Ma, LihongX" To: "Xie, WeiX" , "dts@dpdk.org" CC: "Xie, WeiX" Thread-Topic: [dts] [PATCH V1] tests/port_representor:automation of port_representor Thread-Index: AQHVmHC6wFXbLzv0b0C0MXVDeREgPqeIoMjQ Date: Wed, 13 Nov 2019 06:42:33 +0000 Message-ID: References: <1573464076-20586-1-git-send-email-weix.xie@intel.com> In-Reply-To: <1573464076-20586-1-git-send-email-weix.xie@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dts] [PATCH V1] tests/port_representor:automation of port_representor X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Sender: "dts" Hi, xiewei Same comments as below. -----Original Message----- From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Xie Wei Sent: Monday, November 11, 2019 5:21 PM To: dts@dpdk.org Cc: Xie, WeiX Subject: [dts] [PATCH V1] tests/port_representor:automation of port_represe= ntor new automation of port_representor according to test plan Signed-off-by: Xie Wei --- tests/TestSuite_port_representor.py | 291 ++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 tests/TestSuite_port_representor.py diff --git a/tests/TestSuite_port_representor.py b/tests/TestSuite_port_rep= resentor.py new file mode 100644 index 0000000..eac8491 --- /dev/null +++ b/tests/TestSuite_port_representor.py @@ -0,0 +1,291 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2019 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without #=20 +modification, are permitted provided that the following conditions #=20 +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 #=20 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT #=20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR #=20 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT #=20 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #=20 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT #=20 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #=20 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #=20 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #=20 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #=20 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +Use two representor ports as the control plane to manage the two VFs,=20 +the control plane could change VFs behavior such as change promiscous=20 +mode, stats reset, etc. our statistical data information is independent=20 +on the control plane and data plane. +""" + +import time +import re + +from test_case import TestCase +from dut import Dut +from packet import Packet + + +class TestPortRepresentor(TestCase): + def set_up_all(self): + """ + Prerequisite steps for each test suite. + """ + self.verify(self.nic in ["fortville_eagle", "fortville_spirit", + "fortville_spirit_single", "fortville_25g= "], "NIC Unsupported: " + str(self.nic)) + self.dut_ports =3D self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >=3D 1, "Insufficient ports") + + self.session_secondary =3D self.dut.new_session() + self.session_third =3D self.dut.new_session() + + localPort =3D self.tester.get_local_port(self.dut_ports[0]) + self.tester_itf =3D self.tester.get_interface(localPort) + self.tester_mac =3D self.tester.get_mac(localPort) + self.pf_interface =3D self.dut.ports_info[self.dut_ports[0]]['intf= '] + self.pf_mac =3D self.dut.get_mac_address(0) + self.pf_pci =3D self.dut.ports_info[self.dut_ports[0]]['pci'] + + self.unicast_mac =3D "00:11:22:33:44:55" + + # This is to set up 1pf and 2vfs environment + # PF is bound to igb_uio, while VF is bound to vfio-pci. #Lihong: about the driver igb_uio, before run the suite, it is have been se= t in framework, so I think this step is uesless + self.dut.send_expect("modprobe uio", "#", 70) + self.dut.send_expect("insmod ./" + self.target + "/kmod/igb_uio.ko= ", "#", 60) + self.dut.send_expect("modprobe vfio-pci", "#", 70) + + self.dut.generate_sriov_vfs_by_port(self.dut_ports[0], 2, "igb_uio= ") + self.two_vfs_port =3D self.dut.ports_info[self.dut_ports[0]]["vfs_= port"] + try: + for port in self.two_vfs_port: + port.bind_driver(driver=3D"vfio-pci") + except Exception as e: + self.destroy_env() + raise Exception(e) + self.vfs_pci =3D=20 + self.dut.ports_info[self.dut_ports[0]]['sriov_vfs_pci'] + + def set_up(self): + """ + Run before each test case. + """ + self.vf_flag =3D 1 + + def destroy_env(self): + """ + This is to stop testpmd and destroy 1pf and 2vfs environment. + """ + if self.vf_flag =3D=3D 1: + self.session_third.send_expect("quit", "#") + time.sleep(3) + self.session_secondary.send_expect("quit", "#") + time.sleep(3) + self.dut.send_expect("quit", "#") + time.sleep(3) + else: + self.dut.send_expect("quit", "#") + self.vf_flag =3D 0 + + def testpmd_pf(self): # lihong: please do not use the hard core for lcores, and use the create_ea= l_parameters in dut to create the eal params to start testpmd + cmd_pf =3D "./%s/app/testpmd --lcores 1,2 -n 4 -w %s,representor= =3D0-1 --proc-type auto --file-prefix testpmd-pf -- -i --port-topology=3Dch= ained" % (self.target, self.pf_pci) #lihong: the expect word is 'testpmd>' + return self.dut.send_expect(cmd_pf, "testpmd", 120) + + def testpmd_vf0(self): # lihong: same as before + cmd_vf0 =3D "./%s/app/testpmd --lcores 3,4 -n 4 -w %s --proc-type = auto --file-prefix testpmd-vf0 -- -i" % (self.target, self.vfs_pci[0]) + self.out_vf0 =3D self.session_secondary.send_expect(cmd_vf0, "test= pmd>", 120) + pattern =3D re.compile(r"(([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})") + self.vf0_mac =3D pattern.search(self.out_vf0).group() + + def testpmd_vf1(self): + cmd_vf1 =3D "./%s/app/testpmd --lcores 5,6 -n 4 -w %s --proc-type = auto --file-prefix testpmd-vf1 -- -i" % (self.target, self.vfs_pci[1]) + self.out_vf1 =3D self.session_third.send_expect(cmd_vf1, "testpmd>= ", 120) + pattern =3D re.compile(r"(([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})") + self.vf1_mac =3D pattern.search(self.out_vf1).group() + + def test_port_representor_vf_stats_show_and_clear(self): + """ + use control testpmd to get and clear dataplane testpmd ports Stats + """ + self.testpmd_pf() # lihong : if all testpmd should use cmd 'set promisc all off', I think you= can put it in testpmd_pf/vf function. + self.dut.send_expect("set promisc 0 off", "testpmd>") + self.dut.send_expect("start", "testpmd>", 2) #lihong: if you want use the timesleep to wait link up, you can use the int= erface ' wait_link_status_up' in pmdout.py=20 + time.sleep(2) + self.testpmd_vf0() + self.session_secondary.send_expect("set promisc 0 off", "testpmd>"= ) + self.session_secondary.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf1() + self.session_third.send_expect("set promisc 0 off", "testpmd>") + self.session_third.send_expect("start", "testpmd>", 2) + time.sleep(2) + # check port stats in control testpmd + pkt1 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.pf_mac) + pkt2 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf0_mac) + pkt3 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf1_mac) + pkts =3D [pkt1, pkt2, pkt3] + p =3D Packet() + for i in pkts: + p.append_pkt(i) + p.send_pkt(self.tester, tx_port=3Dself.tester_itf, count=3D10) + + output_before =3D self.dut.send_expect("show port stats all", "tes= tpmd") + self.logger.info(output_before) + result_before =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(ou= tput_before, re.S) # lihong: some nic can not support the promisc, so I think you should modif= y you verify condition + self.verify(int(result_before[1]) =3D=3D 10 and int(result_before[= 2]) =3D=3D 10, "VF Stats show error") + # clear port stats in control testpmd + self.dut.send_expect("clear vf stats 0 0", "testpmd", 2) + self.dut.send_expect("clear vf stats 0 1", "testpmd", 2) + self.dut.send_expect("clear port stats all", "testpmd", 2) + time.sleep(1) # lihong: use the unified expect word 'testpmd>' + output_after =3D self.dut.send_expect("show port stats all", "test= pmd") + self.logger.info(output_after) + result_after =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(out= put_after, re.S) + self.verify(int(result_after[1]) =3D=3D 0 and int(result_after[2])= =20 + =3D=3D 0, "VF Stats clear error") + + def test_port_representor_vf_promiscous(self): + """ + use control testpmd to enable/disable dataplane testpmd ports prom= iscous mode + """ + self.testpmd_pf() + self.dut.send_expect("set promisc 0 off", "testpmd>") + self.dut.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf0() + self.session_secondary.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf1() + self.session_third.send_expect("start", "testpmd>", 2) + time.sleep(2) + + # vf promiscous enable + self.dut.send_expect("set promisc 1 on", "testpmd>") + pkt1 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.pf_mac) + pkt2 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf0_mac) + pkt3 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf1_mac) + pkt4 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.unicast_mac) + pkts =3D [pkt1, pkt2, pkt3, pkt4] + p =3D Packet() + for i in pkts: + p.append_pkt(i) + p.send_pkt(self.tester, tx_port=3Dself.tester_itf, count=3D10) + out_enable =3D self.dut.send_expect("show port stats all", "testpm= d") + self.logger.info(out_enable) + result_enable =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(ou= t_enable, re.S) + self.verify(int(result_enable[1]) =3D=3D 20 and=20 + int(result_enable[2]) =3D=3D 20, "VFs receive packets error") + + # clear port stats in control testpmd + self.dut.send_expect("clear vf stats 0 0", "testpmd", 2) + self.dut.send_expect("clear vf stats 0 1", "testpmd", 2) + self.dut.send_expect("clear port stats all", "testpmd", 2) + time.sleep(1) + + # vf promiscous disable + self.dut.send_expect("set promisc 1 off", "testpmd>") + p =3D Packet() + for i in pkts: + p.append_pkt(i) + p.send_pkt(self.tester, tx_port=3Dself.tester_itf, count=3D10) + out_disable =3D self.dut.send_expect("show port stats all", "testp= md") + self.logger.info(out_disable) + result_disable =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(o= ut_disable, re.S) + self.verify(int(result_disable[1]) =3D=3D 10 and=20 + int(result_disable[2]) =3D=3D 20, "VFs receive packets error") + + def test_port_representor_vf_mac_addr(self): + """ + use control testpmd to set vf mac address + """ + self.testpmd_pf() + self.dut.send_expect("mac_addr set 1 aa:11:22:33:44:55", "testpmd>= ") + self.dut.send_expect("mac_addr set 2 aa:22:33:44:55:66", "testpmd>= ") + self.dut.send_expect("set promisc 0 off", "testpmd>") + self.dut.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf0() + self.session_secondary.send_expect("set promisc 0 off", "testpmd>"= ) + self.session_secondary.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf1() + self.session_third.send_expect("set promisc 0 off", "testpmd>") + self.session_third.send_expect("start", "testpmd>", 2) + time.sleep(2) + # check port stats in control testpmd + pkt1 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.pf_mac) + pkt2 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf0_mac) + pkt3 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.vf1_mac) + pkt4 =3D 'Ether(src=3D"%s",dst=3D"%s")/IP()' % (self.tester_mac, s= elf.unicast_mac) + pkts =3D [pkt1, pkt2, pkt3, pkt4] + p =3D Packet() + for i in pkts: + p.append_pkt(i) + p.send_pkt(self.tester, tx_port=3Dself.tester_itf, count=3D10) + + out =3D self.dut.send_expect("show port stats all", "testpmd") + self.logger.info(out) + result =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(out, re.S= ) + self.verify(int(result[1]) =3D=3D 10 and int(result[2]) =3D=3D 10,= "VFs=20 + receive packets error") + + def test_port_representor_vlan_filter(self): + """ + use control testpmd to set vlan + """ + self.testpmd_pf() + self.dut.send_expect("set promisc 1 off", "testpmd>") + self.dut.send_expect("vlan set filter on 1", "testpmd>") + self.dut.send_expect("rx_vlan add 3 1", "testpmd>") + self.dut.send_expect("set promisc 2 off", "testpmd>") + self.dut.send_expect("vlan set filter on 2", "testpmd>") + self.dut.send_expect("rx_vlan add 4 2", "testpmd>") + self.dut.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf0() + self.session_secondary.send_expect("start", "testpmd>", 2) + time.sleep(2) + self.testpmd_vf1() + self.session_third.send_expect("start", "testpmd>", 2) + time.sleep(2) + + # check port stats in control testpmd + pkt1 =3D 'Ether(src=3D"%s",dst=3D"%s")/Dot1Q(vlan=3D3)/IP()' % (se= lf.tester_mac, self.vf0_mac) + pkt2 =3D 'Ether(src=3D"%s",dst=3D"%s")/Dot1Q(vlan=3D4)/IP()' % (se= lf.tester_mac, self.vf1_mac) + pkts =3D [pkt1, pkt2] + p =3D Packet() + for i in pkts: + p.append_pkt(i) + p.send_pkt(self.tester, tx_port=3Dself.tester_itf, count=3D10) + + out =3D self.dut.send_expect("show port stats all", "testpmd") + self.logger.info(out) + result =3D re.compile('RX-packets:\s+(.*?)\s+?').findall(out, re.S= ) + self.verify(int(result[1]) =3D=3D 10 and int(result[2]) =3D=3D 10,= "VFs=20 + receive packets error") + + def tear_down(self): + """ + Run after each test case. + """ + self.destroy_env() + + def tear_down_all(self): + """ + Run after each test suite. + """ + self.dut.kill_all() + self.dut.destroy_sriov_vfs_by_port(self.dut_ports[0]) + self.dut.close_session(self.session_secondary) + self.dut.close_session(self.session_third) -- 2.17.2