perf: add TCP Iperf3+LDPRELOAD test suite 52/24252/20
authorDave Wallace <dwallacelf@gmail.com>
Wed, 8 Jan 2020 20:51:43 +0000 (20:51 +0000)
committerPeter Mikus <pmikus@cisco.com>
Fri, 17 Jan 2020 13:51:48 +0000 (13:51 +0000)
Change-Id: Icff49fb31cce342a2a4ae799e844ec91f9e5e366
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
resources/libraries/bash/entry/check/tc_naming.sh
resources/libraries/python/Constants.py
resources/libraries/python/HoststackUtil.py
resources/libraries/python/autogen/Regenerator.py
resources/libraries/python/autogen/Testcase.py
resources/libraries/robot/hoststack/hoststack.robot
resources/libraries/robot/shared/suite_setup.robot
resources/templates/vcl/vcl_iperf3.conf [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/common/tasks/ubuntu_bionic.yaml
tests/vpp/perf/hoststack/10ge2p1x710-eth-ip4tcp-ldpreload-iperf3-bps.robot [new file with mode: 0644]

index b193cfa..2a084d9 100644 (file)
@@ -66,7 +66,7 @@ r_testc_rules=(
     #'(ipsec[[:digit:]]+tnlhw|ipsec[[:digit:]]+tnlsw|'
     #'srhip6|tcp|udp|lispip6|lispip4|vxlan){0,1}'
     #'(http){0,1}-'
     #'(ipsec[[:digit:]]+tnlhw|ipsec[[:digit:]]+tnlsw|'
     #'srhip6|tcp|udp|lispip6|lispip4|vxlan){0,1}'
     #'(http){0,1}-'
-    '(.*)-(dev|ndrpdr|cps|rps|reconf)$'
+    '(.*)-(dev|ndrpdr|bps|cps|rps|reconf)$'
     )
 s_suite_rules=(
     'number of SUT nodes'
     )
 s_suite_rules=(
     'number of SUT nodes'
@@ -85,7 +85,7 @@ r_suite_rules=(
     #'(ipsec[[:digit:]]+tnlhw|ipsec[[:digit:]]+tnlsw|'
     #'srhip6|tcp|udp|lispip6|lispip4|vxlan){0,1}'
     #'(http){0,1}-'
     #'(ipsec[[:digit:]]+tnlhw|ipsec[[:digit:]]+tnlsw|'
     #'srhip6|tcp|udp|lispip6|lispip4|vxlan){0,1}'
     #'(http){0,1}-'
-    '(.*)-(dev|ndrpdr|cps|rps|reconf)$'
+    '(.*)-(dev|ndrpdr|bps|cps|rps|reconf)$'
     )
 
 rm -f "tc_naming.log" || die
     )
 
 rm -f "tc_naming.log" || die
@@ -139,4 +139,4 @@ if [ $((total_failed_tc + total_failed_su)) != "0" ]; then
 fi
 
 warn
 fi
 
 warn
-warn "Testcase naming checker: PASS"
\ No newline at end of file
+warn "Testcase naming checker: PASS"
index 1b4d44c..eded294 100644 (file)
@@ -145,9 +145,15 @@ class Constants:
     # Container templates location
     RESOURCES_TPL_CONTAINER = u"resources/templates/container"
 
     # Container templates location
     RESOURCES_TPL_CONTAINER = u"resources/templates/container"
 
+    # VPP Communications Library templates location
+    RESOURCES_TPL_VCL = u"resources/templates/vcl"
+
     # HTTP Server www root directory
     RESOURCES_TP_WRK_WWW = u"resources/traffic_profiles/wrk/www"
 
     # HTTP Server www root directory
     RESOURCES_TP_WRK_WWW = u"resources/traffic_profiles/wrk/www"
 
+    # VPP Communications Library LD_PRELOAD library
+    VCL_LDPRELOAD_LIBRARY=u"/usr/lib/x86_64-linux-gnu/libvcl_ldpreload.so"
+
     # OpenVPP VAT binary name
     VAT_BIN_NAME = u"vpp_api_test"
 
     # OpenVPP VAT binary name
     VAT_BIN_NAME = u"vpp_api_test"
 
index 9e6e200..ad95d51 100644 (file)
@@ -15,6 +15,7 @@
 from time import sleep
 from robot.api import logger
 
 from time import sleep
 from robot.api import logger
 
+from resources.libraries.python.Constants import Constants
 from resources.libraries.python.ssh import exec_cmd, exec_cmd_no_error
 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
 from resources.libraries.python.DUTSetup import DUTSetup
 from resources.libraries.python.ssh import exec_cmd, exec_cmd_no_error
 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
 from resources.libraries.python.DUTSetup import DUTSetup
@@ -55,6 +56,49 @@ class HoststackUtil():
             vpp_echo_cmd[u"args"] += u" tx-results-diff"
         return vpp_echo_cmd
 
             vpp_echo_cmd[u"args"] += u" tx-results-diff"
         return vpp_echo_cmd
 
+    @staticmethod
+    def get_iperf3_command(iperf3_attributes):
+        """Construct the iperf3 command using the specified attributes.
+
+        :param iperf3_attributes: iperf3 test program attributes.
+        :type iperf3_attributes: dict
+        :returns: Command line components of the iperf3 command
+            'env_vars' - environment variables
+            'name' - program name
+            'args' - command arguments.
+        :rtype: dict
+        """
+        # TODO: Use a python class instead of dictionary for the return type
+        iperf3_cmd = {}
+        iperf3_cmd[u"env_vars"] = f"VCL_CONFIG={Constants.REMOTE_FW_DIR}/" \
+            f"{Constants.RESOURCES_TPL_VCL}/" \
+            f"{iperf3_attributes[u'vcl_config']}"
+        if iperf3_attributes[u"ld_preload"]:
+            iperf3_cmd[u"env_vars"] += \
+                f" LD_PRELOAD={Constants.VCL_LDPRELOAD_LIBRARY}"
+        if iperf3_attributes[u'transparent_tls']:
+            iperf3_cmd[u"env_vars"] += u" LDP_ENV_TLS_TRANS=1"
+
+        json_results = u" --json" if iperf3_attributes[u'json'] else u""
+        ip_address = f" {iperf3_attributes[u'ip_address']}" if u"ip_address" \
+                     in iperf3_attributes else u""
+        iperf3_cmd[u"name"] = u"iperf3"
+        iperf3_cmd[u"args"] = f"--{iperf3_attributes[u'role']}{ip_address} " \
+                              f"--interval 0{json_results} " \
+                              f"--version{iperf3_attributes[u'ip_version']}"
+
+        if iperf3_attributes[u"role"] == u"server":
+            iperf3_cmd[u"args"] += u" --one-off"
+        else:
+            iperf3_cmd[u"args"] += u" --get-server-output"
+            if u"parallel" in iperf3_attributes:
+                iperf3_cmd[u"args"] += \
+                    f" --parallel {iperf3_attributes[u'parallel']}"
+            if u"bytes" in iperf3_attributes:
+                iperf3_cmd[u"args"] += \
+                    f" --bytes {iperf3_attributes[u'bytes']}"
+        return iperf3_cmd
+
     @staticmethod
     def set_hoststack_quic_fifo_size(node, fifo_size):
         """Set the QUIC protocol fifo size.
     @staticmethod
     def set_hoststack_quic_fifo_size(node, fifo_size):
         """Set the QUIC protocol fifo size.
index d47680c..cb0d332 100644 (file)
@@ -113,7 +113,7 @@ def check_suite_tag(suite_tag, prolog):
     """
     found = prolog.count(u"| " + suite_tag)
     if found != 1:
     """
     found = prolog.count(u"| " + suite_tag)
     if found != 1:
-        raise ValueError(f"Suite tag found {found} times for {suite_id}")
+        raise ValueError(f"Suite tag found {found} times for {suite_tag}")
 
 
 def add_default_testcases(testcase, iface, suite_id, file_out, tc_kwargs_list):
 
 
 def add_default_testcases(testcase, iface, suite_id, file_out, tc_kwargs_list):
@@ -440,22 +440,56 @@ class Regenerator:
 
         min_frame_size = PROTOCOL_TO_MIN_FRAME_SIZE[protocol]
         default_kwargs_list = [
 
         min_frame_size = PROTOCOL_TO_MIN_FRAME_SIZE[protocol]
         default_kwargs_list = [
-            {u"frame_size": min_frame_size, u"phy_cores": 1},
-            {u"frame_size": min_frame_size, u"phy_cores": 2},
-            {u"frame_size": min_frame_size, u"phy_cores": 4},
-            {u"frame_size": 1518, u"phy_cores": 1},
-            {u"frame_size": 1518, u"phy_cores": 2},
-            {u"frame_size": 1518, u"phy_cores": 4},
-            {u"frame_size": 9000, u"phy_cores": 1},
-            {u"frame_size": 9000, u"phy_cores": 2},
-            {u"frame_size": 9000, u"phy_cores": 4},
-            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 1},
-            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 2},
-            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 4}
+            {u"frame_size": min_frame_size, u"phy_cores": 1, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": min_frame_size, u"phy_cores": 2, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": min_frame_size, u"phy_cores": 4, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 1518, u"phy_cores": 1, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 1518, u"phy_cores": 2, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 1518, u"phy_cores": 4, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 9000, u"phy_cores": 1, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 9000, u"phy_cores": 2, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": 9000, u"phy_cores": 4, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 1, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 2, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"frame_size": u"IMIX_v4_1", u"phy_cores": 4, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"}
         ]
         ]
