Trex_2544_verification: Add verification functionality to Trex code 25/49225/7
authorChristian Trautman <ctrautma@redhat.com>
Thu, 14 Dec 2017 19:44:35 +0000 (14:44 -0500)
committerChristian Trautman <ctrautma@redhat.com>
Tue, 19 Dec 2017 18:45:19 +0000 (13:45 -0500)
- Adds T-Rex verification step as implemented by other trafficgens
- Adds check in rfc2544 loop for if no packets are received to fail test
  immediately
- Refactors the trial code to support the verification option
- Adds trial_run function
- Removed unused line speed configuration setting

JIRA: VSPERF-553

Change-Id: Ie324fe8fb6bf79fe0dc337b91af2bf83e901a8ab
Signed-off-by: Christian Trautman <ctrautma@redhat.com>
conf/03_traffic.conf
conf/10_custom.conf
docs/testing/user/configguide/trafficgen.rst
tools/pkt_gen/trex/trex.py

index 3833a04..3c7bd2f 100644 (file)
@@ -451,10 +451,7 @@ TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD = 0.05
 # Parameter below defines frequency of packets used for latency measurement in PPS.
 # Value 0 will disable latency specific streams.
 TRAFFICGEN_TREX_LATENCY_PPS = 1000
-# Example 10 Gbps: TRAFFICGEN_TREXINE_SPEED_GBPS = '10'
-# Today only 10 Gbps is supported
-TRAFFICGEN_TREX_LINE_SPEED_GBPS = '10'
-# Enable of learning packets before sending test traffic
+# Enablement of learning packets before sending test traffic
 TRAFFICGEN_TREX_LEARNING_MODE = True
 TRAFFICGEN_TREX_LEARNING_DURATION = 5
 # FOR SR-IOV or multistream layer 2 tests to work with T-Rex enable Promiscuous mode
@@ -467,5 +464,9 @@ PATHS['trafficgen'] = {
     }
   }
 }
+# TRex validation option for RFC2544
+TRAFFICGEN_TREX_VERIFICATION_MODE = False
+TRAFFICGEN_TREX_VERIFICATION_DURATION = 60
+TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10
 # TREX Configuration and Connection Info-- END
 ##############################################
index 1f8448b..917d16b 100644 (file)
@@ -133,14 +133,15 @@ TRAFFICGEN_TREX_PORT2 = ''
 # Parameter below defines frequency of packets used for latency measurement in PPS.
 # Value 0 will disable latency specific streams.
 TRAFFICGEN_TREX_LATENCY_PPS = 1000
-# Example 10 Gbps: TRAFFICGEN_TREXINE_SPEED_GBPS = '10'
-# Today only 10 Gbps is supported
-TRAFFICGEN_TREX_LINE_SPEED_GBPS = '10'
-# Enable of learning packets before sending test traffic
+# Enablement of learning packets before sending test traffic
 TRAFFICGEN_TREX_LEARNING_MODE = True
 TRAFFICGEN_TREX_LEARNING_DURATION = 5
 # FOR SR-IOV or multistream layer 2 tests to work with T-Rex enable Promiscuous mode
 TRAFFICGEN_TREX_PROMISCUOUS = False
+# TRex validation option for RFC2544
+TRAFFICGEN_TREX_VERIFICATION_MODE = False
+TRAFFICGEN_TREX_VERIFICATION_DURATION = 60
+TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10
 
 # TREX Configuration and Connection Info-- END
 ####################################################
@@ -164,3 +165,4 @@ PACKAGE_LIST = "src/package-list.mk"
 #        'openvswitch']
 #PATHS['vswitch']['OvsVanilla']['type'] = 'bin'
 
+
index 535f799..91c4084 100644 (file)
@@ -849,3 +849,23 @@ modified. Enable Promiscuous mode when doing multistream at layer 2 testing with
 .. code-block:: console
 
     TRAFFICGEN_TREX_PROMISCUOUS=True
