From 80adeefab9fc1871675688881498304ddc780828 Mon Sep 17 00:00:00 2001 From: Tibor Frank Date: Mon, 13 Jul 2020 14:08:13 +0200 Subject: [PATCH] Remove remains of WRK tests Change-Id: If61783fb717757c6189f06924412bd079e15a08f Signed-off-by: Tibor Frank --- README.md | 6 +- resources/libraries/python/Constants.py | 3 - resources/libraries/python/autogen/Regenerator.py | 5 - resources/libraries/python/tcp.py | 80 ------ .../libraries/robot/hoststack/tcp_setup.robot | 57 ---- resources/libraries/robot/shared/suite_setup.robot | 32 --- .../libraries/robot/shared/suite_teardown.robot | 17 -- resources/libraries/robot/wrk/wrk_utils.robot | 83 ------ .../ansible/roles/cleanup/tasks/tg.yaml | 7 - .../roles/tg/files/csit-initialize-docker-tg.sh | 2 - .../ansible/roles/wrk/defaults/main.yaml | 21 -- .../ansible/roles/wrk/tasks/main.yaml | 48 ---- resources/tools/testbed-setup/ansible/tg.yaml | 2 - resources/tools/testbed-setup/ansible/tg_aws.yaml | 2 - .../tools/testbed-setup/ansible/tg_azure.yaml | 2 - resources/tools/wrk/__init__.py | 16 -- resources/tools/wrk/doc/wrk_lld.rst | 293 -------------------- resources/tools/wrk/wrk.py | 299 --------------------- resources/tools/wrk/wrk_errors.py | 55 ---- resources/tools/wrk/wrk_traffic_profile_parser.py | 294 -------------------- resources/tools/wrk/wrk_utils.sh | 246 ----------------- .../wrk/wrk-sf-2n-ethip4tcphttp-1u1c50con-bw.yaml | 47 ---- .../wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-cps.yaml | 53 ---- .../wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-rps.yaml | 53 ---- resources/traffic_profiles/wrk/www/empty.html | 0 25 files changed, 2 insertions(+), 1721 deletions(-) delete mode 100644 resources/libraries/python/tcp.py delete mode 100644 resources/libraries/robot/hoststack/tcp_setup.robot delete mode 100644 resources/libraries/robot/wrk/wrk_utils.robot delete mode 100644 resources/tools/testbed-setup/ansible/roles/wrk/defaults/main.yaml delete mode 100644 resources/tools/testbed-setup/ansible/roles/wrk/tasks/main.yaml delete mode 100644 resources/tools/wrk/__init__.py delete mode 100644 resources/tools/wrk/doc/wrk_lld.rst delete mode 100644 resources/tools/wrk/wrk.py delete mode 100644 resources/tools/wrk/wrk_errors.py delete mode 100644 resources/tools/wrk/wrk_traffic_profile_parser.py delete mode 100755 resources/tools/wrk/wrk_utils.sh delete mode 100644 resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-1u1c50con-bw.yaml delete mode 100644 resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-cps.yaml delete mode 100644 resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-rps.yaml delete mode 100644 resources/traffic_profiles/wrk/www/empty.html diff --git a/README.md b/README.md index 299011d0c3..5b7d2353ef 100644 --- a/README.md +++ b/README.md @@ -131,12 +131,10 @@ resources │   │   ├── testbed-setup # Physical testbed setup scripts │   │   ├── topology # Helper scripts for topology manipulation │   │   ├── trex # TRex driver -│   │   ├── vagrant # VPP device vagrant environment -│   │   └── wrk # WRK driver +│   │   └── vagrant # VPP device vagrant environment │   ├── topology_schemas │   ├── traffic_profiles # Performance tests traffic profiles -│   │   ├── trex -│   │   └── wrk +│   │   └── trex │   └── traffic_scripts # Functional tests traffic profiles │   ├── dhcp │   └── lisp diff --git a/resources/libraries/python/Constants.py b/resources/libraries/python/Constants.py index 6bf503da51..08de52368e 100644 --- a/resources/libraries/python/Constants.py +++ b/resources/libraries/python/Constants.py @@ -148,9 +148,6 @@ class Constants: # 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" - # VPP Communications Library LD_PRELOAD library VCL_LDPRELOAD_LIBRARY = u"/usr/lib/x86_64-linux-gnu/libvcl_ldpreload.so" diff --git a/resources/libraries/python/autogen/Regenerator.py b/resources/libraries/python/autogen/Regenerator.py index 0d291e231e..e6474e566d 100644 --- a/resources/libraries/python/autogen/Regenerator.py +++ b/resources/libraries/python/autogen/Regenerator.py @@ -480,9 +480,6 @@ class Regenerator: {u"frame_size": u"IMIX_v4_1", u"phy_cores": 2}, {u"frame_size": u"IMIX_v4_1", u"phy_cores": 4} ] - hs_wrk_kwargs_list = [ - {u"frame_size": 0, u"phy_cores": i} for i in (1, 2, 4) - ] hs_bps_kwargs_list = [ {u"frame_size": 1460, u"phy_cores": 1}, ] @@ -513,8 +510,6 @@ class Regenerator: write_default_files(in_filename, in_prolog, default_kwargs_list) 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, hs_wrk_kwargs_list) elif in_filename.endswith(u"-bps.robot"): hoststack_kwargs_list = \ hs_quic_kwargs_list if u"quic" in in_filename \ diff --git a/resources/libraries/python/tcp.py b/resources/libraries/python/tcp.py deleted file mode 100644 index 62cff2f4ff..0000000000 --- a/resources/libraries/python/tcp.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2019 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. - -"""TCP util library.""" - -from resources.libraries.python.Constants import Constants -from resources.libraries.python.PapiExecutor import PapiSocketExecutor - - -class TCPUtils: - """Implementation of the TCP utilities.""" - - www_root_dir = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_TP_WRK_WWW}" - - def __init__(self): - pass - - @classmethod - def start_vpp_http_server_params( - cls, node, http_static_plugin, prealloc_fifos, fifo_size, - private_segment_size): - """Start the test HTTP server internal application or - the HTTP static server plugin internal applicatoin on the given node. - - http static server www-root prealloc-fifos - fifo-size - private-segment-size - -- or -- - test http server static prealloc-fifos fifo-size - private-segment-size - - - Where N is the max number of connections you expect to handle at one - time and should be small if you test for CPS and exchange few - bytes, say 4, if each connection just exchanges few packets. Or it - should be much larger, up to 1024/4096 (i.e. 1-4MB) if you have only - one connection and exchange a lot of packets, i.e., when you test for - RPS. If you need to allocate lots of FIFOs, so you test for CPS, make - private-segment-size something like 4g. - - Example: - - For CPS - http static server www-root prealloc-fifos 10000 - fifo-size 64 private-segment-size 4000m - - For RPS - test http server static prealloc-fifos 500000 fifo-size 4 - private-segment-size 4000m - - :param node: Node to start HTTP server on. - :param http_static_plugin: Run HTTP static server plugin - :param prealloc_fifos: Max number of connections you expect to handle at - one time. - :param fifo_size: FIFO size in kB. - :param private_segment_size: Private segment size. Number + unit. - :type node: dict - :type http_static_plugin: boolean - :type prealloc_fifos: str - :type fifo_size: str - :type private_segment_size: str - """ - cmd = f"http static server www-root {cls.www_root_dir} " \ - f"prealloc-fifos {prealloc_fifos} fifo-size {fifo_size} " \ - f"private-segment-size {private_segment_size}" \ - if http_static_plugin \ - else f"test http server static prealloc-fifos {prealloc_fifos} " \ - f"fifo-size {fifo_size} private-segment-size {private_segment_size}" - - PapiSocketExecutor.run_cli_cmd(node, cmd) diff --git a/resources/libraries/robot/hoststack/tcp_setup.robot b/resources/libraries/robot/hoststack/tcp_setup.robot deleted file mode 100644 index 718070979f..0000000000 --- a/resources/libraries/robot/hoststack/tcp_setup.robot +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2019 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.InterfaceUtil -| Library | resources.libraries.python.IPUtil -| Library | resources.libraries.python.tcp.TCPUtils -| -| Resource | resources/libraries/robot/ip/ip4.robot -| -| Documentation | L2 keywords to set up VPP to test tcp. - -*** Keywords *** -| Set up HTTP server with parameters on the VPP node -| | [Documentation] -| | ... | Configure IP address on the port, set it up and start HTTP server on -| | ... | the VPP. -| | -| | ... | *Arguments:* -| | ... | - http_static_plugin - Use the HTTP static plugin http server. -| | ... | Type: boolean -| | ... | - prealloc_fifos - Max number of connections you expect to handle -| | ... | at one time. Type: string -| | ... | - fifo_size - FIFO size in kB. Type: string -| | ... | - private_segment_size - Private segment size. Number + unit. -| | ... | Type: string -| | -| | ... | *Example:* -| | -| | ... | \| Set up HTTP server with paramters on the VPP node \| ${true}\ -| | ... | \| 400 \| 4096 \| 2g \| -| | -| | [Arguments] | ${http_static_plugin} | ${prealloc_fifos} | ${fifo_size} -| | ... | ${private_segment_size} -| | -| | Set Interface State | ${dut1} | ${dut1_if1} | up -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.10.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.20.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.30.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.40.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.50.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.60.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.70.2 | 24 -| | VPP Interface Set IP Address | ${dut1} | ${dut1_if1} | 192.168.80.2 | 24 -| | Vpp Node Interfaces Ready Wait | ${dut1} -| | Start VPP HTTP server params | ${dut1} | ${http_static_plugin} -| | ... | ${prealloc_fifos} | ${fifo_size} | ${private_segment_size} diff --git a/resources/libraries/robot/shared/suite_setup.robot b/resources/libraries/robot/shared/suite_setup.robot index 05e8fe8e91..a9e57e7024 100644 --- a/resources/libraries/robot/shared/suite_setup.robot +++ b/resources/libraries/robot/shared/suite_setup.robot @@ -19,9 +19,7 @@ | Library | resources.libraries.python.NodePath | Library | resources.libraries.python.topology.Topology | Library | resources.libraries.python.TrafficGenerator -| Library | resources.tools.wrk.wrk | Variables | resources/libraries/python/Constants.py -| Resource | resources/libraries/robot/wrk/wrk_utils.robot | | Documentation | Suite setup keywords. *** Keywords *** @@ -200,33 +198,3 @@ | | Configure crypto device on all DUTs | ${crypto_type} | numvfs=${numvfs} | | ... | force_init=${True} | | Configure kernel module on all DUTs | vfio_pci | force_load=${True} - -| Additional Suite Setup Action For wrk -| | [Documentation] -| | ... | Additional Setup for suites which uses WRK TG. -| | -| | Verify Program Installed | ${tg} | wrk -| | Iface update numa node | ${tg} -# Make sure TRex is stopped -| | ${running}= | Is TRex running | ${tg} -| | Run keyword if | ${running}==${True} | Teardown traffic generator | ${tg} -| | ${curr_driver}= | Get PCI dev driver | ${tg} -| | ... | ${tg['interfaces']['${tg_if1}']['pci_address']} -| | Run keyword if | '${curr_driver}'!='${None}' -| | ... | PCI Driver Unbind | ${tg} | -| | ... | ${tg['interfaces']['${tg_if1}']['pci_address']} -# Bind tg_if1 to driver specified in the topology -| | ${driver}= | Get Variable Value | ${tg['interfaces']['${tg_if1}']['driver']} -| | PCI Driver Bind | ${tg} -| | ... | ${tg['interfaces']['${tg_if1}']['pci_address']} | ${driver} -# Set IP on tg_if1 -| | ${intf_name}= | Get Linux interface name | ${tg} -| | ... | ${tg['interfaces']['${tg_if1}']['pci_address']} -| | FOR | ${ip_addr} | IN | @{wrk_ip_addrs} -| | | ${ip_addr_on_intf}= | Linux interface has IP | ${tg} | ${intf_name} -| | | ... | ${ip_addr} | ${wrk_ip_prefix} -| | | Run Keyword If | ${ip_addr_on_intf}==${False} | Set Linux interface IP -| | | ... | ${tg} | ${intf_name} | ${ip_addr} | ${wrk_ip_prefix} -| | END -| | Set Linux interface up | ${tg} | ${intf_name} -| | Check wrk | ${tg} diff --git a/resources/libraries/robot/shared/suite_teardown.robot b/resources/libraries/robot/shared/suite_teardown.robot index f76fddc9d6..f164b0eeb5 100644 --- a/resources/libraries/robot/shared/suite_teardown.robot +++ b/resources/libraries/robot/shared/suite_teardown.robot @@ -50,23 +50,6 @@ | | | ... | ${nodes['${dut}']} | ${${dut}_${int}1}[0] | ${${dut}_${int}2}[0] | | END -| Additional Suite Tear Down Action For wrk -| | [Documentation] -| | ... | Additional teardown for suites which uses wrk. -| | -| | ${intf_name}= | Get Linux interface name | ${tg} -| | ... | ${tg['interfaces']['${tg_if1}']['pci_address']} -| | FOR | ${ip_addr} | IN | @{wrk_ip_addrs} -| | | ${ip_addr_on_intf}= | Linux Interface Has IP | ${tg} | ${intf_name} -| | | ... | ${ip_addr} | ${wrk_ip_prefix} -| | | Run Keyword If | ${ip_addr_on_intf}==${True} | Delete Linux Interface IP -| | | ... | ${tg} | ${intf_name} | ${ip_addr} | ${wrk_ip_prefix} -| | END -| | Run Keyword And Ignore Error | PCI Driver Unbind -| | ... | ${tg} | ${tg['interfaces']['${tg_if1}']['pci_address']} -| | Run Keyword And Ignore Error | PCI Driver Unbind -| | ... | ${tg} | ${tg['interfaces']['${tg_if2}']['pci_address']} - | Additional Suite Tear Down Action For hoststack | | [Documentation] | | ... | Additional teardown for suites which uses hoststack test programs. diff --git a/resources/libraries/robot/wrk/wrk_utils.robot b/resources/libraries/robot/wrk/wrk_utils.robot deleted file mode 100644 index 0e7150ba1e..0000000000 --- a/resources/libraries/robot/wrk/wrk_utils.robot +++ /dev/null @@ -1,83 +0,0 @@ -# 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.tools.wrk.wrk -| Library | resources.libraries.python.IPUtil -| Library | resources.libraries.python.DUTSetup -| Library | resources.libraries.python.TrafficGenerator -| Library | resources.libraries.python.topology.Topology -| -| Documentation | L2 keywords to set up wrk and to measure performance -| ... | parameters using wrk. - -*** Variables *** -| ${wrk_ip_prefix}= | 24 -| @{wrk_ip_addrs}= | 192.168.10.1 | 192.168.20.1 | 192.168.30.1 -| ... | 192.168.40.1 | 192.168.50.1 | 192.168.60.1 | 192.168.70.1 -| ... | 192.168.80.1 - -*** Keywords *** -| Measure throughput -| | [Documentation] -| | ... | Measure throughput using wrk. -| | -| | ... | *Arguments:* -| | ... | - ${profile} - The name of the wrk traffic profile defining the -| | ... | traffic. Type: string -| | -| | ... | *Example:* -| | -| | ... | \| Measure throughput \| wrk-bw-1url-1core-50con \| -| | -| | [Arguments] | ${profile} -| | -| | ${tg_numa}= | Get interfaces numa node | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] -| | ${output}= | Run wrk | ${tg} | ${profile} | ${tg_numa} | bw -| | Set test message | ${output} - -| Measure requests per second -| | [Documentation] -| | ... | Measure number of requests per second using wrk. -| | -| | ... | *Arguments:* -| | ... | - ${profile} - The name of the wrk traffic profile defining the -| | ... | traffic. Type: string -| | -| | ... | *Example:* -| | -| | ... | \| Measure requests per second \| wrk-bw-1url-1core-50con \| -| | -| | [Arguments] | ${profile} -| | -| | ${tg_numa}= | Get interfaces numa node | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] -| | ${output}= | Run wrk | ${tg} | ${profile} | ${tg_numa} | rps -| | Set test message | ${output} - -| Measure connections per second -| | [Documentation] -| | ... | Measure number of connections per second using wrk. -| | -| | ... | *Arguments:* -| | ... | - ${profile} - The name of the wrk traffic profile defining the -| | ... | traffic. Type: string -| | -| | ... | *Example:* -| | -| | ... | \| Measure connections per second \| wrk-bw-1url-1core-50con \| -| | -| | [Arguments] | ${profile} -| | -| | ${tg_numa}= | Get interfaces numa node | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] -| | ${output}= | Run wrk | ${tg} | ${profile} | ${tg_numa} | cps -| | Set test message | ${output} diff --git a/resources/tools/testbed-setup/ansible/roles/cleanup/tasks/tg.yaml b/resources/tools/testbed-setup/ansible/roles/cleanup/tasks/tg.yaml index a026ec2acd..9ac83bc9fc 100644 --- a/resources/tools/testbed-setup/ansible/roles/cleanup/tasks/tg.yaml +++ b/resources/tools/testbed-setup/ansible/roles/cleanup/tasks/tg.yaml @@ -7,10 +7,3 @@ process: "_t-rex" when: docker_tg is undefined tags: kill-process - -- name: Kill processes - WRK - import_tasks: kill_process.yaml - vars: - process: "wrk" - tags: kill-process - when: docker_tg is undefined \ No newline at end of file diff --git a/resources/tools/testbed-setup/ansible/roles/tg/files/csit-initialize-docker-tg.sh b/resources/tools/testbed-setup/ansible/roles/tg/files/csit-initialize-docker-tg.sh index e9f19fd899..7b90d20bda 100755 --- a/resources/tools/testbed-setup/ansible/roles/tg/files/csit-initialize-docker-tg.sh +++ b/resources/tools/testbed-setup/ansible/roles/tg/files/csit-initialize-docker-tg.sh @@ -44,8 +44,6 @@ case "${1:-start}" in dcr_stc_params+="--volume /dev:/dev " # Mount /opt/boot/ where VM kernel and initrd are located. dcr_stc_params+="--volume /opt:/opt " - # Mount /usr/local/bin/wrk where WRK is located. - dcr_stc_params+="--volume /usr/local/bin/wrk:/usr/local/bin/wrk " # Mount host hugepages for VMs. dcr_stc_params+="--volume /dev/hugepages:/dev/hugepages " diff --git a/resources/tools/testbed-setup/ansible/roles/wrk/defaults/main.yaml b/resources/tools/testbed-setup/ansible/roles/wrk/defaults/main.yaml deleted file mode 100644 index 2d378487df..0000000000 --- a/resources/tools/testbed-setup/ansible/roles/wrk/defaults/main.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -# file: roles/wrk/defaults/main.yaml - -packages: "{{ packages_base + packages_by_distro[ansible_distribution | lower] + packages_by_arch[ansible_machine] }}" - -packages_base: - - [] - -packages_by_distro: - ubuntu: - - "build-essential" - -packages_by_arch: - aarch64: - - [] - x86_64: - - [] - -wrk_target_dir: "/opt" -wrk_version: - - "4.0.2" diff --git a/resources/tools/testbed-setup/ansible/roles/wrk/tasks/main.yaml b/resources/tools/testbed-setup/ansible/roles/wrk/tasks/main.yaml deleted file mode 100644 index 163044de43..0000000000 --- a/resources/tools/testbed-setup/ansible/roles/wrk/tasks/main.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -# file: roles/wrk/tasks/main.yaml - -- name: WRK - Install Distribution - Release - Machine Prerequisites - package: - name: "{{ packages | flatten(levels=1) }}" - state: latest - update_cache: true - tags: - - install-dependencies - -- name: WRK - Get Release Archive - get_url: - url: "https://github.com/wg/wrk/archive/{{ item }}.tar.gz" - dest: "{{ wrk_target_dir }}/wrk-{{ item }}.tar.gz" - mode: 0644 - loop: "{{ wrk_version }}" - register: wrk_downloaded - tags: - - install-wrk - -- name: WRK - Extract Release Archive - unarchive: - remote_src: true - src: "{{ wrk_target_dir }}/wrk-{{ item }}.tar.gz" - dest: "{{ wrk_target_dir }}/" - creates: "{{ wrk_target_dir }}/wrk-{{ item }}/src" - loop: "{{ wrk_version }}" - register: wrk_extracted - tags: - - install-wrk - -- name: WRK - Compile Release I - command: "make" - args: - chdir: "{{ wrk_target_dir }}/wrk-{{ item }}" - loop: "{{ wrk_version }}" - when: wrk_extracted - register: wrk_compiled - tags: - - install-wrk - -- name: WRK - Copy Binary - command: "cp {{ wrk_target_dir }}/wrk-{{ item }}/wrk /usr/local/bin/" - loop: "{{ wrk_version }}" - when: wrk_compiled - tags: - - install-wrk diff --git a/resources/tools/testbed-setup/ansible/tg.yaml b/resources/tools/testbed-setup/ansible/tg.yaml index e800881127..e6c5b4b9db 100644 --- a/resources/tools/testbed-setup/ansible/tg.yaml +++ b/resources/tools/testbed-setup/ansible/tg.yaml @@ -20,8 +20,6 @@ tags: iperf - role: trex tags: trex - - role: wrk - tags: wrk - role: docker tags: docker - role: performance_tuning diff --git a/resources/tools/testbed-setup/ansible/tg_aws.yaml b/resources/tools/testbed-setup/ansible/tg_aws.yaml index dda50f416e..77fde766c9 100644 --- a/resources/tools/testbed-setup/ansible/tg_aws.yaml +++ b/resources/tools/testbed-setup/ansible/tg_aws.yaml @@ -19,8 +19,6 @@ tags: iperf - role: trex tags: trex - - role: wrk - tags: wrk - role: docker tags: docker - role: cleanup diff --git a/resources/tools/testbed-setup/ansible/tg_azure.yaml b/resources/tools/testbed-setup/ansible/tg_azure.yaml index afe2d11c4a..7ecf6d074c 100644 --- a/resources/tools/testbed-setup/ansible/tg_azure.yaml +++ b/resources/tools/testbed-setup/ansible/tg_azure.yaml @@ -17,8 +17,6 @@ tags: iperf - role: trex tags: trex - - role: wrk - tags: wrk - role: docker tags: docker - role: cleanup diff --git a/resources/tools/wrk/__init__.py b/resources/tools/wrk/__init__.py deleted file mode 100644 index 977169c00f..0000000000 --- a/resources/tools/wrk/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2018 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. - -""" -__init__ file for directory tools/wrk -""" diff --git a/resources/tools/wrk/doc/wrk_lld.rst b/resources/tools/wrk/doc/wrk_lld.rst deleted file mode 100644 index 1437fd8948..0000000000 --- a/resources/tools/wrk/doc/wrk_lld.rst +++ /dev/null @@ -1,293 +0,0 @@ -Onboarding of wrk as a http traffic generator in CSIT ------------------------------------------------------ - -wrk is a modern HTTP benchmarking tool capable of generating significant -load when run on a single multi-core CPU. - -An optional LuaJIT script can perform HTTP request generation, response -processing, and custom reporting. - - -wrk installation on TG node -''''''''''''''''''''''''''' - -**Procedure** - - #. Check if wrk is installed on the TG node. - #. If not, install it. - -**wrk installation** - -:: - - # Install pre-requisites: - sudo apt-get install build-essential libssl-dev git -y - - # Get the specified version: - wget ${WRK_DWNLD_PATH}/${WRK_TAR} - tar xzf ${WRK_TAR} - cd wrk-${WRK_VERSION} - - # Build the wrk: - cd wrk - make - - # Move the executable to somewhere in the PATH, e.q: - sudo cp wrk /usr/local/bin - - -wrk traffic profile -''''''''''''''''''' - -**The traffic profile can include these items:** - - - List of URLs - mandatory, - - The first CPU used to run wrk - mandatory, - - Number of CPUs used for wrk - mandatory, - - Test duration - mandatory, - - Number of threads - mandatory, - - Number of connections - mandatory, - - LuaJIT script - optional, defaults to no script, - - HTTP header - optional, defaults to no header, - - Latency - optional, defaults to False, - - Timeout - optional, defaults to wrk default. - -**List of URLs** - -List of URLs for requests. Each URL is requested in a separate instance of wrk. -Type: list - -*Example:* - -:: - - urls: - - "http://192.168.1.1/1kB.bin" - - "http://192.168.1.2/1kB.bin" - - "http://192.168.1.3/1kB.bin" - -**The first CPU used to run wrk** -The first CPU used to run wrk. The other CPUs follow this one. -Type: integer - -*Example:* - -:: - - first-cpu: 1 - -**Number of CPUs used for wrk** - -The number of CPUs used for wrk. The number of CPUs must be a multiplication -of the number of URLs. -Type: integer - -*Example:* - -:: - - cpus: 6 - -.. note:: - - The combinations of URLs and a number of CPUs create following use cases: - - - One URL and one CPU - One instance of wrk sends one request (URL) via - one NIC - - One URL and n CPUs - n instances of wrk send the same request (URL) - via one or more NICs - - n URLs and n CPUs - n instances of wrk send n requests (URL) via one - or more NICs - - n URLs and m CPUs, m = a * n - m instances of wrk send n requests - (URL) via one or more NICs - -**Test duration** - -Duration of the test in seconds. -Type: integer - -*Example:* - -:: - - duration: 30 - -**Number of threads** - -Total number of threads to use by wrk to send traffic. -Type: integer - -*Example:* - -:: - - nr-of-threads: 1 - -**Number of connections** - -Total number of HTTP connections to keep open with each thread handling -N = connections / threads. -Type: integer - -*Example:* - -:: - - nr-of-connections: 50 - -**LuaJIT script** - -Path to LuaJIT script. -Type: string - -For more information see: https://github.com/wg/wrk/blob/master/SCRIPTING - -*Example:* - -:: - - script: "scripts/report.lua" - -**HTTP header** - -HTTP header to add to request. -Type: string (taken as it is) or dictionary - -*Example:* - -:: - - # Dictionary: - header: - Connection: "close" - -or - -:: - - # String: - header: "Connection: close" - -**Latency** - -Print detailed latency statistics. -Type: boolean - -*Example:* - -:: - - latency: False - -**Timeout** - -Record a timeout if a response is not received within this amount of time. -Type: integer - -:: - - timeout: 5 - -**Examples of a wrk traffic profile** - -*Get the number of connections per second:* - -- Use 3 CPUs to send 3 different requests via 3 NICs. -- The test takes 30 seconds. -- wrk sends traffic in one thread per CPU. -- There will be open max 50 connection at the same time. -- The header is set to 'Connection: "close"' so wrk opens separate connection - for each request. Then the number of requests equals to the number of - connections. -- Timeout for responses from the server is set to 5 seconds. - -:: - - urls: - - "http://192.168.1.1/0B.bin" - - "http://192.168.1.2/0B.bin" - - "http://192.168.1.3/0B.bin" - cpus: 3 - duration: 30 - nr-of-threads: 1 - nr-of-connections: 50 - header: - Connection: "close" - timeout: 5 - -*Get the number of requests per second:* - -- Use 3 CPUs to send 3 different requests via 3 NICs. -- The test takes 30 seconds. -- wrk sends traffic in one thread per CPU. -- There will be max 50 concurrent open connections. - -:: - - urls: - - "http://192.168.1.1/1kB.bin" - - "http://192.168.1.2/1kB.bin" - - "http://192.168.1.3/1kB.bin" - cpus: 3 - duration: 30 - nr-of-threads: 1 - nr-of-connections: 50 - -*Get the bandwidth:* - -- Use 3 CPUs to send 3 different requests via 3 NICs. -- The test takes 30 seconds. -- wrk sends traffic in one thread per CPU. -- There will be open max 50 connection at the same time. -- Timeout for responses from the server is set to 5 seconds. - -:: - - urls: - - "http://192.168.1.1/1MB.bin" - - "http://192.168.1.2/1MB.bin" - - "http://192.168.1.3/1MB.bin" - cpus: 3 - duration: 30 - nr-of-threads: 1 - nr-of-connections: 50 - timeout: 5 - - -Running wrk -''''''''''' - -**Suite setup phase** - -CSIT framework checks if wrk is installed on the TG node. If not, or if the -installation is forced, it installs it on the TG node. - -*Procedure:* - - #. Make sure TRex is stopped. - #. Bind used TG interfaces to corresponding drivers (defined in the topology - file). - #. If the wrk installation is forced: - - - Destroy existing wrk - - #. If the wrk installation is not forced: - - - Check if wrk is installed. - - If installed, exit. - - #. Clone wrk from git (https://github.com/wg/wrk.git) - #. Build wrk. - #. Copy the executable to /usr/local/bin so it is in the PATH. - -**Test phase** - -*Procedure:* - -#. Read the wrk traffic profile. -#. Verify the profile. -#. Use the information from the profile to set the wrk parameters. -#. Run wrk. -#. Read the output. -#. Evaluate and log the output. - diff --git a/resources/tools/wrk/wrk.py b/resources/tools/wrk/wrk.py deleted file mode 100644 index 85d18d4a9c..0000000000 --- a/resources/tools/wrk/wrk.py +++ /dev/null @@ -1,299 +0,0 @@ -# Copyright (c) 2019 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. - -"""wrk implementation into CSIT framework. -""" - -import re - -from copy import deepcopy -from time import sleep - -from robot.api import logger - -from resources.libraries.python.ssh import SSH -from resources.libraries.python.topology import NodeType -from resources.libraries.python.CpuUtils import CpuUtils -from resources.libraries.python.Constants import Constants - -from resources.tools.wrk.wrk_traffic_profile_parser import WrkTrafficProfile -from resources.tools.wrk.wrk_errors import WrkError - - -REGEX_LATENCY_STATS = \ - r"Latency\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\%)" -REGEX_RPS_STATS = \ - r"Req/Sec\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\S*)\s*" \ - r"(\d*\.*\d*\%)" -REGEX_RPS = r"Requests/sec:\s*" \ - r"(\d*\.*\S*)" -REGEX_BW = r"Transfer/sec:\s*" \ - r"(\d*\.*\S*)" -REGEX_LATENCY_DIST = \ - r"Latency Distribution\n" \ - r"\s*50\%\s*(\d*\.*\d*\D*)\n" \ - r"\s*75\%\s*(\d*\.*\d*\D*)\n" \ - r"\s*90\%\s*(\d*\.*\d*\D*)\n" \ - r"\s*99\%\s*(\d*\.*\d*\D*)\n" - -# Split number and multiplicand, e.g. 14.25k --> 14.25 and k -REGEX_NUM = r"(\d*\.*\d*)(\D*)" - - -def check_wrk(tg_node): - """Check if wrk is installed on the TG node. - - :param tg_node: Traffic generator node. - :type tg_node: dict - :raises: RuntimeError if the given node is not a TG node or if the - command is not availble. - """ - - if tg_node[u"type"] != NodeType.TG: - raise RuntimeError(u"Node type is not a TG.") - - ssh = SSH() - ssh.connect(tg_node) - - ret, _, _ = ssh.exec_command( - f"sudo -E sh -c '{Constants.REMOTE_FW_DIR}/resources/tools/" - f"wrk/wrk_utils.sh installed'" - ) - if int(ret) != 0: - raise RuntimeError(u"WRK is not installed on TG node.") - - -def run_wrk(tg_node, profile_name, tg_numa, test_type, warm_up=False): - """Send the traffic as defined in the profile. - - :param tg_node: Traffic generator node. - :param profile_name: The name of wrk traffic profile. - :param tg_numa: Numa node on which wrk will run. - :param test_type: The type of the tests: cps, rps, bw - :param warm_up: If True, warm-up traffic is generated before test traffic. - :type profile_name: str - :type tg_node: dict - :type tg_numa: int - :type test_type: str - :type warm_up: bool - :returns: Message with measured data. - :rtype: str - :raises: RuntimeError if node type is not a TG. - """ - - if tg_node[u"type"] != NodeType.TG: - raise RuntimeError(u"Node type is not a TG.") - - # Parse and validate the profile - profile_path = f"resources/traffic_profiles/wrk/{profile_name}.yaml" - profile = WrkTrafficProfile(profile_path).traffic_profile - - cores = CpuUtils.cpu_list_per_node(tg_node, tg_numa) - first_cpu = cores[profile[u"first-cpu"]] - - if len(profile[u"urls"]) == 1 and profile[u"cpus"] == 1: - params = [ - u"traffic_1_url_1_core", - str(first_cpu), - str(profile[u"nr-of-threads"]), - str(profile[u"nr-of-connections"]), - f"{profile[u'duration']}s", - f"'{profile[u'header']}'", - str(profile[u"timeout"]), - str(profile[u"script"]), - str(profile[u"latency"]), - f"'{u' '.join(profile[u'urls'])}'" - ] - if warm_up: - warm_up_params = deepcopy(params) - warm_up_params[4] = u"10s" - elif len(profile[u"urls"]) == profile[u"cpus"]: - params = [ - u"traffic_n_urls_n_cores", - str(first_cpu), - str(profile[u"nr-of-threads"]), - str(profile[u"nr-of-connections"]), - f"{profile[u'duration']}s", - f"'{profile[u'header']}'", - str(profile[u"timeout"]), - str(profile[u"script"]), - str(profile[u"latency"]), - f"'{u' '.join(profile[u'urls'])}'" - ] - if warm_up: - warm_up_params = deepcopy(params) - warm_up_params[4] = u"10s" - else: - params = [ - u"traffic_n_urls_m_cores", - str(first_cpu), - str(profile[u"cpus"] // len(profile[u"urls"])), - str(profile[u"nr-of-threads"]), - str(profile[u"nr-of-connections"]), - f"{profile[u'duration']}s", - f"'{profile[u'header']}'", - str(profile[u"timeout"]), - str(profile[u"script"]), - str(profile[u"latency"]), - f"'{u' '.join(profile[u'urls'])}'" - ] - if warm_up: - warm_up_params = deepcopy(params) - warm_up_params[5] = u"10s" - - args = u" ".join(params) - - ssh = SSH() - ssh.connect(tg_node) - - if warm_up: - warm_up_args = u" ".join(warm_up_params) - ret, _, _ = ssh.exec_command( - f"{Constants.REMOTE_FW_DIR}/resources/tools/wrk/wrk_utils.sh " - f"{warm_up_args}", timeout=1800 - ) - if int(ret) != 0: - raise RuntimeError(u"wrk runtime error.") - sleep(60) - - ret, stdout, _ = ssh.exec_command( - f"{Constants.REMOTE_FW_DIR}/resources/tools/wrk/wrk_utils.sh {args}", - timeout=1800 - ) - if int(ret) != 0: - raise RuntimeError('wrk runtime error.') - - stats = _parse_wrk_output(stdout) - - log_msg = u"\nMeasured values:\n" - if test_type == u"cps": - log_msg += u"Connections/sec: Avg / Stdev / Max / +/- Stdev\n" - for item in stats[u"rps-stats-lst"]: - log_msg += u" / ".join(map(str, item)) + u"\n" - log_msg += f"Total cps: {stats[u'rps-sum']}cps\n" - elif test_type == u"rps": - log_msg += u"Requests/sec: Avg / Stdev / Max / +/- Stdev\n" - for item in stats[u"rps-stats-lst"]: - log_msg += u" / ".join(map(str, item)) + u"\n" - log_msg += f"Total rps: {stats[u'rps-sum']}rps\n" - elif test_type == u"bw": - log_msg += f"Transfer/sec: {stats[u'bw-sum']}Bps" - - logger.info(log_msg) - - return log_msg - - -def _parse_wrk_output(msg): - """Parse the wrk stdout with the results. - - :param msg: stdout of wrk. - :type msg: str - :returns: Parsed results. - :rtype: dict - :raises: WrkError if the message does not include the results. - """ - - if u"Thread Stats" not in msg: - raise WrkError(u"The output of wrk does not include the results.") - - msg_lst = msg.splitlines(False) - - stats = { - u"latency-dist-lst": list(), - u"latency-stats-lst": list(), - u"rps-stats-lst": list(), - u"rps-lst": list(), - u"bw-lst": list(), - u"rps-sum": 0, - u"bw-sum": None - } - - for line in msg_lst: - if u"Latency Distribution" in line: - # Latency distribution - 50%, 75%, 90%, 99% - pass - elif u"Latency" in line: - # Latency statistics - Avg, Stdev, Max, +/- Stdev - pass - elif u"Req/Sec" in line: - # rps statistics - Avg, Stdev, Max, +/- Stdev - stats[u"rps-stats-lst"].append( - ( - _evaluate_number(re.search(REGEX_RPS_STATS, line).group(1)), - _evaluate_number(re.search(REGEX_RPS_STATS, line).group(2)), - _evaluate_number(re.search(REGEX_RPS_STATS, line).group(3)), - _evaluate_number(re.search(REGEX_RPS_STATS, line).group(4)) - ) - ) - elif u"Requests/sec:" in line: - # rps (cps) - stats[u"rps-lst"].append( - _evaluate_number(re.search(REGEX_RPS, line).group(1)) - ) - elif u"Transfer/sec:" in line: - # BW - stats[u"bw-lst"].append( - _evaluate_number(re.search(REGEX_BW, line).group(1)) - ) - - for item in stats[u"rps-stats-lst"]: - stats[u"rps-sum"] += item[0] - stats[u"bw-sum"] = sum(stats[u"bw-lst"]) - - return stats - - -def _evaluate_number(num): - """Evaluate the numeric value of the number with multiplicands, e.g.: - 12.25k --> 12250 - - :param num: Number to evaluate. - :type num: str - :returns: Evaluated number. - :rtype: float - :raises: WrkError if it is not possible to evaluate the given number. - """ - - val = re.search(REGEX_NUM, num) - try: - val_num = float(val.group(1)) - except ValueError: - raise WrkError( - u"The output of wrk does not include the results or the format " - u"of results has changed." - ) - val_mul = val.group(2).lower() - if val_mul: - if u"k" in val_mul: - val_num *= 1000 - elif u"m" in val_mul: - val_num *= 1000000 - elif u"g" in val_mul: - val_num *= 1000000000 - elif u"b" in val_mul: - pass - elif u"%" in val_mul: - pass - elif u"" in val_mul: - pass - else: - raise WrkError(f"The multiplicand {val_mul} is not defined.") - return val_num diff --git a/resources/tools/wrk/wrk_errors.py b/resources/tools/wrk/wrk_errors.py deleted file mode 100644 index 2cdd76815a..0000000000 --- a/resources/tools/wrk/wrk_errors.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (c) 2019 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. - -"""Implementation of exceptions used in the wrk traffic generator. -""" - - -from robot.api import logger - - -class WrkError(Exception): - """Exception(s) raised by the wrk traffic generator. - - When raising this exception, put this information to the message in this - order: - - short description of the encountered problem (parameter msg), - - relevant messages if there are any collected, e.g., from caught - exception (optional parameter details), - - relevant data if there are any collected (optional parameter details). - """ - - def __init__(self, msg, details=u""): - """Sets the exception message and the level. - - :param msg: Short description of the encountered problem. - :param details: Relevant messages if there are any collected, e.g.: - from caught exception (optional parameter details), or relevant data if - there are any collected (optional parameter details). - :type msg: str - :type details: str - """ - - super(WrkError, self).__init__() - self._msg = msg - self._details = details - - logger.error(self._msg) - if self._details: - logger.error(self._details) - - def __repr__(self): - return repr(self._msg) - - def __str__(self): - return str(self._msg) diff --git a/resources/tools/wrk/wrk_traffic_profile_parser.py b/resources/tools/wrk/wrk_traffic_profile_parser.py deleted file mode 100644 index f553465705..0000000000 --- a/resources/tools/wrk/wrk_traffic_profile_parser.py +++ /dev/null @@ -1,294 +0,0 @@ -# Copyright (c) 2019 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. - -"""wrk traffic profile parser. - -See LLD for the structure of a wrk traffic profile. -""" - - -from os.path import isfile -from pprint import pformat - -from yaml import safe_load, YAMLError -from robot.api import logger - -from resources.tools.wrk.wrk_errors import WrkError - - -class WrkTrafficProfile: - """The wrk traffic profile. - """ - - MANDATORY_PARAMS = ( - u"urls", - u"first-cpu", - u"cpus", - u"duration", - u"nr-of-threads", - u"nr-of-connections" - ) - - INTEGER_PARAMS = ( - (u"cpus", 1), - (u"first-cpu", 0), - (u"duration", 1), - (u"nr-of-threads", 1), - (u"nr-of-connections", 1) - ) - - def __init__(self, profile_name): - """Read the traffic profile from the yaml file. - - :param profile_name: Path to the yaml file with the profile. - :type profile_name: str - :raises: WrkError if it is not possible to parse the profile. - """ - - self._profile_name = None - self._traffic_profile = None - - self.profile_name = profile_name - - try: - with open(self.profile_name, u"rt") as profile_file: - self.traffic_profile = safe_load(profile_file) - except IOError as err: - raise WrkError( - msg=f"An error occurred while opening the file " - f"'{self.profile_name}'.", details=str(err) - ) - except YAMLError as err: - raise WrkError( - msg=f"An error occurred while parsing the traffic profile " - f"'{self.profile_name}'.", details=str(err) - ) - - self._validate_traffic_profile() - - if self.traffic_profile: - logger.debug( - f"\nThe wrk traffic profile '{self.profile_name}' is valid.\n" - ) - logger.debug(f"wrk traffic profile '{self.profile_name}':") - logger.debug(pformat(self.traffic_profile)) - else: - logger.debug( - f"\nThe wrk traffic profile '{self.profile_name}' is invalid.\n" - ) - raise WrkError( - f"\nThe wrk traffic profile '{self.profile_name}' is invalid.\n" - ) - - def __repr__(self): - return pformat(self.traffic_profile) - - def __str__(self): - return pformat(self.traffic_profile) - - def _validate_traffic_profile(self): - """Validate the traffic profile. - - The specification, the structure and the rules are described in - doc/wrk_lld.rst - """ - - logger.debug( - f"\nValidating the wrk traffic profile '{self.profile_name}'...\n" - ) - if not (self._validate_mandatory_structure() - and self._validate_mandatory_values() - and self._validate_optional_values() - and self._validate_dependencies()): - self.traffic_profile = None - - def _validate_mandatory_structure(self): - """Validate presence of mandatory parameters in trafic profile dict - - :returns: whether mandatory structure is followed by the profile - :rtype: bool - """ - # Level 1: Check if the profile is a dictionary: - if not isinstance(self.traffic_profile, dict): - logger.error(u"The wrk traffic profile must be a dictionary.") - return False - - # Level 2: Check if all mandatory parameters are present: - is_valid = True - for param in self.MANDATORY_PARAMS: - if self.traffic_profile.get(param, None) is None: - logger.error(f"The parameter '{param}' in mandatory.") - is_valid = False - return is_valid - - def _validate_mandatory_values(self): - """Validate that mandatory profile values satisfy their constraints - - :returns: whether mandatory values are acceptable - :rtype: bool - """ - # Level 3: Mandatory params: Check if urls is a list: - is_valid = True - if not isinstance(self.traffic_profile[u"urls"], list): - logger.error(u"The parameter 'urls' must be a list.") - is_valid = False - - # Level 3: Mandatory params: Check if integers are not below minimum - for param, minimum in self.INTEGER_PARAMS: - if not self._validate_int_param(param, minimum): - is_valid = False - return is_valid - - def _validate_optional_values(self): - """Validate values for optional parameters, if present - - :returns: whether present optional values are acceptable - :rtype: bool - """ - is_valid = True - # Level 4: Optional params: Check if script is present: - script = self.traffic_profile.get(u"script", None) - if script is not None: - if not isinstance(script, str): - logger.error(u"The path to LuaJIT script in invalid") - is_valid = False - else: - if not isfile(script): - logger.error(f"The file '{script}' does not exist.") - is_valid = False - else: - self.traffic_profile[u"script"] = None - logger.debug( - u"The optional parameter 'LuaJIT script' is not defined. " - u"No problem." - ) - - # Level 4: Optional params: Check if header is present: - header = self.traffic_profile.get(u"header", None) - if header is not None: - if isinstance(header, dict): - header = u", ".join( - f"{0}: {1}".format(*item) for item in header.items() - ) - self.traffic_profile[u"header"] = header - elif not isinstance(header, str): - logger.error(u"The parameter 'header' type is not valid.") - is_valid = False - - if not header: - logger.error(u"The parameter 'header' is defined but empty.") - is_valid = False - else: - self.traffic_profile[u"header"] = None - logger.debug( - u"The optional parameter 'header' is not defined. No problem." - ) - - # Level 4: Optional params: Check if latency is present: - latency = self.traffic_profile.get(u"latency", None) - if latency is not None: - if not isinstance(latency, bool): - logger.error(u"The parameter 'latency' must be boolean.") - is_valid = False - else: - self.traffic_profile[u"latency"] = False - logger.debug( - u"The optional parameter 'latency' is not defined. No problem." - ) - - # Level 4: Optional params: Check if timeout is present: - if u"timeout" in self.traffic_profile: - if not self._validate_int_param(u"timeout", 1): - is_valid = False - else: - self.traffic_profile[u"timeout"] = None - logger.debug( - u"The optional parameter 'timeout' is not defined. No problem." - ) - - return is_valid - - def _validate_dependencies(self): - """Validate dependencies between parameters - - :returns: whether dependencies between parameters are acceptable - :rtype: bool - """ - # Level 5: Check urls and cpus: - if self.traffic_profile[u"cpus"] % len(self.traffic_profile[u"urls"]): - logger.error( - u"The number of CPUs must be a multiple of the number of URLs." - ) - return False - return True - - def _validate_int_param(self, param, minimum): - """Validate that an int parameter is set acceptably - If it is not an int already but a string, convert and store it as int. - - :param param: Name of a traffic profile parameter - :param minimum: The minimum value for the named parameter - :type param: str - :type minimum: int - :returns: whether param is set to an int of at least minimum value - :rtype: bool - """ - value = self._traffic_profile[param] - if isinstance(value, str): - if value.isdigit(): - value = int(value) - else: - value = minimum - 1 - if isinstance(value, int) and value >= minimum: - self.traffic_profile[param] = value - return True - logger.error( - f"The parameter '{param}' must be an integer and at least {minimum}" - ) - return False - - @property - def profile_name(self): - """Getter - Profile name. - - :returns: The traffic profile file path - :rtype: str - """ - return self._profile_name - - @profile_name.setter - def profile_name(self, profile_name): - """ - - :param profile_name: - :type profile_name: str - """ - self._profile_name = profile_name - - @property - def traffic_profile(self): - """Getter: Traffic profile. - - :returns: The traffic profile. - :rtype: dict - """ - return self._traffic_profile - - @traffic_profile.setter - def traffic_profile(self, profile): - """Setter - Traffic profile. - - :param profile: The new traffic profile. - :type profile: dict - """ - self._traffic_profile = profile diff --git a/resources/tools/wrk/wrk_utils.sh b/resources/tools/wrk/wrk_utils.sh deleted file mode 100755 index 16af61416b..0000000000 --- a/resources/tools/wrk/wrk_utils.sh +++ /dev/null @@ -1,246 +0,0 @@ -#!/bin/bash -# Copyright (c) 2019 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. - -set -x - -function wrk_utils.installed { - - # Check if the WRK utility is installed. Fail if not installed. - - # Returns: - # - 0 - If command is installed. - # - 1 - If command is not installed. - - set -exuo pipefail - - command -v wrk -} - - -function wrk_utils.traffic_1_url_1_core { - # Send traffic - # - to n URL (NIC) - # - using n instances of wrk, each on separate core. - - # The CPU used for wrk - cpu=${1} - # Total number of threads to use by one instance of wrk to send traffic. - threads=${2} - # Total number of HTTP connections to keep open with each thread handling - # N = connections / threads. - connections=${3} - # Duration of the test. - duration=${4} - # HTTP header to add to request. - header=${5} - # Record a timeout if a response is not received within this amount of time. - timeout=${6} - # Path to LuaJIT script. - script=${7} - # Print detailed latency statistics. - latency=${8} - # URL to send the traffic to. - url=${9} - - if [ "${timeout}" != "None" ]; then - timeout="--timeout ${timeout}" - else - timeout="" - fi - - if [ "${latency}" = "True" ]; then - latency="--latency" - else - latency="" - fi - - if [ "${script}" != "None" ]; then - script="--script '${script}'" - else - script="" - fi - - if [ "${header}" != "None" ]; then - header="${header}" - else - header="''" - fi - - taskset --cpu-list ${cpu} \ - wrk --threads ${threads} \ - --connections ${connections} \ - --duration ${duration} \ - --header "${header}" \ - ${timeout} \ - ${script} \ - ${latency} \ - ${url} -} - -function wrk_utils.traffic_n_urls_n_cores { - # Send traffic - # - to n URL (NIC) - # - using n instances of wrk, each on separate core. - - # The first CPU used for wrk - first_cpu=${1} - # Total number of threads to use by one instance of wrk to send traffic. - threads=${2} - # Total number of HTTP connections to keep open with each thread handling - # N = connections / threads. - connections=${3} - # Duration of the test. - duration=${4} - # HTTP header to add to request. - header=${5} - # Record a timeout if a response is not received within this amount of time. - timeout=${6} - # Path to LuaJIT script. - script=${7} - # Print detailed latency statistics. - latency=${8} - # URL to send the traffic to. - urls=${9} - - if [ "${timeout}" != "None" ]; then - timeout="--timeout ${timeout}" - else - timeout="" - fi - - if [ "${latency}" = "True" ]; then - latency="--latency" - else - latency="" - fi - - if [ "${script}" != "None" ]; then - script="--script '${script}'" - else - script="" - fi - - if [ "${header}" != "None" ]; then - header="${header}" - else - header="''" - fi - - urls=$(echo ${urls} | tr ";" "\n") - cpu=${first_cpu} - for url in ${urls}; do - taskset --cpu-list ${cpu} \ - wrk --threads ${threads} \ - --connections ${connections} \ - --duration ${duration} \ - --header "${header}" \ - ${timeout} \ - ${script} \ - ${latency} \ - ${url} & - cpu=$((cpu+1)) - done - - sleep ${duration} - sleep 2 -} - -function wrk_utils.traffic_n_urls_m_cores { - # Send traffic - # - to n URL (NIC) - # - using m instances of wrk, each on separate core. - - # The first CPU used for wrk - first_cpu=${1} - # The last CPU used for wrk - cpus_per_url=${2} - # Total number of threads to use by one instance of wrk to send traffic. - threads=${3} - # Total number of HTTP connections to keep open with each thread handling - # N = connections / threads. - connections=${4} - # Duration of the test. - duration=${5} - # HTTP header to add to request. - header=${6} - # Record a timeout if a response is not received within this amount of time. - timeout=${7} - # Path to LuaJIT script. - script=${8} - # Print detailed latency statistics. - latency=${9} - # URL to send the traffic to. - urls=${10} - - if [ "${timeout}" != "None" ]; then - timeout="--timeout ${timeout}" - else - timeout="" - fi - - if [ "${latency}" = "True" ]; then - latency="--latency" - else - latency="" - fi - - if [ "${script}" != "None" ]; then - script="--script '${script}'" - else - script="" - fi - - if [ "${header}" != "None" ]; then - header="${header}" - else - header="''" - fi - - urls=$(echo ${urls} | tr ";" "\n") - - cpu=${first_cpu} - for i in `seq 1 ${cpus_per_url}`; do - for url in ${urls}; do - taskset --cpu-list ${cpu} \ - wrk --threads ${threads} \ - --connections ${connections} \ - --duration ${duration} \ - --header "${header}" \ - ${timeout} \ - ${script} \ - ${latency} \ - ${url} & - cpu=$((cpu+1)) - done - done - - sleep ${duration} - sleep 2 -} - -args=("$@") -case ${1} in - installed) - wrk_utils.installed - ;; - traffic_1_url_1_core) - wrk_utils.traffic_1_url_1_core "${args[@]:1}" - ;; - traffic_n_urls_n_cores) - wrk_utils.traffic_n_urls_n_cores "${args[@]:1}" - ;; - traffic_n_urls_m_cores) - wrk_utils.traffic_n_urls_m_cores "${args[@]:1}" - ;; -esac diff --git a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-1u1c50con-bw.yaml b/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-1u1c50con-bw.yaml deleted file mode 100644 index 93ce51d6d0..0000000000 --- a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-1u1c50con-bw.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# This is an example wrk traffic profile. - -# List of urls for requests. Each url is requested in a separate instance of -# wrk. -# Type: list -urls: - # There must be a big file (10MB) requested but vpp does not support it. - - "http://192.168.10.2" - -# Index of the first CPU on the numa used to run wrk. -# Type: integer -first-cpu: 1 - -# The number of cpus used for wrk. The number of cpus must be a -# multiplication of the number of urls. -# Type: integer -cpus: 1 - -# Duration of the test in seconds. -# Type: integer -duration: 30 - -# Total number of threads to use. -# Type: integer -nr-of-threads: 1 - -# Total number of HTTP connections to keep open with each thread handling -# N = connections/threads. -# Type: integer -nr-of-connections: 50 - -# Path to LuaJIT script. -# Type: string -# script: "" - -# HTTP header to add to request, e.g. "Connection: close". -# Type: string (taken as it is) or dictionary -# header: -# Connection: "close" - -# Print detailed latency statistics. -# Type: boolean -latency: False - -# Record a timeout if a response is not received within this amount of time. -# Type: integer -timeout: 5 diff --git a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-cps.yaml b/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-cps.yaml deleted file mode 100644 index 2d059e7b6e..0000000000 --- a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-cps.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# wrk-sf-2n-ethip4tcphttp-8u8c50con-cps traffic profile. - -# List of urls for requests. Each url is requested in a separate instance of -# wrk. -# Type: list -urls: - - "http://192.168.10.2/empty.html" - - "http://192.168.20.2/empty.html" - - "http://192.168.30.2/empty.html" - - "http://192.168.40.2/empty.html" - - "http://192.168.50.2/empty.html" - - "http://192.168.60.2/empty.html" - - "http://192.168.70.2/empty.html" - - "http://192.168.80.2/empty.html" - -# Index of the first CPU on the numa used to run wrk. -# Type: integer -first-cpu: 1 - -# The number of cpus used for wrk. The number of cpus must be a -# multiplication of the number of urls. -# Type: integer -cpus: 8 - -# Duration of the test in seconds. -# Type: integer -duration: 30 - -# Total number of threads to use. -# Type: integer -nr-of-threads: 1 - -# Total number of HTTP connections to keep open with each thread handling -# N = connections/threads. -# Type: integer -nr-of-connections: 50 - -# Path to LuaJIT script. -# Type: string -# script: "" - -# HTTP header to add to request, e.g. "Connection: close". -# Type: string (taken as it is) or dictionary -header: - Connection: "close" - -# Print detailed latency statistics. -# Type: boolean -latency: False - -# Record a timeout if a response is not received within this amount of time. -# Type: integer -timeout: 5 diff --git a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-rps.yaml b/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-rps.yaml deleted file mode 100644 index d997e16ed2..0000000000 --- a/resources/traffic_profiles/wrk/wrk-sf-2n-ethip4tcphttp-8u8c50con-rps.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# wrk-sf-2n-ethip4tcphttp-8u8c50con-rps traffic profile. - -# List of urls for requests. Each url is requested in a separate instance of -# wrk. -# Type: list -urls: - - "http://192.168.10.2/empty.html" - - "http://192.168.20.2/empty.html" - - "http://192.168.30.2/empty.html" - - "http://192.168.40.2/empty.html" - - "http://192.168.50.2/empty.html" - - "http://192.168.60.2/empty.html" - - "http://192.168.70.2/empty.html" - - "http://192.168.80.2/empty.html" - -# Index of the first CPU on the numa used to run wrk. -# Type: integer -first-cpu: 1 - -# The number of cpus used for wrk. The number of cpus must be a -# multiplication of the number of urls. -# Type: integer -cpus: 8 - -# Duration of the test in seconds. -# Type: integer -duration: 30 - -# Total number of threads to use. -# Type: integer -nr-of-threads: 1 - -# Total number of HTTP connections to keep open with each thread handling -# N = connections/threads. -# Type: integer -nr-of-connections: 50 - -# Path to LuaJIT script. -# Type: string -# script: "" - -# HTTP header to add to request, e.g. "Connection: close". -# Type: string (taken as it is) or dictionary -# header: -# Connection: "close" - -# Print detailed latency statistics. -# Type: boolean -latency: False - -# Record a timeout if a response is not received within this amount of time. -# Type: integer -timeout: 5 diff --git a/resources/traffic_profiles/wrk/www/empty.html b/resources/traffic_profiles/wrk/www/empty.html deleted file mode 100644 index e69de29bb2..0000000000 -- 2.16.6