-        tcp_kwargs_list = [
-            {u"phy_cores": i, u"frame_size": 0} for i in (1, 2, 4)
+        hoststack_wrk_kwargs_list = [
+            {u"phy_cores": i, u"frame_size": 0, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"} for i in (1, 2, 4)
         ]
         ]
+        hoststack_iperf3_kwargs_list = [
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"1G"},
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 1,
+             u"streams": 10, u"bytes_str": u"10G"},
+            {u"phy_cores": 2, u"frame_size": 0, u"clients": 1,
+             u"streams": 10, u"bytes_str": u"10G"},
+            {u"phy_cores": 4, u"frame_size": 0, u"clients": 1,
+             u"streams": 10, u"bytes_str": u"10G"},
+        ]
+        hoststack_quic_kwargs_list = [
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 1,
+             u"streams": 1, u"bytes_str": u"100M"},
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 1,
+             u"streams": 10, u"bytes_str": u"100M"},
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 10,
+             u"streams": 1, u"bytes_str": u"100M"},
+            {u"phy_cores": 1, u"frame_size": 0, u"clients": 10,
+             u"streams": 10, u"bytes_str": u"100M"},
+        ]
+
         for in_filename in glob(pattern):
             if not self.quiet:
                 print(
         for in_filename in glob(pattern):
             if not self.quiet:
                 print(
@@ -480,7 +514,12 @@ class Regenerator:
             elif in_filename.endswith(u"-reconf.robot"):
                 write_reconf_files(in_filename, in_prolog, default_kwargs_list)
             elif in_filename[-10:] in (u"-cps.robot", u"-rps.robot"):
             elif in_filename.endswith(u"-reconf.robot"):
                 write_reconf_files(in_filename, in_prolog, default_kwargs_list)
             elif in_filename[-10:] in (u"-cps.robot", u"-rps.robot"):
-                write_tcp_files(in_filename, in_prolog, tcp_kwargs_list)
+                write_tcp_files(in_filename, in_prolog,
+                                hoststack_wrk_kwargs_list)
+            elif in_filename[-10:] in (u"-bps.robot"):
+                write_tcp_files(in_filename, in_prolog,
+                                hoststack_iperf3_kwargs_list if u"iperf3"
+                                in in_filename else hoststack_quic_kwargs_list)
             else:
                 raise RuntimeError(
                     f"Error in {in_filename}: non-primary suite type found."
             else:
                 raise RuntimeError(
                     f"Error in {in_filename}: non-primary suite type found."
index 224295e..6b4cfb2 100644 (file)
@@ -34,7 +34,8 @@ class Testcase:
         """
         self.template = Template(template_string)
 
         """
         self.template = Template(template_string)
 
-    def generate(self, num, frame_size, phy_cores):
+    def generate(self, num, frame_size, phy_cores, clients, streams,
+                 bytes_str):
         """Return string of test case code with placeholders filled.
 
         Fail if there are placeholders left unfilled.
         """Return string of test case code with placeholders filled.
 
         Fail if there are placeholders left unfilled.
@@ -43,9 +44,16 @@ class Testcase:
         :param num: Test case number. Example value: 4.
         :param frame_size: Imix string or numeric frame size. Example: 74.
         :param phy_cores: Number of physical cores to use. Example: 2.
         :param num: Test case number. Example value: 4.
         :param frame_size: Imix string or numeric frame size. Example: 74.
         :param phy_cores: Number of physical cores to use. Example: 2.
+        :param clients: Number of clients used by test program. Example: 4.
+        :param streams: Number of streams used by test program. Example: 10.
+        :param bytes_str: Size in bytes of stream sent by test program.
+            Example: 1G
         :type num: int
         :type frame_size: str or int
         :type phy_cores: int or str
         :type num: int
         :type frame_size: str or int
         :type phy_cores: int or str
+        :type clients: int
+        :type streams: int
+        :type bytes_str: str
         :returns: Filled template, usable as test case code.
         :rtype: str
         """
         :returns: Filled template, usable as test case code.
         :rtype: str
         """
@@ -66,7 +74,12 @@ class Testcase:
             {
                 u"cores_num": f"${{{cores_num:d}}}",
                 u"cores_str": phy_cores,
             {
                 u"cores_num": f"${{{cores_num:d}}}",
                 u"cores_str": phy_cores,
-                u"tc_num": f"tc{num:02d}"
+                u"tc_num": f"tc{num:02d}",
+                u"clients_num": f"${{{clients:d}}}",
+                u"clients_str": str(clients),
+                u"streams_num": f"${{{streams:d}}}",
+                u"streams_str": str(streams),
+                u"bytes_str": bytes_str,
             }
         )
         return self.template.substitute(subst_dict)
             }
         )
         return self.template.substitute(subst_dict)
@@ -103,9 +116,17 @@ class Testcase:
         """
         # TODO: Choose a better frame size identifier for streamed protocols
         # (TCP, QUIC, SCTP, ...) where DUT (not TG) decides frame size.
         """
         # TODO: Choose a better frame size identifier for streamed protocols
         # (TCP, QUIC, SCTP, ...) where DUT (not TG) decides frame size.
-        template_string = f'''
+        if u"tcphttp" in suite_id:
+            template_string = f'''
 | ${{tc_num}}-IMIX-${{cores_str}}c-{suite_id}
 | | [Tags] | ${{cores_str}}C
 | | phy_cores=${{cores_num}}
 '''
 | ${{tc_num}}-IMIX-${{cores_str}}c-{suite_id}
 | | [Tags] | ${{cores_str}}C
 | | phy_cores=${{cores_num}}
 '''
+        else:
+            template_string = f'''
+| ${{tc_num}}-IMIX-${{cores_str}}c-{suite_id}
+| | [Tags] | ${{cores_str}}C | ${{clients_str}}CLIENT | ${{streams_str}}STREAM
+| | phy_cores=${{cores_num}} | clients=${{clients_num}}'''
+            template_string += f" | streams=${{streams_num}}" \
+                               f" | bytes=${{bytes_str}}\n"
         return cls(template_string)
         return cls(template_string)
index d0fd9a2..cdf35f2 100644 (file)
 | ... | sess_evt_q_seg_size=4G
 | ... | sess_evt_q_length=4000000
 | ... | sess_prealloc_sess=4000000
 | ... | sess_evt_q_seg_size=4G
 | ... | sess_evt_q_length=4000000
 | ... | sess_prealloc_sess=4000000
-| ... | sess_v4_sess_tbl_buckets=2000000
-| ... | sess_v4_sess_tbl_mem=2G
-| ... | sess_v4_sess_halfopen_buckets=5000000
-| ... | sess_v4_sess_halfopen_mem=3G
-| ... | sess_lcl_endpt_tbl_buckets=5000000
-| ... | sess_lcl_endpt_tbl_mem=3G
+| ... | sess_v4_tbl_buckets=2000000
+| ... | sess_v4_tbl_mem=2G
+| ... | sess_v4_hopen_buckets=5000000
+| ... | sess_v4_hopen_mem=3G
+| ... | sess_lendpt_buckets=5000000
+| ... | sess_lendpt_mem=3G
 | &{vpp_echo_server_attr}=
 | ... | role=server
 | ... | cfg_vpp_feature=${None}
 | &{vpp_echo_server_attr}=
 | ... | role=server
 | ... | cfg_vpp_feature=${None}
 | ... | tx_bytes=0
 | ... | rx_results_diff=${False}
 | ... | tx_results_diff=${False}
 | ... | tx_bytes=0
 | ... | rx_results_diff=${False}
 | ... | tx_results_diff=${False}
+| &{iperf3_server_attr}=
+| ... | role=server
+| ... | cfg_vpp_feature=${Empty}
+| ... | namespace=default
+| ... | vcl_config=vcl_iperf3.conf
+| ... | ld_preload=${True}
+| ... | transparent_tls=${False}
+| ... | json=${False}
+| ... | ip_version=${4}
+| &{iperf3_client_attr}=
+| ... | role=client
+| ... | cfg_vpp_feature=${Empty}
+| ... | namespace=default
+| ... | vcl_config=vcl_iperf3.conf
+| ... | ld_preload=${True}
+| ... | transparent_tls=${False}
+| ... | json=${False}
+| ... | ip_version=${4}
+| ... | ip_address=${EMPTY}
+| ... | parallel=${1}
+| ... | bytes=1G
 
 *** Keywords ***
 | Set VPP Hoststack Attributes
 
 *** Keywords ***
 | Set VPP Hoststack Attributes
 | | ... | - ${sess_evt_q_length} - Session event queue length Type: string
 | | ... | - ${sess_prealloc_sess} - Number of sessions to preallocate
 | | ... | Type: string
 | | ... | - ${sess_evt_q_length} - Session event queue length Type: string
 | | ... | - ${sess_prealloc_sess} - Number of sessions to preallocate
 | | ... | Type: string
-| | ... | - ${sess_v4_sess_tbl_buckets} - Number of IPv4 session table buckets
+| | ... | - ${sess_v4_tbl_buckets} - Number of IPv4 session table buckets
 | | ... | Type: string
 | | ... | Type: string
-| | ... | - ${sess_v4_sess_tbl_mem} - IPv4 session table memory size
+| | ... | - ${sess_v4_tbl_mem} - IPv4 session table memory size
 | | ... | Type: string
 | | ... | Type: string
-| | ... | - ${sess_v4_sess_halfopen_buckets} - Number of IPv4 session
+| | ... | - ${sess_v4_hopen_buckets} - Number of IPv4 session
 | | ... | half open table buckets Type: string
 | | ... | half open table buckets Type: string
-| | ... | - ${sess_v4_sess_halfopen_mem} - IPv4 session half open
+| | ... | - ${sess_v4_hopen_mem} - IPv4 session half open
 | | ... | table memory size Type: string
 | | ... | table memory size Type: string
-| | ... | - ${sess_lcl_endpt_tbl_buckets} - Number of session local endpoint
+| | ... | - ${sess_lendpt_buckets} - Number of session local endpoint
 | | ... | table buckets Type: string
 | | ... | table buckets Type: string
-| | ... | - ${sess_lcl_endpt_tbl_mem} - Session local endpoint
+| | ... | - ${sess_lendpt_mem} - Session local endpoint
 | | ... | table memory size Type: string
 | |
 | | ... | *Example:*
 | | ... | table memory size Type: string
 | |
 | | ... | *Example:*
 | | ... | ${sess_evt_q_seg_size}=${vpp_hoststack_attr}[sess_evt_q_seg_size]
 | | ... | ${sess_evt_q_length}=${vpp_hoststack_attr}[sess_evt_q_length]
 | | ... | ${sess_prealloc_sess}=${vpp_hoststack_attr}[sess_prealloc_sess]
 | | ... | ${sess_evt_q_seg_size}=${vpp_hoststack_attr}[sess_evt_q_seg_size]
 | | ... | ${sess_evt_q_length}=${vpp_hoststack_attr}[sess_evt_q_length]
 | | ... | ${sess_prealloc_sess}=${vpp_hoststack_attr}[sess_prealloc_sess]
-| | ... | ${sess_v4_sess_tbl_buckets}=${vpp_hoststack_attr}[sess_v4_sess_tbl_buckets]
-| | ... | ${sess_v4_sess_tbl_mem}=${vpp_hoststack_attr}[sess_v4_sess_tbl_mem]
-| | ... | ${sess_v4_sess_halfopen_buckets}=${vpp_hoststack_attr}[sess_v4_sess_halfopen_buckets]
-| | ... | ${sess_v4_sess_halfopen_mem}=${vpp_hoststack_attr}[sess_v4_sess_halfopen_mem]
-| | ... | ${sess_lcl_endpt_tbl_buckets}=${vpp_hoststack_attr}[sess_lcl_endpt_tbl_buckets]
-| | ... | ${sess_lcl_endpt_tbl_mem}=${vpp_hoststack_attr}[sess_lcl_endpt_tbl_mem]
+| | ... | ${sess_v4_tbl_buckets}=${vpp_hoststack_attr}[sess_v4_tbl_buckets]
+| | ... | ${sess_v4_tbl_mem}=${vpp_hoststack_attr}[sess_v4_tbl_mem]
+| | ... | ${sess_v4_hopen_buckets}=${vpp_hoststack_attr}[sess_v4_hopen_buckets]
+| | ... | ${sess_v4_hopen_mem}=${vpp_hoststack_attr}[sess_v4_hopen_mem]
+| | ... | ${sess_lendpt_buckets}=${vpp_hoststack_attr}[sess_lendpt_buckets]
+| | ... | ${sess_lendpt_mem}=${vpp_hoststack_attr}[sess_lendpt_mem]
 | |
 | | Set To Dictionary | ${vpp_hoststack_attr} | rxq | ${rxq}
 | | Set To Dictionary | ${vpp_hoststack_attr} | phy_cores | ${phy_cores}
 | |
 | | Set To Dictionary | ${vpp_hoststack_attr} | rxq | ${rxq}
 | | Set To Dictionary | ${vpp_hoststack_attr} | phy_cores | ${phy_cores}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | ... | sess_prealloc_sess | ${sess_prealloc_sess}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | ... | sess_prealloc_sess | ${sess_prealloc_sess}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_v4_sess_tbl_buckets | ${sess_v4_sess_tbl_buckets}
+| | ... | sess_v4_tbl_buckets | ${sess_v4_tbl_buckets}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_v4_sess_tbl_mem | ${sess_v4_sess_tbl_mem}
+| | ... | sess_v4_tbl_mem | ${sess_v4_tbl_mem}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_v4_sess_halfopen_buckets | ${sess_v4_sess_halfopen_buckets}
+| | ... | sess_v4_hopen_buckets | ${sess_v4_hopen_buckets}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_v4_sess_halfopen_mem | ${sess_v4_sess_halfopen_mem}
+| | ... | sess_v4_hopen_mem | ${sess_v4_hopen_mem}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_lcl_endpt_tbl_buckets | ${sess_lcl_endpt_tbl_buckets}
+| | ... | sess_lendpt_buckets | ${sess_lendpt_buckets}
 | | Set To Dictionary | ${vpp_hoststack_attr}
 | | Set To Dictionary | ${vpp_hoststack_attr}
-| | ... | sess_lcl_endpt_tbl_mem | ${sess_lcl_endpt_tbl_mem}
+| | ... | sess_lendpt_mem | ${sess_lendpt_mem}
 
 | Set VPP Echo Server Attributes
 | | [Documentation]
 
 | Set VPP Echo Server Attributes
 | | [Documentation]
 | | Set To Dictionary
 | | ... | ${vpp_echo_client_attr} | tx_results_diff | ${tx_results_diff}
 
 | | Set To Dictionary
 | | ... | ${vpp_echo_client_attr} | tx_results_diff | ${tx_results_diff}
 
+| Set Iperf3 Server Attributes
+| | [Documentation]
+| | ... | Set the HostStack iperf3 test program attributes
+| | ... | in the iperf3_server_attr dictionary.
+| |
+| | ... | *Arguments:*
+| | ... | - ${vcl_config} - VCL configuration file name Type: string
+| | ... | - ${ld_preload} - Use the VCL LD_PRELOAD library Type: bool
+| | ... | - ${transparent_tls} - Use VCL Transparent-TLS mode Type: bool
+| | ... | - ${ip_version} - IP version (4 or 6) Type: int
+| |
+| | ... | *Example:*
+| |
+| | ... | \| Set Iperf3 Server Attributes \| vcl_config=${vcl_config} \|
+| | ... | \| ip_version=${ip_version} \|
+| |
+| | [Arguments]
+| | ... | ${vcl_config}=${iperf3_server_attr}[vcl_config]
+| | ... | ${ld_preload}=${iperf3_server_attr}[ld_preload]
+| | ... | ${transparent_tls}=${iperf3_server_attr}[transparent_tls]
+| | ... | ${ip_version}=${iperf3_server_attr}[ip_version]
+| |
+| | Set To Dictionary | ${iperf3_server_attr} | vcl_config | ${vcl_config}
+| | Set To Dictionary | ${iperf3_server_attr} | ld_preload | ${ld_preload}
+| | Set To Dictionary | ${iperf3_server_attr} | transparent_tls
+| | ... | ${transparent_tls}
+| | Set To Dictionary | ${iperf3_server_attr} | ip_version | ${ip_version}
+
+| Set Iperf3 Client Attributes
+| | [Documentation]
+| | ... | Set the HostStack iperf3 test program attributes
+| | ... | in the iperf3_client_attr dictionary.
+| |
+| | ... | *Arguments:*
+| | ... | - ${vcl_config} - VCL configuration file name Type: string
+| | ... | - ${ld_preload} - Use the VCL LD_PRELOAD library Type: bool
+| | ... | - ${transparent_tls} - Use VCL Transparent-TLS mode Type: bool
+| | ... | - ${ip_version} - IP version (4 or 6) Type: int
+| | ... | - ${parallel} - Number of parallel streams Type: int
+| | ... | - ${bytes} - Number of bytes to send Type: string
+| |
+| | ... | *Example:*
+| |
+| | ... | \| Set Iperf3 Client Attributes \| vcl_config=${vcl_config} \|
+| | ... | \| ip_version=${ip_version} \| parallel=${streams} \|
+| |
+| | [Arguments]
+| | ... | ${vcl_config}=${iperf3_client_attr}[vcl_config]
+| | ... | ${ld_preload}=${iperf3_client_attr}[ld_preload]
+| | ... | ${transparent_tls}=${iperf3_client_attr}[transparent_tls]
+| | ... | ${ip_version}=${iperf3_client_attr}[ip_version]
+| | ... | ${parallel}=${iperf3_client_attr}[parallel]
+| | ... | ${bytes}=${iperf3_client_attr}[bytes]
+| |
+| | Set To Dictionary | ${iperf3_client_attr} | vcl_config | ${vcl_config}
+| | Set To Dictionary | ${iperf3_client_attr} | ld_preload | ${ld_preload}
+| | Set To Dictionary | ${iperf3_client_attr} | transparent_tls
+| | ... | ${transparent_tls}
+| | Set To Dictionary | ${iperf3_client_attr} | ip_version | ${ip_version}
+| | Set To Dictionary | ${iperf3_client_attr} | parallel | ${parallel}
+| | Set To Dictionary | ${iperf3_client_attr} | bytes | ${bytes}
+
 | Run hoststack test program on DUT
 | | [Documentation]
 | | ... | Configure IP address on the port, set it up and start the specified
 | Run hoststack test program on DUT
 | | [Documentation]
 | | ... | Configure IP address on the port, set it up and start the specified
 | | [Documentation]
 | | ... | Configure VPP HostStack attributes on all DUTs.
 | |
 | | [Documentation]
 | | ... | Configure VPP HostStack attributes on all DUTs.
 | |
+| | Set Max Rate And Jumbo
 | | Add worker threads to all DUTs
 | | ... | ${vpp_hoststack_attr}[phy_cores] | ${vpp_hoststack_attr}[rxq]
 | | Add worker threads to all DUTs
 | | ... | ${vpp_hoststack_attr}[phy_cores] | ${vpp_hoststack_attr}[rxq]
-| | Add DPDK PCI devices to all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
+| | Pre-initialize layer driver | ${nic_driver}
 | | FOR | ${dut} | IN | @{duts}
 | | | Import Library | resources.libraries.python.VppConfigGenerator
 | | | ... | WITH NAME | ${dut}
 | | FOR | ${dut} | IN | @{duts}
 | | | Import Library | resources.libraries.python.VppConfigGenerator
 | | | ... | WITH NAME | ${dut}
 | | | Run keyword | ${dut}.Add session preallocated sessions
 | | | ... | ${vpp_hoststack_attr}[sess_prealloc_sess]
 | | | Run keyword | ${dut}.Add session v4 session table buckets
 | | | Run keyword | ${dut}.Add session preallocated sessions
 | | | ... | ${vpp_hoststack_attr}[sess_prealloc_sess]
 | | | Run keyword | ${dut}.Add session v4 session table buckets
-| | | ... | ${vpp_hoststack_attr}[sess_v4_sess_tbl_buckets]
+| | | ... | ${vpp_hoststack_attr}[sess_v4_tbl_buckets]
 | | | Run keyword | ${dut}.Add session v4 session table memory
 | | | Run keyword | ${dut}.Add session v4 session table memory
-| | | ... | ${vpp_hoststack_attr}[sess_v4_sess_tbl_mem]
+| | | ... | ${vpp_hoststack_attr}[sess_v4_tbl_mem]
 | | | Run keyword | ${dut}.Add session v4 halfopen table buckets
 | | | Run keyword | ${dut}.Add session v4 halfopen table buckets
-| | | ... | ${vpp_hoststack_attr}[sess_v4_sess_halfopen_buckets]
+| | | ... | ${vpp_hoststack_attr}[sess_v4_hopen_buckets]
 | | | Run keyword | ${dut}.Add session v4 halfopen table memory
 | | | Run keyword | ${dut}.Add session v4 halfopen table memory
-| | | ... | ${vpp_hoststack_attr}[sess_v4_sess_halfopen_mem]
+| | | ... | ${vpp_hoststack_attr}[sess_v4_hopen_mem]
 | | | Run keyword | ${dut}.Add session local endpoints table buckets
 | | | Run keyword | ${dut}.Add session local endpoints table buckets
-| | | ... | ${vpp_hoststack_attr}[sess_lcl_endpt_tbl_buckets]
+| | | ... | ${vpp_hoststack_attr}[sess_lendpt_buckets]
 | | | Run keyword | ${dut}.Add session local endpoints table memory
 | | | Run keyword | ${dut}.Add session local endpoints table memory
-| | | ... | ${vpp_hoststack_attr}[sess_lcl_endpt_tbl_mem]
+| | | ... | ${vpp_hoststack_attr}[sess_lendpt_mem]
 | | END
 | | Apply startup configuration on all VPP DUTs
 
 | | END
 | | Apply startup configuration on all VPP DUTs
 
 | | Set test message | ${server_output} | append=True
 | | Run Keyword And Return | No Hoststack Test Program Results
 | | ... | ${server_no_results} | ${client_no_results}
 | | Set test message | ${server_output} | append=True
 | | Run Keyword And Return | No Hoststack Test Program Results
 | | ... | ${server_no_results} | ${client_no_results}
+
+| Get Test Results From Hoststack Iperf3 Test
+| | [Documentation]
+| | ... | Configure IP address on the port, set it up and start the specified
+| | ... | HostStack test programs on the DUTs. Gather test program
+| | ... | output and append test results in message.
+| | ... | Return boolean indicating when no results were available from
+| | ... | both the server and client test programs.
+| |
+| | Set To Dictionary | ${iperf3_client_attr} | ip_address
+| | ... | ${dut2_if1_ip4_addr}
+| | Configure VPP Hoststack Attributes on all DUTs
+| | ${iperf3_server}= | Get Iperf3 Command | ${iperf3_server_attr}
+| | ${server_pid}= | Run hoststack test program on DUT
+| | ... | ${dut2} | ${dut2_if1} | ${dut2_if1_ip4_addr} | ${dut2_if1_ip4_prefix}
+| | ... | ${iperf3_server_attr}[namespace]
+| | ... | ${iperf3_server_attr}[cfg_vpp_feature] | ${iperf3_server}
+| | ${iperf3_client}= | Get Iperf3 Command | ${iperf3_client_attr}
+| | ${client_pid}= | Run hoststack test program on DUT
+| | ... | ${dut1} | ${dut1_if1} | ${dut1_if1_ip4_addr} | ${dut1_if1_ip4_prefix}
+| | ... | ${iperf3_client_attr}[namespace]
+| | ... | ${iperf3_client_attr}[cfg_vpp_feature] | ${iperf3_client}
+| | When Hoststack Test Program Finished | ${dut1} | ${client_pid}
+| | ${client_no_results} | ${client_output}=
+| | ... | Analyze hoststack test program output | ${dut1} | Client
+| | ... | ${vpp_nsim_attr} | ${iperf3_client}
+| | Then Set test message | ${client_output}
+| | Return From Keyword | ${client_no_results}
index 7518899..7cfb38b 100644 (file)
 | | | Append Node | ${nodes['${dut}']} | filter_list=${nic_model_list}
 | | END
 | | Append Node | ${nodes['@{duts}[0]']} | filter_list=${nic_model_list}
 | | | Append Node | ${nodes['${dut}']} | filter_list=${nic_model_list}
 | | END
 | | Append Node | ${nodes['@{duts}[0]']} | filter_list=${nic_model_list}
-| | Compute Path | always_same_link=${FALSE}
+| | Compute Path | always_same_link=${TRUE}
 | | FOR | ${i} | IN RANGE | 1 | ${DATAPATH_INTERFACES_MAX}
 | | | ${dutx_if} | ${dutx}= | Next Interface
 | | | Run Keyword If | '${dutx_if}' == 'None' | EXIT FOR LOOP
 | | FOR | ${i} | IN RANGE | 1 | ${DATAPATH_INTERFACES_MAX}
 | | | ${dutx_if} | ${dutx}= | Next Interface
 | | | Run Keyword If | '${dutx_if}' == 'None' | EXIT FOR LOOP
diff --git a/resources/templates/vcl/vcl_iperf3.conf b/resources/templates/vcl/vcl_iperf3.conf
new file mode 100644 (file)
index 0000000..9e4b057
--- /dev/null
@@ -0,0 +1,7 @@
+vcl {
+  rx-fifo-size 4000000
+  tx-fifo-size 4000000
+  app-scope-local
+  app-scope-global
+  api-socket-name /run/vpp/api.sock
+}
\ No newline at end of file
index 2db85cf..480358b 100644 (file)
@@ -14,6 +14,7 @@
       - 'build-essential'
       - 'cgroup-bin'
       - 'dkms'
       - 'build-essential'
       - 'cgroup-bin'
       - 'dkms'
+      - 'iperf3'
       - 'libpcap-dev'
       - 'python-all'
       - 'python-apt'
       - 'libpcap-dev'
       - 'python-all'
       - 'python-apt'
diff --git a/tests/vpp/perf/hoststack/10ge2p1x710-eth-ip4tcp-ldpreload-iperf3-bps.robot b/tests/vpp/perf/hoststack/10ge2p1x710-eth-ip4tcp-ldpreload-iperf3-bps.robot
new file mode 100644 (file)
index 0000000..81b5d05
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (c) 2020 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 ***
+| Library  | resources.libraries.python.HoststackUtil
+| Resource | resources/libraries/robot/shared/default.robot
+| Resource | resources/libraries/robot/hoststack/hoststack.robot
+|
+| Force Tags | 3_NODE_SINGLE_LINK_TOPO | PERFTEST | HW_ENV
+| ... | TCP | NIC_Intel-X710 | DRV_VFIO_PCI
+| ... | eth-ip4tcp-ldpreload-iperf3
+|
+| Suite Setup | Setup suite single link no tg
+| Suite Teardown | Tear down suite
+| Test Setup | Setup test
+| Test Teardown | Tear down test
+|
+| Test Template | Local template
+|
+| Documentation | *Iperf3 client -> Iperf3 server throughput.
+|
+| ... | *[Top] Network Topologies:* DUT-DUT 2-node topology
+| ... | with single link between nodes.
+| ... | *[Enc] Packet Encapsulations:* Eth-IPv4-TCP
+| ... | *[Cfg] DUT configuration:*
+| ... | *[Ref] Applicable standard specifications:*
+
+*** Variables ***
+| @{plugins_to_enable}= | dpdk_plugin.so
+| ${nic_name}= | Intel-X710
+| ${nic_driver}= | vfio-pci
+| ${overhead}= | ${0}
+| ${frame_size}= | IMIX_v4_1
+| ${crypto_type}= | ${None}
+
+*** Keywords ***
+| Local template
+| | [Arguments] | ${phy_cores} | ${clients} | ${streams} | ${bytes}
+| |
+| | Set VPP Hoststack Attributes | phy_cores=${phy_cores}
+| | Set Iperf3 Client Attributes | parallel=${streams} | bytes=${bytes}
+| | ${no_results}= | Get Test Results From Hoststack Iperf3 Test
+| | Run Keyword If | ${no_results}==True | FAIL
+| | ... | No Test Results From Iperf3 client
+
+*** Test Cases ***
+| tc01-IMIX-1c-eth-ip4tcp-ldpreload-iperf3-bps
+| | [Tags] | 1C | 1CLIENT | 1STREAM
+| | phy_cores=${1} | clients=${1} | streams=${1} | bytes=1G
+
+| tc02-IMIX-1c-eth-ip4tcp-ldpreload-iperf3-bps
+| | [Tags] | 1C | 1CLIENT | 10STREAM
+| | phy_cores=${1} | clients=${1} | streams=${10} | bytes=10G
+
+| tc03-IMIX-2c-eth-ip4tcp-ldpreload-iperf3-bps
+| | [Tags] | 2C | 1CLIENT | 10STREAM
+| | phy_cores=${2} | clients=${1} | streams=${10} | bytes=10G
+
+| tc04-IMIX-4c-eth-ip4tcp-ldpreload-iperf3-bps
+| | [Tags] | 4C | 1CLIENT | 10STREAM
+| | phy_cores=${4} | clients=${1} | streams=${10} | bytes=10G