+
+RFC2544 Validation
+~~~~~~~~~~~~~~~~~~
+
+T-Rex can perform a verification run for a longer duration once the binary search of the
+RFC2544 trials have completed. This duration should be at least 60 seconds. This is similar
+to other traffic generator functionality where a more sustained time can be attempted to
+verify longer runs from the result of the search. This can be configured with the following
+params
+
+.. code-block:: console
+
+    TRAFFICGEN_TREX_VERIFICATION_MODE = False
+    TRAFFICGEN_TREX_VERIFICATION_DURATION = 60
+    TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10
+
+The duration and maximum number of attempted verification trials can be set to change the
+behavior of this step. If the verification step fails, it will resume the binary search
+with new values where the maximum output will be the last attempted frame rate minus the
+current set thresh hold.
index c166310..82118f6 100644 (file)
@@ -82,6 +82,7 @@ class Trex(ITrafficGenerator):
             settings.getValue('TRAFFICGEN_TREX_BASE_DIR'))
         self._trex_user = settings.getValue('TRAFFICGEN_TREX_USER')
         self._stlclient = None
+        self._verification_params = None
 
     def connect(self):
         '''Connect to Trex traffic generator
@@ -339,6 +340,56 @@ class Trex(ITrafficGenerator):
         self._logger.info("T-Rex finished learning packets")
         time.sleep(3)  # allow packets to complete before starting test traffic
 
+    def run_trials(self, traffic, boundaries, duration, lossrate):
+        """
+        Run rfc2544 trial loop
+        :param traffic: traffic profile dictionary
+        :param boundaries: A dictionary of three keys left, right, center to dictate
+                          the highest, lowest, and starting point of the binary search.
+                          Values are percentages of line rates for each key.
+        :param duration: length in seconds for trials
+        :param lossrate: loweset loss rate percentage calculated from
+                         comparision between received and sent packets
+        :return: passing stats as dictionary
+        """
+        threshold = settings.getValue('TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD')
+        stats_ok = _EMPTY_STATS
+        new_params = copy.deepcopy(traffic)
+        iteration = 1
+        left = boundaries['left']
+        right = boundaries['right']
+        center = boundaries['center']
+        self._logger.info('Starting RFC2544 trials')
+        while (right - left) > threshold:
+            stats = self.generate_traffic(new_params, duration)
+            test_lossrate = ((stats["total"]["opackets"] - stats[
+                "total"]["ipackets"]) * 100) / stats["total"]["opackets"]
+            if stats["total"]["ipackets"] == 0:
+                self._logger.error('No packets recieved. Test failed')
+                return _EMPTY_STATS
+            if settings.getValue('TRAFFICGEN_TREX_VERIFICATION_MODE'):
+                if test_lossrate <= lossrate:
+                    # save the last passing trial for verification
+                    self._verification_params = copy.deepcopy(new_params)
+            self._logger.debug("Iteration: %s, frame rate: %s, throughput_rx_fps: %s, frame_loss_percent: %s",
+                               iteration, "{:.3f}".format(new_params['frame_rate']), stats['total']['rx_pps'],
+                               "{:.3f}".format(test_lossrate))
+            if test_lossrate == 0.0 and new_params['frame_rate'] == traffic['frame_rate']:
+                return copy.deepcopy(stats)
+            elif test_lossrate > lossrate:
+                right = center
+                center = (left + right) / 2
+                new_params = copy.deepcopy(traffic)
+                new_params['frame_rate'] = center
+            else:
+                stats_ok = copy.deepcopy(stats)
+                left = center
+                center = (left + right) / 2
+                new_params = copy.deepcopy(traffic)
+                new_params['frame_rate'] = center
+            iteration += 1
+        return stats_ok
+
     def send_cont_traffic(self, traffic=None, duration=30):
         """See ITrafficGenerator for description
         """
@@ -372,47 +423,51 @@ class Trex(ITrafficGenerator):
         """
         self._logger.info("In Trex send_rfc2544_throughput method")
         self._params.clear()
-        threshold = settings.getValue('TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD')
-        test_lossrate = 0
-        left = 0
-        iteration = 1
-        stats_ok = _EMPTY_STATS
         self._params['traffic'] = self.traffic_defaults.copy()
         if traffic:
             self._params['traffic'] = merge_spec(
                 self._params['traffic'], traffic)
-        new_params = copy.deepcopy(traffic)
         if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'):
             self.learning_packets(traffic)
-        stats = self.generate_traffic(traffic, duration)
-        right = traffic['frame_rate']
-        center = traffic['frame_rate']
+        self._verification_params = copy.deepcopy(traffic)
+
+        binary_bounds = {'right' : traffic['frame_rate'],
+                         'left'  : 0,
+                         'center': traffic['frame_rate'],}
 
-        # Loops until the preconfigured difference between frame rate
+        # Loops until the preconfigured differencde between frame rate
         # of successful and unsuccessful iterations is reached
-        while (right - left) > threshold:
-            test_lossrate = ((stats["total"]["opackets"] - stats["total"]
-                              ["ipackets"]) * 100) / stats["total"]["opackets"]
-            self._logger.debug("Iteration: %s, frame rate: %s, throughput_rx_fps: %s, frame_loss_percent: %s",
-                               iteration, "{:.3f}".format(new_params['frame_rate']), stats['total']['rx_pps'],
-                               "{:.3f}".format(test_lossrate))
-            if test_lossrate == 0.0 and new_params['frame_rate'] == traffic['frame_rate']:
-                stats_ok = copy.deepcopy(stats)
-                break
-            elif test_lossrate > lossrate:
-                right = center
-                center = (left+right) / 2
-                new_params = copy.deepcopy(traffic)
-                new_params['frame_rate'] = center
-                stats = self.generate_traffic(new_params, duration)
+        stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration,
+                                   lossrate=lossrate, traffic=traffic)
+        if settings.getValue('TRAFFICGEN_TREX_VERIFICATION_MODE'):
+            verification_iterations = 1
+            while verification_iterations <= settings.getValue('TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS'):
+                self._logger.info('Starting Trex Verification trial for %s seconds at frame rate %s',
+                                  settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION'),
+                                  self._verification_params['frame_rate'])
+                stats = self.generate_traffic(self._verification_params,
+                                              settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION'))
+                verification_lossrate = ((stats["total"]["opackets"] - stats[
+                    "total"]["ipackets"]) * 100) / stats["total"]["opackets"]
+                if verification_lossrate <= lossrate:
+                    self._logger.info('Trex Verification passed, %s packets were lost',
+                                      stats["total"]["opackets"] - stats["total"]["ipackets"])
+                    stats_ok = copy.deepcopy(stats)
+                    break
+                else:
+                    self._logger.info('Trex Verification failed, %s packets were lost',
+                                      stats["total"]["opackets"] - stats["total"]["ipackets"])
+                    new_right = self._verification_params['frame_rate'] - settings.getValue(
+                        'TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD')
+                    self._verification_params['frame_rate'] = new_right
+                    binary_bounds = {'right': new_right,
+                                     'left': 0,
+                                     'center': new_right,}
+                    stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration,
+                                               lossrate=lossrate, traffic=self._verification_params)
+                verification_iterations += 1
             else:
-                stats_ok = copy.deepcopy(stats)
-                left = center
-                center = (left+right) / 2
-                new_params = copy.deepcopy(traffic)
-                new_params['frame_rate'] = center
-                stats = self.generate_traffic(new_params, duration)
-            iteration += 1
+                self._logger.error('Could not pass Trex Verification. Test failed')
         return self.calculate_results(stats_ok)
 
     def start_rfc2544_throughput(self, traffic=None, tests=1, duration=60,