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 ED66FA2E1B for ; Wed, 4 Sep 2019 07:30:00 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E3BCA1EBB7; Wed, 4 Sep 2019 07:30:00 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 9A51B1EBAC for ; Wed, 4 Sep 2019 07:29:58 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Sep 2019 22:29:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,465,1559545200"; d="scan'208";a="183789879" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga007.fm.intel.com with ESMTP; 03 Sep 2019 22:29:57 -0700 Received: from fmsmsx606.amr.corp.intel.com (10.18.126.86) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 3 Sep 2019 22:29:56 -0700 Received: from fmsmsx606.amr.corp.intel.com (10.18.126.86) by fmsmsx606.amr.corp.intel.com (10.18.126.86) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 3 Sep 2019 22:29:56 -0700 Received: from shsmsx106.ccr.corp.intel.com (10.239.4.159) by fmsmsx606.amr.corp.intel.com (10.18.126.86) 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, 3 Sep 2019 22:29:56 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.92]) by SHSMSX106.ccr.corp.intel.com ([169.254.10.86]) with mapi id 14.03.0439.000; Wed, 4 Sep 2019 13:29:54 +0800 From: "Tu, Lijuan" To: "Zhao, MeijuanX" , "dts@dpdk.org" CC: "Lin, Xueqin" , "Zhao, MeijuanX" Thread-Topic: [dts] [PATCH V1] tests: add new test suite vm hotplug Thread-Index: AQHVXwoKpuaP9oqMUUS7MHA8RWaIjqcbBXLw Date: Wed, 4 Sep 2019 05:29:53 +0000 Message-ID: <8CE3E05A3F976642AAB0F4675D0AD20E0BB1C08A@SHSMSX101.ccr.corp.intel.com> References: <20190830160719.13174-1-meijuanx.zhao@intel.com> In-Reply-To: <20190830160719.13174-1-meijuanx.zhao@intel.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-ctpclassification: CTP_NT x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMWYwYzRhYWEtMzQyYy00Y2FmLWEwNmMtODFjOTkwNDljY2ZjIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiT05xY2FPNWxUOGs2ZU52QVwvTGVITmtkeUF1bEFoRXhlRjR4aWU2MzRmRFhzQkpRMDVabGdWZUdNamhTRFl1enkifQ== 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: add new test suite vm hotplug 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" Applied, thanks > -----Original Message----- > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of zhaomeijuan > Sent: Saturday, August 31, 2019 12:07 AM > To: dts@dpdk.org > Cc: Lin, Xueqin ; Zhao, MeijuanX > > Subject: [dts] [PATCH V1] tests: add new test suite vm hotplug >=20 > Signed-off-by: zhaomeijuan > --- > tests/TestSuite_vm_hotplug.py | 351 > ++++++++++++++++++++++++++++++++++ > 1 file changed, 351 insertions(+) > create mode 100644 tests/TestSuite_vm_hotplug.py >=20 > diff --git a/tests/TestSuite_vm_hotplug.py b/tests/TestSuite_vm_hotplug.p= y > new file mode 100644 index 0000000..87edad6 > --- /dev/null > +++ b/tests/TestSuite_vm_hotplug.py > @@ -0,0 +1,351 @@ > +# BSD LICENSE > +# > +# Copyright(c) <2019> 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 some vm hotplug function with vfio > + > +""" > + > +import re > +import time > +from qemu_kvm import QEMUKvm > +from test_case import TestCase > +from pmd_output import PmdOutput > + > +VM_CORES_MASK =3D 'all' > + > + > +class TestVmHotplug(TestCase): > + > + def set_up_all(self): > + > + self.dut_ports =3D self.dut.get_ports(self.nic) > + self.verify(len(self.dut_ports) > 1, "Insufficient ports") > + self.dut.restore_interfaces() > + tester_port =3D self.tester.get_local_port(self.dut_ports[0]) > + self.tester_intf =3D self.tester.get_interface(tester_port) > + > + self.ports =3D self.dut.get_ports() > + self.dut.send_expect('modprobe vfio-pci', '#') > + self.setup_pf_1vm_env_flag =3D 0 > + tester_port0 =3D self.tester.get_local_port(self.dut_ports[0]) > + tester_port1 =3D self.tester.get_local_port(self.dut_ports[1]) > + self.tester_intf0 =3D self.tester.get_interface(tester_port0) > + self.tester_intf1 =3D self.tester.get_interface(tester_port1) > + self.device =3D 0 > + self.test_pmd_flag =3D 1 > + # due to current dts framework is not support monitor stdio, > + # so start vm command is written with hardcode > + self.qemu_cmd =3D "taskset -c 0-7 qemu-system-x86_64 -enable-kvm= \ > + -pidfile /tmp/.vm0.pid \ > + -m 10240 -cpu host -smp 8 -name vm0 \ > + -monitor unix:/tmp/vm0_monitor.sock,server,nowait \ > + -chardev > socket,path=3D/tmp/vm0_qga0.sock,server,nowait,id=3Dvm0_qga0 \ > + -device virtio-serial \ > + -device > virtserialport,chardev=3Dvm0_qga0,name=3Dorg.qemu.guest_agent.0 \ > + -device e1000,netdev=3Dnttsip1 \ > + -netdev user,id=3Dnttsip1,hostfwd=3Dtcp:%s:6000-:22 \ > + -monitor stdio \ > + -drive file=3D/home/image/test_vfio.img \ > + -vnc :5 \ > + -device vfio-pci,host=3D%s,id=3Ddev1 \ > + " > + > + def start_vm(self, device=3D1): > + self.host_session =3D self.dut.new_session(suite=3D"host_session= ") > + self.dut.bind_interfaces_linux('vfio-pci', [self.ports[0]]) > + if device =3D=3D 2: > + self.dut.bind_interfaces_linux('vfio-pci', [self.ports[1]]) > + self.qemu_cmd +=3D '-device vfio-pci,host=3D%s,id=3Ddev2' > + cmd =3D self.qemu_cmd % (self.dut.get_ip_address(), > self.dut.ports_info[0]['pci'], self.dut.ports_info[1]['pci']) > + else: > + cmd =3D self.qemu_cmd % (self.dut.get_ip_address(), > self.dut.ports_info[0]['pci']) > + self.host_session.send_expect(cmd, "QEMU ") > + time.sleep(10) > + self.vm0_dut =3D self.connect_vm() > + self.verify(self.vm0_dut is not None, 'vm start fail') > + self.setup_pf_1vm_env_flag =3D 1 > + # load vfio > + self.vm0_dut.send_expect('modprobe -r vfio_iommu_type1', '#') > + self.vm0_dut.send_expect('modprobe -r vfio', '#') > + self.vm0_dut.send_expect('modprobe vfio > enable_unsafe_noiommu_mode=3D1', '#') > + self.vm0_dut.send_expect('modprobe vfio-pci', '#') > + # bind device to vfio > + netdev =3D self.vm0_dut.ports_info[0]['port'] > + netdev.bind_driver(driver=3D'vfio-pci') > + if device =3D=3D 2: > + netdev =3D self.vm0_dut.ports_info[1]['port'] > + netdev.bind_driver(driver=3D'vfio-pci') > + > + self.vm_session =3D self.vm0_dut.new_session(suite=3D"vm_session= ") > + self.vf_pci0 =3D self.vm0_dut.ports_info[0]['pci'] > + if device =3D=3D 2: > + self.vf_pci1 =3D self.vm0_dut.ports_info[1]['pci'] > + self.vm0_dut.get_ports('any') > + self.vm_testpmd =3D PmdOutput(self.vm0_dut) > + > + def connect_vm(self): > + self.vm0 =3D QEMUKvm(self.dut, 'vm0', 'vm_hotplug') > + self.vm0.net_type =3D 'hostfwd' > + self.vm0.hostfwd_addr =3D '%s:6000' % self.dut.get_ip_address() > + self.vm0.def_driver =3D 'igb_uio' > + self.wait_vm_net_ready() > + vm_dut =3D self.vm0.instantiate_vm_dut(autodetect_topo=3DFalse) > + if vm_dut: > + return vm_dut > + else: > + return None > + > + def wait_vm_net_ready(self): > + self.vm_net_session =3D self.dut.new_session(suite=3D'vm_net_ses= sion') > + self.start_time =3D time.time() > + cur_time =3D time.time() > + time_diff =3D cur_time - self.start_time > + while time_diff < 120: > + try: > + out =3D self.vm_net_session.send_expect('~/QMP/qemu-ga-c= lient -- > address=3D/tmp/vm0_qga0.sock ifconfig', '#') > + except Exception, EnvironmentError: > + pass > + if '10.0.2' in out: > + break > + time.sleep(1) > + cur_time =3D time.time() > + time_diff =3D cur_time - self.start_time > + self.dut.close_session(self.vm_net_session) > + > + def set_up(self): > + # according to nic number starts vm > + if self.device =3D=3D 1: > + if 'two' in self.running_case: > + self.device =3D 2 > + self.destroy_pf_1vm_env() > + self.dut.restore_interfaces() > + self.start_vm(self.device) > + elif self.device =3D=3D 0: > + if 'two' in self.running_case: > + self.device =3D 2 > + else: > + self.device =3D 1 > + self.start_vm(self.device) > + else: > + if 'two' in self.running_case: > + pass > + else: > + self.destroy_pf_1vm_env() > + self.dut.restore_interfaces() > + self.start_vm(self.device) > + > + def test_one_device_hotplug(self): > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + # add cycle for del/add device > + for i in range(3): > + self.host_session.send_expect('device_del dev1', '(qemu)') > + time.sleep(2) > + self.check_vf_device(has_device=3DFalse) > + self.add_pf_device_qemu(device=3D1) > + out =3D self.vm_testpmd.execute_cmd('port attach %s' % > self.vm0_dut.ports_info[0]['pci']) > + self.verify('Port 0 is attached' in out, 'attach device fail= ') > + self.verify_rxtx_only() > + self.vm_testpmd.execute_cmd('quit', '#') > + time.sleep(1) > + > + def test_one_device_reset_hotplug(self): > + for i in range(3): > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + # del device > + self.host_session.send_expect('device_del dev1', '(qemu)') > + self.vm_testpmd.execute_cmd('quit', '#') > + self.check_vf_device(has_device=3DFalse) > + self.add_pf_device_qemu(device=3D1) > + > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + self.vm_testpmd.execute_cmd('quit', '#') > + > + def test_two_device_hotplug(self): > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + # add cycle for del or add device > + for i in range(3): > + self.host_session.send_expect('device_del dev1', '(qemu)') > + self.host_session.send_expect('device_del dev2', '(qemu)') > + time.sleep(1) > + self.check_vf_device(has_device=3DFalse, device=3D2) > + self.add_pf_device_qemu(device=3D2) > + out =3D self.vm_testpmd.execute_cmd('port attach %s' % > self.vm0_dut.ports_info[0]['pci']) > + self.verify('Port 0 is attached' in out, 'attach device fail= ') > + out =3D self.vm_testpmd.execute_cmd('port attach %s' % > self.vm0_dut.ports_info[1]['pci']) > + self.verify('Port 1 is attached' in out, 'attach device fail= ') > + self.verify_rxtx_only() > + self.vm_testpmd.execute_cmd('quit', '#') > + > + def test_two_device_reset_hotplug(self): > + for i in range(3): > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + # del device > + self.host_session.send_expect('device_del dev1', '(qemu)') > + self.host_session.send_expect('device_del dev2', '(qemu)') > + self.vm_testpmd.execute_cmd('quit', '#') > + time.sleep(1) > + > + self.check_vf_device(has_device=3DFalse, device=3D2) > + self.add_pf_device_qemu(device=3D2) > + > + self.vm_testpmd.start_testpmd('all', '--hot-plug') > + self.verify_rxtx_only() > + self.vm_testpmd.execute_cmd('quit', '#') > + > + def start_tcpdump(self, iface_list): > + for iface in iface_list: > + self.tester.send_expect("rm -rf tcpdump%s.out" % iface, "#") > + self.tester.send_expect("tcpdump -i %s 2>tcpdump%s.out &" % > (iface, iface), "#") > + time.sleep(1) > + > + def get_tcpdump_package(self, iface_list): > + self.tester.send_expect("killall tcpdump", "#") > + result =3D [] > + for iface in iface_list: > + out =3D self.tester.send_expect("cat tcpdump%s.out" % iface,= "#", > timeout=3D60) > + cap_num =3D re.findall('(\d+) packets', out) > + result.append(cap_num[0]) > + return result > + > + def verify_rxtx_only(self): > + # rxonly > + self.vm_testpmd.execute_cmd('set fwd rxonly') > + self.vm_testpmd.execute_cmd('set verbose 1') > + self.vm_testpmd.execute_cmd('port start all') > + self.vm_testpmd.execute_cmd('start') > + time.sleep(1) > + > + self.send_packet() > + out =3D self.vm0_dut.get_session_output() > + self.verify(self.vf0_mac in out, 'vf0 receive packet fail') > + if self.device =3D=3D 2: > + self.verify(self.vf1_mac in out, 'vf1 receive packet fail') > + # txonly > + self.vm_testpmd.execute_cmd('stop') > + self.vm_testpmd.execute_cmd('set fwd txonly') > + iface_list =3D [] > + iface_list.append(self.tester_intf0) > + if self.device =3D=3D 2: > + iface_list.append(self.tester_intf1) > + self.start_tcpdump(iface_list) > + self.vm_testpmd.execute_cmd('start') > + time.sleep(1) > + self.vm_testpmd.execute_cmd('stop') > + out =3D self.get_tcpdump_package(iface_list) > + for pkt_num in out: > + # rule out miscellaneous package possibility > + self.verify(pkt_num > 1000, 'vf send packet fail') > + > + def check_vf_device(self, has_device=3DTrue, device=3D1): > + time.sleep(1) > + sign =3D 'Connection' > + if self.nic.startswith('fortville'): > + sign =3D 'Ethernet' > + out =3D self.vm_session.send_expect('./usertools/dpdk-devbind.py= -s | > grep %s' % sign, '#') > + time.sleep(2) > + if has_device: > + self.verify(self.vf_pci0 in out, 'no vf device') > + if device =3D=3D 2: > + self.verify(self.vf_pci1 in out, 'no vf device') > + else: > + self.verify(self.vf_pci0 not in out, 'have vf device') > + if device =3D=3D 2: > + self.verify(self.vf_pci1 not in out, 'have vf device') > + > + def add_pf_device_qemu(self, device=3D1): > + self.host_session.send_expect('device_add vfio-pci,host=3D%s,id= =3Ddev1' % > self.dut.ports_info[0]['pci'], '(qemu)') > + if device =3D=3D 2: > + self.host_session.send_expect('device_add vfio- > pci,host=3D%s,id=3Ddev2' % self.dut.ports_info[1]['pci'], '(qemu)') > + self.check_vf_device(has_device=3DTrue, device=3Ddevice) > + self.vm_session.send_expect('./usertools/dpdk-devbind.py -b vfio= - > pci %s' % self.vf_pci0, '#') > + if device =3D=3D 2: > + self.vm_session.send_expect('./usertools/dpdk-devbind.py -b = vfio- > pci %s' % self.vf_pci1, '#') > + time.sleep(1) > + > + def send_packet(self): > + self.vf0_mac =3D self.vm_testpmd.get_port_mac(0) > + pkts =3D [] > + pkt1 =3D r'sendp([Ether(dst=3D"%s")/IP()/UDP()/Raw(load=3D"P"*26= )], > iface=3D"%s")' % (self.vf0_mac, self.tester_intf) > + pkts.append(pkt1) > + if self.device =3D=3D 2: > + self.vf1_mac =3D self.vm_testpmd.get_port_mac(1) > + pkt2 =3D r'sendp([Ether(dst=3D"%s")/IP()/UDP()/Raw(load=3D"P= "*26)], > iface=3D"%s")' % (self.vf1_mac, self.tester_intf) > + pkts.append(pkt2) > + for pkt in pkts: > + > + self.tester.scapy_append(pkt) > + self.tester.scapy_execute() > + time.sleep(2) > + > + def destroy_pf_1vm_env(self): > + if getattr(self, 'vm0', None): > + self.vm0_dut.close_session(self.vm_session) > + try: > + self.vm0.stop() > + except Exception: > + pass > + self.dut.send_expect('killall qemu-system-x86_64', '#') > + time.sleep(1) > + out =3D self.dut.send_expect('ps -ef |grep qemu', '#') > + if self.dut.get_ip_address() in out: > + self.dut.send_expect('killall qemu-system-x86_64', '#') > + self.vm0 =3D None > + self.setup_pf_1vm_env_flag =3D 0 > + self.dut.close_session(self.host_session) > + self.host_session =3D None > + self.vm_session =3D None > + > + self.dut.virt_exit() > + > + if getattr(self, 'used_dut_port', None): > + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port) > + port =3D self.dut.ports_info[self.used_dut_port]['port'] > + port.bind_driver() > + self.used_dut_port =3D None > + > + for port_id in self.dut_ports: > + port =3D self.dut.ports_info[port_id]['port'] > + port.bind_driver() > + > + def tear_down(self): > + self.add_pf_device_qemu(self.device) > + > + def tear_down_all(self): > + self.destroy_pf_1vm_env() > -- > 2.17.1