summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Provoost <luc.provoost@intel.com>2019-06-30 09:46:10 +0200
committerLuc Provoost <luc.provoost@intel.com>2019-06-30 09:46:10 +0200
commitccae9496c217020455acfe337aaf2b2f0c5644d8 (patch)
tree4f9165a7f2cbf77290b80a6545400e9cd7d7b00c
parent080733bfa5facd0eb457fc3db1c3ee7885f2a438 (diff)
Multiple changes for June release
- Change inittest in warmuptest. This has now a warmuptime, warmupspeed, packet size and flow size. - Change in centos.json. This will now also copy deploycentostools.sh during image building so that it can be used to re-compile prox in the VM by typing "./deploycentostools.sh compile" - runrapid.py parameters needing a file name, need to be complete file names: no extensions will be added any more by the scripts. - Changes in createrapid.py to handel the openstack CLI output in a simpler way. - The management interface of the VMs can now also be an SRIOV interface. We have now an extra optional parameter in the VM sections of the rapiVMs.vms file: SRIOV_mgmt_port - Changed the name of some sections and keys in the environment file since runrapid.py will not always communicate to OpenStack VMs. This could be containers or any other (virtual) machine. - The previous MachineMap.cfg has been renamed to machine.map - A new test has been added: monitorswap is just showing the statistics of a swap (virtual) machine, without generating any packets. This is useful in situations where an external tester is used. - Latency and core statistics can now be measured even if there are multiple PROX cores and tasks running. A new parameter has been added in the test files with following default value: tasks=[0]. During the collection of statistics, all tasks in this list will be queried. It is ok to have a non-existing task in such a query since it will be ignored. - A --screenlog parameter was added for runrapid.py allowing for more detailed output on the screen during debugging. No need to check the log file. - Previous tests to run multiple packet size with a given flow size and to run multiple flow size, with a given packet size are now combined by specifiying 2 lists: packetsizes & flows - The screen output of this test has also been reworked with more meaningful column names and the test result is now in the field "core received". This allows also for faster termination of the test: When the all packets sent by Gen NIC are received by the cores within the thresholds for packet loss and latency, the test is now stopped, even we were requesting more packets to be sent. Change-Id: I3307e7a972f2140e739f376f146fe875df0303e6 Signed-off-by: Luc Provoost <luc.provoost@intel.com>
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/README53
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/bare.test56
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test31
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/centos.json24
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service1
-rwxr-xr-xVNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh13
-rwxr-xr-xVNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py279
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/deploycentostools.sh (renamed from VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh)45
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg4
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg4
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/impair.test9
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/irq.test1
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test11
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg4
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/l2gen_bare.cfg59
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test28
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test13
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/machine.map (renamed from VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg)0
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/monitorswap.test31
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py50
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms3
-rwxr-xr-xVNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py837
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test16
-rwxr-xr-xVNFs/DPPD-PROX/helper-scripts/rapid/sharkproxlog.sh1
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg1
25 files changed, 861 insertions, 713 deletions
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/README b/VNFs/DPPD-PROX/helper-scripts/rapid/README
index 43243a6..cb3a4fd 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/README
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/README
@@ -18,21 +18,21 @@ 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.
+dataplane performance of an OpenStack or container 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.
+In case of OpenStack, copy the files in a directory on a machine that can run the OpenStack CLI
+commands and that can reach the 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.
+You can also build this image manually by executing all the commands described in the deploycentostools.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
+There are 2 files: centos.json and deploycentostools.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
@@ -46,7 +46,7 @@ be the ID's of your system:
- "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.
+but also does some system optimizations (tuned). Check deploycentostools.sh for more details.
Now you can run the createrapid.py file. Use help for more info on the usage:
# ./createrapid.py --help
@@ -106,44 +106,43 @@ 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 key information in the [ssh] section
* the total_number_of_vms information in the [rapid] section
-[DEFAULT]
-admin_ip = none
+[rapid]
+loglevel = DEBUG
+version = 19.6.30
+total_number_of_machines = 3
[M1]
name = rapid-VM1
-admin_ip = 10.25.1.116
-dp_ip = 10.10.10.7
-dp_mac = fa:16:3e:59:b8:28
+admin_ip = 10.25.1.109
+dp_ip = 10.10.10.4
+dp_mac = fa:16:3e:25:be:25
[M2]
name = rapid-VM2
-admin_ip = 10.25.1.126
-dp_ip = 10.10.10.11
-dp_mac = fa:16:3e:c9:54:c7
+admin_ip = 10.25.1.110
+dp_ip = 10.10.10.7
+dp_mac = fa:16:3e:72:bf:e8
[M3]
name = rapid-VM3
-admin_ip = 10.25.1.108
+admin_ip = 10.25.1.125
dp_ip = 10.10.10.15
-dp_mac = fa:16:3e:72:90:3e
+dp_mac = fa:16:3e:69:f3:e7
-[OpenStack]
-stack = rapid
-vms = rapidVMs
+[ssh]
key = prox
+
+[Varia]
+vim = OpenStack
+stack = rapid
+vms = rapidVMs.vms
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
-
+floating_network = admin_floating_net
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/bare.test b/VNFs/DPPD-PROX/helper-scripts/rapid/bare.test
new file mode 100644
index 0000000..e686e15
--- /dev/null
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/bare.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 = BareTesting
+number_of_tests = 2
+total_number_of_test_machines = 2
+prox_socket = true
+prox_launch_exit = true
+tasks=[0]
+
+[TestM1]
+name = Generator
+config_file = l2gen_bare.cfg
+dest_vm = 2
+gencores = [1]
+latcores = [3]
+
+[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
+startspeed = 10
+
+[test1]
+test=warmuptest
+flowsize=1024
+packetsize=64
+warmupspeed=10
+warmuptime=2
+
+[test2]
+test=flowsizetest
+packetsizes=[64,128]
+# 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]
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test b/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test
index b2f8f23..4bdfdda 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/basicrapid.test
@@ -16,10 +16,11 @@
[DEFAULT]
name = BasicSwapTesting
-number_of_tests = 4
+number_of_tests = 2
total_number_of_test_machines = 2
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -27,7 +28,6 @@ config_file = gen.cfg
dest_vm = 2
gencores = [1]
latcores = [3]
-startspeed = 10
[TestM2]
name = Swap
@@ -36,25 +36,22 @@ swapcores = [1]
[BinarySearchParams]
drop_rate_threshold = 0.1
-lat_avg_threshold = 500
-lat_max_threshold = 1000
+lat_avg_threshold = 400
+lat_max_threshold = 800
accuracy = 0.1
+startspeed = 10
[test1]
-test=inittest
-
-[test2]
-test=speedtest
+test=warmuptest
+flowsize=1024
packetsize=64
+warmupspeed=1
+warmuptime=2
-[test3]
-test=sizetest
-flow=1
-packetsizes=[64,256,1024]
-
-[test4]
-test=flowtest
-packetsize=64
+[test2]
+test=flowsizetest
+packetsizes=[64,128]
# 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]
+flows=[1,512]
+
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json b/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json
index 237a648..3754ea0 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/centos.json
@@ -6,12 +6,14 @@
"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",
+"source_image": "09ada6c0-21aa-49aa-ad7b-d364f279ee92",
+"flavor": "2d198ea9-7cbc-4211-9983-531493b07a96",
+"networks": "2d2bb4ec-58ae-47a4-8af9-f58f14533337",
"use_floating_ip": true,
-"floating_ip_pool": "d629619f-8f96-4f32-9b90-1b62e5ea3809",
-"security_groups": "460b7929-c6de-4b1c-ae83-901c2042a894"
+"floating_ip_pool": "ff966059-9dd2-4ed1-ad9a-5fae516eb0fa",
+"security_groups": "1da93e77-29c2-42d7-b611-f2ae094aa8df",
+"ssh_timeout":"1000s",
+"ssh_pty":"true"
}
],
"provisioners": [
@@ -26,8 +28,18 @@
"destination": "/home/centos/"
},
{
+ "type": "file",
+ "source": "./sharkproxlog.sh",
+ "destination": "/home/centos/"
+ },
+ {
+ "type": "file",
+ "source": "./deploycentostools.sh",
+ "destination": "/home/centos/"
+ },
+ {
"type": "shell",
- "script": "deploycentos.sh"
+ "script": "deploycentostools.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
index a55e0c0..6339d3e 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/check-prox-system-setup.service
@@ -9,3 +9,4 @@ 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
index 4899951..9effa53 100755
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/check_prox_system_setup.sh
@@ -26,16 +26,16 @@ then
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
+ 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
+ tuned-adm profile realtime-virtual-guest
reboot
- exit 0
+ exit 0
;;
*)
echo "$line"
@@ -43,9 +43,10 @@ then
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
+ 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
index a1c1de6..3fbdc4c 100755
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/createrapid.py
@@ -31,10 +31,10 @@ from logging import handlers
from prox_ctrl import prox_ctrl
import ConfigParser
-version="19.4.15"
+version="19.6.30"
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
+vms = "rapidVMs.vms" #Default string for vms file
+key = "prox" # default name for key
image = "rapidVM" # default name for the image
image_file = "rapidVM.qcow2"
dataplane_network = "dataplane-network" # default name for the dataplane network
@@ -43,7 +43,6 @@ 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]")
@@ -65,7 +64,7 @@ def usage():
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(" --vms VMS_FILE Specify the vms file to be used. Default is %s."%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)
@@ -142,7 +141,7 @@ file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
log = logging.getLogger()
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
- raise ValueError('Invalid log level: %s' % loglevel)
+ raise ValueError('Invalid log level: %s' % loglevel)
log.setLevel(numeric_level)
log.propagate = 0
@@ -173,58 +172,82 @@ 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 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("Checking control plane network: " + internal_network)
+cmd = 'openstack network list -f value -c Name'
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")
+Networks = subprocess.check_output(cmd , shell=True).decode().strip()
+if internal_network in Networks:
+ 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")
+# Checking if the floating ip network should be used. If yes, check if it exists and stop the script if it doesn't
+if floating_network !='NO':
+ log.debug("Checking floating ip network: " + floating_network)
+ if floating_network in Networks:
+ 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 dataplane network already exists, if not create it
+log.debug("Checking dataplane network: " + dataplane_network)
+if dataplane_network in Networks:
+ log.info("Dataplane network (" + dataplane_network + ") already active")
+else:
+ log.info('Creating dataplane network ...')
+ cmd = 'openstack network create '+dataplane_network+' -f value -c status'
+ log.debug(cmd)
+ NetworkExist = subprocess.check_output(cmd , shell=True).decode().strip()
+ if 'ACTIVE' in NetworkExist:
+ log.info("Dataplane network created")
+ # Checking if the dataplane subnet already exists, if not create it
+ log.debug("Checking subnet: "+subnet)
+ cmd = 'openstack subnet list -f value -c Name'
+ log.debug (cmd)
+ Subnets = subprocess.check_output(cmd , shell=True).decode().strip()
+ if subnet in Subnets:
+ 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+' -f value -c name'
+ log.debug(cmd)
+ Subnets = subprocess.check_output(cmd , shell=True).decode().strip()
+ if subnet in Subnets:
+ log.info("Subnet created")
+ else :
+ log.exception("Failed to create subnet: " + subnet)
+ raise Exception("Failed to create subnet: " + subnet)
+ else :
+ log.exception("Failed to create dataplane network: " + dataplane_network)
+ raise Exception("Failed to create dataplane network: " + dataplane_network)
+
# Checking if the image already exists, if not create it
-log.debug("Checking image: "+image)
-cmd = 'openstack image show '+image
+log.debug("Checking image: " + image)
+cmd = 'openstack image list -f value -c Name'
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")
+Images = subprocess.check_output(cmd , shell=True).decode().strip()
+if image in Images:
+ 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
+ cmd = 'openstack image create -f value -c status --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':
+ ImageExist = subprocess.check_output(cmd , shell=True).decode().strip()
+ if 'active' in ImageExist:
log.info('Image created and active')
- cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image
+# cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image
# subprocess.check_call(cmd , shell=True)
else :
log.exception("Failed to create image")
@@ -232,11 +255,10 @@ else:
# Checking if the key already exists, if not create it
log.debug("Checking key: "+key)
-cmd = 'openstack keypair show '+key
+cmd = 'openstack keypair list -f value -c Name'
log.debug (cmd)
-cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
-KeyExist = subprocess.check_output(cmd , shell=True).strip()
-if KeyExist == key:
+KeyExist = subprocess.check_output(cmd , shell=True).decode().strip()
+if key in KeyExist:
log.info("Key ("+key+") already installed")
else:
log.info('Creating key ...')
@@ -245,95 +267,51 @@ else:
subprocess.check_call(cmd , shell=True)
cmd = 'chmod 600 ' +key+'.pem'
subprocess.check_call(cmd , shell=True)
- cmd = 'openstack keypair show '+key
+ cmd = 'openstack keypair list -f value -c Name'
log.debug(cmd)
- cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
- KeyExist = subprocess.check_output(cmd , shell=True).strip()
- if KeyExist == key:
+ KeyExist = subprocess.check_output(cmd , shell=True).decode().strip()
+ if key in KeyExist:
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')
+vmconfig.read(vms)
total_number_of_VMs = vmconfig.get('DEFAULT', 'total_number_of_vms')
+cmd = 'openstack server list -f value -c Name'
+log.debug (cmd)
+Servers = subprocess.check_output(cmd , shell=True).decode().strip()
+cmd = 'openstack flavor list -f value -c Name'
+log.debug (cmd)
+Flavors = subprocess.check_output(cmd , shell=True).decode().strip()
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')
+ SRIOV_mgmt_port = vmconfig.get('VM%d'%vm, 'SRIOV_mgmt_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")
+ log.debug("Checking server: " + ServerName[-1])
+ if ServerName[-1] in Servers:
+ 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")
+ log.debug("Checking flavor: " + flavor_name)
+ if flavor_name in Flavors:
+ log.info("Flavor (" + flavor_name+") already installed")
else:
log.info('Creating flavor ...')
- cmd = 'openstack flavor create %s %s'%(flavor_name,flavor_info)
+ cmd = 'openstack flavor create %s %s -f value -c name'%(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:
+ NewFlavor = subprocess.check_output(cmd , shell=True).decode().strip()
+ if flavor_name in NewFlavor:
cmd = 'openstack flavor set %s %s'%(flavor_name, flavor_meta_data)
log.debug(cmd)
subprocess.check_call(cmd , shell=True)
@@ -341,55 +319,61 @@ for vm in range(1, int(total_number_of_VMs)+1):
else :
log.exception("Failed to create flavor: " + flavor_name)
raise Exception("Failed to create flavor: " + flavor_name)
+ if SRIOV_mgmt_port == 'NO':
+ nic_info = '--nic net-id=%s'%(internal_network)
+ else:
+ for port in SRIOV_mgmt_port.split(','):
+ nic_info = '--nic port-id=%s'%(port)
if SRIOV_port == 'NO':
- nic_info = '--nic net-id=%s --nic net-id=%s'%(internal_network,dataplane_network)
+ nic_info = nic_info + ' --nic net-id=%s'%(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 '
+ # In that case, we might be too fast when we query for the IP & MAC addresses.
+ wait = '--wait'
else:
- wait = ' '
+ 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])
+ 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':
+ output = subprocess.check_output(cmd , shell=True).decode().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()
-
+ 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).decode().strip()
+ cmd = 'openstack port list -c ID -c "Fixed IP Addresses" | grep %s | cut -d" " -f 2 ' %(vmportIP)
+ log.debug(cmd)
+ vmportID = subprocess.check_output(cmd , shell=True).decode().strip()
+ cmd = 'openstack floating ip create --port %s %s'%(vmportID,floating_network)
+ log.debug(cmd)
+ output = subprocess.check_output(cmd , shell=True).decode().strip()
+
+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)
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)
+ output = subprocess.check_output(cmd , shell=True).decode().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)
+ 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()
+ vmDPmac = subprocess.check_output(cmd , shell=True).decode().strip()
config.add_section('M%d'%vm)
config.set('M%d'%vm, 'name', ServerName[vm-1])
config.set('M%d'%vm, 'admin_ip', vmAdminIP)
@@ -397,22 +381,19 @@ for vm in range(1, int(total_number_of_VMs)+1):
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')
+config.add_section('ssh')
+config.set('ssh', 'key', key)
+config.add_section('Varia')
+config.set('Varia', 'VIM', 'OpenStack')
+config.set('Varia', 'stack', stack)
+config.set('Varia', 'VMs', vms)
+config.set('Varia', 'image', image)
+config.set('Varia', 'image_file', image_file)
+config.set('Varia', 'dataplane_network', dataplane_network)
+config.set('Varia', 'subnet', subnet)
+config.set('Varia', 'subnet_cidr', subnet_cidr)
+config.set('Varia', 'internal_network', internal_network)
+config.set('Varia', 'floating_network', floating_network)
# Writing the environment file
with open(stack+'.env', 'wb') as envfile:
- config.write(envfile)
+ config.write(envfile)
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh b/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentostools.sh
index 848520c..883244f 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentos.sh
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/deploycentostools.sh
@@ -16,9 +16,9 @@
##
BUILD_DIR="/opt/openstackrapid"
-COPY_DIR="/home/centos" # Directory where the packer tool has copied some files
+COPY_DIR="/home/centos" # Directory where the packer tool has copied some files (e.g. check_prox_system_setup.sh)
DPDK_VERSION="18.08"
-PROX_COMMIT="af95b812"
+PROX_COMMIT="c8e9e6bb696363a397b2e718eb4d3e5f38a8ef22"
export RTE_SDK="${BUILD_DIR}/dpdk-${DPDK_VERSION}"
export RTE_TARGET="x86_64-native-linuxapp-gcc"
@@ -31,7 +31,7 @@ function os_pkgs_install()
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
+ numactl-devel vim tuna openssl-devel nasm wireshark
}
function os_cfg()
@@ -39,10 +39,7 @@ 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/
+ # huge pages to be used by DPDK
sudo sh -c '(echo "vm.nr_hugepages = 1024") > /etc/sysctl.conf'
# Enabling tuned with the realtime-virtual-guest profile
@@ -115,25 +112,37 @@ function dpdk_install()
popd > /dev/null 2>&1
}
+function prox_compile()
+{
+ # Compile PROX
+ pushd ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX
+ make -j`getconf _NPROCESSORS_ONLN`
+ 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
+ prox_compile
+ sudo ln -s ${BUILD_DIR}/samplevnf/VNFs/DPPD-PROX /root/prox
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
+if [ "$1" == "compile" ]; then
+ prox_compile
+else
+ echo "Positional parameter 1 is empty"
+ [ ! -d ${BUILD_DIR} ] && sudo mkdir -p ${BUILD_DIR}
+ sudo chmod 0777 ${BUILD_DIR}
+
+ os_pkgs_install
+ os_cfg
+ mblib_install
+ dpdk_install
+ prox_install
+fi
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg
index 42cfdc1..0b52430 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/gen.cfg
@@ -56,7 +56,7 @@ drop=yes
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
signature pos=56
;arp update time=1
@@ -69,7 +69,7 @@ rx port=p0
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
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
index e819041..d6a2fa9 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/gen_gw.cfg
@@ -56,7 +56,7 @@ drop=yes
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
signature pos=56
;arp update time=1
@@ -69,6 +69,6 @@ rx port=p0
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
signature pos=56
;arp update time=1
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test
index 9b633d9..d1b0e36 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/impair.test
@@ -20,6 +20,7 @@ number_of_tests = 2
total_number_of_test_machines = 3
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -28,7 +29,6 @@ gw_vm = 2
dest_vm = 3
gencores = [1]
latcores = [3]
-startspeed = 10
[TestM2]
name = ImpairGW
@@ -45,9 +45,14 @@ drop_rate_threshold = 0.1
lat_avg_threshold = 500
lat_max_threshold = 1000
accuracy = 0.1
+startspeed = 10
[test1]
-test=inittest
+test=warmuptest
+flowsize=1024
+packetsize=64
+warmupspeed=10
+warmuptime=2
[test2]
test=impairtest
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test
index b8dc706..78b6848 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/irq.test
@@ -20,6 +20,7 @@ number_of_tests = 1
total_number_of_test_machines = 1
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = InterruptTesting
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test
index 44fefdd..a9f8d0a 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2framerate.test
@@ -20,6 +20,7 @@ number_of_tests = 2
total_number_of_test_machines = 2
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -35,8 +36,14 @@ config_file = l2swap.cfg
swapcores = [1]
[test1]
-test=inittest
+test=warmuptest
+flowsize=1024
+packetsize=64
+warmupspeed=10
+warmuptime=2
+
[test2]
-test=max_frame_rate
+test=fixed_rate
packetsizes=[256]
+speed=10
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg
index 1469604..3a3cf2c 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen.cfg
@@ -55,7 +55,7 @@ drop=yes
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
signature pos=56
[core $latcores]
@@ -66,5 +66,5 @@ rx port=p0
lat pos=42
accuracy pos=46
packet id pos=50
-signature=0x6789abcd
+signature=0x98765432
signature pos=56
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen_bare.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen_bare.cfg
new file mode 100644
index 0000000..7914062
--- /dev/null
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2gen_bare.cfg
@@ -0,0 +1,59 @@
+;;
+;; 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
+local ipv4=${local_ip}
+min bulk size=$mbs
+max bulk size=64
+drop=yes
+
+[core $latcores]
+name=drop
+task=0
+mode=none
+rx port=p0
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test
index 0406590..af60c40 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l2zeroloss.test
@@ -16,10 +16,11 @@
[DEFAULT]
name = L2BasicSwapTesting
-number_of_tests = 4
+number_of_tests = 2
total_number_of_test_machines = 2
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -27,7 +28,6 @@ config_file = l2gen.cfg
dest_vm = 2
gencores = [1]
latcores = [3]
-startspeed = 10
[TestM2]
name = Swap
@@ -39,18 +39,20 @@ drop_rate_threshold = 0
lat_avg_threshold = 500
lat_max_threshold = 1000
accuracy = 0.1
-
+startspeed = 10
[test1]
-test=inittest
-
-[test2]
-test=speedtest
+test=warmuptest
+flowsize=1024
packetsize=64
+warmupspeed=1
+warmuptime=2
-[test3]
-test=sizetest
-
-[test4]
-test=flowtest
-packetsize=64
+[test2]
+test=flowsizetest
+packetsizes=[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]
+#
+#
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test b/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test
index 21bf810..81d9989 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/l3framerate.test
@@ -20,6 +20,7 @@ number_of_tests = 2
total_number_of_test_machines = 2
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -27,7 +28,6 @@ config_file = gen.cfg
dest_vm = 2
gencores = [1]
latcores = [3]
-startspeed = 10
[TestM2]
name = Swap
@@ -35,8 +35,13 @@ config_file = swap.cfg
swapcores = [1]
[test1]
-test=inittest
+test=warmuptest
+flowsize=1024
+packetsize=64
+warmupspeed=10
+warmuptime=2
[test2]
-test=max_frame_rate
-packetsizes=[256]
+test=fixed_rate
+packetsizes=[64]
+speed=10
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/machine.map
index b6e199d..b6e199d 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/MachineMap.cfg
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/machine.map
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/monitorswap.test b/VNFs/DPPD-PROX/helper-scripts/rapid/monitorswap.test
new file mode 100644
index 0000000..76da234
--- /dev/null
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/monitorswap.test
@@ -0,0 +1,31 @@
+##
+## 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 = MonitorSwap
+number_of_tests = 1
+total_number_of_test_machines = 1
+prox_socket = true
+prox_launch_exit = false
+tasks=[0]
+
+[TestM1]
+name = Swap
+config_file = swap.cfg
+swapcores = [1]
+
+[test1]
+test=measureswap
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py b/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py
index 3ee28c0..bda3e5d 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py
@@ -183,15 +183,21 @@ class prox_sock(object):
def reset_stats(self):
self._send('reset stats')
- def lat_stats(self, cores, task=0):
+ def lat_stats(self, cores, tasks={0}):
min_lat = 999999999
max_lat = avg_lat = 0
- self._send('lat stats %s %s' % (','.join(map(str, cores)), task))
+ self._send('lat stats %s %s' % (','.join(map(str, cores)), ','.join(map(str, tasks))))
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])
+ for task in tasks:
+ stats = self._recv().split(',')
+ if stats[0].startswith('error'):
+ if stats[0].startswith('error: invalid syntax'):
+ log.critical("dp core stats error: unexpected invalid syntax (potential incompatibility between scripts and PROX)")
+ raise Exception("dp core stats error")
+ continue
+ 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())
@@ -211,19 +217,27 @@ class prox_sock(object):
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))
+ def core_stats(self, cores, tasks={0}):
+ rx = tx = drop = tsc = hz = rx_non_dp = tx_non_dp = tx_fail = 0
+ self._send('dp core stats %s %s' % (','.join(map(str, cores)), ','.join(map(str, tasks))))
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
+ for task in tasks:
+ stats = self._recv().split(',')
+ if stats[0].startswith('error'):
+ if stats[0].startswith('error: invalid syntax'):
+ log.critical("dp core stats error: unexpected invalid syntax (potential incompatibility between scripts and PROX)")
+ raise Exception("dp core stats error")
+ continue
+ rx += int(stats[0])
+ tx += int(stats[1])
+ rx_non_dp += int(stats[2])
+ tx_non_dp += int(stats[3])
+ drop += int(stats[4])
+ tx_fail += int(stats[5])
+ tsc = int(stats[6])
+ hz = int(stats[7])
+ return rx,rx_non_dp, tx,tx_non_dp, drop, tx_fail, tsc, hz
+ #return rx-rx_non_dp, tx-tx_non_dp, drop, tx_fail, 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))
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms b/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms
index d18184d..b83c0d0 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/rapidVMs.vms
@@ -22,8 +22,9 @@ 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
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 default --config-drive=true
boot_info=--availability-zone nova --security-group prox
+SRIOV_mgmt_port=NO
SRIOV_port=NO
[VM1]
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py b/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py
index 3b0eeb8..159550c 100755
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py
@@ -34,11 +34,12 @@ 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
+version="19.6.30"
+env = "rapid.env" #Default string for environment
+test_file = "basicrapid.test" #Default string for test
+machine_map_file = "machine.map" #Default string for machine map file
loglevel="DEBUG" # sets log level for writing to file
+screenloglevel="INFO" # sets log level for writing to screen
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
@@ -56,17 +57,18 @@ def usage():
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(" --env ENVIRONMENT_NAME Parameters will be read from ENVIRONMENT_NAME. Default is %s."%env)
+ print(" --test TEST_NAME Test cases will be read from TEST_NAME. Default is %s."%test_file)
+ print(" --map MACHINE_MAP_FILE Machine mapping will be read from MACHINE_MAP_FILE. 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(" --log Specify logging level for log file output, default is DEBUG")
+ print(" --screenlog Specify logging level for screen output, default is INFO")
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="])
+ opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "env=", "test=", "map=", "runtime=","configonly=","log=","screenlog="])
except getopt.GetoptError as err:
print("===========================================")
print(str(err))
@@ -85,32 +87,41 @@ for opt, arg in opts:
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")
+ test_file = arg
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 configonly == 'True':
+ configonly = True
+ print('No actual runs, only uploading configuration files')
+ else:
+ configonly = False
+ print('--configonly parameter is defaulted to False')
if opt in ("--log"):
loglevel = arg
print ("Log level: "+ loglevel)
+ if opt in ("--screenlog"):
+ screenloglevel = arg
+ print ("Screen Log level: "+ screenloglevel)
+
+print ("Using '"+env+"' as name for the environment")
+print ("Using '"+test_file+"' for test case definition")
+print ("Using '"+machine_map_file+"' for machine mapping")
+print ("Runtime: "+ runtime)
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'
+ 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")
@@ -123,7 +134,7 @@ file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
log = logging.getLogger()
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
- raise ValueError('Invalid log level: %s' % loglevel)
+ raise ValueError('Invalid log level: %s' % loglevel)
log.setLevel(numeric_level)
log.propagate = 0
@@ -131,13 +142,17 @@ log.propagate = 0
# and set its log level to the command-line option
#
console_handler = logging.StreamHandler(sys.stdout)
-console_handler.setLevel(logging.INFO)
+#console_handler.setLevel(logging.INFO)
+numeric_screenlevel = getattr(logging, screenloglevel.upper(), None)
+if not isinstance(numeric_screenlevel, int):
+ raise ValueError('Invalid screenlog level: %s' % screenloglevel)
+console_handler.setLevel(numeric_screenlevel)
console_handler.setFormatter(screen_formatter)
# create a file handler
-# and set its log level to DEBUG
+# and set its log level
#
-log_file = 'RUN{}.{}.log'.format(env,test)
+log_file = 'RUN{}.{}.log'.format(env,test_file)
file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10)
#file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5)
file_handler.setLevel(numeric_level)
@@ -154,11 +169,11 @@ 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())
+ # Add timestamp
+ log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime())
- # Roll over on application start
- log.handlers[0].doRollover()
+ # Roll over on application start
+ log.handlers[0].doRollover()
# Add timestamp
log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime())
@@ -199,41 +214,53 @@ def connect_client(client):
log.debug("Connected to VM on %s" % client.ip())
def run_iteration(gensock,sutsock):
- sleep_time = 3
+ sleep_time = 2
# 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)
+ abs_old_rx, abs_old_non_dp_rx, abs_old_tx, abs_old_non_dp_tx, abs_old_drop, abs_old_tx_fail, abs_old_tsc, abs_tsc_hz = gensock.core_stats(genstatcores,tasks)
+ abs_old_rx = abs_old_rx - abs_old_non_dp_rx
+ abs_old_tx = abs_old_tx - abs_old_non_dp_tx
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)
+ old_sut_rx, old_sut_non_dp_rx, old_sut_tx, old_sut_non_dp_tx, old_sut_drop, old_sut_tx_fail, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ old_sut_rx = old_sut_rx - old_sut_non_dp_rx
+ old_sut_tx = old_sut_tx - old_sut_non_dp_tx
+ old_rx, old_non_dp_rx, old_tx, old_non_dp_tx, old_drop, old_tx_fail, old_tsc, tsc_hz = gensock.core_stats(genstatcores,tasks)
+ old_rx = old_rx - old_non_dp_rx
+ old_tx = old_tx - old_non_dp_tx
# Measure latency statistics per second
- n_loops = 0
- lat_min = 0
- lat_max = 0
- lat_avg = 0
+ 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
+ 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
+ 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)
+ new_rx, new_non_dp_rx, new_tx, new_non_dp_tx, new_drop, new_tx_fail, new_tsc, tsc_hz = gensock.core_stats(genstatcores,tasks)
+ new_rx = new_rx - new_non_dp_rx
+ new_tx = new_tx - new_non_dp_tx
if sutsock!='none':
- new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores)
+ new_sut_rx, new_sut_non_dp_rx, new_sut_tx, new_sut_non_dp_tx, new_sut_drop, new_sut_tx_fail, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ new_sut_rx = new_sut_rx - new_sut_non_dp_rx
+ new_sut_tx = new_sut_tx - new_sut_non_dp_tx
#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)
+ abs_new_rx, abs_new_non_dp_rx, abs_new_tx, abs_new_non_dp_tx, abs_new_drop, abs_new_tx_fail, abs_new_tsc, abs_tsc_hz = gensock.core_stats(genstatcores,tasks)
+ abs_new_rx = abs_new_rx - abs_new_non_dp_rx
+ abs_new_tx = abs_new_tx - abs_new_non_dp_tx
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
@@ -252,9 +279,9 @@ def run_iteration(gensock,sutsock):
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.")
+ 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)
+ return(pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg,lat_max,abs_dropped,(abs_new_tx_fail - abs_old_tx_fail),(abs_new_tx - abs_old_tx),lat_min,used_avg)
def new_speed(speed,minspeed,maxspeed,success):
if success:
@@ -265,197 +292,126 @@ def new_speed(speed,minspeed,maxspeed,success):
return (newspeed,minspeed,maxspeed)
def get_pps(speed,size):
+ # speed is given in % of 10Gb/s, returning Mpps
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 get_speed(packet_speed,size):
+ # return speed in Gb/s
+ return (packet_speed / 1000.0 * (8*(size+24)))
-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
+
+def run_flow_size_test(gensock,sutsock):
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
+ for size in packet_size_list:
+ size = size-4
+ 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 different calculation
+ 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 | core generated | Sent by Gen NIC| Forward by SUT | core received | Avg. Latency | Max. Latency | Packets Lost | Loss Ratio |")
+ log.info("+--------+--------------------+----------------+----------------+----------------+------------------------+----------------+----------------+----------------+------------+")
+ 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_fail, 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.WARNING + ' Latency accuracy issue?: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC
else:
- drop_rate_prefix = bcolors.FAIL
- if (lat_avg< LAT_AVG_TRESHOLD):
+ lat_warning = ''
+ if ((drop_rate < DROP_RATE_TRESHOLD) or (abs_dropped==DROP_RATE_TRESHOLD ==0)) and (lat_avg< LAT_AVG_TRESHOLD) and (lat_max < LAT_MAX_TRESHOLD):
lat_avg_prefix = bcolors.ENDC
- else:
- lat_avg_prefix = bcolors.FAIL
- if (lat_max< LAT_MAX_TRESHOLD):
lat_max_prefix = bcolors.ENDC
+ abs_drop_rate_prefix = bcolors.ENDC
+ drop_rate_prefix = bcolors.ENDC
+ if ((get_pps(speed,size) - pps_tx)/get_pps(speed,size))>0.01:
+ speed_prefix = bcolors.WARNING
+ if abs_tx_fail > 0:
+ gen_warning = bcolors.WARNING + ' Network limit?: requesting {:<.3f} Mpps and getting {:<.3f} Mpps - {} failed to be transmitted'.format(get_pps(speed,size), pps_tx, abs_tx_fail) + bcolors.ENDC
+ else:
+ gen_warning = bcolors.WARNING + ' Generator limit?: requesting {:<.3f} Mpps and getting {:<.3f} Mpps'.format(get_pps(speed,size), pps_tx) + bcolors.ENDC
+ else:
+ speed_prefix = bcolors.ENDC
+ gen_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 + gen_warning
+ success = True
+ success_message='% | SUCCESS'
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")
+ success_message='% | FAILED'
+ gen_warning = ''
+ 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
+ success = False
+ log.debug('|step{:>3}'.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 | '+bcolors.OKBLUE + '{:>4.1f}'.format(get_speed(pps_rx,size)) + 'Gb/s{:>9.3f}'.format(pps_rx)+' Mpps'+bcolors.ENDC+' | '+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+ success_message +lat_warning + gen_warning)
+ 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) + '% ' + speed_prefix + '{:>6.3f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.3f}'.format(endpps_req_tx)+ ' Mpps | '+ bcolors.ENDC + '{:>9.3f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+bcolors.OKBLUE + '{:>4.1f}'.format(get_speed(pps_rx,size)) + 'Gb/s{:>9.3f}'.format(endpps_rx)+' Mpps'+bcolors.ENDC+' | '+ '{:>9.0f}'.format(endlat_avg)+' us | '+ '{:>9.0f}'.format(endlat_max)+' us | '+ '{:>14d}'.format(endabs_dropped)+ ' |'+'{:>9.2f}'.format(enddrop_rate)+ '% |')
+ if endwarning:
+ log.info (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("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+")
+
+def run_fixed_rate(gensock,sutsock):
+ log.info("+-----------------------------------------------------------------------------------------------------------------------------------------------------------+")
+ log.info("| UDP, 1 flow, different packet sizes |")
+ log.info("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+")
+ log.info("|Pktsz| Speed requested | Gen by core | Sent by NIC | Fwrd by SUT | Rec. by core| 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
- attempts = 0
gensock.reset_stats()
if sutsock!='none':
sutsock.reset_stats()
@@ -463,190 +419,157 @@ def run_sizetest(gensock,sutsock):
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)
+ 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_non_dp_rx, old_sut_tx, old_sut_non_dp_tx, old_sut_drop, old_sut_tx_fail, old_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ old_sut_rx = old_sut_rx - old_sut_non_dp_rx
+ old_sut_tx = old_sut_tx - old_sut_non_dp_tx
+ old_rx, old_non_dp_rx, old_tx, old_non_dp_tx, old_drop, old_tx_fail, old_tsc, tsc_hz = gensock.core_stats(genstatcores,tasks)
+ old_rx = old_rx - old_non_dp_rx
+ old_tx = old_tx - old_non_dp_tx
+ 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.
+ # Get statistics after some execution time
+ new_rx, new_non_dp_rx, new_tx, new_non_dp_tx, new_drop, new_tx_fail, new_tsc, tsc_hz = gensock.core_stats(genstatcores,tasks)
+ new_rx = new_rx - new_non_dp_rx
+ new_tx = new_tx - new_non_dp_tx
+ if sutsock!='none':
+ new_sut_rx, new_sut_non_dp_rx, new_sut_tx, new_sut_non_dp_tx, new_sut_drop, new_sut_tx_fail, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ new_sut_rx = new_sut_rx - new_sut_non_dp_rx
+ new_sut_tx = new_sut_tx - new_sut_non_dp_tx
+ 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 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)
+ 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("+-----+------------------+-------------+-------------+-------------+-------------+-------------+-------------+-----------+-----------+---------+------------+")
+ # Get statistics after some execution time
+ new_rx, new_non_dp_rx, new_tx, new_non_dp_tx, new_drop, new_tx_fail, new_tsc, tsc_hz = gensock.core_stats(genstatcores,tasks)
+ new_rx = new_rx - new_non_dp_rx
+ new_tx = new_tx - new_non_dp_tx
+ if sutsock!='none':
+ new_sut_rx, new_sut_non_dp_rx, new_sut_tx, new_sut_non_dp_tx, new_sut_drop, new_sut_tx_fail, new_sut_tsc, sut_tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ new_sut_rx = new_sut_rx - new_sut_non_dp_rx
+ new_sut_tx = new_sut_tx - new_sut_non_dp_tx
+ 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_measure_swap(sutsock):
+ log.info("+------------------------------------------------------------------------------------------------------+")
+ log.info("| Measuring packets on SWAP system |")
+ log.info("+-----------+------------+------------+------------+------------+------------+------------+------------+")
+ log.info("| Time | RX | TX | non DP RX | non DP TX | TX - RX | nonDP TX-RX| DROP TOT |")
+ log.info("+-----------+------------+------------+------------+------------+------------+------------+------------+")
+ sutsock.reset_stats()
+ duration = float(runtime)
+ first = 1
+ tot_drop = 0
+ old_rx, old_non_dp_rx, old_tx, old_non_dp_tx, old_drop, old_tx_fail, old_tsc, tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ while (duration > 0):
+ time.sleep(0.5)
+ # Get statistics after some execution time
+ new_rx, new_non_dp_rx, new_tx, new_non_dp_tx, new_drop, new_tx_fail, new_tsc, tsc_hz = sutsock.core_stats(sutstatcores,tasks)
+ drop = new_drop-old_drop
+ rx = new_rx - old_rx
+ tx = new_tx - old_tx
+ non_dp_rx = new_non_dp_rx - old_non_dp_rx
+ non_dp_tx = new_non_dp_tx - old_non_dp_tx
+ tsc = new_tsc - old_tsc
+ if tsc == 0 :
+ continue
+ duration = duration - 1
+ old_drop = new_drop
+ old_rx = new_rx
+ old_tx = new_tx
+ old_non_dp_rx = new_non_dp_rx
+ old_non_dp_tx = new_non_dp_tx
+ old_tsc = new_tsc
+ tot_drop = tot_drop + tx - rx
+
+ log.info('|{:>10.0f}'.format(duration)+' | ' + '{:>10.0f}'.format(rx) + ' | ' +'{:>10.0f}'.format(tx) + ' | '+'{:>10.0f}'.format(non_dp_rx)+' | '+'{:>10.0f}'.format(non_dp_tx)+' | ' + '{:>10.0f}'.format(tx-rx) + ' | '+ '{:>10.0f}'.format(non_dp_tx-non_dp_rx) + ' | '+'{:>10.0f}'.format(tot_drop) +' |')
+ log.info("+------------------------------------------------------------------------------------------------------+")
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("+----------------------------------------------------------------------------------------------------------------------------")
+ 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()
+ 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')
+ 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)]
@@ -671,12 +594,11 @@ def run_irqtest(sock):
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("| 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("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+")
@@ -688,31 +610,41 @@ def run_impairtest(gensock,sutsock):
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)
+ 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_fail, 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)
+ 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):
+def run_warmuptest(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.speed(WARMUPSPEED / len(gencores), gencores)
+ size=PACKETSIZE-4
+ 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)
+ gensock.set_value(gencores,0,56,1,1)
+ # This will only work when using sending UDP packets. For different protocols and ethernet types, we would need a different calculation
+ source_port,destination_port = flows[FLOWSIZE]
+ gensock.set_random(gencores,0,34,source_port,2)
+ gensock.set_random(gencores,0,36,destination_port,2)
gensock.start(genstatcores)
- time.sleep(2)
+ time.sleep(WARMUPTIME)
gensock.stop(genstatcores)
+ gensock.set_value(gencores,0,56,50,1)
global sutstatcores
global genstatcores
@@ -721,8 +653,34 @@ global gencores
global irqcores
global PACKETSIZE
global packet_size_list
+global FLOWSIZE
global flow_size_list
+global WARMUPTIME
+global WARMUPSPEED
global required_number_of_test_machines
+# 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'],}
clients =[]
socks =[]
socks_control =[]
@@ -737,16 +695,16 @@ auto_start =[]
mach_type =[]
sock_type =[]
-data_file = 'RUN{}.{}.csv'.format(env,test)
+data_file = 'RUN{}.{}.csv'.format(env,test_file)
data_csv_file = open(data_file,'w')
testconfig = ConfigParser.RawConfigParser()
-testconfig.read(test+'.test')
+testconfig.read(test_file)
required_number_of_test_machines = testconfig.get('DEFAULT', 'total_number_of_test_machines')
config = ConfigParser.RawConfigParser()
-config.read(env+'.env')
+config.read(env)
machine_map = ConfigParser.RawConfigParser()
-machine_map.read(machine_map_file +'.cfg')
-key = config.get('OpenStack', 'key')
+machine_map.read(machine_map_file)
+key = config.get('ssh', '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))
@@ -765,14 +723,13 @@ 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:
+ with open('{}_{}_parameters{}.lua'.format(env,test_file,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]):
+ if re.match('(l2){0,1}gen(_bare){0,1}\.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')
@@ -785,7 +742,6 @@ for vm in range(1, int(required_number_of_test_machines)+1):
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')
@@ -831,9 +787,9 @@ def exit_handler():
log.debug ('exit cleanup')
for index, sock in enumerate(socks):
if socks_control[index]:
- sock.quit()
+ sock.quit()
for client in clients:
- client.close()
+ client.close()
data_csv_file.close
sys.exit(0)
@@ -844,7 +800,7 @@ for vm in range(0, int(required_number_of_test_machines)):
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)
+ devbindfile = '{}_{}_devbindvm{}.sh'.format(env,test_file, vm+1)
with open("devbind.sh") as f:
newText=f.read().replace('MACADDRESS', vmDPmac[machine_index[vm]])
with open(devbindfile, "w") as f:
@@ -856,7 +812,7 @@ for vm in range(0, int(required_number_of_test_machines)):
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')
+ clients[-1].scp_put('./{}_{}_parameters{}.lua'.format(env,test_file, vm+1), '/root/parameters.lua')
if not configonly:
if prox_launch_exit[vm]:
log.debug("Starting PROX on VM%d"%(vm+1))
@@ -881,6 +837,7 @@ def get_BinarySearchParams() :
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'))
+ STARTSPEED = float(testconfig.get('BinarySearchParams', 'startspeed'))
if configonly:
sys.exit()
@@ -898,30 +855,30 @@ with data_csv_file:
writer.writeheader()
for test_nr in range(1, int(number_of_tests)+1):
test=testconfig.get('test%d'%test_nr,'test')
+ tasks= ast.literal_eval(testconfig.get('test%d'%test_nr, 'tasks'))
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':
+ if test == 'flowsizetest':
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'))
+ flow_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'flows'))
+ run_flow_size_test(socks[gensock_index],socks[sutsock_index])
+ elif test == 'fixed_rate':
packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes'))
- run_max_frame_rate(socks[gensock_index],socks[sutsock_index])
+ STARTSPEED = float(testconfig.get('test%d'%test_nr, 'speed'))
+ run_fixed_rate(socks[gensock_index],socks[sutsock_index])
+ elif test == 'measureswap':
+ #packet_size_list = ast.literal_eval(testconfig.get('test%d'%test_nr, 'packetsizes'))
+ run_measure_swap(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])
+ elif test == 'warmuptest':
+ PACKETSIZE = int(testconfig.get('test%d'%test_nr, 'packetsize'))
+ FLOWSIZE = int(testconfig.get('test%d'%test_nr, 'flowsize'))
+ WARMUPSPEED = int(testconfig.get('test%d'%test_nr, 'warmupspeed'))
+ WARMUPTIME = int(testconfig.get('test%d'%test_nr, 'warmuptime'))
+ run_warmuptest(socks[gensock_index])
####################################################
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test
index cf1b552..5c5813f 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/secgw.test
@@ -20,6 +20,7 @@ number_of_tests = 2
total_number_of_test_machines = 3
prox_socket = true
prox_launch_exit = true
+tasks=[0]
[TestM1]
name = Generator
@@ -28,7 +29,6 @@ dest_vm = 3
gw_vm = 2
gencores = [1]
latcores = [3]
-startspeed = 10
[TestM2]
name = GW1
@@ -46,10 +46,18 @@ drop_rate_threshold = 0.1
lat_avg_threshold = 500
lat_max_threshold = 1000
accuracy = 0.1
+startspeed = 10
[test1]
-test=inittest
+test=warmuptest
+flowsize=1024
+packetsize=64
+warmupspeed=1
+warmuptime=2
[test2]
-test=speedtest
-packetsize=64
+test=flowsizetest
+packetsizes=[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=[512]
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/sharkproxlog.sh b/VNFs/DPPD-PROX/helper-scripts/rapid/sharkproxlog.sh
new file mode 100755
index 0000000..f52e576
--- /dev/null
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/sharkproxlog.sh
@@ -0,0 +1 @@
+egrep '^[0-9]{4}|^[0-9]+\.' prox.log | text2pcap -q - - | tshark -r -
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg b/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg
index 47cb0b0..02300f8 100644
--- a/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/swap.cfg
@@ -24,6 +24,7 @@ dofile("parameters.lua")
[port 0]
name=if0
mac=hardware
+vlan=yes
[defaults]
mempool size=2K