Rework of statistics reporting 78/72378/1
authorLuc Provoost <luc.provoost@intel.com>
Thu, 15 Apr 2021 09:49:42 +0000 (11:49 +0200)
committerLuc Provoost <luc.provoost@intel.com>
Thu, 15 Apr 2021 09:49:42 +0000 (11:49 +0200)
- Cleanup of the format.yaml file.
- Adding of the packet mis-ordering statistics
- Added a warmup phase to get the correct mis-ordering statistics since
  ARP messages need to be dealt with before we can collect correct
  misordering stats
- Code cleanup avoiding some long lines
- Removing background traffic control from rapid_flowsizetest.py since
  this is already done in the iteration code in rapid_test.py

Change-Id: I4c60a90353f27b8e2d0b62505e8f1cd886a17f0a
Signed-off-by: Luc Provoost <luc.provoost@intel.com>
28 files changed:
VNFs/DPPD-PROX/helper-scripts/rapid/configs/gen.cfg
VNFs/DPPD-PROX/helper-scripts/rapid/configs/gen_gw.cfg
VNFs/DPPD-PROX/helper-scripts/rapid/format.yaml
VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_corestatstest.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_flowsizetest.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_impairtest.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_irqtest.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_parser.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_portstatstest.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_test.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_warmuptest.py
VNFs/DPPD-PROX/helper-scripts/rapid/runrapid.py
VNFs/DPPD-PROX/helper-scripts/rapid/tests/TST009_Throughput.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/TST009_Throughput_64B_64F.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/TST009_Throughput_acaeab_16384F.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/TST009ipV6.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/bare.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/basicrapid.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/cgnat.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/corestats.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/impair.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/increment_till_fail.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/ipv6.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/l2zeroloss.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/l3framerate.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/portstats.test
VNFs/DPPD-PROX/helper-scripts/rapid/tests/secgw.test

index d0ccc13..8d3f858 100644 (file)
@@ -50,7 +50,7 @@ task=0
 mode=gen
 sub mode=l3
 tx port=p0
-bps=1250000000
+bps=1250000
 pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip1} ${dest_hex_ip1} 0b b8 0b b9 00 1a 55 7b
 pkt size=60
 min bulk size=$mbs
index 2843d35..8a477e5 100644 (file)
@@ -49,7 +49,7 @@ task=0
 mode=gen
 sub mode=l3
 tx port=p0
-bps=1250000000
+bps=1250000
 pkt inline=00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 00 2e 00 01 00 00 40 11 f7 7d ${local_hex_ip1} ${dest_hex_ip1} 0b b8 0b b9 00 1a 55 7b
 pkt size=60
 gateway ipv4=${gw_ip1}
index 01415ec..8dcb09b 100644 (file)
@@ -7,7 +7,7 @@
   part2: test
   part3: /instance/
   part4: environment_file
-;rapid_flowsizetest:
+;FlowsizeTest:
   Flows: Flows 
   Size: Size
   RequestedSpeed: RequestedSpeed
   PCTLatency: lat_perc
   MinLatency: lat_min
   MaxLatency: lat_max
-  PacketsSent: abs_tx
-  PacketsReceived: abs_rx
-  PacketsLost: abs_dropped
-rapid_flowsizetest:
+  Sent: abs_tx
+  Received: abs_rx
+  Lost: abs_dropped
+  Misordered: mis_ordered
+  Extent: extent
+  Duplicated: duplicate
+FlowSizeTest:
   Environment: environment_file
   Test: test
   Flows: Flows 
@@ -42,11 +45,61 @@ rapid_flowsizetest:
       bucket_size: bucket_size
       buckets: buckets
   Absolute Packet Count:
-    PacketsSent: abs_tx
-    PacketsReceived: abs_rx
-    PacketsLost: abs_dropped
-rapid_irqtest:
+    Sent: abs_tx
+    Received: abs_rx
+    Lost: abs_dropped
+  Re-ordering:
+    Misordered: mis_ordered
+    Extent: extent
+    Duplicated: duplicate
+IrqTest:
   Environment: environment_file
   Test: test
   Buckets: buckets
