From 7fa9c0b506709a683ec8984e19e9ba9deb27e021 Mon Sep 17 00:00:00 2001 From: Luc Provoost Date: Sat, 3 Feb 2018 22:47:55 +0100 Subject: Fixed issues with the pkt_size command Fixed issues with pkt_size. For a 64 byte packet, we need to issue pkt_size 60 4 extra bytes will be calculated and added automatically by PROX Also added the missing irq.test and irq.cfg files Added support for OpenStack systems not using floating IP addresses Change-Id: I05d775eb858a58dd349ea370a0e34ac6448590c9 Signed-off-by: Luc Provoost --- .../helper-scripts/openstackrapid/runrapid.py | 147 ++++++++++++++------- 1 file changed, 97 insertions(+), 50 deletions(-) (limited to 'VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py') diff --git a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py index 22181b96..7b999523 100755 --- a/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py +++ b/VNFs/DPPD-PROX/helper-scripts/openstackrapid/runrapid.py @@ -32,15 +32,15 @@ from prox_ctrl import prox_ctrl import ConfigParser import ast -version="17.12.15" -stack = "rapid" #Default string for stack +version="18.2.3" +env = "rapid" #Default string for environment test = "basicrapid" #Default string for test loglevel="DEBUG" # sets log level for writing to file runtime=10 # time in seconds for 1 test run def usage(): print("usage: runrapid [--version] [-v]") - print(" [--stack STACK_NAME]") + print(" [--env ENVIRONMENT_NAME]") print(" [--test TEST_NAME]") print(" [--runtime TIME_FOR_TEST]") print(" [--log DEBUG|INFO|WARNING|ERROR|CRITICAL]") @@ -50,7 +50,7 @@ def usage(): print("") print("optional arguments:") print(" -v, --version Show program's version number and exit") - print(" --stack STACK_NAME Parameters will be read from STACK_NAME.env Default is %s."%stack) + 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(" --runtime Specify time in seconds for 1 test run") print(" --log Specify logging level for log file output, screen output level is hard coded") @@ -58,7 +58,7 @@ def usage(): print("") try: - opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "stack=", "test=","runtime=","log="]) + opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "env=", "test=","runtime=","log="]) except getopt.GetoptError as err: print("===========================================") print(str(err)) @@ -75,9 +75,9 @@ for opt, arg in opts: 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") + 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") @@ -114,7 +114,7 @@ console_handler.setFormatter(screen_formatter) # create a file handler # and set its log level to DEBUG # -log_file = 'RUN' +stack+'.'+test+'.log' +log_file = 'RUN' +env+'.'+test+'.log' file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10) #file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5) file_handler.setLevel(numeric_level) @@ -177,7 +177,7 @@ def connect_client(client): def run_iteration(gensock,sutsock): gensock.start(gencores) - time.sleep(1) + time.sleep(3) 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) @@ -202,7 +202,7 @@ def run_iteration(gensock,sutsock): sut_tx = new_sut_tx - old_sut_tx sut_tsc = new_sut_tsc - old_sut_tsc pps_sut_tx = round(sut_tx*sut_tsc_hz*1.0/(sut_tsc*1000000),3) - pps_sut_tx_str = str(pps_sut_tx) + pps_sut_tx_str = '{:>9.2f}'.format(pps_sut_tx) else: pps_sut_tx = 0 pps_sut_tx_str = 'NO MEAS.' @@ -211,19 +211,28 @@ def run_iteration(gensock,sutsock): raise Exception("TX = 0") return(pps_req_tx,pps_tx,pps_sut_tx_str,pps_rx,lat_avg) -def new_speed(speed,drop_rate): +def new_speed(speed,minspeed,maxspeed,drop_rate): # 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=1 - q=.99 - ratio = min((q-y0)/p*drop_rate+y0,(q-y100)/(p-100)*drop_rate+q-p*(q-y100)/(p-100)) - return (int(speed*ratio*100)+0.5)/100.0 +# y0=0.99 +# y100=0.1 +# p=1 +# q=.99 +# ratio = min((q-y0)/p*drop_rate+y0,(q-y100)/(p-100)*drop_rate+q-p*(q-y100)/(p-100)) +# return (int(speed*ratio*100)+0.5)/100.0 + if drop_rate < DROP_RATE_TRESHOLD: + minspeed = speed + else: + maxspeed = speed + newspeed = (maxspeed+minspeed)/2.0 + return (newspeed,minspeed,maxspeed) + +def get_pps(speed,size): + return (speed * 100.0 / (8*(size+24))) def get_drop_rate(speed,pps_rx,size): # pps_rx are all the packets that are received by the generator. That is substracted @@ -232,7 +241,7 @@ def get_drop_rate(speed,pps_rx,size): # that the speed variable is already expressed in % so we only take 100 and not 10000) # divided by the number of bits in 1 packet. That is 8 bits in a byte times the size of # a frame (=our size + 24 bytes overhead). - tried_to_send = speed * 100.0 / (8*(size+24)) + tried_to_send = get_pps(speed,size) return (100.0*(tried_to_send - pps_rx)/tried_to_send) def run_speedtest(gensock,sutsock): @@ -242,9 +251,16 @@ def run_speedtest(gensock,sutsock): log.info("| Test | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency | Result |") log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+------------+") speed = 100 - size=64 + maxspeed = speed + minspeed = 0 + size=60 attempts = 0 - while (speed > 0.1): + 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-18),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-38),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 + while (maxspeed-minspeed > 1): attempts += 1 print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r') sys.stdout.flush() @@ -254,16 +270,23 @@ 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 = run_iteration(gensock,sutsock) drop_rate = get_drop_rate(speed,pps_rx,size) - if ((drop_rate) < 1): - # This will stop the test when number of dropped packets is below a certain percentage - log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+------------+") - log.info('|{:>7}'.format(str(attempts))+" | "+ '{:>14}'.format(str(round(speed,2))) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+' Mpps | '+ '{:>9}'.format(str(lat_avg))+" us | SUCCESS |") - log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+------------+") - break + if (drop_rate < DROP_RATE_TRESHOLD): + log.info('|{:>7}'.format(str(attempts))+" | "+ '{:>10.2f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.2f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.2f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.2f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+" us | SUCCESS |") + 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 else: - log.info('|{:>7}'.format(str(attempts))+" | "+ '{:>14}'.format(str(round(speed,2))) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+' Mpps | '+ '{:>9}'.format(str(lat_avg))+" us | FAILED |") - speed = new_speed(speed,drop_rate) - time.sleep(2) + log.info('|{:>7}'.format(str(attempts))+" | "+ '{:>10.2f}'.format(get_pps(speed,size)) + ' Mpps | '+ '{:>9.2f}'.format(pps_req_tx)+' Mpps | '+ '{:>9.2f}'.format(pps_tx) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9.2f}'.format(pps_rx)+' Mpps | '+ '{:>9.0f}'.format(lat_avg)+" us | FAILED |") + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,drop_rate) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+------------+") + log.info('|{:>7}'.format("END")+" | "+ '{:>10.2f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.2f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.2f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.2f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+" us | SUCCESS |") + log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+------------+") + else: + log.debug('| Speed 0 or close to 0') def run_flowtest(gensock,sutsock): log.info("+---------------------------------------------------------------------------------------------------------------+") @@ -272,10 +295,14 @@ def run_flowtest(gensock,sutsock): log.info("| Flows | Speed requested | Sent to NIC | Sent by Gen | Forward by SUT | Rec. by Gen | Avg. Latency |") log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") speed = 100 - size=64 + size=60 # 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:['1000000000000XXX','100000000000XXXX'],1024:['10000000000XXXXX','10000000000XXXXX'],8192:['1000000000XXXXXX','100000000XXXXXXX'],65535:['10000000XXXXXXXX','10000000XXXXXXXX'],524280:['1000000XXXXXXXXX','100000XXXXXXXXXX']} # flows={524280:['1000000XXXXXXXXX','100000XXXXXXXXXX']} + gensock.set_size(gencores,0,size) # This is setting the frame size + gensock.set_value(gencores,0,16,(size-18),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-38),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() @@ -284,7 +311,10 @@ def run_flowtest(gensock,sutsock): 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 (speed > 0.1): + endpps_sut_tx_str = 'NO_RESULTS' + maxspeed = speed + minspeed = 0 + while (maxspeed-minspeed > 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) @@ -293,13 +323,19 @@ 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 = run_iteration(gensock,sutsock) drop_rate = get_drop_rate(speed,pps_rx,size) - if ((drop_rate) < 1): - # This will stop the test when number of dropped packets is below a certain percentage - log.info('|{:>7}'.format(str(flow_number))+" | "+ '{:>14}'.format(str(round(speed,2))) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+" Mpps |"+ '{:>10}'.format(str(lat_avg))+" us |") - log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") - break - speed = new_speed(speed,drop_rate) - time.sleep(2) + if (drop_rate < DROP_RATE_TRESHOLD): + 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 + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,drop_rate) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info('|{:>7}'.format(str(flow_number))+" | "+ '{:>10.2f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.2f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.2f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.2f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us |{:>7.1f}%'.format(speed)) + log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") + else: + log.debug('|{:>7}'.format(str(flow_number))+" | Speed 0 or close to 0") def run_sizetest(gensock,sutsock): log.info("+---------------------------------------------------------------------------------------------------------------+") @@ -309,7 +345,8 @@ def run_sizetest(gensock,sutsock): log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") speed = 100 # PROX will use different packet sizes as defined in sizes[] - sizes=[1400,1024,512,256,128,64] +# sizes=[1496,1020,508,252,124,60] + sizes=[1020,508,252,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() @@ -319,22 +356,30 @@ def run_sizetest(gensock,sutsock): gensock.set_value(gencores,0,16,(size-18),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-38),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 - while (speed > 0.1): + endpps_sut_tx_str = 'NO_RESULTS' + maxspeed = speed + minspeed = 0 + while (maxspeed-minspeed > 1): print(str(size)+' 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, gencores) - 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 = run_iteration(gensock,sutsock) drop_rate = get_drop_rate(speed,pps_rx,size) - if ((drop_rate) < 1): - # This will stop the test when number of dropped packets is below a certain percentage - log.info('|{:>7}'.format(str(size))+" | "+ '{:>14}'.format(str(round(speed,2))) + '% | '+ '{:>9}'.format(str(pps_req_tx))+' Mpps | '+ '{:>9}'.format(str(pps_tx)) +' Mpps | ' + '{:>9}'.format(pps_sut_tx_str) +' Mpps | '+ '{:>9}'.format(str(pps_rx))+" Mpps |"+ '{:>10}'.format(str(lat_avg))+" us |") - log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") - break - speed = new_speed(speed,drop_rate) - time.sleep(2) + if (drop_rate < DROP_RATE_TRESHOLD): + 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 + speed,minspeed,maxspeed = new_speed(speed,minspeed,maxspeed,drop_rate) + if endpps_sut_tx_str <> 'NO_RESULTS': + log.info('|{:>7d}'.format(size+4)+" | "+ '{:>10.2f}'.format(get_pps(endspeed,size)) + ' Mpps | '+ '{:>9.2f}'.format(endpps_req_tx)+' Mpps | '+ '{:>9.2f}'.format(endpps_tx) +' Mpps | ' + '{:>9}'.format(endpps_sut_tx_str) +' Mpps | '+ '{:>9.2f}'.format(endpps_rx)+' Mpps | '+ '{:>9.0f}'.format(endlat_avg)+' us | {:>7.1f}%'.format(speed)) + log.info("+--------+-----------------+----------------+----------------+----------------+----------------+----------------+") + else: + log.debug('|{:>7}'.format(str(size))+" | Speed 0 or close to 0") def run_irqtest(sock): log.info("+----------------------------------------------------------------------------------------------------------------------------") @@ -383,6 +428,8 @@ global genstatcores global latcores global gencores global irqcores +global DROP_RATE_TRESHOLD +DROP_RATE_TRESHOLD = 1 vmDPIP =[] vmAdminIP =[] vmDPmac =[] @@ -394,7 +441,7 @@ testconfig = ConfigParser.RawConfigParser() testconfig.read(test+'.test') required_number_of_VMs = testconfig.get('DEFAULT', 'total_number_of_vms') config = ConfigParser.RawConfigParser() -config.read(stack+'.env') +config.read(env+'.env') key = config.get('OpenStack', 'key') total_number_of_VMs = config.get('rapid', 'total_number_of_VMs') if int(required_number_of_VMs) > int(total_number_of_VMs): -- cgit 1.2.3-korg