# Copyright 2017-2018 Intel Corporation., Tieto # # 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. # This file introduces a set of regression tests, which verify several DPDK features # used internally by Open vSwitch. Tests can be used for verification of performance # and correct functionality of upcoming DPDK and OVS releases and release candidates. ############################################################ # # Generic configuration used by OVSDPDK testcases # ############################################################ # required to import path to the log file from conf import settings _OVSDPDK_1st_PMD_CORE = 4 _OVSDPDK_2nd_PMD_CORE = 5 # calculate PMD mask from core IDs configured above _OVSDPDK_PMD_MASK_1_CORE = str(hex(1<<_OVSDPDK_1st_PMD_CORE))[2:] _OVSDPDK_PMD_MASK_2_CORE = str(hex((1<<_OVSDPDK_1st_PMD_CORE) + (1<<_OVSDPDK_2nd_PMD_CORE))[2:]) _OVSDPDK_GUEST_5_CORES = [('7', '8', '9', '10', '11')] # number of queues configured in OVS and GUEST _OVSDPDK_MQ = '2' # path to the log file _RESULTS_PATH = settings.getValue('RESULTS_PATH') name, ext = os.path.splitext(settings.getValue('LOG_FILE_VSWITCHD')) log_file = "{name}_{uid}{ex}".format(name=name,uid=settings.getValue('LOG_TIMESTAMP'),ex=ext) _OVSDPDK_VSWITCH_LOG = os.path.join(_RESULTS_PATH, log_file) _OVSDPDK_HEADER_LEN = 18 # length of frame headers in bytes, it's used for calculation # of payload size, i.e. payload = frame_size - header_len _OVSDPDK_PKT_SIZES = (64,128,256,512,1024,1500) INTEGRATION_TESTS = INTEGRATION_TESTS + [ ############################################################ # # DPDK NIC Support # ############################################################ { "Name": "ovsdpdk_nic_p2p_single_pmd_unidir_cont", "Deployment": "p2p", "Description": "P2P with single PMD in OVS and unidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_1_CORE, }, }, { "Name": "ovsdpdk_nic_p2p_single_pmd_bidir_cont", "Deployment": "p2p", "Description": "P2P with single PMD in OVS and bidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_1_CORE, }, }, { "Name": "ovsdpdk_nic_p2p_two_pmd_bidir_cont", "Deployment": "p2p", "Description": "P2P with two PMDs in OVS and bidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, }, }, { "Name": "ovsdpdk_nic_p2p_single_pmd_unidir_tput", "Deployment": "p2p", "Description": "P2P with single PMD in OVS and unidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_throughput", 'bidir' : 'False', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_1_CORE, }, }, { "Name": "ovsdpdk_nic_p2p_single_pmd_bidir_tput", "Deployment": "p2p", "Description": "P2P with single PMD in OVS and bidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_throughput", 'bidir' : 'True', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_1_CORE, }, }, { "Name": "ovsdpdk_nic_p2p_two_pmd_bidir_tput", "Deployment": "p2p", "Description": "P2P with two PMDs in OVS and bidirectional traffic.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_throughput", 'bidir' : 'True', }, "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, }, }, ############################################################ # # DPDK Hotplug Support # ############################################################ { "Name": "ovsdpdk_hotplug_attach", "Deployment": "clean", "Description": "Ensure successful port-add after binding a device to igb_uio after ovs-vswitchd is launched.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { # suppress DPDK configuration, so physical interfaces are not bound to DPDK driver 'WHITELIST_NICS' : [], 'NICS' : [], }, "TestSteps": [ # restore original NICS configuration, so we can use add/del_phy_port ['settings', 'setValue', 'TEST_PARAMS', ''], # add DPDK port, but it should fail ['vswitch', 'add_switch', 'int_br0'], ['#port', 'vswitch', 'add_phy_port', 'int_br0'], # check, that DPDK port is not available and remove it ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|Error attaching device.*$NICS[0]["pci"]'], # NOTE: it fails in case that NIC was already bound to DPDK driver ['tools', 'assert', 'len(#STEP[-1])'], ['vswitch', 'del_port', 'int_br0', '#STEP[port][0]'], # find out which DPDK driver is being used; it should be the last configured # DPDK module; optional path and .ko suffix must be removed ['tools', 'eval', '\'$TOOLS["dpdk_modules"][-1]\'.split("/")[-1].split(".")[0]'], # bind NIC to DPDK driver ['tools', 'exec_shell', 'sudo $TOOLS["bind-tool"] --bind #STEP[-1] $NICS[0]["pci"]'], # and check that DPDK port can be created without errors ['#port2', 'vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|Error attaching device.*$NICS[0]["pci"]'], ['tools', 'assert', 'not len(#STEP[-1])'], ] }, { # Support of netdev-dpdk/detach has been removed from OVS, so testcase will fail with recent # OVS/DPDK versions. There is an ongoing discussion about possible support of netdev-dpdk/detach # in the future OVS versions. # Test has been tested with: # OVS_TAG = 03d6399e618e4136c5da0be2b6f18f0b7d75b2bb # DPDK_TAG = v16.11 "Name": "ovsdpdk_hotplug_detach", "Deployment": "clean", "Description": "Same as ovsdpdk_hotplug_attach, but delete and detach the device after the hotplug. " "Note: Support of netdev-dpdk/detach has been removed from OVS, so testcase will fail " "with recent OVS/DPDK versions.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { # suppress DPDK configuration, so physical interfaces are not bound to DPDK driver 'WHITELIST_NICS' : [], 'NICS' : [], }, "TestSteps": [ # check if OVS supports netdev-dpdk/detach, fail otherwise ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] list-commands', '|netdev-dpdk\/detach'], ['tools', 'assert', 'len(#STEP[-1])'], # restore original NICS configuration, so we can use add/del_phy_port ['settings', 'setValue', 'TEST_PARAMS', ''], # find out which DPDK driver is being used; it should be the last configured # DPDK module; optional path and .ko suffix must be removed ['tools', 'eval', '\'$TOOLS["dpdk_modules"][-1]\'.split("/")[-1].split(".")[0]'], # bind NIC to DPDK driver ['tools', 'exec_shell', 'sudo $TOOLS["bind-tool"] --bind #STEP[-1] $NICS[0]["pci"]'], # and check that DPDK port can be created without errors ['vswitch', 'add_switch', 'int_br0'], ['#port', 'vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|Error attaching device.*$NICS[0]["pci"]'], ['tools', 'assert', 'not len(#STEP[-1])'], # try to unbind port - should fail beause it is being used ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] netdev-dpdk/detach $NICS[0]["pci"] 2>&1; exit 0', '|Device.*$NICS[0]["pci"].*is being used by interface'], ['tools', 'assert', 'len(#STEP[-1])'], # delete port and unbind it - should succeed ['vswitch', 'del_port', 'int_br0', '#STEP[port][0]'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] netdev-dpdk/detach $NICS[0]["pci"]', '|Device.*$NICS[0]["pci"].*has been detached'], ['tools', 'assert', 'len(#STEP[-1])'], # try to add port again ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|Error attaching device.*$NICS[0]["pci"]'], # it will work because auto attach was implemented into OVS ['tools', 'assert', 'not len(#STEP[-1])'], ['vswitch', 'del_switch', 'int_br0'], ] }, ] ############################################################ # # RX Checksum Support # ############################################################ # TCL script used for simulation of traffic with wrong CRC _OVSDPDK_CRC_CRC_TCL = '' _OVSDPDK_CRC_FRAME_LOSS = '' _OVSDPDK_CRC_VERIFY_CRC = [ # use TCL script with tunneling protocols encap/decap support; # it must be configured dynamically, otherwise it won't # be possible to change it again below. ['settings', 'setValue', 'TRAFFICGEN_IXNET_TCL_SCRIPT', 'ixnetrfc2544v2.tcl'], # send traffic before IP or UDP header checksum is randomized ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # packets should flow through OVS without frameloss (frame_rate is low) ['tools', 'assert', 'float(#STEP[-1][0]["frame_loss_percent"]) == 0'], # for 2nd run use TCL file with randomized checksum values ['settings', 'setValue', 'TRAFFICGEN_IXNET_TCL_SCRIPT', '$_OVSDPDK_CRC_CRC_TCL'], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # and verify that majority of frames but not all of them were lost ['tools', 'assert', 'round(float(#STEP[-1][0]["frame_loss_percent"]),3) == $_OVSDPDK_CRC_FRAME_LOSS'], ] INTEGRATION_TESTS = INTEGRATION_TESTS + [ { "Name": "ovsdpdk_checksum_l3", "Deployment": "op2p", "Description": "Test verifies RX IP header checksum (offloading) validation for tunneling protocols.", "Tunnel Type": "vxlan", "Tunnel Operation": "decapsulation", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 20, 'bidir' : 'False', }, "TRAFFICGEN_DURATION" : 10, "TRAFFICGEN_PKT_SIZES" : (64,) }, "TestSteps": [ # TCL file with randomized IP header checksum values ['settings', 'setValue', '_OVSDPDK_CRC_CRC_TCL', 'ixnetrfc2544v2_random_ip_crc.tcl'], # IP checksum is a value between 0 and 65536, so only 1 of 65536 # frames has correct CRC and all other frames will be dropped ['settings', 'setValue', '_OVSDPDK_CRC_FRAME_LOSS', round(100 - 1 / 65536 * 100, 3)], ] + _OVSDPDK_CRC_VERIFY_CRC }, { "Name": "ovsdpdk_checksum_l4", "Deployment": "op2p", "Description": "Test verifies RX UDP header checksum (offloading) validation for tunneling protocols.", "Tunnel Type": "vxlan", "Tunnel Operation": "decapsulation", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 20, 'bidir' : 'False', }, "TRAFFICGEN_DURATION" : 10, "TRAFFICGEN_PKT_SIZES" : (64,) }, "TestSteps": [ # TCL file with randomized UDP header checksum values ['settings', 'setValue', '_OVSDPDK_CRC_CRC_TCL', 'ixnetrfc2544v2_random_udp_crc.tcl'], # UDP checksum can be disabled by value 0; so valid checksum # values are from 1 to 65535; It means that only one of 65535 frames # has correct checksum and all other frames will be dropped ['settings', 'setValue', '_OVSDPDK_CRC_FRAME_LOSS', round(100 - 1 / 65535 * 100, 3)], ] + _OVSDPDK_CRC_VERIFY_CRC }, ############################################################ # # Flow Control Support # ############################################################ { "Name": "ovsdpdk_flow_ctrl_rx", "Deployment": "p2p", "Description": "Test the rx flow control functionality of DPDK PHY ports.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, "flow_control" : True, 'bidir' : 'True', }, "TRAFFICGEN_DURATION" : 10, "TRAFFICGEN_PKT_SIZES" : (64,) }, "TestSteps": [ # send traffic before flow control is applied ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show'], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # frame loss with small packets should be detected ['tools', 'assert', '#STEP[-1][0]["frame_loss_percent"] > 10'], # delete phy ports so they can be created with flow control ['vswitch', 'del_flow', '$VSWITCH_BRIDGE_NAME', {}], ['vswitch', 'del_port', '$VSWITCH_BRIDGE_NAME', 'dpdk0'], ['vswitch', 'del_port', '$VSWITCH_BRIDGE_NAME', 'dpdk1'], # turn on flow control ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] add-port $VSWITCH_BRIDGE_NAME dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-devargs=$NICS[0]["pci"] options:rx-flow-ctrl=true'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] add-port $VSWITCH_BRIDGE_NAME dpdk1 -- set Interface dpdk1 type=dpdk options:dpdk-devargs=$NICS[1]["pci"] options:rx-flow-ctrl=true'], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '3', 'actions': ['output:4'], 'idle_timeout': '0'}], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '4', 'actions': ['output:3'], 'idle_timeout': '0'}], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show'], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # frame loss with flow control enabled should converge to 0% ['tools', 'assert', 'float(#STEP[-1][0]["frame_loss_percent"]) == 0'], ] }, { "Name": "ovsdpdk_flow_ctrl_rx_dynamic", "Deployment": "p2p", "Description": "Change the rx flow control support at run time and ensure the system honored the changes.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, "flow_control" : True, 'bidir' : 'True', }, "TRAFFICGEN_DURATION" : 10, "TRAFFICGEN_PKT_SIZES" : (64,) }, "TestSteps": [ # send traffic before flow control is applied ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show'], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # frame loss with small packets should be detected ['tools', 'assert', '#STEP[-1][0]["frame_loss_percent"] > 10'], # turn on flow control ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 type=dpdk options:rx-flow-ctrl=true'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk1 type=dpdk options:rx-flow-ctrl=true'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show'], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # frame loss with flow control enabled should converge to 0% ['tools', 'assert', 'float(#STEP[-1][0]["frame_loss_percent"]) == 0'], ] }, ############################################################ # # Multiqueue Support # ############################################################ { "Name": "ovsdpdk_mq_p2p_rxqs", "Deployment": "p2p", "Description": "Setup rxqs on NIC port.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "TRAFFICGEN_DURATION" : 1, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, }, "TestSteps": [ ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpif-netdev/pmd-rxq-show','|dpdk[01]\s+queue-id:\s+\d+'], # check that requested nr of queues was created on both NICs ['tools', 'assert', 'len(#STEP[-1])=={}'.format(int(_OVSDPDK_MQ)*2)], ] }, { "Name": "ovsdpdk_mq_p2p_rxqs_same_core_affinity", "Deployment": "p2p", "Description": "Affinitize rxqs to the same core.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "TRAFFICGEN_DURATION" : 1, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, }, "TestSteps": [ ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] -- set Interface dpdk0 other_config:pmd-rxq-affinity="0:{},1:{}"'.format(_OVSDPDK_1st_PMD_CORE, _OVSDPDK_1st_PMD_CORE)], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpif-netdev/pmd-rxq-show','|dpdk0\s+queue-id:\s+0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpif-netdev/pmd-rxq-show','|dpdk0\s+queue-id:\s+1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ] }, { "Name": "ovsdpdk_mq_p2p_rxqs_multi_core_affinity", "Deployment": "p2p", "Description": "Affinitize rxqs to separate cores.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "TRAFFICGEN_DURATION" : 1, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, }, "TestSteps": [ ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] -- set Interface dpdk0 other_config:pmd-rxq-affinity="0:{},1:{}"'.format(_OVSDPDK_1st_PMD_CORE, _OVSDPDK_2nd_PMD_CORE)], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpif-netdev/pmd-rxq-show','|dpdk0\s+queue-id:\s+0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpif-netdev/pmd-rxq-show','|dpdk0\s+queue-id:\s+1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ] }, { "Name" : "ovsdpdk_mq_pvp_rxqs", "Deployment" : "clean", "Description" : "Setup rxqs on vhost user port.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_1_CORE, "GUEST_NIC_QUEUES" : [_OVSDPDK_MQ], "GUEST_LOOPBACK" : ['clean'], }, "TestSteps": STEP_VSWITCH_PVP_INIT + [ ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] dpif-netdev/pmd-rxq-show", '|dpdkvhostuserclient0\s+queue-id:\s+\d'], ['tools', 'assert', 'len(#STEP[-1])==1'], ['vnf', 'start'], ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] dpif-netdev/pmd-rxq-show", '|dpdkvhostuserclient0\s+queue-id:\s+0'], ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] dpif-netdev/pmd-rxq-show", '|dpdkvhostuserclient0\s+queue-id:\s+1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ['tools', 'assert', 'len(#STEP[-2])==1'], ['vnf', 'stop'], ] + STEP_VSWITCH_PVP_FINIT }, { "Name" : "ovsdpdk_mq_pvp_rxqs_linux_bridge", "Deployment" : "clean", "Description" : "Confirm traffic received over vhost RXQs with Linux virtio device in guest.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { # configure 2 queues at both OVS and QEMU "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, "GUEST_NIC_QUEUES" : [_OVSDPDK_MQ], "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, "GUEST_LOOPBACK" : ['clean'], "TRAFFICGEN_DURATION" : 5, "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "bidir" : "false", "traffic_type" : "rfc2544_continuous", "multistream" : 6, "stream_type" : "L3", "frame_rate" : 1, 'l2': { 'srcmac': "00:00:07:00:0E:00", 'dstmac': "00:00:00:00:00:01" }, 'l3': { 'enabled': True, 'proto': 'udp', 'srcip': '6.6.6.6', 'dstip': '1.1.1.1', }, } }, "TestSteps": STEP_VSWITCH_PVP_INIT + [ # one flow will sent data to the VM ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}], # second flow just forwards traffic to the traffic generator, # so send_traffic() will end with success ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[2][1]', 'actions': ['output:#STEP[1][1]'], 'idle_timeout': '0'}], ['vnf', 'start'], # configure two channels, so multiple cores could be used ['vnf', 'execute_and_wait', 'ethtool -L eth0 combined 2'], ['vnf', 'execute_and_wait', 'ethtool -l eth0', '|Combined:\s+2'], ['tools', 'assert', 'len(#STEP[-1])==2'], # traffic will be sent to several DST IPs so it can be # dispatched between channels; We have to insert routes # and ARPs, otherwise traffic will be dropped ['vnf', 'execute_and_wait', 'ifconfig eth0 5.5.5.1/24 up'], ['vnf', 'execute_and_wait', 'sysctl -w net.ipv4.ip_forward=1'], ['vnf', 'execute_and_wait', 'sysctl -w net.ipv4.conf.all.rp_filter=0'], ['vnf', 'execute_and_wait', 'ip route add 6.6.6.0/24 dev eth0'], ['vnf', 'execute_and_wait', 'route add default gw 6.6.6.6 eth0'], ['vnf', 'execute_and_wait', 'arp -s 6.6.6.6 00:00:07:00:0E:00'], ['vnf', 'execute_and_wait', 'ip route add 1.1.1.0/31 dev eth0'], ['vnf', 'execute_and_wait', 'route add default gw 1.1.1.1 eth0'], ['vnf', 'execute_and_wait', 'arp -s 1.1.1.1 DE:AD:BE:EF:CA:FA'], ['vnf', 'execute_and_wait', 'ip route add 1.1.1.2/31 dev eth0'], ['vnf', 'execute_and_wait', 'route add default gw 1.1.1.3 eth0'], ['vnf', 'execute_and_wait', 'arp -s 1.1.1.3 DE:AD:BE:EF:CA:FB'], ['vnf', 'execute_and_wait', 'ip route add 1.1.1.4/31 dev eth0'], ['vnf', 'execute_and_wait', 'route add default gw 1.1.1.5 eth0'], ['vnf', 'execute_and_wait', 'arp -s 1.1.1.5 DE:AD:BE:EF:CA:FC'], ['vnf', 'execute_and_wait', 'ip a'], ['trafficgen', 'send_traffic',{}], # check interrupts to verify that traffic was corectly dispatched... ['#result', 'vnf', 'execute_and_wait', 'cat /proc/interrupts', '|^\s*\d+:\s+(\d+)\s+(\d+).+virtio0-input'], # ...it means that two channels were created... ['tools', 'assert', 'len(#STEP[result])==2'], # ...and both channels processed data; Check that interrupt count is "much" # higher than 0 to eliminate impact of rogue interrupts. ['tools', 'assert', 'int(#STEP[result][0][0]) + int(#STEP[result][0][1]) > 1000'], ['tools', 'assert', 'int(#STEP[result][1][0]) + int(#STEP[result][1][1]) > 1000'], ['vnf', 'stop'], ] }, { "Name" : "ovsdpdk_mq_pvp_rxqs_testpmd", "Deployment" : "clean", "Description" : "Confirm traffic received over vhost RXQs with DPDK device in guest.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "TRAFFICGEN" : "IxNet", # configure 2 queues at both OVS and QEMU "VSWITCH_DPDK_MULTI_QUEUES" : _OVSDPDK_MQ, "GUEST_NIC_QUEUES" : [_OVSDPDK_MQ], "VSWITCH_PMD_CPU_MASK" : _OVSDPDK_PMD_MASK_2_CORE, "GUEST_CORE_BINDING" : _OVSDPDK_GUEST_5_CORES, "GUEST_LOOPBACK" : ['testpmd'], # there must be separate CPU for each of RX/TX queues "GUEST_SMP" : ['5'], "GUEST_TESTPMD_PARAMS" : ['-c 0x1F -n 4 --socket-mem 512 -- ' '--burst=64 -i --nb-cores=4 ' # map queue stats to separate regs to verify MQ functionality '--rx-queue-stats-mapping=\(0,0,0\),\(0,1,1\),\(1,0,2\),\(1,1,3\) ' '--tx-queue-stats-mapping=\(0,0,4\),\(0,1,5\),\(1,0,6\),\(1,1,7\) ' '--rxq=2 --txq=2'], "TRAFFICGEN_DURATION" : 5, "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "multistream" : 3, "stream_type" : "L3", 'l3': { 'enabled': True, 'proto': 'udp', 'srcip': '6.6.6.6', 'dstip': '1.1.1.1', }, }, }, "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT + [ ['vnf', 'start'], ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] dpif-netdev/pmd-rxq-show", '|dpdk\w+\s+queue-id:\s+\d'], # there must be two standalone queue records for every interface (2x4) ['tools', 'assert', 'len(#STEP[-1])==8'], ['trafficgen', 'send_traffic', {}], # check that packets were received by both queues at both ports ['vnf', 'execute_and_wait', 'show port stats 0', 60, 'testpmd>', '|Stats reg [01] RX-packets:\s+(\d+)'], ['tools', 'assert', '"0" not in #STEP[-1]'], # rx queue of 2nd port should be mapped to reg 2 and 3, but mapping might not work # so let us check that exactly two RX regs have non zero values ['vnf', 'execute_and_wait', 'show port stats 1', 60, 'testpmd>', '|Stats reg\s+\d+ RX-packets:\s+\d\d+'], ['tools', 'assert', 'len(#STEP[-1])==2'], # clean up ['vnf', 'stop'], ] }, ############################################################ # # Vhost User # ############################################################ { "Name": "ovsdpdk_vhostuser_client", "Deployment": "pvp", "Description": "Test vhost-user client mode", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "TRAFFICGEN_DURATION" : 1, }, "TestSteps": [ # check that client ports are really used ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|type.*dpdkvhostuserclient'], ['tools', 'assert', 'len(#STEP[-1])==2'], # send traffic manually, so TC will fail in case # that packets won't make it through ['trafficgen', 'send_traffic', {}], ], }, { "Name": "ovsdpdk_vhostuser_client_reconnect", "Deployment": "pvp", "Description": "Test vhost-user client mode reconnect feature", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "TRAFFICGEN_DURATION" : 1, }, "TestSteps": [ # send traffic to verify correct PVP configuration ['trafficgen', 'send_traffic', {}], ['vswitch', 'dump_flows', '$VSWITCH_BRIDGE_NAME'], # restart vswitchd, ovsdb is kept untouched, so ovs configuration # (except flows) will be restored ['vswitch', 'restart'], ['vswitch', 'del_flow', '$VSWITCH_BRIDGE_NAME', {}], ['vswitch', 'dump_flows', '$VSWITCH_BRIDGE_NAME'], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '1', 'actions': ['output:3'], 'idle_timeout': '0'}], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '3', 'actions': ['output:1'], 'idle_timeout': '0'}], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '2', 'actions': ['output:4'], 'idle_timeout': '0'}], ['vswitch', 'add_flow', '$VSWITCH_BRIDGE_NAME', {'in_port': '4', 'actions': ['output:2'], 'idle_timeout': '0'}], ['vswitch', 'dump_flows', '$VSWITCH_BRIDGE_NAME'], # send traffic to verify that OVS works correctly after restart ['trafficgen', 'send_traffic', {}], ], }, { "Name": "ovsdpdk_vhostuser_server", "Deployment": "pvp", "Description": "Test vhost-user server mode", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'True', }, "VSWITCH_VHOSTUSER_SERVER_MODE" : True, "TRAFFICGEN_DURATION" : 1, }, "TestSteps": [ # check that server ports are really used ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|type.*dpdkvhostuser$'], ['tools', 'assert', 'len(#STEP[-1])==2'], # send traffic manually, so TC will fail in case # that packets won't make it through ['trafficgen', 'send_traffic', {}], ], }, { "Name": "ovsdpdk_vhostuser_sock_dir", "Deployment": "clean", "Description": "Verify functionality of vhost-sock-dir flag", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : True, }, "TestSteps": [ ['vswitch', 'add_switch', '$VSWITCH_BRIDGE_NAME'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Open_vSwitch . ' 'other_config:vhost-sock-dir=test_dir'], # enforce vswitchd to read new configuration ['vswitch', 'restart'], ['tools', 'exec_shell', 'sudo mkdir $TOOLS["ovs_var_tmp"]/test_dir'], ['vswitch', 'add_vport', '$VSWITCH_BRIDGE_NAME'], ['tools', 'exec_shell', 'ls -1 $TOOLS["ovs_var_tmp"]/test_dir', '|dpdkvhostuser0'], ['tools', 'assert', 'len(#STEP[-1])'], ], }, ] ############################################################ # # Virtual Devices Support # ############################################################ _OVSDPDK_VDEV_ADD_NULL = [ ['vswitch', 'add_switch', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] add-port int_br0 null0 -- ' 'set Interface null0 type=dpdk options:dpdk-devargs=eth_null0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|dpdk-devargs=\S+eth_null0'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] _OVSDPDK_VDEV_ADD_AF_PACKET = [ # resore original NICS configuration, so we can use NICS dictionary ['settings', 'setValue', 'TEST_PARAMS', ''], # check if vsperf was able to read device name ['tools', 'assert', 'str(\"$NICS[0]["device"]\") != \"None\"'], ['tools', 'exec_shell', 'sudo ip link set dev $NICS[0]["device"] up'], ['vswitch', 'add_switch', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] add-port int_br0 myeth0 -- ' 'set Interface myeth0 type=dpdk options:dpdk-devargs=eth_af_packet0,iface=$NICS[0]["device"]'], # check if device was created... ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|dpdk-devargs=\S+eth_af_packet0'], ['tools', 'assert', 'len(#STEP[-1])==1'], # ...without errors ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|Error attaching device'], ['tools', 'assert', 'not len(#STEP[-1])'], ] INTEGRATION_TESTS = INTEGRATION_TESTS + [ { "Name": "ovsdpdk_vdev_add_null_pmd", "Deployment": "clean", "Description": "Test addition of port using the null DPDK PMD driver.", "vSwitch" : "OvsDpdkVhost", "TestSteps": _OVSDPDK_VDEV_ADD_NULL }, { "Name": "ovsdpdk_vdev_del_null_pmd", "Deployment": "clean", "Description": "Test deletion of port using the null DPDK PMD driver.", "vSwitch" : "OvsDpdkVhost", "TestSteps": _OVSDPDK_VDEV_ADD_NULL + [ ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] del-port null0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|dpdk-devargs=\S+eth_null0'], ['tools', 'assert', 'not len(#STEP[-1])'], ] }, { "Name": "ovsdpdk_vdev_add_af_packet_pmd", "Deployment": "clean", "Description": "Test addition of port using the af_packet DPDK PMD driver.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { # suppress DPDK configuration, so physical interfaces are not bound to DPDK driver 'WHITELIST_NICS' : [], 'NICS' : [], }, "TestSteps": _OVSDPDK_VDEV_ADD_AF_PACKET }, { "Name": "ovsdpdk_vdev_del_af_packet_pmd", "Deployment": "clean", "Description": "Test deletion of port using the af_packet DPDK PMD driver.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { # suppress DPDK configuration, so physical interfaces are not bound to DPDK driver 'WHITELIST_NICS' : [], 'NICS' : [], }, "TestSteps": _OVSDPDK_VDEV_ADD_AF_PACKET + [ ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] del-port myeth0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] show', '|dpdk-devargs=\S+eth_af_packet0'], ['tools', 'assert', 'not len(#STEP[-1])'], ] }, ############################################################ # # NUMA Support # ############################################################ { "Name": "ovsdpdk_numa", "Deployment": "clean", "Description": "Test vhost-user NUMA support. Vhostuser PMD threads should migrate " "to the same numa slot, where QEMU is executed.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { # ensure that memory and cpus are available at both numa slots "DPDK_SOCKET_MEM" : ['1024', '1024'], "VSWITCH_PMD_CPU_MASK" : 'FFFFFE', "VSWITCH_VHOSTUSER_SERVER_MODE" : False, # traffic won't be send, so speed up VNF deployment "GUEST_LOOPBACK" : ['clean'] }, "TestSteps": STEP_VSWITCH_PVP_INIT + [ # check that at least 2 numa slots are available ['tools', 'exec_shell', 'numactl -H', '|available: ([0-9]+)'], ['tools', 'assert', '#STEP[-1][0]>1'], # check that PMD thread serving dpdkvhostuserclient0 runs at NUMA slot 0 ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] " "dpif-netdev/pmd-rxq-show | " "sed -e '/dpdkvhostuserclient0/,$d' | tac", '|pmd thread numa_id ([0-9])+' ], ['tools', 'assert', '#STEP[-1][0]==0'], # store last 2 cores from 2nd numa slot ['tools', 'exec_shell', 'numactl -H', '|node 1 cpus:.*\s+(\\d+) (\\d+)$'], # pin VNF to 2nd NUMA slot ['settings', 'setValue', 'GUEST_CORE_BINDING', [("#STEP[-1][0][0]", "#STEP[-1][0][1]")] ], ['vnf', 'start'], # ...and check that PMD thread serving dpdkvhostuserclient0 # has migrated to NUMA slot 1 ['tools', 'exec_shell', "sudo $TOOLS['ovs-appctl'] " "dpif-netdev/pmd-rxq-show | " "sed -e '/dpdkvhostuserclient0/,$d' | tac", '|pmd thread numa_id ([0-9])+' ], ['tools', 'assert', '#STEP[-1][0]==1'], ['vnf', 'stop'], ] + STEP_VSWITCH_PVP_FINIT }, ############################################################ # # Jumbo Frame Support # ############################################################ { "Name": "ovsdpdk_jumbo_increase_mtu_phy_port_ovsdb", "Deployment": "clean", "Description": "Ensure that the increased MTU for a DPDK physical port is updated in OVSDB.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==1500'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ] }, { "Name": "ovsdpdk_jumbo_increase_mtu_vport_ovsdb", "Deployment": "clean", "Description": "Ensure that the increased MTU for a DPDK vhost-user port is updated in OVSDB.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==1500'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ] }, { "Name": "ovsdpdk_jumbo_reduce_mtu_phy_port_ovsdb", "Deployment": "clean", "Description": "Ensure that the reduced MTU for a DPDK physical port is updated in OVSDB.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=2000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==2000'], ] }, { "Name": "ovsdpdk_jumbo_reduce_mtu_vport_ovsdb", "Deployment": "clean", "Description": "Ensure that the reduced MTU for a DPDK vhost-user port is updated in OVSDB.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=2000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==2000'], ] }, { "Name": "ovsdpdk_jumbo_increase_mtu_phy_port_datapath", "Deployment": "clean", "Description": "Ensure that the MTU for a DPDK physical port is updated in the datapath itself when increased to a valid value.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=1500'], ['tools', 'assert', 'len(#STEP[-1])==1'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=9000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_jumbo_increase_mtu_vport_datapath", "Deployment": "clean", "Description": "Ensure that the MTU for a DPDK vhost-user port is updated in the datapath itself when increased to a valid value.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=1500'], ['tools', 'assert', 'len(#STEP[-1])==1'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=9000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_jumbo_reduce_mtu_phy_port_datapath", "Deployment": "clean", "Description": "Ensure that the MTU for a DPDK physical port is updated in the datapath itself when decreased to a valid value.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=9000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=2000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=2000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_jumbo_reduce_mtu_vport_datapath", "Deployment": "clean", "Description": "Ensure that the MTU for a DPDK vhost-user port is updated in the datapath itself when decreased to a valid value.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=9000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=2000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] dpctl/show', '|mtu=2000'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_jumbo_mtu_upper_bound_phy_port", "Deployment": "clean", "Description": "Verify that the upper bound limit is enforced for OvS DPDK Phy ports.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=9702'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9702'], # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=9711'], # check vswitchd log file, that new MTU request was denied ['tools', 'exec_shell', "sed -n '#STEP[-2][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|unsupported MTU 9711'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9702'], ] }, { "Name": "ovsdpdk_jumbo_mtu_upper_bound_vport", "Deployment": "clean", "Description": "Verify that the upper bound limit is enforced for OvS DPDK vhost-user ports.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=9702'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9702'], # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=9711'], # check vswitchd log file, that new MTU request was denied ['tools', 'exec_shell', "sed -n '#STEP[-2][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|unsupported MTU 9711'], ['tools', 'assert', 'len(#STEP[-1])'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9702'], ] }, { "Name": "ovsdpdk_jumbo_mtu_lower_bound_phy_port", "Deployment": "clean", "Description": "Verify that the lower bound limit is enforced for OvS DPDK Phy ports.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=68'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==68'], # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdk0 mtu_request=67'], # check vswitchd log file, that new MTU request was denied ['tools', 'exec_shell', "sed -n '#STEP[-2][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|unsupported MTU 67'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==68'], ] }, { "Name": "ovsdpdk_jumbo_mtu_lower_bound_vport", "Deployment": "clean", "Description": "Verify that the lower bound limit is enforced for OvS DPDK vhost-user ports.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=68'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==68'], # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set Interface dpdkvhostuserclient0 mtu_request=67'], # check vswitchd log file, that new MTU request was denied ['tools', 'exec_shell', "sed -n '#STEP[-2][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|unsupported MTU 67'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==68'], ] }, { "Name": "ovsdpdk_jumbo_p2p", "Deployment": "p2p", "Description": "Ensure that jumbo frames are received, processed and forwarded correctly by DPDK physical ports.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', 'learning_frames' : False, }, "TRAFFICGEN_PKT_SIZES" : (9018,), "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ # verify jumbo frame configuration ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk1 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['trafficgen', 'send_traffic', {}], # check that jumbo frames were received by traffic generator ['trafficgen', 'get_results'], # i.e. (RX in Bytes/s) divide (RX frames/s) ~ 9018 Bytes ['tools', 'assert', 'round(float(#STEP[-1][0]["throughput_rx_mbps"])*1000000/8 / ' 'float(#STEP[-1][0]["throughput_rx_fps"]))==9018'], ] }, { "Name": "ovsdpdk_jumbo_pvp", "Deployment": "clean", "Description": "Ensure that jumbo frames are received, processed and forwarded correctly by DPDK vhost-user ports.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', 'learning_frames' : False, }, "TRAFFICGEN_PKT_SIZES" : (9018,), "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "GUEST_LOOPBACK" : ['linux_bridge'], "GUEST_NIC_MERGE_BUFFERS_DISABLE" : [False], }, "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT + [ # verify jumbo frame configuration ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk1 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdkvhostuserclient1 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], # VNF startup, MTU configuration ['vnf', 'start'], ['vnf', 'execute_and_wait', 'ifconfig eth0 mtu 9000'], ['vnf', 'execute_and_wait', 'ifconfig eth1 mtu 9000'], ['trafficgen', 'send_traffic', {}], # check that jumbo frames were received by traffic generator ['trafficgen', 'get_results'], # i.e. (RX in Bytes/s) divide (RX frames/s) ~ 9018 Bytes ['tools', 'assert', 'round(float(#STEP[-1][0]["throughput_rx_mbps"])*1000000/8 / ' 'float(#STEP[-1][0]["throughput_rx_fps"]))==9018'], ['vnf', 'stop'], ] + STEP_VSWITCH_PVP_FLOWS_FINIT }, { "Name": "ovsdpdk_jumbo_p2p_upper_bound", "Deployment": "p2p", "Description": "Ensure that jumbo frames above the configured Rx port's MTU are not accepted", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 10, 'bidir' : 'False', 'learning_frames' : False, }, "VSWITCH_JUMBO_FRAMES_ENABLED" : 'True', "VSWITCH_JUMBO_FRAMES_SIZE" : 9000, }, "TestSteps": [ # set and verify jumbo frame support ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk0 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] get Interface dpdk1 mtu'], ['tools', 'assert', 'int(#STEP[-1])==9000'], # set packetsize to 9018 and send traffic ['settings', 'setValue', 'TRAFFICGEN_PKT_SIZES', (9018,)], ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # all traffic should pass through (i.e. 0% frame loss) ['tools', 'assert', 'float(#STEP[-1][0]["frame_loss_percent"])==0'], # set packetsize to 9702 and send traffic ['settings', 'setValue', 'TRAFFICGEN_PKT_SIZES', (9702,)], # disable verification of send_traffic "!" prefix, otherwise vsperf # will fail when 100% packet loss is detected ['!trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # all traffic should be dropped ['tools', 'assert', 'float(#STEP[-1][0]["frame_loss_percent"])==100'], ] }, ] ############################################################ # # Rate Limiting # ############################################################ # default settings of limiter used in macros and tests _OVSDPDK_RATE_PORT = 'dpdk' _OVSDPDK_RATE_NICID = '0' _OVSDPDK_RATE_RATE = '10000' # desired maximum rate of PAYLOAD carried by frames _OVSDPDK_RATE_BURST = '8000' _OVSDPDK_RATE_LIMITER_CREATED = 'True' # set to False to verify that limiter was not created _OVSDPDK_RATE_DEVIATION = '5' # acceptable deviation from configured frame rate in % # Formula used for validation of rate settings. # Note: OVS parameter "ingress_policing_rate" configures maximum rate of payload in Kbps, # but traffic generator measures throughput in Mbps based on whole frames including headers. # Thus measured RX throughput value reported by traffic generator must be deducted by bit # rate consumed by frame header transmission. _OVSDPDK_RATE_CHECK = ('abs(1-float(#STEP[{}][{}]["throughput_rx_mbps"])*1000*' '(1-$_OVSDPDK_HEADER_LEN/float(#STEP[{}][{}]["packet_size"]))' '/float($_OVSDPDK_RATE_RATE))*100 < $_OVSDPDK_RATE_DEVIATION') # macro will setup rate limiter at interface defined by _DPDK_RATE_PORT and # _DPDK_RATE_NICID; It will verify, that limiter was created by parsing # vswitchd log file. It will also check that proper limiter values are # set for given interface. _OVSDPDK_RATE_set_rate_limiter = [ # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] ' 'set Interface $_OVSDPDK_RATE_PORT$_OVSDPDK_RATE_NICID ' 'ingress_policing_burst=$_OVSDPDK_RATE_BURST ' 'ingress_policing_rate=$_OVSDPDK_RATE_RATE'], # check vswitchd log file, that rate limiter was created ['tools', 'exec_shell', "sed -n '#STEP[-2][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|CIR period'], ['tools', 'assert', '("CIR period" in #STEP[-1])==$_OVSDPDK_RATE_LIMITER_CREATED'], # verify that interface has correct rate limiter configuration ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] ' 'list interface $_OVSDPDK_RATE_PORT$_OVSDPDK_RATE_NICID', '(ingress_policing_\w+: \d+)'], ['tools', 'assert', '"ingress_policing_burst: $_OVSDPDK_RATE_BURST" in #STEP[-1]'], ['tools', 'assert', '"ingress_policing_rate: $_OVSDPDK_RATE_RATE" in #STEP[-2]'], ] _OVSDPDK_RATE_set_rate_limiter_NIC0 = [ ['settings', 'setValue', '_OVSDPDK_RATE_NICID', '0'] ] + _OVSDPDK_RATE_set_rate_limiter _OVSDPDK_RATE_set_rate_limiter_NIC1 = [ ['settings', 'setValue', '_OVSDPDK_RATE_NICID', '1'] ] + _OVSDPDK_RATE_set_rate_limiter # macro will set different limiter values and sends traffic to verify proper # limiter functionality _OVSDPDK_RATE_confirm_multiple_rate_limit_setup = \ _OVSDPDK_RATE_set_rate_limiter_NIC0 + _OVSDPDK_RATE_set_rate_limiter_NIC1 + [ # by default rate limit is 10Mbits/s ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # check result and accept preconfigured deviation to the configured frame rate ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("-1", "0", "-1", "0")], # set rate limit to 20Mbits/s ['settings', 'setValue', '_OVSDPDK_RATE_RATE', '20000'] ] + _OVSDPDK_RATE_set_rate_limiter_NIC0 + _OVSDPDK_RATE_set_rate_limiter_NIC1 + [ ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # check result and accept preconfigured deviation to the configured frame rate ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("-1", "0", "-1", "0")], # set rate limit to 30Mbits/s ['settings', 'setValue', '_OVSDPDK_RATE_RATE', '30000'] ] + _OVSDPDK_RATE_set_rate_limiter_NIC0 + _OVSDPDK_RATE_set_rate_limiter_NIC1 + [ ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], # check result and accept preconfigured deviation to the configured frame rate ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("-1", "0", "-1", "0")], # disable rate limiter and verify unlimited speed ['settings', 'setValue', '_OVSDPDK_RATE_RATE', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_BURST', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_LIMITER_CREATED', 'False'], ] + _OVSDPDK_RATE_set_rate_limiter_NIC0 + _OVSDPDK_RATE_set_rate_limiter_NIC1 + [ ['trafficgen', 'send_traffic', {}], # check that traffic rate is no longer limited ['trafficgen', 'get_results'], ['tools', 'assert', 'int(#STEP[-1][0]["throughput_rx_mbps"])>500'], ['vswitch', 'dump_flows', '$VSWITCH_BRIDGE_NAME'], ] INTEGRATION_TESTS = INTEGRATION_TESTS + [ { "Name": "ovsdpdk_rate_create_phy_port", "Deployment": "clean", "Description": "Ensure a rate limiting interface can be created on a physical DPDK port.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_delete_phy_port", "Deployment": "clean", "Description": "Ensure a rate limiting interface can be destroyed on a physical DPDK port.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter + [ ['settings', 'setValue', '_OVSDPDK_RATE_RATE', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_BURST', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_LIMITER_CREATED', 'False'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_create_vport", "Deployment": "clean", "Description": "Ensure a rate limiting interface can be created on a vhost-user port.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_RATE_PORT" : 'dpdkvhostuserclient', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_delete_vport", "Deployment": "clean", "Description": "Ensure a rate limiting interface can be destroyed on a vhost-user port.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_RATE_PORT" : 'dpdkvhostuserclient', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter + [ ['settings', 'setValue', '_OVSDPDK_RATE_RATE', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_BURST', '0'], ['settings', 'setValue', '_OVSDPDK_RATE_LIMITER_CREATED', 'False'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_no_policing", "Deployment": "clean", "Description": "Ensure when a user attempts to create a rate limiting interface but is missing policing rate argument, no rate limitiner is created.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_RATE_PORT" : 'dpdkvhostuserclient', "_OVSDPDK_RATE_RATE" : '0', "_OVSDPDK_RATE_BURST" : '1000', "_OVSDPDK_RATE_LIMITER_CREATED" : 'False', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_no_burst", "Deployment": "clean", "Description": "Ensure when a user attempts to create a rate limiting interface but is missing policing burst argument, rate limitiner is created.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_RATE_PORT" : 'dpdkvhostuserclient', "_OVSDPDK_RATE_RATE" : '10000', "_OVSDPDK_RATE_BURST" : '0', "_OVSDPDK_RATE_LIMITER_CREATED" : 'True', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_RATE_set_rate_limiter }, { "Name": "ovsdpdk_rate_p2p", "Deployment": "p2p", "Description": "Ensure when a user creates a rate limiting physical interface that the traffic is limited to the specified policer rate in a p2p setup.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "_OVSDPDK_RATE_PORT" : 'dpdk', "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, }, "TestSteps": _OVSDPDK_RATE_confirm_multiple_rate_limit_setup }, { "Name": "ovsdpdk_rate_pvp", "Deployment": "pvp", "Description": "Ensure when a user creates a rate limiting vHost User interface that the traffic is limited to the specified policer rate in a pvp setup.", "vSwitch" : "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_RATE_PORT" : 'dpdkvhostuserclient', "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, }, "TestSteps": _OVSDPDK_RATE_confirm_multiple_rate_limit_setup }, { "Name": "ovsdpdk_rate_p2p_multi_pkt_sizes", "Deployment": "p2p", "Description": "Ensure that rate limiting works for various frame sizes.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "_OVSDPDK_RATE_PORT" : 'dpdk', "_OVSDPDK_RATE_RATE" : '10000', "TRAFFICGEN_PKT_SIZES" : _OVSDPDK_PKT_SIZES, "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, }, "TestSteps": _OVSDPDK_RATE_set_rate_limiter_NIC0 + _OVSDPDK_RATE_set_rate_limiter_NIC1 + [ # dump rate limiter configuration of both NICs ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] ' 'list interface dpdk0'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] ' 'list interface dpdk1'], ['trafficgen', 'send_traffic', {}], ['#result', 'trafficgen', 'get_results'], # check results and accept preconfigured deviation to the configured frame rates ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("result","0", "result","0")], ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("result","1", "result","1")], ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("result","2", "result","2")], ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("result","3", "result","3")], ['tools', 'assert', _OVSDPDK_RATE_CHECK.format("result","4", "result","4")], ], }, ] ############################################################ # # Quality of Service # ############################################################ # default settings of limiter used in macros and tests _OVSDPDK_QOS_PORT = 'dpdk' _OVSDPDK_QOS_NICID = '0' _OVSDPDK_QOS_CIR = '1250000' # desired maximum rate of PAYLOAD carried by frames in BYTEs _OVSDPDK_QOS_CBS = '2048' _OVSDPDK_QOS_DEVIATION = '5' # acceptable deviation from configured frame rate in % # Formula used for validation of rate settings. # Note: OVS parameter "ingress_policing_rate" configures maximum rate of payload in Kbps, # but traffic generator measures throughput in Mbps based on whole frames including headers. # Thus measured RX throughput value reported by traffic generator must be deducted by bit # rate consumed by frame header transmission. _OVSDPDK_QOS_CHECK = ('abs(1-float(#STEP[{}][{}]["throughput_rx_mbps"])*1000000*' '(1-$_OVSDPDK_HEADER_LEN/float(#STEP[{}][{}]["packet_size"]))' '/float($_OVSDPDK_QOS_CIR*8))*100 < $_OVSDPDK_QOS_DEVIATION') # macro will setup QoS at interface defined by _OVSDPDK_QOS_PORT and # _OVSDPDK_QOS_NICID; It will verify, that QoS was created by parsing # vswitchd log file. It will also check that proper QoS values are # set for given interface. _OVSDPDK_QOS_set_qos = [ # get line number of next log file entry ['tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], # Crete QoS policy and check the returned policy ID ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] ' 'set port $_OVSDPDK_QOS_PORT$_OVSDPDK_QOS_NICID qos=@newqos -- ' '--id=@newqos create qos type=egress-policer other-config:cir=$_OVSDPDK_QOS_CIR ' 'other-config:cbs=$_OVSDPDK_QOS_CBS','|\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'], ['tools', 'assert', 'len(#STEP[-1])==1'], # Check the OVS logs ['tools', 'exec_shell', "sed -n '#STEP[-3][0],$ p' $_OVSDPDK_VSWITCH_LOG", '|CIR period'], ['tools', 'assert', '"CIR period" in #STEP[-1]'], # Check the QoS policy and attributes ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] -t ovs-vswitchd qos/show ' '$_OVSDPDK_QOS_PORT$_OVSDPDK_QOS_NICID', '.+'], ['tools', 'assert', "'QoS: $_OVSDPDK_QOS_PORT$_OVSDPDK_QOS_NICID egress-policer' in #STEP[-1]"], ['tools', 'assert', "'cbs: $_OVSDPDK_QOS_CBS' in #STEP[-2]"], ['tools', 'assert', "'cir: $_OVSDPDK_QOS_CIR' in #STEP[-3]"], ] _OVSDPDK_QOS_set_qos_NIC0 = [ ['settings', 'setValue', '_OVSDPDK_QOS_NICID', '0'] ] + _OVSDPDK_QOS_set_qos _OVSDPDK_QOS_set_qos_NIC1 = [ ['settings', 'setValue', '_OVSDPDK_QOS_NICID', '1'] ] + _OVSDPDK_QOS_set_qos # macro will set different limiter values and sends traffic to verify proper # QoS functionality _OVSDPDK_QOS_confirm_multiple_qos_setup = [ # Create QoS policy with payload rate of 23*10^6 Bytes/s ['settings', 'setValue', '_OVSDPDK_QOS_CIR', '23000000'] ] + _OVSDPDK_QOS_set_qos_NIC0 + _OVSDPDK_QOS_set_qos_NIC1 + [ ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], ['tools', 'assert', _OVSDPDK_QOS_CHECK.format("-1", "0", "-1", "0")], # Create QoS policy with payload rate of 46*10^6 Bytes/s ['settings', 'setValue', '_OVSDPDK_QOS_CIR', '46000000'] ] + _OVSDPDK_QOS_set_qos_NIC0 + _OVSDPDK_QOS_set_qos_NIC1 + [ ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], ['tools', 'assert', _OVSDPDK_QOS_CHECK.format("-1", "0", "-1", "0")], # Create QoS policy with payload rate of 92*10^6 Bytes/s ['settings', 'setValue', '_OVSDPDK_QOS_CIR', '92000000'] ] + _OVSDPDK_QOS_set_qos_NIC0 + _OVSDPDK_QOS_set_qos_NIC1 + [ ['trafficgen', 'send_traffic', {}], ['trafficgen', 'get_results'], ['tools', 'assert', _OVSDPDK_QOS_CHECK.format("-1", "0", "-1", "0")], ] INTEGRATION_TESTS = INTEGRATION_TESTS + [ { "Name": "ovsdpdk_qos_create_phy_port", "Deployment": "clean", "Description": "Ensure a QoS policy can be created on a physical DPDK port", "vSwitch": "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ] + _OVSDPDK_QOS_set_qos }, { "Name": "ovsdpdk_qos_delete_phy_port", "Deployment": "clean", "Description": "Ensure an existing QoS policy can be destroyed on a physical DPDK port.", "vSwitch": "OvsDpdkVhost", "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_phy_port', 'int_br0'], ] + _OVSDPDK_QOS_set_qos + [ # Destroy the QoS policy and check the attributes ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] -- destroy QoS #STEP[1][0] -- clear Port #STEP[1][0] qos'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] -t ovs-vswitchd qos/show #STEP[1][0]', 'QoS not configured on #STEP[1][0]'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_qos_create_vport", "Deployment": "clean", "Description": "Ensure a QoS policy can be created on a virtual vhost user port.", "vSwitch": "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_QOS_PORT" : 'dpdkvhostuserclient', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_QOS_set_qos }, { "Name": "ovsdpdk_qos_delete_vport", "Deployment": "clean", "Description": "Ensure an existing QoS policy can be destroyed on a vhost user port.", "vSwitch": "OvsDpdkVhost", "Parameters" : { "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "_OVSDPDK_QOS_PORT" : 'dpdkvhostuserclient', }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], ['vswitch', 'add_vport', 'int_br0'], ] + _OVSDPDK_QOS_set_qos + [ # Destroy the QoS policy and check the attributes ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] -- destroy QoS #STEP[1][0] -- clear Port #STEP[1][0] qos'], ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] -t ovs-vswitchd qos/show #STEP[1][0]', 'QoS not configured on #STEP[1][0]'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_qos_create_no_cir", "Deployment": "clean", "Description": "Ensure that a QoS policy cannot be created if the egress policer cir argument is missing.", "vSwitch": "OvsDpdkVhost", "Parameters" : {}, "TestSteps": [ # Setup switch,port and logs ['vswitch', 'add_switch', '$VSWITCH_BRIDGE_NAME'], ['vswitch', 'add_vport', '$VSWITCH_BRIDGE_NAME'], ['#LOG_MARK', 'tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], # Crete QoS policy and check the returned policy ID ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set port #STEP[1][0] qos=@newqos -- ' '--id=@newqos create qos type=egress-policer other-config:cbs=2048', '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'], ['tools', 'assert', 'len(#STEP[-1])==1'], # Check the OVS logs ['tools', 'exec_shell', "sed -n '#STEP[LOG_MARK][0],$ p' $_OVSDPDK_VSWITCH_LOG", 'Failed to set QoS type egress-policer on port #STEP[1][0]: No such file or directory'], ['tools', 'assert', 'len(#STEP[-1])==1'], # Check the attributes for vhost0 ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] -t ovs-vswitchd qos/show #STEP[1][0]', 'QoS not configured on #STEP[1][0]'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_qos_create_no_cbs", "Deployment": "clean", "Description": "Ensure that a QoS policy cannot be created if the egress policer cbs argument is missing.", "vSwitch": "OvsDpdkVhost", "Parameters" : {}, "TestSteps": [ # Setup switch,port and logs ['vswitch', 'add_switch', '$VSWITCH_BRIDGE_NAME'], ['vswitch', 'add_vport', '$VSWITCH_BRIDGE_NAME'], ['#LOG_MARK', 'tools', 'exec_shell', 'echo $((1+`wc -l $_OVSDPDK_VSWITCH_LOG | cut -d" " -f1`))', '(\d+)'], # Crete QoS policy and check the returned policy ID ['tools', 'exec_shell', 'sudo $TOOLS["ovs-vsctl"] set port #STEP[1][0] qos=@newqos -- ' '--id=@newqos create qos type=egress-policer other-config:cir=1250000', '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'], ['tools', 'assert', 'len(#STEP[-1])==1'], # Check the OVS logs ['tools', 'exec_shell', "sed -n '#STEP[LOG_MARK][0],$ p' $_OVSDPDK_VSWITCH_LOG", 'Failed to set QoS type egress-policer on port #STEP[1][0]: No such file or directory'], ['tools', 'assert', 'len(#STEP[-1])==1'], # Check the attributes for vhost0 ['tools', 'exec_shell', 'sudo $TOOLS["ovs-appctl"] -t ovs-vswitchd qos/show #STEP[1][0]', 'QoS not configured on #STEP[1][0]'], ['tools', 'assert', 'len(#STEP[-1])==1'], ] }, { "Name": "ovsdpdk_qos_p2p", "Deployment": "p2p", "Description": "In a p2p setup, ensure when a QoS egress policer is created that the traffic is limited to the specified rate.", "vSwitch": "OvsDpdkVhost", "Parameters" : { "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, }, "TestSteps": _OVSDPDK_QOS_confirm_multiple_qos_setup }, { "Name": "ovsdpdk_qos_pvp", "Deployment": "pvp", "Description": "In a pvp setup, ensure when a QoS egress policer is created that the traffic is limited to the specified rate.", "vSwitch": "OvsDpdkVhost", "VNF" : "QemuDpdkVhostUser", "Parameters" : { "_OVSDPDK_QOS_PORT" : 'dpdkvhostuserclient', "VSWITCH_VHOSTUSER_SERVER_MODE" : False, "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 100, 'bidir' : 'False', }, }, "TestSteps": _OVSDPDK_QOS_confirm_multiple_qos_setup }, ############################################################ # # Custom statistics # ############################################################ { "Name": "ovsdpdk_custstat_check", "Deployment": "clean", "Description": "Test if custom statistics are supported.", "vSwitch" : "OvsDpdkVhost", "TestSteps": [ # enable custom statistics ['vswitch', 'add_switch', 'int_br0', [ 'protocols=OpenFlow10,OpenFlow11,OpenFlow12,' 'OpenFlow13,OpenFlow14,OpenFlow15']], ['#port', 'vswitch', 'add_phy_port', 'int_br0'], # check that custom statistics are available for given interface ['tools', 'exec_shell', 'sudo $TOOLS["ovs-ofctl"] -O OpenFlow14 ' 'dump-ports int_br0 #STEP[port][1]', '|CUSTOM Statistics'], ['tools', 'assert', 'len(#STEP[-1])'], ['vswitch', 'del_port', 'int_br0', '#STEP[port][0]'], ['vswitch', 'del_switch', 'int_br0'], ] }, { "Name": "ovsdpdk_custstat_rx_error", "Deployment": "clean", "Description": "Test bad ethernet CRC counter 'rx_crc_errors' exposed by custom statistics.", "vSwitch" : "OvsDpdkVhost", "Parameters" : { "OVS_OFCTL_ARGS" : [], "TRAFFICGEN" : "IxNet", "TRAFFIC" : { "traffic_type" : "rfc2544_continuous", "frame_rate" : 10, }, "TRAFFICGEN_DURATION" : 10, "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544_bad_l2_crc.tcl", }, "TestSteps": [ # enable custom statistics ['vswitch', 'add_switch', 'int_br0', [ 'protocols=OpenFlow10,OpenFlow11,OpenFlow12,' 'OpenFlow13,OpenFlow14,OpenFlow15']], ['#port1', 'vswitch', 'add_phy_port', 'int_br0'], ['#port2', 'vswitch', 'add_phy_port', 'int_br0'], ['vswitch', 'add_flow', 'int_br0', {'in_port': '1', 'actions': ['output:2']}], ['vswitch', 'add_flow', 'int_br0', {'in_port': '2', 'actions': ['output:1']}], ['#crc_old', 'tools', 'exec_shell', 'sudo $TOOLS["ovs-ofctl"] -O OpenFlow14 ' 'dump-ports int_br0 #STEP[port1][1]', '|rx_crc_errors=(\d+)'], # frames will be dropped by NIC, so we have to suppress send_traffic validation # to avoid test failure ['!trafficgen', 'send_traffic', {}], # check that custom statistics are available for given interface ['#crc_new', 'tools', 'exec_shell', 'sudo $TOOLS["ovs-ofctl"] -O OpenFlow14 ' 'dump-ports int_br0 #STEP[port1][1]', '|rx_crc_errors=(\d+)'], ['tools', 'assert', '#STEP[crc_new] > #STEP[crc_old]'], # tear down the environment ['vswitch', 'dump_flows', 'int_br0'], ['vswitch', 'del_flow', 'int_br0', {}], ['vswitch', 'del_port', 'int_br0', '#STEP[port1][0]'], ['vswitch', 'del_port', 'int_br0', '#STEP[port2][0]'], ['vswitch', 'del_switch', 'int_br0'], ] }, ]