-  Machine_data: machine_data 
+  Machine_data: machine_data
+ImpairTest:
+  Environment: environment_file
+  Test: test
+  Flows: Flows 
+  Size: Size
+  Speed (Mpps):
+    RequestedSpeed: RequestedSpeed
+    CoreGenerated: pps_req_tx
+    SentByNIC: pps_tx
+    FwdBySUT: pps_sut_tx
+    RevByCore: pps_rx
+  Latency (usec):
+    AvgLatency: lat_avg
+    PCTLatency: lat_perc
+    MinLatency: lat_min
+    MaxLatency: lat_max
+    Distribution:
+      bucket_size: bucket_size
+      buckets: buckets
+  Absolute Packet Count:
+    Sent: abs_tx
+    Received: abs_rx
+    Lost: abs_dropped
+  Re-ordering:
+    Misordered: mis_ordered
+    Extent: extent
+    Duplicated: duplicate
+CoreStatsTest:
+  Environment: environment_file
+  Test: test
+  PROXID: PROXID
+  StepSize: StepSize
+  Received: Received
+  Sent: Sent
+  NonDPReceived: NonDPReceived
+  NonDPSent: NonDPSent
+  Dropped: Dropped
+PortStatsTest:
+  Environment: environment_file
+  Test: test
+  PROXID: PROXID
+  StepSize: StepSize
+  Received: Received
+  Sent: Sent
+  NoMbufs: NoMbufs
+  iErrMiss: iErrMiss
index a9497e1..8cd2e3f 100644 (file)
@@ -201,8 +201,11 @@ class prox_sock(object):
         result = {}
         result['lat_min'] = 999999999
         result['lat_max'] = result['lat_avg'] = 0
-        number_tasks_returning_stats = 0
         result['buckets'] = [0] * 128
+        result['mis_ordered'] = 0
+        result['extent'] = 0
+        result['duplicate'] = 0
+        number_tasks_returning_stats = 0
         self._send('lat all stats %s %s' % (','.join(map(str, cores)),
             ','.join(map(str, tasks))))
         for core in cores:
@@ -226,9 +229,9 @@ class prox_sock(object):
             result['lat_hz'] = int(stats[6])
             #coreid = int(stats[7])
             #taskid = int(stats[8])
-            mis_ordered = int(stats[9])
-            extent = int(stats[10])
-            duplicate = int(stats[11])
+            result['mis_ordered'] += int(stats[9])
+            result['extent'] += int(stats[10])
+            result['duplicate'] += int(stats[11])
             stats = self._recv().split(':')
             if stats[0].startswith('error'):
                 RapidLog.critical("lat stats error: unexpected lat bucket \
index a6a31c3..e6a7f51 100644 (file)
@@ -30,7 +30,7 @@ class CoreStatsTest(RapidTest):
     def __init__(self, test_param,  runtime, testname, environment_file,
             machines):
         super().__init__(test_param, runtime, testname, environment_file)
-        self.machines = machines 
+        self.machines = machines
 
     def run(self):
         result_details = {'Details': 'Nothing'}
@@ -81,7 +81,7 @@ class CoreStatsTest(RapidTest):
                         'NonDPReceived': non_dp_rx,
                         'NonDPSent': non_dp_tx,
                         'Dropped': tot_drop[i]}
-                result_details = self.post_data('rapid_corestatstest', result_details)
+                result_details = self.post_data(result_details)
                 if machines_to_go == 0:
                     duration = duration - 1
                     machines_to_go = len (self.machines)
index d65afd6..0ca7c71 100644 (file)
@@ -64,8 +64,10 @@ class FlowSizeTest(RapidTest):
             if success:
                 self.test['TST009_L'] = self.test['TST009_m'] + 1
             else:
-                self.test['TST009_R'] = max(self.test['TST009_m'] - 1, self.test['TST009_L'])
-            self.test['TST009_m'] = int (old_div((self.test['TST009_L'] + self.test['TST009_R']),2))
+                self.test['TST009_R'] = max(self.test['TST009_m'] - 1,
+                        self.test['TST009_L'])
+            self.test['TST009_m'] = int (old_div((self.test['TST009_L'] +
+                self.test['TST009_R']),2))
             return (self.get_percentageof10Gbps(self.test['TST009_S'][self.test['TST009_m']],size))
         else:
             if success:
@@ -82,7 +84,8 @@ class FlowSizeTest(RapidTest):
         elif 'TST009' in self.test.keys():
             self.test['TST009_L'] = 0
             self.test['TST009_R'] = self.test['TST009_n'] - 1
-            self.test['TST009_m'] = int(old_div((self.test['TST009_L'] + self.test['TST009_R']), 2))
+            self.test['TST009_m'] = int(old_div((self.test['TST009_L'] +
+                self.test['TST009_R']), 2))
             return (self.get_percentageof10Gbps(self.test['TST009_S'][self.test['TST009_m']],size))
         else:
             self.test['minspeed'] = 0
@@ -97,24 +100,64 @@ class FlowSizeTest(RapidTest):
         else:
             return ((self.test['maxspeed'] - self.test['minspeed']) <= self.test['accuracy'])
 
