[dts] [PATCH] tests: add ftag test suite and plan

Lin, Xueqin xueqin.lin at intel.com
Wed Aug 10 08:31:04 CEST 2016


Hi marvin,
Many thanks for review and guide.
Agreed, will send next version according to the comments.

Best regards,
Xueqin

> -----Original Message-----
> From: Liu, Yong
> Sent: Wednesday, August 10, 2016 10:08 AM
> To: xueqin.lin; dts at dpdk.org
> Cc: Lin, Xueqin
> Subject: Re: [dts][PATCH] tests: add ftag test suite and plan
> 
> Thanks xueqin, please check with my comments.
> 
> On 08/09/2016 02:18 PM, xueqin.lin wrote:
> > From: Xueqin Lin <xueqin.lin at intel.com>
> >
> > FTAG is placed at the begingging of the frame, which is essential for a set of
> switches to behave like one switch.The case validates packet forwarding
> function based on FTAG, uses FTAG unit test instead of testpmd to run.
> >
> > diff --git a/dep/unit_test_FTAG_devargs.patch
> b/dep/unit_test_FTAG_devargs.patch
> > new file mode 100644
> > index 0000000..d65666e
> > --- /dev/null
> > +++ b/dep/unit_test_FTAG_devargs.patch
> > @@ -0,0 +1,316 @@
> > +From f8d65293caa2fc130241ef34e6418eb22373d05b Mon Sep 17
> 00:00:00 2001
> > +From: Wang Xiao W <xiaow.wang at intel.com>
> > +Date: Wed, 3 Aug 2016 16:24:08 +0800
> > +Subject: [PATCH] fm10k: add a unit test for FTAG based forwardin
> > +
> > +This patch adds a unit test case for FTAG functional test. Before running
> > +the test, set PORT0_GLORT and PORT1_GLORT environment variables, and
> ensure
> > +two fm10k ports are used for dpdk, glort info for each port can be shown
> in
> > +TestPoint. In the unit test, a packet will be forwarded to the target port
> > +by the switch without changing the destination mac address.
> > +
> > +---
> > + app/test/Makefile          |   1 +
> > + app/test/test_fm10k_ftag.c | 267
> +++++++++++++++++++++++++++++++++++++++++++++
> > + config/common_linuxapp     |   2 +
> > + 3 files changed, 270 insertions(+)
> > + create mode 100644 app/test/test_fm10k_ftag.c
> > +
> > +diff --git a/app/test/Makefile b/app/test/Makefile
> > +index 49ea195..b6eed1e 100644
> > +--- a/app/test/Makefile
> > ++++ b/app/test/Makefile
> > +@@ -98,6 +98,7 @@ SRCS-y += test_memzone.c
> > + SRCS-y += test_ring.c
> > + SRCS-y += test_ring_perf.c
> > + SRCS-y += test_pmd_perf.c
> > ++SRCS-y += test_fm10k_ftag.c
> 
> Test application's makefile may change in each release, suggest to add
> this line in suite by sed command.
> 
> > +
> > + ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y)
> > + SRCS-y += test_table.c
> > +diff --git a/app/test/test_fm10k_ftag.c b/app/test/test_fm10k_ftag.c
> > +new file mode 100644
> > +index 0000000..c75a7b1
> > +--- /dev/null
> > ++++ b/app/test/test_fm10k_ftag.c
> > +@@ -0,0 +1,267 @@
> > ++/*-
> > ++ *   BSD LICENSE
> > ++ *
> > ++ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > ++ *   All rights reserved.
> > ++ *
> > ++ *   Redistribution and use in source and binary forms, with or without
> > ++ *   modification, are permitted provided that the following conditions
> > ++ *   are met:
> > ++ *
> > ++ *     * Redistributions of source code must retain the above copyright
> > ++ *       notice, this list of conditions and the following disclaimer.
> > ++ *     * Redistributions in binary form must reproduce the above copyright
> > ++ *       notice, this list of conditions and the following disclaimer in
> > ++ *       the documentation and/or other materials provided with the
> > ++ *       distribution.
> > ++ *     * Neither the name of Intel Corporation nor the names of its
> > ++ *       contributors may be used to endorse or promote products derived
> > ++ *       from this software without specific prior written permission.
> > ++ *
> > ++ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> > ++ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> > ++ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> > ++ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> > ++ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> > ++ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
> BUT NOT
> > ++ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> LOSS OF USE,
> > ++ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND ON ANY
> > ++ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> > ++ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> OF THE USE
> > ++ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> > ++ */
> > ++
> > ++#include <stdint.h>
> > ++#include <inttypes.h>
> > ++#include <rte_eal.h>
> > ++#include <rte_ethdev.h>
> > ++#include <rte_cycles.h>
> > ++#include <rte_lcore.h>
> > ++#include <rte_mbuf.h>
> > ++#include "test.h"
> > ++
> > ++#define RX_RING_SIZE 128
> > ++#define TX_RING_SIZE 512
> > ++
> > ++#define NUM_MBUFS 8191
> > ++#define MBUF_CACHE_SIZE 250
> > ++#define BURST_SIZE 32
> > ++
> > ++struct fm10k_ftag {
> > ++	uint16_t swpri_type_user;
> > ++	uint16_t vlan;
> > ++	uint16_t sglort;
> > ++	uint16_t dglort;
> > ++};
> > ++
> > ++static const struct rte_eth_conf port_conf_default = {
> > ++	.rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
> > ++};
> > ++
> > ++/*
> > ++ * Initializes a given port using global settings and with the RX buffers
> > ++ * coming from the mbuf_pool passed as a parameter.
> > ++ */
> > ++static inline int
> > ++port_init(uint8_t port, struct rte_mempool *mbuf_pool)
> > ++{
> > ++	struct rte_eth_conf port_conf = port_conf_default;
> > ++	const uint16_t rx_rings = 1, tx_rings = 1;
> > ++	int retval;
> > ++	uint16_t q;
> > ++	struct ether_addr addr;
> > ++
> > ++	if (port >= rte_eth_dev_count())
> > ++		return -1;
> > ++
> > ++	/* Configure the Ethernet device. */
> > ++	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
> > ++	if (retval != 0)
> > ++		return retval;
> > ++
> > ++	/* Allocate and set up 1 RX queue per Ethernet port. */
> > ++	for (q = 0; q < rx_rings; q++) {
> > ++		retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
> > ++				rte_eth_dev_socket_id(port), NULL,
> mbuf_pool);
> > ++		if (retval < 0)
> > ++			return retval;
> > ++	}
> > ++
> > ++	/* Allocate and set up 1 TX queue per Ethernet port. */
> > ++	for (q = 0; q < tx_rings; q++) {
> > ++		retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
> > ++				rte_eth_dev_socket_id(port), NULL);
> > ++		if (retval < 0)
> > ++			return retval;
> > ++	}
> > ++
> > ++	/* Start the Ethernet port. */
> > ++	retval = rte_eth_dev_start(port);
> > ++	if (retval < 0)
> > ++		return retval;
> > ++
> > ++	/* Display the port MAC address. */
> > ++	rte_eth_macaddr_get(port, &addr);
> > ++	printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
> > ++			   " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
> > ++			(unsigned)port,
> > ++			addr.addr_bytes[0], addr.addr_bytes[1],
> > ++			addr.addr_bytes[2], addr.addr_bytes[3],
> > ++			addr.addr_bytes[4], addr.addr_bytes[5]);
> > ++
> > ++	return 0;
> > ++}
> > ++
> > ++static int set_glort_value(const char *str, uint16_t *glort)
> > ++{
> > ++	const char *glort_str;
> > ++	char *end = NULL;
> > ++
> > ++	glort_str = getenv(str);
> > ++	if (glort_str == NULL) {
> > ++		printf("Please set environment value %s first\n", str);
> > ++		return -1;
> > ++	}
> > ++	*glort = (uint16_t)strtoul(glort_str, &end, 16);
> > ++	if ((glort_str[0] == '\0') || (end == NULL) || (*end != '\0')) {
> > ++		printf("Glort value is not valid\n");
> > ++		return -1;
> > ++	}
> > ++	return 0;
> > ++}
> > ++
> > ++static int test_ftag_rxtx(void)
> > ++{
> > ++	uint8_t port = 0;
> > ++	uint16_t glort[2];
> > ++
> > ++	struct rte_mbuf *bufs[BURST_SIZE];
> > ++	uint16_t nb_rx, nb_tx, i;
> > ++	struct fm10k_ftag *ftag_addr;
> > ++	int ret = 0;
> > ++
> > ++	/* Get the glort value of the two ports */
> > ++	if ((set_glort_value("PORT0_GLORT", &glort[0]) < 0) ||
> > ++			(set_glort_value("PORT1_GLORT", &glort[1]) < 0))
> > ++		return -1;
> > ++
> > ++	/* Receive packets coming from EPL on any of the two ports */
> > ++	printf("Please send some packets from Ethernet port to one PEP\n");
> > ++	do {
> > ++		port ^= 1;
> > ++		nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
> > ++	} while (nb_rx <= 0);
> > ++	printf("Receive %d packets on port %d\n", nb_rx, port);
> > ++
> > ++	/* Check sglort value on mbuf->vlan_tci_outer. */
> > ++	for (i = 0; i < nb_rx; i++) {
> > ++		if (bufs[i]->vlan_tci_outer == 0) {
> > ++			printf("Find a packet with sglort 0\n");
> > ++			return -1;
> > ++		}
> > ++	}
> > ++	printf("test for FTAG RX passed\n");
> > ++
> > ++	/* Put an FTAG header on each of the packets received and set FTAG
> > ++	 * TX flag
> > ++	 **/
> > ++	for (i = 0; i < nb_rx; i++) {
> > ++		ftag_addr = (struct fm10k_ftag
> *)rte_pktmbuf_prepend(bufs[i],
> > ++						sizeof(struct fm10k_ftag));
> > ++		ftag_addr->swpri_type_user = 0;
> > ++		ftag_addr->vlan = 0;
> > ++		ftag_addr->dglort = rte_cpu_to_be_16(glort[port ^ 1]);
> > ++		ftag_addr->sglort = rte_cpu_to_be_16(glort[port]);
> > ++		bufs[i]->timesync = 1;
> > ++	}
> > ++
> > ++	/* Send packets to the other port by method of FTAG based
> forwarding */
> > ++	nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_rx);
> > ++	if (nb_tx <= 0) {
> > ++		printf("Can not send out packets with FTAG\n");
> > ++		return -1;
> > ++	}
> > ++	if (unlikely(nb_tx < nb_rx)) {
> > ++		do {
> > ++			rte_pktmbuf_free(bufs[nb_tx]);
> > ++		} while (++nb_tx < nb_rx);
> > ++	}
> > ++	printf("Send out %d packets with FTAG on port %d\n", nb_tx, port);
> > ++
> > ++	/* Wait enough time for a burst of packets forwarding */
> > ++	rte_delay_us(100);
> > ++
> > ++	nb_rx = rte_eth_rx_burst(port ^ 1, 0, bufs, BURST_SIZE);
> > ++	printf("Receive %d packets on port %d\n", nb_rx, port ^ 1);
> > ++	if (nb_rx < nb_tx) {
> > ++		printf("Packet loss happens in FTAG TX test\n");
> > ++		ret = -1;
> > ++	}
> > ++
> > ++	/* check if the sglort value is right on the other port */
> > ++	for (i = 0; i < nb_rx; i++)	{
> > ++		if (bufs[i]->vlan_tci_outer != glort[port]) {
> > ++			printf("sglort of the received packet is not right\n");
> > ++			ret = -1;
> > ++			break;
> > ++		}
> > ++	}
> > ++	for (i = 0; i < nb_rx; i++)
> > ++		rte_pktmbuf_free(bufs[i]);
> > ++
> > ++	if (!ret)
> > ++		printf("test for FTAG TX passed\n");
> > ++	return ret;
> > ++}
> > ++
> > ++static int
> > ++test_fm10k_ftag(void)
> > ++{
> > ++	uint16_t nb_ports;
> > ++	uint16_t portid, pid;
> > ++	struct rte_mempool *mbuf_pool;
> > ++	int ret = 0;
> > ++
> > ++	printf("Dump the devices args\n");
> > ++	rte_eal_devargs_dump(stdout);
> > ++
> > ++	nb_ports = rte_eth_dev_count();
> > ++	if (nb_ports != 2) {
> > ++		printf("2 ports needed for fm10k ftag based forwarding
> test\n");
> > ++		return -1;
> > ++	}
> > ++
> > ++	/* Creates a new mempool in memory to hold the mbufs. */
> > ++	mbuf_pool = rte_mempool_lookup("MBUF_POOL_FTAG");
> > ++	if (mbuf_pool == NULL)
> > ++		mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL_FTAG",
> > ++			NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0,
> > ++			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
> > ++
> > ++	if (mbuf_pool == NULL)
> > ++		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
> > ++
> > ++	/* Initialize all ports. */
> > ++	for (portid = 0; portid < nb_ports; portid++)
> > ++		if (port_init(portid, mbuf_pool) != 0) {
> > ++			for (pid = 0; pid < portid; pid++) {
> > ++				rte_eth_dev_stop(portid);
> > ++				//rte_eth_dev_close(portid);
> > ++			}
> > ++			rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
> > ++					portid);
> > ++		}
> > ++
> > ++	if (test_ftag_rxtx() < 0)
> > ++		ret = -1;
> > ++
> > ++	/* port tear down */
> > ++	for (portid = 0; portid < nb_ports; portid++) {
> > ++		rte_eth_dev_stop(portid);
> > ++		//rte_eth_dev_close(portid);
> > ++	}
> > ++
> > ++	return ret;
> > ++}
> > ++
> > ++REGISTER_TEST_COMMAND(fm10k_ftag_autotest, test_fm10k_ftag);
> > +diff --git a/config/common_linuxapp b/config/common_linuxapp
> > +index 2483dfa..ac3e0bf 100644
> > +--- a/config/common_linuxapp
> > ++++ b/config/common_linuxapp
> > +@@ -44,3 +44,5 @@ CONFIG_RTE_LIBRTE_PMD_VHOST=y
> > + CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
> > + CONFIG_RTE_LIBRTE_POWER=y
> > + CONFIG_RTE_VIRTIO_USER=y
> > ++CONFIG_RTE_LIBRTE_FM10K_FTAG_FWD=y
> > ++
> > +--
> 
> DPDK configuration file may change in each release, suggest to add this
> line in suite by sed command.
> > +1.9.3
> > +
> > diff --git a/nics/rrc.py b/nics/rrc.py
> > index 02fe6c5..398f744 100644
> > --- a/nics/rrc.py
> > +++ b/nics/rrc.py
> > @@ -28,7 +28,7 @@
> >   # 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 re
> >   from crb import Crb
> >   from config import PortConf, PORTCONF
> >   from exception import PortConfigParseException
> > @@ -239,3 +239,32 @@ class RedRockCanyou(NetDevice):
> >               self.ctrl_crb.send_expect("set port config 5 max_frame_size %d" %
> framesize, "<0>%")
> >           else:
> >               self.ctrl_crb.send_expect("set port config 1 max_frame_size %d" %
> framesize, "<0>%")
> > +
> > +    def ftag_glortid(self, dmac):
> 
> This function is used to get glort id by mac address, support change
> name to get_glortid_bymac.
> > +        out = self.ctrl_crb.send_expect("show mac table all", "<0>%")
> > +        pattern = r"([0-9a-f]{2}:){5}([0-9a-f]{2})"
> > +        s = re.compile(pattern)
> > +        res = s.search(dmac)
> > +        if res is None:
> > +            print "search none mac filter"
> > +            return None
> > +        else:
> > +            mac_filter = res.group(2)
> > +        pattern = r"(?<=%s)+([\sA-Za-z0-9/])+([0-9]{4})" %mac_filter
> > +        s = re.compile(pattern)
> > +        res = s.search(out)
> > +        if res is None:
> > +            print "search none port value"
> > +            return None
> > +        else:
> > +            port_value = res.group(2)
> > +        out = self.ctrl_crb.send_expect("show stacking logical-port all",
> "<0>%",10000)
> > +        pattern = r"([0-9a-z]{6})+(\s)+(%s)+" %port_value
> > +        s = re.compile(pattern)
> > +        res = s.search(out)
> > +        if res is None:
> > +            print "search none port glort id"
> > +            return None
> > +        else:
> > +            port_glortid = res.group(1)
> > +            return port_glortid
> > diff --git a/test_plans/ftag_test_plan.rst b/test_plans/ftag_test_plan.rst
> > new file mode 100644
> > index 0000000..55e387f
> > --- /dev/null
> > +++ b/test_plans/ftag_test_plan.rst
> > @@ -0,0 +1,106 @@
> > +.. Copyright (c) <2016>, Intel Corporation
> > +   All rights reserved.
> > +
> > +   Redistribution and use in source and binary forms, with or without
> > +   modification, are permitted provided that the following conditions
> > +   are met:
> > +
> > +   - Redistributions of source code must retain the above copyright
> > +     notice, this list of conditions and the following disclaimer.
> > +
> > +   - Redistributions in binary form must reproduce the above copyright
> > +     notice, this list of conditions and the following disclaimer in
> > +     the documentation and/or other materials provided with the
> > +     distribution.
> > +
> > +   - Neither the name of Intel Corporation nor the names of its
> > +     contributors may be used to endorse or promote products derived
> > +     from this software without specific prior written permission.
> > +
> > +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> > +   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS
> > +   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> > +   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT,
> > +   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> > +   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> OR
> > +   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> > +   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> CONTRACT,
> > +   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> > +   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> ADVISED
> > +   OF THE POSSIBILITY OF SUCH DAMAGE.
> > +
> > +==========================
> > +FM10k FTAG FORWARDING TEST
> > +==========================
> > +
> > +FM10000 supports the addition of a Fabric Tag (FTAG) to carry special
> > +information between Switches, between Switch and PCIe Host Interface or
> > +between Switch and Tunneling Engines. This tag is essential for a set of
> > +switches to behave like one switch (switch aggregation).
> > +
> > +The FTAG is placed at the beginning of the frame.  The case will validate
> > +packet forwarding function based on FTAG.
> > +
> > +Prerequisites
> > +-------------
> > +Turn on CONFIG_RTE_LIBRTE_FM10K_FTAG_FWD in common_linuxapp
> configuration file.
> > +Startup testpoint and export Port0 and Port1's GLORT ID.
> > +
> > +Strip port logic value from mac table information.
> > +There's the sample output from RubyRapid. From the output, port0's logic
> > +value is 4122 and port1's logic value is 4123.
> > +
> > +	<0>% show mac table all
> > +	MAC                Mode      FID1 FID2 Type   Value  Trig ...
> > +	------------------ --------- ---- ---- ------ ------ -----
> > +	00:00:00:00:01:01  Dynamic   1    NA   Local  1      1
> > +	a0:36:9f:60:b6:6e  Static    1    NA   PF/VF  4506   1
> > +	a0:36:9f:60:b6:68  Static    1    NA   PF/VF  4123   1
> > +	00:00:00:00:01:00  Dynamic   1    NA   Local  1      1
> > +	a0:36:9f:60:b6:66  Static    1    NA   PF/VF  4122   1
> > +
> > +
> > +Strip port glort ID from stacking information.
> > +There's the sample output from RubyRapid. Logic port0's GLORT ID is
> 0x4000.
> > +Logic port1's GLORT ID is 0x4200.
> > +
> > +	show stacking logical-port all
> > +	<0>% show stacking logical-port all
> > +
> > +	SW  GLORT  LOGICAL PORT   PORT TYPE
> > +	---- ----- --------------- ---------
> > +	...
> > +	0 0x4000         4122    ?
> > +	0 0x4200         4123    ?
> > +
> > +Add port's GLORT ID into environment variables.
> > +	export PORT1_GLORT=0x4200
> > +	export PORT0_GLORT=0x4000
> > +
> > +Test Case: Ftag forwarding unit test
> > +====================================
> > +1. port 0 pci 85:00.0, port 1 pci 87:00.0,start test application::
> > +
> > +	./x86_64-native-linuxapp-gcc/app/test -c f -n 4 -w
> 0000:85:00.0,enable_ftag=1 -w 0000:87:00.0,enable_ftag=1
> > +
> > +2. Run FTAG test function::
> > +
> > +	RTE>>fm10k_ftag_autotest
> > +
> > +3. Send one packet to Port0 and verify packet with ftag forwarded to Port1
> > +	Receive 1 packets on port 0
> > +	test for FTAG RX passed
> > +	Send out 1 packets with FTAG on port 0
> > +	Receive 1 packets on port 1
> > +	test for FTAG TX passed
> > +	Test OK
> > +
> > +4. Send one packet to Port1 and verify packet with ftag forwarded to Port0
> > +	Receive 1 packets on port 0
> > +	test for FTAG RX passed
> > +	Send out 1 packets with FTAG on port 0
> > +	Receive 1 packets on port 1
> > +	test for FTAG TX passed
> > +	Test OK
> > +
> > diff --git a/tests/TestSuite_ftag.py b/tests/TestSuite_ftag.py
> > new file mode 100644
> > index 0000000..5427972
> > --- /dev/null
> > +++ b/tests/TestSuite_ftag.py
> > @@ -0,0 +1,211 @@
> > +# BSD LICENSE
> > +#
> > +# Copyright(c) 2010-2015 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 ftag feature
> > +
> > +"""
> > +
> > +import dts
> > +import time
> > +import re
> > +import os
> > +import dut
> > +from config import PortConf
> > +from test_case import TestCase
> > +from pmd_output import PmdOutput
> > +from settings import FOLDERS
> > +from packet import Packet
> > +
> > +#
> > +#
> > +# Test class.
> > +#
> > +
> > +
> > +class TestFtag(TestCase):
> > +    #
> > +    # Test cases.
> > +    #
> > +
> > +    def set_up_all(self):
> > +        """
> > +        Run at the start of each test suite.
> > +        """
> > +        self.ports = self.dut.get_ports(self.nic)
> > +        self.verify(len(self.ports) >= 2, "Insufficient number of ports.")
> > +
> > +    def set_up(self):
> > +        """
> > +        Run before each test case.
> > +        """
> > +        try:
> > +            patch_file = FOLDERS["Depends"] +
> r'/unit_test_FTAG_devargs.patch'
> > +        except:
> > +            self.logger.warning(str(FOLDERS))
> > +            patch_file = r'dep/unit_test_FTAG_devargs_org.patch'
> > +            FOLDERS["Depends"] = 'dep'
> > +        patch_dst = "/tmp/"
> The patch will be merged in, so there's no need to check whether patch
> file existed.
> > +
> > +        # dpdk patch and build
> > +        try:
> > +            self.dut.session.copy_file_to(patch_file, patch_dst)
> > +            self.patch_hotfix_dpdk(patch_dst +
> "unit_test_FTAG_devargs.patch", True)
> > +            out = self.dut.send_expect("make install T=x86_64-native-linuxapp-
> gcc -j", "# ", 300)
> Target should be dynamic, it can be easily get from "self.dut.target".
> > +            self.verify('Build complete' in out, "Compilation failed")
> > +
> > +        except Exception, e:
> > +            raise IOError("dpdk setup failure: %s" % e)
> Applied patch and build is must for this feature, please move it to
> set_up_all function.
> Don't need to capture the exception. If failed in set_up_all, case
> status will be "Blocked".
> 
> > +
> > +    def check_forwarding(self, txPort, rxPort, nic, received=True):
> > +         self.send_packet(txPort, rxPort, self.nic, received)
> > +
> > +    def send_packet(self, txPort, rxPort, nic, received=True):
> > +        """
> > +        Send packages according to parameters.
> > +        """
> > +        rxitf = self.tester.get_interface(self.tester.get_local_port(rxPort))
> > +        txitf = self.tester.get_interface(self.tester.get_local_port(txPort))
> > +
> > +        dmac_tx = self.dut.get_mac_address(txPort)
> > +        dmac_rx = self.dut.get_mac_address(rxPort)
> > +
> > +        pkg =
> 'Ether(dst="%s",src="52:00:00:00:00:00")/IP()/TCP()/("X"*46)' %dmac_rx
> > +        self.tester.scapy_foreground()
> > +        self.tester.scapy_append('sendp(%s, iface="%s")' % (pkg, txitf))
> > +        self.tester.scapy_execute()
> > +        time.sleep(3)
> > +
> > +    def patch_hotfix_dpdk(self, patch_dir, on = True):
> > +        """
> > +        This function is to apply or remove patch for dpdk.
> > +        patch_dir: the abs path of the patch
> > +        on: True for apply, False for remove
> > +        """
> > +        try:
> > +            if on:
> > +                self.dut.send_expect("git am %s" % patch_dir,"#",2)
> > +            else:
> > +                self.dut.send_expect("git reset --hard HEAD^1","#",2)
> > +        except Exception, e:
> > +            raise ValueError("patch_hotfix_dpdk failure: %s" % e)
> dpdk folder will not contain git information by default, so please use
> patch command to apply the patch.
> Again, no need to capture the exception. Let it handled by dts framework.
> > +
> > +    def test_ftag_function(self):
> > +        """
> > +        ftag functional test
> > +        """
> > +        try:
> > +            self.dut.send_expect("./x86_64-native-linuxapp-gcc/app/testpmd -c
> f -n 4 -- -i","testpmd", 60)
> > +
> > +        except Exception, e:
> > +            raise IOError("dpdk start failure: %s" % e)
> No need to capture the exception. Let it handled by dts framework.
> > +
> > +        self.tx_port = self.ports[0]
> > +        self.rx_port = self.ports[1]
> > +
> > +        dmac_tx = self.dut.get_mac_address(self.tx_port)
> > +        dmac_rx = self.dut.get_mac_address(self.rx_port)
> > +        """
> > +        get port glort id in the mac table of testpoint switch
> > +        """
> > +        if self.kdriver == "fm10k":
> > +            netobj = self.dut.ports_info[self.tx_port]['port']
> > +            port0_glortid = netobj.ftag_glortid(dmac_tx)
> > +            port1_glortid = netobj.ftag_glortid(dmac_rx)
> > +
> This suite only support fm10k, please add nic type check in set_up_all
> function.
> > +        try:
> > +            self.dut.send_expect("quit", "# ")
> > +        except Exception, e:
> > +            raise IOError("dpdk quit failure: %s" % e)
> > +        """
> > +        export port glort id
> > +        """
> > +
> > +        try:
> > +            self.dut.send_expect("export PORT0_GLORT=%s" %port0_glortid,
> "#", 2)
> > +            self.dut.send_expect("export PORT1_GLORT=%s" %port1_glortid,
> "#", 2)
> > +        except Exception, e:
> > +            raise IOError("set port glort id failure: %s" % e)
> > +
> > +        enable_ftag_ports = ''
> > +        for port in range(0,len(self.ports)):
> > +            pci_bus = self.dut.ports_info[port]['pci']
> > +            enable_ftag_ports += '-w %s,enable_ftag=1 ' % pci_bus
> > +
> > +        try:
> > +            self.dut.send_expect("./x86_64-native-linuxapp-gcc/app/test -c f -n
> 4 %s" % enable_ftag_ports,"R.*T.*E.*>.*>", 60)
> > +
> > +        except Exception, e:
> > +            raise IOError("dpdk start failure: %s" % e)
> > +
> > +        #fm10k ftag auto test
> > +        for txport in range(0,len(self.ports)):
> > +            for rxport in range(0,len(self.ports)):
> > +                try:
> > +                    self.dut.send_expect("fm10k_ftag_autotest", "Dump", 100)
> > +                    self.check_forwarding(txport, rxport, self.nic, received=False)
> > +                    out = self.dut.get_session_output()
> > +                    print "out:%s" %out
> > +                    self.verify("Test OK" in out, "Fail to do fm10k ftag test")
> > +
> > +                except Exception, e:
> > +                    raise IOError("ftag test fail: %s" % e)
> > +
> > +
> > +    def tear_down(self):
> > +        """
> > +        Run after each test case.
> > +        """
> > +        patch_dst = "/tmp/"
> > +
> > +        try:
> > +            print "quit ftag test"
> > +            self.dut.send_expect("quit", "# ")
> > +        except:
> > +            print "Failed to quit ftag test"
> > +
> > +        self.dut.kill_all()
> > +
> > +        try:
> > +            self.patch_hotfix_dpdk(patch_dst +
> "unit_test_FTAG_devargs.patch", False)
> > +        except Exception, e:
> > +            print "patch_hotfix_dpdk remove failure :%s" %e
> > +
> > +    def tear_down_all(self):
> > +        """
> > +        Run after each test suite.
> > +        """
> > +        self.dut.kill_all()
> > +        self.dut.send_expect("rm -rf /tmp/unit_test_FTAG_devargs.patch", "#")
> No need to handle the temporary file, should reverse the changes in dpdk
> like common_linuxapp and makefile.



More information about the dts mailing list