diff options
Diffstat (limited to 'VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapid.py')
-rwxr-xr-x | VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapid.py | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapid.py b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapid.py deleted file mode 100755 index 1a0ea41c..00000000 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/rapid.py +++ /dev/null @@ -1,445 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (c) 2010-2017 Intel Corporation -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## - -import sys -import time -import subprocess -import getopt -from prox_ctrl import prox_ctrl - -version="17.04.19" -stack = "rapidTestEnv" #Default string for stack -yaml = "rapid.yaml" #Default string for yaml file -key = "prox" # This is also the default in the yaml file.... -flavor = "prox_flavor" # This is also the default in the yaml file.... -image = "rapidVM" # This is also the default in the yaml file.... -image_file = "rapidVM.qcow2" -network = "dpdk-network" # This is also the default in the yaml file.... -subnet = "dpdk-subnet" #Hardcoded at this moment - -def usage(): - print("usage: rapid [--version] [-v]") - print(" [--stack STACK_NAME]") - print(" [--yaml YAML_FILE]") - print(" [--key KEY_NAME]") - print(" [--flavor FLAVOR_NAME]") - print(" [--image IMAGE_NAME]") - print(" [--image_file IMAGE_FILE]") - print(" [--network NETWORK]") - print(" [-h] [--help]") - print("") - print("Command-line interface to RAPID") - print("") - print("optional arguments:") - print(" -v, --version Show program's version number and exit") - print(" --stack STACK_NAME Specify a name for the heat stack. Default is rapidTestEnv.") - print(" --yaml YAML_FILE Specify the yaml file to be used. Default is rapid.yaml.") - print(" --key KEY_NAME Specify the key to be used. Default is prox.") - print(" --flavor FLAVOR_NAME Specify the flavor to be used. Default is prox_flavor.") - print(" --image IMAGE_NAME Specify the image to be used. Default is rapidVM.") - print(" --image_file IMAGE_FILE Specify the image qcow2 file to be used. Default is rapidVM.qcow2.") - print(" --network NETWORK Specify the network name to be used for the dataplane. Default is dpdk-network.") - print(" -h, --help Show help message and exit.") - print("") - print("To delete the rapid stack, type the following command") - print(" openstack stack delete --yes --wait DPTestEnv") - print("Note that rapidTestEnv is the default stack name. Replace with STACK_NAME if needed") - -try: - opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "yaml=","stack=","key=","flavor=","image=","network="]) -except getopt.GetoptError as err: - print("===========================================") - print str(err) - print("===========================================") - usage() - sys.exit(2) -if args: - usage() - sys.exit(2) -for opt, arg in opts: - if opt in ("-h", "--help"): - usage() - sys.exit() - if opt in ("-v", "--version"): - print("Rapid Automated Performance Indication for Dataplane "+version) - sys.exit() - if opt in ("--stack"): - stack = arg - print ("Using '"+stack+"' as name for the stack") - elif opt in ("--yaml"): - yaml = arg - print ("Using stack: "+yaml) - elif opt in ("--key"): - key = arg - print ("Using key: "+key) - elif opt in ("--flavor"): - flavor = arg - print ("Using flavor: "+flavor) - elif opt in ("--image"): - image = arg - print ("Using image: "+image) - elif opt in ("--image_file"): - image_file = arg - print ("Using qcow2 file: "+image_file) - elif opt in ("--network"): - network = arg - print ("Using network: "+ network) - -print("Checking image: "+image) -cmd = 'openstack image show '+image+' |grep "status " | tr -s " " | cut -d" " -f 4' -ImageExist = subprocess.check_output(cmd , shell=True).strip() -if ImageExist == 'active': - print("Image already available") -else: - print('Creating image ...') - cmd = 'openstack image create --disk-format qcow2 --container-format bare --public --file ./'+image_file+ ' ' +image+' |grep "status " | tr -s " " | cut -d" " -f 4' - ImageExist = subprocess.check_output(cmd , shell=True).strip() - if ImageExist == 'active': - print('Image created and active') - cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image - subprocess.check_call(cmd , shell=True) - else : - raise Exception("Failed to create image") - -print("Checking key: "+key) -cmd = 'openstack keypair show '+key+' |grep "name " | tr -s " " | cut -d" " -f 4' -KeyExist = subprocess.check_output(cmd , shell=True).strip() -if KeyExist == key: - print("Key already installed") -else: - print('Creating key ...') - cmd = 'openstack keypair create '+ key + '>' +key+'.pem' - subprocess.check_call(cmd , shell=True) - cmd = 'chmod 600 ' +key+'.pem' - subprocess.check_call(cmd , shell=True) - cmd = 'openstack keypair show '+key+' |grep "name " | tr -s " " | cut -d" " -f 4' - KeyExist = subprocess.check_output(cmd , shell=True).strip() - if KeyExist == key: - print("Key created") - else : - raise Exception("Failed to create key: " + key) - -print("Checking flavor: "+flavor) -cmd = 'openstack flavor show '+flavor+' |grep "name " | tr -s " " | cut -d" " -f 4' -FlavorExist = subprocess.check_output(cmd , shell=True).strip() -if FlavorExist == flavor: - print("Flavor already installed") -else: - print('Creating flavor ...') - cmd = 'openstack flavor create '+flavor+' --ram 8192 --disk 80 --vcpus 4 |grep "name " | tr -s " " | cut -d" " -f 4' - FlavorExist = subprocess.check_output(cmd , shell=True).strip() - if FlavorExist == flavor: - cmd = 'openstack flavor set '+ flavor +' --property hw:mem_page_size="large" --property hw:cpu_policy="dedicated" --property hw:cpu_threads_policy="isolate"' - subprocess.check_call(cmd , shell=True) - print("Flavor created") - else : - raise Exception("Failed to create flavor: " + flavor) - -print("Checking network: "+network) -cmd = 'openstack network show '+network+' |grep "status " | tr -s " " | cut -d" " -f 4' -NetworkExist = subprocess.check_output(cmd , shell=True).strip() -if NetworkExist == 'ACTIVE': - print("Network already active") -else: - print('Creating network ...') - cmd = 'openstack network create '+network+' |grep "status " | tr -s " " | cut -d" " -f 4' - NetworkExist = subprocess.check_output(cmd , shell=True).strip() - if NetworkExist == 'ACTIVE': - print("Network created") - else : - raise Exception("Failed to create network: " + network) - -print("Checking subnet: "+subnet) -cmd = 'neutron subnet-show '+ subnet+' |grep "name " | tr -s " " | cut -d" " -f 4' -SubnetExist = subprocess.check_output(cmd , shell=True).strip() -if SubnetExist == subnet: - print("Subnet already exists") -else: - print('Creating subnet ...') - cmd = 'neutron subnet-create --name '+ subnet+ ' ' +network+' 10.10.10.0/24 |grep "name " | tr -s " " | cut -d" " -f 4' - SubnetExist = subprocess.check_output(cmd , shell=True).strip() - if SubnetExist == subnet: - print("Subnet created") - else : - raise Exception("Failed to create subnet: " + subnet) - -print("Checking Stack: "+stack) -cmd = 'openstack stack show '+stack+' |grep "stack_status " | tr -s " " | cut -d" " -f 4' -StackRunning = subprocess.check_output(cmd , shell=True).strip() -if StackRunning == '': - print('Creating Stack ...') - cmd = 'openstack stack create -t '+ yaml + ' --parameter flavor="'+flavor +'" --parameter key="'+ key + '" --parameter image="'+image + '" --parameter dpdk_network="'+network+'" --wait '+stack +' |grep "stack_status " | tr -s " " | cut -d" " -f 4' - StackRunning = subprocess.check_output(cmd , shell=True).strip() -if StackRunning != 'CREATE_COMPLETE': - raise Exception("Failed to create stack") - -print('Stack running') -genName=stack+'-gen' -sutName=stack+'-sut' -cmd = 'nova list | grep '+ genName +' | tr -s " " | cut -d " " -f 4' -genVMName = subprocess.check_output(cmd , shell=True).strip() -print('Generator: '+ genVMName) -cmd = 'nova list | grep '+ sutName +' | tr -s " " | cut -d " " -f 4' -sutVMName = subprocess.check_output(cmd , shell=True).strip() -print('SUT: '+ sutVMName) -cmd='nova show ' + genVMName + ' | grep "dpdk-network" | tr -s " " | cut -d" " -f 5' -genDPIP = subprocess.check_output(cmd , shell=True).strip() -cmd='nova show ' + genVMName + ' | grep "admin_internal_net" | tr -s " " | cut -d" " -f 6' -genAdminIP = subprocess.check_output(cmd , shell=True).strip() -cmd='nova show ' + sutVMName + ' | grep "dpdk-network" | tr -s " " | cut -d" " -f 5' -sutDPIP = subprocess.check_output(cmd , shell=True).strip() -cmd='nova show ' + sutVMName + ' | grep "admin_internal_net" | tr -s " " | cut -d" " -f 6' -sutAdminIP = subprocess.check_output(cmd , shell=True).strip() - -#======================================================================== -def connect_socket(client): - attempts = 1 - print("Trying to connect to PROX (just launched) on %s, attempt: %d" - % (client.ip(), attempts)) - sock = None - while True: - sock = client.prox_sock() - if sock is not None: - break - attempts += 1 - if attempts > 20: - raise Exception("Failed to connect to PROX on %s after %d attempts" - % (client.ip(), attempts)) - time.sleep(10) - print("Trying to connect to PROX (just launched) on %s, attempt: %d" - % (client.ip(), attempts)) - print("Connected to PROX on %s" % client.ip()) - return sock - -def connect_client(client): - attempts = 1 - print ("Trying to connect to VM which was just launched on %s, attempt: %d" - % (client.ip(), attempts)) - while True: - try: - client.connect() - break - except RuntimeWarning, ex: - attempts += 1 - if attempts > 20: - raise Exception("Failed to connect to VM after %d attempts:\n%s" - % (attempts, ex)) - time.sleep(15) - print ("Trying to connect to VM which was just launched on %s, attempt: %d" - % (client.ip(), attempts)) - print("Connected to VM on %s" % client.ip()) - - -def run_testA(): - global genclient - global sutclient - ip = genDPIP.split('.') - hexgenDPIP=hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2) - ip = sutDPIP.split('.') - hexsutDPIP=hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2) - with open("parameters.lua", "w") as f: - f.write('gen_hex_ip="'+hexgenDPIP+'"\n') - f.write('sut_hex_ip="'+hexsutDPIP+'"\n') - f.write('gen_ip="'+genDPIP+'"\n') - f.write('sut_ip="'+sutDPIP+'"\n') - f.close - genclient.scp_put('./gen.cfg', '/root/gen.cfg') - sutclient.scp_put('./sut.cfg', '/root/sut.cfg') - genclient.scp_put('./parameters.lua', '/root/parameters.lua') - sutclient.scp_put('./parameters.lua', '/root/parameters.lua') - print("Config files copied") - cmd = '/root/prox/build/prox -e -t -o cli -f /root/gen.cfg' - genclient.fork_cmd(cmd, 'PROX GEN') - cmd = '/root/prox/build/prox -t -o cli -f /root/sut.cfg' - sutclient.fork_cmd(cmd, 'PROX SUT') - gensock = connect_socket(genclient) - sutsock = connect_socket(sutclient) - new_speed = 100 - attempts = 0 - cores = [1,2] - gencores = [1] - gensock.reset_stats() - sutsock.reset_stats() - gensock.start([2]) - print("+---------------------------------------------------------------------------------------------------------+") - print("| Generator is sending UDP (1 flow) packets (64 bytes) to SUT. SUT sends packets back |") - print("+------+-----------------+----------------+----------------+----------------+----------------+------------+") - print("| Test | Speed requested | Req to Generate| Sent by Gen | Forward by SUT | Rec. by Gen | Result |") - print("+------+-----------------+----------------+----------------+----------------+----------------+------------+") - while (new_speed > 0.1): - attempts += 1 - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(new_speed, gencores) - gensock.start(gencores) - time.sleep(1) - # Get statistics now that the generation is stable and NO ARP messages any more - old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats([1]) - old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(cores) - time.sleep(10) - # Get statistics after some execution time - new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(cores) - new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats([1]) - time.sleep(1) - # Stop generating - gensock.stop(gencores) - 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. - 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 (tx == 0): - raise Exception("TX = 0") - drop_rate = round(((drop-rx) * 100.0)/(tx+drop-rx),1) - pps_req_tx = round((tx+drop-rx)*tsc_hz*1.0/(tsc*1000000),5) - pps_tx = round(tx*tsc_hz*1.0/(tsc*1000000),5) - pps_rx = round(rx*tsc_hz*1.0/(tsc*1000000),5) - pps_sut_tx = round(sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000),5) - if ((drop_rate) < 1): - # This will stop the test when number of dropped packets is below a certain percentage - print("+------+-----------------+----------------+----------------+----------------+----------------+------------+") - print('|{:>5}'.format(str(attempts))+" | "+ '{:>14}'.format(str(new_speed)) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(str(pps_sut_tx)) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+" Mpps | SUCCESS |") - print("+------+-----------------+----------------+----------------+----------------+----------------+------------+") - break - else: - print('|{:>5}'.format(str(attempts))+" | "+ '{:>14}'.format(str(new_speed)) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(str(pps_sut_tx)) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+" Mpps | FAILED |") - # Following calculates the ratio for the new speed to be applied - # On the Y axis, we will find the ratio, a number between 0 and 1 - # On the x axis, we find the % of dropped packets, a number between 0 and 100 - # 2 lines are drawn and we take the minumun of these lines to calculate the ratio - # One line goes through (0,y0) and (p,q) - # The second line goes through (p,q) and (100,y100) - y0=0.99 - y100=0.1 - p=15 - q=.9 - ratio = min((q-y0)/p*drop_rate+y0,(q-y100)/(p-100)*drop_rate+q-p*(q-y100)/(p-100)) - new_speed = (int(new_speed*ratio*100)+0.5)/100 - gensock.quit() - sutsock.quit() - time.sleep(2) - print("") - -def run_testB(): - global genclient - global sutclient - ip = genDPIP.split('.') - hexgenDPIP=hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2) - ip = sutDPIP.split('.') - hexsutDPIP=hex(int(ip[0]))[2:].zfill(2) + ' ' + hex(int(ip[1]))[2:].zfill(2) + ' ' + hex(int(ip[2]))[2:].zfill(2) + ' ' + hex(int(ip[3]))[2:].zfill(2) - with open("parameters.lua", "w") as f: - f.write('gen_hex_ip="'+hexgenDPIP+'"\n') - f.write('sut_hex_ip="'+hexsutDPIP+'"\n') - f.write('gen_ip="'+genDPIP+'"\n') - f.write('sut_ip="'+sutDPIP+'"\n') - f.close - genclient.scp_put('./gen.cfg', '/root/gen.cfg') - sutclient.scp_put('./sut.cfg', '/root/sut.cfg') - genclient.scp_put('./parameters.lua', '/root/parameters.lua') - sutclient.scp_put('./parameters.lua', '/root/parameters.lua') - print("Config files copied") - cmd = '/root/prox/build/prox -e -t -o cli -f /root/gen.cfg' - genclient.fork_cmd(cmd, 'PROX GEN') - cmd = '/root/prox/build/prox -t -o cli -f /root/sut.cfg' - sutclient.fork_cmd(cmd, 'PROX SUT') - gensock = connect_socket(genclient) - sutsock = connect_socket(sutclient) - print("+----------------------------------------------------------------------------------------------+") - print("| UDP, 64 bytes, different number of flows by randomizing SRC & DST UDP port |") - print("+--------+-----------------+----------------+----------------+----------------+----------------+") - print("| Flows | Speed requested | Req to Generate| Sent by Gen | Forward by SUT | Rec. by Gen |") - print("+--------+-----------------+----------------+----------------+----------------+----------------+") - cores = [1,2] - gencores = [1] - gensock.start([2]) - new_speed = 100 - # 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={128:['0000000000000XXX','000000000000XXXX'],1024:['00000000000XXXXX','00000000000XXXXX'],8192:['0000000000XXXXXX','000000000XXXXXXX'],65535:['00000000XXXXXXXX','00000000XXXXXXXX'],524280:['0000000XXXXXXXXX','000000XXXXXXXXXX']} - for flow_number in sorted(flows.iterkeys()): - #new_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 - attempts = 0 - gensock.reset_stats() - 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) - while (new_speed > 0.1): - attempts += 1 - # Start generating packets at requested speed (in % of a 10Gb/s link) - gensock.speed(new_speed, gencores) - gensock.start(gencores) - time.sleep(1) - # Get statistics now that the generation is stable and NO ARP messages any more - old_sut_rx, old_sut_tx, old_sut_drop, old_sut_tsc, sut_tsc_hz = sutsock.core_stats([1]) - old_rx, old_tx, old_drop, old_tsc, tsc_hz = gensock.core_stats(cores) - time.sleep(10) - # Get statistics after some execution time - new_rx, new_tx, new_drop, new_tsc, tsc_hz = gensock.core_stats(cores) - new_sut_rx, new_sut_tx, new_sut_drop, new_sut_tsc, sut_tsc_hz = sutsock.core_stats([1]) - time.sleep(1) - # Stop generating - gensock.stop(gencores) - 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. - 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 (tx == 0): - raise Exception("TX = 0") - drop_rate = round(((drop-rx) * 100.0)/(tx+drop-rx),1) - pps_req_tx = round((tx+drop-rx)*tsc_hz*1.0/(tsc*1000000),5) - pps_tx = round(tx*tsc_hz*1.0/(tsc*1000000),5) - pps_rx = round(rx*tsc_hz*1.0/(tsc*1000000),5) - pps_sut_tx = round(sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000),5) - if ((drop_rate) < 1): - # This will stop the test when number of dropped packets is below a certain percentage - print('|{:>7}'.format(str(flow_number))+" | "+ '{:>14}'.format(str(new_speed)) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(str(pps_sut_tx)) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+" Mpps |") - print("+--------+-----------------+----------------+----------------+----------------+----------------+") - break - # Following calculates the ratio for the new speed to be applied - # On the Y axis, we will find the ratio, a number between 0 and 1 - # On the x axis, we find the % of dropped packets, a number between 0 and 100 - # 2 lines are drawn and we take the minumun of these lines to calculate the ratio - # One line goes through (0,y0) and (p,q) - # The second line goes through (p,q) and (100,y100) - y0=0.99 - y100=0.1 - p=15 - q=.9 - ratio = min((q-y0)/p*drop_rate+y0,(q-y100)/(p-100)*drop_rate+q-p*(q-y100)/(p-100)) - new_speed = (int(new_speed*ratio*100)+0.5)/100 - gensock.quit() - sutsock.quit() - time.sleep(2) - print("") - -#======================================================================== -genclient = prox_ctrl(genAdminIP, key+'.pem') -connect_client(genclient) -sutclient = prox_ctrl(sutAdminIP, key+'.pem') -connect_client(sutclient) -##################################################################################### -run_testA() -run_testB() -##################################################################################### -genclient.close() -sutclient.close() - |