+    def warm_up(self):
+        # 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 however 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
+        imix = self.test['warmupimix']
+        FLOWSIZE = self.test['warmupflowsize']
+        WARMUPSPEED = self.test['warmupspeed']
+        WARMUPTIME = self.test['warmuptime']
+        RapidLog.info(("Warming up during {} seconds..., packet size = {},"
+            " flows = {}, speed = {}").format(WARMUPTIME, imix, FLOWSIZE,
+                WARMUPSPEED))
+        self.gen_machine.set_generator_speed(WARMUPSPEED)
+        self.set_background_speed(self.background_machines, WARMUPSPEED)
+        self.gen_machine.set_udp_packet_size(imix)
+        self.set_background_size(self.background_machines, imix)
+        _ = self.gen_machine.set_flows(FLOWSIZE)
+        self.set_background_flows(self.background_machines, FLOWSIZE)
+        self.gen_machine.start()
+        self.start_background_traffic(self.background_machines)
+        time.sleep(WARMUPTIME)
+        self.stop_background_traffic(self.background_machines)
+        self.gen_machine.stop()
+
     def run(self):
         result_details = {'Details': 'Nothing'}
         TestResult = 0
         end_data = {}
         iteration_prefix = {}
+        self.warm_up()
         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)
+                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, imix)
-            RapidLog.info("+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+")
-            RapidLog.info('| UDP, {:>5} bytes, different number of flows by randomizing SRC & DST UDP port. {:116.116}|'.format(round(size), backgroundinfo))
-            RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
-            RapidLog.info('| Flows  | Speed requested  | Gen by core | Sent by NIC | Fwrd by SUT | Rec. by core           | Avg. Lat.|{:.0f} Pcentil| Max. Lat.|   Sent    |  Received |    Lost   | Total Lost|L.Ratio|Time|'.format(self.test['lat_percentile']*100))
-            RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
+            RapidLog.info('+' + '-' * 188 + '+')
+            RapidLog.info(("| UDP, {:>5} bytes, different number of flows by "
+                "randomizing SRC & DST UDP port. {:116.116}|").
+                format(round(size), backgroundinfo))
+            RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+                    '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+                    '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+                    + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+                    + '-' * 7 + '+' + '-' * 4 + '+')
+            RapidLog.info(('| Flows  | Speed requested  | Gen by core | Sent by'
+                ' NIC | Fwrd by SUT | Rec. by core           | Avg. Lat.|{:.0f}'
+                ' Pcentil| Max. Lat.|   Sent    |  Received |    Lost   | Total'
+                ' Lost|L.Ratio|Time|').format(self.test['lat_percentile']*100))
+            RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+                    '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+                    '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+                    + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+                    + '-' * 7 + '+' + '-' * 4 + '+')
             for flow_number in self.test['flows']:
                 attempts = 0
                 self.gen_machine.reset_stats()
@@ -122,31 +165,33 @@ class FlowSizeTest(RapidTest):
                     self.sut_machine.reset_stats()
                 flow_number = self.gen_machine.set_flows(flow_number)
                 self.set_background_flows(self.background_machines, flow_number)
-#                endspeed = None
                 end_data['speed'] = None
                 speed = self.get_start_speed_and_init(size)
                 while True:
                     attempts += 1
                     endwarning = False
-                    print(str(flow_number)+' flows: Measurement ongoing at speed: ' + str(round(speed,2)) + '%      ',end='\r')
+                    print('{} flows: Measurement ongoing at speed: {}%'.format(
+                        str(flow_number), str(round(speed, 2))), end='     \r')
                     sys.stdout.flush()
-                    # Start generating packets at requested speed (in % of a 10Gb/s link)
-                    self.gen_machine.set_generator_speed(speed)
-                    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
                     iteration_data = self.run_iteration(
                             float(self.test['runtime']),flow_number,size,speed)
-                    iteration_data['speed'] = speed
-                    self.stop_background_traffic(self.background_machines)
                     if iteration_data['r'] > 1:
-                        retry_warning = bcolors.WARNING + ' {:1} retries needed'.format(iteration_data['r']) +  bcolors.ENDC
+                        retry_warning = '{} {:1} retries needed{}'.format(
+                                bcolors.WARNING, iteration_data['r'],
+                                bcolors.ENDC)
                     else:
                         retry_warning = ''
