Test improvements and fixes for image creation 31/64331/1
authorLuc Provoost <luc.provoost@intel.com>
Thu, 11 Oct 2018 16:23:20 +0000 (18:23 +0200)
committerDeepak S <deepak.s@linux.intel.com>
Wed, 31 Oct 2018 23:02:45 +0000 (04:32 +0530)
Updated and corrected the creation of an image containing the PROX
tool with packer.
Test will now only be declared successful when average and maximum
latency are below a certain threshold.
The start speed is now also a parameter of the *.test files.

Change-Id: I1112555c87e7a857e1c699921ae08f61281642e1
Signed-off-by: Luc Provoost <luc.provoost@intel.com>
13 files changed:
VNFs/DPPD-PROX/helper-scripts/openstackrapid/README
VNFs/DPPD-PROX/helper-scripts/openstackrapid/basicrapid.test
VNFs/DPPD-PROX/helper-scripts/openstackrapid/centos.json
VNFs/DPPD-PROX/helper-scripts/openstackrapid/createrapid.py
VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos1.sh [new file with mode: 0644]
VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos2.sh [moved from VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos.sh with 69% similarity]
VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.cfg
VNFs/DPPD-PROX/helper-scripts/openstackrapid/impair.test
VNFs/DPPD-PROX/helper-scripts/openstackrapid/irq.test
VNFs/DPPD-PROX/helper-scripts/openstackrapid/l2zeroloss.test
VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapidVMs.vms
VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py
VNFs/DPPD-PROX/helper-scripts/openstackrapid/secgw.test

index cc940fc..d58b4bf 100644 (file)
@@ -22,22 +22,18 @@ dataplane performance of an OpenStack environment.
 
 Copy the files in a directory on a machine that can run the OpenStack CLI
 commands and that can reach the OpenStack public network.
-One option is to create a qcow2 image in the same directory with the
-following characteristics:
-* Name of the qcow2 file should be: rapidVM.qcow2
-  This default name can be overruled on the rapid command line (--image_file)
-* Should have DPDK and PROX installed. PROX should be in /root/prox/ directory
-* Image should have cloud-init installed
-* /mnt/huge should exist to support a command that is executed at startup of the VM: 'mount  -t hugetlbfs nodev /mnt/huge'
-* Compile prox with 'make crc=soft'. This is a workaround for some cases where the crc calculation offload is not working as expected.
-* Compile dpdk to support AESN-NI Multi Buffer Crypto Poll Mode Driver: http://dpdk.org/doc/guides/cryptodevs/aesni_mb.html
-
-Alternatively, you can create an image in OpenStack using Packer and then specify
-the image to be used as a parameter to createrapid.py. First step is to upload an
+
+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 deploycentos1.sh
+and deploycentos2.sh file.
+The default name of the qcow2 file should 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 3 files: centos.json, deploycentos1.sh and deploycentos2.sh, allowing you to create
 an image automatically. Run
   # packer build centos.json
 Note that this procedure is not only installing the necessary tools to run PROX,
index 84f8192..f97d821 100644 (file)
@@ -26,7 +26,10 @@ group1cores = not_used
 group2cores = not_used
 group3cores = not_used
 drop_rate_treshold = 0.1
-accuracy = 0.01
+lat_avg_treshold = 50
+lat_max_treshold = 1000
+accuracy = 0.1
+startspeed = 100
 
 
 [TestM1]
index bdca725..efab7ad 100644 (file)
@@ -5,7 +5,7 @@
    {
 "type": "openstack",
 "ssh_username": "centos",
-"image_name": "newrapidVM",
+"image_name": "ProxDPDK1802VM",
 "source_image": "aa0f8333-d8e1-42db-8210-6b39d9ee7267",
 "flavor": "7aaec028-eccc-4612-8f9b-29a1e039943a",
 "networks": "97bbe96f-ee1b-4789-ace8-e922f76bea3f",
    },
    {
    "type": "shell",
-   "script": "deploycentos.sh"
+   "script": "deploycentos1.sh",
+   "expect_disconnect": true
+   },
+   {
+   "type": "shell",
+   "script": "deploycentos2.sh",
+   "pause_before": "20s"
    }
 ]
 }
index f21b91d..8fab2b6 100755 (executable)
@@ -31,7 +31,7 @@ from logging import handlers
 from prox_ctrl import prox_ctrl
 import ConfigParser
 
-version="18.6.15"
+version="18.10.15"
 stack = "rapid" #Default string for stack. This is not an OpenStack Heat stack, just a group of VMs
 vms = "rapidVMs" #Default string for vms file
 key = "prox" # default name for kay
diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos1.sh b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/deploycentos1.sh
new file mode 100644 (file)
index 0000000..ff1c1c1
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+##
+## Copyright (c) 2010-2018 Intel Corporation
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+sudo sh -c '(echo "export RTE_TARGET=\"build\"";echo "export RTE_SDK=\"/root/dpdk\"";echo "export AESNI_MULTI_BUFFER_LIB_PATH=\"/home/centos/intel-ipsec-mb-0.49\"";) >> /root/.bashrc'
+sudo yum install deltarpm -y
+sudo yum update -y
+sudo yum-config-manager --add-repo http://www.nasm.us/nasm.repo
+sudo yum install git wget gcc unzip libpcap-devel ncurses-devel libedit-devel lua-devel kernel-devel iperf3 pciutils numactl-devel vim tuna openssl-devel nasm -y
+# Enabling root ssh access
+sudo sed -i '/disable_root: 1/c\disable_root: 0' /etc/cloud/cloud.cfg
+# Reboot, before continuing with deploycentos2.sh
+sudo reboot
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ##
-sudo sh -c '(echo "export RTE_TARGET=\"build\"";echo "export RTE_SDK=\"/root/dpdk\"";echo "export AESNI_MULTI_BUFFER_LIB_PATH=\"/home/centos/intel-ipsec-mb-0.48\"";) >> /root/.bashrc'
-sudo yum install deltarpm -y
-sudo yum update -y
-sudo yum-config-manager --add-repo http://www.nasm.us/nasm.repo
-sudo yum install git wget gcc unzip libpcap-devel ncurses-devel libedit-devel lua-devel kernel-devel iperf3 pciutils numactl-devel vim tuna openssl-devel nasm -y
-# Enabling root ssh access
-sudo sed -i '/disable_root: 1/c\disable_root: 0' /etc/cloud/cloud.cfg
 # The following line is commented since this was a workaround for a problem with the content of /etc/resolv.conf.
 # That file could contain DNS information coming from the dataplane which might be wrong. A solution is to confire the correct DNS for the dataplne
 # in OpenStack.  DNS might be slowing down ssh access. We don't need that for our dataplane benchmarking purposes
@@ -33,42 +26,46 @@ sudo umount `awk '/hugetlbfs/ { print $2 }' /proc/mounts` >/dev/null 2>&1
 sudo mount -t hugetlbfs nodev /mnt/huge/
 sudo sh -c '(echo "vm.nr_hugepages = 1024") > /etc/sysctl.conf'
 
-# Downloading the Multi-buffer library
-wget https://github.com/01org/intel-ipsec-mb/archive/v0.48.zip
-unzip v0.48.zip
-export  AESNI_MULTI_BUFFER_LIB_PATH=/home/centos/intel-ipsec-mb-0.48
+# Downloading the Multi-buffer library. Note that the version to download is linked to the DPDK version being used
+cd /home/centos
+wget https://github.com/01org/intel-ipsec-mb/archive/v0.50.zip
+unzip v0.50.zip
+# AESNI_MULTI_BUFFER_LIB_PATH should be already set in deploycentos1.sh
+export  AESNI_MULTI_BUFFER_LIB_PATH=/home/centos/intel-ipsec-mb-0.50
 cd $AESNI_MULTI_BUFFER_LIB_PATH
-make -j8
+make
+sudo make install
 # Clone and compile DPDK
 cd /home/centos/
 git clone http://dpdk.org/git/dpdk
 cd dpdk
-git checkout v17.11
+git checkout v18.05
 export RTE_TARGET=build
 export RTE_SDK=/home/centos/dpdk
 make config T=x86_64-native-linuxapp-gcc
 # The next sed lines make sure that we can compile DPDK 17.11 with a relatively new OS. Using a newer DPDK (18.5) should also resolve this issue
