Reporting test details for all tests
[samplevnf.git] / VNFs / DPPD-PROX / helper-scripts / rapid / rapid_flowsizetest.py
index b8071b4..c4308b1 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 
 ##
-## Copyright (c) 2010-2020 Intel Corporation
+## Copyright (c) 2020 Intel Corporation
 ##
 ## Licensed under the Apache License, Version 2.0 (the "License");
 ## you may not use this file except in compliance with the License.
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ##
-
 import sys
 import time
 from math import ceil
+from statistics import mean
 from past.utils import old_div
 from rapid_log import RapidLog
 from rapid_log import bcolors
@@ -30,39 +30,35 @@ class FlowSizeTest(RapidTest):
     """
     Class to manage the flowsizetesting
     """
-    def __init__(self, test_param, lat_percentile, runtime, pushgateway,
+    def __init__(self, test_param, lat_percentile, runtime, testname,
             environment_file, gen_machine, sut_machine, background_machines):
-        self.test = test_param
+        super().__init__(test_param, runtime, testname, environment_file)
         self.gen_machine = gen_machine
         self.sut_machine = sut_machine
         self.background_machines = background_machines
         self.test['lat_percentile'] = lat_percentile
-        self.test['runtime'] = runtime
-        self.test['pushgateway'] = pushgateway
-        self.test['environment_file'] = environment_file
-        if 'maxr' not in self.test.keys():
-            self.test['maxr'] = 1
-        if 'maxz' not in self.test.keys():
-            self.test['maxz'] = inf
         if self.test['test'] == 'TST009test':
-            # This test implements some of the testing as defined in https://docbox.etsi.org/ISG/NFV/open/Publications_pdf/Specs-Reports/NFV-TST%20009v3.2.1%20-%20GS%20-%20NFVI_Benchmarks.pdf
-            self.test['TST009_n'] = int(ceil(old_div(self.test['maxframespersecondallingress'], self.test['stepsize'])))
+            # This test implements some of the testing as defined in
+            # https://docbox.etsi.org/ISG/NFV/open/Publications_pdf/Specs-Reports/NFV-TST%20009v3.2.1%20-%20GS%20-%20NFVI_Benchmarks.pdf
+            self.test['TST009_n'] = int(ceil(old_div(
+                self.test['maxframespersecondallingress'],
+                self.test['stepsize'])))
             self.test['TST009'] = True
             self.test['TST009_L'] = 0
             self.test['TST009_R'] = self.test['TST009_n'] - 1
             self.test['TST009_S']= []
             for m in range(0, self.test['TST009_n']):
                 self.test['TST009_S'].append((m+1) * self.test['stepsize'])
-            self.test['lat_avg_threshold'] = inf
-            self.test['lat_perc_threshold'] = inf
-            self.test['lat_max_threshold'] = inf
         elif self.test['test'] == 'fixed_rate':
-            for key in['drop_rate_threshold','lat_avg_threshold','lat_perc_threshold','lat_max_threshold']:
+            for key in['drop_rate_threshold','lat_avg_threshold',
+                    'lat_perc_threshold','lat_max_threshold']:
                 self.test[key] = inf
 
     def new_speed(self, speed,size,success):
         if self.test['test'] == 'fixed_rate':
             return (self.test['startspeed'])
+        elif self.test['test'] == 'increment_till_fail':
+            return (speed + self.test['step'])
         elif 'TST009' in self.test.keys():
             if success:
                 self.test['TST009_L'] = self.test['TST009_m'] + 1
@@ -80,6 +76,8 @@ class FlowSizeTest(RapidTest):
     def get_start_speed_and_init(self, size):
         if self.test['test'] == 'fixed_rate':
             return (self.test['startspeed'])
+        elif self.test['test'] == 'increment_till_fail':
+            return (self.test['startspeed'])
         elif 'TST009' in self.test.keys():
             self.test['TST009_L'] = 0
             self.test['TST009_R'] = self.test['TST009_n'] - 1
@@ -99,21 +97,17 @@ class FlowSizeTest(RapidTest):
             return ((self.test['maxspeed'] - self.test['minspeed']) <= self.test['accuracy'])
 
     def run(self):
-    #    global fieldnames
-    #    global writer
-    #    #fieldnames = ['Flows','PacketSize','Gbps','Mpps','AvgLatency','MaxLatency','PacketsDropped','PacketDropRate']
-    #    fieldnames = ['Flows','PacketSize','RequestedPPS','GeneratedPPS','SentPPS','ForwardedPPS','ReceivedPPS','AvgLatencyUSEC','MaxLatencyUSEC','Sent','Received','Lost','LostTotal']
-    #    writer = csv.DictWriter(data_csv_file, fieldnames=fieldnames)
-    #    writer.writeheader()
+        result_details = {'Details': 'Nothing'}
         self.gen_machine.start_latency_cores()
         TestPassed = True
-        for size in self.test['packetsizes']:
-            self.gen_machine.set_udp_packet_size(size)
+        for imix in self.test['imixs']:
+            size = mean(imix)
+            self.gen_machine.set_udp_packet_size(imix)
             if self.background_machines:
                 backgroundinfo = '{}Running {} x background traffic not represented in the table{}'.format(bcolors.FLASH,len(self.background_machines),bcolors.ENDC)
             else:
                 backgroundinfo = '{}{}'.format(bcolors.FLASH,bcolors.ENDC)
-            self.set_background_size(self.background_machines, size)
+            self.set_background_size(self.background_machines, imix)
             RapidLog.info("+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+")
             RapidLog.info('| UDP, {:>5} bytes, different number of flows by randomizing SRC & DST UDP port. {:116.116}|'.format(size, backgroundinfo))
             RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
@@ -124,10 +118,11 @@ class FlowSizeTest(RapidTest):
                 self.gen_machine.reset_stats()
                 if self.sut_machine:
                     self.sut_machine.reset_stats()
-                self.gen_machine.set_flows(flow_number)
+                flow_number = self.gen_machine.set_flows(flow_number)
                 self.set_background_flows(self.background_machines, flow_number)
                 endspeed = None
                 speed = self.get_start_speed_and_init(size)
+                self.record_start_time()
                 while True:
                     attempts += 1
                     endwarning = False
@@ -138,7 +133,7 @@ class FlowSizeTest(RapidTest):
                     self.set_background_speed(self.background_machines, speed)
                     self.start_background_traffic(self.background_machines)
                     # Get statistics now that the generation is stable and initial ARP messages are dealt with
-                    pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg,lat_perc , lat_perc_max, lat_max, abs_tx,abs_rx,abs_dropped, abs_tx_fail, drop_rate, lat_min, lat_used, r, actual_duration = self.run_iteration(float(self.test['runtime']),flow_number,size,speed)
+                    pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg,lat_perc , lat_perc_max, lat_max, abs_tx,abs_rx,abs_dropped, abs_tx_fail, drop_rate, lat_min, lat_used, r, actual_duration, avg_bg_rate, bucket_size, buckets = self.run_iteration(float(self.test['runtime']),flow_number,size,speed)
                     self.stop_background_traffic(self.background_machines)
                     if r > 1:
                         retry_warning = bcolors.WARNING + ' {:1} retries needed'.format(r) +  bcolors.ENDC
@@ -160,14 +155,16 @@ class FlowSizeTest(RapidTest):
                         endlat_perc = lat_perc
                         endlat_perc_max = lat_perc_max
                         endlat_max = lat_max
+                        endbuckets = buckets
                         endabs_dropped = abs_dropped
                         enddrop_rate = drop_rate
                         endabs_tx = abs_tx
                         endabs_rx = abs_rx
+                        endavg_bg_rate = avg_bg_rate
                         if lat_warning or retry_warning:
                             endwarning = '|        | {:177.177} |'.format(retry_warning + lat_warning)
                         success = True
-                        TestPassed = False # fixed rate testing cannot be True, it is just reported numbers every second
+                        TestPassed = False # fixed rate testing cannot be True, it is just reporting numbers every second
                         speed_prefix = lat_avg_prefix = lat_perc_prefix = lat_max_prefix = abs_drop_rate_prefix = drop_rate_prefix = bcolors.ENDC
                     # The following if statement is testing if we pass the success criteria of a certain drop rate, average latency and maximum latency below the threshold
                     # The drop rate success can be achieved in 2 ways: either the drop rate is below a treshold, either we want that no packet has been lost during the test
@@ -192,12 +189,14 @@ class FlowSizeTest(RapidTest):
                         endlat_perc = lat_perc
                         endlat_perc_max = lat_perc_max
                         endlat_max = lat_max
+                        endbuckets = buckets
                         endabs_dropped = None
                         enddrop_rate = drop_rate
                         endabs_tx = abs_tx
                         endabs_rx = abs_rx
+                        endavg_bg_rate = avg_bg_rate
                         if lat_warning or gen_warning or retry_warning:
-                            endwarning = '|        | {:177.177} |'.format(retry_warning + lat_warning + gen_warning)
+                            endwarning = '|        | {:186.186} |'.format(retry_warning + lat_warning + gen_warning)
                         success = True
                         success_message=' SUCCESS'
                         speed_prefix = lat_avg_prefix = lat_perc_prefix = lat_max_prefix = abs_drop_rate_prefix = drop_rate_prefix = bcolors.ENDC
@@ -230,30 +229,46 @@ class FlowSizeTest(RapidTest):
                         success = False 
                         RapidLog.debug(self.report_result(-attempts,size,speed,pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg,lat_perc,lat_perc_max,lat_max,abs_tx,abs_rx,abs_dropped,actual_duration,speed_prefix,lat_avg_prefix,lat_perc_prefix,lat_max_prefix,abs_drop_rate_prefix,drop_rate_prefix)+ success_message + retry_warning + lat_warning)
                     speed = self.new_speed(speed, size, success)
-                    if self.resolution_achieved():
+                    if self.test['test'] == 'increment_till_fail':
+                        if not success:
+                            break
+                    elif self.resolution_achieved():
                         break
+                self.record_stop_time()
                 if endspeed is not None:
                     if TestPassed and (endpps_rx < self.test['pass_threshold']):
                         TestPassed = False
                     speed_prefix = lat_avg_prefix = lat_perc_prefix = lat_max_prefix = abs_drop_rate_prefix = drop_rate_prefix = bcolors.ENDC
                     RapidLog.info(self.report_result(flow_number,size,endspeed,endpps_req_tx,endpps_tx,endpps_sut_tx,endpps_rx,endlat_avg,endlat_perc,endlat_perc_max,endlat_max,endabs_tx,endabs_rx,endabs_dropped,actual_duration,speed_prefix,lat_avg_prefix,lat_perc_prefix,lat_max_prefix,abs_drop_rate_prefix,drop_rate_prefix))
+                    if endavg_bg_rate:
+                        tot_avg_rx_rate = endpps_rx + (endavg_bg_rate * len(self.background_machines))
+                        endtotaltrafficrate = '|        | Total amount of traffic received by all generators during this test: {:>4.3f} Gb/s {:7.3f} Mpps {} |'.format(RapidTest.get_speed(tot_avg_rx_rate,size) , tot_avg_rx_rate, ' '*84)
+                        RapidLog.info (endtotaltrafficrate)
                     if endwarning:
                         RapidLog.info (endwarning)
                     RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
-    #                writer.writerow({'Flows':flow_number,'PacketSize':(size+4),'RequestedPPS':self.get_pps(endspeed,size),'GeneratedPPS':endpps_req_tx,'SentPPS':endpps_tx,'ForwardedPPS':endpps_sut_tx,'ReceivedPPS':endpps_rx,'AvgLatencyUSEC':endlat_avg,'MaxLatencyUSEC':endlat_max,'Sent':endabs_tx,'Received':endabs_rx,'Lost':endabs_dropped,'LostTotal':endabs_dropped})
-                    if self.test['pushgateway']:
-                        URL = self.test['pushgateway'] + '/metrics/job/' + self.test['test']+ '/instance/' + self.test['environment_file']
-                        if endabs_dropped == None:
-                            ead = 0
-                        else:
-                            ead = endabs_dropped
-                        DATA = 'Flows {}\nPacketSize {}\nRequestedPPS {}\nGeneratedPPS {}\nSentPPS {}\nForwardedPPS {}\nReceivedPPS {}\nAvgLatencyUSEC {}\nMaxLatencyUSEC {}\nSent {}\nReceived {}\nLost {}\nLostTotal {}\n'.format(flow_number,size+4,self.get_pps(endspeed,size),endpps_req_tx,endpps_tx,endpps_sut_tx,endpps_rx,endlat_avg,endlat_max,endabs_tx,endabs_rx,ead,ead)
-                        HEADERS = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
-                        response = requests.post(url=URL, data=DATA,headers=HEADERS)
-                        if (response.status_code != 202) and (response.status_code != 200):
-                            RapidLog.info('Cannot send metrics to {}'.format(URL))
-                            RapidLog.info(DATA)
+                    if self.test['test'] != 'fixed_rate':
+                        result_details = {'test': self.test['testname'],
+                                'environment_file': self.test['environment_file'],
+                                'start_date': self.start,
+                                'stop_date': self.stop,
+                                'Flows': flow_number,
+                                'Size': size,
+                                'RequestedSpeed': RapidTest.get_pps(endspeed,size),
+                                'CoreGenerated': endpps_req_tx,
+                                'SentByNIC': endpps_tx,
+                                'FwdBySUT': endpps_sut_tx,
+                                'RevByCore': endpps_rx,
+                                'AvgLatency': endlat_avg,
+                                'PCTLatency': endlat_perc,
+                                'MaxLatency': endlat_max,
+                                'PacketsSent': endabs_tx,
+                                'PacketsReceived': endabs_rx,
+                                'PacketsLost': endabs_dropped,
+                                'bucket_size': bucket_size,
+                                'buckets': endbuckets}
+                        result_details = self.post_data('rapid_flowsizetest', result_details)
                 else:
                     RapidLog.info('|{:>7}'.format(str(flow_number))+" | Speed 0 or close to 0")
         self.gen_machine.stop_latency_cores()
-        return (TestPassed)
+        return (TestPassed, result_details)