-                    # Drop rate is expressed in percentage. lat_used is a ratio (0 to 1). The sum of these 2 should be 100%.
-                    # If the sum is lower than 95, it means that more than 5% of the latency measurements where dropped for accuracy reasons.
-                    if (iteration_data['drop_rate'] + iteration_data['lat_used'] * 100) < 95:
-                        lat_warning = bcolors.WARNING + ' Latency accuracy issue?: {:>3.0f}%'.format(iteration_data['lat_used']*100) +  bcolors.ENDC
+                    # Drop rate is expressed in percentage. lat_used is a ratio
+                    # (0 to 1). The sum of these 2 should be 100%.
+                    # If the sum is lower than 95, it means that more than 5%
+                    # of the latency measurements where dropped for accuracy
+                    # reasons.
+                    if (iteration_data['drop_rate'] +
+                            iteration_data['lat_used'] * 100) < 95:
+                        lat_warning = ('{} Latency accuracy issue?: {:>3.0f}%'
+                            '{}').format(bcolors.WARNING,
+                                    iteration_data['lat_used'] * 100,
+                                    bcolors.ENDC)
                     else:
                         lat_warning = ''
                     iteration_prefix = {'speed' : bcolors.ENDC,
@@ -159,11 +204,18 @@ class FlowSizeTest(RapidTest):
                         end_data = copy.deepcopy(iteration_data)
                         end_prefix = copy.deepcopy(iteration_prefix)
                         if lat_warning or retry_warning:
-                            endwarning = '|        | {:177.177} |'.format(retry_warning + lat_warning)
+                            endwarning = '|        | {:177.177} |'.format(
+                                    retry_warning + lat_warning)
                         success = True
-                        #TestResult = TestResult + iteration_data['pps_rx'] # fixed rate testing result is strange: we just report the pps received
-                    # 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
+                        # TestResult = TestResult + iteration_data['pps_rx']
+                        # fixed rate testing result is strange: we just report
+                        # the pps received
+                    # 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.
                     # This can be specified by putting 0 in the .test file
                     elif ((iteration_data['drop_rate'] < self.test['drop_rate_threshold']) or (iteration_data['abs_dropped']==self.test['drop_rate_threshold']==0)) and (iteration_data['lat_avg']< self.test['lat_avg_threshold']) and (iteration_data['lat_perc']< self.test['lat_perc_threshold']) and (iteration_data['lat_max'] < self.test['lat_max_threshold']):
                         if (old_div((self.get_pps(speed,size) - iteration_data['pps_tx']),self.get_pps(speed,size)))>0.01:
@@ -177,7 +229,6 @@ class FlowSizeTest(RapidTest):
                             gen_warning = ''
                         end_data = copy.deepcopy(iteration_data)
                         end_prefix = copy.deepcopy(iteration_prefix)
-                        end_data['abs_dropped'] = None
                         if lat_warning or gen_warning or retry_warning:
                             endwarning = '|        | {:186.186} |'.format(retry_warning + lat_warning + gen_warning)
                         success = True
@@ -219,25 +270,30 @@ class FlowSizeTest(RapidTest):
                             break
                     elif self.resolution_achieved():
                         break
-                if end_data['speed'] is not None:
-                    RapidLog.info(self.report_result(flow_number, size,
-                        end_data, end_prefix))
-                    if end_data['avg_bg_rate']:
-                        tot_avg_rx_rate = end_data['pps_rx'] + (end_data['avg_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("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
-                    if self.test['test'] != 'fixed_rate':
-                        TestResult = TestResult + end_data['pps_rx']
-                        end_data['test'] = self.test['testname']
-                        end_data['environment_file'] = self.test['environment_file']
-                        end_data['Flows'] = flow_number
-                        end_data['Size'] = size
-                        end_data['RequestedSpeed'] = RapidTest.get_pps(end_data['speed'] ,size)
-                        result_details = self.post_data('rapid_flowsizetest', end_data)
-                else:
-                    RapidLog.info('|{:>7}'.format(str(flow_number))+" | Speed 0 or close to 0")
-        self.gen_machine.stop_latency_cores()
+                if end_data['speed'] is None:
+                    end_data = iteration_data
+                    end_prefix = iteration_prefix
+                    RapidLog.info('|{:>7} | {:<177} |'.format("FAILED","Speed 0 or close to 0, data for last failed step below:"))
+                RapidLog.info(self.report_result(flow_number, size,
+                    end_data, end_prefix))
+                if end_data['avg_bg_rate']:
+                    tot_avg_rx_rate = end_data['pps_rx'] + (end_data['avg_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)
+                if self.test['test'] != 'fixed_rate':
+                    TestResult = TestResult + end_data['pps_rx']
+                    end_data['test'] = self.test['testname']
+                    end_data['environment_file'] = self.test['environment_file']
+                    end_data['Flows'] = flow_number
+                    end_data['Size'] = size
+                    end_data['RequestedSpeed'] = RapidTest.get_pps(end_data['speed'] ,size)
+                    result_details = self.post_data(end_data)
+                    RapidLog.debug(result_details)
+                RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+                    '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+                    '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+                    + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+                    + '-' * 7 + '+' + '-' * 4 + '+')
         return (TestResult, result_details)
index ee9ed79..3945cd8 100644 (file)
@@ -21,6 +21,7 @@ import sys
 import time
 import requests
 from rapid_log import RapidLog
+from rapid_log import bcolors
 from rapid_test import RapidTest
 from statistics import mean
 
@@ -29,10 +30,11 @@ class ImpairTest(RapidTest):
     Class to manage the impair testing
     """
     def __init__(self, test_param, lat_percentile, runtime, testname,
-            environment_file, gen_machine, sut_machine):
+            environment_file, gen_machine, sut_machine, background_machines):
         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
 
     def run(self):
@@ -40,20 +42,32 @@ class ImpairTest(RapidTest):
         imix = self.test['imix']
         size = mean (imix)
         flow_number = self.test['flowsize']
-        attempts = 0
+        attempts = self.test['steps']
         self.gen_machine.set_udp_packet_size(imix)
         flow_number = self.gen_machine.set_flows(flow_number)
         self.gen_machine.start_latency_cores()
-        RapidLog.info("+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+")
-        RapidLog.info("| Generator is sending UDP ({:>5} flow) packets ({:>5} bytes) to SUT via GW dropping and delaying packets. SUT sends packets back. Use ctrl-c to stop the test                               |".format(flow_number,round(size)))
-        RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
-        RapidLog.info('| Test   | Speed requested  | Gen by core | Sent by NIC | Fwrd by SUT | Rec. by core           | Avg. Lat.|{:.0f} Pcentil| Max. Lat.|   Sent    |  Received |    Lost   | Total Lost|L.Ratio|Time|'.format(self.test['lat_percentile']*100))
-        RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
-
+        RapidLog.info('+' + '-' * 188 + '+')
+        RapidLog.info(("| Generator is sending UDP ({:>5} flow) packets ({:>5}"
+            " bytes) to SUT via GW dropping and delaying packets. SUT sends "
+            "packets back.{:>60}").format(flow_number,round(size),'|'))
+        RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+            '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+            '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+            + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+            + '-' * 7 + '+' + '-' * 4 + '+')
+        RapidLog.info(('| Test   | Speed requested  | Gen by core | Sent by NIC'
+            ' | Fwrd by SUT | Rec. by core           | Avg. Lat.|{:.0f} Pcentil'
+            '| Max. Lat.|   Sent    |  Received |    Lost   | Total Lost|'
+            'L.Ratio|Time|').format(self.test['lat_percentile']*100))
+        RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+            '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+            '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+            + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+            + '-' * 7 + '+' + '-' * 4 + '+')
         speed = self.test['startspeed']
         self.gen_machine.set_generator_speed(speed)
-        while True:
-            attempts += 1
+        while attempts:
+            attempts -= 1
             print('Measurement ongoing at speed: ' + str(round(speed,2)) + '%      ',end='\r')
             sys.stdout.flush()
             time.sleep(1)
@@ -62,8 +76,11 @@ class ImpairTest(RapidTest):
             iteration_data['speed'] = speed
             # Drop rate is expressed in percentage. lat_used is a ratio (0 to 1). The sum of these 2 should be 100%.
             # If the sum is lower than 95, it means that more than 5% of the latency measurements where dropped for accuracy reasons.
-            if (iteration_data['drop_rate'] + iteration_data['lat_used'] * 100) < 95:
-                lat_warning = bcolors.WARNING + ' Latency accuracy issue?: {:>3.0f}%'.format(iteration_data['lat_used']*100) +  bcolors.ENDC
+            if (iteration_data['drop_rate'] +
+                    iteration_data['lat_used'] * 100) < 95:
+                lat_warning = ('{} Latency accuracy issue?: {:>3.0f}%'
+                    '{}').format(bcolors.WARNING,
+                            iteration_data['lat_used']*100, bcolors.ENDC)
             else:
                 lat_warning = ''
             iteration_prefix = {'speed' : '',
@@ -74,22 +91,18 @@ class ImpairTest(RapidTest):
                     'drop_rate' : ''}
             RapidLog.info(self.report_result(attempts, size, iteration_data,
                 iteration_prefix))
-            result_details = {'test': self.test['test'],
-                    'environment_file': self.test['environment_file'],
-                    'Flows': flow_number,
-                    'Size': size,
-                    'RequestedSpeed': RapidTest.get_pps(speed,size),
-                    'CoreGenerated': iteration_data['pps_req_tx'],
-                    'SentByNIC': iteration_data['pps_tx'],
-                    'FwdBySUT': iteration_data['pps_sut_tx'],
-                    'RevByCore': iteration_data['pps_rx'],
-                    'AvgLatency': iteration_data['lat_avg'],
-                    'PCTLatency': iteration_data['lat_perc'],
-                    'MaxLatency': iteration_data['lat_max'],
-                    'PacketsLost': iteration_data['abs_dropped'],
-                    'DropRate': iteration_data['drop_rate'],
-                    'bucket_size': iteration_data['bucket_size'],
-                    'buckets': iteration_data['buckets']}
-            result_details = self.post_data('rapid_impairtest', result_details)
+            iteration_data['test'] = self.test['testname']
+            iteration_data['environment_file'] = self.test['environment_file']
+            iteration_data['Flows'] = flow_number
+            iteration_data['Size'] = size
+            iteration_data['RequestedSpeed'] = RapidTest.get_pps(
+                    iteration_data['speed'] ,size)
+            result_details = self.post_data(iteration_data)
+            RapidLog.debug(result_details)
+        RapidLog.info('+' + '-' * 8 + '+' + '-' * 18 + '+' + '-' * 13 +
+            '+' + '-' * 13 + '+' + '-' * 13 + '+' + '-' * 24 + '+' +
+            '-' * 10 + '+' + '-' * 10 + '+' + '-' * 10 + '+' + '-' * 11
+            + '+' + '-' * 11 + '+' + '-' * 11 + '+'  + '-' * 11 +  '+'
+            + '-' * 7 + '+' + '-' * 4 + '+')
         self.gen_machine.stop_latency_cores()
         return (True, result_details)
index f990a23..b0516ee 100644 (file)
@@ -102,5 +102,5 @@ class IrqTest(RapidTest):
                 core_details['Core {}'.format(row_names[j])] = row
             machine_details[machine.name] = core_details
         result_details['machine_data'] = machine_details
-        result_details = self.post_data('rapid_irqtest', result_details)
+        result_details = self.post_data(result_details)
         return (500000 - max_loop_duration, result_details)
index 8ff586e..d7d8fab 100644 (file)
@@ -70,16 +70,16 @@ class RapidConfigParser(object):
             section = 'test%d'%test_index
             options = testconfig.options(section)
             for option in options:
-                if option in ['imix','imixs','flows']:
+                if option in ['imix','imixs','flows', 'warmupimix']:
                     test[option] = ast.literal_eval(testconfig.get(section,
                         option))
                 elif option in ['maxframespersecondallingress','stepsize',
-                        'flowsize']:
+                        'flowsize','warmupflowsize','warmuptime', 'steps']:
                     test[option] = int(testconfig.get(section, option))
                 elif option in ['startspeed', 'step', 'drop_rate_threshold',
                         'lat_avg_threshold','lat_perc_threshold',
                         'lat_max_threshold','accuracy','maxr','maxz',
-                        'ramp_step']:
+                        'ramp_step','warmupspeed']:
                     test[option] = float(testconfig.get(section, option))
                 else:
                     test[option] = testconfig.get(section, option)
@@ -99,7 +99,9 @@ class RapidConfigParser(object):
             raise Exception("Not enough VMs for this test: %d needed and only %d available" % (required_number_of_test_machines,total_number_of_machines))
         map_info = test_params['machine_map_file'].strip('[]').split(',')
         map_info_length = len(map_info)
-        if map_info_length > 1:
+        # If map_info is a list where the first entry is numeric, we assume we
+        # are dealing with a list of machines and NOT the machine.map file
+        if map_info[0].isnumeric():
             if map_info_length < test_params[
                     'required_number_of_test_machines']:
                 RapidLog.exception('Not enough machine indices in --map \
index 135770f..8157ddf 100644 (file)
@@ -75,7 +75,7 @@ class PortStatsTest(RapidTest):
                         'Sent': tx,
                         'NoMbufs': no_mbufs,
                         'iErrMiss': errors}
-                result_details = self.post_data('rapid_corestatstest', result_details)
+                result_details = self.post_data(result_details)
                 if machines_to_go == 0:
                     duration = duration - 1
                     machines_to_go = len (self.machines)
index b431e5b..8f3a9d8 100644 (file)
@@ -105,24 +105,25 @@ class RapidTest(object):
                 if v in variables.keys():
                     data_format[k] = variables[v]
 
-    def post_data(self, test, variables):
+    def post_data(self, variables):
+        test_type = type(self).__name__
         var = copy.deepcopy(self.data_format)
         self.parse_data_format_dict(var, variables)
-        if var.keys() >= {'URL', test, 'Format'}:
+        if var.keys() >= {'URL', test_type, 'Format'}:
             URL=''
             for value in var['URL'].values():
                 URL = URL + value
             HEADERS = {'X-Requested-With': 'Python requests', 'Content-type': 'application/rapid'}
             if var['Format'] == 'PushGateway':
-                data = "\n".join("{} {}".format(k, v) for k, v in var[test].items()) + "\n"
+                data = "\n".join("{} {}".format(k, v) for k, v in var[test_type].items()) + "\n"
                 response = requests.post(url=URL, data=data,headers=HEADERS)
             elif var['Format'] == 'Xtesting':
-                data = var[test]
+                data = var[test_type]
                 response = requests.post(url=URL, json=data)
             if (response.status_code >= 300):
                 RapidLog.info('Cannot send metrics to {}'.format(URL))
                 RapidLog.info(data)
-        return (var[test])
+        return (var[test_type])
 
     @staticmethod
     def report_result(flow_number, size, data, prefix):
@@ -190,23 +191,21 @@ class RapidTest(object):
             t1_dp_tx = t1_tx - t1_non_dp_tx
             self.gen_machine.set_generator_speed(0)
             self.gen_machine.start_gen_cores()
-            if self.background_machines:
-                self.set_background_speed(self.background_machines, 0)
-                self.start_background_traffic(self.background_machines)
+            self.set_background_speed(self.background_machines, 0)
+            self.start_background_traffic(self.background_machines)
             if 'ramp_step' in self.test.keys():
                 ramp_speed = self.test['ramp_step']
             else:
                 ramp_speed = speed
             while ramp_speed < speed:
                 self.gen_machine.set_generator_speed(ramp_speed)
-                if self.background_machines:
-                    self.set_background_speed(self.background_machines, ramp_speed)
+                self.set_background_speed(self.background_machines, ramp_speed)
                 time.sleep(2)
                 ramp_speed = ramp_speed + self.test['ramp_step']
             self.gen_machine.set_generator_speed(speed)
-            if self.background_machines:
-                self.set_background_speed(self.background_machines, speed)
-            iteration_data['speed'] = time_loop_data['speed'] = speed
+            self.set_background_speed(self.background_machines, speed)
+            iteration_data['speed'] = speed
+            time_loop_data['speed'] = speed
             time.sleep(2) ## Needs to be 2 seconds since this 1 sec is the time that PROX uses to refresh the stats. Note that this can be changed in PROX!! Don't do it.
             start_bg_gen_stats = []
             for bg_gen_machine in self.background_machines:
@@ -346,7 +345,7 @@ class RapidTest(object):
                         time_loop_data['Flows'] = flow_number
                         time_loop_data['Size'] = size
                         time_loop_data['RequestedSpeed'] = RapidTest.get_pps(speed, size)
-                        _ = self.post_data('rapid_flowsizetest', time_loop_data)
+                        _ = self.post_data(time_loop_data)
             end_bg_gen_stats = []
             for bg_gen_machine in self.background_machines:
                 bg_rx, bg_non_dp_rx, bg_tx, bg_non_dp_tx, _, _, bg_tsc, bg_hz = bg_gen_machine.core_stats()
@@ -356,8 +355,7 @@ class RapidTest(object):
                         "bg_hz"    : bg_hz
                         }
                 end_bg_gen_stats.append(dict(bg_gen_stat))
-            if self.background_machines:
-                self.stop_background_traffic(self.background_machines)
+            self.stop_background_traffic(self.background_machines)
             i = 0
             bg_rates =[]
             while i < len(end_bg_gen_stats):
index 32579f8..bedf51a 100644 (file)
@@ -35,10 +35,10 @@ class WarmupTest(RapidTest):
     # 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
-        imix = self.test['imix']
-        FLOWSIZE = int(self.test['flowsize'])
-        WARMUPSPEED = int(self.test['warmupspeed'])
-        WARMUPTIME = int(self.test['warmuptime'])
+        imix = self.test['warmupimix']
+        FLOWSIZE = self.test['warmupflowsize']
+        WARMUPSPEED = self.test['warmupspeed']
+        WARMUPTIME = self.test['warmuptime']
         self.gen_machine.set_generator_speed(WARMUPSPEED)
         self.gen_machine.set_udp_packet_size(imix)
     #    gen_machine['socket'].set_value(gencores,0,56,1,1)
index 157bd8c..33fb8df 100755 (executable)
@@ -105,11 +105,11 @@ class RapidTestManager(object):
                         test_params['TestName'], 
                         test_params['environment_file'], gen_machine,
                         sut_machine, background_machines)
-            elif test_param['test'] in ['corestats']:
+            elif test_param['test'] in ['corestatstest']:
                 test = CoreStatsTest(test_param, test_params['runtime'],
                         test_params['TestName'], 
                         test_params['environment_file'], self.machines)
-            elif test_param['test'] in ['portstats']:
+            elif test_param['test'] in ['portstatstest']:
                 test = PortStatsTest(test_param, test_params['runtime'],
                         test_params['TestName'], 
                         test_params['environment_file'], self.machines)
@@ -118,7 +118,7 @@ class RapidTestManager(object):
                         test_params['runtime'],
                         test_params['TestName'], 
                         test_params['environment_file'], gen_machine,
-                        sut_machine)
+                        sut_machine, background_machines)
             elif test_param['test'] in ['irqtest']:
                 test = IrqTest(test_param, test_params['runtime'],
                         test_params['TestName'], 
index 19d62fa..d51d304 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = Rapid_ETSINFV_TST009
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 lat_percentile = 99
 
@@ -36,14 +36,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=TST009test
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=TST009test
 imixs=[[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, 65536, 131072, 262144, 524288, 1048576
index 66767a0..2b0d386 100644 (file)
@@ -37,6 +37,10 @@ cores = [1]
 
 [test1]
 test=TST009test
+warmupflowsize=512
+warmupimix=[64]
+warmupspeed=1
+warmuptime=2
 imixs=[[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, 65536, 131072, 262144, 524288, 1048576
index 31d19bf..22f194b 100644 (file)
@@ -37,6 +37,10 @@ cores = [1]
 
 [test1]
 test=TST009test
+warmupflowsize=512
+warmupimix=[64]
+warmupspeed=1
+warmuptime=2
 imixs=[[64,256,64,1024,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, 65536, 131072, 262144, 524288, 1048576
index a19289f..4b8a5e9 100644 (file)
 
 [TestParameters]
 name = BasicSwapTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 lat_percentile = 99
+ipv6 = True
 
 [TestM1]
 name = Generator
@@ -38,14 +39,11 @@ cores = [1]
 #prox_launch_exit = true
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=TST009test
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=TST009test
 # DO NOT USE IMIX FOR IPV6 TESTING. THE LIST OF IMIXS CAN ONLY CONTAIN LISTS
 # WITH ONE ELEMENT!!!
 # PACKET SIZE NEEDS TO BE AT LEAST 84 (66 + 18) FOR IPV6
index 9aab3fd..803c65e 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = BareTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 
 [TestM1]
@@ -34,14 +34,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=10
 warmuptime=2
-
-[test2]
-test=flowsizetest
 imixs=[[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, 65536, 131072, 262144, 524288, 1048576
index 76c1fa0..752e783 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = BasicSwapTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 lat_percentile = 99
 
@@ -38,14 +38,11 @@ cores = [1]
 #prox_launch_exit = true
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=flowsizetest
 # Each element in the imix list will result in a separate test. Each element
 # is on its turn a list of packet sizes which will be used during one test
 # execution. If you only want to test 1 size, define a list with only one
index 9136d03..c345370 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = CGNATTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 3
 
 [TestM1]
@@ -45,14 +45,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=flowsizetest
 imixs=[[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, 65536, 131072, 262144, 524288, 1048576
index 865394f..08616f4 100644 (file)
@@ -43,17 +43,18 @@ cores = [1]
 
 [test1]
 test=warmuptest
-flowsize=1024
-imix=[64]
+warmupflowsize=1024
+warmupimix=[64]
 warmupspeed=10
 warmuptime=2
 
 [test2]
 test=impairtest
+steps=5
 imix=[64]
 flowsize=64
 drop_rate_threshold = 0.1
 lat_avg_threshold = 500
 lat_max_threshold = 1000
 accuracy = 0.1
-startspeed = 10
+startspeed = 5
index 7cee0a3..b69bb49 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = IncrementTillFailTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 lat_percentile = 99
 
@@ -38,14 +38,11 @@ cores = [1]
 #prox_launch_exit = true
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=increment_till_fail
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=increment_till_fail
 # Each element in the imix list will result in a separate test. Each element
 # is on its turn a list of packet sizes which will be used during one test
 # execution. If you only want to test 1 size, define a list with only one
index e973bc9..9f9e40a 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = BasicSwapTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 lat_percentile = 99
 ipv6 = True
@@ -39,14 +39,11 @@ cores = [1]
 #prox_launch_exit = true
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[84]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[84]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=flowsizetest
 # DO NOT USE IMIX FOR IPV6 TESTING. THE LIST OF IMIXS CAN ONLY CONTAIN LISTS
 # WITH ONE ELEMENT!!!
 # PACKET SIZE NEEDS TO BE AT LEAST 84 (66 + 18) FOR IPV6
index 30b807f..0e7b256 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = L2BasicSwapTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 
 [TestM1]
@@ -34,14 +34,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=flowsizetest
 # Each element in the imix list will result in a separate test. Each element
 # is on its turn a list of packet sizes which will be used during one test
 # execution. If you only want to test 1 size, define a list with only one
index 04aa473..3ffd9d2 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = L3FrameRateTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 2
 
 [TestM1]
@@ -34,14 +34,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=64
-imix=[64]
+test=fixed_rate
+warmupflowsize=64
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=fixed_rate
 imixs=[[64],[128]]
 # the number of flows in the list need to be powers of 2, max 2^20
 # If not a power of 2, we will use the lowest power of 2 that is larger than
index 509727a..f6e8025 100644 (file)
@@ -16,7 +16,7 @@
 
 [TestParameters]
 name = GWTesting
-number_of_tests = 2
+number_of_tests = 1
 total_number_of_test_machines = 3
 
 [TestM1]
@@ -42,14 +42,11 @@ mcore = [0]
 cores = [1]
 
 [test1]
-test=warmuptest
-flowsize=512
-imix=[64]
+test=flowsizetest
+warmupflowsize=512
+warmupimix=[64]
 warmupspeed=1
 warmuptime=2
-
-[test2]
-test=flowsizetest
 imixs=[[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, 65536, 131072, 262144, 524288, 1048576