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

Liu, Yong yong.liu at intel.com
Wed Aug 10 04:08:09 CEST 2016


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