diff options
author | Tibor Frank <tifrank@cisco.com> | 2017-12-04 16:41:57 +0100 |
---|---|---|
committer | Tibor Frank <tifrank@cisco.com> | 2018-01-10 15:35:01 +0100 |
commit | a95c54b7821596402e0aa7136cd7d1de71a5b187 (patch) | |
tree | f1c941b06bb05069af1b3f587b5bcfc8bc22ef3a /resources/libraries | |
parent | ec120d957cfec192d30e84a0d337198153214a70 (diff) |
CSIT-866: wrk onboarding in CSIT
- CSIT-867: Low Level Description
- CSIT-868: wrk traffic profile - parsing
- CSIT-869: wrk implementation into CSIT
Change-Id: I65e1037f5ae05b3a5b2020e4a6c54462766ae1b4
Signed-off-by: Tibor Frank <tifrank@cisco.com>
Diffstat (limited to 'resources/libraries')
-rw-r--r-- | resources/libraries/python/IPUtil.py | 52 | ||||
-rw-r--r-- | resources/libraries/python/TrafficGenerator.py | 18 | ||||
-rw-r--r-- | resources/libraries/python/VppConfigGenerator.py | 92 | ||||
-rw-r--r-- | resources/libraries/python/constants.py | 2 | ||||
-rw-r--r-- | resources/libraries/python/tcp.py | 36 | ||||
-rw-r--r-- | resources/libraries/python/topology.py | 4 | ||||
-rw-r--r-- | resources/libraries/robot/performance/performance_setup.robot | 54 | ||||
-rw-r--r-- | resources/libraries/robot/tcp/tcp_setup.robot | 43 | ||||
-rw-r--r-- | resources/libraries/robot/wrk/wrk_utils.robot | 78 |
9 files changed, 373 insertions, 6 deletions
diff --git a/resources/libraries/python/IPUtil.py b/resources/libraries/python/IPUtil.py index d2f2adcf28..e215b301b9 100644 --- a/resources/libraries/python/IPUtil.py +++ b/resources/libraries/python/IPUtil.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# 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: @@ -13,6 +13,8 @@ """Common IP utilities library.""" +import re + from ipaddress import IPv4Network, ip_address from resources.libraries.python.ssh import SSH @@ -138,6 +140,54 @@ class IPUtil(object): exec_cmd_no_error(node, cmd, sudo=True) @staticmethod + def get_linux_interface_name(node, pci_addr): + """Get the interface name. + + :param node: Node where to execute command. + :param pci_addr: PCI address + :type node: dict + :type pci_addr: str + :returns: Interface name + :rtype: str + :raises RuntimeError: If cannot get the information about interfaces. + """ + + regex_intf_info = r"pci@" \ + r"([0-9a-f]{4}:[0-9a-f]{2}:[0-9a-f]{2}.[0-9a-f])\s*" \ + r"([a-zA-Z0-9]*)\s*network" + + cmd = "lshw -class network -businfo" + ret_code, stdout, stderr = exec_cmd(node, cmd, timeout=30, sudo=True) + if ret_code != 0: + raise RuntimeError('Could not get information about interfaces, ' + 'reason:{0}'.format(stderr)) + + for line in stdout.splitlines()[2:]: + try: + if re.search(regex_intf_info, line).group(1) == pci_addr: + return re.search(regex_intf_info, line).group(2) + except AttributeError: + continue + return None + + @staticmethod + def set_linux_interface_up(node, interface): + """Set the specified interface up. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :type node: dict + :type interface: str + :raises RuntimeError: If the interface could not be set up. + """ + + cmd = "ip link set {0} up".format(interface) + ret_code, _, stderr = exec_cmd(node, cmd, timeout=30, sudo=True) + if ret_code != 0: + raise RuntimeError('Could not set the interface up, reason:{0}'. + format(stderr)) + + @staticmethod def set_linux_interface_ip(node, interface, ip_addr, prefix, namespace=None): """Set IP address to interface in linux. diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py index 698b67ead2..f363fe3f55 100644 --- a/resources/libraries/python/TrafficGenerator.py +++ b/resources/libraries/python/TrafficGenerator.py @@ -308,6 +308,24 @@ class TrafficGenerator(object): raise RuntimeError('t-rex-64 startup failed') @staticmethod + def is_trex_running(node): + """Check if TRex is running using pidof. + + :param node: Traffic generator node. + :type node: dict + :returns: True if TRex is running otherwise False. + :rtype: bool + :raises: RuntimeError if node type is not a TG. + """ + if node['type'] != NodeType.TG: + raise RuntimeError('Node type is not a TG') + + ssh = SSH() + ssh.connect(node) + ret, _, _ = ssh.exec_command_sudo("pidof t-rex") + return bool(int(ret) == 0) + + @staticmethod def teardown_traffic_generator(node): """TG teardown. diff --git a/resources/libraries/python/VppConfigGenerator.py b/resources/libraries/python/VppConfigGenerator.py index c1bde49742..d4fde0a6c8 100644 --- a/resources/libraries/python/VppConfigGenerator.py +++ b/resources/libraries/python/VppConfigGenerator.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# 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: @@ -382,6 +382,96 @@ class VppConfigGenerator(object): path = ['nat'] self.add_config_item(self._nodeconfig, value, path) + def add_tcp_preallocated_connections(self, value): + """Add TCP pre-allocated connections. + + :param value: The number of pre-allocated connections. + :type value: int + """ + path = ['tcp', 'preallocated-connections'] + self.add_config_item(self._nodeconfig, value, path) + + def add_tcp_preallocated_half_open_connections(self, value): + """Add TCP pre-allocated half open connections. + + :param value: The number of pre-allocated half open connections. + :type value: int + """ + path = ['tcp', 'preallocated-half-open-connections'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_event_queue_length(self, value): + """Add session event queue length. + + :param value: Session event queue length. + :type value: int + """ + path = ['session', 'event-queue-length'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_preallocated_sessions(self, value): + """Add the number of pre-allocated sessions. + + :param value: Number of pre-allocated sessions. + :type value: int + """ + path = ['session', 'preallocated-sessions'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_v4_session_table_buckets(self, value): + """Add number of v4 session table buckets to the config. + + :param value: Number of v4 session table buckets. + :type value: int + """ + path = ['session', 'v4-session-table-buckets'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_v4_session_table_memory(self, value): + """Add the size of v4 session table memory. + + :param value: Size of v4 session table memory. + :type value: str + """ + path = ['session', 'v4-session-table-memory'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_v4_halfopen_table_buckets(self, value): + """Add the number of v4 halfopen table buckets. + + :param value: Number of v4 halfopen table buckets. + :type value: int + """ + path = ['session', 'v4-halfopen-table-buckets'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_v4_halfopen_table_memory(self, value): + """Add the size of v4 halfopen table memory. + + :param value: Size of v4 halfopen table memory. + :type value: str + """ + path = ['session', 'v4-halfopen-table-memory'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_local_endpoints_table_buckets(self, value): + """Add the number of local endpoints table buckets. + + :param value: Number of local endpoints table buckets. + :type value: int + """ + path = ['session', 'local-endpoints-table-buckets'] + self.add_config_item(self._nodeconfig, value, path) + + def add_session_local_endpoints_table_memory(self, value): + """Add the size of local endpoints table memory. + + :param value: Size of local endpoints table memory. + :type value: str + """ + path = ['session', 'local-endpoints-table-memory'] + self.add_config_item(self._nodeconfig, value, path) + def apply_config(self, filename=None, waittime=5, retries=12, restart_vpp=True): """Generate and apply VPP configuration for node. diff --git a/resources/libraries/python/constants.py b/resources/libraries/python/constants.py index 30f7531947..c3f1551c55 100644 --- a/resources/libraries/python/constants.py +++ b/resources/libraries/python/constants.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# 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: diff --git a/resources/libraries/python/tcp.py b/resources/libraries/python/tcp.py new file mode 100644 index 0000000000..5ae1ebf929 --- /dev/null +++ b/resources/libraries/python/tcp.py @@ -0,0 +1,36 @@ +# 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. + +"""TCP util library. +""" + +from resources.libraries.python.VatExecutor import VatTerminal + + +class TCPUtils(object): + """Implementation of the TCP utilities. + """ + + def __init__(self): + pass + + @staticmethod + def start_http_server(node): + """Start HTTP server on the given node. + + :param node: Node to start HTTP server on. + :type node: dict + """ + + with VatTerminal(node) as vat: + vat.vat_terminal_exec_cmd_from_template("start_http_server.vat") diff --git a/resources/libraries/python/topology.py b/resources/libraries/python/topology.py index 94652dbd23..38e08d23d3 100644 --- a/resources/libraries/python/topology.py +++ b/resources/libraries/python/topology.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# 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: @@ -21,7 +21,7 @@ from robot.api import logger from robot.libraries.BuiltIn import BuiltIn, RobotNotRunningError from robot.api.deco import keyword -__all__ = ["DICT__nodes", 'Topology'] +__all__ = ["DICT__nodes", 'Topology', 'NodeType'] def load_topo_from_yaml(): diff --git a/resources/libraries/robot/performance/performance_setup.robot b/resources/libraries/robot/performance/performance_setup.robot index 0453fad275..0e909aa455 100644 --- a/resources/libraries/robot/performance/performance_setup.robot +++ b/resources/libraries/robot/performance/performance_setup.robot @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Cisco and/or its affiliates. +# 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: @@ -13,6 +13,7 @@ *** Settings *** | Library | resources.libraries.python.DUTSetup +| Library | resources.tools.wrk.wrk | Resource | resources/libraries/robot/performance/performance_configuration.robot | Resource | resources/libraries/robot/performance/performance_utils.robot | Documentation | Performance suite keywords - Suite and test setups and @@ -385,6 +386,45 @@ | | Configure VPP in all 'VNF' containers | | Install VPP in all 'VNF' containers +| Set up 3-node performance topology with wrk and DUT's NIC model +| | [Documentation] +| | ... | Suite preparation phase that setup default startup configuration of +| | ... | VPP on all DUTs. Updates interfaces on all nodes and setup global +| | ... | variables used in test cases based on interface model provided as an +| | ... | argument. Installs the traffic generator. +| | ... +| | ... | *Arguments:* +| | ... | - iface_model - Interface model. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Set up 3-node performance topology with wrk and DUT's NIC model\ +| | ... | \| Intel-X520-DA2 \| +| | ... +| | [Arguments] | ${iface_model} +| | ... +| | Set variables in 3-node circular topology with DUT interface model +| | ... | ${iface_model} +| | 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']} +| | Set Linux interface IP | ${tg} | ${intf_name} | 192.168.10.1 | 24 +| | Set Linux interface up | ${tg} | ${intf_name} +| | Install wrk | ${tg} + # Suite teardowns | Tear down 3-node performance topology @@ -480,6 +520,18 @@ | | Show VAT History On All DUTs | ${nodes} | | Show statistics on all DUTs | ${nodes} +| Tear down performance test with wrk +| | [Documentation] | Common test teardown for ndrdisc and pdrdisc performance \ +| | ... | tests. +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Tear down performance test with wrk \| +| | ... +| | Remove All Added Ports On All DUTs From Topology | ${nodes} +| | Show VAT History On All DUTs | ${nodes} +| | Show statistics on all DUTs | ${nodes} + | Tear down performance test with vhost and VM with dpdk-testpmd | | [Documentation] | Common test teardown for performance tests which use | | ... | vhost(s) and VM(s) with dpdk-testpmd. diff --git a/resources/libraries/robot/tcp/tcp_setup.robot b/resources/libraries/robot/tcp/tcp_setup.robot new file mode 100644 index 0000000000..09f6afd592 --- /dev/null +++ b/resources/libraries/robot/tcp/tcp_setup.robot @@ -0,0 +1,43 @@ +# 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. + +*** Settings *** +| Library | resources.libraries.python.IPv4Util.IPv4Util +| Library | resources.libraries.python.InterfaceUtil +| 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 on the VPP node +| | [Documentation] +| | ... | Configure IP address on the port, set it up and start HTTP server on +| | ... | the VPP. +| | ... +| | ... | *Arguments:* +| | ... | - ${dut1_if1_ip4} - IP address to be set on the dut1_if1 interface. +| | ... | Type: string +| | ... | - ${ip4_len} - Length of the netmask. Type: integer +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Set up HTTP server on the VPP node \| 192.168.10.2 \| 24 \| +| | ... +| | [Arguments] | ${dut1_if1_ip4} | ${ip4_len} +| | ... +| | Set Interface State | ${dut1} | ${dut1_if1} | up +| | Set Interface Address | ${dut1} | ${dut1_if1} | ${dut1_if1_ip4} | ${ip4_len} +| | Vpp Node Interfaces Ready Wait | ${dut1} +| | Start HTTP server | ${dut1} +| | Sleep | 30 diff --git a/resources/libraries/robot/wrk/wrk_utils.robot b/resources/libraries/robot/wrk/wrk_utils.robot new file mode 100644 index 0000000000..fd18a5d686 --- /dev/null +++ b/resources/libraries/robot/wrk/wrk_utils.robot @@ -0,0 +1,78 @@ +# 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. + +*** 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 +| Resource | resources/libraries/robot/performance/performance_setup.robot +| ... +| Documentation | L2 keywords to set up wrk and to measure performance +| ... | parameters using wrk. + +*** 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_if1} | ${tg_if2} +| | ${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_if1} | ${tg_if2} +| | ${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_if1} | ${tg_if2} +| | ${output}= | Run wrk | ${tg} | ${profile} | ${tg_numa} | cps +| | Set test message | ${output} |