-sudo sed -i '/CONFIG_RTE_LIBRTE_KNI=y/c\CONFIG_RTE_LIBRTE_KNI=n' /home/centos/dpdk/build/.config
-sudo sed -i '/CONFIG_RTE_LIBRTE_PMD_KNI=y/c\CONFIG_RTE_LIBRTE_PMD_KNI=n' /home/centos/dpdk/build/.config
-sudo sed -i '/CONFIG_RTE_KNI_KMOD=y/c\CONFIG_RTE_KNI_KMOD=n' /home/centos/dpdk/build/.config
-sudo sed -i '/CONFIG_RTE_KNI_PREEMPT_DEFAULT=y/c\CONFIG_RTE_KNI_PREEMPT_DEFAULT=n' /home/centos/dpdk/build/.config
+#sudo sed -i '/CONFIG_RTE_LIBRTE_KNI=y/c\CONFIG_RTE_LIBRTE_KNI=n' /home/centos/dpdk/build/.config
+#sudo sed -i '/CONFIG_RTE_LIBRTE_PMD_KNI=y/c\CONFIG_RTE_LIBRTE_PMD_KNI=n' /home/centos/dpdk/build/.config
+#sudo sed -i '/CONFIG_RTE_KNI_KMOD=y/c\CONFIG_RTE_KNI_KMOD=n' /home/centos/dpdk/build/.config
+#sudo sed -i '/CONFIG_RTE_KNI_PREEMPT_DEFAULT=y/c\CONFIG_RTE_KNI_PREEMPT_DEFAULT=n' /home/centos/dpdk/build/.config
 # Compile with MB library
-sudo sed -i '/CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n/c\CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y' /home/centos/dpdk/build/.config
-make -j8 
-cd /home/centos
-# Copy everything to root since the scripts are assuming /root as the directory for PROX
-sudo cp -r dpdk /root/
+sed -i '/CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n/c\CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y' /home/centos/dpdk/build/.config
+make 
+# Runtime scripts are assuming /root as the directory for PROX
+sudo ln -s /home/centos/dpdk /root/dpdk
 
 # Clone and compile PROX
-git clone https://git.opnfv.org/samplevnf
-cp -r /home/centos/samplevnf/VNFs/DPPD-PROX /home/centos/prox
-cd /home/centos/prox
-make -j8
 cd /home/centos
-# Copy everything to root since the scripts are assuming /root as the directory for PROX
-sudo cp -r /home/centos/prox /root/
+git clone https://git.opnfv.org/samplevnf
+cd /home/centos/samplevnf/VNFs/DPPD-PROX
+git checkout 4d59d3530d1c41734f15423142e64eb9c929c717
+# Compiling PROX with the crc=soft option because offloaded CRC calculation causes problems on multiple VIM environments. This will of course slow
+# down the performance of the generator.
+make crc=soft
+sudo ln -s /home/centos/samplevnf/VNFs/DPPD-PROX /root/prox
 
 # Enabling tuned with the realtime-virtual-guest profile
+cd /home/centos/
 wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-realtime-2.8.0-5.el7_4.2.noarch.rpm
 wget http://linuxsoft.cern.ch/cern/centos/7/rt/x86_64/Packages/tuned-profiles-nfv-guest-2.8.0-5.el7_4.2.noarch.rpm
 # Install with --nodeps. The latest CentOS cloud images come with a tuned version higher than 2.8. These 2 packages however
index f52cc5d..8fefd41 100644 (file)
@@ -41,6 +41,6 @@ mode=impair
 sub mode=l3
 rx port=if0
 tx port=if0
-delay us=10
-probability=80
+delay us=1000
+probability=100
 local ipv4=${local_ip}
index 27078c5..5f75e00 100644 (file)
@@ -26,8 +26,10 @@ group1cores = not_used
 group2cores = not_used
 group3cores = not_used
 drop_rate_treshold = 1
+lat_avg_treshold = 100
+lat_max_treshold = 800
 accuracy = 0.01
-
+startspeed = 10
 
 [TestM1]
 name = Generator
@@ -53,4 +55,3 @@ group1cores = [1]
 
 [test1]
 cmd=run_impairtest(socks[0],socks[2],8)
-# The last parameter specifies the speed at which this test will run
index 2d413c1..26ae3de 100644 (file)
@@ -26,19 +26,22 @@ group1cores = not_used
 group2cores = not_used
 group3cores = not_used
 drop_rate_treshold = 1
+lat_avg_treshold = 100
+lat_max_treshold = 800
 accuracy = 0.01
+startspeed = 10
 
 [TestM1]
 name = InterruptTesting
 machine_index = 1
 config_file = irq.cfg
-group1cores = [1,2,3]
+group1cores = [1,2,3,4,5,6,7]
 
 [TestM2]
 name = InterruptTesting
 machine_index = 2
 config_file = irq.cfg
-group1cores = [1,2,3]
+group1cores = [1,2,3,4,5,6,7]
 
 [TestM3]
 name = InterruptTesting
index 3d3bb13..691af09 100644 (file)
@@ -16,7 +16,7 @@
 
 [DEFAULT]
 name = L2BasicSwapTesting
