From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id F0FDD4F94 for ; Thu, 28 Feb 2019 09:40:36 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2019 00:40:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,422,1544515200"; d="scan'208";a="130019751" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga003.jf.intel.com with ESMTP; 28 Feb 2019 00:40:35 -0800 Received: from shsmsx103.ccr.corp.intel.com (10.239.4.69) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 28 Feb 2019 00:40:34 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.74]) by SHSMSX103.ccr.corp.intel.com ([169.254.4.134]) with mapi id 14.03.0415.000; Thu, 28 Feb 2019 16:40:33 +0800 From: "Chen, Zhaoyan" To: "Mo, YufengX" , "dts@dpdk.org" CC: "Mo, YufengX" , "Chen, Zhaoyan" Thread-Topic: [dts] [PATCH V2]pmd_stacked_bonded: upload automation script Thread-Index: AQHUzysmO2mwRQ5yV06GIuCMNFkYDKX0MjAAgACx/NA= Date: Thu, 28 Feb 2019 08:40:32 +0000 Message-ID: <9DEEADBC57E43F4DA73B571777FECECA41C5A18F@SHSMSX104.ccr.corp.intel.com> References: <1551333708-34248-1-git-send-email-yufengx.mo@intel.com> <1551333708-34248-2-git-send-email-yufengx.mo@intel.com> In-Reply-To: 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.0.400.15 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 V2]pmd_stacked_bonded: 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: , X-List-Received-Date: Thu, 28 Feb 2019 08:40:37 -0000 Acked-by: Chen, Zhaoyan Regards, Zhaoyan Chen > -----Original Message----- > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Mo, YufengX > Sent: Thursday, February 28, 2019 2:03 PM > To: dts@dpdk.org > Cc: Mo, YufengX > Subject: Re: [dts] [PATCH V2]pmd_stacked_bonded: upload automation script >=20 >=20 >=20 > Tested-by: Mo, YufengX >=20 > > -----Original Message----- > > From: Mo, YufengX > > Sent: Thursday, February 28, 2019 2:02 PM > > To: dts@dpdk.org > > Cc: Mo, YufengX > > Subject: [dts][PATCH V2]pmd_stacked_bonded: upload automation script > > > > > > This automation script is for pmd stacked bonded feature. > > > > Allow bonded devices to be stacked to allow two or more bonded devices > > to be bonded into one master bonded device > > > > Signed-off-by: yufengmx > > --- > > tests/TestSuite_pmd_stacked_bonded.py | 531 > > ++++++++++++++++++++++++++++++++++ > > 1 file changed, 531 insertions(+) > > create mode 100644 tests/TestSuite_pmd_stacked_bonded.py > > > > diff --git a/tests/TestSuite_pmd_stacked_bonded.py > > b/tests/TestSuite_pmd_stacked_bonded.py > > new file mode 100644 > > index 0000000..e1ce01a > > --- /dev/null > > +++ b/tests/TestSuite_pmd_stacked_bonded.py > > @@ -0,0 +1,531 @@ > > +# 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 > > +# 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 copyrigh= t > > +# 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. > > + > > +import time > > +import traceback > > + > > +# import dts/framework libs > > +import utils > > +from test_case import TestCase > > +from exception import VerifyFailure > > + > > +# import bonding lib > > +import bonding > > +from bonding import ( > > + MODE_ROUND_ROBIN, > > + MODE_ACTIVE_BACKUP, > > + MODE_XOR_BALANCE, > > + MODE_BROADCAST, > > + MODE_LACP, > > + MODE_TLB_BALANCE, > > + MODE_ALB_BALANCE, > > + FRAME_SIZE_64) > > + > > +class TestBondingStacked(TestCase): > > + > > + # > > + # On dut, dpdk bonding > > + # > > + def check_bonded_device_queue_config(self, *devices): > > + ''' > > + check if master bonded device/slave device queue configuration > > + is the same. > > + ''' > > + # get master bonded device queue configuration > > + master =3D self.bond_inst.get_port_info(devices[0], 'queue_con= fig') > > + # get slave device queue configuration > > + for port_id in devices[1:]: > > + config =3D self.bond_inst.get_port_info(port_id, 'queue_co= nfig') > > + if cmp(config, master) =3D=3D 0: > > + continue > > + msg =3D ("slave bonded port [{0}] is " > > + "different to top bonded port [{1}]").format( > > + port_id, devic= es[0]) > > + raise VerifyFailure('bonded device queue config:: ' + > > + msg) > > + > > + def set_stacked_bonded(self, slaveGrpOne, slaveGrpTwo, bond_mode, > > + ignore=3DFalse): > > + ''' > > + set stacked bonded mode for a custom bonding mode > > + ''' > > + inst =3D self.bond_inst > > + socket_id =3D self.dut.get_numa_id(self.bond_slave) > > + # create first bonded device 1, add slaves in it > > + bond_port_1 =3D inst.create_bonded_device(bond_mode, socket_id= ) > > + inst.add_slave(bond_port_1, False, '', *slaveGrpOne) > > + # create second bonded device 2, add slaves in it > > + bond_port_2 =3D inst.create_bonded_device(bond_mode, socket_id= ) > > + inst.add_slave(bond_port_2, False, '', *slaveGrpTwo) > > + # create master bonded device 3, which is the top bonded devic= e > > + master_bond_port =3D inst.create_bonded_device(bond_mode, sock= et_id) > > + # add bond bonded device 1 to bonded device 3 > > + # check bonding config status > > + inst.add_slave(master_bond_port, False, '', *[bond_port_1]) > > + # add bonded device 2 to bonded device 3 > > + # check bonding config status > > + inst.add_slave(master_bond_port, False, '', *[bond_port_2]) > > + # check if master bonding/each slaves queue configuration is t= he same. > > + if not ignore: > > + self.check_bonded_device_queue_config(*[master_bond_port, > > + bond_port_1, > > + bond_port_2]) > > + > > + return [bond_port_1, bond_port_2, master_bond_port] > > + > > + def set_third_stacked_bonded(self, bond_port, bond_mode): > > + ''' > > + set third level stacked bonded to check if stacked level can b= e set > > + more than 2 > > + ''' > > + inst =3D self.bond_inst > > + socket_id =3D self.dut.get_numa_id(self.bond_slave) > > + third_bond_port =3D inst.create_bonded_device(bond_mode, socke= t_id) > > + inst.add_slave(third_bond_port, False, '', *[bond_port]) > > + > > + def duplicate_add_stacked_bonded(self, bond_port_1, bond_port_2, > > + master_bond_port): > > + ''' > > + check if adding duplicate stacked bonded device is forbidden > > + ''' > > + inst =3D self.bond_inst > > + # check exception process > > + expected_str =3D 'Slave device is already a slave of a bonded = device' > > + # add bonded device 1 to bonded device 3 > > + # check bonding config status > > + inst.add_slave(master_bond_port, False, expected_str, *[bond_p= ort_1]) > > + # add bonded device 2 to bonded device 3 > > + # check bonding config status > > + inst.add_slave(master_bond_port, False, expected_str, > > + *[bond_port_2]) > > + > > + def preset_stacked_bonded(self, slaveGrpOne, slaveGrpTwo, bond_mod= e): > > + bond_port_1, bond_port_2, master_bond_port =3D self.set_stacke= d_bonded( > > + slaveG= rpOne, > > + slaveG= rpTwo, > > + bond_m= ode, > > + ignore= =3DTrue) > > + portList =3D [slaveGrpOne[0], > > + slaveGrpTwo[0], > > + bond_port_1, > > + bond_port_2, > > + master_bond_port] > > + cmds =3D [ > > + ["port stop all", ''], > > + ["set portlist " + ",".join([str(port) for port in portLis= t]), ''], > > + ["port start all", ' ', 15]] > > + self.bond_inst.d_console(cmds) > > + # blank space command is used to skip LSC event to avoid core = dumped > issue > > + time.sleep(5) > > + cmds =3D [ [' ', ''], > > + ["start", '']] > > + self.bond_inst.d_console(cmds) > > + time.sleep(5) > > + > > + return bond_port_1, bond_port_2, master_bond_port > > + > > + # > > + # packet transmission > > + # > > + def traffic(self, traffic_config, ports): > > + # get ports statistics before sending packets > > + stats_pre =3D self.bond_inst.get_all_stats(ports) > > + # send packets > > + self.bond_inst.send_packet(traffic_config) > > + # get ports statistics after sending packets > > + stats_post =3D self.bond_inst.get_all_stats(ports) > > + # calculate ports statistics result > > + for port_id in ports: > > + stats_post[port_id]['RX-packets'] -=3D stats_pre[port_id][= 'RX-packets'] > > + stats_post[port_id]['TX-packets'] -=3D > > + stats_pre[port_id]['TX-packets'] > > + > > + return stats_post > > + > > + def config_port_traffic(self, tx_port, rx_port, total_pkt): > > + ''' set traffic configuration ''' > > + traffic_config =3D { > > + 'port topo': [tx_port, rx_port], > > + 'stream': self.bond_inst.set_stream_to_slave_port(rx_port)= , > > + 'traffic configs': { > > + 'count': total_pkt, > > + },} > > + > > + return traffic_config > > + > > + def active_slave_rx(self, slave, bond_port, mode): > > + msg =3D "send packet to active slave port <{0}>".format(slave) > > + self.logger.info(msg) > > + tx_intf =3D self.tester.get_interface( > > + self.tester.get_local_port(self.dut_ports[slav= e])) > > + # get traffic config > > + traffic_config =3D self.config_port_traffic(tx_intf, slave,sel= f.total_pkt) > > + # select ports for statistics > > + ports =3D [slave, bond_port] > > + # run traffic > > + stats =3D self.traffic(traffic_config, ports) > > + # check slave statistics > > + msg =3D "port <{0}> Data not received by port <{1}>".format( > > + tx_intf, slave) > > + # here using `>=3D` to ignore some miscellaneous packets, e.g.= lldp > > + self.verify(stats[slave]['RX-packets'] >=3D self.total_pkt, ms= g) > > + msg =3D "tester port {0} <----> dut port {1} is ok".format( > > + tx_intf, slave= ) > > + self.logger.info(msg) > > + # check bond port statistics > > + # here using `>=3D` to ignore some miscellaneous packets, e.g.= lldp > > + self.verify(stats[slave]['RX-packets'] >=3D self.total_pkt, > > + "Bond port have error RX packet in XOR") > > + > > + def inactive_slave_rx(self, slave, bond_port, mode): > > + msg =3D "send packet to inactive slave port <{0}>".format(slav= e) > > + self.logger.info(msg) > > + tx_intf =3D self.tester.get_interface( > > + self.tester.get_local_port(self.dut_ports[slav= e])) > > + # get traffic config > > + traffic_config =3D self.config_port_traffic(tx_intf, slave,sel= f.total_pkt) > > + # select ports for statistics > > + ports =3D [slave, bond_port] > > + # run traffic > > + stats =3D self.traffic(traffic_config, ports) > > + # check slave statistics > > + msg =3D ("port <{0}> Data received by port <{1}>, " > > + "but should not.").format(tx_intf, slave) > > + self.verify(stats[slave]['RX-packets'] =3D=3D 0, msg) > > + msg =3D "tester port {0} <-| |-> dut port {1} is blocked".fo= rmat( > > + tx_int= f, slave) > > + self.logger.info(msg) > > + # check bond port statistics > > + self.verify(stats[slave]['RX-packets'] =3D=3D 0, > > + "Bond port have error RX packet in > > + {0}".format(mode)) > > + > > + def check_traffic_with_one_slave_down(self, mode): > > + """ > > + Verify that transmitting packets correctly when set one slave = of > > + the bonded device link down. > > + """ > > + results =3D [] > > + #------------------------------- > > + # boot up testpmd > > + self.bond_inst.start_testpmd() > > + try: > > + slaves =3D {'active' : [], 'inactive' : []} > > + #------------------------------- > > + # preset stacked bonded device > > + slaveGrpOne =3D self.slaveGrpOne > > + slaveGrpTwo =3D self.slaveGrpTwo > > + bond_port_1, bond_port_2, master_bond_port =3D \ > > + self.preset_stacked_bonded(slaveGrpOne, slaveGrpTw= o, mode) > > + #--------------------------------------------------- > > + # set one slave of first bonded device link down > > + primary_slave =3D slaveGrpOne[0] > > + self.bond_inst.set_dut_port_status(primary_slave, "down") > > + slaves['inactive'].append(primary_slave) > > + # get slave status > > + primary_port, active_slaves =3D \ > > + self.bond_inst.get_active_slaves(bond_= port_1) > > + slaves['active'].extend(active_slaves) > > + if primary_slave in slaves['active']: > > + msg =3D "{0} should not be in active slaves list".form= at( > > + primar= y_slave) > > + raise Exception(msg) > > + #--------------------------------------------------- > > + # set one slave of second bonded device link down > > + primary_slave =3D slaveGrpTwo[0] > > + self.bond_inst.set_dut_port_status(primary_slave, "down") > > + slaves['inactive'].append(primary_slave) > > + # check active slaves > > + primary_port_2, active_slaves_2 =3D \ > > + self.bond_inst.get_active_slaves(bond_= port_2) > > + slaves['active'].extend(active_slaves_2) > > + if primary_slave in slaves['active']: > > + msg =3D "{0} should not be in active slaves list".form= at( > > + primar= y_slave) > > + raise Exception(msg) > > + # traffic testing > > + # active slave traffic testing > > + for slave in slaves['active']: > > + self.active_slave_rx(slave, master_bond_port, mode) > > + # inactive slave traffic testing > > + for slave in slaves['inactive']: > > + self.inactive_slave_rx(slave, master_bond_port, mode) > > + except Exception as e: > > + results.append(e) > > + self.logger.error(traceback.format_exc()) > > + finally: > > + self.bond_inst.close_testpmd() > > + > > + return results > > + > > + def check_traffic(self, mode): > > + """ normal traffic with all slaves are under active status. > > + verify the RX packets are all correct with stacked bonded devi= ce. > > + bonded device's statistics should be the sum of slaves statist= ics. > > + """ > > + self.bond_inst.start_testpmd() > > + slaveGrpOne =3D self.slaveGrpOne > > + slaveGrpTwo =3D self.slaveGrpTwo > > + bond_port_1, bond_port_2, master_bond_port =3D \ > > + self.preset_stacked_bonded(slaveGrpOne, slaveGrpTwo, m= ode) > > + results =3D [] > > + # check first bonded device > > + try: > > + self.logger.info('check first bonded device') > > + # active slave traffic testing > > + for slave in slaveGrpOne: > > + self.active_slave_rx(slave, bond_port_1, mode) > > + except Exception as e: > > + results.append(e) > > + # check second bonded device > > + try: > > + self.logger.info('check second bonded device') > > + # active slave traffic testing > > + for slave in slaveGrpOne: > > + self.active_slave_rx(slave, bond_port_2, mode) > > + except Exception as e: > > + results.append(e) > > + > > + # check top bonded device > > + try: > > + self.logger.info('check master bonded device') > > + # active slave traffic testing > > + for slave in slaveGrpOne + slaveGrpTwo: > > + self.active_slave_rx(slave, master_bond_port, mode) > > + except Exception as e: > > + results.append(e) > > + > > + self.bond_inst.close_testpmd() > > + > > + return results > > + > > + def backup_check_traffic(self): > > + mode =3D MODE_ACTIVE_BACKUP > > + msg =3D "begin checking bonding backup(stacked) mode transmiss= ion" > > + self.logger.info(msg) > > + results =3D self.check_traffic(mode) > > + if results: > > + for item in results: > > + self.logger.error(item) > > + raise VerifyFailure("backup(stacked) mode: rx failed") > > + > > + def backup_check_traffic_with_slave_down(self): > > + mode =3D MODE_ACTIVE_BACKUP > > + self.logger.info("begin checking bonding backup(stacked) " > > + "mode transmission with one slave down") > > + results =3D self.check_traffic_with_one_slave_down(mode) > > + if results: > > + for item in results: > > + self.logger.error(item) > > + msg =3D "backup(stacked) mode: rx with one slave down fail= ed" > > + raise VerifyFailure(msg) > > + > > + def xor_check_rx(self): > > + mode =3D MODE_XOR_BALANCE > > + msg =3D "begin checking bonding xor(stacked) mode transmission= " > > + self.logger.info(msg) > > + results =3D self.check_traffic(mode) > > + if results: > > + for item in results: > > + self.logger.error(item) > > + raise VerifyFailure("xor(stacked) mode: rx failed") > > + > > + def xor_check_stacked_rx_one_slave_down(self): > > + mode =3D MODE_XOR_BALANCE > > + self.logger.info("begin checking bonding xor(stacked) mode " > > + "transmission with one slave down") > > + results =3D self.check_traffic_with_one_slave_down(mode) > > + if results: > > + for item in results: > > + self.logger.error(item) > > + msg =3D "xor(stacked) mode: rx with one slave down failed" > > + raise VerifyFailure(msg) > > + # > > + # Test cases. > > + # > > + def set_up_all(self): > > + """ > > + Run before each test suite > > + """ > > + self.verify('bsdapp' not in self.target, "Bonding not support = freebsd") > > + self.dut_ports =3D self.dut.get_ports() > > + num_ports =3D len(self.dut_ports) > > + self.verify(num_ports =3D=3D 2 or num_ports =3D=3D 4, "Insuffi= cient ports") > > + # separate ports into two group as first level bond ports' sla= ves > > + sep_index =3D len(self.dut_ports)/2 > > + self.slaveGrpOne =3D self.dut_ports[:sep_index] > > + self.slaveGrpTwo =3D self.dut_ports[sep_index:] > > + self.bond_slave =3D self.dut_ports[0] > > + # initialize bonding common methods name > > + self.total_pkt =3D 100 > > + config =3D { > > + 'parent': self, > > + 'pkt_name': 'udp', > > + 'pkt_size': FRAME_SIZE_64, > > + 'src_mac': '52:00:00:00:00:03', > > + 'src_ip': '10.239.129.65', > > + 'src_port': 61, > > + 'dst_ip': '10.239.129.88', > > + 'dst_port': 53,} > > + self.bond_inst =3D bonding.PmdBonding(**config) > > + > > + def tear_down_all(self): > > + """ > > + Run after each test suite. > > + """ > > + pass > > + > > + def set_up(self): > > + """ > > + Run before each test case. > > + """ > > + pass > > + > > + def tear_down(self): > > + """ > > + Run after each test case. > > + """ > > + > > + def test_basic_behav(self): > > + ''' > > + allow a bonded device to be added to another bonded device. > > + There's two limitations to create master bonding: > > + > > + - Total depth of nesting is limited to two levels, > > + - 802.3ad mode is not supported if one or more slaves is a > > + bond device > > + > > + note: There 802.3ad mode can not be supported on this bond dev= ice. > > + > > + This case is aimed at testing basic behavior of stacked bonded= commands. > > + > > + ''' > > + #------------------------------------------------ > > + # check stacked bonded status, except mode 4 (802.3ad) > > + mode_list =3D[MODE_ROUND_ROBIN, > > + MODE_ACTIVE_BACKUP, > > + MODE_XOR_BALANCE, > > + MODE_BROADCAST, > > + MODE_TLB_BALANCE, > > + MODE_ALB_BALANCE] > > + slaveGrpOne =3D self.slaveGrpOne > > + slaveGrpTwo =3D self.slaveGrpTwo > > + check_result =3D [] > > + for bond_mode in mode_list: > > + self.logger.info("begin mode <{0}> checking".format(bond_m= ode)) > > + # boot up testpmd > > + self.bond_inst.start_testpmd() > > + try: > > + self.logger.info("check bonding mode <{0}>".format(bon= d_mode)) > > + # set up stacked bonded status > > + bond_port_1, bond_port_2, master_bond_port =3D \ > > + self.set_stacked_bonded(slaveGrpOne, slaveGrpTwo, = bond_mode) > > + # check duplicate add slave > > + self.duplicate_add_stacked_bonded(bond_port_1, bond_po= rt_2, > > + master_bond_port) > > + # check stacked limitation > > + self.set_third_stacked_bonded(master_bond_port, bond_m= ode) > > + # quit testpmd, it is not supported to reset testpmd > > + self.logger.info("mode <{0}> done !".format(bond_mode)= ) > > + check_result.append([bond_mode, None]) > > + except Exception as e: > > + check_result.append([bond_mode, e]) > > + self.logger.error(e) > > + finally: > > + self.bond_inst.close_testpmd() > > + time.sleep(5) > > + #------------------------------------------------ > > + # 802.3ad mode is not supported > > + # if one or more slaves is a bond device > > + # so it should raise a exception > > + msg =3D '' > > + try: > > + # boot up testpmd > > + self.bond_inst.start_testpmd() > > + # set up stacked bonded status > > + self.set_stacked_bonded(slaveGrpOne, slaveGrpTwo, MODE_LAC= P) > > + # quit testpmd, it is not supported to reset testpmd > > + msg =3D ("802.3ad mode hasn't been forbidden to " > > + "use stacked bonded setting") > > + check_result.append([MODE_LACP, msg]) > > + except Exception as e: > > + check_result.append([MODE_LACP, None]) > > + finally: > > + self.bond_inst.close_testpmd() > > + > > + exception_flag =3D False > > + for bond_mode, e in check_result: > > + msg =3D "mode <{0}>".format(bond_mode) > > + if e: > > + self.logger.info(msg) > > + self.logger.error(e) > > + exception_flag =3D True > > + else: > > + self.logger.info(msg + ' done !') > > + # if some checking item is failed, raise exception > > + if exception_flag: > > + raise VerifyFailure('some test items failed') > > + else: > > + self.logger.info('all test items have done !') > > + > > + def test_mode_backup_rx(self): > > + """ > > + Verify receive packets correctly in the active-backup(stacked)= mode. > > + """ > > + self.backup_check_traffic() > > + > > + def test_mode_backup_one_slave_down(self): > > + """ > > + Verify that receive packets correctly in the active-backup(sta= cked) mode > > + when bringing any one slave of the bonding device link down. > > + """ > > + slave_down_port_limit =3D 4 > > + if len(self.dut_ports) < slave_down_port_limit: > > + msg =3D ("ports less than {0}, " > > + "ignore stacked one slave down check").format( > > + slave_down_por= t_limit) > > + self.logger.warning(msg) > > + return > > + self.backup_check_traffic_with_slave_down() > > + > > + def test_mode_xor_rx(self): > > + """ > > + Verify that receive packets correctly in the XOR(stacked) mode= . > > + """ > > + self.xor_check_rx() > > + > > + def test_mode_xor_rx_one_slave_down(self): > > + """ > > + Verify that receive packets correctly in the XOR(stacked) mode= when > > + bringing any one slave of the bonding device link down. > > + """ > > + slave_down_port_limit =3D 4 > > + if len(self.dut_ports) < slave_down_port_limit: > > + msg =3D ("ports less than {0}, " > > + "ignore stacked one slave down check").format( > > + slave_down_por= t_limit) > > + self.logger.warning(msg) > > + return > > + self.xor_check_stacked_rx_one_slave_down() > > \ No newline at end of file > > -- > > 1.9.3