aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/libraries/python/CpuUtils.py33
-rw-r--r--resources/libraries/robot/default.robot27
-rw-r--r--resources/libraries/robot/performance.robot68
-rwxr-xr-xresources/tools/t-rex/t-rex-stateless.py4
-rw-r--r--tests/perf/Long_Xconnect_Intel-XL710.robot253
5 files changed, 337 insertions, 48 deletions
diff --git a/resources/libraries/python/CpuUtils.py b/resources/libraries/python/CpuUtils.py
index a8698dfd54..85c2e843e4 100644
--- a/resources/libraries/python/CpuUtils.py
+++ b/resources/libraries/python/CpuUtils.py
@@ -98,3 +98,36 @@ class CpuUtils(object):
raise RuntimeError("Node cpuinfo not available.")
return cpulist
+
+ @staticmethod
+ def cpu_list_per_node_str(node, cpu_node, skip_cnt=0,
+ cpu_cnt=0, sep=","):
+ """Return string of node related list of CPU numbers.
+
+ :param node: Node dictionary with cpuinfo.
+ :param cpu_node: Numa node number.
+ :param skip_cnt: Skip first "skip_cnt" CPUs.
+ :param cpu_cnt: Count of cpus to return, if 0 then return all.
+ :param sep: Separator, default: 1,2,3,4,....
+ :type node: dict
+ :type cpu_node: int
+ :type skip_cnt: int
+ :type cpu_cnt: int
+ :type sep: str
+ :return: Cpu numbers related to numa from argument.
+ :rtype: str
+ """
+
+ cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node)
+ cpu_list_len = len(cpu_list)
+ cpu_flist = ""
+ if cpu_cnt == 0:
+ cpu_cnt = cpu_list_len - skip_cnt
+
+ if cpu_cnt + skip_cnt > cpu_list_len:
+ raise RuntimeError("cpu_cnt + skip_cnt > length(cpu list).")
+
+ cpu_flist = sep.join(str(a) for a in
+ cpu_list[skip_cnt:skip_cnt+cpu_cnt])
+
+ return cpu_flist
diff --git a/resources/libraries/robot/default.robot b/resources/libraries/robot/default.robot
index 3135ef0041..742906e94a 100644
--- a/resources/libraries/robot/default.robot
+++ b/resources/libraries/robot/default.robot
@@ -14,6 +14,7 @@
*** Settings ***
| Variables | resources/libraries/python/topology.py
| Library | resources.libraries.python.topology.Topology
+| Library | resources.libraries.python.CpuUtils
| Library | resources.libraries.python.DUTSetup
| Library | resources.libraries.python.TGSetup
| Library | resources/libraries/python/VppConfigGenerator.py
@@ -41,6 +42,32 @@
| | | Vpp api trace save | ${nodes['${dut}']}
| | | Vpp api trace dump | ${nodes['${dut}']}
+| Add '${m}' worker threads and rxqueues '${n}' in 3-node single-link topo
+| | [Documentation] | Setup M worker threads and N rxqueues in vpp startup
+| | ... | configuration on all DUTs in 3-node single-link topology.
+| | ${m_int}= | Convert To Integer | ${m}
+| | ${dut1_numa}= | Get interfaces numa node | ${dut1}
+| | ... | ${dut1_if1} | ${dut1_if2}
+| | ${dut2_numa}= | Get interfaces numa node | ${dut2}
+| | ... | ${dut2_if1} | ${dut2_if2}
+| | ${dut1_cpu_main}= | Cpu list per node str | ${dut1} | ${dut1_numa}
+| | ... | cpu_cnt=${1}
+| | ${dut1_cpu_w}= | Cpu list per node str | ${dut1} | ${dut1_numa}
+| | ... | skip_cnt=${1} | cpu_cnt=${m_int}
+| | ${dut2_cpu_main}= | Cpu list per node str | ${dut2} | ${dut2_numa}
+| | ... | cpu_cnt=${1}
+| | ${dut2_cpu_w}= | Cpu list per node str | ${dut2} | ${dut2_numa}
+| | ... | skip_cnt=${1} | cpu_cnt=${m_int}
+| | ${dut1_cpu}= | Catenate | main-core | ${dut1_cpu_main}
+| | ... | corelist-workers | ${dut1_cpu_w}
+| | ${dut2_cpu}= | Catenate | main-core | ${dut2_cpu_main}
+| | ... | corelist-workers | ${dut2_cpu_w}
+| | ${rxqueues}= | Catenate | num-rx-queues | ${n}
+| | Add CPU config | ${dut1} | ${dut1_cpu}
+| | Add CPU config | ${dut2} | ${dut2_cpu}
+| | Add rxqueues config | ${dut1} | ${rxqueues}
+| | Add rxqueues config | ${dut2} | ${rxqueues}
+
| Add '${m}' worker threads and rxqueues '${n}' without HTT to all DUTs
| | [Documentation] | Setup M worker threads without HTT and rxqueues N in
| | ... | startup configuration of VPP to all DUTs
diff --git a/resources/libraries/robot/performance.robot b/resources/libraries/robot/performance.robot
index 0ef07ebefc..62b175668d 100644
--- a/resources/libraries/robot/performance.robot
+++ b/resources/libraries/robot/performance.robot
@@ -75,6 +75,8 @@
| | ... | for 40GE with 9004B L2 Frame.
| | ... | - 40Ge_linerate_pps_9008B - Maximum number of packet per second
| | ... | for 40GE with 9008B L2 Frame.
+| | ... | - 40Ge_linerate_pps_IMIX_v4_1 - Maximum number of packet per second
+| | ... | for 40GE with IMIX_v4_1 profile.
| | ...
| | Set Suite Variable | ${10Ge_linerate_pps_64B} | 14880952
| | Set Suite Variable | ${10Ge_linerate_pps_68B} | 14204545
@@ -95,6 +97,26 @@
| | Set Suite Variable | ${40Ge_linerate_pps_9000B} | 554323
| | Set Suite Variable | ${40Ge_linerate_pps_9004B} | 554078
| | Set Suite Variable | ${40Ge_linerate_pps_9008B} | 553832
+| | Set Suite Variable | ${40Ge_linerate_pps_IMIX_v4_1} | 13374944
+
+| Calculate pps
+| | [Documentation]
+| | ... | Calculate pps for given rate and L2 frame size,
+| | ... | additional 20B are added to L2 frame size as padding.
+| | ...
+| | ... | *Arguments*
+| | ... | - bps - Rate in bps. Type: integer
+| | ... | - framesize - L2 frame size in Bytes. Type: integer
+| | ...
+| | ... | *Return*
+| | ... | - Calculated pps. Type: integer
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Calculate pps \| 10000000000 | 64
+| | [Arguments] | ${bps} | ${framesize}
+| | ${ret}= | Evaluate | (${bps}/((${framesize}+20)*8)).__trunc__()
+| | Return From Keyword | ${ret}
| Get Frame Size
| | [Documentation]
@@ -465,52 +487,6 @@
| | Vpp l2bd forwarding setup | ${dut2} | ${dut2_if1} | ${dut2_if2}
| | All Vpp Interfaces Ready Wait | ${nodes}
-| 2-node Performance Suite Setup
-| | [Documentation]
-| | ... | Suite preparation phase that setup default startup configuration of
-| | ... | VPP on all DUTs. Updates interfaces on all nodes and setup global
-| | ... | variables used in test cases. Initializes traffic generator.
-| | ...
-| | ... | *Arguments:*
-| | ... | - topology_type - Topology type. Type: string
-| | ...
-| | ... | *Example:*
-| | ...
-| | ... | \| 2-node Performance Suite Setup \| L2 \|
-| | [Arguments] | ${topology_type}
-| | Setup default startup configuration of VPP on all DUTs
-| | Show vpp version on all DUTs
-| | Setup performance rate Variables
-| | Setup performance global Variables
-| | 2-node circular Topology Variables Setup
-| | Initialize traffic generator | ${tg} | ${tg_if1} | ${tg_if2}
-| | ... | ${dut1} | ${dut1_if1}
-| | ... | ${dut1} | ${dut1_if2}
-| | ... | ${topology_type}
-
-| 3-node Performance Suite Setup
-| | [Documentation]
-| | ... | Suite preparation phase that setup default startup configuration of
-| | ... | VPP on all DUTs. Updates interfaces on all nodes and setup global
-| | ... | variables used in test cases. Initializes traffic generator.
-| | ...
-| | ... | *Arguments:*
-| | ... | - topology_type - Topology type. Type: string
-| | ...
-| | ... | *Example:*
-| | ...
-| | ... | \| 3-node Performance Suite Setup \| L2 \|
-| | [Arguments] | ${topology_type}
-| | Setup default startup configuration of VPP on all DUTs
-| | Show vpp version on all DUTs
-| | Setup performance rate Variables
-| | Setup performance global Variables
-| | 3-node circular Topology Variables Setup
-| | Initialize traffic generator | ${tg} | ${tg_if1} | ${tg_if2}
-| | ... | ${dut1} | ${dut1_if1}
-| | ... | ${dut2} | ${dut2_if2}
-| | ... | ${topology_type}
-
2-node Performance Suite Setup with DUT's NIC model
| | [Documentation]
| | ... | Suite preparation phase that setup default startup configuration of
diff --git a/resources/tools/t-rex/t-rex-stateless.py b/resources/tools/t-rex/t-rex-stateless.py
index 6c7579d0c3..f456b66316 100755
--- a/resources/tools/t-rex/t-rex-stateless.py
+++ b/resources/tools/t-rex/t-rex-stateless.py
@@ -380,7 +380,7 @@ def simple_burst(stream_a, stream_b, stream_lat_a, stream_lat_b, duration, rate,
if client.get_warnings():
for warning in client.get_warnings():
- print_error(warning)
+ print(warning)
# read the stats after the test
stats = client.get_stats()
@@ -408,7 +408,7 @@ def simple_burst(stream_a, stream_b, stream_lat_a, stream_lat_b, duration, rate,
if client.get_warnings():
for warning in client.get_warnings():
- print_error(warning)
+ print(warning)
# read the stats after the test
stats = client.get_stats()
diff --git a/tests/perf/Long_Xconnect_Intel-XL710.robot b/tests/perf/Long_Xconnect_Intel-XL710.robot
new file mode 100644
index 0000000000..d39fde9f2d
--- /dev/null
+++ b/tests/perf/Long_Xconnect_Intel-XL710.robot
@@ -0,0 +1,253 @@
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+*** Settings ***
+| Resource | resources/libraries/robot/performance.robot
+| Library | resources.libraries.python.InterfaceUtil
+| Library | resources.libraries.python.NodePath
+| Force Tags | 3_NODE_SINGLE_LINK_TOPO | PERFTEST | HW_ENV | PERFTEST_LONG
+| ... | NIC_Intel-XL710
+| Suite Setup | 3-node Performance Suite Setup with DUT's NIC model
+| ... | L2 | Intel-XL710
+| Suite Teardown | 3-node Performance Suite Teardown
+| Test Setup | Setup all DUTs before test
+| Test Teardown | Run Keywords | Remove startup configuration of VPP from all DUTs
+| ... | AND | Show vpp trace dump on all DUTs
+| Documentation | *RFC2544: Pkt throughput L2XC test cases*
+| ...
+| ... | *[Top] Network Topologies:* TG-DUT1-DUT2-TG 3-node circular topology
+| ... | with single links between nodes.
+| ... | *[Enc] Packet Encapsulations:* Eth-IPv4 for L2 cross connect.
+| ... | *[Cfg] DUT configuration:* DUT1 and DUT2 are configured with L2 cross-
+| ... | connect. DUT1 and DUT2 tested with 2p10GE NIC X520 Niantic by Intel.
+| ... | *[Ver] TG verification:* TG finds and reports throughput NDR (Non Drop
+| ... | Rate) with zero packet loss tolerance or throughput PDR (Partial Drop
+| ... | Rate) with non-zero packet loss tolerance (LT) expressed in percentage
+| ... | of packets transmitted. NDR and PDR are discovered for different
+| ... | Ethernet L2 frame sizes using either binary search or linear search
+| ... | algorithms with configured starting rate and final step that determines
+| ... | throughput measurement resolution. Test packets are generated by TG on
+| ... | links to DUTs. TG traffic profile contains two L3 flow-groups
+| ... | (flow-group per direction, 253 flows per flow-group) with all packets
+| ... | containing Ethernet header, IPv4 header with IP protocol=61 and static
+| ... | payload. MAC addresses are matching MAC addresses of the TG node
+| ... | interfaces.
+| ... | *[Ref] Applicable standard specifications:* RFC2544.
+
+*** Variables ***
+#XL710-DA2 bandwidth limit ~49Gbps/2=24.5Gbps
+| ${s_24.5G} | ${24500000000}
+#XL710-DA2 Mpps limit 37.5Mpps/2=18.75Mpps
+| ${s_18.75Mpps} | ${18750000}
+
+*** Test Cases ***
+| TC01: 64B NDR binary search - DUT L2XC - 1thread 1core 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 1 thread, 1 phy core, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for 64 Byte frames
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | [Tags] | 1_THREAD_NOHTT_RXQUEUES_1 | SINGLE_THREAD | NDR
+| | ${framesize}= | Set Variable | 64
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Set Variable | ${s_18.75Mpps}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '1' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC03: 1518B NDR binary search - DUT L2XC - 1thread 1core 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 1 thread, 1 phy core, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for 1518 Byte frames
+| | ... | using binary search start at 10GE linerate, step 10kpps.
+| | [Tags] | 1_THREAD_NOHTT_RXQUEUES_1 | SINGLE_THREAD | NDR
+| | ${framesize}= | Set Variable | 1518
+| | ${min_rate}= | Set Variable | 10000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${framesize}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '1' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC07: 64B NDR binary search - DUT L2XC - 2threads 2cores 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 2 threads, 2 phy cores, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for 64 Byte frames
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | [Tags] | 2_THREAD_NOHTT_RXQUEUES_1 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | 64
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Set Variable | ${s_18.75Mpps}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '2' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC09: 1518B NDR binary search - DUT L2XC - 2threads 2cores 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 2 threads, 2 phy cores, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for 1518 Byte frames
+| | ... | using binary search start at 10GE linerate, step 10kpps.
+| | [Tags] | 2_THREAD_NOHTT_RXQUEUES_1 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | 1518
+| | ${min_rate}= | Set Variable | 10000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${framesize}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '2' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC13: 64B NDR binary search - DUT L2XC - 4threads 4cores 2rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 4 threads, 4 phy cores, \
+| | ... | 2 receive queues per NIC port. [Ver] Find NDR for 64 Byte frames
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | [Tags] | 4_THREAD_NOHTT_RXQUEUES_2 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | 64
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Set Variable | ${s_18.75Mpps}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '4' worker threads and rxqueues '2' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC15: 1518B NDR binary search - DUT L2XC - 4threads 4cores 2rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 4 threads, 4 phy cores, \
+| | ... | 2 receive queues per NIC port. [Ver] Find NDR for 1518 Byte frames
+| | ... | using binary search start at 10GE linerate, step 10kpps.
+| | [Tags] | 4_THREAD_NOHTT_RXQUEUES_2 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | 1518
+| | ${min_rate}= | Set Variable | 10000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${framesize}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '4' worker threads and rxqueues '2' in 3-node single-link topo
+| | And Add PCI devices to DUTs from 3-node single link topology
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC19: IMIX_v4_1 NDR binary search - DUT L2XC - 1thread 1core 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 1 thread, 1 phy core, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for IMIX_v4_1 frame size
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | ... | IMIX_v4_1 = (28x64B;16x570B;4x1518B)
+| | [Tags] | 1_THREAD_NOHTT_RXQUEUES_1 | SINGLE_THREAD | NDR
+| | ${framesize}= | Set Variable | IMIX_v4_1
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${353.83333}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '1' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add all PCI devices to all DUTs
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC20: IMIX_v4_1 NDR binary search - DUT L2XC - 2threads 2cores 1rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 2 thread, 2 phy core, \
+| | ... | 1 receive queue per NIC port. [Ver] Find NDR for IMIX_v4_1 frame size
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | ... | IMIX_v4_1 = (28x64B;16x570B;4x1518B)
+| | [Tags] | 2_THREAD_NOHTT_RXQUEUES_1 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | IMIX_v4_1
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${353.83333}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '2' worker threads and rxqueues '1' in 3-node single-link topo
+| | And Add all PCI devices to all DUTs
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}
+
+| TC21: IMIX_v4_1 NDR binary search - DUT L2XC - 4threads 4cores 2rxq
+| | [Documentation]
+| | ... | [Cfg] DUT runs L2XC switching config with 4 thread, 4 phy core, \
+| | ... | 2 receive queue per NIC port. [Ver] Find NDR for IMIX_v4_1 frame size
+| | ... | using binary search start at 10GE linerate, step 100kpps.
+| | ... | IMIX_v4_1 = (28x64B;16x570B;4x1518B)
+| | [Tags] | 4_THREAD_NOHTT_RXQUEUES_2 | MULTI_THREAD | NDR
+| | ${framesize}= | Set Variable | IMIX_v4_1
+| | ${min_rate}= | Set Variable | 100000
+| | ${max_rate}= | Calculate pps | ${s_24.5G} | ${353.83333}
+| | ${binary_min}= | Set Variable | ${min_rate}
+| | ${binary_max}= | Set Variable | ${max_rate}
+| | ${threshold}= | Set Variable | ${min_rate}
+| | Given Add '4' worker threads and rxqueues '2' in 3-node single-link topo
+| | And Add all PCI devices to all DUTs
+| | And Add No Multi Seg to all DUTs
+| | And Apply startup configuration on all VPP DUTs
+| | And L2 xconnect initialized in a 3-node circular topology
+| | Then Find NDR using binary search and pps | ${framesize} | ${binary_min}
+| | ... | ${binary_max} | 3-node-xconnect
+| | ... | ${min_rate} | ${max_rate}
+| | ... | ${threshold}