-number_of_tests = 3
+number_of_tests = 1
 total_number_of_test_machines = 2
 init_code=init_test()
 dest_vm = not_used
@@ -26,7 +26,10 @@ group1cores = not_used
 group2cores = not_used
 group3cores = not_used
 drop_rate_treshold = 0
+lat_avg_treshold = 100
+lat_max_treshold = 800
 accuracy = 0.1
+startspeed = 10
 
 [TestM1]
 name = Generator
index 1e45ed0..4c197d0 100644 (file)
@@ -17,7 +17,7 @@
 
 [DEFAULT]
 total_number_of_vms=3
-flavor_info=--ram 4096 --disk 20 --vcpus 4
+flavor_info=--ram 4096 --disk 20 --vcpus 8
 ;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate --property hw:numa_nodes=1 --property hw:numa_cpus.0=0,1,2,3 --property hw:numa_mempolicy=strict --property hw:numa_mem.0=4096
 ;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated --property hw:cpu_thread_policy=isolate
 ;flavor_meta_data=--property hw:mem_page_size=large --property hw:cpu_policy=dedicated
index e968441..5208698 100755 (executable)
@@ -32,8 +32,9 @@ from prox_ctrl import prox_ctrl
 import ConfigParser
 import ast
 import atexit
+import csv
 
-version="18.6.15"
+version="18.10.15"
 env = "rapid" #Default string for environment
 test = "basicrapid" #Default string for test
 loglevel="DEBUG" # sets log level for writing to file
@@ -95,6 +96,15 @@ for opt, arg in opts:
                loglevel = arg
                print ("Log level: "+ loglevel)
 
+class bcolors:
+    HEADER = '\033[95m'
+    OKBLUE = '\033[94m'
+    OKGREEN = '\033[92m'
+    WARNING = '\033[93m'
+    FAIL = '\033[91m'
+    ENDC = '\033[0m'
+    BOLD = '\033[1m'
+    UNDERLINE = '\033[4m'
 
 # create formatters
 screen_formatter = logging.Formatter("%(message)s")
@@ -122,6 +132,7 @@ console_handler.setFormatter(screen_formatter)
 # and set its log level to DEBUG
 #
 log_file = 'RUN' +env+'.'+test+'.log'
+data_file = 'RUN' +env+'.'+test+'.csv'
 file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10)
 #file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5)
 file_handler.setLevel(numeric_level)
@@ -253,7 +264,7 @@ def run_speedtest(gensock,sutsock):
        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("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+------------+")
-       maxspeed = speed = 100
+       maxspeed = speed = STARTSPEED
        minspeed = 0
        size=60
        attempts = 0
@@ -272,7 +283,7 @@ def run_speedtest(gensock,sutsock):
                 # 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 = run_iteration(gensock,sutsock)
                drop_rate = 100.0*abs_dropped/abs_tx
-               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)):
+               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    |')
                        endspeed = speed
                        endpps_req_tx = pps_req_tx
@@ -285,7 +296,26 @@ def run_speedtest(gensock,sutsock):
                        enddrop_rate = drop_rate
                        success = True 
                else:
-                       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)+ '%  | FAILED     |')
+                       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 | '+ bcolors.ENDC + '{:>9.3f}'.format(pps_tx) +' Mpps | ' + '{:>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     |')
                        success = False 
                speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,success)
        if endpps_sut_tx_str <>  'NO_RESULTS':
@@ -310,7 +340,6 @@ def run_flowtest(gensock,sutsock):
        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
        for flow_number in sorted(flows.iterkeys()):
-               #speed = 100 Commented out: Not starting from 100% since we are trying more flows, so speed will not be higher than the speed achieved in previous loop
                gensock.reset_stats()
                if sutsock!='none':
                        sutsock.reset_stats()
@@ -318,7 +347,7 @@ def run_flowtest(gensock,sutsock):
                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 = 100
+               maxspeed = speed = STARTSPEED
                minspeed = 0
                while (maxspeed-minspeed > ACCURACY):
                        print(str(flow_number)+' flows: Measurement ongoing at speed: ' + str(round(speed,2)) + '%      ',end='\r')
@@ -329,7 +358,7 @@ def run_flowtest(gensock,sutsock):
                        # 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 = run_iteration(gensock,sutsock)
                        drop_rate = 100.0*abs_dropped/abs_tx
-                       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)):
+                       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):
                                endspeed = speed
                                endpps_req_tx = pps_req_tx
                                endpps_tx = pps_tx
