From ad0f9d7c68be48e33348fc46ec187ca83b30340b Mon Sep 17 00:00:00 2001 From: Christian Trautman Date: Thu, 14 Dec 2017 14:44:35 -0500 Subject: Trex_2544_verification: Add verification functionality to Trex code - 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 --- conf/03_traffic.conf | 9 +- conf/10_custom.conf | 10 ++- docs/testing/user/configguide/trafficgen.rst | 20 +++++ tools/pkt_gen/trex/trex.py | 119 ++++++++++++++++++++------- 4 files changed, 118 insertions(+), 40 deletions(-) diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf index 3833a040..3c7bd2f5 100644 --- a/conf/03_traffic.conf +++ b/conf/03_traffic.conf @@ -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 ############################################## diff --git a/conf/10_custom.conf b/conf/10_custom.conf index 1f8448b4..917d16b4 100644 --- a/conf/10_custom.conf +++ b/conf/10_custom.conf @@ -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' + diff --git a/docs/testing/user/configguide/trafficgen.rst b/docs/testing/user/configguide/trafficgen.rst index 535f7995..91c4084e 100644 --- a/docs/testing/user/configguide/trafficgen.rst +++ b/docs/testing/user/configguide/trafficgen.rst @@ -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. diff --git a/tools/pkt_gen/trex/trex.py b/tools/pkt_gen/trex/trex.py index c166310d..82118f6f 100644 --- a/tools/pkt_gen/trex/trex.py +++ b/tools/pkt_gen/trex/trex.py @@ -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, -- cgit 1.2.3-korg