From 080733bfa5facd0eb457fc3db1c3ee7885f2a438 Mon Sep 17 00:00:00 2001 From: Luc Provoost Date: Thu, 27 Jun 2019 12:52:11 +0200 Subject: Change of openstackrapid directory name The scripts are orrignally written to support an OpenStack deployment. We are now making changes to support container environments, hence renaming the directory to rapid. Change-Id: Icaa2fad83c6da451eee733934151e98e9cd07de4 Signed-off-by: Luc Provoost --- .../helper-scripts/openstackrapid/MachineMap.cfg | 30 - .../DPPD-PROX/helper-scripts/openstackrapid/README | 149 ---- .../helper-scripts/openstackrapid/basicrapid.test | 60 -- .../helper-scripts/openstackrapid/centos.json | 33 - .../openstackrapid/check-prox-system-setup.service | 11 - .../openstackrapid/check_prox_system_setup.sh | 51 -- .../helper-scripts/openstackrapid/createrapid.py | 418 ---------- .../helper-scripts/openstackrapid/deploycentos.sh | 139 --- .../helper-scripts/openstackrapid/devbind.sh | 27 - .../helper-scripts/openstackrapid/gen.cfg | 76 -- .../helper-scripts/openstackrapid/gen_gw.cfg | 74 -- .../helper-scripts/openstackrapid/impair.cfg | 50 -- .../helper-scripts/openstackrapid/impair.test | 54 -- .../helper-scripts/openstackrapid/irq.cfg | 42 - .../helper-scripts/openstackrapid/irq.test | 32 - .../helper-scripts/openstackrapid/l2framerate.test | 42 - .../helper-scripts/openstackrapid/l2gen.cfg | 70 -- .../helper-scripts/openstackrapid/l2swap.cfg | 46 - .../helper-scripts/openstackrapid/l2zeroloss.test | 56 -- .../helper-scripts/openstackrapid/l3framerate.test | 42 - .../helper-scripts/openstackrapid/prox_ctrl.py | 254 ------ .../helper-scripts/openstackrapid/rapidVMs.vms | 61 -- .../helper-scripts/openstackrapid/runrapid.py | 927 --------------------- .../helper-scripts/openstackrapid/secgw.test | 55 -- .../helper-scripts/openstackrapid/secgw1.cfg | 54 -- .../helper-scripts/openstackrapid/secgw2.cfg | 55 -- .../helper-scripts/openstackrapid/swap.cfg | 46 - VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg | 30 + VNFs/DPPD-PROX/helper-scripts/rapid/README | 149 ++++ .../DPPD-PROX/helper-scripts/rapid/basicrapid.test | 60 ++ VNFs/DPPD-PROX/helper-scripts/rapid/centos.json | 33 + .../rapid/check-prox-system-setup.service | 11 + .../rapid/check_prox_system_setup.sh | 51 ++ VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py | 418 ++++++++++ .../DPPD-PROX/helper-scripts/rapid/deploycentos.sh | 139 +++ VNFs/DPPD-PROX/helper-scripts/rapid/devbind.sh | 27 + VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg | 76 ++ VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg | 74 ++ VNFs/DPPD-PROX/helper-scripts/rapid/impair.cfg | 50 ++ VNFs/DPPD-PROX/helper-scripts/rapid/impair.test | 54 ++ VNFs/DPPD-PROX/helper-scripts/rapid/irq.cfg | 42 + VNFs/DPPD-PROX/helper-scripts/rapid/irq.test | 32 + .../helper-scripts/rapid/l2framerate.test | 42 + VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg | 70 ++ VNFs/DPPD-PROX/helper-scripts/rapid/l2swap.cfg | 46 + .../DPPD-PROX/helper-scripts/rapid/l2zeroloss.test | 56 ++ .../helper-scripts/rapid/l3framerate.test | 42 + VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py | 254 ++++++ VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms | 61 ++ VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py | 927 +++++++++++++++++++++ VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test | 55 ++ VNFs/DPPD-PROX/helper-scripts/rapid/secgw1.cfg | 54 ++ VNFs/DPPD-PROX/helper-scripts/rapid/secgw2.cfg | 55 ++ VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg | 46 + 54 files changed, 2954 insertions(+), 2954 deletions(-) delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/MachineMap.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/README delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/basicrapid.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/centos.json delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/check-prox-system-setup.service delete mode 100755 VNFs/DPPD-PROX/helper-scripts/openstackrapid/check_prox_system_setup.sh delete mode 100755 VNFs/DPPD-PROX/helper-scripts/openstackrapid/createrapid.py delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos.sh delete mode 100755 VNFs/DPPD-PROX/helper-scripts/openstackrapid/devbind.sh delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen_gw.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2framerate.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2gen.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2swap.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2zeroloss.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/l3framerate.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/prox_ctrl.py delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapidVMs.vms delete mode 100755 VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw.test delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw1.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw2.cfg delete mode 100644 VNFs/DPPD-PROX/helper-scripts/openstackrapid/swap.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/README create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/centos.json create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service create mode 100755 VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh create mode 100755 VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh create mode 100755 VNFs/DPPD-PROX/helper-scripts/rapid/devbind.sh create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/impair.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/impair.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/irq.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/irq.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/l2swap.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms create mode 100755 VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/secgw1.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/secgw2.cfg create mode 100644 VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/MachineMap.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/MachineMap.cfg deleted file mode 100644 index b6e199d7..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/MachineMap.cfg +++ /dev/null @@ -1,30 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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 contains the mapping for each test machine. The test machine will -## be deployed on a machine defined in the *.env file, as defined by the -## machine_index - -[DEFAULT] -machine_index=0 - -[TestM1] -machine_index=1 - -[TestM2] -machine_index=2 - -[TestM3] -machine_index=3 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/README b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/README deleted file mode 100644 index 43243a6c..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/README +++ /dev/null @@ -1,149 +0,0 @@ -## -## Copyright (c) 2010-2017 Intel Corporation -## -## 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. -## - -rapid (Rapid Automated Performance Indication for Dataplane) -************************************************************ - -rapid is a set of files offering an easy way to do a sanity check of the -dataplane performance of an OpenStack environment. - -Copy the files in a directory on a machine that can run the OpenStack CLI -commands and that can reach the OpenStack networks to connect to the VMs. - -You will need an image that has the PROX tool installed. -A good way to do this is to use the packer tool to build an image for a target of your choice. -You can also build this image manually by executing all the commands described in the deploycentos.sh. -The default name of the qcow2 file is rapidVM.qcow2 - -When using the packer tool, the first step is to upload an -existing CentOS cloud image from the internet into OpenStack. -Check out: https://cloud.centos.org/centos/7/images/ -You should now source the proper .rc file so Packer can connect to your OpenStack. -There are 2 files: centos.json and deploycentos.sh, allowing you to create -an image automatically. Run - # packer build centos.json -Edit centos.json to reflect the settings of your environment: The following fields need to -be the ID's of your system: - - "source_image": Needs to be the id of the Centos cloud image - - "flavor": Needs to be the ID of the flavor existing in your OpenStack environment that will be used - to start the VM in which we will install all tools - - "networks": ID of the network that will be used for the VM - - "use_floating_ip": true or false - - "floating_ip_pool": ID of the floating ip pool in case floating ip are being used - - "security_groups": ID of the security group being used - -Note that this procedure is not only installing the necessary tools to run PROX, -but also does some system optimizations (tuned). Check deploycentos.sh for more details. - -Now you can run the createrapid.py file. Use help for more info on the usage: - # ./createrapid.py --help - -createrapid.py will use the OpenStack CLI to create the flavor, key-pair, network, image, -servers, ... -It will create a .env file containing all info that will be used by runrapid.py -to actually run the tests. Logging can be found in the CREATE.log file -You can use floating IP addresses by specifying the floating IP network ---floating_network NETWORK -or directly connect through the INTERNAL_NETWORK by using the following parameter: ---floating_network NO -/etc/resolv.conf will contain DNS info from the "best" interface. Since we are -deploying VMs with multiple interface on different networks, this info might be -taken from the "wrong" network (e.g. the dataplane network). - -Now you can run the runrapid.py file. Use help for more info on the usage: - # ./runrapid.py --help -The script will connect to all machines that have been instantiated and it will launch -PROX in all machines. This will be done through the admin IP assigned to the machines. -Once that is done it will connect to the PROX tcp socket and start sending -commands to run the actual test. -Make sure the security groups allow for tcp access (ssh & prox port). -It will print test results on the screen while running. -The actual test that is running is described in .test. - -Notes about prox_user_data.sh script: -- The script contains commands that will be executed using cloud-init at - startup of the VMs. -- huge pages are allocated for DPDK on node 0 (hard-coded) in the VM. - -Note on using SRIOV ports: -Before running createrapid, make sure the network, subnet and ports are already created -This can be done as follows (change the parameters to your needs): -openstack network create --share --external --provider-network-type flat --provider-physical-network physnet2 fast-network -openstack subnet create --network fast-network --subnet-range 20.20.20.0/24 --gateway none fast-subnet -openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port1 -openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port2 -openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port3 -Make sure to use the network and subnet in the createrapid parameters list. Port1, Port2 and Port3 -are being used in the *.env file. - -Note when doing tests using the gateway functionality on OVS: -When a GW VM is sending packets on behalf of another VM (e.g. the generator), we need to make sure the OVS -will allow those packets to go through. Therefore you need to the IP address of the generator in the -"allowed address pairs" of the GW VM. - -Note when doing tests using encryption on OVS: -Your OVS configuration might block encrypted packets. To allow packets to go through, -you can disable port_security. You can do this by using the following commands -neutron port-update xxxxxx --no-security-groups -neutron port-update xxxxxx --port_security_enabled=False - -An example of the env file generated by createrapid.py can be found below. -Note that this file can be created manually in case the stack is created in a -different way (not using the createrapid.py). This can be useful in case you are -not using OpenStack as a VIM or when using special configurations that cannot be -achieved using createrapid.py. Fields needed for runrapid are: -* all info in the [Mx] sections -* the key information in the [OpenStack] section -* the total_number_of_vms information in the [rapid] section - -[DEFAULT] -admin_ip = none - -[M1] -name = rapid-VM1 -admin_ip = 10.25.1.116 -dp_ip = 10.10.10.7 -dp_mac = fa:16:3e:59:b8:28 - -[M2] -name = rapid-VM2 -admin_ip = 10.25.1.126 -dp_ip = 10.10.10.11 -dp_mac = fa:16:3e:c9:54:c7 - -[M3] -name = rapid-VM3 -admin_ip = 10.25.1.108 -dp_ip = 10.10.10.15 -dp_mac = fa:16:3e:72:90:3e - -[OpenStack] -stack = rapid -vms = rapidVMs -key = prox -image = rapidVM -image_file = rapidVM.qcow2 -dataplane_network = dataplane-network -subnet = dpdk-subnet -subnet_cidr = 10.10.10.0/24 -internal_network = admin_internal_net -floating_network = floating-ip-net - -[rapid] -loglevel = DEBUG -version = 19.4.15 -total_number_of_machines = 3 - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/basicrapid.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/basicrapid.test deleted file mode 100644 index b2f8f230..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/basicrapid.test +++ /dev/null @@ -1,60 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = BasicSwapTesting -number_of_tests = 4 -total_number_of_test_machines = 2 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = gen.cfg -dest_vm = 2 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = Swap -config_file = swap.cfg -swapcores = [1] - -[BinarySearchParams] -drop_rate_threshold = 0.1 -lat_avg_threshold = 500 -lat_max_threshold = 1000 -accuracy = 0.1 - -[test1] -test=inittest - -[test2] -test=speedtest -packetsize=64 - -[test3] -test=sizetest -flow=1 -packetsizes=[64,256,1024] - -[test4] -test=flowtest -packetsize=64 -# the number of flows in the list need to be powers of 2, max 2^20 -# Select from following numbers: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65535, 131072, 262144, 524280, 1048576 -flows=[1,512,1024] diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/centos.json b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/centos.json deleted file mode 100644 index 237a6483..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/centos.json +++ /dev/null @@ -1,33 +0,0 @@ -{ -"_Copyright": "Copyright (c) 2010-2018 Intel Corporation", -"_License": "SPDX-License-Identifier: Apache-2.0", -"builders": [ - { -"type": "openstack", -"ssh_username": "centos", -"image_name": "rapidVM", -"source_image": "06101dd4-f162-49c0-a072-2fe32ac446a9", -"flavor": "3ea20ea9-855c-4a6e-b454-63ad6e8e0db9", -"networks": "451a030a-eb1e-4c74-85b8-782ef8a6ad38", -"use_floating_ip": true, -"floating_ip_pool": "d629619f-8f96-4f32-9b90-1b62e5ea3809", -"security_groups": "460b7929-c6de-4b1c-ae83-901c2042a894" - } -], -"provisioners": [ - { - "type": "file", - "source": "./check_prox_system_setup.sh", - "destination": "/home/centos/" - }, - { - "type": "file", - "source": "./check-prox-system-setup.service", - "destination": "/home/centos/" - }, - { - "type": "shell", - "script": "deploycentos.sh" - } -] -} diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check-prox-system-setup.service b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check-prox-system-setup.service deleted file mode 100644 index a55e0c08..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check-prox-system-setup.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Check PROX system setup (isolated_cores, uio) -DefaultDependencies=no -After=multi-user.target - -[Service] -Type=oneshot -ExecStart=/usr/local/libexec/check_prox_system_setup.sh - -[Install] -WantedBy=multi-user.target diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check_prox_system_setup.sh b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check_prox_system_setup.sh deleted file mode 100755 index 48999510..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/check_prox_system_setup.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## -NCPUS="$(lscpu | egrep '^CPU\(s\):' | awk '{ print $2 }')" -MAXCOREID="$((NCPUS-1))" - -filename="/etc/tuned/realtime-virtual-guest-variables.conf" -logfile="/home/centos/prox_system_setup.log" -if [ -f "$filename" ] -then - while read -r line - do - case $line in - isolated_cores=1-$MAXCOREID*) - echo "Isolated CPU(s) OK, no reboot: $line">>$logfile - modprobe uio - insmod /root/dpdk/build/kmod/igb_uio.ko - exit 0 - ;; - isolated_cores=*) - echo "Isolated CPU(s) NOK, change the config and reboot: $line">>$logfile - sed -i "/^isolated_cores=.*/c\isolated_cores=1-$MAXCOREID" $filename - tuned-adm profile realtime-virtual-guest - reboot - exit 0 - ;; - *) - echo "$line" - ;; - esac - done < "$filename" - echo "isolated_cores=1-$MAXCOREID" >> $filename - echo "No Isolated CPU(s) defined in config, line added: $line">>$logfile - tuned-adm profile realtime-virtual-guest - reboot -else - echo "$filename not found.">>$logfile -fi diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/createrapid.py b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/createrapid.py deleted file mode 100755 index a1c1de60..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/createrapid.py +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (c) 2010-2017 Intel Corporation -## -## 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. -## - -from __future__ import print_function - -import os -import stat -import sys -import time -import subprocess -import getopt -import re -import logging -from logging.handlers import RotatingFileHandler -from logging import handlers -from prox_ctrl import prox_ctrl -import ConfigParser - -version="19.4.15" -stack = "rapid" #Default string for stack. This is not an OpenStack Heat stack, just a group of VMs -vms = "rapidVMs" #Default string for vms file -key = "prox" # default name for kay -image = "rapidVM" # default name for the image -image_file = "rapidVM.qcow2" -dataplane_network = "dataplane-network" # default name for the dataplane network -subnet = "dpdk-subnet" #subnet for dataplane -subnet_cidr="10.10.10.0/24" # cidr for dataplane -internal_network="admin_internal_net" -floating_network="admin_floating_net" -loglevel="DEBUG" # sets log level for writing to file -runtime=10 # time in seconds for 1 test run - -def usage(): - print("usage: createrapid [--version] [-v]") - print(" [--stack STACK_NAME]") - print(" [--vms VMS_FILE]") - print(" [--key KEY_NAME]") - print(" [--image IMAGE_NAME]") - print(" [--image_file IMAGE_FILE]") - print(" [--dataplane_network DP_NETWORK]") - print(" [--subnet DP_SUBNET]") - print(" [--subnet_cidr SUBNET_CIDR]") - print(" [--internal_network ADMIN_NETWORK]") - print(" [--floating_network FLOATING_NETWORK]") - print(" [--log DEBUG|INFO|WARNING|ERROR|CRITICAL]") - print(" [-h] [--help]") - print("") - print("Command-line interface to createrapid") - print("") - print("optional arguments:") - print(" -v, --version Show program's version number and exit") - print(" --stack STACK_NAME Specify a name for the stack. Default is %s."%stack) - print(" --vms VMS_FILE Specify the vms file to be used. Default is %s.vms."%vms) - print(" --key KEY_NAME Specify the key to be used. Default is %s."%key) - print(" --image IMAGE_NAME Specify the image to be used. Default is %s."%image) - print(" --image_file IMAGE_FILE Specify the image qcow2 file to be used. Default is %s."%image_file) - print(" --dataplane_network NETWORK Specify the network name to be used for the dataplane. Default is %s."%dataplane_network) - print(" --subnet DP_SUBNET Specify the subnet name to be used for the dataplane. Default is %s."%subnet) - print(" --subnet_cidr SUBNET_CIDR Specify the subnet CIDR to be used for the dataplane. Default is %s."%subnet_cidr) - print(" --internal_network NETWORK Specify the network name to be used for the control plane. Default is %s."%internal_network) - print(" --floating_network NETWORK Specify the external floating ip network name. Default is %s. NO if no floating ip used."%floating_network) - print(" --log Specify logging level for log file output, screen output level is hard coded") - print(" -h, --help Show help message and exit.") - print("") - -try: - opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "vms=","stack=","key=","image=","image_file=","dataplane_network=","subnet=","subnet_cidr=","internal_network=","floating_network=","log="]) -except getopt.GetoptError as err: - print("===========================================") - print(str(err)) - print("===========================================") - usage() - sys.exit(2) -if args: - usage() - sys.exit(2) -for opt, arg in opts: - if opt in ("-h", "--help"): - usage() - sys.exit() - if opt in ("-v", "--version"): - print("Rapid Automated Performance Indication for Dataplane "+version) - sys.exit() - if opt in ("--stack"): - stack = arg - print ("Using '"+stack+"' as name for the stack") - elif opt in ("--vms"): - vms = arg - print ("Using Virtual Machines Description: "+vms) - elif opt in ("--key"): - key = arg - print ("Using key: "+key) - elif opt in ("--image"): - image = arg - print ("Using image: "+image) - elif opt in ("--image_file"): - image_file = arg - print ("Using qcow2 file: "+image_file) - elif opt in ("--dataplane_network"): - dataplane_network = arg - print ("Using dataplane network: "+ dataplane_network) - elif opt in ("--subnet"): - subnet = arg - print ("Using dataplane subnet: "+ subnet) - elif opt in ("--subnet_cidr"): - subnet_cidr = arg - print ("Using dataplane subnet: "+ subnet_cidr) - elif opt in ("--internal_network"): - internal_network = arg - print ("Using control plane network: "+ internal_network) - elif opt in ("--floating_network"): - floating_network = arg - print ("Using floating ip network: "+ floating_network) - elif opt in ("--log"): - loglevel = arg - print ("Log level: "+ loglevel) - - -# create formatters -screen_formatter = logging.Formatter("%(message)s") -file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") - -# get a top-level logger, -# set its log level, -# BUT PREVENT IT from propagating messages to the root logger -# -log = logging.getLogger() -numeric_level = getattr(logging, loglevel.upper(), None) -if not isinstance(numeric_level, int): - raise ValueError('Invalid log level: %s' % loglevel) -log.setLevel(numeric_level) -log.propagate = 0 - -# create a console handler -# and set its log level to the command-line option -# -console_handler = logging.StreamHandler(sys.stdout) -console_handler.setLevel(logging.INFO) -console_handler.setFormatter(screen_formatter) - -# create a file handler -# and set its log level to DEBUG -# -log_file = 'CREATE' +stack +'.log' -file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10) -#file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5) -file_handler.setLevel(numeric_level) -file_handler.setFormatter(file_formatter) - -# add handlers to the logger -# -log.addHandler(file_handler) -log.addHandler(console_handler) - -# Check if log exists and should therefore be rolled -needRoll = os.path.isfile(log_file) - - -# This is a stale log, so roll it -if needRoll: - # Add timestamp - log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime()) - - # Roll over on application start - log.handlers[0].doRollover() - -# Add timestamp -log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime()) - -log.debug("createrapid.py version: "+version) -# Checking if the control network already exists, if not, stop the script -log.debug("Checking control plane network: "+internal_network) -cmd = 'openstack network show '+internal_network -log.debug (cmd) -cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' -NetworkExist = subprocess.check_output(cmd , shell=True).strip() -if NetworkExist == 'ACTIVE': - log.info("Control plane network ("+internal_network+") already active") -else: - log.exception("Control plane network " + internal_network + " not existing") - raise Exception("Control plane network " + internal_network + " not existing") - -# Checking if the floating ip network already exists, if not, stop the script -if floating_network <>'NO': - log.debug("Checking floating ip network: "+floating_network) - cmd = 'openstack network show '+floating_network - log.debug (cmd) - cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' - NetworkExist = subprocess.check_output(cmd , shell=True).strip() - if NetworkExist == 'ACTIVE': - log.info("Floating ip network ("+floating_network+") already active") - else: - log.exception("Floating ip network " + floating_network + " not existing") - raise Exception("Floating ip network " + floating_network + " not existing") - -# Checking if the image already exists, if not create it -log.debug("Checking image: "+image) -cmd = 'openstack image show '+image -log.debug(cmd) -cmd = cmd +' |grep "status " | tr -s " " | cut -d" " -f 4' -ImageExist = subprocess.check_output(cmd , shell=True).strip() -if ImageExist == 'active': - log.info("Image ("+image+") already available") -else: - log.info('Creating image ...') - cmd = 'openstack image create --disk-format qcow2 --container-format bare --public --file ./'+image_file+ ' ' +image - log.debug(cmd) - cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' - ImageExist = subprocess.check_output(cmd , shell=True).strip() - if ImageExist == 'active': - log.info('Image created and active') - cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image -# subprocess.check_call(cmd , shell=True) - else : - log.exception("Failed to create image") - raise Exception("Failed to create image") - -# Checking if the key already exists, if not create it -log.debug("Checking key: "+key) -cmd = 'openstack keypair show '+key -log.debug (cmd) -cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4' -KeyExist = subprocess.check_output(cmd , shell=True).strip() -if KeyExist == key: - log.info("Key ("+key+") already installed") -else: - log.info('Creating key ...') - cmd = 'openstack keypair create '+ key + '>' +key+'.pem' - log.debug(cmd) - subprocess.check_call(cmd , shell=True) - cmd = 'chmod 600 ' +key+'.pem' - subprocess.check_call(cmd , shell=True) - cmd = 'openstack keypair show '+key - log.debug(cmd) - cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4' - KeyExist = subprocess.check_output(cmd , shell=True).strip() - if KeyExist == key: - log.info("Key created") - else : - log.exception("Failed to create key: " + key) - raise Exception("Failed to create key: " + key) - - -# Checking if the dataplane network already exists, if not create it -log.debug("Checking dataplane network: "+dataplane_network) -cmd = 'openstack network show '+dataplane_network -log.debug (cmd) -cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' -NetworkExist = subprocess.check_output(cmd , shell=True).strip() -if NetworkExist == 'ACTIVE': - log.info("Dataplane network ("+dataplane_network+") already active") -else: - log.info('Creating dataplane network ...') - cmd = 'openstack network create '+dataplane_network - log.debug(cmd) - cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' - NetworkExist = subprocess.check_output(cmd , shell=True).strip() - if NetworkExist == 'ACTIVE': - log.info("Dataplane network created") - else : - log.exception("Failed to create dataplane network: " + dataplane_network) - raise Exception("Failed to create dataplane network: " + dataplane_network) - -# Checking if the dataplane subnet already exists, if not create it -log.debug("Checking subnet: "+subnet) -cmd = 'openstack subnet show '+ subnet -log.debug (cmd) -cmd = cmd +' |grep "name " | tr -s " " | cut -d"|" -f 3' -SubnetExist = subprocess.check_output(cmd , shell=True).strip() -if SubnetExist == subnet: - log.info("Subnet (" +subnet+ ") already exists") -else: - log.info('Creating subnet ...') - cmd = 'openstack subnet create --network ' + dataplane_network + ' --subnet-range ' + subnet_cidr +' --gateway none ' + subnet - log.debug(cmd) - cmd = cmd + ' |grep "name " | tr -s " " | cut -d"|" -f 3' - SubnetExist = subprocess.check_output(cmd , shell=True).strip() - if SubnetExist == subnet: - log.info("Subnet created") - else : - log.exception("Failed to create subnet: " + subnet) - raise Exception("Failed to create subnet: " + subnet) - -ServerToBeCreated=[] -ServerName=[] -config = ConfigParser.RawConfigParser() -vmconfig = ConfigParser.RawConfigParser() -vmconfig.read(vms+'.vms') -total_number_of_VMs = vmconfig.get('DEFAULT', 'total_number_of_vms') -for vm in range(1, int(total_number_of_VMs)+1): - flavor_info = vmconfig.get('VM%d'%vm, 'flavor_info') - flavor_meta_data = vmconfig.get('VM%d'%vm, 'flavor_meta_data') - boot_info = vmconfig.get('VM%d'%vm, 'boot_info') - SRIOV_port = vmconfig.get('VM%d'%vm, 'SRIOV_port') - ServerName.append('%s-VM%d'%(stack,vm)) - flavor_name = '%s-VM%d-flavor'%(stack,vm) - log.debug("Checking server: "+ServerName[-1]) - cmd = 'openstack server show '+ServerName[-1] - log.debug (cmd) - cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' - ServerExist = subprocess.check_output(cmd , shell=True).strip() - if ServerExist == ServerName[-1]: - log.info("Server ("+ServerName[-1]+") already active") - ServerToBeCreated.append("no") - else: - ServerToBeCreated.append("yes") - # Checking if the flavor already exists, if not create it - log.debug("Checking flavor: "+flavor_name) - cmd = 'openstack flavor show '+flavor_name - log.debug (cmd) - cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' - FlavorExist = subprocess.check_output(cmd , shell=True).strip() - if FlavorExist == flavor_name: - log.info("Flavor ("+flavor_name+") already installed") - else: - log.info('Creating flavor ...') - cmd = 'openstack flavor create %s %s'%(flavor_name,flavor_info) - log.debug(cmd) - cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' - FlavorExist = subprocess.check_output(cmd , shell=True).strip() - if FlavorExist == flavor_name: - cmd = 'openstack flavor set %s %s'%(flavor_name, flavor_meta_data) - log.debug(cmd) - subprocess.check_call(cmd , shell=True) - log.info("Flavor created") - else : - log.exception("Failed to create flavor: " + flavor_name) - raise Exception("Failed to create flavor: " + flavor_name) - if SRIOV_port == 'NO': - nic_info = '--nic net-id=%s --nic net-id=%s'%(internal_network,dataplane_network) - else: - nic_info = '--nic net-id=%s'%(internal_network) - for port in SRIOV_port.split(','): - nic_info = nic_info + ' --nic port-id=%s'%(port) - if vm==int(total_number_of_VMs): - # For the last server, we want to wait for the server creation to complete, so the next operations will succeeed (e.g. IP allocation) - # Note that this waiting is not bullet proof. Imagine, we loop through all the VMs, and the last VM was already running, while the previous - # VMs still needed to be created. Or the previous server creations take much longer than the last one. - # In that case, we might be to fast when we query for the IP & MAC addresses. - wait = ' --wait ' - else: - wait = ' ' - log.info("Creating server...") - cmd = 'openstack server create --flavor %s --key-name %s --image %s %s %s%s%s'%(flavor_name,key,image,nic_info,boot_info,wait,ServerName[-1]) - log.debug(cmd) - cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' - ServerExist = subprocess.check_output(cmd , shell=True).strip() -if floating_network <> 'NO': - for vm in range(0, int(total_number_of_VMs)): - if ServerToBeCreated[vm] =="yes": - log.info('Creating & Associating floating IP for ('+ServerName[vm]+')...') - cmd = 'openstack server show %s -c addresses -f value |grep -Eo "%s=[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | cut -d"=" -f2'%(ServerName[vm],internal_network) - log.debug(cmd) - vmportIP = subprocess.check_output(cmd , shell=True).strip() - cmd = 'openstack port list -c ID -c "Fixed IP Addresses" | grep %s' %(vmportIP) - cmd = cmd + ' | cut -d" " -f 2 ' - log.debug(cmd) - vmportID = subprocess.check_output(cmd , shell=True).strip() - cmd = 'openstack floating ip create --port %s %s'%(vmportID,floating_network) - log.debug(cmd) - output = subprocess.check_output(cmd , shell=True).strip() - -for vm in range(1, int(total_number_of_VMs)+1): - cmd = 'openstack server show %s'%(ServerName[vm-1]) - log.debug(cmd) - output = subprocess.check_output(cmd , shell=True).strip() - searchString = '.*%s=([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)' %(dataplane_network) - matchObj = re.search(searchString, output, re.DOTALL) - vmDPIP = matchObj.group(1) - searchString = '.*%s=([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+),*\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)*' %(internal_network) - matchObj = re.search(searchString, output, re.DOTALL) - vmAdminIP = matchObj.group(2) - if vmAdminIP == None: - vmAdminIP = matchObj.group(1) - cmd = 'openstack port list |egrep "\\b%s\\b" | tr -s " " | cut -d"|" -f 4'%(vmDPIP) - log.debug(cmd) - vmDPmac = subprocess.check_output(cmd , shell=True).strip() - config.add_section('M%d'%vm) - config.set('M%d'%vm, 'name', ServerName[vm-1]) - config.set('M%d'%vm, 'admin_ip', vmAdminIP) - config.set('M%d'%vm, 'dp_ip', vmDPIP) - config.set('M%d'%vm, 'dp_mac', vmDPmac) - log.info('%s: (admin IP: %s), (dataplane IP: %s), (dataplane MAC: %s)' % (ServerName[vm-1],vmAdminIP,vmDPIP,vmDPmac)) - -config.add_section('OpenStack') -config.set('OpenStack', 'stack', stack) -config.set('OpenStack', 'VMs', vms) -config.set('OpenStack', 'key', key) -config.set('OpenStack', 'image', image) -config.set('OpenStack', 'image_file', image_file) -config.set('OpenStack', 'dataplane_network', dataplane_network) -config.set('OpenStack', 'subnet', subnet) -config.set('OpenStack', 'subnet_cidr', subnet_cidr) -config.set('OpenStack', 'internal_network', internal_network) -config.set('OpenStack', 'floating_network', floating_network) -config.add_section('rapid') -config.set('rapid', 'loglevel', loglevel) -config.set('rapid', 'version', version) -config.set('rapid', 'total_number_of_machines', total_number_of_VMs) -config.set('DEFAULT', 'admin_ip', 'none') -# Writing the environment file -with open(stack+'.env', 'wb') as envfile: - config.write(envfile) diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos.sh b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos.sh deleted file mode 100644 index 848520ce..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env bash -## -## Copyright (c) 2010-2019 Intel Corporation -## -## 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. -## - -BUILD_DIR="/opt/openstackrapid" -COPY_DIR="/home/centos" # Directory where the packer tool has copied some files -DPDK_VERSION="18.08" -PROX_COMMIT="af95b812" -export RTE_SDK="${BUILD_DIR}/dpdk-${DPDK_VERSION}" -export RTE_TARGET="x86_64-native-linuxapp-gcc" - -function os_pkgs_install() -{ - # NASM repository for AESNI MB library - sudo yum-config-manager --add-repo http://www.nasm.us/nasm.repo - - sudo yum install -y deltarpm - sudo yum update -y - sudo yum install -y git wget gcc unzip libpcap-devel ncurses-devel \ - libedit-devel lua-devel kernel-devel iperf3 pciutils \ - numactl-devel vim tuna openssl-devel nasm -} - -function os_cfg() -{ - # Enabling root ssh access - sudo sed -i '/disable_root: 1/c\disable_root: 0' /etc/cloud/cloud.cfg - - # Mounting huge pages to be used by DPDK, mounting already done by CentOS - # sudo mkdir -p /mnt/huge - # sudo umount `awk '/hugetlbfs/ { print $2 }' /proc/mounts` >/dev/null 2>&1 - # sudo mount -t hugetlbfs nodev /mnt/huge/ - sudo sh -c '(echo "vm.nr_hugepages = 1024") > /etc/sysctl.conf' - - # Enabling tuned with the realtime-virtual-guest profile - pushd ${BUILD_DIR} > /dev/null 2>&1 - wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-realtime-2.8.0-5.el7_4.2.noarch.rpm - wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-nfv-guest-2.8.0-5.el7_4.2.noarch.rpm - # Install with --nodeps. The latest CentOS cloud images come with a tuned version higher than 2.8. These 2 packages however - # do not depend on v2.8 and also work with tuned 2.9. Need to be careful in the future - sudo rpm -ivh ${BUILD_DIR}/tuned-profiles-realtime-2.8.0-5.el7_4.2.noarch.rpm --nodeps - sudo rpm -ivh ${BUILD_DIR}/tuned-profiles-nfv-guest-2.8.0-5.el7_4.2.noarch.rpm --nodeps - # Although we do no know how many cores the VM will have when begin deployed for real testing, we already put a number for the - # isolated CPUs so we can start the realtime-virtual-guest profile. If we don't, that command will fail. - # When the VM will be instantiated, the check_kernel_params service will check for the real number of cores available to this VM - # and update the realtime-virtual-guest-variables.conf accordingly. - echo "isolated_cores=1" | sudo tee -a /etc/tuned/realtime-virtual-guest-variables.conf - sudo tuned-adm profile realtime-virtual-guest - - # Install the check_tuned_params service to make sure that the grub cmd line has the right cpus in isolcpu. The actual number of cpu's - # assigned to this VM depends on the flavor used. We don't know at this time what that will be. - sudo chmod +x ${COPY_DIR}/check_prox_system_setup.sh - sudo cp -r ${COPY_DIR}/check_prox_system_setup.sh /usr/local/libexec/ - sudo cp -r ${COPY_DIR}/check-prox-system-setup.service /etc/systemd/system/ - sudo systemctl daemon-reload - sudo systemctl enable check-prox-system-setup.service - - popd > /dev/null 2>&1 -} - -function mblib_install() -{ - export AESNI_MULTI_BUFFER_LIB_PATH="${BUILD_DIR}/intel-ipsec-mb-0.50" - - # Downloading the Multi-buffer library. Note that the version to download is linked to the DPDK version being used - pushd ${BUILD_DIR} > /dev/null 2>&1 - wget https://github.com/01org/intel-ipsec-mb/archive/v0.50.zip - unzip v0.50.zip - pushd ${AESNI_MULTI_BUFFER_LIB_PATH} - make -j`getconf _NPROCESSORS_ONLN` - sudo make install - popd > /dev/null 2>&1 - popd > /dev/null 2>&1 -} - -function dpdk_install() -{ - # Build DPDK for the latest kernel installed - LATEST_KERNEL_INSTALLED=`ls -v1 /lib/modules/ | tail -1` - export RTE_KERNELDIR="/lib/modules/${LATEST_KERNEL_INSTALLED}/build" - - # Get and compile DPDK - pushd ${BUILD_DIR} > /dev/null 2>&1 - wget http://fast.dpdk.org/rel/dpdk-${DPDK_VERSION}.tar.xz - tar -xf ./dpdk-${DPDK_VERSION}.tar.xz - popd > /dev/null 2>&1 - - # Runtime scripts are assuming /root as the directory for PROX - sudo ln -s ${RTE_SDK} /root/dpdk - - pushd ${RTE_SDK} > /dev/null 2>&1 - make config T=${RTE_TARGET} - # The next sed lines make sure that we can compile DPDK 17.11 with a relatively new OS. Using a newer DPDK (18.5) should also resolve this issue - #sudo sed -i '/CONFIG_RTE_LIBRTE_KNI=y/c\CONFIG_RTE_LIBRTE_KNI=n' ${RTE_SDK}/build/.config - #sudo sed -i '/CONFIG_RTE_LIBRTE_PMD_KNI=y/c\CONFIG_RTE_LIBRTE_PMD_KNI=n' ${RTE_SDK}/build/.config - #sudo sed -i '/CONFIG_RTE_KNI_KMOD=y/c\CONFIG_RTE_KNI_KMOD=n' ${RTE_SDK}/build/.config - #sudo sed -i '/CONFIG_RTE_KNI_PREEMPT_DEFAULT=y/c\CONFIG_RTE_KNI_PREEMPT_DEFAULT=n' ${RTE_SDK}/build/.config - # Compile with MB library - sed -i '/CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n/c\CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y' ${RTE_SDK}/build/.config - make -j`getconf _NPROCESSORS_ONLN` - ln -s ${RTE_SDK}/build ${RTE_SDK}/${RTE_TARGET} - popd > /dev/null 2>&1 -} - -function prox_install() -{ - # Clone and compile PROX - pushd ${BUILD_DIR} > /dev/null 2>&1 - git clone https://git.opnfv.org/samplevnf - pushd ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX -# git checkout ffc6be26 - git checkout ${PROX_COMMIT} - make -j`getconf _NPROCESSORS_ONLN` - sudo ln -s ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX /root/prox - popd > /dev/null 2>&1 - popd > /dev/null 2>&1 -} - -[ ! -d ${BUILD_DIR} ] && sudo mkdir -p ${BUILD_DIR} -sudo chmod 0777 ${BUILD_DIR} - -os_pkgs_install -os_cfg -mblib_install -dpdk_install -prox_install diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/devbind.sh b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/devbind.sh deleted file mode 100755 index f9fc03ce..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/devbind.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -## -## Copyright (c) 2010-2017 Intel Corporation -## -## 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. -## - -link="$(ip -o link | grep MACADDRESS |cut -d":" -f 2)" -if [ -n "$link" ]; -then - echo Need to bind - /root/dpdk/usertools/dpdk-devbind.py --force --bind igb_uio $(/root/dpdk/usertools/dpdk-devbind.py --status |grep $link | cut -d" " -f 1) -else - echo Assuming port is already bound to DPDK -fi -exit 0 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen.cfg deleted file mode 100644 index 42cfdc1b..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen.cfg +++ /dev/null @@ -1,76 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=p0 -rx desc=2048 -tx desc=2048 -vlan=yes - -[variables] -$mbs=8 - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $gencores] -name=p0 -task=0 -mode=gen -sub mode=l3 -tx port=p0 -bps=1250000000 -pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b -pkt size=60 -;gateway ipv4=${gw_ip} -local ipv4=${local_ip} -min bulk size=$mbs -max bulk size=16 -drop=yes -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 -;arp update time=1 - -[core $latcores] -name=lat -task=0 -mode=lat -sub mode=l3 -rx port=p0 -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 -accuracy limit nsec=1000000 -;arp update time=1 - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen_gw.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen_gw.cfg deleted file mode 100644 index e819041c..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/gen_gw.cfg +++ /dev/null @@ -1,74 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=p0 -rx desc=2048 -tx desc=2048 -vlan=yes - -[variables] -$mbs=8 - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $gencores] -name=p0 -task=0 -mode=gen -sub mode=l3 -tx port=p0 -bps=1250000000 -pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b -pkt size=60 -gateway ipv4=${gw_ip} -local ipv4=${local_ip} -min bulk size=$mbs -max bulk size=16 -drop=yes -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 -;arp update time=1 - -[core $latcores] -name=lat -task=0 -mode=lat -sub mode=l3 -rx port=p0 -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 -;arp update time=1 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.cfg deleted file mode 100644 index 8ca9e05d..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.cfg +++ /dev/null @@ -1,50 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=if0 -mac=hardware -rx desc=2048 -tx desc=2048 -vlan=yes - - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $impaircores] -name=impair -task=0 -mode=impair -sub mode=l3 -rx port=if0 -tx port=if0 -delay us=1000 -probability=100 -local ipv4=${local_ip} diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.test deleted file mode 100644 index 9b633d99..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.test +++ /dev/null @@ -1,54 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = impairTesting -number_of_tests = 2 -total_number_of_test_machines = 3 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = gen_gw.cfg -gw_vm = 2 -dest_vm = 3 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = ImpairGW -config_file = impair.cfg -impaircores = [1] - -[TestM3] -name = Swap -config_file = swap.cfg -swapcores = [1] - -[BinarySearchParams] -drop_rate_threshold = 0.1 -lat_avg_threshold = 500 -lat_max_threshold = 1000 -accuracy = 0.1 - -[test1] -test=inittest - -[test2] -test=impairtest -packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.cfg deleted file mode 100644 index 38e4b966..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.cfg +++ /dev/null @@ -1,42 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[;port 0] -name=p0 - -[variables] -$mbs=8 - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $irqcores] -name=irq -task=0 -mode=irq diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.test deleted file mode 100644 index b8dc706b..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.test +++ /dev/null @@ -1,32 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = BasicSwapTesting -number_of_tests = 1 -total_number_of_test_machines = 1 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = InterruptTesting -config_file = irq.cfg -irqcores = [1,2,3] - - -[test1] -test=irqtest - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2framerate.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2framerate.test deleted file mode 100644 index 44fefdda..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2framerate.test +++ /dev/null @@ -1,42 +0,0 @@ -## -## Copyright (c) 2010-2019 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = L2BasicSwapTesting -number_of_tests = 2 -total_number_of_test_machines = 2 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = l2gen.cfg -dest_vm = 2 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = Swap -config_file = l2swap.cfg -swapcores = [1] - -[test1] -test=inittest - -[test2] -test=max_frame_rate -packetsizes=[256] diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2gen.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2gen.cfg deleted file mode 100644 index 1469604b..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2gen.cfg +++ /dev/null @@ -1,70 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=p0 -rx desc=2048 -tx desc=2048 -vlan=yes - -[variables] -$mbs=8 - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $gencores] -name=p0 -task=0 -mode=gen -tx port=p0 -bps=1250000000 -pkt inline=${dest_hex_mac} 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b -pkt size=60 -;gateway ipv4=${gw_ip} -local ipv4=${local_ip} -min bulk size=$mbs -max bulk size=16 -drop=yes -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 - -[core $latcores] -name=lat -task=0 -mode=lat -rx port=p0 -lat pos=42 -accuracy pos=46 -packet id pos=50 -signature=0x6789abcd -signature pos=56 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2swap.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2swap.cfg deleted file mode 100644 index 004588c0..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2swap.cfg +++ /dev/null @@ -1,46 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=if0 -mac=hardware -rx desc=2048 -tx desc=2048 -vlan=yes - -[defaults] -mempool size=8K - -[global] -name=${name} - -[core 0] -mode=master - -[core $swapcores] -name=swap -task=0 -mode=swap -rx port=if0 -tx port=if0 -drop=no diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2zeroloss.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2zeroloss.test deleted file mode 100644 index 04065909..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2zeroloss.test +++ /dev/null @@ -1,56 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = L2BasicSwapTesting -number_of_tests = 4 -total_number_of_test_machines = 2 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = l2gen.cfg -dest_vm = 2 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = Swap -config_file = l2swap.cfg -swapcores = [1] - -[BinarySearchParams] -drop_rate_threshold = 0 -lat_avg_threshold = 500 -lat_max_threshold = 1000 -accuracy = 0.1 - - -[test1] -test=inittest - -[test2] -test=speedtest -packetsize=64 - -[test3] -test=sizetest - -[test4] -test=flowtest -packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l3framerate.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l3framerate.test deleted file mode 100644 index 21bf8106..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/l3framerate.test +++ /dev/null @@ -1,42 +0,0 @@ -## -## Copyright (c) 2010-2019 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = L3FrameRateTesting -number_of_tests = 2 -total_number_of_test_machines = 2 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = gen.cfg -dest_vm = 2 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = Swap -config_file = swap.cfg -swapcores = [1] - -[test1] -test=inittest - -[test2] -test=max_frame_rate -packetsizes=[256] diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/prox_ctrl.py b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/prox_ctrl.py deleted file mode 100644 index 3ee28c00..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/prox_ctrl.py +++ /dev/null @@ -1,254 +0,0 @@ -## -## Copyright (c) 2010-2017 Intel Corporation -## -## 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. -## - -from __future__ import print_function - -import os -import subprocess -import socket - -class prox_ctrl(object): - def __init__(self, ip, key=None, user=None): - self._ip = ip - self._key = key - self._user = user - self._children = [] - self._proxsock = [] - - def ip(self): - return self._ip - - def connect(self): - """Simply try to run 'true' over ssh on remote system. - On failure, raise RuntimeWarning exception when possibly worth - retrying, and raise RuntimeError exception otherwise. - """ - return self.run_cmd('true', True) - - def close(self): - """Must be called before program termination.""" -# for prox in self._proxsock: -# prox.quit() - children = len(self._children) - if children == 0: - return - if children > 1: - print('Waiting for %d child processes to complete ...' % children) - for child in self._children: - ret = os.waitpid(child[0], os.WNOHANG) - if ret[0] == 0: - print("Waiting for child process '%s' to complete ..." % child[1]) - ret = os.waitpid(child[0], 0) - rc = ret[1] - if os.WIFEXITED(rc): - if os.WEXITSTATUS(rc) == 0: - print("Child process '%s' completed successfully" % child[1]) - else: - print("Child process '%s' returned exit status %d" % ( - child[1], os.WEXITSTATUS(rc))) - elif os.WIFSIGNALED(rc): - print("Child process '%s' exited on signal %d" % ( - child[1], os.WTERMSIG(rc))) - else: - print("Wait status for child process '%s' is 0x%04x" % ( - child[1], rc)) - - def run_cmd(self, command, _connect=False): - """Execute command over ssh on remote system. - Wait for remote command completion. - Return command output (combined stdout and stderr). - _connect argument is reserved for connect() method. - """ - cmd = self._build_ssh(command) - try: - return subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as ex: - if _connect and ex.returncode == 255: - raise RuntimeWarning(ex.output.strip()) - raise RuntimeError('ssh returned exit status %d:\n%s' - % (ex.returncode, ex.output.strip())) - - def fork_cmd(self, command, name=None): - """Execute command over ssh on remote system, in a child process. - Do not wait for remote command completion. - Return child process id. - """ - if name is None: - name = command - cmd = self._build_ssh(command) - pid = os.fork() - if (pid != 0): - # In the parent process - self._children.append((pid, name)) - return pid - # In the child process: use os._exit to terminate - try: - # Actually ignore output on success, but capture stderr on failure - subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as ex: - raise RuntimeError("Child process '%s' failed:\n" - 'ssh returned exit status %d:\n%s' - % (name, ex.returncode, ex.output.strip())) - os._exit(0) - - def prox_sock(self, port=8474): - """Connect to the PROX instance on remote system. - Return a prox_sock object on success, None on failure. - """ - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - sock.connect((self._ip, port)) - prox = prox_sock(sock) - self._proxsock.append(prox) - return prox - except: - return None - - def scp_put(self, src, dst): - """Copy src file from local system to dst on remote system.""" - cmd = [ 'scp', - '-B', - '-oStrictHostKeyChecking=no', - '-oUserKnownHostsFile=/dev/null', - '-oLogLevel=ERROR' ] - if self._key is not None: - cmd.extend(['-i', self._key]) - cmd.append(src) - remote = '' - if self._user is not None: - remote += self._user + '@' - remote += self._ip + ':' + dst - cmd.append(remote) - try: - # Actually ignore output on success, but capture stderr on failure - subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as ex: - raise RuntimeError('scp returned exit status %d:\n%s' - % (ex.returncode, ex.output.strip())) - - def _build_ssh(self, command): - cmd = [ 'ssh', - '-oBatchMode=yes', - '-oStrictHostKeyChecking=no', - '-oUserKnownHostsFile=/dev/null', - '-oLogLevel=ERROR' ] - if self._key is not None: - cmd.extend(['-i', self._key]) - remote = '' - if self._user is not None: - remote += self._user + '@' - remote += self._ip - cmd.append(remote) - cmd.append(command) - return cmd - -class prox_sock(object): - def __init__(self, sock): - self._sock = sock - self._rcvd = b'' - - def quit(self): - if self._sock is not None: - self._send('quit') - self._sock.close() - self._sock = None - - def start(self, cores): - self._send('start %s' % ','.join(map(str, cores))) - - def stop(self, cores): - self._send('stop %s' % ','.join(map(str, cores))) - - def speed(self, speed, cores, tasks=None): - if tasks is None: - tasks = [ 0 ] * len(cores) - elif len(tasks) != len(cores): - raise ValueError('cores and tasks must have the same len') - for (core, task) in zip(cores, tasks): - self._send('speed %s %s %s' % (core, task, speed)) - - def reset_stats(self): - self._send('reset stats') - - def lat_stats(self, cores, task=0): - min_lat = 999999999 - max_lat = avg_lat = 0 - self._send('lat stats %s %s' % (','.join(map(str, cores)), task)) - for core in cores: - stats = self._recv().split(',') - min_lat = min(int(stats[0]),min_lat) - max_lat = max(int(stats[1]),max_lat) - avg_lat += int(stats[2]) - avg_lat = avg_lat/len(cores) - self._send('stats latency(0).used') - used = float(self._recv()) - self._send('stats latency(0).total') - total = float(self._recv()) - return min_lat, max_lat, avg_lat, (used/total) - - def irq_stats(self, core, bucket, task=0): - self._send('stats task.core(%s).task(%s).irq(%s)' % (core, task, bucket)) - stats = self._recv().split(',') - return int(stats[0]) - - def show_irq_buckets(self, core, task=0): - rx = tx = drop = tsc = hz = 0 - self._send('show irq buckets %s %s' % (core,task)) - buckets = self._recv().split(';') - buckets = buckets[:-1] - return buckets - - def core_stats(self, cores, task=0): - rx = tx = drop = tsc = hz = rx_non_dp = tx_non_dp = 0 - self._send('dp core stats %s %s' % (','.join(map(str, cores)), task)) - for core in cores: - stats = self._recv().split(',') - rx += int(stats[0]) - tx += int(stats[1]) - rx_non_dp += int(stats[2]) - tx_non_dp += int(stats[3]) - drop += int(stats[4]) - tsc = int(stats[5]) - hz = int(stats[6]) - return rx-rx_non_dp, tx-tx_non_dp, drop, tsc, hz - - def set_random(self, cores, task, offset, mask, length): - self._send('set random %s %s %s %s %s' % (','.join(map(str, cores)), task, offset, mask, length)) - - def set_size(self, cores, task, pkt_size): - self._send('pkt_size %s %s %s' % (','.join(map(str, cores)), task, pkt_size)) - - def set_value(self, cores, task, offset, value, length): - self._send('set value %s %s %s %s %s' % (','.join(map(str, cores)), task, offset, value, length)) - - def _send(self, cmd): - """Append LF and send command to the PROX instance.""" - if self._sock is None: - raise RuntimeError("PROX socket closed, cannot send '%s'" % cmd) - self._sock.sendall(cmd.encode() + b'\n') - - def _recv(self): - """Receive response from PROX instance, and return it with LF removed.""" - if self._sock is None: - raise RuntimeError("PROX socket closed, cannot receive anymore") - pos = self._rcvd.find(b'\n') - while pos == -1: - self._rcvd += self._sock.recv(256) - pos = self._rcvd.find(b'\n') - rsp = self._rcvd[:pos] - self._rcvd = self._rcvd[pos+1:] - return rsp.decode() - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapidVMs.vms b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapidVMs.vms deleted file mode 100644 index d18184d6..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapidVMs.vms +++ /dev/null @@ -1,61 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - - -[DEFAULT] -total_number_of_vms=3 -flavor_info=--ram 4096 --disk 40 --vcpus 4 -;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate --property hw:numa_nodes=1 --property hw:numa_cpus.0=0,1,2,3 --property hw:numa_mempolicy=strict --property hw:numa_mem.0=4096 -;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate -flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated -;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_realtime=yes --property hw:cpu_realtime_mask=^0 -;boot_info=--availability-zone nova --security-group default -boot_info=--availability-zone nova --security-group prox -SRIOV_port=NO - -[VM1] - -[VM2] - -[VM3] - -[VM4] - -[VM5] - -[VM6] - -[VM7] - -[VM8] - -[VM9] - -[VM10] - -[VM11] - -[VM12] - -[VM13] - -[VM14] - -[VM15] - -[VM16] - - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py deleted file mode 100755 index 3b0eeb8b..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py +++ /dev/null @@ -1,927 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (c) 2010-2017 Intel Corporation -## -## 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. -## - -from __future__ import print_function - -import os -import stat -import sys -import time -import subprocess -import getopt -import re -import logging -from logging.handlers import RotatingFileHandler -from logging import handlers -from prox_ctrl import prox_ctrl -import ConfigParser -import ast -import atexit -import csv - -version="19.4.15" -env = "rapid" #Default string for environment -test = "basicrapid" #Default string for test -machine_map_file = "MachineMap" #Default string for machine map file -loglevel="DEBUG" # sets log level for writing to file -runtime=10 # time in seconds for 1 test run -configonly = False # IF True, the system will upload all the necessary config fiels to the VMs, but not start PROX and the actual testing - -def usage(): - print("usage: runrapid [--version] [-v]") - print(" [--env ENVIRONMENT_NAME]") - print(" [--test TEST_NAME]") - print(" [--map MACHINE_MAP_FILE]") - print(" [--runtime TIME_FOR_TEST]") - print(" [--configonly False|True]") - print(" [--log DEBUG|INFO|WARNING|ERROR|CRITICAL]") - print(" [-h] [--help]") - print("") - print("Command-line interface to runrapid") - print("") - print("optional arguments:") - print(" -v, --version Show program's version number and exit") - print(" --env ENVIRONMENT_NAME Parameters will be read from ENVIRONMENT_NAME.env Default is %s."%env) - print(" --test TEST_NAME Test cases will be read from TEST_NAME.test Default is %s."%test) - print(" --map MACHINE_MAP_FILE Machine mapping will be read from MACHINE_MAP_FILE.cfg Default is %s."%machine_map_file) - print(" --runtime Specify time in seconds for 1 test run") - print(" --configonly If True, only upload all config files to the VMs, do not run the tests. Default is %s."%configonly) - print(" --log Specify logging level for log file output, screen output level is hard coded") - print(" -h, --help Show help message and exit.") - print("") - -try: - opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "env=", "test=", "map=", "runtime=","configonly=","log="]) -except getopt.GetoptError as err: - print("===========================================") - print(str(err)) - print("===========================================") - usage() - sys.exit(2) -if args: - usage() - sys.exit(2) -for opt, arg in opts: - if opt in ("-h", "--help"): - usage() - sys.exit() - if opt in ("-v", "--version"): - print("Rapid Automated Performance Indication for Dataplane "+version) - sys.exit() - if opt in ("--env"): - env = arg - print ("Using '"+env+"' as name for the environment") - if opt in ("--test"): - test = arg - print ("Using '"+test+".test' for test case definition") - if opt in ("--map"): - machine_map_file = arg - print ("Using '"+machine_map_file+".cfg' for machine mapping") - if opt in ("--runtime"): - runtime = arg - print ("Runtime: "+ runtime) - if opt in ("--configonly"): - configonly = arg - print ("configonly: "+ configonly) - if opt in ("--log"): - loglevel = arg - print ("Log level: "+ loglevel) - -class bcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - -# create formatters -screen_formatter = logging.Formatter("%(message)s") -file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") - -# get a top-level logger, -# set its log level, -# BUT PREVENT IT from propagating messages to the root logger -# -log = logging.getLogger() -numeric_level = getattr(logging, loglevel.upper(), None) -if not isinstance(numeric_level, int): - raise ValueError('Invalid log level: %s' % loglevel) -log.setLevel(numeric_level) -log.propagate = 0 - -# create a console handler -# and set its log level to the command-line option -# -console_handler = logging.StreamHandler(sys.stdout) -console_handler.setLevel(logging.INFO) -console_handler.setFormatter(screen_formatter) - -# create a file handler -# and set its log level to DEBUG -# -log_file = 'RUN{}.{}.log'.format(env,test) -file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10) -#file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5) -file_handler.setLevel(numeric_level) -file_handler.setFormatter(file_formatter) - -# add handlers to the logger -# -log.addHandler(file_handler) -log.addHandler(console_handler) - -# Check if log exists and should therefore be rolled -needRoll = os.path.isfile(log_file) - - -# This is a stale log, so roll it -if needRoll: - # Add timestamp - log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime()) - - # Roll over on application start - log.handlers[0].doRollover() - -# Add timestamp -log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime()) - -log.debug("runrapid.py version: "+version) -#======================================================================== -def connect_socket(client): - attempts = 1 - log.debug("Trying to connect to PROX (just launched) on %s, attempt: %d" % (client.ip(), attempts)) - sock = None - while True: - sock = client.prox_sock() - if sock is not None: - break - attempts += 1 - if attempts > 20: - log.exception("Failed to connect to PROX on %s after %d attempts" % (client.ip(), attempts)) - raise Exception("Failed to connect to PROX on %s after %d attempts" % (client.ip(), attempts)) - time.sleep(2) - log.debug("Trying to connect to PROX (just launched) on %s, attempt: %d" % (client.ip(), attempts)) - log.info("Connected to PROX on %s" % client.ip()) - return sock - -def connect_client(client): - attempts = 1 - log.debug("Trying to connect to VM which was just launched on %s, attempt: %d" % (client.ip(), attempts)) - while True: - try: - client.connect() - break - except RuntimeWarning, ex: - attempts += 1 - if attempts > 20: - log.exception("Failed to connect to VM after %d attempts:\n%s" % (attempts, ex)) - raise Exception("Failed to connect to VM after %d attempts:\n%s" % (attempts, ex)) - time.sleep(2) - log.debug("Trying to connect to VM which was just launched on %s, attempt: %d" % (client.ip(), attempts)) - log.debug("Connected to VM on %s" % client.ip()) - -def run_iteration(gensock,sutsock): - sleep_time = 3 - # Sleep_time is needed to be able to do accurate measurements to check for packet loss. We need to make this time large enough so that we do not take the first measurement while some packets from the previous tests migth still be in flight - time.sleep(sleep_time) - abs_old_rx, abs_old_tx, abs_old_drop, abs_old_tsc, abs_tsc_hz = gensock.core_stats(genstatcores) - gensock.start(gencores) - time.sleep(sleep_time) - if sutsock!='none': - old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) - old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(genstatcores) - # Measure latency statistics per second - n_loops = 0 - lat_min = 0 - lat_max = 0 - lat_avg = 0 - used_avg = 0 - while n_loops < float(runtime): - n_loops +=1 - time.sleep(1) - lat_min_sample, lat_max_sample, lat_avg_sample, used_sample = gensock.lat_stats(latcores) - if lat_min > lat_min_sample: - lat_min = lat_min_sample - if lat_max < lat_max_sample: - lat_max = lat_max_sample - lat_avg = lat_avg + lat_avg_sample - used_avg = used_avg + used_sample - lat_avg = lat_avg / n_loops - used_avg = used_avg / n_loops - # Get statistics after some execution time - new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) - if sutsock!='none': - new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) - #Stop generating - gensock.stop(gencores) - time.sleep(sleep_time) - abs_new_rx, abs_new_tx, abs_new_drop, abs_new_tsc, abs_tsc_hz = gensock.core_stats(genstatcores) - drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM - rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM - tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface - abs_dropped = (abs_new_tx - abs_old_tx) - (abs_new_rx - abs_old_rx) - tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. - pps_req_tx = (tx+drop-rx)*tsc_hz*1.0/(tsc*1000000) - pps_tx = tx*tsc_hz*1.0/(tsc*1000000) - pps_rx = rx*tsc_hz*1.0/(tsc*1000000) - if sutsock!='none': - sut_rx = new_sut_rx - old_sut_rx - sut_tx = new_sut_tx - old_sut_tx - sut_tsc = new_sut_tsc - old_sut_tsc - pps_sut_tx = sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000) - pps_sut_tx_str = '{:>9.3f}'.format(pps_sut_tx) - else: - pps_sut_tx = 0 - pps_sut_tx_str = 'NO MEAS.' - if (tx == 0): - log.critical("TX = 0. Test interrupted since no packet has been sent.") - raise Exception("TX = 0") - return(pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max,abs_dropped,(abs_new_tx - abs_old_tx),lat_min,used_avg) - -def new_speed(speed,minspeed,maxspeed,success): - if success: - minspeed = speed - else: - maxspeed = speed - newspeed = (maxspeed+minspeed)/2.0 - return (newspeed,minspeed,maxspeed) - -def get_pps(speed,size): - return (speed * 100.0 / (8*(size+24))) - -def run_speedtest(gensock,sutsock): - maxspeed = speed = STARTSPEED - minspeed = 0 - size=PACKETSIZE-4 - attempts = 0 - log.info("+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+") - log.info("| Generator is sending UDP (1 flow) packets ("+ '{:>5}'.format(size+4) +" bytes) to SUT. SUT sends packets back |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") - log.info("| Test | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio | Result |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") - endpps_sut_tx_str = 'NO_RESULTS' - gensock.set_size(gencores,0,size) # This is setting the frame size - gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) - gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) - # This will only work when using sending UDP packets. For different protocols and ethernet types, we would need a different calculation - gensock.start(latcores) - while (maxspeed-minspeed > ACCURACY): - attempts += 1 - print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') - sys.stdout.flush() - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(speed / len(gencores), gencores) - time.sleep(1) - # Get statistics now that the generation is stable and initial ARP messages are dealt with. - pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) - drop_rate = 100.0*abs_dropped/abs_tx - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): - log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) - endspeed = speed - endpps_req_tx = pps_req_tx - endpps_tx = pps_tx - endpps_sut_tx_str = pps_sut_tx_str - endpps_rx = pps_rx - endlat_avg = lat_avg - endlat_max = lat_max - endabs_dropped = abs_dropped - enddrop_rate = drop_rate - endwarning = lat_warning - success = True - else: - abs_drop_rate_prefix = bcolors.ENDC - if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): - abs_drop_rate_prefix = bcolors.FAIL - if (drop_rate < DROP_RATE_TRESHOLD): - drop_rate_prefix = bcolors.ENDC - else: - drop_rate_prefix = bcolors.FAIL - if (lat_avg< LAT_AVG_TRESHOLD): - lat_avg_prefix = bcolors.ENDC - else: - lat_avg_prefix = bcolors.FAIL - if (lat_max< LAT_MAX_TRESHOLD): - lat_max_prefix = bcolors.ENDC - else: - lat_max_prefix = bcolors.FAIL - if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): - speed_prefix = bcolors.ENDC - else: - speed_prefix = bcolors.FAIL - log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+lat_warning) - success = False - speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) - if endpps_sut_tx_str <> 'NO_RESULTS': - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") - log.info('|{:>7}'.format('END')+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+ '{:>9.0f}'.format(endlat_max)+' us | '+'{:>14d}'.format(endabs_dropped)+ ' |''{:>9.2f}'.format(enddrop_rate)+ '% | SUCCESS |'+endwarning) - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") - writer.writerow({'flow':'1','size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) - else: - log.info('| Speed 0 or close to 0') - gensock.stop(latcores) - -def run_flowtest(gensock,sutsock): - size=PACKETSIZE-4 - log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") - log.info("| UDP, "+ '{:>5}'.format(size+4) +" bytes, different number of flows by randomizing SRC & DST UDP port |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - log.info("| Flows | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - # To generate a desired number of flows, PROX will randomize the bits in source and destination ports, as specified by the bit masks in the flows variable. - flows={\ - 1: ['1000000000000000','1000000000000000'],\ - 2: ['1000000000000000','100000000000000X'],\ - 4: ['100000000000000X','100000000000000X'],\ - 8: ['100000000000000X','10000000000000XX'],\ - 16: ['10000000000000XX','10000000000000XX'],\ - 32: ['10000000000000XX','1000000000000XXX'],\ - 64: ['1000000000000XXX','1000000000000XXX'],\ - 128: ['1000000000000XXX','100000000000XXXX'],\ - 256: ['100000000000XXXX','100000000000XXXX'],\ - 512: ['100000000000XXXX','10000000000XXXXX'],\ - 1024: ['10000000000XXXXX','10000000000XXXXX'],\ - 2048: ['10000000000XXXXX','1000000000XXXXXX'],\ - 4096: ['1000000000XXXXXX','1000000000XXXXXX'],\ - 8192: ['1000000000XXXXXX','100000000XXXXXXX'],\ - 16384: ['100000000XXXXXXX','100000000XXXXXXX'],\ - 32768: ['100000000XXXXXXX','10000000XXXXXXXX'],\ - 65535: ['10000000XXXXXXXX','10000000XXXXXXXX'],\ - 131072: ['10000000XXXXXXXX','1000000XXXXXXXXX'],\ - 262144: ['1000000XXXXXXXXX','1000000XXXXXXXXX'],\ - 524280: ['1000000XXXXXXXXX','100000XXXXXXXXXX'],\ - 1048576:['100000XXXXXXXXXX','100000XXXXXXXXXX'],} - gensock.set_size(gencores,0,size) # This is setting the frame size - gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) - gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) - # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation - gensock.start(latcores) - for flow_number in flow_size_list: - attempts = 0 - gensock.reset_stats() - if sutsock!='none': - sutsock.reset_stats() - source_port,destination_port = flows[flow_number] - gensock.set_random(gencores,0,34,source_port,2) - gensock.set_random(gencores,0,36,destination_port,2) - endpps_sut_tx_str = 'NO_RESULTS' - maxspeed = speed = STARTSPEED - minspeed = 0 - while (maxspeed-minspeed > ACCURACY): - attempts += 1 - print(str(flow_number)+' flows: Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') - sys.stdout.flush() - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(speed / len(gencores), gencores) - time.sleep(1) - # Get statistics now that the generation is stable and initial ARP messages are dealt with - pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) - drop_rate = 100.0*abs_dropped/abs_tx - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): - log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) - endspeed = speed - endpps_req_tx = pps_req_tx - endpps_tx = pps_tx - endpps_sut_tx_str = pps_sut_tx_str - endpps_rx = pps_rx - endlat_avg = lat_avg - endlat_max = lat_max - endabs_dropped = abs_dropped - enddrop_rate = drop_rate - endwarning = lat_warning - success = True - else: - abs_drop_rate_prefix = bcolors.ENDC - if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): - abs_drop_rate_prefix = bcolors.FAIL - if (drop_rate < DROP_RATE_TRESHOLD): - drop_rate_prefix = bcolors.ENDC - else: - drop_rate_prefix = bcolors.FAIL - if (lat_avg< LAT_AVG_TRESHOLD): - lat_avg_prefix = bcolors.ENDC - else: - lat_avg_prefix = bcolors.FAIL - if (lat_max< LAT_MAX_TRESHOLD): - lat_max_prefix = bcolors.ENDC - else: - lat_max_prefix = bcolors.FAIL - if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): - speed_prefix = bcolors.ENDC - else: - speed_prefix = bcolors.FAIL - log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+lat_warning) - success = False - speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) - if endpps_sut_tx_str <> 'NO_RESULTS': - log.info('|{:>7}'.format(str(flow_number))+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+ '{:>9.0f}'.format(endlat_max)+' us | '+ '{:>14d}'.format(endabs_dropped)+ ' |'+'{:>9.2f}'.format(enddrop_rate)+ '% |'+endwarning) - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - writer.writerow({'flow':flow_number,'size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) - else: - log.info('|{:>7}'.format(str(flow_number))+" | Speed 0 or close to 0") - gensock.stop(latcores) - -def run_sizetest(gensock,sutsock): - log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") - log.info("| UDP, 1 flow, different packet sizes |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - log.info("| Pktsize| Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - gensock.start(latcores) - for size in packet_size_list: - size = size-4 - attempts = 0 - gensock.reset_stats() - if sutsock!='none': - sutsock.reset_stats() - gensock.set_size(gencores,0,size) # This is setting the frame size - gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) - gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) - # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation - endpps_sut_tx_str = 'NO_RESULTS' - maxspeed = speed = STARTSPEED - minspeed = 0 - while (maxspeed-minspeed > ACCURACY): - attempts += 1 - print(str(size+4)+' bytes: Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') - sys.stdout.flush() - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(speed / len(gencores), gencores) - # Get statistics now that the generation is stable and initial ARP messages are dealt with - pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) - drop_rate = 100.0*abs_dropped/abs_tx - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): - log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) - endspeed = speed - endpps_req_tx = pps_req_tx - endpps_tx = pps_tx - endpps_sut_tx_str = pps_sut_tx_str - endpps_rx = pps_rx - endlat_avg = lat_avg - endlat_max = lat_max - endabs_dropped = abs_dropped - enddrop_rate = drop_rate - endwarning = lat_warning - success = True - else: - abs_drop_rate_prefix = bcolors.ENDC - if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): - abs_drop_rate_prefix = bcolors.FAIL - if (drop_rate < DROP_RATE_TRESHOLD): - drop_rate_prefix = bcolors.ENDC - else: - drop_rate_prefix = bcolors.FAIL - if (lat_avg< LAT_AVG_TRESHOLD): - lat_avg_prefix = bcolors.ENDC - else: - lat_avg_prefix = bcolors.FAIL - if (lat_max< LAT_MAX_TRESHOLD): - lat_max_prefix = bcolors.ENDC - else: - lat_max_prefix = bcolors.FAIL - if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): - speed_prefix = bcolors.ENDC - else: - speed_prefix = bcolors.FAIL - log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+ lat_warning) - success = False - speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) - if endpps_sut_tx_str <> 'NO_RESULTS': - log.info('|{:>7}'.format(size+4)+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+'{:>9.0f}'.format(endlat_max)+' us | '+ '{:>14d}'.format(endabs_dropped)+ ' |'+'{:>9.2f}'.format(enddrop_rate)+ '% |'+ endwarning) - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - writer.writerow({'flow':'1','size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) - else: - log.debug('|{:>7}'.format(str(size))+" | Speed 0 or close to 0") - gensock.stop(latcores) - -def run_max_frame_rate(gensock,sutsock): - log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------+") - log.info("| UDP, 1 flow, different packet sizes |") - log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") - log.info("|Pktsz| Speed requested | Sent to NIC | Sent by Gen | Fwrd by SUT | Rec. by Gen | Avg. Latency| Max. Latency| Sent | Received | Lost | Total Lost |") - log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") - sleep_time = 3 - gensock.start(latcores) - for size in packet_size_list: - # Sleep_time is needed to be able to do accurate measurements to check for packet loss. We need to make this time large enough so that we do not take the first measurement while some packets from the previous tests migth still be in flight - time.sleep(sleep_time) - size = size-4 - gensock.reset_stats() - if sutsock!='none': - sutsock.reset_stats() - gensock.set_size(gencores,0,size) # This is setting the frame size - gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) - gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) - # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation - pps_sut_tx_str = 'NO_RESULTS' - speed = STARTSPEED - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(speed / len(gencores), gencores) - duration = float(runtime) - first = 1 - tot_drop = 0 - if sutsock!='none': - old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) - old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(genstatcores) - gensock.start(gencores) - while (duration > 0): - time.sleep(0.5) - lat_min, lat_max, lat_avg, lat_used = gensock.lat_stats(latcores) - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - # Get statistics after some execution time - new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) - if sutsock!='none': - new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) - drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM - rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM - tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface - tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. - if tsc == 0 : - continue - if sutsock!='none': - sut_rx = new_sut_rx - old_sut_rx - sut_tx = new_sut_tx - old_sut_tx - sut_tsc = new_sut_tsc - old_sut_tsc - if sut_tsc == 0 : - continue - duration = duration - 1 - old_drop = new_drop - old_rx = new_rx - old_tx = new_tx - old_tsc = new_tsc - pps_req_tx = (tx+drop-rx)*tsc_hz*1.0/(tsc*1000000) - pps_tx = tx*tsc_hz*1.0/(tsc*1000000) - pps_rx = rx*tsc_hz*1.0/(tsc*1000000) - if sutsock!='none': - old_sut_tx = new_sut_tx - old_sut_rx = new_sut_rx - old_sut_tsc= new_sut_tsc - pps_sut_tx = sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000) - pps_sut_tx_str = '{:>7.3f}'.format(pps_sut_tx) - else: - pps_sut_tx = 0 - pps_sut_tx_str = 'NO MEAS.' - if (tx == 0): - log.critical("TX = 0. Test interrupted since no packet has been sent.") - raise Exception("TX = 0") - tot_drop = tot_drop + tx - rx - - if pps_sut_tx_str <> 'NO_RESULTS': - # First second mpps are not valid as there is no alignement between time the generator is started and per seconds stats - if (first): - log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+' |' +' |' +' |'+ ' |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+'{:>7.0f}'.format(tot_drop) +' |'+lat_warning) - else: - log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+ '{:>7.3f}'.format(pps_req_tx)+' Mpps |'+ '{:>7.3f}'.format(pps_tx) +' Mpps |' + '{:>7}'.format(pps_sut_tx_str) +' Mpps |'+ '{:>7.3f}'.format(pps_rx)+' Mpps |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+ '{:>7.0f}'.format(tot_drop) +' |'+lat_warning) - else: - log.debug('|{:>7}'.format(str(size))+" | Speed 0 or close to 0") - first = 0 - if (duration <= 0): - #Stop generating - gensock.stop(gencores) - time.sleep(sleep_time) - lat_min, lat_max, lat_avg, lat_used = gensock.lat_stats(latcores) - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - # Get statistics after some execution time - new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) - if sutsock!='none': - new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) - drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM - rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM - tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface - tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. - tot_drop = tot_drop + tx - rx - if sutsock!='none': - sut_rx = new_sut_rx - old_sut_rx - sut_tx = new_sut_tx - old_sut_tx - sut_tsc = new_sut_tsc - old_sut_tsc - if pps_sut_tx_str <> 'NO_RESULTS': - log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+' |' +' |' +' |'+ ' |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+ '{:>7.0f}'.format(tot_drop) +' |'+lat_warning) - log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") - gensock.stop(latcores) - - - -def run_irqtest(sock): - log.info("+----------------------------------------------------------------------------------------------------------------------------") - log.info("| Measuring time probably spent dealing with an interrupt. Interrupting DPDK cores for more than 50us might be problematic ") - log.info("| and result in packet loss. The first row shows the interrupted time buckets: first number is the bucket between 0us and ") - log.info("| that number expressed in us and so on. The numbers in the other rows show how many times per second, the program was ") - log.info("| interrupted for a time as specified by its bucket. '0' is printed when there are no interrupts in this bucket throughout ") - log.info("| the duration of the test. This is to avoid rounding errors in the case of 0.0 ") - log.info("+----------------------------------------------------------------------------------------------------------------------------") - sys.stdout.flush() - buckets=sock.show_irq_buckets(1) - print('Measurement ongoing ... ',end='\r') - sock.stop(irqcores) - old_irq = [[0 for x in range(len(buckets)+1)] for y in range(len(irqcores)+1)] - irq = [[0 for x in range(len(buckets)+1)] for y in range(len(irqcores)+1)] - irq[0][0] = 'bucket us' - for j,bucket in enumerate(buckets,start=1): - irq[0][j] = '<'+ bucket - irq[0][-1] = '>'+ buckets [-2] - sock.start(irqcores) - time.sleep(2) - for j,bucket in enumerate(buckets,start=1): - for i,irqcore in enumerate(irqcores,start=1): - old_irq[i][j] = sock.irq_stats(irqcore,j-1) - time.sleep(float(runtime)) - sock.stop(irqcores) - for i,irqcore in enumerate(irqcores,start=1): - irq[i][0]='core %s '%irqcore - for j,bucket in enumerate(buckets,start=1): - diff = sock.irq_stats(irqcore,j-1) - old_irq[i][j] - if diff == 0: - irq[i][j] = '0' - else: - irq[i][j] = str(round(diff/float(runtime), 2)) - for row in irq: - log.info(''.join(['{:>12}'.format(item) for item in row])) -# log.info('\n'.join([''.join(['{:>12}'.format(item) for item in row]) for row in irq])) - -def run_impairtest(gensock,sutsock): - size=PACKETSIZE-4 - log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") - log.info("| Generator is sending UDP (1 flow) packets ("+ '{:>5}'.format(size+4) +" bytes) to SUT via GW dropping and delaying packets. SUT sends packets back. Use ctrl-c to stop the test |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - log.info("| Test | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") - log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") - attempts = 0 - gensock.set_size(gencores,0,size) # This is setting the frame size - gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) - gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) - # This will only work when using sending UDP packets. For different protocols and ethernet types, we would need a different calculation - gensock.start(latcores) - speed = STARTSPEED - gensock.speed(speed / len(gencores), gencores) - while True: - attempts += 1 - print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') - sys.stdout.flush() - time.sleep(1) - # Get statistics now that the generation is stable and NO ARP messages any more - pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) - drop_rate = 100.0*abs_dropped/abs_tx - if lat_used < 0.95: - lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC - else: - lat_warning = '' - log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% |'+lat_warning) - writer.writerow({'flow':'1','size':(size+4),'endspeed':speed,'endspeedpps':get_pps(speed,size),'endpps_req_tx':pps_req_tx,'endpps_tx':pps_tx,'endpps_sut_tx_str':pps_sut_tx_str,'endpps_rx':pps_rx,'endlat_avg':lat_avg,'endlat_max':lat_max,'endabs_dropped':abs_dropped,'enddrop_rate':drop_rate}) - gensock.stop(latcores) - -def run_inittest(gensock): -# Running at low speed to make sure the ARP messages can get through. -# If not doing this, the ARP message could be dropped by a switch in overload and then the test will not give proper results -# Note hoever that if we would run the test steps during a very long time, the ARP would expire in the switch. -# PROX will send a new ARP request every seconds so chances are very low that they will all fail to get through - gensock.speed(0.01 / len(gencores), gencores) - gensock.start(genstatcores) - time.sleep(2) - gensock.stop(genstatcores) - -global sutstatcores -global genstatcores -global latcores -global gencores -global irqcores -global PACKETSIZE -global packet_size_list -global flow_size_list -global required_number_of_test_machines -clients =[] -socks =[] -socks_control =[] -vmDPIP =[] -vmAdminIP =[] -vmDPmac =[] -hexDPIP =[] -config_file =[] -prox_socket =[] -prox_launch_exit =[] -auto_start =[] -mach_type =[] -sock_type =[] - -data_file = 'RUN{}.{}.csv'.format(env,test) -data_csv_file = open(data_file,'w') -testconfig = ConfigParser.RawConfigParser() -testconfig.read(test+'.test') -required_number_of_test_machines = testconfig.get('DEFAULT', 'total_number_of_test_machines') -config = ConfigParser.RawConfigParser() -config.read(env+'.env') -machine_map = ConfigParser.RawConfigParser() -machine_map.read(machine_map_file +'.cfg') -key = config.get('OpenStack', 'key') -total_number_of_machines = config.get('rapid', 'total_number_of_machines') -if int(required_number_of_test_machines) > int(total_number_of_machines): - log.exception("Not enough VMs for this test: %s needed and only %s available" % (required_number_of_test_machines,total_number_of_machines)) - raise Exception("Not enough VMs for this test: %s needed and only %s available" % (required_number_of_test_machines,total_number_of_machines)) -for vm in range(1, int(total_number_of_machines)+1): - vmAdminIP.append(config.get('M%d'%vm, 'admin_ip')) - vmDPmac.append(config.get('M%d'%vm, 'dp_mac')) - vmDPIP.append(config.get('M%d'%vm, 'dp_ip')) - ip = vmDPIP[-1].split('.') - hexDPIP.append(hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2)) -machine_index = [] -for vm in range(1, int(required_number_of_test_machines)+1): - machine_index.append(int(machine_map.get('TestM%d'%vm, 'machine_index'))-1) - prox_socket.append(testconfig.getboolean('TestM%d'%vm, 'prox_socket')) -for vm in range(1, int(required_number_of_test_machines)+1): - if prox_socket[vm-1]: - prox_launch_exit.append(testconfig.getboolean('TestM%d'%vm, 'prox_launch_exit')) - config_file.append(testconfig.get('TestM%d'%vm, 'config_file')) - with open('{}_{}_parameters{}.lua'.format(env,test,vm), "w") as f: - f.write('name="%s"\n'% testconfig.get('TestM%d'%vm, 'name')) - f.write('local_ip="%s"\n'% vmDPIP[machine_index[vm-1]]) - f.write('local_hex_ip="%s"\n'% hexDPIP[machine_index[vm-1]]) - if re.match('(l2){0,1}gen\.cfg',config_file[-1]): - gencores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'gencores')) - latcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'latcores')) - STARTSPEED = float(testconfig.get('TestM%d'%vm, 'startspeed')) - genstatcores = gencores + latcores - auto_start.append(False) - mach_type.append('gen') - f.write('gencores="%s"\n'% ','.join(map(str, gencores))) - f.write('latcores="%s"\n'% ','.join(map(str, latcores))) - destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 - f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) - f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) - f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) - elif re.match('(l2){0,1}gen_gw\.cfg',config_file[-1]): - gencores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'gencores')) - latcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'latcores')) - STARTSPEED = float(testconfig.get('TestM%d'%vm, 'startspeed')) - genstatcores = gencores + latcores - auto_start.append(False) - mach_type.append('gen') - f.write('gencores="%s"\n'% ','.join(map(str, gencores))) - f.write('latcores="%s"\n'% ','.join(map(str, latcores))) - gwVMindex = int(testconfig.get('TestM%d'%vm, 'gw_vm')) -1 - f.write('gw_ip="%s"\n'% vmDPIP[machine_index[gwVMindex]]) - f.write('gw_hex_ip="%s"\n'% hexDPIP[machine_index[gwVMindex]]) - destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 - f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) - f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) - f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) - elif re.match('(l2){0,1}swap.*\.cfg',config_file[-1]): - sutstatcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'swapcores')) - auto_start.append(True) - mach_type.append('sut') - f.write('swapcores="%s"\n'% ','.join(map(str, sutstatcores))) - elif config_file[-1] == 'secgw1.cfg': - auto_start.append(True) - mach_type.append('none') - f.write('secgwcores="%s"\n'% ','.join(map(str, ast.literal_eval(testconfig.get('TestM%d'%vm, 'secgwcores'))))) - destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 - f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) - f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) - f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) - elif config_file[-1] == 'secgw2.cfg': - sutstatcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'secgwcores')) - auto_start.append(True) - mach_type.append('sut') - f.write('secgwcores="%s"\n'% ','.join(map(str, sutstatcores))) - elif config_file[-1] == 'impair.cfg': - auto_start.append(True) - mach_type.append('none') - f.write('impaircores="%s"\n'% ','.join(map(str, ast.literal_eval(testconfig.get('TestM%d'%vm, 'impaircores'))))) - elif config_file[-1] == 'irq.cfg': - irqcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'irqcores')) - auto_start.append(False) - mach_type.append('irq') - f.write('irqcores="%s"\n'% ','.join(map(str, irqcores))) - f.close -##################################################################################### -def exit_handler(): - log.debug ('exit cleanup') - for index, sock in enumerate(socks): - if socks_control[index]: - sock.quit() - for client in clients: - client.close() - data_csv_file.close - sys.exit(0) - -atexit.register(exit_handler) - -for vm in range(0, int(required_number_of_test_machines)): - if prox_socket[vm]: - clients.append(prox_ctrl(vmAdminIP[machine_index[vm]], key+'.pem','root')) - connect_client(clients[-1]) -# Creating script to bind the right network interface to the poll mode driver - devbindfile = '{}_{}_devbindvm{}.sh'.format(env,test, vm+1) - with open("devbind.sh") as f: - newText=f.read().replace('MACADDRESS', vmDPmac[machine_index[vm]]) - with open(devbindfile, "w") as f: - f.write(newText) - st = os.stat(devbindfile) - os.chmod(devbindfile, st.st_mode | stat.S_IEXEC) - clients[-1].scp_put('./%s'%devbindfile, '/root/devbind.sh') - cmd = '/root/devbind.sh' - clients[-1].run_cmd(cmd) - log.debug("devbind.sh running on VM%d"%(vm+1)) - clients[-1].scp_put('./%s'%config_file[vm], '/root/%s'%config_file[vm]) - clients[-1].scp_put('./{}_{}_parameters{}.lua'.format(env,test, vm+1), '/root/parameters.lua') - if not configonly: - if prox_launch_exit[vm]: - log.debug("Starting PROX on VM%d"%(vm+1)) - if auto_start[vm]: - cmd = '/root/prox/build/prox -t -o cli -f /root/%s'%config_file[vm] - else: - cmd = '/root/prox/build/prox -e -t -o cli -f /root/%s'%config_file[vm] - clients[-1].fork_cmd(cmd, 'PROX Testing on TestM%d'%(vm+1)) - socks_control.append(prox_launch_exit[vm]) - socks.append(connect_socket(clients[-1])) - sock_type.append(mach_type[vm]) -socks.append('none') -socks_control.append(False) - -def get_BinarySearchParams() : - global DROP_RATE_TRESHOLD - global LAT_AVG_TRESHOLD - global LAT_MAX_TRESHOLD - global ACCURACY - global STARTSPEED - DROP_RATE_TRESHOLD = float(testconfig.get('BinarySearchParams', 'drop_rate_threshold')) - LAT_AVG_TRESHOLD = float(testconfig.get('BinarySearchParams', 'lat_avg_threshold')) - LAT_MAX_TRESHOLD = float(testconfig.get('BinarySearchParams', 'lat_max_threshold')) - ACCURACY = float(testconfig.get('BinarySearchParams', 'accuracy')) - -if configonly: - sys.exit() -#################################################### -# Run test cases -# Best to run the flow test at the end since otherwise the tests coming after might be influenced by the big number of entries in the switch flow tables -#################################################### -gensock_index = sock_type.index('gen') if 'gen' in sock_type else -1 -sutsock_index = sock_type.index('sut') if 'sut' in sock_type else -1 -irqsock_index = sock_type.index('irq') if 'irq' in sock_type else -1 -number_of_tests = testconfig.get('DEFAULT', 'number_of_tests') -with data_csv_file: - fieldnames = ['flow','size','endspeed','endspeedpps','endpps_req_tx','endpps_tx','endpps_sut_tx_str','endpps_rx','endlat_avg','endlat_max','endabs_dropped','enddrop_rate'] - writer = csv.DictWriter(data_csv_file, fieldnames=fieldnames) - writer.writeheader() - for test_nr in range(1, int(number_of_tests)+1): - test=testconfig.get('test%d'%test_nr,'test') - log.info(test) - if test == 'speedtest': - get_BinarySearchParams() - PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) - run_speedtest(socks[gensock_index],socks[sutsock_index]) - elif test == 'flowtest': - get_BinarySearchParams() - PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) - flow_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'flows')) - run_flowtest(socks[gensock_index],socks[sutsock_index]) - elif test == 'sizetest': - get_BinarySearchParams() - packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes')) - run_sizetest(socks[gensock_index],socks[sutsock_index]) - elif test == 'max_frame_rate': -# PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) - packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes')) - run_max_frame_rate(socks[gensock_index],socks[sutsock_index]) - elif test == 'impairtest': - get_BinarySearchParams() - PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) - run_impairtest(socks[gensock_index],socks[sutsock_index]) - elif test == 'irqtest': - run_irqtest(socks[irqsock_index]) - elif test == 'inittest': - run_inittest(socks[gensock_index]) -#################################################### diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw.test b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw.test deleted file mode 100644 index cf1b5522..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw.test +++ /dev/null @@ -1,55 +0,0 @@ -## -## Copyright (c) 2010-2018 Intel Corporation -## -## 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. -## - -[DEFAULT] -name = GWTesting -number_of_tests = 2 -total_number_of_test_machines = 3 -prox_socket = true -prox_launch_exit = true - -[TestM1] -name = Generator -config_file = gen_gw.cfg -dest_vm = 3 -gw_vm = 2 -gencores = [1] -latcores = [3] -startspeed = 10 - -[TestM2] -name = GW1 -config_file = secgw1.cfg -dest_vm = 3 -secgwcores = [1] - -[TestM3] -name = GW2 -config_file = secgw2.cfg -secgwcores = [1] - -[BinarySearchParams] -drop_rate_threshold = 0.1 -lat_avg_threshold = 500 -lat_max_threshold = 1000 -accuracy = 0.1 - -[test1] -test=inittest - -[test2] -test=speedtest -packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw1.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw1.cfg deleted file mode 100644 index 301a138e..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw1.cfg +++ /dev/null @@ -1,54 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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 is sample ESP config. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=if -mac=hardware - -[variables] -$tun_hop_limit=5 -$lookup_port_mask=0xffc0 - -[defaults] -mempool size=16K - -[global] -start time=20 -name=${name} - -[core 0] -mode=master - -[core $secgwcores] -name=esp_enc -task=0 -mode=esp_enc -sub mode=l3 -local ipv4=${local_ip} -remote ipv4=${dest_ip} -rx port=if -tx port=if diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw2.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw2.cfg deleted file mode 100644 index 9c970e83..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw2.cfg +++ /dev/null @@ -1,55 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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 is sample ESP config. -;; -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=if -mac=hardware - -[variables] -$tun_hop_limit=5 -$lookup_port_mask=0xffc0 - -[defaults] -mempool size=16K - -[global] -start time=20 -name=${name} - -[core 0] -mode=master - -[core $secgwcores] -name=esp_dec -task=0 -mode=esp_dec -sub mode=l3 -local ipv4=${local_ip} -rx port=if -tx port=if - - - diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/swap.cfg b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/swap.cfg deleted file mode 100644 index 47cb0b07..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/swap.cfg +++ /dev/null @@ -1,46 +0,0 @@ -;; -;; Copyright (c) 2010-2017 Intel Corporation -;; -;; 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. -;; - -[eal options] --n=4 ; force number of memory channels -no-output=no ; disable DPDK debug output - -[lua] -dofile("parameters.lua") - -[port 0] -name=if0 -mac=hardware - -[defaults] -mempool size=2K - -[global] -name=${name} - -[core 0] -mode=master - -[core $swapcores] -name=swap -task=0 -mode=swap -sub mode=l3 -rx port=if0 -tx port=if0 -local ipv4=${local_ip} -drop=no -;arp update time=1 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg new file mode 100644 index 00000000..b6e199d7 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg @@ -0,0 +1,30 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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 contains the mapping for each test machine. The test machine will +## be deployed on a machine defined in the *.env file, as defined by the +## machine_index + +[DEFAULT] +machine_index=0 + +[TestM1] +machine_index=1 + +[TestM2] +machine_index=2 + +[TestM3] +machine_index=3 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/README b/VNFs/DPPD-PROX/helper-scripts/rapid/README new file mode 100644 index 00000000..43243a6c --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/README @@ -0,0 +1,149 @@ +## +## Copyright (c) 2010-2017 Intel Corporation +## +## 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. +## + +rapid (Rapid Automated Performance Indication for Dataplane) +************************************************************ + +rapid is a set of files offering an easy way to do a sanity check of the +dataplane performance of an OpenStack environment. + +Copy the files in a directory on a machine that can run the OpenStack CLI +commands and that can reach the OpenStack networks to connect to the VMs. + +You will need an image that has the PROX tool installed. +A good way to do this is to use the packer tool to build an image for a target of your choice. +You can also build this image manually by executing all the commands described in the deploycentos.sh. +The default name of the qcow2 file is rapidVM.qcow2 + +When using the packer tool, the first step is to upload an +existing CentOS cloud image from the internet into OpenStack. +Check out: https://cloud.centos.org/centos/7/images/ +You should now source the proper .rc file so Packer can connect to your OpenStack. +There are 2 files: centos.json and deploycentos.sh, allowing you to create +an image automatically. Run + # packer build centos.json +Edit centos.json to reflect the settings of your environment: The following fields need to +be the ID's of your system: + - "source_image": Needs to be the id of the Centos cloud image + - "flavor": Needs to be the ID of the flavor existing in your OpenStack environment that will be used + to start the VM in which we will install all tools + - "networks": ID of the network that will be used for the VM + - "use_floating_ip": true or false + - "floating_ip_pool": ID of the floating ip pool in case floating ip are being used + - "security_groups": ID of the security group being used + +Note that this procedure is not only installing the necessary tools to run PROX, +but also does some system optimizations (tuned). Check deploycentos.sh for more details. + +Now you can run the createrapid.py file. Use help for more info on the usage: + # ./createrapid.py --help + +createrapid.py will use the OpenStack CLI to create the flavor, key-pair, network, image, +servers, ... +It will create a .env file containing all info that will be used by runrapid.py +to actually run the tests. Logging can be found in the CREATE.log file +You can use floating IP addresses by specifying the floating IP network +--floating_network NETWORK +or directly connect through the INTERNAL_NETWORK by using the following parameter: +--floating_network NO +/etc/resolv.conf will contain DNS info from the "best" interface. Since we are +deploying VMs with multiple interface on different networks, this info might be +taken from the "wrong" network (e.g. the dataplane network). + +Now you can run the runrapid.py file. Use help for more info on the usage: + # ./runrapid.py --help +The script will connect to all machines that have been instantiated and it will launch +PROX in all machines. This will be done through the admin IP assigned to the machines. +Once that is done it will connect to the PROX tcp socket and start sending +commands to run the actual test. +Make sure the security groups allow for tcp access (ssh & prox port). +It will print test results on the screen while running. +The actual test that is running is described in .test. + +Notes about prox_user_data.sh script: +- The script contains commands that will be executed using cloud-init at + startup of the VMs. +- huge pages are allocated for DPDK on node 0 (hard-coded) in the VM. + +Note on using SRIOV ports: +Before running createrapid, make sure the network, subnet and ports are already created +This can be done as follows (change the parameters to your needs): +openstack network create --share --external --provider-network-type flat --provider-physical-network physnet2 fast-network +openstack subnet create --network fast-network --subnet-range 20.20.20.0/24 --gateway none fast-subnet +openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port1 +openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port2 +openstack port create --network fast-network --vnic-type direct --fixed-ip subnet=fast-subnet Port3 +Make sure to use the network and subnet in the createrapid parameters list. Port1, Port2 and Port3 +are being used in the *.env file. + +Note when doing tests using the gateway functionality on OVS: +When a GW VM is sending packets on behalf of another VM (e.g. the generator), we need to make sure the OVS +will allow those packets to go through. Therefore you need to the IP address of the generator in the +"allowed address pairs" of the GW VM. + +Note when doing tests using encryption on OVS: +Your OVS configuration might block encrypted packets. To allow packets to go through, +you can disable port_security. You can do this by using the following commands +neutron port-update xxxxxx --no-security-groups +neutron port-update xxxxxx --port_security_enabled=False + +An example of the env file generated by createrapid.py can be found below. +Note that this file can be created manually in case the stack is created in a +different way (not using the createrapid.py). This can be useful in case you are +not using OpenStack as a VIM or when using special configurations that cannot be +achieved using createrapid.py. Fields needed for runrapid are: +* all info in the [Mx] sections +* the key information in the [OpenStack] section +* the total_number_of_vms information in the [rapid] section + +[DEFAULT] +admin_ip = none + +[M1] +name = rapid-VM1 +admin_ip = 10.25.1.116 +dp_ip = 10.10.10.7 +dp_mac = fa:16:3e:59:b8:28 + +[M2] +name = rapid-VM2 +admin_ip = 10.25.1.126 +dp_ip = 10.10.10.11 +dp_mac = fa:16:3e:c9:54:c7 + +[M3] +name = rapid-VM3 +admin_ip = 10.25.1.108 +dp_ip = 10.10.10.15 +dp_mac = fa:16:3e:72:90:3e + +[OpenStack] +stack = rapid +vms = rapidVMs +key = prox +image = rapidVM +image_file = rapidVM.qcow2 +dataplane_network = dataplane-network +subnet = dpdk-subnet +subnet_cidr = 10.10.10.0/24 +internal_network = admin_internal_net +floating_network = floating-ip-net + +[rapid] +loglevel = DEBUG +version = 19.4.15 +total_number_of_machines = 3 + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test b/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test new file mode 100644 index 00000000..b2f8f230 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test @@ -0,0 +1,60 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = BasicSwapTesting +number_of_tests = 4 +total_number_of_test_machines = 2 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = gen.cfg +dest_vm = 2 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = Swap +config_file = swap.cfg +swapcores = [1] + +[BinarySearchParams] +drop_rate_threshold = 0.1 +lat_avg_threshold = 500 +lat_max_threshold = 1000 +accuracy = 0.1 + +[test1] +test=inittest + +[test2] +test=speedtest +packetsize=64 + +[test3] +test=sizetest +flow=1 +packetsizes=[64,256,1024] + +[test4] +test=flowtest +packetsize=64 +# the number of flows in the list need to be powers of 2, max 2^20 +# Select from following numbers: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65535, 131072, 262144, 524280, 1048576 +flows=[1,512,1024] diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json b/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json new file mode 100644 index 00000000..237a6483 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json @@ -0,0 +1,33 @@ +{ +"_Copyright": "Copyright (c) 2010-2018 Intel Corporation", +"_License": "SPDX-License-Identifier: Apache-2.0", +"builders": [ + { +"type": "openstack", +"ssh_username": "centos", +"image_name": "rapidVM", +"source_image": "06101dd4-f162-49c0-a072-2fe32ac446a9", +"flavor": "3ea20ea9-855c-4a6e-b454-63ad6e8e0db9", +"networks": "451a030a-eb1e-4c74-85b8-782ef8a6ad38", +"use_floating_ip": true, +"floating_ip_pool": "d629619f-8f96-4f32-9b90-1b62e5ea3809", +"security_groups": "460b7929-c6de-4b1c-ae83-901c2042a894" + } +], +"provisioners": [ + { + "type": "file", + "source": "./check_prox_system_setup.sh", + "destination": "/home/centos/" + }, + { + "type": "file", + "source": "./check-prox-system-setup.service", + "destination": "/home/centos/" + }, + { + "type": "shell", + "script": "deploycentos.sh" + } +] +} diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service b/VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service new file mode 100644 index 00000000..a55e0c08 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service @@ -0,0 +1,11 @@ +[Unit] +Description=Check PROX system setup (isolated_cores, uio) +DefaultDependencies=no +After=multi-user.target + +[Service] +Type=oneshot +ExecStart=/usr/local/libexec/check_prox_system_setup.sh + +[Install] +WantedBy=multi-user.target diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh b/VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh new file mode 100755 index 00000000..48999510 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## +NCPUS="$(lscpu | egrep '^CPU\(s\):' | awk '{ print $2 }')" +MAXCOREID="$((NCPUS-1))" + +filename="/etc/tuned/realtime-virtual-guest-variables.conf" +logfile="/home/centos/prox_system_setup.log" +if [ -f "$filename" ] +then + while read -r line + do + case $line in + isolated_cores=1-$MAXCOREID*) + echo "Isolated CPU(s) OK, no reboot: $line">>$logfile + modprobe uio + insmod /root/dpdk/build/kmod/igb_uio.ko + exit 0 + ;; + isolated_cores=*) + echo "Isolated CPU(s) NOK, change the config and reboot: $line">>$logfile + sed -i "/^isolated_cores=.*/c\isolated_cores=1-$MAXCOREID" $filename + tuned-adm profile realtime-virtual-guest + reboot + exit 0 + ;; + *) + echo "$line" + ;; + esac + done < "$filename" + echo "isolated_cores=1-$MAXCOREID" >> $filename + echo "No Isolated CPU(s) defined in config, line added: $line">>$logfile + tuned-adm profile realtime-virtual-guest + reboot +else + echo "$filename not found.">>$logfile +fi diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py b/VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py new file mode 100755 index 00000000..a1c1de60 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py @@ -0,0 +1,418 @@ +#!/usr/bin/python + +## +## Copyright (c) 2010-2017 Intel Corporation +## +## 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. +## + +from __future__ import print_function + +import os +import stat +import sys +import time +import subprocess +import getopt +import re +import logging +from logging.handlers import RotatingFileHandler +from logging import handlers +from prox_ctrl import prox_ctrl +import ConfigParser + +version="19.4.15" +stack = "rapid" #Default string for stack. This is not an OpenStack Heat stack, just a group of VMs +vms = "rapidVMs" #Default string for vms file +key = "prox" # default name for kay +image = "rapidVM" # default name for the image +image_file = "rapidVM.qcow2" +dataplane_network = "dataplane-network" # default name for the dataplane network +subnet = "dpdk-subnet" #subnet for dataplane +subnet_cidr="10.10.10.0/24" # cidr for dataplane +internal_network="admin_internal_net" +floating_network="admin_floating_net" +loglevel="DEBUG" # sets log level for writing to file +runtime=10 # time in seconds for 1 test run + +def usage(): + print("usage: createrapid [--version] [-v]") + print(" [--stack STACK_NAME]") + print(" [--vms VMS_FILE]") + print(" [--key KEY_NAME]") + print(" [--image IMAGE_NAME]") + print(" [--image_file IMAGE_FILE]") + print(" [--dataplane_network DP_NETWORK]") + print(" [--subnet DP_SUBNET]") + print(" [--subnet_cidr SUBNET_CIDR]") + print(" [--internal_network ADMIN_NETWORK]") + print(" [--floating_network FLOATING_NETWORK]") + print(" [--log DEBUG|INFO|WARNING|ERROR|CRITICAL]") + print(" [-h] [--help]") + print("") + print("Command-line interface to createrapid") + print("") + print("optional arguments:") + print(" -v, --version Show program's version number and exit") + print(" --stack STACK_NAME Specify a name for the stack. Default is %s."%stack) + print(" --vms VMS_FILE Specify the vms file to be used. Default is %s.vms."%vms) + print(" --key KEY_NAME Specify the key to be used. Default is %s."%key) + print(" --image IMAGE_NAME Specify the image to be used. Default is %s."%image) + print(" --image_file IMAGE_FILE Specify the image qcow2 file to be used. Default is %s."%image_file) + print(" --dataplane_network NETWORK Specify the network name to be used for the dataplane. Default is %s."%dataplane_network) + print(" --subnet DP_SUBNET Specify the subnet name to be used for the dataplane. Default is %s."%subnet) + print(" --subnet_cidr SUBNET_CIDR Specify the subnet CIDR to be used for the dataplane. Default is %s."%subnet_cidr) + print(" --internal_network NETWORK Specify the network name to be used for the control plane. Default is %s."%internal_network) + print(" --floating_network NETWORK Specify the external floating ip network name. Default is %s. NO if no floating ip used."%floating_network) + print(" --log Specify logging level for log file output, screen output level is hard coded") + print(" -h, --help Show help message and exit.") + print("") + +try: + opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "vms=","stack=","key=","image=","image_file=","dataplane_network=","subnet=","subnet_cidr=","internal_network=","floating_network=","log="]) +except getopt.GetoptError as err: + print("===========================================") + print(str(err)) + print("===========================================") + usage() + sys.exit(2) +if args: + usage() + sys.exit(2) +for opt, arg in opts: + if opt in ("-h", "--help"): + usage() + sys.exit() + if opt in ("-v", "--version"): + print("Rapid Automated Performance Indication for Dataplane "+version) + sys.exit() + if opt in ("--stack"): + stack = arg + print ("Using '"+stack+"' as name for the stack") + elif opt in ("--vms"): + vms = arg + print ("Using Virtual Machines Description: "+vms) + elif opt in ("--key"): + key = arg + print ("Using key: "+key) + elif opt in ("--image"): + image = arg + print ("Using image: "+image) + elif opt in ("--image_file"): + image_file = arg + print ("Using qcow2 file: "+image_file) + elif opt in ("--dataplane_network"): + dataplane_network = arg + print ("Using dataplane network: "+ dataplane_network) + elif opt in ("--subnet"): + subnet = arg + print ("Using dataplane subnet: "+ subnet) + elif opt in ("--subnet_cidr"): + subnet_cidr = arg + print ("Using dataplane subnet: "+ subnet_cidr) + elif opt in ("--internal_network"): + internal_network = arg + print ("Using control plane network: "+ internal_network) + elif opt in ("--floating_network"): + floating_network = arg + print ("Using floating ip network: "+ floating_network) + elif opt in ("--log"): + loglevel = arg + print ("Log level: "+ loglevel) + + +# create formatters +screen_formatter = logging.Formatter("%(message)s") +file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") + +# get a top-level logger, +# set its log level, +# BUT PREVENT IT from propagating messages to the root logger +# +log = logging.getLogger() +numeric_level = getattr(logging, loglevel.upper(), None) +if not isinstance(numeric_level, int): + raise ValueError('Invalid log level: %s' % loglevel) +log.setLevel(numeric_level) +log.propagate = 0 + +# create a console handler +# and set its log level to the command-line option +# +console_handler = logging.StreamHandler(sys.stdout) +console_handler.setLevel(logging.INFO) +console_handler.setFormatter(screen_formatter) + +# create a file handler +# and set its log level to DEBUG +# +log_file = 'CREATE' +stack +'.log' +file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10) +#file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5) +file_handler.setLevel(numeric_level) +file_handler.setFormatter(file_formatter) + +# add handlers to the logger +# +log.addHandler(file_handler) +log.addHandler(console_handler) + +# Check if log exists and should therefore be rolled +needRoll = os.path.isfile(log_file) + + +# This is a stale log, so roll it +if needRoll: + # Add timestamp + log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime()) + + # Roll over on application start + log.handlers[0].doRollover() + +# Add timestamp +log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime()) + +log.debug("createrapid.py version: "+version) +# Checking if the control network already exists, if not, stop the script +log.debug("Checking control plane network: "+internal_network) +cmd = 'openstack network show '+internal_network +log.debug (cmd) +cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' +NetworkExist = subprocess.check_output(cmd , shell=True).strip() +if NetworkExist == 'ACTIVE': + log.info("Control plane network ("+internal_network+") already active") +else: + log.exception("Control plane network " + internal_network + " not existing") + raise Exception("Control plane network " + internal_network + " not existing") + +# Checking if the floating ip network already exists, if not, stop the script +if floating_network <>'NO': + log.debug("Checking floating ip network: "+floating_network) + cmd = 'openstack network show '+floating_network + log.debug (cmd) + cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' + NetworkExist = subprocess.check_output(cmd , shell=True).strip() + if NetworkExist == 'ACTIVE': + log.info("Floating ip network ("+floating_network+") already active") + else: + log.exception("Floating ip network " + floating_network + " not existing") + raise Exception("Floating ip network " + floating_network + " not existing") + +# Checking if the image already exists, if not create it +log.debug("Checking image: "+image) +cmd = 'openstack image show '+image +log.debug(cmd) +cmd = cmd +' |grep "status " | tr -s " " | cut -d" " -f 4' +ImageExist = subprocess.check_output(cmd , shell=True).strip() +if ImageExist == 'active': + log.info("Image ("+image+") already available") +else: + log.info('Creating image ...') + cmd = 'openstack image create --disk-format qcow2 --container-format bare --public --file ./'+image_file+ ' ' +image + log.debug(cmd) + cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' + ImageExist = subprocess.check_output(cmd , shell=True).strip() + if ImageExist == 'active': + log.info('Image created and active') + cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image +# subprocess.check_call(cmd , shell=True) + else : + log.exception("Failed to create image") + raise Exception("Failed to create image") + +# Checking if the key already exists, if not create it +log.debug("Checking key: "+key) +cmd = 'openstack keypair show '+key +log.debug (cmd) +cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4' +KeyExist = subprocess.check_output(cmd , shell=True).strip() +if KeyExist == key: + log.info("Key ("+key+") already installed") +else: + log.info('Creating key ...') + cmd = 'openstack keypair create '+ key + '>' +key+'.pem' + log.debug(cmd) + subprocess.check_call(cmd , shell=True) + cmd = 'chmod 600 ' +key+'.pem' + subprocess.check_call(cmd , shell=True) + cmd = 'openstack keypair show '+key + log.debug(cmd) + cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4' + KeyExist = subprocess.check_output(cmd , shell=True).strip() + if KeyExist == key: + log.info("Key created") + else : + log.exception("Failed to create key: " + key) + raise Exception("Failed to create key: " + key) + + +# Checking if the dataplane network already exists, if not create it +log.debug("Checking dataplane network: "+dataplane_network) +cmd = 'openstack network show '+dataplane_network +log.debug (cmd) +cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' +NetworkExist = subprocess.check_output(cmd , shell=True).strip() +if NetworkExist == 'ACTIVE': + log.info("Dataplane network ("+dataplane_network+") already active") +else: + log.info('Creating dataplane network ...') + cmd = 'openstack network create '+dataplane_network + log.debug(cmd) + cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4' + NetworkExist = subprocess.check_output(cmd , shell=True).strip() + if NetworkExist == 'ACTIVE': + log.info("Dataplane network created") + else : + log.exception("Failed to create dataplane network: " + dataplane_network) + raise Exception("Failed to create dataplane network: " + dataplane_network) + +# Checking if the dataplane subnet already exists, if not create it +log.debug("Checking subnet: "+subnet) +cmd = 'openstack subnet show '+ subnet +log.debug (cmd) +cmd = cmd +' |grep "name " | tr -s " " | cut -d"|" -f 3' +SubnetExist = subprocess.check_output(cmd , shell=True).strip() +if SubnetExist == subnet: + log.info("Subnet (" +subnet+ ") already exists") +else: + log.info('Creating subnet ...') + cmd = 'openstack subnet create --network ' + dataplane_network + ' --subnet-range ' + subnet_cidr +' --gateway none ' + subnet + log.debug(cmd) + cmd = cmd + ' |grep "name " | tr -s " " | cut -d"|" -f 3' + SubnetExist = subprocess.check_output(cmd , shell=True).strip() + if SubnetExist == subnet: + log.info("Subnet created") + else : + log.exception("Failed to create subnet: " + subnet) + raise Exception("Failed to create subnet: " + subnet) + +ServerToBeCreated=[] +ServerName=[] +config = ConfigParser.RawConfigParser() +vmconfig = ConfigParser.RawConfigParser() +vmconfig.read(vms+'.vms') +total_number_of_VMs = vmconfig.get('DEFAULT', 'total_number_of_vms') +for vm in range(1, int(total_number_of_VMs)+1): + flavor_info = vmconfig.get('VM%d'%vm, 'flavor_info') + flavor_meta_data = vmconfig.get('VM%d'%vm, 'flavor_meta_data') + boot_info = vmconfig.get('VM%d'%vm, 'boot_info') + SRIOV_port = vmconfig.get('VM%d'%vm, 'SRIOV_port') + ServerName.append('%s-VM%d'%(stack,vm)) + flavor_name = '%s-VM%d-flavor'%(stack,vm) + log.debug("Checking server: "+ServerName[-1]) + cmd = 'openstack server show '+ServerName[-1] + log.debug (cmd) + cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' + ServerExist = subprocess.check_output(cmd , shell=True).strip() + if ServerExist == ServerName[-1]: + log.info("Server ("+ServerName[-1]+") already active") + ServerToBeCreated.append("no") + else: + ServerToBeCreated.append("yes") + # Checking if the flavor already exists, if not create it + log.debug("Checking flavor: "+flavor_name) + cmd = 'openstack flavor show '+flavor_name + log.debug (cmd) + cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' + FlavorExist = subprocess.check_output(cmd , shell=True).strip() + if FlavorExist == flavor_name: + log.info("Flavor ("+flavor_name+") already installed") + else: + log.info('Creating flavor ...') + cmd = 'openstack flavor create %s %s'%(flavor_name,flavor_info) + log.debug(cmd) + cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' + FlavorExist = subprocess.check_output(cmd , shell=True).strip() + if FlavorExist == flavor_name: + cmd = 'openstack flavor set %s %s'%(flavor_name, flavor_meta_data) + log.debug(cmd) + subprocess.check_call(cmd , shell=True) + log.info("Flavor created") + else : + log.exception("Failed to create flavor: " + flavor_name) + raise Exception("Failed to create flavor: " + flavor_name) + if SRIOV_port == 'NO': + nic_info = '--nic net-id=%s --nic net-id=%s'%(internal_network,dataplane_network) + else: + nic_info = '--nic net-id=%s'%(internal_network) + for port in SRIOV_port.split(','): + nic_info = nic_info + ' --nic port-id=%s'%(port) + if vm==int(total_number_of_VMs): + # For the last server, we want to wait for the server creation to complete, so the next operations will succeeed (e.g. IP allocation) + # Note that this waiting is not bullet proof. Imagine, we loop through all the VMs, and the last VM was already running, while the previous + # VMs still needed to be created. Or the previous server creations take much longer than the last one. + # In that case, we might be to fast when we query for the IP & MAC addresses. + wait = ' --wait ' + else: + wait = ' ' + log.info("Creating server...") + cmd = 'openstack server create --flavor %s --key-name %s --image %s %s %s%s%s'%(flavor_name,key,image,nic_info,boot_info,wait,ServerName[-1]) + log.debug(cmd) + cmd = cmd + ' |grep "\sname\s" | tr -s " " | cut -d" " -f 4' + ServerExist = subprocess.check_output(cmd , shell=True).strip() +if floating_network <> 'NO': + for vm in range(0, int(total_number_of_VMs)): + if ServerToBeCreated[vm] =="yes": + log.info('Creating & Associating floating IP for ('+ServerName[vm]+')...') + cmd = 'openstack server show %s -c addresses -f value |grep -Eo "%s=[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | cut -d"=" -f2'%(ServerName[vm],internal_network) + log.debug(cmd) + vmportIP = subprocess.check_output(cmd , shell=True).strip() + cmd = 'openstack port list -c ID -c "Fixed IP Addresses" | grep %s' %(vmportIP) + cmd = cmd + ' | cut -d" " -f 2 ' + log.debug(cmd) + vmportID = subprocess.check_output(cmd , shell=True).strip() + cmd = 'openstack floating ip create --port %s %s'%(vmportID,floating_network) + log.debug(cmd) + output = subprocess.check_output(cmd , shell=True).strip() + +for vm in range(1, int(total_number_of_VMs)+1): + cmd = 'openstack server show %s'%(ServerName[vm-1]) + log.debug(cmd) + output = subprocess.check_output(cmd , shell=True).strip() + searchString = '.*%s=([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)' %(dataplane_network) + matchObj = re.search(searchString, output, re.DOTALL) + vmDPIP = matchObj.group(1) + searchString = '.*%s=([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+),*\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)*' %(internal_network) + matchObj = re.search(searchString, output, re.DOTALL) + vmAdminIP = matchObj.group(2) + if vmAdminIP == None: + vmAdminIP = matchObj.group(1) + cmd = 'openstack port list |egrep "\\b%s\\b" | tr -s " " | cut -d"|" -f 4'%(vmDPIP) + log.debug(cmd) + vmDPmac = subprocess.check_output(cmd , shell=True).strip() + config.add_section('M%d'%vm) + config.set('M%d'%vm, 'name', ServerName[vm-1]) + config.set('M%d'%vm, 'admin_ip', vmAdminIP) + config.set('M%d'%vm, 'dp_ip', vmDPIP) + config.set('M%d'%vm, 'dp_mac', vmDPmac) + log.info('%s: (admin IP: %s), (dataplane IP: %s), (dataplane MAC: %s)' % (ServerName[vm-1],vmAdminIP,vmDPIP,vmDPmac)) + +config.add_section('OpenStack') +config.set('OpenStack', 'stack', stack) +config.set('OpenStack', 'VMs', vms) +config.set('OpenStack', 'key', key) +config.set('OpenStack', 'image', image) +config.set('OpenStack', 'image_file', image_file) +config.set('OpenStack', 'dataplane_network', dataplane_network) +config.set('OpenStack', 'subnet', subnet) +config.set('OpenStack', 'subnet_cidr', subnet_cidr) +config.set('OpenStack', 'internal_network', internal_network) +config.set('OpenStack', 'floating_network', floating_network) +config.add_section('rapid') +config.set('rapid', 'loglevel', loglevel) +config.set('rapid', 'version', version) +config.set('rapid', 'total_number_of_machines', total_number_of_VMs) +config.set('DEFAULT', 'admin_ip', 'none') +# Writing the environment file +with open(stack+'.env', 'wb') as envfile: + config.write(envfile) diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh b/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh new file mode 100644 index 00000000..848520ce --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +## +## Copyright (c) 2010-2019 Intel Corporation +## +## 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. +## + +BUILD_DIR="/opt/openstackrapid" +COPY_DIR="/home/centos" # Directory where the packer tool has copied some files +DPDK_VERSION="18.08" +PROX_COMMIT="af95b812" +export RTE_SDK="${BUILD_DIR}/dpdk-${DPDK_VERSION}" +export RTE_TARGET="x86_64-native-linuxapp-gcc" + +function os_pkgs_install() +{ + # NASM repository for AESNI MB library + sudo yum-config-manager --add-repo http://www.nasm.us/nasm.repo + + sudo yum install -y deltarpm + sudo yum update -y + sudo yum install -y git wget gcc unzip libpcap-devel ncurses-devel \ + libedit-devel lua-devel kernel-devel iperf3 pciutils \ + numactl-devel vim tuna openssl-devel nasm +} + +function os_cfg() +{ + # Enabling root ssh access + sudo sed -i '/disable_root: 1/c\disable_root: 0' /etc/cloud/cloud.cfg + + # Mounting huge pages to be used by DPDK, mounting already done by CentOS + # sudo mkdir -p /mnt/huge + # sudo umount `awk '/hugetlbfs/ { print $2 }' /proc/mounts` >/dev/null 2>&1 + # sudo mount -t hugetlbfs nodev /mnt/huge/ + sudo sh -c '(echo "vm.nr_hugepages = 1024") > /etc/sysctl.conf' + + # Enabling tuned with the realtime-virtual-guest profile + pushd ${BUILD_DIR} > /dev/null 2>&1 + wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-realtime-2.8.0-5.el7_4.2.noarch.rpm + wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-nfv-guest-2.8.0-5.el7_4.2.noarch.rpm + # Install with --nodeps. The latest CentOS cloud images come with a tuned version higher than 2.8. These 2 packages however + # do not depend on v2.8 and also work with tuned 2.9. Need to be careful in the future + sudo rpm -ivh ${BUILD_DIR}/tuned-profiles-realtime-2.8.0-5.el7_4.2.noarch.rpm --nodeps + sudo rpm -ivh ${BUILD_DIR}/tuned-profiles-nfv-guest-2.8.0-5.el7_4.2.noarch.rpm --nodeps + # Although we do no know how many cores the VM will have when begin deployed for real testing, we already put a number for the + # isolated CPUs so we can start the realtime-virtual-guest profile. If we don't, that command will fail. + # When the VM will be instantiated, the check_kernel_params service will check for the real number of cores available to this VM + # and update the realtime-virtual-guest-variables.conf accordingly. + echo "isolated_cores=1" | sudo tee -a /etc/tuned/realtime-virtual-guest-variables.conf + sudo tuned-adm profile realtime-virtual-guest + + # Install the check_tuned_params service to make sure that the grub cmd line has the right cpus in isolcpu. The actual number of cpu's + # assigned to this VM depends on the flavor used. We don't know at this time what that will be. + sudo chmod +x ${COPY_DIR}/check_prox_system_setup.sh + sudo cp -r ${COPY_DIR}/check_prox_system_setup.sh /usr/local/libexec/ + sudo cp -r ${COPY_DIR}/check-prox-system-setup.service /etc/systemd/system/ + sudo systemctl daemon-reload + sudo systemctl enable check-prox-system-setup.service + + popd > /dev/null 2>&1 +} + +function mblib_install() +{ + export AESNI_MULTI_BUFFER_LIB_PATH="${BUILD_DIR}/intel-ipsec-mb-0.50" + + # Downloading the Multi-buffer library. Note that the version to download is linked to the DPDK version being used + pushd ${BUILD_DIR} > /dev/null 2>&1 + wget https://github.com/01org/intel-ipsec-mb/archive/v0.50.zip + unzip v0.50.zip + pushd ${AESNI_MULTI_BUFFER_LIB_PATH} + make -j`getconf _NPROCESSORS_ONLN` + sudo make install + popd > /dev/null 2>&1 + popd > /dev/null 2>&1 +} + +function dpdk_install() +{ + # Build DPDK for the latest kernel installed + LATEST_KERNEL_INSTALLED=`ls -v1 /lib/modules/ | tail -1` + export RTE_KERNELDIR="/lib/modules/${LATEST_KERNEL_INSTALLED}/build" + + # Get and compile DPDK + pushd ${BUILD_DIR} > /dev/null 2>&1 + wget http://fast.dpdk.org/rel/dpdk-${DPDK_VERSION}.tar.xz + tar -xf ./dpdk-${DPDK_VERSION}.tar.xz + popd > /dev/null 2>&1 + + # Runtime scripts are assuming /root as the directory for PROX + sudo ln -s ${RTE_SDK} /root/dpdk + + pushd ${RTE_SDK} > /dev/null 2>&1 + make config T=${RTE_TARGET} + # The next sed lines make sure that we can compile DPDK 17.11 with a relatively new OS. Using a newer DPDK (18.5) should also resolve this issue + #sudo sed -i '/CONFIG_RTE_LIBRTE_KNI=y/c\CONFIG_RTE_LIBRTE_KNI=n' ${RTE_SDK}/build/.config + #sudo sed -i '/CONFIG_RTE_LIBRTE_PMD_KNI=y/c\CONFIG_RTE_LIBRTE_PMD_KNI=n' ${RTE_SDK}/build/.config + #sudo sed -i '/CONFIG_RTE_KNI_KMOD=y/c\CONFIG_RTE_KNI_KMOD=n' ${RTE_SDK}/build/.config + #sudo sed -i '/CONFIG_RTE_KNI_PREEMPT_DEFAULT=y/c\CONFIG_RTE_KNI_PREEMPT_DEFAULT=n' ${RTE_SDK}/build/.config + # Compile with MB library + sed -i '/CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n/c\CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y' ${RTE_SDK}/build/.config + make -j`getconf _NPROCESSORS_ONLN` + ln -s ${RTE_SDK}/build ${RTE_SDK}/${RTE_TARGET} + popd > /dev/null 2>&1 +} + +function prox_install() +{ + # Clone and compile PROX + pushd ${BUILD_DIR} > /dev/null 2>&1 + git clone https://git.opnfv.org/samplevnf + pushd ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX +# git checkout ffc6be26 + git checkout ${PROX_COMMIT} + make -j`getconf _NPROCESSORS_ONLN` + sudo ln -s ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX /root/prox + popd > /dev/null 2>&1 + popd > /dev/null 2>&1 +} + +[ ! -d ${BUILD_DIR} ] && sudo mkdir -p ${BUILD_DIR} +sudo chmod 0777 ${BUILD_DIR} + +os_pkgs_install +os_cfg +mblib_install +dpdk_install +prox_install diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/devbind.sh b/VNFs/DPPD-PROX/helper-scripts/rapid/devbind.sh new file mode 100755 index 00000000..f9fc03ce --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/devbind.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +## +## Copyright (c) 2010-2017 Intel Corporation +## +## 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. +## + +link="$(ip -o link | grep MACADDRESS |cut -d":" -f 2)" +if [ -n "$link" ]; +then + echo Need to bind + /root/dpdk/usertools/dpdk-devbind.py --force --bind igb_uio $(/root/dpdk/usertools/dpdk-devbind.py --status |grep $link | cut -d" " -f 1) +else + echo Assuming port is already bound to DPDK +fi +exit 0 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg new file mode 100644 index 00000000..42cfdc1b --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg @@ -0,0 +1,76 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=p0 +rx desc=2048 +tx desc=2048 +vlan=yes + +[variables] +$mbs=8 + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $gencores] +name=p0 +task=0 +mode=gen +sub mode=l3 +tx port=p0 +bps=1250000000 +pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b +pkt size=60 +;gateway ipv4=${gw_ip} +local ipv4=${local_ip} +min bulk size=$mbs +max bulk size=16 +drop=yes +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 +;arp update time=1 + +[core $latcores] +name=lat +task=0 +mode=lat +sub mode=l3 +rx port=p0 +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 +accuracy limit nsec=1000000 +;arp update time=1 + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg new file mode 100644 index 00000000..e819041c --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg @@ -0,0 +1,74 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=p0 +rx desc=2048 +tx desc=2048 +vlan=yes + +[variables] +$mbs=8 + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $gencores] +name=p0 +task=0 +mode=gen +sub mode=l3 +tx port=p0 +bps=1250000000 +pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b +pkt size=60 +gateway ipv4=${gw_ip} +local ipv4=${local_ip} +min bulk size=$mbs +max bulk size=16 +drop=yes +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 +;arp update time=1 + +[core $latcores] +name=lat +task=0 +mode=lat +sub mode=l3 +rx port=p0 +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 +;arp update time=1 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/impair.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.cfg new file mode 100644 index 00000000..8ca9e05d --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.cfg @@ -0,0 +1,50 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=if0 +mac=hardware +rx desc=2048 +tx desc=2048 +vlan=yes + + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $impaircores] +name=impair +task=0 +mode=impair +sub mode=l3 +rx port=if0 +tx port=if0 +delay us=1000 +probability=100 +local ipv4=${local_ip} diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test new file mode 100644 index 00000000..9b633d99 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test @@ -0,0 +1,54 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = impairTesting +number_of_tests = 2 +total_number_of_test_machines = 3 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = gen_gw.cfg +gw_vm = 2 +dest_vm = 3 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = ImpairGW +config_file = impair.cfg +impaircores = [1] + +[TestM3] +name = Swap +config_file = swap.cfg +swapcores = [1] + +[BinarySearchParams] +drop_rate_threshold = 0.1 +lat_avg_threshold = 500 +lat_max_threshold = 1000 +accuracy = 0.1 + +[test1] +test=inittest + +[test2] +test=impairtest +packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/irq.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.cfg new file mode 100644 index 00000000..38e4b966 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.cfg @@ -0,0 +1,42 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[;port 0] +name=p0 + +[variables] +$mbs=8 + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $irqcores] +name=irq +task=0 +mode=irq diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test new file mode 100644 index 00000000..b8dc706b --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test @@ -0,0 +1,32 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = BasicSwapTesting +number_of_tests = 1 +total_number_of_test_machines = 1 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = InterruptTesting +config_file = irq.cfg +irqcores = [1,2,3] + + +[test1] +test=irqtest + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test new file mode 100644 index 00000000..44fefdda --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test @@ -0,0 +1,42 @@ +## +## Copyright (c) 2010-2019 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = L2BasicSwapTesting +number_of_tests = 2 +total_number_of_test_machines = 2 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = l2gen.cfg +dest_vm = 2 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = Swap +config_file = l2swap.cfg +swapcores = [1] + +[test1] +test=inittest + +[test2] +test=max_frame_rate +packetsizes=[256] diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg new file mode 100644 index 00000000..1469604b --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg @@ -0,0 +1,70 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=p0 +rx desc=2048 +tx desc=2048 +vlan=yes + +[variables] +$mbs=8 + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $gencores] +name=p0 +task=0 +mode=gen +tx port=p0 +bps=1250000000 +pkt inline=${dest_hex_mac} 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip} ${dest_hex_ip} 0b b8 0b b9 00 1a 55 7b +pkt size=60 +;gateway ipv4=${gw_ip} +local ipv4=${local_ip} +min bulk size=$mbs +max bulk size=16 +drop=yes +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 + +[core $latcores] +name=lat +task=0 +mode=lat +rx port=p0 +lat pos=42 +accuracy pos=46 +packet id pos=50 +signature=0x6789abcd +signature pos=56 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2swap.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/l2swap.cfg new file mode 100644 index 00000000..004588c0 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2swap.cfg @@ -0,0 +1,46 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=if0 +mac=hardware +rx desc=2048 +tx desc=2048 +vlan=yes + +[defaults] +mempool size=8K + +[global] +name=${name} + +[core 0] +mode=master + +[core $swapcores] +name=swap +task=0 +mode=swap +rx port=if0 +tx port=if0 +drop=no diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test new file mode 100644 index 00000000..04065909 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test @@ -0,0 +1,56 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = L2BasicSwapTesting +number_of_tests = 4 +total_number_of_test_machines = 2 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = l2gen.cfg +dest_vm = 2 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = Swap +config_file = l2swap.cfg +swapcores = [1] + +[BinarySearchParams] +drop_rate_threshold = 0 +lat_avg_threshold = 500 +lat_max_threshold = 1000 +accuracy = 0.1 + + +[test1] +test=inittest + +[test2] +test=speedtest +packetsize=64 + +[test3] +test=sizetest + +[test4] +test=flowtest +packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test new file mode 100644 index 00000000..21bf8106 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test @@ -0,0 +1,42 @@ +## +## Copyright (c) 2010-2019 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = L3FrameRateTesting +number_of_tests = 2 +total_number_of_test_machines = 2 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = gen.cfg +dest_vm = 2 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = Swap +config_file = swap.cfg +swapcores = [1] + +[test1] +test=inittest + +[test2] +test=max_frame_rate +packetsizes=[256] diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py b/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py new file mode 100644 index 00000000..3ee28c00 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py @@ -0,0 +1,254 @@ +## +## Copyright (c) 2010-2017 Intel Corporation +## +## 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. +## + +from __future__ import print_function + +import os +import subprocess +import socket + +class prox_ctrl(object): + def __init__(self, ip, key=None, user=None): + self._ip = ip + self._key = key + self._user = user + self._children = [] + self._proxsock = [] + + def ip(self): + return self._ip + + def connect(self): + """Simply try to run 'true' over ssh on remote system. + On failure, raise RuntimeWarning exception when possibly worth + retrying, and raise RuntimeError exception otherwise. + """ + return self.run_cmd('true', True) + + def close(self): + """Must be called before program termination.""" +# for prox in self._proxsock: +# prox.quit() + children = len(self._children) + if children == 0: + return + if children > 1: + print('Waiting for %d child processes to complete ...' % children) + for child in self._children: + ret = os.waitpid(child[0], os.WNOHANG) + if ret[0] == 0: + print("Waiting for child process '%s' to complete ..." % child[1]) + ret = os.waitpid(child[0], 0) + rc = ret[1] + if os.WIFEXITED(rc): + if os.WEXITSTATUS(rc) == 0: + print("Child process '%s' completed successfully" % child[1]) + else: + print("Child process '%s' returned exit status %d" % ( + child[1], os.WEXITSTATUS(rc))) + elif os.WIFSIGNALED(rc): + print("Child process '%s' exited on signal %d" % ( + child[1], os.WTERMSIG(rc))) + else: + print("Wait status for child process '%s' is 0x%04x" % ( + child[1], rc)) + + def run_cmd(self, command, _connect=False): + """Execute command over ssh on remote system. + Wait for remote command completion. + Return command output (combined stdout and stderr). + _connect argument is reserved for connect() method. + """ + cmd = self._build_ssh(command) + try: + return subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as ex: + if _connect and ex.returncode == 255: + raise RuntimeWarning(ex.output.strip()) + raise RuntimeError('ssh returned exit status %d:\n%s' + % (ex.returncode, ex.output.strip())) + + def fork_cmd(self, command, name=None): + """Execute command over ssh on remote system, in a child process. + Do not wait for remote command completion. + Return child process id. + """ + if name is None: + name = command + cmd = self._build_ssh(command) + pid = os.fork() + if (pid != 0): + # In the parent process + self._children.append((pid, name)) + return pid + # In the child process: use os._exit to terminate + try: + # Actually ignore output on success, but capture stderr on failure + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as ex: + raise RuntimeError("Child process '%s' failed:\n" + 'ssh returned exit status %d:\n%s' + % (name, ex.returncode, ex.output.strip())) + os._exit(0) + + def prox_sock(self, port=8474): + """Connect to the PROX instance on remote system. + Return a prox_sock object on success, None on failure. + """ + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + sock.connect((self._ip, port)) + prox = prox_sock(sock) + self._proxsock.append(prox) + return prox + except: + return None + + def scp_put(self, src, dst): + """Copy src file from local system to dst on remote system.""" + cmd = [ 'scp', + '-B', + '-oStrictHostKeyChecking=no', + '-oUserKnownHostsFile=/dev/null', + '-oLogLevel=ERROR' ] + if self._key is not None: + cmd.extend(['-i', self._key]) + cmd.append(src) + remote = '' + if self._user is not None: + remote += self._user + '@' + remote += self._ip + ':' + dst + cmd.append(remote) + try: + # Actually ignore output on success, but capture stderr on failure + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as ex: + raise RuntimeError('scp returned exit status %d:\n%s' + % (ex.returncode, ex.output.strip())) + + def _build_ssh(self, command): + cmd = [ 'ssh', + '-oBatchMode=yes', + '-oStrictHostKeyChecking=no', + '-oUserKnownHostsFile=/dev/null', + '-oLogLevel=ERROR' ] + if self._key is not None: + cmd.extend(['-i', self._key]) + remote = '' + if self._user is not None: + remote += self._user + '@' + remote += self._ip + cmd.append(remote) + cmd.append(command) + return cmd + +class prox_sock(object): + def __init__(self, sock): + self._sock = sock + self._rcvd = b'' + + def quit(self): + if self._sock is not None: + self._send('quit') + self._sock.close() + self._sock = None + + def start(self, cores): + self._send('start %s' % ','.join(map(str, cores))) + + def stop(self, cores): + self._send('stop %s' % ','.join(map(str, cores))) + + def speed(self, speed, cores, tasks=None): + if tasks is None: + tasks = [ 0 ] * len(cores) + elif len(tasks) != len(cores): + raise ValueError('cores and tasks must have the same len') + for (core, task) in zip(cores, tasks): + self._send('speed %s %s %s' % (core, task, speed)) + + def reset_stats(self): + self._send('reset stats') + + def lat_stats(self, cores, task=0): + min_lat = 999999999 + max_lat = avg_lat = 0 + self._send('lat stats %s %s' % (','.join(map(str, cores)), task)) + for core in cores: + stats = self._recv().split(',') + min_lat = min(int(stats[0]),min_lat) + max_lat = max(int(stats[1]),max_lat) + avg_lat += int(stats[2]) + avg_lat = avg_lat/len(cores) + self._send('stats latency(0).used') + used = float(self._recv()) + self._send('stats latency(0).total') + total = float(self._recv()) + return min_lat, max_lat, avg_lat, (used/total) + + def irq_stats(self, core, bucket, task=0): + self._send('stats task.core(%s).task(%s).irq(%s)' % (core, task, bucket)) + stats = self._recv().split(',') + return int(stats[0]) + + def show_irq_buckets(self, core, task=0): + rx = tx = drop = tsc = hz = 0 + self._send('show irq buckets %s %s' % (core,task)) + buckets = self._recv().split(';') + buckets = buckets[:-1] + return buckets + + def core_stats(self, cores, task=0): + rx = tx = drop = tsc = hz = rx_non_dp = tx_non_dp = 0 + self._send('dp core stats %s %s' % (','.join(map(str, cores)), task)) + for core in cores: + stats = self._recv().split(',') + rx += int(stats[0]) + tx += int(stats[1]) + rx_non_dp += int(stats[2]) + tx_non_dp += int(stats[3]) + drop += int(stats[4]) + tsc = int(stats[5]) + hz = int(stats[6]) + return rx-rx_non_dp, tx-tx_non_dp, drop, tsc, hz + + def set_random(self, cores, task, offset, mask, length): + self._send('set random %s %s %s %s %s' % (','.join(map(str, cores)), task, offset, mask, length)) + + def set_size(self, cores, task, pkt_size): + self._send('pkt_size %s %s %s' % (','.join(map(str, cores)), task, pkt_size)) + + def set_value(self, cores, task, offset, value, length): + self._send('set value %s %s %s %s %s' % (','.join(map(str, cores)), task, offset, value, length)) + + def _send(self, cmd): + """Append LF and send command to the PROX instance.""" + if self._sock is None: + raise RuntimeError("PROX socket closed, cannot send '%s'" % cmd) + self._sock.sendall(cmd.encode() + b'\n') + + def _recv(self): + """Receive response from PROX instance, and return it with LF removed.""" + if self._sock is None: + raise RuntimeError("PROX socket closed, cannot receive anymore") + pos = self._rcvd.find(b'\n') + while pos == -1: + self._rcvd += self._sock.recv(256) + pos = self._rcvd.find(b'\n') + rsp = self._rcvd[:pos] + self._rcvd = self._rcvd[pos+1:] + return rsp.decode() + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms b/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms new file mode 100644 index 00000000..d18184d6 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms @@ -0,0 +1,61 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + + +[DEFAULT] +total_number_of_vms=3 +flavor_info=--ram 4096 --disk 40 --vcpus 4 +;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate --property hw:numa_nodes=1 --property hw:numa_cpus.0=0,1,2,3 --property hw:numa_mempolicy=strict --property hw:numa_mem.0=4096 +;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate +flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated +;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_realtime=yes --property hw:cpu_realtime_mask=^0 +;boot_info=--availability-zone nova --security-group default +boot_info=--availability-zone nova --security-group prox +SRIOV_port=NO + +[VM1] + +[VM2] + +[VM3] + +[VM4] + +[VM5] + +[VM6] + +[VM7] + +[VM8] + +[VM9] + +[VM10] + +[VM11] + +[VM12] + +[VM13] + +[VM14] + +[VM15] + +[VM16] + + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py b/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py new file mode 100755 index 00000000..3b0eeb8b --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py @@ -0,0 +1,927 @@ +#!/usr/bin/python + +## +## Copyright (c) 2010-2017 Intel Corporation +## +## 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. +## + +from __future__ import print_function + +import os +import stat +import sys +import time +import subprocess +import getopt +import re +import logging +from logging.handlers import RotatingFileHandler +from logging import handlers +from prox_ctrl import prox_ctrl +import ConfigParser +import ast +import atexit +import csv + +version="19.4.15" +env = "rapid" #Default string for environment +test = "basicrapid" #Default string for test +machine_map_file = "MachineMap" #Default string for machine map file +loglevel="DEBUG" # sets log level for writing to file +runtime=10 # time in seconds for 1 test run +configonly = False # IF True, the system will upload all the necessary config fiels to the VMs, but not start PROX and the actual testing + +def usage(): + print("usage: runrapid [--version] [-v]") + print(" [--env ENVIRONMENT_NAME]") + print(" [--test TEST_NAME]") + print(" [--map MACHINE_MAP_FILE]") + print(" [--runtime TIME_FOR_TEST]") + print(" [--configonly False|True]") + print(" [--log DEBUG|INFO|WARNING|ERROR|CRITICAL]") + print(" [-h] [--help]") + print("") + print("Command-line interface to runrapid") + print("") + print("optional arguments:") + print(" -v, --version Show program's version number and exit") + print(" --env ENVIRONMENT_NAME Parameters will be read from ENVIRONMENT_NAME.env Default is %s."%env) + print(" --test TEST_NAME Test cases will be read from TEST_NAME.test Default is %s."%test) + print(" --map MACHINE_MAP_FILE Machine mapping will be read from MACHINE_MAP_FILE.cfg Default is %s."%machine_map_file) + print(" --runtime Specify time in seconds for 1 test run") + print(" --configonly If True, only upload all config files to the VMs, do not run the tests. Default is %s."%configonly) + print(" --log Specify logging level for log file output, screen output level is hard coded") + print(" -h, --help Show help message and exit.") + print("") + +try: + opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "env=", "test=", "map=", "runtime=","configonly=","log="]) +except getopt.GetoptError as err: + print("===========================================") + print(str(err)) + print("===========================================") + usage() + sys.exit(2) +if args: + usage() + sys.exit(2) +for opt, arg in opts: + if opt in ("-h", "--help"): + usage() + sys.exit() + if opt in ("-v", "--version"): + print("Rapid Automated Performance Indication for Dataplane "+version) + sys.exit() + if opt in ("--env"): + env = arg + print ("Using '"+env+"' as name for the environment") + if opt in ("--test"): + test = arg + print ("Using '"+test+".test' for test case definition") + if opt in ("--map"): + machine_map_file = arg + print ("Using '"+machine_map_file+".cfg' for machine mapping") + if opt in ("--runtime"): + runtime = arg + print ("Runtime: "+ runtime) + if opt in ("--configonly"): + configonly = arg + print ("configonly: "+ configonly) + if opt in ("--log"): + loglevel = arg + print ("Log level: "+ loglevel) + +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + +# create formatters +screen_formatter = logging.Formatter("%(message)s") +file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") + +# get a top-level logger, +# set its log level, +# BUT PREVENT IT from propagating messages to the root logger +# +log = logging.getLogger() +numeric_level = getattr(logging, loglevel.upper(), None) +if not isinstance(numeric_level, int): + raise ValueError('Invalid log level: %s' % loglevel) +log.setLevel(numeric_level) +log.propagate = 0 + +# create a console handler +# and set its log level to the command-line option +# +console_handler = logging.StreamHandler(sys.stdout) +console_handler.setLevel(logging.INFO) +console_handler.setFormatter(screen_formatter) + +# create a file handler +# and set its log level to DEBUG +# +log_file = 'RUN{}.{}.log'.format(env,test) +file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10) +#file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5) +file_handler.setLevel(numeric_level) +file_handler.setFormatter(file_formatter) + +# add handlers to the logger +# +log.addHandler(file_handler) +log.addHandler(console_handler) + +# Check if log exists and should therefore be rolled +needRoll = os.path.isfile(log_file) + + +# This is a stale log, so roll it +if needRoll: + # Add timestamp + log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime()) + + # Roll over on application start + log.handlers[0].doRollover() + +# Add timestamp +log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime()) + +log.debug("runrapid.py version: "+version) +#======================================================================== +def connect_socket(client): + attempts = 1 + log.debug("Trying to connect to PROX (just launched) on %s, attempt: %d" % (client.ip(), attempts)) + sock = None + while True: + sock = client.prox_sock() + if sock is not None: + break + attempts += 1 + if attempts > 20: + log.exception("Failed to connect to PROX on %s after %d attempts" % (client.ip(), attempts)) + raise Exception("Failed to connect to PROX on %s after %d attempts" % (client.ip(), attempts)) + time.sleep(2) + log.debug("Trying to connect to PROX (just launched) on %s, attempt: %d" % (client.ip(), attempts)) + log.info("Connected to PROX on %s" % client.ip()) + return sock + +def connect_client(client): + attempts = 1 + log.debug("Trying to connect to VM which was just launched on %s, attempt: %d" % (client.ip(), attempts)) + while True: + try: + client.connect() + break + except RuntimeWarning, ex: + attempts += 1 + if attempts > 20: + log.exception("Failed to connect to VM after %d attempts:\n%s" % (attempts, ex)) + raise Exception("Failed to connect to VM after %d attempts:\n%s" % (attempts, ex)) + time.sleep(2) + log.debug("Trying to connect to VM which was just launched on %s, attempt: %d" % (client.ip(), attempts)) + log.debug("Connected to VM on %s" % client.ip()) + +def run_iteration(gensock,sutsock): + sleep_time = 3 + # Sleep_time is needed to be able to do accurate measurements to check for packet loss. We need to make this time large enough so that we do not take the first measurement while some packets from the previous tests migth still be in flight + time.sleep(sleep_time) + abs_old_rx, abs_old_tx, abs_old_drop, abs_old_tsc, abs_tsc_hz = gensock.core_stats(genstatcores) + gensock.start(gencores) + time.sleep(sleep_time) + if sutsock!='none': + old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) + old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(genstatcores) + # Measure latency statistics per second + n_loops = 0 + lat_min = 0 + lat_max = 0 + lat_avg = 0 + used_avg = 0 + while n_loops < float(runtime): + n_loops +=1 + time.sleep(1) + lat_min_sample, lat_max_sample, lat_avg_sample, used_sample = gensock.lat_stats(latcores) + if lat_min > lat_min_sample: + lat_min = lat_min_sample + if lat_max < lat_max_sample: + lat_max = lat_max_sample + lat_avg = lat_avg + lat_avg_sample + used_avg = used_avg + used_sample + lat_avg = lat_avg / n_loops + used_avg = used_avg / n_loops + # Get statistics after some execution time + new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) + if sutsock!='none': + new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) + #Stop generating + gensock.stop(gencores) + time.sleep(sleep_time) + abs_new_rx, abs_new_tx, abs_new_drop, abs_new_tsc, abs_tsc_hz = gensock.core_stats(genstatcores) + drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM + rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM + tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface + abs_dropped = (abs_new_tx - abs_old_tx) - (abs_new_rx - abs_old_rx) + tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. + pps_req_tx = (tx+drop-rx)*tsc_hz*1.0/(tsc*1000000) + pps_tx = tx*tsc_hz*1.0/(tsc*1000000) + pps_rx = rx*tsc_hz*1.0/(tsc*1000000) + if sutsock!='none': + sut_rx = new_sut_rx - old_sut_rx + sut_tx = new_sut_tx - old_sut_tx + sut_tsc = new_sut_tsc - old_sut_tsc + pps_sut_tx = sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000) + pps_sut_tx_str = '{:>9.3f}'.format(pps_sut_tx) + else: + pps_sut_tx = 0 + pps_sut_tx_str = 'NO MEAS.' + if (tx == 0): + log.critical("TX = 0. Test interrupted since no packet has been sent.") + raise Exception("TX = 0") + return(pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max,abs_dropped,(abs_new_tx - abs_old_tx),lat_min,used_avg) + +def new_speed(speed,minspeed,maxspeed,success): + if success: + minspeed = speed + else: + maxspeed = speed + newspeed = (maxspeed+minspeed)/2.0 + return (newspeed,minspeed,maxspeed) + +def get_pps(speed,size): + return (speed * 100.0 / (8*(size+24))) + +def run_speedtest(gensock,sutsock): + maxspeed = speed = STARTSPEED + minspeed = 0 + size=PACKETSIZE-4 + attempts = 0 + log.info("+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+") + log.info("| Generator is sending UDP (1 flow) packets ("+ '{:>5}'.format(size+4) +" bytes) to SUT. SUT sends packets back |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") + log.info("| Test | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio | Result |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") + endpps_sut_tx_str = 'NO_RESULTS' + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) + gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) + # This will only work when using sending UDP packets. For different protocols and ethernet types, we would need a different calculation + gensock.start(latcores) + while (maxspeed-minspeed > ACCURACY): + attempts += 1 + print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') + sys.stdout.flush() + # Start generating packets at requested speed (in % of a 10Gb/s link) + gensock.speed(speed / len(gencores), gencores) + time.sleep(1) + # Get statistics now that the generation is stable and initial ARP messages are dealt with. + pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) + drop_rate = 100.0*abs_dropped/abs_tx + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): + log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) + endspeed = speed + endpps_req_tx = pps_req_tx + endpps_tx = pps_tx + endpps_sut_tx_str = pps_sut_tx_str + endpps_rx = pps_rx + endlat_avg = lat_avg + endlat_max = lat_max + endabs_dropped = abs_dropped + enddrop_rate = drop_rate + endwarning = lat_warning + success = True + else: + abs_drop_rate_prefix = bcolors.ENDC + if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): + abs_drop_rate_prefix = bcolors.FAIL + if (drop_rate < DROP_RATE_TRESHOLD): + drop_rate_prefix = bcolors.ENDC + else: + drop_rate_prefix = bcolors.FAIL + if (lat_avg< LAT_AVG_TRESHOLD): + lat_avg_prefix = bcolors.ENDC + else: + lat_avg_prefix = bcolors.FAIL + if (lat_max< LAT_MAX_TRESHOLD): + lat_max_prefix = bcolors.ENDC + else: + lat_max_prefix = bcolors.FAIL + if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): + speed_prefix = bcolors.ENDC + else: + speed_prefix = bcolors.FAIL + log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+lat_warning) + success = False + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") + log.info('|{:>7}'.format('END')+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+ '{:>9.0f}'.format(endlat_max)+' us | '+'{:>14d}'.format(endabs_dropped)+ ' |''{:>9.2f}'.format(enddrop_rate)+ '% | SUCCESS |'+endwarning) + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+") + writer.writerow({'flow':'1','size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) + else: + log.info('| Speed 0 or close to 0') + gensock.stop(latcores) + +def run_flowtest(gensock,sutsock): + size=PACKETSIZE-4 + log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") + log.info("| UDP, "+ '{:>5}'.format(size+4) +" bytes, different number of flows by randomizing SRC & DST UDP port |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + log.info("| Flows | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + # To generate a desired number of flows, PROX will randomize the bits in source and destination ports, as specified by the bit masks in the flows variable. + flows={\ + 1: ['1000000000000000','1000000000000000'],\ + 2: ['1000000000000000','100000000000000X'],\ + 4: ['100000000000000X','100000000000000X'],\ + 8: ['100000000000000X','10000000000000XX'],\ + 16: ['10000000000000XX','10000000000000XX'],\ + 32: ['10000000000000XX','1000000000000XXX'],\ + 64: ['1000000000000XXX','1000000000000XXX'],\ + 128: ['1000000000000XXX','100000000000XXXX'],\ + 256: ['100000000000XXXX','100000000000XXXX'],\ + 512: ['100000000000XXXX','10000000000XXXXX'],\ + 1024: ['10000000000XXXXX','10000000000XXXXX'],\ + 2048: ['10000000000XXXXX','1000000000XXXXXX'],\ + 4096: ['1000000000XXXXXX','1000000000XXXXXX'],\ + 8192: ['1000000000XXXXXX','100000000XXXXXXX'],\ + 16384: ['100000000XXXXXXX','100000000XXXXXXX'],\ + 32768: ['100000000XXXXXXX','10000000XXXXXXXX'],\ + 65535: ['10000000XXXXXXXX','10000000XXXXXXXX'],\ + 131072: ['10000000XXXXXXXX','1000000XXXXXXXXX'],\ + 262144: ['1000000XXXXXXXXX','1000000XXXXXXXXX'],\ + 524280: ['1000000XXXXXXXXX','100000XXXXXXXXXX'],\ + 1048576:['100000XXXXXXXXXX','100000XXXXXXXXXX'],} + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) + gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) + # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation + gensock.start(latcores) + for flow_number in flow_size_list: + attempts = 0 + gensock.reset_stats() + if sutsock!='none': + sutsock.reset_stats() + source_port,destination_port = flows[flow_number] + gensock.set_random(gencores,0,34,source_port,2) + gensock.set_random(gencores,0,36,destination_port,2) + endpps_sut_tx_str = 'NO_RESULTS' + maxspeed = speed = STARTSPEED + minspeed = 0 + while (maxspeed-minspeed > ACCURACY): + attempts += 1 + print(str(flow_number)+' flows: Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') + sys.stdout.flush() + # Start generating packets at requested speed (in % of a 10Gb/s link) + gensock.speed(speed / len(gencores), gencores) + time.sleep(1) + # Get statistics now that the generation is stable and initial ARP messages are dealt with + pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) + drop_rate = 100.0*abs_dropped/abs_tx + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): + log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) + endspeed = speed + endpps_req_tx = pps_req_tx + endpps_tx = pps_tx + endpps_sut_tx_str = pps_sut_tx_str + endpps_rx = pps_rx + endlat_avg = lat_avg + endlat_max = lat_max + endabs_dropped = abs_dropped + enddrop_rate = drop_rate + endwarning = lat_warning + success = True + else: + abs_drop_rate_prefix = bcolors.ENDC + if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): + abs_drop_rate_prefix = bcolors.FAIL + if (drop_rate < DROP_RATE_TRESHOLD): + drop_rate_prefix = bcolors.ENDC + else: + drop_rate_prefix = bcolors.FAIL + if (lat_avg< LAT_AVG_TRESHOLD): + lat_avg_prefix = bcolors.ENDC + else: + lat_avg_prefix = bcolors.FAIL + if (lat_max< LAT_MAX_TRESHOLD): + lat_max_prefix = bcolors.ENDC + else: + lat_max_prefix = bcolors.FAIL + if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): + speed_prefix = bcolors.ENDC + else: + speed_prefix = bcolors.FAIL + log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+lat_warning) + success = False + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info('|{:>7}'.format(str(flow_number))+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+ '{:>9.0f}'.format(endlat_max)+' us | '+ '{:>14d}'.format(endabs_dropped)+ ' |'+'{:>9.2f}'.format(enddrop_rate)+ '% |'+endwarning) + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + writer.writerow({'flow':flow_number,'size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) + else: + log.info('|{:>7}'.format(str(flow_number))+" | Speed 0 or close to 0") + gensock.stop(latcores) + +def run_sizetest(gensock,sutsock): + log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") + log.info("| UDP, 1 flow, different packet sizes |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + log.info("| Pktsize| Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + gensock.start(latcores) + for size in packet_size_list: + size = size-4 + attempts = 0 + gensock.reset_stats() + if sutsock!='none': + sutsock.reset_stats() + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) + gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) + # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation + endpps_sut_tx_str = 'NO_RESULTS' + maxspeed = speed = STARTSPEED + minspeed = 0 + while (maxspeed-minspeed > ACCURACY): + attempts += 1 + print(str(size+4)+' bytes: Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') + sys.stdout.flush() + # Start generating packets at requested speed (in % of a 10Gb/s link) + gensock.speed(speed / len(gencores), gencores) + # Get statistics now that the generation is stable and initial ARP messages are dealt with + pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) + drop_rate = 100.0*abs_dropped/abs_tx + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001 and ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD): + log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% | SUCCESS |'+lat_warning) + endspeed = speed + endpps_req_tx = pps_req_tx + endpps_tx = pps_tx + endpps_sut_tx_str = pps_sut_tx_str + endpps_rx = pps_rx + endlat_avg = lat_avg + endlat_max = lat_max + endabs_dropped = abs_dropped + enddrop_rate = drop_rate + endwarning = lat_warning + success = True + else: + abs_drop_rate_prefix = bcolors.ENDC + if ((abs_dropped>0) and (DROP_RATE_TRESHOLD ==0)): + abs_drop_rate_prefix = bcolors.FAIL + if (drop_rate < DROP_RATE_TRESHOLD): + drop_rate_prefix = bcolors.ENDC + else: + drop_rate_prefix = bcolors.FAIL + if (lat_avg< LAT_AVG_TRESHOLD): + lat_avg_prefix = bcolors.ENDC + else: + lat_avg_prefix = bcolors.FAIL + if (lat_max< LAT_MAX_TRESHOLD): + lat_max_prefix = bcolors.ENDC + else: + lat_max_prefix = bcolors.FAIL + if (((get_pps(speed,size) - pps_tx)/get_pps(speed,size))<0.001): + speed_prefix = bcolors.ENDC + else: + speed_prefix = bcolors.FAIL + log.debug('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% '+speed_prefix +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | ' + '{:>9.3f}'.format(pps_tx) +' Mpps | '+ bcolors.ENDC + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+lat_avg_prefix+ '{:>9.0f}'.format(lat_avg)+' us | '+lat_max_prefix+ '{:>9.0f}'.format(lat_max)+' us | '+ abs_drop_rate_prefix + '{:>14d}'.format(abs_dropped)+drop_rate_prefix+ ' |''{:>9.2f}'.format(drop_rate)+bcolors.ENDC+ '% | FAILED |'+ lat_warning) + success = False + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info('|{:>7}'.format(size+4)+" | " + '{:>5.1f}'.format(endspeed) + '% ' +'{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+'{:>9.0f}'.format(endlat_max)+' us | '+ '{:>14d}'.format(endabs_dropped)+ ' |'+'{:>9.2f}'.format(enddrop_rate)+ '% |'+ endwarning) + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + writer.writerow({'flow':'1','size':(size+4),'endspeed':endspeed,'endspeedpps':get_pps(endspeed,size),'endpps_req_tx':endpps_req_tx,'endpps_tx':endpps_tx,'endpps_sut_tx_str':endpps_sut_tx_str,'endpps_rx':endpps_rx,'endlat_avg':endlat_avg,'endlat_max':endlat_max,'endabs_dropped':endabs_dropped,'enddrop_rate':enddrop_rate}) + else: + log.debug('|{:>7}'.format(str(size))+" | Speed 0 or close to 0") + gensock.stop(latcores) + +def run_max_frame_rate(gensock,sutsock): + log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------+") + log.info("| UDP, 1 flow, different packet sizes |") + log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") + log.info("|Pktsz| Speed requested | Sent to NIC | Sent by Gen | Fwrd by SUT | Rec. by Gen | Avg. Latency| Max. Latency| Sent | Received | Lost | Total Lost |") + log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") + sleep_time = 3 + gensock.start(latcores) + for size in packet_size_list: + # Sleep_time is needed to be able to do accurate measurements to check for packet loss. We need to make this time large enough so that we do not take the first measurement while some packets from the previous tests migth still be in flight + time.sleep(sleep_time) + size = size-4 + gensock.reset_stats() + if sutsock!='none': + sutsock.reset_stats() + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) + gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) + # This will only work when using sending UDP packets. For different protocls and ehternet types, we would need a differnt calculation + pps_sut_tx_str = 'NO_RESULTS' + speed = STARTSPEED + # Start generating packets at requested speed (in % of a 10Gb/s link) + gensock.speed(speed / len(gencores), gencores) + duration = float(runtime) + first = 1 + tot_drop = 0 + if sutsock!='none': + old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) + old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(genstatcores) + gensock.start(gencores) + while (duration > 0): + time.sleep(0.5) + lat_min, lat_max, lat_avg, lat_used = gensock.lat_stats(latcores) + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + # Get statistics after some execution time + new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) + if sutsock!='none': + new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) + drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM + rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM + tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface + tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. + if tsc == 0 : + continue + if sutsock!='none': + sut_rx = new_sut_rx - old_sut_rx + sut_tx = new_sut_tx - old_sut_tx + sut_tsc = new_sut_tsc - old_sut_tsc + if sut_tsc == 0 : + continue + duration = duration - 1 + old_drop = new_drop + old_rx = new_rx + old_tx = new_tx + old_tsc = new_tsc + pps_req_tx = (tx+drop-rx)*tsc_hz*1.0/(tsc*1000000) + pps_tx = tx*tsc_hz*1.0/(tsc*1000000) + pps_rx = rx*tsc_hz*1.0/(tsc*1000000) + if sutsock!='none': + old_sut_tx = new_sut_tx + old_sut_rx = new_sut_rx + old_sut_tsc= new_sut_tsc + pps_sut_tx = sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000) + pps_sut_tx_str = '{:>7.3f}'.format(pps_sut_tx) + else: + pps_sut_tx = 0 + pps_sut_tx_str = 'NO MEAS.' + if (tx == 0): + log.critical("TX = 0. Test interrupted since no packet has been sent.") + raise Exception("TX = 0") + tot_drop = tot_drop + tx - rx + + if pps_sut_tx_str <> 'NO_RESULTS': + # First second mpps are not valid as there is no alignement between time the generator is started and per seconds stats + if (first): + log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+' |' +' |' +' |'+ ' |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+'{:>7.0f}'.format(tot_drop) +' |'+lat_warning) + else: + log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+ '{:>7.3f}'.format(pps_req_tx)+' Mpps |'+ '{:>7.3f}'.format(pps_tx) +' Mpps |' + '{:>7}'.format(pps_sut_tx_str) +' Mpps |'+ '{:>7.3f}'.format(pps_rx)+' Mpps |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+ '{:>7.0f}'.format(tot_drop) +' |'+lat_warning) + else: + log.debug('|{:>7}'.format(str(size))+" | Speed 0 or close to 0") + first = 0 + if (duration <= 0): + #Stop generating + gensock.stop(gencores) + time.sleep(sleep_time) + lat_min, lat_max, lat_avg, lat_used = gensock.lat_stats(latcores) + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + # Get statistics after some execution time + new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(genstatcores) + if sutsock!='none': + new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores) + drop = new_drop-old_drop # drop is all packets dropped by all tasks. This includes packets dropped at the generator task + packets dropped by the nop task. In steady state, this equals to the number of packets received by this VM + rx = new_rx - old_rx # rx is all packets received by the nop task = all packets received in the gen VM + tx = new_tx - old_tx # tx is all generated packets actually accepted by the interface + tsc = new_tsc - old_tsc # time difference between the 2 measurements, expressed in cycles. + tot_drop = tot_drop + tx - rx + if sutsock!='none': + sut_rx = new_sut_rx - old_sut_rx + sut_tx = new_sut_tx - old_sut_tx + sut_tsc = new_sut_tsc - old_sut_tsc + if pps_sut_tx_str <> 'NO_RESULTS': + log.info('|{:>4}'.format(size+4)+" |" + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps|'+' |' +' |' +' |'+ ' |'+ '{:>8.0f}'.format(lat_avg)+' us |'+'{:>8.0f}'.format(lat_max)+' us | ' + '{:>9.0f}'.format(tx) + ' | '+ '{:>9.0f}'.format(rx) + ' | '+ '{:>7.0f}'.format(tx-rx) + ' | '+ '{:>7.0f}'.format(tot_drop) +' |'+lat_warning) + log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+") + gensock.stop(latcores) + + + +def run_irqtest(sock): + log.info("+----------------------------------------------------------------------------------------------------------------------------") + log.info("| Measuring time probably spent dealing with an interrupt. Interrupting DPDK cores for more than 50us might be problematic ") + log.info("| and result in packet loss. The first row shows the interrupted time buckets: first number is the bucket between 0us and ") + log.info("| that number expressed in us and so on. The numbers in the other rows show how many times per second, the program was ") + log.info("| interrupted for a time as specified by its bucket. '0' is printed when there are no interrupts in this bucket throughout ") + log.info("| the duration of the test. This is to avoid rounding errors in the case of 0.0 ") + log.info("+----------------------------------------------------------------------------------------------------------------------------") + sys.stdout.flush() + buckets=sock.show_irq_buckets(1) + print('Measurement ongoing ... ',end='\r') + sock.stop(irqcores) + old_irq = [[0 for x in range(len(buckets)+1)] for y in range(len(irqcores)+1)] + irq = [[0 for x in range(len(buckets)+1)] for y in range(len(irqcores)+1)] + irq[0][0] = 'bucket us' + for j,bucket in enumerate(buckets,start=1): + irq[0][j] = '<'+ bucket + irq[0][-1] = '>'+ buckets [-2] + sock.start(irqcores) + time.sleep(2) + for j,bucket in enumerate(buckets,start=1): + for i,irqcore in enumerate(irqcores,start=1): + old_irq[i][j] = sock.irq_stats(irqcore,j-1) + time.sleep(float(runtime)) + sock.stop(irqcores) + for i,irqcore in enumerate(irqcores,start=1): + irq[i][0]='core %s '%irqcore + for j,bucket in enumerate(buckets,start=1): + diff = sock.irq_stats(irqcore,j-1) - old_irq[i][j] + if diff == 0: + irq[i][j] = '0' + else: + irq[i][j] = str(round(diff/float(runtime), 2)) + for row in irq: + log.info(''.join(['{:>12}'.format(item) for item in row])) +# log.info('\n'.join([''.join(['{:>12}'.format(item) for item in row]) for row in irq])) + +def run_impairtest(gensock,sutsock): + size=PACKETSIZE-4 + log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+") + log.info("| Generator is sending UDP (1 flow) packets ("+ '{:>5}'.format(size+4) +" bytes) to SUT via GW dropping and delaying packets. SUT sends packets back. Use ctrl-c to stop the test |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + log.info("| Test | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |") + log.info("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+") + attempts = 0 + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-14),2) # 18 is the difference between the frame size and IP size = size of (MAC addresses, ethertype and FCS) + gensock.set_value(gencores,0,38,(size-34),2) # 38 is the difference between the frame size and UDP size = 18 + size of IP header (=20) + # This will only work when using sending UDP packets. For different protocols and ethernet types, we would need a different calculation + gensock.start(latcores) + speed = STARTSPEED + gensock.speed(speed / len(gencores), gencores) + while True: + attempts += 1 + print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') + sys.stdout.flush() + time.sleep(1) + # Get statistics now that the generation is stable and NO ARP messages any more + pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max, abs_dropped, abs_tx, lat_min, lat_used = run_iteration(gensock,sutsock) + drop_rate = 100.0*abs_dropped/abs_tx + if lat_used < 0.95: + lat_warning = bcolors.FAIL + ' Potential latency accuracy problem: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC + else: + lat_warning = '' + log.info('|{:>7}'.format(str(attempts))+" | " + '{:>5.1f}'.format(speed) + '% ' +'{:>6.3f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.3f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.3f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+' us | '+ '{:>9.0f}'.format(lat_max)+' us | '+ '{:>14d}'.format(abs_dropped)+ ' |''{:>9.2f}'.format(drop_rate)+ '% |'+lat_warning) + writer.writerow({'flow':'1','size':(size+4),'endspeed':speed,'endspeedpps':get_pps(speed,size),'endpps_req_tx':pps_req_tx,'endpps_tx':pps_tx,'endpps_sut_tx_str':pps_sut_tx_str,'endpps_rx':pps_rx,'endlat_avg':lat_avg,'endlat_max':lat_max,'endabs_dropped':abs_dropped,'enddrop_rate':drop_rate}) + gensock.stop(latcores) + +def run_inittest(gensock): +# Running at low speed to make sure the ARP messages can get through. +# If not doing this, the ARP message could be dropped by a switch in overload and then the test will not give proper results +# Note hoever that if we would run the test steps during a very long time, the ARP would expire in the switch. +# PROX will send a new ARP request every seconds so chances are very low that they will all fail to get through + gensock.speed(0.01 / len(gencores), gencores) + gensock.start(genstatcores) + time.sleep(2) + gensock.stop(genstatcores) + +global sutstatcores +global genstatcores +global latcores +global gencores +global irqcores +global PACKETSIZE +global packet_size_list +global flow_size_list +global required_number_of_test_machines +clients =[] +socks =[] +socks_control =[] +vmDPIP =[] +vmAdminIP =[] +vmDPmac =[] +hexDPIP =[] +config_file =[] +prox_socket =[] +prox_launch_exit =[] +auto_start =[] +mach_type =[] +sock_type =[] + +data_file = 'RUN{}.{}.csv'.format(env,test) +data_csv_file = open(data_file,'w') +testconfig = ConfigParser.RawConfigParser() +testconfig.read(test+'.test') +required_number_of_test_machines = testconfig.get('DEFAULT', 'total_number_of_test_machines') +config = ConfigParser.RawConfigParser() +config.read(env+'.env') +machine_map = ConfigParser.RawConfigParser() +machine_map.read(machine_map_file +'.cfg') +key = config.get('OpenStack', 'key') +total_number_of_machines = config.get('rapid', 'total_number_of_machines') +if int(required_number_of_test_machines) > int(total_number_of_machines): + log.exception("Not enough VMs for this test: %s needed and only %s available" % (required_number_of_test_machines,total_number_of_machines)) + raise Exception("Not enough VMs for this test: %s needed and only %s available" % (required_number_of_test_machines,total_number_of_machines)) +for vm in range(1, int(total_number_of_machines)+1): + vmAdminIP.append(config.get('M%d'%vm, 'admin_ip')) + vmDPmac.append(config.get('M%d'%vm, 'dp_mac')) + vmDPIP.append(config.get('M%d'%vm, 'dp_ip')) + ip = vmDPIP[-1].split('.') + hexDPIP.append(hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2)) +machine_index = [] +for vm in range(1, int(required_number_of_test_machines)+1): + machine_index.append(int(machine_map.get('TestM%d'%vm, 'machine_index'))-1) + prox_socket.append(testconfig.getboolean('TestM%d'%vm, 'prox_socket')) +for vm in range(1, int(required_number_of_test_machines)+1): + if prox_socket[vm-1]: + prox_launch_exit.append(testconfig.getboolean('TestM%d'%vm, 'prox_launch_exit')) + config_file.append(testconfig.get('TestM%d'%vm, 'config_file')) + with open('{}_{}_parameters{}.lua'.format(env,test,vm), "w") as f: + f.write('name="%s"\n'% testconfig.get('TestM%d'%vm, 'name')) + f.write('local_ip="%s"\n'% vmDPIP[machine_index[vm-1]]) + f.write('local_hex_ip="%s"\n'% hexDPIP[machine_index[vm-1]]) + if re.match('(l2){0,1}gen\.cfg',config_file[-1]): + gencores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'gencores')) + latcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'latcores')) + STARTSPEED = float(testconfig.get('TestM%d'%vm, 'startspeed')) + genstatcores = gencores + latcores + auto_start.append(False) + mach_type.append('gen') + f.write('gencores="%s"\n'% ','.join(map(str, gencores))) + f.write('latcores="%s"\n'% ','.join(map(str, latcores))) + destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 + f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) + f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) + f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) + elif re.match('(l2){0,1}gen_gw\.cfg',config_file[-1]): + gencores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'gencores')) + latcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'latcores')) + STARTSPEED = float(testconfig.get('TestM%d'%vm, 'startspeed')) + genstatcores = gencores + latcores + auto_start.append(False) + mach_type.append('gen') + f.write('gencores="%s"\n'% ','.join(map(str, gencores))) + f.write('latcores="%s"\n'% ','.join(map(str, latcores))) + gwVMindex = int(testconfig.get('TestM%d'%vm, 'gw_vm')) -1 + f.write('gw_ip="%s"\n'% vmDPIP[machine_index[gwVMindex]]) + f.write('gw_hex_ip="%s"\n'% hexDPIP[machine_index[gwVMindex]]) + destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 + f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) + f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) + f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) + elif re.match('(l2){0,1}swap.*\.cfg',config_file[-1]): + sutstatcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'swapcores')) + auto_start.append(True) + mach_type.append('sut') + f.write('swapcores="%s"\n'% ','.join(map(str, sutstatcores))) + elif config_file[-1] == 'secgw1.cfg': + auto_start.append(True) + mach_type.append('none') + f.write('secgwcores="%s"\n'% ','.join(map(str, ast.literal_eval(testconfig.get('TestM%d'%vm, 'secgwcores'))))) + destVMindex = int(testconfig.get('TestM%d'%vm, 'dest_vm'))-1 + f.write('dest_ip="%s"\n'% vmDPIP[machine_index[destVMindex]]) + f.write('dest_hex_ip="%s"\n'% hexDPIP[machine_index[destVMindex]]) + f.write('dest_hex_mac="%s"\n'% vmDPmac[machine_index[destVMindex]].replace(':',' ')) + elif config_file[-1] == 'secgw2.cfg': + sutstatcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'secgwcores')) + auto_start.append(True) + mach_type.append('sut') + f.write('secgwcores="%s"\n'% ','.join(map(str, sutstatcores))) + elif config_file[-1] == 'impair.cfg': + auto_start.append(True) + mach_type.append('none') + f.write('impaircores="%s"\n'% ','.join(map(str, ast.literal_eval(testconfig.get('TestM%d'%vm, 'impaircores'))))) + elif config_file[-1] == 'irq.cfg': + irqcores = ast.literal_eval(testconfig.get('TestM%d'%vm, 'irqcores')) + auto_start.append(False) + mach_type.append('irq') + f.write('irqcores="%s"\n'% ','.join(map(str, irqcores))) + f.close +##################################################################################### +def exit_handler(): + log.debug ('exit cleanup') + for index, sock in enumerate(socks): + if socks_control[index]: + sock.quit() + for client in clients: + client.close() + data_csv_file.close + sys.exit(0) + +atexit.register(exit_handler) + +for vm in range(0, int(required_number_of_test_machines)): + if prox_socket[vm]: + clients.append(prox_ctrl(vmAdminIP[machine_index[vm]], key+'.pem','root')) + connect_client(clients[-1]) +# Creating script to bind the right network interface to the poll mode driver + devbindfile = '{}_{}_devbindvm{}.sh'.format(env,test, vm+1) + with open("devbind.sh") as f: + newText=f.read().replace('MACADDRESS', vmDPmac[machine_index[vm]]) + with open(devbindfile, "w") as f: + f.write(newText) + st = os.stat(devbindfile) + os.chmod(devbindfile, st.st_mode | stat.S_IEXEC) + clients[-1].scp_put('./%s'%devbindfile, '/root/devbind.sh') + cmd = '/root/devbind.sh' + clients[-1].run_cmd(cmd) + log.debug("devbind.sh running on VM%d"%(vm+1)) + clients[-1].scp_put('./%s'%config_file[vm], '/root/%s'%config_file[vm]) + clients[-1].scp_put('./{}_{}_parameters{}.lua'.format(env,test, vm+1), '/root/parameters.lua') + if not configonly: + if prox_launch_exit[vm]: + log.debug("Starting PROX on VM%d"%(vm+1)) + if auto_start[vm]: + cmd = '/root/prox/build/prox -t -o cli -f /root/%s'%config_file[vm] + else: + cmd = '/root/prox/build/prox -e -t -o cli -f /root/%s'%config_file[vm] + clients[-1].fork_cmd(cmd, 'PROX Testing on TestM%d'%(vm+1)) + socks_control.append(prox_launch_exit[vm]) + socks.append(connect_socket(clients[-1])) + sock_type.append(mach_type[vm]) +socks.append('none') +socks_control.append(False) + +def get_BinarySearchParams() : + global DROP_RATE_TRESHOLD + global LAT_AVG_TRESHOLD + global LAT_MAX_TRESHOLD + global ACCURACY + global STARTSPEED + DROP_RATE_TRESHOLD = float(testconfig.get('BinarySearchParams', 'drop_rate_threshold')) + LAT_AVG_TRESHOLD = float(testconfig.get('BinarySearchParams', 'lat_avg_threshold')) + LAT_MAX_TRESHOLD = float(testconfig.get('BinarySearchParams', 'lat_max_threshold')) + ACCURACY = float(testconfig.get('BinarySearchParams', 'accuracy')) + +if configonly: + sys.exit() +#################################################### +# Run test cases +# Best to run the flow test at the end since otherwise the tests coming after might be influenced by the big number of entries in the switch flow tables +#################################################### +gensock_index = sock_type.index('gen') if 'gen' in sock_type else -1 +sutsock_index = sock_type.index('sut') if 'sut' in sock_type else -1 +irqsock_index = sock_type.index('irq') if 'irq' in sock_type else -1 +number_of_tests = testconfig.get('DEFAULT', 'number_of_tests') +with data_csv_file: + fieldnames = ['flow','size','endspeed','endspeedpps','endpps_req_tx','endpps_tx','endpps_sut_tx_str','endpps_rx','endlat_avg','endlat_max','endabs_dropped','enddrop_rate'] + writer = csv.DictWriter(data_csv_file, fieldnames=fieldnames) + writer.writeheader() + for test_nr in range(1, int(number_of_tests)+1): + test=testconfig.get('test%d'%test_nr,'test') + log.info(test) + if test == 'speedtest': + get_BinarySearchParams() + PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) + run_speedtest(socks[gensock_index],socks[sutsock_index]) + elif test == 'flowtest': + get_BinarySearchParams() + PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) + flow_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'flows')) + run_flowtest(socks[gensock_index],socks[sutsock_index]) + elif test == 'sizetest': + get_BinarySearchParams() + packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes')) + run_sizetest(socks[gensock_index],socks[sutsock_index]) + elif test == 'max_frame_rate': +# PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) + packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes')) + run_max_frame_rate(socks[gensock_index],socks[sutsock_index]) + elif test == 'impairtest': + get_BinarySearchParams() + PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize')) + run_impairtest(socks[gensock_index],socks[sutsock_index]) + elif test == 'irqtest': + run_irqtest(socks[irqsock_index]) + elif test == 'inittest': + run_inittest(socks[gensock_index]) +#################################################### diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test new file mode 100644 index 00000000..cf1b5522 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test @@ -0,0 +1,55 @@ +## +## Copyright (c) 2010-2018 Intel Corporation +## +## 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. +## + +[DEFAULT] +name = GWTesting +number_of_tests = 2 +total_number_of_test_machines = 3 +prox_socket = true +prox_launch_exit = true + +[TestM1] +name = Generator +config_file = gen_gw.cfg +dest_vm = 3 +gw_vm = 2 +gencores = [1] +latcores = [3] +startspeed = 10 + +[TestM2] +name = GW1 +config_file = secgw1.cfg +dest_vm = 3 +secgwcores = [1] + +[TestM3] +name = GW2 +config_file = secgw2.cfg +secgwcores = [1] + +[BinarySearchParams] +drop_rate_threshold = 0.1 +lat_avg_threshold = 500 +lat_max_threshold = 1000 +accuracy = 0.1 + +[test1] +test=inittest + +[test2] +test=speedtest +packetsize=64 diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/secgw1.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw1.cfg new file mode 100644 index 00000000..301a138e --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw1.cfg @@ -0,0 +1,54 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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 is sample ESP config. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=if +mac=hardware + +[variables] +$tun_hop_limit=5 +$lookup_port_mask=0xffc0 + +[defaults] +mempool size=16K + +[global] +start time=20 +name=${name} + +[core 0] +mode=master + +[core $secgwcores] +name=esp_enc +task=0 +mode=esp_enc +sub mode=l3 +local ipv4=${local_ip} +remote ipv4=${dest_ip} +rx port=if +tx port=if diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/secgw2.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw2.cfg new file mode 100644 index 00000000..9c970e83 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw2.cfg @@ -0,0 +1,55 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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 is sample ESP config. +;; +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=if +mac=hardware + +[variables] +$tun_hop_limit=5 +$lookup_port_mask=0xffc0 + +[defaults] +mempool size=16K + +[global] +start time=20 +name=${name} + +[core 0] +mode=master + +[core $secgwcores] +name=esp_dec +task=0 +mode=esp_dec +sub mode=l3 +local ipv4=${local_ip} +rx port=if +tx port=if + + + diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg new file mode 100644 index 00000000..47cb0b07 --- /dev/null +++ b/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg @@ -0,0 +1,46 @@ +;; +;; Copyright (c) 2010-2017 Intel Corporation +;; +;; 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. +;; + +[eal options] +-n=4 ; force number of memory channels +no-output=no ; disable DPDK debug output + +[lua] +dofile("parameters.lua") + +[port 0] +name=if0 +mac=hardware + +[defaults] +mempool size=2K + +[global] +name=${name} + +[core 0] +mode=master + +[core $swapcores] +name=swap +task=0 +mode=swap +sub mode=l3 +rx port=if0 +tx port=if0 +local ipv4=${local_ip} +drop=no +;arp update time=1 -- cgit 1.2.3-korg