@@ -346,6 +375,7 @@ def run_flowtest(gensock,sutsock):
                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)+ '%  |')
                        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")
 
@@ -356,10 +386,10 @@ def run_sizetest(gensock,sutsock):
        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("+--------+--------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+------------+")
        # PROX will use different packet sizes as defined in sizes[]
-#      sizes=[1496,1020,508,252,124,60]
-       sizes=[1020,508,252,124,60]
+       sizes=[1496,1020,508,252,124,60]
+#      sizes=[1020,508,252,124,60]
+#      sizes=[124,60]
        for size in sizes:
-               #speed = 100 Commented out: Not starting from 100% since we are trying smaller packets, so speed will not be higher than the speed achieved in previous loop
                gensock.reset_stats()
                if sutsock!='none':
                        sutsock.reset_stats()
@@ -368,7 +398,7 @@ def run_sizetest(gensock,sutsock):
                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 = 100
+               maxspeed = speed = STARTSPEED
                minspeed = 0
                while (maxspeed-minspeed > ACCURACY):
                        print(str(size+4)+' bytes: Measurement ongoing at speed: ' + str(round(speed,2)) + '%      ',end='\r')
@@ -378,7 +408,7 @@ def run_sizetest(gensock,sutsock):
                        # 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 = run_iteration(gensock,sutsock)
                        drop_rate = 100.0*abs_dropped/abs_tx
-                       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)):
+                       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):
                                endspeed = speed
                                endpps_req_tx = pps_req_tx
                                endpps_tx = pps_tx
@@ -395,6 +425,7 @@ def run_sizetest(gensock,sutsock):
                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)+ '%  |')
                        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")
 
@@ -473,7 +504,10 @@ global latcores
 global gencores
 global irqcores
 global DROP_RATE_TRESHOLD
+global LAT_AVG_TRESHOLD
+global LAT_MAX_TRESHOLD
 global ACCURACY
+global STARTSPEED
 global required_number_of_test_machines
 clients =[]
 socks =[]
@@ -488,7 +522,10 @@ testconfig = ConfigParser.RawConfigParser()
 testconfig.read(test+'.test')
 required_number_of_test_machines = testconfig.get('DEFAULT', 'total_number_of_test_machines')
 DROP_RATE_TRESHOLD = float(testconfig.get('DEFAULT', 'drop_rate_treshold'))
+LAT_AVG_TRESHOLD = float(testconfig.get('DEFAULT', 'lat_avg_treshold'))
+LAT_MAX_TRESHOLD = float(testconfig.get('DEFAULT', 'lat_max_treshold'))
 ACCURACY = float(testconfig.get('DEFAULT', 'accuracy'))
+STARTSPEED = float(testconfig.get('DEFAULT', 'startspeed'))
 config = ConfigParser.RawConfigParser()
 config.read(env+'.env')
 key = config.get('OpenStack', 'key')
@@ -596,10 +633,16 @@ if init_code <> 'not_used':
        eval(init_code)
 ####################################################
 # Run test cases
-# Best to run the flow test at the end since otherwise the tests coming after thatmight be influenced by the big number of entries in the switch flow tables
+# Best to run the flow test at the end since otherwise the tests coming after might be influenced by the big number of entries in the switch flow tables
 ####################################################
 number_of_tests = testconfig.get('DEFAULT', 'number_of_tests')
-for vm in range(1, int(number_of_tests)+1):
-       cmd=testconfig.get('test%d'%vm,'cmd')
-       eval(cmd)
+data_file = 'RUN' +env+'.'+test+'.csv'
+data_csv_file = open(data_file,'w')
+with data_csv_file:
+       fieldnames = ['flow','size','endspeed','endspeedpps','endpps_req_tx','endpps_tx','endpps_sut_tx_str','endpps_rx','endlat_avg','endlat_max','endabs_dropped','enddrop_rate']
+       writer = csv.DictWriter(data_csv_file, fieldnames=fieldnames)
+       writer.writeheader()
+       for vm in range(1, int(number_of_tests)+1):
+               cmd=testconfig.get('test%d'%vm,'cmd')
+               eval(cmd)
 ####################################################
index faaeadf..cd2483a 100644 (file)
@@ -26,7 +26,10 @@ group1cores = not_used
 group2cores = not_used
 group3cores = not_used
 drop_rate_treshold = 0.01
+lat_avg_treshold = 100
+lat_max_treshold = 800
 accuracy = 0.01
+startspeed = 10
 
 [TestM1]
 name = Generator