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 A6B6FA04A3; Tue, 16 Jun 2020 05:20:53 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 96DF849E0; Tue, 16 Jun 2020 05:20:53 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 66F1025B3 for ; Tue, 16 Jun 2020 05:20:51 +0200 (CEST) IronPort-SDR: 1NftFbSHtbgWOSGz9mXTJ8y0v85bEY3NzS8F2bGhcNLA2Rgm3mOw9DmCfziFMsy/ft9DyGQO8z sanlMJEt7BZQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jun 2020 20:20:50 -0700 IronPort-SDR: PqhCUh0LdeW8SVbNrQaMkKird8DHRZP5KMSe5TxjdLKRTKGBSzHi4VrxoycMNNyNCyGvn4idek XV32m9B3rS1Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,517,1583222400"; d="scan'208";a="308329871" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga008.jf.intel.com with ESMTP; 15 Jun 2020 20:20:49 -0700 Received: from fmsmsx104.amr.corp.intel.com (10.18.124.202) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 15 Jun 2020 20:20:49 -0700 Received: from shsmsx103.ccr.corp.intel.com (10.239.4.69) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 15 Jun 2020 20:20:49 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.161]) by SHSMSX103.ccr.corp.intel.com ([10.239.4.69]) with mapi id 14.03.0439.000; Tue, 16 Jun 2020 11:20:46 +0800 From: "Chen, Zhaoyan" To: "Mo, YufengX" , "dts@dpdk.org" CC: "Chen, Zhaoyan" Thread-Topic: [dts][PATCH V3 1/1] tests/dcf_lifecycle: upload automation script Thread-Index: AQHWQ4avcllPqx5Oy0S5D1NLe8UNHqjakxnA Date: Tue, 16 Jun 2020 03:20:45 +0000 Message-ID: <9DEEADBC57E43F4DA73B571777FECECA41FE78C7@SHSMSX104.ccr.corp.intel.com> References: <20200616023450.16143-1-yufengx.mo@intel.com> <20200616023450.16143-2-yufengx.mo@intel.com> In-Reply-To: <20200616023450.16143-2-yufengx.mo@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-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 V3 1/1] tests/dcf_lifecycle: upload automation script 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" Acked-by: Chen, Zhaoyan > -----Original Message----- > From: Mo, YufengX > Sent: Tuesday, June 16, 2020 10:35 AM > To: dts@dpdk.org; Chen, Zhaoyan > Cc: Mo, YufengX > Subject: [dts][PATCH V3 1/1] tests/dcf_lifecycle: upload automation scrip= t >=20 >=20 > The DCF is a device configuration function (DCF - driver) bound to one of > the device's VFs which can act as a sole controlling entity to exercise > advance functionality (such as switch, ACL) for rest of the VNFs (virtual > network functions) under a DPDK based NFV deployment. >=20 > The DCF can act as a special VF talking to the kernel PF over the same > virtchannel mailbox to configure the underlying device (port) for the VFs= . >=20 > The test suite covers the lifecycle of DCF context in Kernel PF, such as > launch, and exit, switch rules handling, resetting, and exception exit. >=20 > Signed-off-by: yufengmx > --- > tests/TestSuite_dcf_lifecycle.py | 1175 > ++++++++++++++++++++++++++++++ > 1 file changed, 1175 insertions(+) > create mode 100644 tests/TestSuite_dcf_lifecycle.py >=20 > diff --git a/tests/TestSuite_dcf_lifecycle.py > b/tests/TestSuite_dcf_lifecycle.py > new file mode 100644 > index 0000000..90a56e6 > --- /dev/null > +++ b/tests/TestSuite_dcf_lifecycle.py > @@ -0,0 +1,1175 @@ > +# BSD LICENSE > +# > +# Copyright(c) 2010-2020 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 dcf life cycle. > + > +The DCF is a device configuration function (DCF - driver) bound to one > +of the device's VFs which can act as a sole controlling entity to > +exercise advance functionality (such as switch, ACL) for rest of the > +VNFs (virtual network functions) under a DPDK based NFV deployment. > + > +The DCF can act as a special VF talking to the kernel PF over the same > +virtchannel mailbox to configure the underlying device (port) for the VF= s. > + > +The test suite covers the lifecycle of DCF context in Kernel PF, such > +as launch, and exit, switch rules handling, resetting, and exception exi= t. > +""" > + > +import re > +import time > +import traceback > +from contextlib import contextmanager > +from pprint import pformat > +from functools import partial > + > + > +from settings import HEADER_SIZE > +from test_case import TestCase > +from exception import VerifyFailure > +from packet import Packet > +from pmd_output import PmdOutput > +import utils > + > + > +class TestDcfLifeCycle(TestCase): > + > + @property > + def target_dir(self): > + target_dir =3D '/root' + self.dut.base_dir[1:] \ > + if self.dut.base_dir.startswith('~') else \ > + self.dut.base_dir > + return target_dir > + > + def d_con(self, cmd): > + _cmd =3D [cmd, '# ', 15] if isinstance(cmd, str) else cmd > + return self.dut.send_expect(*_cmd) > + > + def d_a_con(self, cmds): > + if isinstance(cmds, str): > + _cmd =3D [cmds, '# ', 15] > + return self.dut.alt_session.send_expect(*_cmd) > + else: > + return [self.dut.alt_session.send_expect(_cmd, '# ', 10) > + for _cmd in cmds] > + > + def vf_pmd2_con(self, cmd): > + _cmd =3D [cmd, '# ', 15] if isinstance(cmd, str) else cmd > + return self.vf_pmd2_session.session.send_expect(*_cmd) > + > + def get_ip_layer(self): > + layer =3D {'ipv4': { > + 'src': '192.168.0.2', > + 'dst': '192.168.0.3', > + }, } > + return layer > + > + def get_mac_layer(self, dut_port_id=3D0, vf_id=3D0): > + dmac =3D self.vf_ports_info[dut_port_id]['vfs_mac'][vf_id] \ > + if vf_id is not None else self.dut.ports_info[dut_port_id]['= mac'] > + layer =3D {'ether': {'dst': dmac, }, } > + return layer > + > + def get_pkt_len(self): > + headers_size =3D sum([HEADER_SIZE[x] for x in ['eth', 'ip']]) > + pktlen =3D 64 - headers_size > + return pktlen > + > + def config_stream(self, dut_port_id=3D0, vf_id=3DNone): > + pkt_layers =3D {'raw': {'payload': ['58'] * self.get_pkt_len()}} > + pkt_layers.update(self.get_ip_layer()) > + pkt_layers.update(self.get_mac_layer(dut_port_id, vf_id)) > + pkt =3D Packet(pkt_type=3D'IP_RAW') > + for layer in list(pkt_layers.keys()): > + pkt.config_layer(layer, pkt_layers[layer]) > + self.logger.info(pkt.pktgen.pkt.command()) > + return pkt > + > + def send_packet_by_scapy(self, pkt, dut_port_id=3D0, count=3D1): > + tester_port_id =3D self.tester.get_local_port(dut_port_id) > + tx_iface =3D self.tester.get_interface(tester_port_id) > + pkt.send_pkt(crb=3Dself.tester, tx_port=3Dtx_iface, count=3Dcoun= t) > + > + def init_adq(self): > + cmds =3D [ > + "modprobe sch_mqprio", > + "modprobe act_mirred", > + "modprobe cls_flower", > + ] > + self.d_a_con(cmds) > + > + def set_adq_on_pf(self, dut_port_id=3D0): > + ''' > + Set ADQ on PF > + ''' > + msg =3D "Set ADQ on PF" > + self.logger.info(msg) > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmds =3D [ > + f"ethtool -K {intf} hw-tc-offload on", > + f"tc qdisc add dev {intf} ingress", > + f"tc qdisc show dev {intf}", > + f"tc qdisc add dev {intf} root mqprio num_tc 4 map 0 0 0 0 1= 1 1 1 > 2 2 2 2 3 3 3 3 queues 4@0 4@4 8@8 8@16 hw 1 mode channel", > + f"tc filter add dev {intf} protocol ip parent ffff: prio 1 f= lower dst_ip > 192.168.1.10 ip_proto tcp action gact pass", > + f"tc filter show dev {intf} parent ffff:", > + ] > + output =3D self.d_a_con(cmds) > + self.is_adq_set =3D True > + return output > + > + def remove_adq_on_pf(self, dut_port_id=3D0): > + ''' > + Remove ADQ on PF > + ''' > + if not self.is_adq_set: > + return > + msg =3D "Remove ADQ on PF" > + self.logger.info(msg) > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmds =3D [ > + f"tc filter del dev {intf} parent ffff: pref 1 protocol ip", > + f"tc filter show dev {intf} parent ffff:", > + f"tc qdisc del dev {intf} root mqprio", > + f"tc qdisc del dev {intf} ingress", > + f"tc qdisc show dev {intf}", > + f"ethtool -K {intf} hw-tc-offload off", > + ] > + self.d_a_con(cmds) > + self.is_adq_set =3D False > + > + def set_adq_mac_vlan(self, dut_port_id=3D0): > + ''' > + change the ADQ commands to MAC-VLAN > + ''' > + msg =3D "change the ADQ commands to MAC-VLAN" > + self.logger.info(msg) > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmds =3D [ > + f"ethtool -K {intf} l2-fwd-offload on", > + f"ip link add link macvlan0 link {intf} type macvlan", > + f"ip ad", > + f"ifconfig macvlan0 up", > + ] > + output =3D self.d_a_con(cmds) > + self.is_adq_set =3D True > + return output > + > + def remove_adq_mac_vlan(self, dut_port_id=3D0): > + ''' > + Remove MAC-VLAN commands > + ''' > + if not self.is_adq_set: > + return > + msg =3D "Remove MAC-VLAN commands" > + self.logger.info(msg) > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmds =3D [ > + "ip link del macvlan0", > + f"ethtool -K {intf} l2-fwd-offload off", > + ] > + self.d_a_con(cmds) > + self.is_adq_set =3D False > + > + def clear_dmesg(self): > + cmd =3D 'dmesg -C' > + self.d_a_con(cmd) > + > + def get_dmesg(self): > + cmd =3D 'dmesg --color=3Dnever' > + return self.d_a_con(cmd) or '' > + > + def vf_init(self): > + self.vf_ports_info =3D {} > + self.dut.setup_modules(self.target, 'vfio-pci', '') > + > + def vf_create(self): > + max_vfs =3D 4 > + for index, port_id in enumerate(self.dut_ports): > + port_obj =3D self.dut.ports_info[port_id]['port'] > + pf_driver =3D port_obj.default_driver > + self.dut.generate_sriov_vfs_by_port( > + port_id, max_vfs, driver=3Dpf_driver) > + pf_pci =3D port_obj.pci > + sriov_vfs_port =3D self.dut.ports_info[port_id].get('vfs_por= t') > + if not sriov_vfs_port: > + msg =3D f"failed to create vf on dut port {pf_pci}" > + self.logger.error(msg) > + continue > + for port in sriov_vfs_port: > + port.bind_driver(driver=3D'vfio-pci') > + vfs_mac =3D [ > + "00:12:34:56:{1}:{0}".format( > + str(vf_index).zfill(2), str(index + 1).zfill(2)) > + for vf_index in range(max_vfs)] > + self.vf_ports_info[port_id] =3D { > + 'pf_pci': pf_pci, > + 'vfs_pci': port_obj.get_sriov_vfs_pci(), > + 'vfs_mac': vfs_mac, > + 'src_mac': "02:00:00:00:00:0%d" % index, } > + self.logger.debug(pformat(self.vf_ports_info)) > + > + def vf_destroy(self): > + if not self.vf_ports_info: > + return > + for port_id, _ in self.vf_ports_info.items(): > + self.dut.destroy_sriov_vfs_by_port(port_id) > + port_obj =3D self.dut.ports_info[port_id]['port'] > + port_obj.bind_driver(self.drivername) > + self.vf_ports_info =3D None > + > + def vf_whitelist(self): > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[0] > + pf1_vf1 =3D self.vf_ports_info[0].get('vfs_pci')[1] > + pf1_vf2 =3D self.vf_ports_info[0].get('vfs_pci')[2] > + pf2_vf0 =3D self.vf_ports_info[1].get('vfs_pci')[0] \ > + if len(self.vf_ports_info) =3D=3D 2 else '' > + whitelist =3D { > + 'pf1_vf0_dcf': f"-w {pf1_vf0},cap=3Ddcf", > + 'pf1_vf1_dcf': f"-w {pf1_vf1},cap=3Ddcf", > + 'pf1_vf0_pf2_vf0_dcf': f"-w {pf1_vf0},cap=3Ddcf -w > {pf2_vf0},cap=3Ddcf", > + 'pf1_vf1_vf2': f"-w {pf1_vf1} -w {pf1_vf2}", > + 'pf1_vf1': f"-w {pf1_vf1}", > + 'pf2_vf0_dcf': f"-w {pf2_vf0},cap=3Ddcf", > + } > + return whitelist > + > + def vf_set_mac_addr(self, dut_port_id=3D0, vf_id=3D1): > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmd =3D f"ip link set {intf} vf 1 mac 00:01:02:03:04:05" > + self.d_a_con(cmd) > + self.vf_testpmd2_reset_port() > + > + def vf_set_trust(self, dut_port_id=3D0, vf_id=3D0, flag=3D'on'): > + ''' > + Set a VF as trust > + ''' > + intf =3D self.dut.ports_info[dut_port_id]['port'].intf_name > + cmd =3D f"ip link set {intf} vf {vf_id} trust {flag}" > + self.d_a_con(cmd) > + > + def vf_set_trust_off(self): > + ''' > + Turn off VF trust mode > + ''' > + self.vf_set_trust(flag=3D'off') > + > + def testpmd_set_flow_rule(self, dut_port_id=3D0, con_name=3D'vf_dcf'= ): > + ''' > + Set switch rule to VF from DCF > + ''' > + cmd =3D ( > + 'flow create ' > + '{port} ' > + 'priority 0 ' > + 'ingress pattern eth / ipv4 src is {ip_src} dst is {ip_dst} = / end ' > + 'actions vf id {vf_id} / end' > + ).format(**{ > + 'port': dut_port_id, > + 'vf_id': 1, > + 'ip_src': self.get_ip_layer()['ipv4']['src'], > + 'ip_dst': self.get_ip_layer()['ipv4']['dst'], > + }) > + > + con =3D self.d_con if con_name =3D=3D 'vf_dcf' else self.vf_pmd2= _con > + output =3D con([cmd, "testpmd> ", 15]) > + return output > + > + def init_vf_dcf_testpmd(self): > + self.vf_dcf_testpmd =3D "{}/{}/app/testpmd".format( > + self.target_dir, self.dut.target) > + > + def start_vf_dcf_testpmd(self, pmd_opiton): > + whitelist_name, prefix =3D pmd_opiton > + cores =3D self.corelist[:5] > + core_mask =3D utils.create_mask(cores) > + whitelist =3D self.vf_whitelist().get(whitelist_name) > + cmd =3D ( > + "{bin} " > + "-v " > + "-c {core_mask} " > + "-n {mem_channel} " > + "{whitelist} " > + "--file-prefix=3D{prefix} " > + "-- -i ").format(**{ > + 'bin': self.vf_dcf_testpmd, > + 'core_mask': core_mask, > + 'mem_channel': self.dut.get_memory_channels(), > + 'whitelist': whitelist, > + 'prefix': prefix, }) > + self.vf_dcf_pmd_start_output =3D self.d_con([cmd, "testpmd> ", 1= 20]) > + self.is_vf_dcf_pmd_on =3D True > + time.sleep(1) > + > + def close_vf_dcf_testpmd(self): > + if not self.is_vf_dcf_pmd_on: > + return > + try: > + self.d_con(['quit', '# ', 15]) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + self.is_vf_dcf_pmd_on =3D False > + > + def kill_vf_dcf_process(self): > + ''' > + Kill DCF process > + ''' > + cmd =3D "ps aux | grep testpmd" > + self.d_a_con(cmd) > + cmd =3D r"kill -9 `ps -ef | grep testpmd | grep -v grep | grep -= v > testpmd_vf | awk '{print $2}'`" > + self.d_a_con(cmd) > + self.is_vf_dcf_pmd_on =3D False > + time.sleep(2) > + cmd =3D "ps aux | grep testpmd" > + self.d_a_con(cmd) > + > + def vf_dcf_testpmd_set_flow_rule(self, dut_port_id=3D0): > + return self.testpmd_set_flow_rule(dut_port_id) > + > + def get_vf_dcf_testpmd_start_output(self): > + output =3D self.vf_dcf_pmd_start_output > + msg =3D "vf dcf testpmd boot up output is empty" > + self.verify(output, msg) > + return output > + > + def create_vf_testpmd2(self): > + self.vf_testpmd2 =3D "{}/{}/app/testpmd_vf".format( > + self.target_dir, self.dut.target) > + cmd =3D 'rm -f {vf_pmd2};cp {vf_dcf_pmd} {vf_pmd2}'.format( > + **{'vf_dcf_pmd': self.vf_dcf_testpmd, 'vf_pmd2': > self.vf_testpmd2}) > + self.d_a_con(cmd) > + > + def init_vf_testpmd2(self): > + self.create_vf_testpmd2() > + self.vf_pmd2_session_name =3D 'vf_testpmd2' > + self.vf_pmd2_session =3D self.dut.create_session( > + self.vf_pmd2_session_name) > + > + def start_vf_testpmd2(self, pmd_opiton): > + whitelist_name, prefix =3D pmd_opiton > + cores =3D self.corelist[5:] > + core_mask =3D utils.create_mask(cores) > + whitelist =3D self.vf_whitelist().get(whitelist_name) > + cmd =3D ( > + "{bin} " > + "-v " > + "-c {core_mask} " > + "-n {mem_channel} " > + "{whitelist} " > + "--file-prefix=3D{prefix} " > + "-- -i ").format(**{ > + 'bin': self.vf_testpmd2, > + 'core_mask': core_mask, > + 'mem_channel': self.dut.get_memory_channels(), > + 'whitelist': whitelist, > + 'prefix': prefix, }) > + self.vf_pmd2_start_output =3D self.vf_pmd2_con([cmd, "testpmd> "= , > 120]) > + self.is_vf_pmd2_on =3D True > + cmds =3D [ > + 'set verbose 1', > + 'set fwd mac', > + 'start'] if prefix =3D=3D 'vf' else ['start'] > + [self.vf_pmd2_con([cmd, "testpmd> ", 15]) for cmd in cmds] > + time.sleep(1) > + > + def close_vf_testpmd2(self): > + if not self.is_vf_pmd2_on: > + return > + try: > + self.vf_pmd2_con(['quit', '# ', 15]) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + self.is_vf_pmd2_on =3D False > + > + def vf_testpmd2_reset_port(self): > + if not self.is_vf_pmd2_on: > + return > + cmds =3D [ > + 'stop', > + 'port stop all', > + 'port reset all', > + 'port start all', > + 'start', > + ] > + [self.vf_pmd2_con([cmd, "testpmd> ", 15]) for cmd in cmds] > + > + def vf_testpmd2_set_flow_rule(self, dut_port_id=3D0): > + self.testpmd_set_flow_rule(dut_port_id, con_name=3D'vf2') > + > + def vf_pmd2_clear_port_stats(self): > + cmd =3D 'clear port stats all' > + self.vf_pmd2_con([cmd, "testpmd> ", 15]) > + > + def check_vf_pmd2_stats(self, traffic, portid=3D0, is_traffic_valid= =3DTrue): > + pmd =3D PmdOutput(self.dut, session=3Dself.vf_pmd2_session) > + info =3D pmd.get_pmd_stats(portid) or {} > + ori_pkt =3D info.get('RX-packets') or 0 > + traffic() > + info =3D pmd.get_pmd_stats(portid) or {} > + rx_pkt =3D info.get('RX-packets') or 0 > + check_pkt =3D rx_pkt - ori_pkt > + if is_traffic_valid: > + msg =3D f"port {portid} should receive packets, but no traff= ic > happen" > + self.verify(check_pkt and check_pkt > 0, msg) > + else: > + msg =3D f"port {portid} should not receive packets" > + self.verify(not check_pkt, msg) > + return rx_pkt > + > + def get_vf_testpmd2_start_output(self): > + output =3D self.vf_pmd2_start_output > + msg =3D "vf testpmd2 boot up output is empty" > + self.verify(output, msg) > + return output > + > + def check_vf_pmd2_traffic(self, func_name, topo=3DNone, flag=3DFalse= ): > + dut_port_id, vf_id =3D topo if topo else [0, 1] > + pkt =3D self.config_stream(dut_port_id, vf_id) > + traffic =3D partial(self.send_packet_by_scapy, pkt, dut_port_id,= 1) > + self.vf_pmd2_clear_port_stats() > + self.check_vf_pmd2_stats(traffic) > + status_change_func =3D getattr(self, func_name) > + status_change_func() > + self.check_vf_pmd2_stats(traffic, is_traffic_valid=3Dflag) > + > + def run_test_pre(self, pmd_opitons): > + pri_pmd_option =3D pmd_opitons[0] > + self.start_vf_dcf_testpmd(pri_pmd_option) > + if len(pmd_opitons) =3D=3D 1: # if only one pmd > + return > + slave_pmd_option =3D pmd_opitons[1] > + self.start_vf_testpmd2(slave_pmd_option) > + > + def run_test_post(self): > + # close all binary processes > + self.close_vf_testpmd2() > + self.close_vf_dcf_testpmd() > + time.sleep(5) > + > + def check_support_dcf_mode_01_result(self): > + dcf_output =3D self.get_vf_dcf_testpmd_start_output() > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[0] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf0} > (socket {self.socket})", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dcf_output, msg) > + > + def verify_support_dcf_mode_01(self): > + ''' > + Generate 1 trust VF on 1 PF, and request 1 DCF on the trust VF. > + PF should grant DCF mode to it. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'vf']] > + self.run_test_pre(pmd_opts) > + self.check_support_dcf_mode_01_result() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_support_dcf_mode_02_result(self): > + dcf_output =3D self.get_vf_dcf_testpmd_start_output() > + vf2_output =3D self.get_vf_testpmd2_start_output() > + # vf 1 testpmd > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[0] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf0} > (socket {self.socket})", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dcf_output, msg) > + # vf 2 testpmd > + pf2_vf0 =3D self.vf_ports_info[1].get('vfs_pci')[0] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf2_vf0} > (socket {self.socket})", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in vf2_output, msg) > + > + def verify_support_dcf_mode_02(self): > + ''' > + Generate 2 trust VFs on 2 PFs, each trust VF request DCF. > + Each PF should grant DCF mode to them. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + self.vf_set_trust(dut_port_id=3D1) > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf1'], ['pf2_vf0_dcf', 'dcf2= ']] > + self.run_test_pre(pmd_opts) > + self.check_support_dcf_mode_02_result() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_support_dcf_mode_03_result(self): > + dcf_output =3D self.get_vf_dcf_testpmd_start_output() > + dmesg_output =3D self.get_dmesg() > + # vf testpmd > + pf1_vf1 =3D self.vf_ports_info[0].get('vfs_pci')[1] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf1} > (socket {self.socket})", > + "ice_dcf_get_vf_resource(): Failed to get response of > OP_GET_VF_RESOURCE", > + "ice_dcf_init_hw(): Failed to get VF resource", > + "ice_dcf_dev_init(): Failed to init DCF hardware", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dcf_output, msg) > + # dmesg content > + pf1 =3D self.vf_ports_info[0].get('pf_pci') > + expected_strs =3D [ > + f"ice {pf1}: VF 1 requested DCF capability, but only VF 0 is= allowed > to request DCF capability", > + f"ice {pf1}: VF 1 failed opcode 3, retval: -5", > + ] > + msg =3D 'no dmesg output' > + self.verify(dmesg_output, msg) > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dmesg_output, msg) > + > + def verify_support_dcf_mode_03(self): > + except_content =3D None > + try: > + self.vf_set_trust(vf_id=3D1) > + self.clear_dmesg() > + pmd_opts =3D [['pf1_vf1_dcf', 'vf']] > + self.run_test_pre(pmd_opts) > + self.check_support_dcf_mode_03_result() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + self.vf_set_trust(vf_id=3D1, flag=3D'off') > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_support_dcf_mode_04_result(self): > + dcf_output =3D self.get_vf_dcf_testpmd_start_output() > + dmesg_output =3D self.get_dmesg() > + # vf testpmd > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[0] > + expected_strs =3D [ > + "ice_dcf_get_vf_resource(): Failed to get response of > OP_GET_VF_RESOURCE", > + "ice_dcf_init_hw(): Failed to get VF resource", > + "ice_dcf_dev_init(): Failed to init DCF hardware", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dcf_output, msg) > + # dmesg content > + pf1 =3D self.vf_ports_info[0].get('pf_pci') > + expected_strs =3D [ > + f"ice {pf1}: VF needs to be trusted to configure DCF capabil= ity", > + f"ice {pf1}: VF 0 failed opcode 3, retval: -5", > + ] > + msg =3D 'no dmesg output' > + self.verify(dmesg_output, msg) > + for expected_str in expected_strs: > + msg =3D "'{}' not display".format(expected_str) > + self.verify(expected_str in dmesg_output, msg) > + > + def verify_support_dcf_mode_04(self): > + except_content =3D None > + try: > + self.vf_set_trust_off() > + self.clear_dmesg() > + pmd_opts =3D [['pf1_vf0_dcf', 'vf']] > + self.run_test_pre(pmd_opts) > + self.check_support_dcf_mode_04_result() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_support_dcf_mode_05(self): > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf'], ['pf1_vf1', 'vf']] > + self.run_test_pre(pmd_opts) > + self.vf_dcf_testpmd_set_flow_rule() > + self.check_vf_pmd2_traffic('close_vf_dcf_testpmd') > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_handle_switch_filter_01(self): > + ''' > + If turn trust mode off, when DCF launched. The DCF rules should = be > removed. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf'], ['pf1_vf1', 'vf']] > + self.run_test_pre(pmd_opts) > + self.vf_dcf_testpmd_set_flow_rule() > + self.check_vf_pmd2_traffic('vf_set_trust_off') > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_handle_switch_filter_02(self): > + ''' > + If kill DCF process, when DCF launched. The DCF rules should be > removed. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf'], ['pf1_vf1', 'vf']] > + self.run_test_pre(pmd_opts) > + self.vf_dcf_testpmd_set_flow_rule() > + self.check_vf_pmd2_traffic('kill_vf_dcf_process', flag=3DTru= e) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_pmd2_create_dcf_failed(self, vf_id=3D0): > + vf2_output =3D self.get_vf_testpmd2_start_output() > + pf1_vf =3D self.vf_ports_info[0].get('vfs_pci')[vf_id] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf} > (socket {self.socket})", > + ] > + for expected_str in expected_strs: > + msg =3D "Expect: the second testpmd can't be launched" > + self.verify(expected_str not in vf2_output, msg) > + expected_strs =3D [ > + f"EAL: Requested device {pf1_vf} cannot be used" > + ] > + for expected_str in expected_strs: > + msg =3D "Expect: the second testpmd can't be launched" > + self.verify(expected_str in vf2_output, msg) > + > + def verify_handle_switch_filter_03(self): > + ''' > + Launch 2nd DCF process on the same VF, PF shall reject the reque= st. > + DPDK does not support to open 2nd DCF PMD driver on same VF. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf'], ['pf1_vf0_dcf', 'dcf2'= ]] > + self.run_test_pre(pmd_opts) > + self.check_pmd2_create_dcf_failed() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_handle_switch_filter_04(self): > + ''' > + If DCF enabled, one of VF reset. DCF shall clean up all the rule= s of this > VF. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf'], ['pf1_vf1', 'vf']] > + self.run_test_pre(pmd_opts) > + self.vf_dcf_testpmd_set_flow_rule() > + self.check_vf_pmd2_traffic('vf_set_mac_addr', flag=3DTrue) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_dcf_pmd_create_dcf_failed(self, vf_id=3D0): > + dcf_output =3D self.get_vf_dcf_testpmd_start_output() > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[vf_id] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf0} > (socket {self.socket})", > + "ice_dcf_get_vf_resource(): Failed to get response of > OP_GET_VF_RESOURCE", > + "ice_dcf_init_hw(): Failed to get VF resource", > + "ice_dcf_dev_init(): Failed to init DCF hardware", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display, PF should reject DCF > mode.".format(expected_str) > + self.verify(expected_str in dcf_output, msg) > + > + def check_dcf_pmd_create_dcf_success(self): > + output =3D self.get_vf_dcf_testpmd_start_output() > + pf1_vf0 =3D self.vf_ports_info[0].get('vfs_pci')[0] > + expected_strs =3D [ > + f"Probe PCI driver: net_ice_dcf ({self.dcf_dev_id}) device: = {pf1_vf0} > (socket {self.socket})", > + "ice_load_pkg_type(): Active package is", > + ] > + for expected_str in expected_strs: > + msg =3D "'{}' not display, DCF mode should be > grant".format(expected_str) > + self.verify(expected_str in output, msg) > + > + def verify_dcf_with_adq_01(self): > + ''' > + When ADQ set on PF, PF should reject the DCF mode. Remove the > ADQ setting, > + PF shall accept DCF mode. > + > + Host kernel version is required 4.19+, and MACVLAN offload shoul= d > be set off > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + self.set_adq_on_pf() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + # Expect: testpmd can't be launched. PF should reject DCF mo= de. > + self.run_test_pre(pmd_opts) > + self.check_dcf_pmd_create_dcf_failed() > + self.run_test_post() > + # Expect: testpmd can launch successfully. DCF mode can be g= rant > + self.remove_adq_on_pf() > + self.run_test_pre(pmd_opts) > + self.check_dcf_pmd_create_dcf_success() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_on_pf() > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_dcf_with_adq_failed_result(self, output): > + expected_strs =3D [ > + "Exclusivity flag on", > + "RTNETLINK answers: Operation not supported", ] > + for _output in output: > + if any(expected_str in output for expected_str in expected_s= trs): > + msg =3D "exclusive action occurs correctly" > + self.logger.info(msg) > + break > + else: > + msg =3D "Expect: ADQ command can't be success" > + self.verify(False, msg) > + > + def check_dcf_with_adq_result1(self, output): > + check_strs =3D [ > + "Exclusivity flag on", > + "RTNETLINK answers: Device or resource busy", ] > + for _output in output: > + status =3D all(check_str not in _output for check_str in che= ck_strs) > + msg =3D "ADQ setting on PF shall be successful, but failed" > + self.verify(status, msg) > + > + def verify_dcf_with_adq_02(self): > + ''' > + When DCF mode enabled, ADQ setting on PF shall fail. > + Exit DCF mode, ADQ setting on PF shall be successful. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + self.run_test_pre(pmd_opts) > + # Expect: ADQ command can't be success > + output =3D self.set_adq_on_pf() > + self.remove_adq_on_pf() > + self.run_test_post() > + self.check_dcf_with_adq_failed_result(output) > + # Expect: ADQ can be set. > + output =3D self.set_adq_on_pf() > + self.check_dcf_with_adq_result1(output) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_on_pf() > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_dcf_with_adq_03(self): > + ''' > + Configure the DCF on 1 PF port and configure ADQ on the other PF > port. > + Then turn off DCF, other PF's should not be impact. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + self.run_test_pre(pmd_opts) > + # run PF1 DCF mode, ADQ can be set. > + output =3D self.set_adq_on_pf(1) > + self.remove_adq_on_pf(1) > + self.run_test_post() > + self.check_dcf_with_adq_result1(output) > + # quit PF1 DCF mode, ADQ can be set. > + output =3D self.set_adq_on_pf(1) > + self.check_dcf_with_adq_result1(output) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_on_pf(1) > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_dcf_with_l2fwd_01(self): > + ''' > + When L2 forwarding set, PF should reject the DCF mode. > + Remove L2 forwarding set, PF shall accept the DCF mode. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + self.set_adq_mac_vlan() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + # Expect: testpmd can't be launched. PF should reject DCF mo= de. > + self.run_test_pre(pmd_opts) > + self.check_dcf_pmd_create_dcf_failed() > + self.run_test_post() > + # Expect: testpmd can launch successfully. DCF mode can be g= rant > + self.remove_adq_mac_vlan() > + self.run_test_pre(pmd_opts) > + self.check_dcf_pmd_create_dcf_success() > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_mac_vlan() > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def check_dcf_with_l2fwd_adp_failed_result(self, output): > + expected_str =3D "Could not change any device features" > + status =3D any(expected_str in _output for _output in output) > + msg =3D "When DCF mode enabled, PF should set L2 forwarding > failed." > + self.verify(status, msg) > + > + def check_dcf_with_l2fwd_adp_result(self, output): > + check_strs =3D [ > + "Exclusivity flag on", > + "RTNETLINK answers: Device or resource busy", ] > + for _output in output: > + status =3D all(check_str not in _output for check_str in che= ck_strs) > + msg =3D "PF should set L2 forwarding successful, but failed" > + self.verify(status, msg) > + > + def verify_dcf_with_l2fwd_02(self): > + ''' > + When DCF mode enabled, PF can't set L2 forwarding. > + Exit DCF mode, PF can set L2 forwarding. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + self.run_test_pre(pmd_opts) > + # When DCF mode enabled, PF can't set L2 forwarding. > + output =3D self.set_adq_mac_vlan() > + self.remove_adq_mac_vlan() > + self.run_test_post() > + self.check_dcf_with_l2fwd_adp_failed_result(output) > + # Exit DCF mode, PF can set L2 forwarding. > + output =3D self.set_adq_mac_vlan() > + self.check_dcf_with_l2fwd_adp_result(output) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_mac_vlan() > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_dcf_with_l2fwd_03(self): > + ''' > + Configure the DCF on 1 PF port and configure MAC-VLAN on the > other PF port. > + Then turn off DCF, other PF's MAC-VLAN filter should not be impa= ct. > + ''' > + except_content =3D None > + try: > + self.vf_set_trust() > + pmd_opts =3D [['pf1_vf0_dcf', 'dcf']] > + self.run_test_pre(pmd_opts) > + # run PF1 DCF mode, PF2 can set L2 forwarding. > + output =3D self.set_adq_mac_vlan(1) > + self.remove_adq_mac_vlan(1) > + self.run_test_post() > + self.check_dcf_with_l2fwd_adp_result(output) > + # Exit PF1 DCF mode, PF2 can set L2 forwarding. > + output =3D self.set_adq_mac_vlan(1) > + self.check_dcf_with_l2fwd_adp_result(output) > + except Exception as e: > + self.logger.error(traceback.format_exc()) > + except_content =3D e > + finally: > + self.remove_adq_mac_vlan(1) > + self.run_test_post() > + # re-raise verify exception result > + if except_content: > + raise VerifyFailure(except_content) > + > + def verify_supported_nic(self): > + supported_drivers =3D ['ice'] > + result =3D all([self.dut.ports_info[index]['port'].default_drive= r in > + supported_drivers > + for index in self.dut_ports]) > + msg =3D "current nic <{0}> is not supported".format(self.nic) > + self.verify(result, msg) > + > + def preset_pmd_res(self): > + self.dcf_dev_id =3D '8086:1889' > + self.socket =3D self.dut.get_numa_id(self.dut_ports[0]) > + self.corelist =3D self.dut.get_core_list( > + "1S/14C/1T", socket=3Dself.socket)[4:] > + > + def clear_flags(self): > + self.is_vf_dcf_pmd_on =3D self.is_vf_pmd2_on =3D False > + self.vf_dcf_pmd_start_output =3D self.vf_pmd2_start_output =3D N= one > + > + def init_suite(self): > + self.is_vf_dcf_pmd_on =3D self.is_vf_pmd2_on =3D self.is_adq_set= =3D \ > + self.vf_pmd2_session =3D None > + self.vf_dcf_pmd_start_output =3D self.vf_pmd2_start_output =3D N= one > + self.vf_init() > + > + def preset_test_environment(self): > + cmds =3D [ > + "uname -a", > + "modinfo ice | grep version:", ] > + self.d_a_con(cmds) > + self.init_adq() > + self.init_vf_dcf_testpmd() > + self.init_vf_testpmd2() > + self.preset_pmd_res() > + self.vf_create() > + > + def destroy_resource(self): > + try: > + self.vf_destroy() > + finally: > + msg =3D "close vf devices" > + self.logger.info(msg) > + if self.vf_pmd2_session: > + self.dut.close_session(self.vf_pmd2_session) > + self.vf_pmd2_session =3D None > + # > + # Test cases. > + # > + > + def set_up_all(self): > + """ > + Run at the start of each test suite. > + """ > + self.init_suite() > + self.dut_ports =3D self.dut.get_ports(self.nic) > + self.verify(len(self.dut_ports) >=3D 1, "Not enough ports") > + self.verify_supported_nic() > + # prepare testing environment > + self.preset_test_environment() > + > + def tear_down_all(self): > + """ > + Run after each test suite. > + """ > + self.destroy_resource() > + > + def set_up(self): > + """ > + Run before each test case. > + """ > + pass > + > + def tear_down(self): > + """ > + Run after each test case. > + """ > + self.dut.kill_all() > + self.clear_flags() > + > + def test_support_dcf_mode_01(self): > + ''' > + DCF on 1 trust VF on 1 PF > + ''' > + msg =3D "begin : DCF on 1 trust VF on 1 PF" > + self.logger.info(msg) > + self.verify_support_dcf_mode_01() > + > + def test_support_dcf_mode_02(self): > + ''' > + DCF on 2 PFs, 1 trust VF on each PF > + ''' > + self.verify(len(self.dut_ports) >=3D 2, "2 ports at least") > + msg =3D "begin : DCF on 2 PFs, 1 trust VF on each PF" > + self.logger.info(msg) > + self.verify_support_dcf_mode_02() > + > + def test_support_dcf_mode_03(self): > + ''' > + Check only VF zero can get DCF mode > + ''' > + msg =3D "begin : Check only VF zero can get DCF mode" > + self.logger.info(msg) > + self.verify_support_dcf_mode_03() > + > + def test_support_dcf_mode_04(self): > + ''' > + Check only trusted VF can get DCF mode > + ''' > + msg =3D "begin : Check only trusted VF can get DCF mode" > + self.logger.info(msg) > + self.verify_support_dcf_mode_04() > + > + def test_support_dcf_mode_05(self): > + ''' > + DCF graceful exit > + ''' > + msg =3D "begin : DCF graceful exit" > + self.logger.info(msg) > + self.verify_support_dcf_mode_05() > + > + def test_handle_switch_filter_01(self): > + ''' > + Turn trust mode off, when DCF launched > + ''' > + msg =3D "begin : Turn trust mode off, when DCF launched" > + self.logger.info(msg) > + self.verify_handle_switch_filter_01() > + > + def test_handle_switch_filter_02(self): > + ''' > + Kill DCF process > + ''' > + msg =3D "begin : Kill DCF process" > + self.logger.info(msg) > + self.verify_handle_switch_filter_02() > + > + def test_handle_switch_filter_03(self): > + ''' > + Launch 2nd DCF process on the same VF > + ''' > + msg =3D "begin : Launch 2nd DCF process on the same VF" > + self.logger.info(msg) > + self.verify_handle_switch_filter_03() > + > + def test_handle_switch_filter_04(self): > + ''' > + DCF enabled, one of VF reset > + ''' > + msg =3D "begin : DCF enabled, one of VF reset" > + self.logger.info(msg) > + self.verify_handle_switch_filter_04() > + > + def test_dcf_with_adq_01(self): > + ''' > + When ADQ set on PF, PF should reject the DCF mode > + ''' > + msg =3D "begin : When ADQ set on PF, PF should reject the DCF mo= de" > + self.logger.info(msg) > + self.verify_dcf_with_adq_01() > + > + def test_dcf_with_adq_02(self): > + ''' > + When DCF mode enabled, ADQ setting on PF shall fail > + ''' > + msg =3D "begin : When DCF mode enabled, ADQ setting on PF shall = fail" > + self.logger.info(msg) > + self.verify_dcf_with_adq_02() > + > + def test_dcf_with_adq_03(self): > + ''' > + DCF and ADQ can be enabled on different PF > + ''' > + self.verify(len(self.dut_ports) >=3D 2, "2 ports at least") > + msg =3D "begin : DCF and ADQ can be enabled on different PF" > + self.logger.info(msg) > + self.verify_dcf_with_adq_03() > + > + def test_dcf_with_l2fwd_01(self): > + ''' > + When L2 forwarding set, PF should reject the DCF mode > + ''' > + msg =3D "begin : When L2 forwarding set, PF should reject the DC= F > mode" > + self.logger.info(msg) > + self.verify_dcf_with_l2fwd_01() > + > + def test_dcf_with_l2fwd_02(self): > + ''' > + When DCF mode enabled, PF can't set L2 forwarding > + ''' > + msg =3D "begin : When DCF mode enabled, PF can't set L2 forwardi= ng" > + self.logger.info(msg) > + self.verify_dcf_with_l2fwd_02() > + > + def test_dcf_with_l2fwd_03(self): > + ''' > + DCF and L2 forwarding can be enabled on different PF > + ''' > + self.verify(len(self.dut_ports) >=3D 2, "2 ports at least") > + msg =3D "begin : DCF and L2 forwarding can be enabled on differe= nt > PF" > + self.logger.info(msg) > + self.verify_dcf_with_l2fwd_03() > -- > 2.21.0