get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/119557/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 119557,
    "url": "http://patches.dpdk.org/api/patches/119557/?format=api",
    "web_url": "http://patches.dpdk.org/project/dts/patch/20221108150636.2459852-4-yogesh.jangra@intel.com/",
    "project": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/projects/3/?format=api",
        "name": "DTS",
        "link_name": "dts",
        "list_id": "dts.dpdk.org",
        "list_email": "dts@dpdk.org",
        "web_url": "",
        "scm_url": "git://dpdk.org/tools/dts",
        "webscm_url": "http://git.dpdk.org/tools/dts/",
        "list_archive_url": "https://inbox.dpdk.org/dts",
        "list_archive_url_format": "https://inbox.dpdk.org/dts/{}",
        "commit_url_format": ""
    },
    "msgid": "<20221108150636.2459852-4-yogesh.jangra@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20221108150636.2459852-4-yogesh.jangra@intel.com",
    "date": "2022-11-08T15:06:36",
    "name": "[3/3] test/softnic: updated softnic test suite as per dpdk 22.11 changes",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "dc6ab58b8094281f94364a4d3c03cab0bcf4fec4",
    "submitter": {
        "id": 2025,
        "url": "http://patches.dpdk.org/api/people/2025/?format=api",
        "name": "Yogesh Jangra",
        "email": "yogesh.jangra@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dts/patch/20221108150636.2459852-4-yogesh.jangra@intel.com/mbox/",
    "series": [
        {
            "id": 25623,
            "url": "http://patches.dpdk.org/api/series/25623/?format=api",
            "web_url": "http://patches.dpdk.org/project/dts/list/?series=25623",
            "date": "2022-11-08T15:06:33",
            "name": "update testsuites that uses softnic driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/25623/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/119557/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/119557/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dts-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 3F3EEA00C2;\n\tTue,  8 Nov 2022 16:16:40 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 3B62142D3A;\n\tTue,  8 Nov 2022 16:16:40 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n by mails.dpdk.org (Postfix) with ESMTP id 52741400D4\n for <dts@dpdk.org>; Tue,  8 Nov 2022 16:16:38 +0100 (CET)",
            "from fmsmga007.fm.intel.com ([10.253.24.52])\n by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 08 Nov 2022 07:06:51 -0800",
            "from ena3-s2600wft.iind.intel.com ([10.235.221.73])\n by fmsmga007.fm.intel.com with ESMTP; 08 Nov 2022 07:06:49 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1667920598; x=1699456598;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=E7wtUzgRgUpGQH+85y2YJqVgtR6EyYQg2v/hsgBqVp4=;\n b=hXgRNBc0xV/yQzxd/yTWUv1bVaXd+jIyHR82CIyG/Y88MXdFW09NmGUn\n go1EIhqIAlDN6jqM8Sl5WiY7rEILFczSgTi4+A1xWngf6e51dGHK/qLZs\n /PrZHA5vuyo2qFRzzwxn3aXrvJSdIXJCVrfgdE1g0+qOnHHBghS4RG0D0\n DTaujaZe6dNlquKEPYQy2ItIAStgfBC2CUvIx+MoAG8FsBOZhuNxY5H0c\n ssIPqZEVKRLekwWcZTdivUUEVXmznVij95jbyltsmepqGAIl4ASaTuDbx\n gDhoKOHqrHax4ZTrm7tDnaloHYtqPlJHH84COWf8w94IHIw/3vMvtvYHl Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10525\"; a=\"310715331\"",
            "E=Sophos;i=\"5.96,148,1665471600\";\n d=\"scan'208,223\";a=\"310715331\"",
            "E=McAfee;i=\"6500,9779,10525\"; a=\"638816605\"",
            "E=Sophos;i=\"5.96,148,1665471600\";\n d=\"scan'208,223\";a=\"638816605\""
        ],
        "X-ExtLoop1": "1",
        "From": "Yogesh Jangra <yogesh.jangra@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "cristian.dumitrescu@intel.com, kamalakannan.r@intel.com,\n harshad.suresh.narayane@intel.com",
        "Subject": "[PATCH 3/3] test/softnic: updated softnic test suite as per dpdk\n 22.11 changes",
        "Date": "Tue,  8 Nov 2022 20:36:36 +0530",
        "Message-Id": "<20221108150636.2459852-4-yogesh.jangra@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20221108150636.2459852-1-yogesh.jangra@intel.com>",
        "References": "<20221108150636.2459852-1-yogesh.jangra@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dts@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "test suite reviews and discussions <dts.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dts>,\n <mailto:dts-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dts/>",
        "List-Post": "<mailto:dts@dpdk.org>",
        "List-Help": "<mailto:dts-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dts>,\n <mailto:dts-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dts-bounces@dpdk.org"
    },
    "content": "From dpdk 22.11 release, Soft NIC driver has started to use rte_swx_pipeline_xxx\nlibrary. This changes the CLI format of the Soft NIC. To accomodate those changes,\nupdating the test suite.\n\nSigned-off-by: Yogesh Jangra <yogesh.jangra@intel.com>\n---\n dep/softnic/rx_tx/pcap_files/in.txt  |  12 +\n dep/softnic/rx_tx/pcap_files/out.txt |  12 +\n dep/softnic/rx_tx/readme.txt         |   8 +\n dep/softnic/rx_tx/rx_tx.cli          |  21 ++\n dep/softnic/rx_tx/rx_tx.spec         |  19 ++\n dep/softnic/rx_tx/rx_tx_1.io         |  30 ++\n dep/softnic/rx_tx/rx_tx_2.io         |  30 ++\n test_plans/softnic_test_plan.rst     | 137 ++++-----\n tests/TestSuite_softnic.py           | 414 ++++++++++++++-------------\n 9 files changed, 416 insertions(+), 267 deletions(-)\n create mode 100644 dep/softnic/rx_tx/pcap_files/in.txt\n create mode 100644 dep/softnic/rx_tx/pcap_files/out.txt\n create mode 100644 dep/softnic/rx_tx/readme.txt\n create mode 100644 dep/softnic/rx_tx/rx_tx.cli\n create mode 100644 dep/softnic/rx_tx/rx_tx.spec\n create mode 100644 dep/softnic/rx_tx/rx_tx_1.io\n create mode 100644 dep/softnic/rx_tx/rx_tx_2.io",
    "diff": "diff --git a/dep/softnic/rx_tx/pcap_files/in.txt b/dep/softnic/rx_tx/pcap_files/in.txt\nnew file mode 100644\nindex 00000000..9b37ef2e\n--- /dev/null\n+++ b/dep/softnic/rx_tx/pcap_files/in.txt\n@@ -0,0 +1,12 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2022 Intel Corporation\n+#\n+\n+# text to pcap: text2pcap packet.txt packet.pcap\n+# pcap to text: tcpdump -r packet.pcap -xx\n+\n+# Packet 0\n+000000  00 11 22 33 44 55 00 66 77 88 99 aa 08 00 45 00\n+000010  00 2e 00 01 00 00 40 06 4e b5 64 00 00 0a c8 00\n+000020  00 0a 00 64 00 c8 00 00 00 00 00 00 00 00 50 02\n+000030  20 00 59 93 00 00 58 58 58 58 58 58\n\\ No newline at end of file\ndiff --git a/dep/softnic/rx_tx/pcap_files/out.txt b/dep/softnic/rx_tx/pcap_files/out.txt\nnew file mode 100644\nindex 00000000..9b37ef2e\n--- /dev/null\n+++ b/dep/softnic/rx_tx/pcap_files/out.txt\n@@ -0,0 +1,12 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2022 Intel Corporation\n+#\n+\n+# text to pcap: text2pcap packet.txt packet.pcap\n+# pcap to text: tcpdump -r packet.pcap -xx\n+\n+# Packet 0\n+000000  00 11 22 33 44 55 00 66 77 88 99 aa 08 00 45 00\n+000010  00 2e 00 01 00 00 40 06 4e b5 64 00 00 0a c8 00\n+000020  00 0a 00 64 00 c8 00 00 00 00 00 00 00 00 50 02\n+000030  20 00 59 93 00 00 58 58 58 58 58 58\n\\ No newline at end of file\ndiff --git a/dep/softnic/rx_tx/readme.txt b/dep/softnic/rx_tx/readme.txt\nnew file mode 100644\nindex 00000000..906bb615\n--- /dev/null\n+++ b/dep/softnic/rx_tx/readme.txt\n@@ -0,0 +1,8 @@\n+Test Case: rx_tx\n+-----------------------\n+Description:\n+    This test is to verify packet transmission by the Soft NIC driver. In this test we have two pipeline connected using ring\n+    port. First pipeline takes packet from physical port and put the packet in ring port. And second pipeline takes packet\n+    from ring port and send the packet out to the physical port.\n+Verification:\n+    The received packets should be same as the transmitted packets.\ndiff --git a/dep/softnic/rx_tx/rx_tx.cli b/dep/softnic/rx_tx/rx_tx.cli\nnew file mode 100644\nindex 00000000..cbc0c58a\n--- /dev/null\n+++ b/dep/softnic/rx_tx/rx_tx.cli\n@@ -0,0 +1,21 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2022 Intel Corporation\n+\n+;\n+; Pipeline code generation & shared object library build.\n+;\n+pipeline codegen /tmp/softnic/rx_tx/rx_tx.spec /tmp/firmware.c\n+pipeline libbuild /tmp/firmware.c /tmp/firmware.so\n+\n+;\n+; List of pipelines.\n+;\n+pipeline RX build lib /tmp/firmware.so io /tmp/softnic/rx_tx/rx_tx_1.io numa 0\n+pipeline TX build lib /tmp/firmware.so io /tmp/softnic/rx_tx/rx_tx_2.io numa 0\n+\n+;\n+; Pipelines-to-threads mapping. For the Soft NIC devices, the pipelines can be mapped to any of the\n+; application service cores (see the -s <core_mask> argument):\n+;\n+thread 2 pipeline RX enable\n+thread 2 pipeline TX enable\n\\ No newline at end of file\ndiff --git a/dep/softnic/rx_tx/rx_tx.spec b/dep/softnic/rx_tx/rx_tx.spec\nnew file mode 100644\nindex 00000000..106caae7\n--- /dev/null\n+++ b/dep/softnic/rx_tx/rx_tx.spec\n@@ -0,0 +1,19 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2022 Intel Corporation\n+\n+//\n+// Meta-data.\n+//\n+struct metadata_t {\n+\tbit<32> port\n+}\n+\n+metadata instanceof metadata_t\n+\n+//\n+// Pipeline.\n+//\n+apply {\n+\trx m.port\n+\ttx m.port\n+}\ndiff --git a/dep/softnic/rx_tx/rx_tx_1.io b/dep/softnic/rx_tx/rx_tx_1.io\nnew file mode 100644\nindex 00000000..731f672c\n--- /dev/null\n+++ b/dep/softnic/rx_tx/rx_tx_1.io\n@@ -0,0 +1,30 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2022 Intel Corporation\n+\n+;\n+; Pipeline input ports.\n+;\n+; Syntax:\n+;\n+;    port in <port_id> ethdev <ethdev_name> rxq <queue_id> bsz <burst_size>\n+;    port in <port_id> ring <ring_name> bsz <burst_size>\n+;    port in <port_id> source mempool <mempool_name> file <file_name> loop <n_loops> packets <n_pkts_max>\n+;    port in <port_id> fd <file_descriptor> mtu <mtu> mempool <mempool_name> bsz <burst_size>\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+port in 0 ethdev 0000:af:00.1 rxq 0 bsz 32\n+\n+;\n+; Pipeline output ports.\n+;\n+; Syntax:\n+;\n+;    port out <port_id> ethdev <ethdev_name> txq <queue_id> bsz <burst_size>\n+;    port out <port_id> ring <ring_name> bsz <burst_size>\n+;    port out <port_id> sink file <file_name> | none\n+;    port out <port_id> fd <file_descriptor> bsz <burst_size>\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+port out 0 ring RXQ0 bsz 32\ndiff --git a/dep/softnic/rx_tx/rx_tx_2.io b/dep/softnic/rx_tx/rx_tx_2.io\nnew file mode 100644\nindex 00000000..d8c9ccbd\n--- /dev/null\n+++ b/dep/softnic/rx_tx/rx_tx_2.io\n@@ -0,0 +1,30 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2022 Intel Corporation\n+\n+;\n+; Pipeline input ports.\n+;\n+; Syntax:\n+;\n+;    port in <port_id> ethdev <ethdev_name> rxq <queue_id> bsz <burst_size>\n+;    port in <port_id> ring <ring_name> bsz <burst_size>\n+;    port in <port_id> source mempool <mempool_name> file <file_name> loop <n_loops> packets <n_pkts_max>\n+;    port in <port_id> fd <file_descriptor> mtu <mtu> mempool <mempool_name> bsz <burst_size>\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+port in 0 ring TXQ0 bsz 32\n+\n+;\n+; Pipeline output ports.\n+;\n+; Syntax:\n+;\n+;    port out <port_id> ethdev <ethdev_name> txq <queue_id> bsz <burst_size>\n+;    port out <port_id> ring <ring_name> bsz <burst_size>\n+;    port out <port_id> sink file <file_name> | none\n+;    port out <port_id> fd <file_descriptor> bsz <burst_size>\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+port out 0 ethdev 0000:af:00.1 txq 0 bsz 32\ndiff --git a/test_plans/softnic_test_plan.rst b/test_plans/softnic_test_plan.rst\nindex 84d34f63..a6f8348a 100644\n--- a/test_plans/softnic_test_plan.rst\n+++ b/test_plans/softnic_test_plan.rst\n@@ -12,95 +12,84 @@ is configurable through firmware (DPDK Packet Framework script).\n \n Prerequisites\n =============\n-1. The DUT must have one 10G Ethernet port connected to a port on tester\n-   that are controlled by the traffic generator::\n+The DUT must have atleast one 10G Ethernet ports connected to one port on\n+Tester.::\n \n     dut_port_0 <---> tester_port_0\n \n-   Assume the DUT 10G Ethernet port's pci device id is as the following::\n+Assume DUT 10G Ethernet ports' pci device id is as the following::\n \n-    dut_port_0 : \"0000:05:00.0\"\n+    dut_port_0 : \"0000:af:00.1\"\n \n-   Bind it to dpdk igb_uio driver::\n+Bind them to dpdk vfio-pci driver::\n \n-    ./usertools/dpdk-devbind.py -b igb_uio 05:00.0\n+    ./usertools/dpdk-devbind.py -b vfio-pci 0000:af:00.1\n \n-2. Change ./drivers/net/softnic/firmware.cli to meet the specific test environment.\n-   Change the DUT port info to the actual port info in your test environment::\n-\n-    link LINK dev 0000:05:00.0\n-\n-3. Start softnic with following command line::\n-\n-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \\\n-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/firmware.cli,cpu_id=1,conn_port=8086' \\\n-    -- -i --forward-mode=softnic --portmask=0x2\n-    testpmd> start\n-\n-   Set the thread id consistent to the service core::\n-\n-    thread 2 pipeline PIPELINE0 enable\n-\n-Test Case 1: softnic performance\n-================================\n-1. Start softnic::\n-\n-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \\\n-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/firmware.cli,cpu_id=1,conn_port=8086' \\\n-    -- -i --forward-mode=softnic --portmask=0x2\n-    testpmd> start\n-\n-2. Send packet at line rate from traffic generator (IXIA or other) with packet size from 64~1518B.\n-3. Check performance number is same as the physical NIC's performance number, no performance drop.\n-\n-Test Case 2: shaping for pipe\n-=============================\n-1. The specifications of the default Hierarchical Scheduler are as follows:\n-\n-    Root node (x1, level 0)\n-    Subport node (x1, level 1)\n-    Pipe node (x4096, level 2)\n-    Traffic Class node (x16348, level 3)\n-    Queue node (x65536, level 4)\n-\n-2. Start softnic with the default hierarchy Qos::\n-\n-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \\\n-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/tm_firmware.cli,cpu_id=1,conn_port=8086' \\\n-    -- -i --forward-mode=softnic --portmask=0x2\n-    testpmd> start\n-\n-3. Send per flow traffic with 100% line rate, verify output flow rate is 1/4096 subport rate.\n-\n-Test Case 3: NAT\n+Supporting Files\n ================\n-1. Set SNAT with proto tcp test, edit nat_firmware.cli to change \"table action\" as below::\n-\n-    table action profile AP0 ipv4 offset 270 fwd nat src proto tcp\n-\n-(a). Start softnic::\n-\n-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \\\n-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/nat_firmware.cli,cpu_id=1,conn_port=8086' \\\n-    -- -i --forward-mode=softnic --portmask=0x2\n+All the supporting files for this test suite are maintained inside softnic folder, and softnic folder\n+is present in the {DTS_SRC_DIR}/dep directory.\n+\n+Directory Structure of Each Test Case\n+=====================================\n+Within {DTS_SRC_DIR}/dep/softnic, all files related to a particular test case are maintained\n+in a separate directory of which the directory structure is shown below::\n+\n+    test_case_name [directory]\n+        test_case_name.spec\n+        test_case_name_x.io [x: 1 to n; depending on the test case]\n+        test_case_name.cli\n+        table.txt [applicable for test cases requiring it]\n+        readme.txt\n+        pcap_files [subdirectory]\n+            in.txt\n+            out.txt\n+\n+For an example, files related to rx_tx test case are maintained as shown below::\n+\n+    rx_tx [directory]\n+        rx_tx.spec\n+        rx_tx_1.io\n+        rx_tx_2.io\n+        rx_tx.cli\n+        readme.txt\n+        pcap_files [subdirectory]\n+            in.txt\n+            out.txt\n+\n+Template of each Test Case\n+===========================\n+1. Edit test_case_name/test_case_name.io:\n+   change pci device id of port in and port out to pci device id of dut_port_0\n+\n+2. Run softnic driver as the following::\n+\n+    x86_64-native-linuxapp-gcc/app/dpdk-testpmd -l 0-2 -n 4  --file-prefix=dpdk_2374972_20221107140937   -s 0x4 -a 0000:af:00.1 \\\n+    --vdev 'net_softnic0,firmware=/tmp/softnic/rx_tx/firmware.cli,cpu_id=1,conn_port=8086' -- -i --portmask=0x2\n     testpmd> start\n \n-(b). Sent packet, verify the received packet's ipaddr and port was changed as expected.\n+3. Send packets at tester side using scapy. The packets to be sent are maintained in softnic/test_case_name/pcap_files/in.txt\n \n-2. Set DNAT with proto tcp test, edit nat_firmware.cli to change \"table action\" as below::\n+4. Verify the packets received using tcpdump. The expected packets are maintained in softnic/test_case_name/pcap_files/out.txt\n \n-    table action profile AP0 ipv4 offset 270 fwd nat dst proto tcp\n+5. Test case is considered as successful if the received packets and the expected packets match for all the port combinations used.\n \n-   Then re-run step (a) & step (b).\n-\n-3. Set SNAT with proto udp test, edit nat_firmware.cli to change \"table action\" as below::\n+Example Test Case : rx_tx\n+================================\n+1. Edit rx_tx/rx_tx_1.io:\n+   change pci device id of port in to pci device id of dut_port_0\n+   Edit rx_tx/rx_tx_2.io:\n+   change pci device id of port out to pci device id of dut_port_0\n \n-    table action profile AP0 ipv4 offset 270 fwd nat src proto udp\n+2. Start softnic::\n \n-   Then re-run step (a) & step (b).\n+    x86_64-native-linuxapp-gcc/app/dpdk-testpmd -l 0-2 -n 4  --file-prefix=dpdk_2374972_20221107140937 \\\n+    -s 0x4 -a 0000:af:00.1 --vdev 'net_softnic0,firmware=/tmp/softnic/rx_tx/firmware.cli,cpu_id=1, \\\n+    conn_port=8086' -- -i --portmask=0x2\n+    testpmd> start\n \n-4. Set DNAT with proto udp test, edit nat_firmware.cli to change \"table action\" as below::\n+3. Send packets at tester side using scapy. The packets to be sent are maintained in softnic/rx_tx/pcap_files/in.txt\n \n-    table action profile AP0 ipv4 offset 270 fwd nat dst proto udp\n+4. Verify the packets received using tcpdump. The expected packets are maintained in softnic/rx_tx/pcap_files/out.txt\n \n-   Then re-run step (a) & step (b).\n+5. Test rx_tx is considered as successful if the received packets and the expected packets match for all port combinations used.\n\\ No newline at end of file\ndiff --git a/tests/TestSuite_softnic.py b/tests/TestSuite_softnic.py\nindex e379125d..94814bd7 100644\n--- a/tests/TestSuite_softnic.py\n+++ b/tests/TestSuite_softnic.py\n@@ -7,233 +7,263 @@ DPDK Test suite.\n Test softnic API in DPDK.\n \"\"\"\n \n+import itertools\n import os\n import re\n import string\n import time\n+import traceback\n+from time import sleep\n+\n+import scapy.layers.inet\n+from scapy.arch import get_if_hwaddr\n+from scapy.packet import Raw, bind_layers\n+from scapy.route import *\n+from scapy.sendrecv import sendp, sniff\n+from scapy.utils import hexstr, rdpcap, wrpcap\n \n import framework.utils as utils\n-from framework.pktgen import PacketGeneratorHelper\n from framework.pmd_output import PmdOutput\n-from framework.settings import HEADER_SIZE\n from framework.test_case import TestCase\n \n \n class TestSoftnic(TestCase):\n-    def set_up_all(self):\n+    def pair_hex_digits(self, iterable, count, fillvalue=None):\n+        args = [iter(iterable)] * count\n+        return itertools.zip_longest(*args, fillvalue=fillvalue)\n+\n+    def get_flow_direction_param_of_tcpdump(self):\n+        \"\"\"\n+        get flow dirction param depend on tcpdump version\n+        \"\"\"\n+        param = \"\"\n+        direct_param = r\"(\\s+)\\[ (\\S+) in\\|out\\|inout \\]\"\n+        out = self.tester.send_expect(\"tcpdump -h\", \"# \", trim_whitespace=False)\n+        for line in out.split(\"\\n\"):\n+            m = re.match(direct_param, line)\n+            if m:\n+                opt = re.search(\"-Q\", m.group(2))\n+                if opt:\n+                    param = \"-Q\" + \" in\"\n+                else:\n+                    opt = re.search(\"-P\", m.group(2))\n+                    if opt:\n+                        param = \"-P\" + \" in\"\n+        if len(param) == 0:\n+            self.logger.info(\"tcpdump not support direction choice!!!\")\n+        return param\n+\n+    def tcpdump_start_sniff(self, interface, filters=\"\"):\n+        \"\"\"\n+        Starts tcpdump in the background to sniff packets that received by interface.\n+        \"\"\"\n+        cmd = \"rm -f /tmp/tcpdump_{0}.pcap\".format(interface)\n+        self.tester.send_expect(cmd, \"#\")\n+        cmd = \"tcpdump -nn -e {0} -w /tmp/tcpdump_{1}.pcap -i {1} {2} -Q in 2>/tmp/tcpdump_{1}.out &\".format(\n+            self.param_flow_dir, interface, filters\n+        )\n+        self.tester.send_expect(cmd, \"# \")\n+\n+    def tcpdump_stop_sniff(self):\n+        \"\"\"\n+        Stops the tcpdump process running in the background.\n+        \"\"\"\n+        self.tester.send_expect(\"killall tcpdump\", \"# \")\n+        # For the [pid]+ Done tcpdump... message after killing the process\n+        sleep(1)\n+        self.tester.send_expect('echo \"Cleaning buffer\"', \"# \")\n+        sleep(1)\n+\n+    def compare_packets(self, in_file, out_file, all_pkts):\n+        \"\"\"\n+        Flag all_pkt is zero, then it compares small packet(size upto 48 bytes).\n+        Flag all_pkt is non-zero, then it compares all packets of out_file.\n+        \"\"\"\n+        if all_pkts == 0:\n+            cmd = \"diff -sqw <(head -n 11 {}) <(head -n 11 {})\".format(\n+                in_file, out_file\n+            )\n+        else:\n+            cmd = \"diff -sqw {} {}\".format(in_file, out_file)\n+        return self.tester.send_command(cmd, timeout=0.5)\n+\n+    def convert_tcpdump_to_text2pcap(self, in_filename, out_filename):\n+        with open(in_filename) as input, open(out_filename, \"w\") as output:\n+            output.write(\"# SPDX-License-Identifier: BSD-3-Clause\\n\")\n+            output.write(\"# Copyright(c) 2022 Intel Corporation\\n\")\n+            output.write(\"#\\n\\n\")\n+            output.write(\"# text to pcap: text2pcap packet.txt packet.pcap\\n\")\n+            output.write(\"# pcap to text: tcpdump -r packet.pcap -xx\\n\\n\")\n+\n+            i = 0\n+            for line in input:\n+                time = self.pkt_timestamp.match(line)\n+                if time:\n+                    output.write(\"# Packet {}\\n\".format(i))\n+                    i += 1\n+                    continue\n+                payload = self.pkt_content.match(line)\n+                if payload:\n+                    address = payload.group(1)\n+                    hex_data = payload.group(2).replace(\" \", \"\")\n+                    hex_data = \" \".join(\n+                        \"\".join(part) for part in self.pair_hex_digits(hex_data, 2, \" \")\n+                    )\n+                    output.write(\"{:0>6}  {:<47}\\n\".format(address, hex_data))\n+\n+    def send_and_sniff(\n+        self, from_port, to_port, in_pcap, out_pcap, filters, all_pkts=0\n+    ):\n+        self.tester.send_expect(\"rm -f /tmp/*.txt /tmp/*.pcap /tmp/*.out\", \"# \")\n+        tx_count = len(from_port)\n+        rx_count = len(to_port)\n+        tx_port, rx_port, tx_inf, rx_inf = ([] for i in range(4))\n+\n+        for i in range(tx_count):\n+            tx_port.append(self.tester.get_local_port(self.dut_ports[from_port[i]]))\n+            tx_inf.append(self.tester.get_interface(tx_port[i]).strip())\n+\n+        for i in range(rx_count):\n+            rx_port.append(self.tester.get_local_port(self.dut_ports[to_port[i]]))\n+            rx_inf.append(self.tester.get_interface(rx_port[i]).strip())\n+            self.tcpdump_start_sniff(rx_inf[i], filters[i])\n+\n+        self.tester.scapy_foreground()\n+        for i in range(tx_count):\n+            self.tester.send_expect(\n+                \"text2pcap -q {} /tmp/tx_{}.pcap\".format(\n+                    self.src_path + in_pcap[i], tx_inf[i]\n+                ),\n+                \"# \",\n+            )\n+            self.tester.scapy_append(\n+                'pkt = rdpcap(\"/tmp/tx_{}.pcap\")'.format(tx_inf[i])\n+            )\n+\n+            self.tester.scapy_append(\n+                'sendp(pkt, iface=\"{}\", count=32)'.format(tx_inf[i])\n+            )\n+\n+        self.tester.scapy_execute()\n+        self.tcpdump_stop_sniff()\n+        mismatch_count = 0\n+\n+        for i in range(rx_count):\n+            self.tester.send_expect(\n+                \"tcpdump -n -r /tmp/tcpdump_{}.pcap -xx > /tmp/packet_rx.txt\".format(\n+                    rx_inf[i]\n+                ),\n+                \"# \",\n+            )\n+            self.convert_tcpdump_to_text2pcap(\n+                \"/tmp/packet_rx.txt\", \"/tmp/packet_rx_rcv_{}.txt\".format(rx_inf[i])\n+            )\n+            out = self.compare_packets(\n+                \"/tmp/packet_rx_rcv_{}.txt\".format(rx_inf[i]),\n+                self.src_path + out_pcap[i],\n+                all_pkts,\n+            )\n+            if \"are identical\" not in out:\n+                return False\n+        return True\n \n+    def set_up_all(self):\n         # Based on h/w type, choose how many ports to use\n-        ports = self.dut.get_ports()\n-        self.dut_ports = self.dut.get_ports(self.nic)\n+        self.dut_ports = self.dut.get_ports()\n \n         # Verify that enough ports are available\n-        self.verify(len(ports) >= 1, \"Insufficient ports for testing\")\n-        self.def_driver = self.dut.ports_info[ports[0]][\"port\"].get_nic_driver()\n-        self.ports_socket = self.dut.get_numa_id(ports[0])\n+        self.verify(len(self.dut_ports) >= 1, \"Insufficient ports for testing\")\n+        self.def_driver = self.dut.ports_info[self.dut_ports[0]][\n+            \"port\"\n+        ].get_nic_driver()\n+        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])\n         # Verify that enough threads are available\n         cores = self.dut.get_core_list(\"1S/1C/1T\")\n         self.verify(cores is not None, \"Insufficient cores for speed testing\")\n-        global P0\n-        P0 = ports[0]\n-\n-        self.txItf = self.tester.get_interface(self.tester.get_local_port(P0))\n-        self.dmac = self.dut.get_mac_address(P0)\n-        self.headers_size = HEADER_SIZE[\"eth\"] + HEADER_SIZE[\"ip\"] + HEADER_SIZE[\"udp\"]\n-\n-        # need change config files\n-        self.root_path = \"/tmp/\"\n-        self.firmware = r\"dep/firmware.cli\"\n-        self.tm_firmware = r\"dep/tm_firmware.cli\"\n-        self.nat_firmware = r\"dep/nat_firmware.cli\"\n-        self.dut.session.copy_file_to(self.firmware, self.root_path)\n-        self.dut.session.copy_file_to(self.tm_firmware, self.root_path)\n-        self.dut.session.copy_file_to(self.nat_firmware, self.root_path)\n-        self.eal_param = \" -a %s\" % self.dut.ports_info[0][\"pci\"]\n+        self.param_flow_dir = self.get_flow_direction_param_of_tcpdump()\n+\n+        # setting up source and destination location\n+        self.dst_path = \"/tmp/\"\n+        FILE_DIR = os.path.dirname(os.path.abspath(__file__)).split(os.path.sep)\n+        self.src_path = os.path.sep.join(FILE_DIR[:-1]) + \"/dep/\"\n+        SOFTNIC_TAR_FOLDER = self.src_path + \"softnic\"\n+\n+        # copy dependancies to the DUT\n+        self.tester.send_expect(\"rm -rf /tmp/softnic.tar.gz\", \"# \")\n+        self.tester.send_expect(\n+            \"tar -zcf /tmp/softnic.tar.gz --absolute-names {}\".format(self.src_path),\n+            \"# \",\n+            20,\n+        )\n+        self.dut.send_expect(\"rm -rf /tmp/softnic.tar.gz /tmp/softnic\", \"# \", 20)\n+        self.dut.session.copy_file_to(\"/tmp/softnic.tar.gz\", self.dst_path)\n+        self.dut.send_expect(\n+            \"tar -zxf /tmp/softnic.tar.gz --strip-components={} --absolute-names --directory /tmp\".format(\n+                SOFTNIC_TAR_FOLDER.count(\"/\") - 1\n+            ),\n+            \"# \",\n+            20,\n+        )\n+\n+        self.eal_param = \" \".join(\n+            \" -a \" + port_info[\"pci\"] for port_info in self.dut.ports_info\n+        )\n         self.path = self.dut.apps_name[\"test-pmd\"]\n         self.pmdout = PmdOutput(self.dut)\n+\n+        # create packet matching regular expression\n+        self.pkt_timestamp = re.compile(r\"\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{6}\")\n+        self.pkt_content = re.compile(r\"\\t0x([0-9a-fA-F]+):  ([0-9a-fA-F ]+)\")\n+\n         # get dts output path\n         if self.logger.log_path.startswith(os.sep):\n             self.output_path = self.logger.log_path\n         else:\n             cur_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))\n             self.output_path = os.sep.join([cur_path, self.logger.log_path])\n-        # create an instance to set stream field setting\n-        self.pktgen_helper = PacketGeneratorHelper()\n-        self.dut.bind_interfaces_linux(self.drivername, [ports[0]])\n+        # bind the ports\n+        self.dut.bind_interfaces_linux(self.drivername, [self.dut_ports[0]])\n \n     def set_up(self):\n         \"\"\"\n         Run before each test case.\n         \"\"\"\n \n-    def change_config_file(self, file_name):\n-        self.dut.send_expect(\n-            \"sed -i -e '4c link LINK0 dev %s' %s\"\n-            % (self.dut.ports_info[0][\"pci\"], self.root_path + file_name),\n-            \"#\",\n-        )\n-        self.dut.send_expect(\n-            \"sed -i -e 's/thread [0-9]/thread 2/g' %s\" % self.root_path + file_name, \"#\"\n-        )\n+    def run_test_pmd(self, file_name):\n+        try:\n+            cmd = 'test -f {} && echo \"File exists!\"'.format(file_name)\n+            self.dut.send_expect(cmd, \"File exists!\", 1)\n \n-    def test_perf_softnic_performance(self):\n-        self.frame_size = [64, 128, 256, 512, 1024, 1280, 1518]\n-        self.change_config_file(\"firmware.cli\")\n-        # 10G nic pps(M)\n-        expect_pps = [14, 8, 4, 2, 1, 0.9, 0.8]\n-\n-        self.pmdout.start_testpmd(\n-            list(range(3)),\n-            \"--forward-mode=softnic --portmask=0x2\",\n-            eal_param=\"-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'\"\n-            % (self.eal_param, \"firmware.cli\"),\n-        )\n-        self.dut.send_expect(\"start\", \"testpmd>\")\n-        rx_port = self.tester.get_local_port(0)\n-        tx_port = self.tester.get_local_port(0)\n-        n = 0\n-        for frame in self.frame_size:\n-            payload_size = frame - self.headers_size\n-            tgen_input = []\n-            pcap = os.sep.join([self.output_path, \"test.pcap\"])\n-            pkt = \"Ether(dst='%s')/IP()/UDP()/Raw(load='x'*%d)\" % (\n-                self.dmac,\n-                payload_size,\n+            self.pmdout.start_testpmd(\n+                list(range(3)),\n+                \"--portmask=0x2\",\n+                eal_param=\"-s 0x4 %s --vdev 'net_softnic0,firmware=%s,cpu_id=1,conn_port=8086'\"\n+                % (self.eal_param, file_name),\n             )\n-            self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap, pkt))\n-            tgen_input.append((tx_port, rx_port, pcap))\n-            self.tester.scapy_execute()\n-            # clear streams before add new streams\n-            self.tester.pktgen.clear_streams()\n-            # run packet generator\n-            streams = self.pktgen_helper.prepare_stream_from_tginput(\n-                tgen_input, 100, None, self.tester.pktgen\n-            )\n-            _, pps = self.tester.pktgen.measure_throughput(stream_ids=streams)\n-            pps = pps / 1000000.0\n-            self.verify(pps > 0, \"No traffic detected\")\n-            self.verify(pps > expect_pps[n], \"No traffic detected\")\n-            n = n + 1\n-\n-    def test_perf_shaping_for_pipe(self):\n-        self.change_config_file(\"tm_firmware.cli\")\n-        self.pmdout.start_testpmd(\n-            list(range(3)),\n-            \"--forward-mode=softnic --portmask=0x2\",\n-            eal_param=\"-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'\"\n-            % (self.eal_param, \"tm_firmware.cli\"),\n-        )\n+        except Exception:\n+            trace = traceback.format_exc()\n+            self.logger.error(\"Error while running testpmd:\\n\" + trace)\n+\n+    def test_rx_tx(self):\n+        cli_file = \"/tmp/softnic/rx_tx/rx_tx.cli\"\n+        self.run_test_pmd(cli_file)\n+        sleep(5)\n         self.dut.send_expect(\"start\", \"testpmd>\")\n-        rx_port = self.tester.get_local_port(0)\n-        pkts = [\n-            \"Ether(dst='%s')/IP(dst='100.0.0.0')/UDP()/Raw(load='x'*(64 - %s))\",\n-            \"Ether(dst='%s')/IP(dst='100.0.15.255')/UDP()/Raw(load='x'*(64 - %s))\",\n-            \"Ether(dst='%s')/IP(dst='100.0.4.0')/UDP()/Raw(load='x'*(64 - %s))\",\n-        ]\n-        except_bps_range = [1700000, 2000000]\n-\n-        for i in range(3):\n-            tgen_input = []\n-            pcap = os.sep.join([self.output_path, \"test.pcap\"])\n-            pkt = pkts[i] % (self.dmac, self.headers_size)\n-            self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap, pkt))\n-            self.tester.scapy_execute()\n-            if i == 2:\n-                for j in range(16):\n-                    pk = (\n-                        \"Ether(dst='%s')/IP(dst='100.0.15.%d')/UDP()/Raw(load='x'*(64 - %s))\"\n-                        % (self.dmac, j, self.headers_size)\n-                    )\n-                    self.tester.scapy_append(\n-                        'wrpcap(\"%s/test_%d.pcap\", [%s])' % (self.output_path, j, pk)\n-                    )\n-                    self.tester.scapy_execute()\n-                    tgen_input.append(\n-                        (rx_port, rx_port, \"%s/test_%d.pcap\" % (self.output_path, j))\n-                    )\n-            else:\n-                tgen_input.append((rx_port, rx_port, pcap))\n-            # clear streams before add new streams\n-            self.tester.pktgen.clear_streams()\n-            # run packet generator\n-            streams = self.pktgen_helper.prepare_stream_from_tginput(\n-                tgen_input, 100, None, self.tester.pktgen\n-            )\n-            bps, pps = self.tester.pktgen.measure_throughput(stream_ids=streams)\n-            if i == 2:\n-                self.verify(\n-                    except_bps_range[1] * 16 > bps > except_bps_range[0] * 16,\n-                    \"No traffic detected\",\n-                )\n-            else:\n-                self.verify(\n-                    except_bps_range[1] > bps > except_bps_range[0],\n-                    \"No traffic detected\",\n-                )\n-\n-    def test_nat(self):\n-        self.change_config_file(\"nat_firmware.cli\")\n-        expect_ips = [\"192.168.0.1.5000\", \"192.168.0.2.5001\"]\n-        ips = [\"100.0.0.1\", \"100.0.0.2\"]\n-        pkt_location = [\"src\", \"dst\"]\n-        pkt_type = [\"tcp\", \"udp\"]\n-        for t in pkt_type:\n-            for i in range(2):\n-                self.dut.send_expect(\n-                    \"sed -i -e '12c table action profile AP0 ipv4 offset 270 fwd nat %s proto %s' %s\"\n-                    % (pkt_location[i], t, self.root_path + \"nat_firmware.cli\"),\n-                    \"#\",\n-                )\n-                self.pmdout.start_testpmd(\n-                    list(range(3)),\n-                    \"--forward-mode=softnic --portmask=0x2\",\n-                    eal_param=\"-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'\"\n-                    % (self.eal_param, \"nat_firmware.cli\"),\n-                )\n-                if self.nic in [\n-                    \"ICE_100G-E810C_QSFP\",\n-                    \"ICE_25G-E810C_SFP\",\n-                    \"ICE_25G-E810_XXV_SFP\",\n-                ]:\n-                    self.dut.send_expect(\"set fwd mac\", \"testpmd>\")\n-                self.dut.send_expect(\"start\", \"testpmd>\")\n-                # src ip tcp\n-                for j in range(2):\n-                    out = self.scapy_send_packet(pkt_location[i], ips[j], t)\n-                    self.verify(expect_ips[j] in out, \"fail to receive expect packet\")\n-                self.dut.send_expect(\"quit\", \"# \")\n-                time.sleep(1)\n-\n-    def scapy_send_packet(self, pkt_location, ip, pkt_type):\n-        self.tester.scapy_foreground()\n-        pkt = \"Ether(dst='%s')/IP(dst='%s')/\" % (self.dmac, ip)\n-        if pkt_type == \"tcp\":\n-            pkt = pkt + \"TCP()/Raw(load='x'*20)\"\n-        else:\n-            pkt = pkt + \"UDP()/Raw(load='x'*20)\"\n \n-        self.tester.scapy_append('sendp([%s], iface=\"%s\")' % (pkt, self.txItf))\n-        self.start_tcpdump(self.txItf)\n-        self.tester.scapy_execute()\n-        out = self.get_tcpdump_package()\n-        return out\n-\n-    def get_tcpdump_package(self):\n-        time.sleep(4)\n-        self.tester.send_expect(\"killall tcpdump\", \"#\")\n-        out = self.tester.send_expect(\n-            \"tcpdump -A -nn -e -vv -r getPackageByTcpdump.cap |grep '192.168'\", \"#\"\n-        )\n-        return out\n+        in_pcap = [\"softnic/rx_tx/pcap_files/in.txt\"]\n+        out_pcap = [\"softnic/rx_tx/pcap_files/out.txt\"]\n+        filters = [\"tcp\"]\n+        tx_port = [0]\n+        rx_port = [0]\n+        result = self.send_and_sniff(tx_port, rx_port, in_pcap, out_pcap, filters)\n+        if result:\n+            self.dut.send_expect(\"stop\", \"testpmd>\")\n+        else:\n+            self.verify(False, \"Output pcap files mismatch error\")\n \n-    def start_tcpdump(self, rxItf):\n-        self.tester.send_expect(\"rm -rf getPackageByTcpdump.cap\", \"#\")\n-        self.tester.send_expect(\n-            \"tcpdump -A -nn -e -vv -w getPackageByTcpdump.cap -i %s 2> /dev/null& \"\n-            % self.txItf,\n-            \"#\",\n-        )\n-        time.sleep(4)\n+        \"\"\"\n+        Add new test cases here.\n+        \"\"\"\n \n     def tear_down(self):\n         \"\"\"\n@@ -245,6 +275,4 @@ class TestSoftnic(TestCase):\n         \"\"\"\n         Run after each test suite.\n         \"\"\"\n-        self.dut.bind_interfaces_linux(\n-            driver=self.def_driver, nics_to_bind=self.dut.get_ports()\n-        )\n+        self.dut.kill_all()\n",
    "prefixes": [
        "3/3"
    ]
}