aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pkt_gen/moongen/moongen.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pkt_gen/moongen/moongen.py')
-rw-r--r--tools/pkt_gen/moongen/moongen.py167
1 files changed, 96 insertions, 71 deletions
diff --git a/tools/pkt_gen/moongen/moongen.py b/tools/pkt_gen/moongen/moongen.py
index d6c09e5d..790286d8 100644
--- a/tools/pkt_gen/moongen/moongen.py
+++ b/tools/pkt_gen/moongen/moongen.py
@@ -20,10 +20,11 @@ Moongen Traffic Generator Model
"""
# python imports
-import logging
from collections import OrderedDict
-import subprocess
+import logging
+import math
import re
+import subprocess
# VSPerf imports
from conf import settings
@@ -49,6 +50,13 @@ class Moongen(ITrafficGenerator):
self._moongen_user = settings.getValue('TRAFFICGEN_MOONGEN_USER')
self._moongen_ports = settings.getValue('TRAFFICGEN_MOONGEN_PORTS')
+ if settings.getValue('TRAFFICGEN_MOONGEN_LINE_SPEED_GBPS') == '10':
+ self._moongen_line_speed = math.pow(10, 10)
+ else:
+ raise RuntimeError(
+ 'MOONGEN: Invalid line speed in configuration ' + \
+ 'file (today 10Gbps supported)')
+
@property
def traffic_defaults(self):
"""Default traffic values.
@@ -58,12 +66,12 @@ class Moongen(ITrafficGenerator):
will likely break traffic generator implementations or tests
respectively.
"""
- self._logger.info("In moongen traffic_defaults method")
+ self._logger.info("In Moongen traffic_defaults method")
return self._traffic_defaults
def create_moongen_cfg_file(self, traffic, duration=60,
acceptable_loss_pct=1, one_shot=0):
- """Create the MoonGen configuration file from VSPERF's traffic profile
+ """Create the Moongen configuration file from VSPERF's traffic profile
:param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
:param duration: The length of time to generate packet throughput
:param acceptable_loss: Maximum packet loss acceptable
@@ -138,8 +146,9 @@ class Moongen(ITrafficGenerator):
out_file.write("dstIp = \"" + \
str(traffic['l3']['dstip']) + "\",\n")
- out_file.write("vlanId = " + \
- str(traffic['vlan']['id']) + ",\n")
+ if traffic['vlan']['enabled']:
+ out_file.write("vlanId = " + \
+ str(traffic['vlan']['id']) + ",\n")
out_file.write("searchRunTime = " + \
str(duration) + ",\n")
@@ -156,10 +165,17 @@ class Moongen(ITrafficGenerator):
if one_shot:
out_file.write("oneShot = true,\n")
- # Assume 10G line rates at the moment. Need to convert VSPERF
- # frame_rate (percentage of line rate) to Mpps for MoonGen
+ # Need to convert VSPERF frame_rate (percentage of line rate)
+ # to Mpps for Moongen
+ start_rate = str(
+ (traffic['frame_rate'] / 100) * (self._moongen_line_speed / \
+ (8 * (traffic['l2']['framesize'] + 20)) / math.pow(10, 6)))
+
+ logging.debug("startRate = " + start_rate)
+
+ out_file.write("startRate = " + \
+ start_rate + "\n")
- out_file.write("startRate = " + str((traffic['frame_rate'] / 100) * 14.88) + "\n")
out_file.write("}" + "\n")
out_file.close()
@@ -181,17 +197,17 @@ class Moongen(ITrafficGenerator):
raise RuntimeError('MOONGEN: Error copying configuration file')
def connect(self):
- """Connect to MoonGen traffic generator
+ """Connect to Moongen traffic generator
- Verify that MoonGen is on the system indicated by
+ Verify that Moongen is on the system indicated by
the configuration file
"""
- self._logger.info("MOONGEN: In MoonGen connect method...")
+ self._logger.info("MOONGEN: In Moongen connect method...")
if self._moongen_host_ip_addr:
cmd_ping = "ping -c1 " + self._moongen_host_ip_addr
else:
- raise RuntimeError('MOONGEN: MoonGen host not defined')
+ raise RuntimeError('MOONGEN: Moongen host not defined')
ping = subprocess.Popen(cmd_ping, shell=True, stderr=subprocess.PIPE)
output, error = ping.communicate()
@@ -199,7 +215,7 @@ class Moongen(ITrafficGenerator):
if ping.returncode:
self._logger.error(error)
self._logger.error(output)
- raise RuntimeError('MOONGEN: Cannot ping MoonGen host at ' + \
+ raise RuntimeError('MOONGEN: Cannot ping Moongen host at ' + \
self._moongen_host_ip_addr)
connect_moongen = "ssh " + self._moongen_user + \
@@ -218,10 +234,10 @@ class Moongen(ITrafficGenerator):
self._logger.error(error)
self._logger.error(output)
raise RuntimeError(
- 'MOONGEN: Cannot locate MoonGen program at %s within %s' \
+ 'MOONGEN: Cannot locate Moongen program at %s within %s' \
% (self._moongen_host_ip_addr, self._moongen_base_dir))
- self._logger.info("MOONGEN: MoonGen host successfully found...")
+ self._logger.info("MOONGEN: Moongen host successfully found...")
def disconnect(self):
"""Disconnect from the traffic generator.
@@ -252,7 +268,7 @@ class Moongen(ITrafficGenerator):
- List of List of Rx Bytes,
- Payload Errors and Sequence Errors.
"""
- self._logger.info("In moongen send_burst_traffic method")
+ self._logger.info("In Moongen send_burst_traffic method")
return NotImplementedError('Moongen Burst traffic not implemented')
def send_cont_traffic(self, traffic=None, duration=20):
@@ -274,7 +290,7 @@ class Moongen(ITrafficGenerator):
- Max Latency (ns),
- Avg Latency (ns)
"""
- self._logger.info("In moongen send_cont_traffic method")
+ self._logger.info("In Moongen send_cont_traffic method")
self._params.clear()
self._params['traffic'] = self.traffic_defaults.copy()
@@ -316,31 +332,31 @@ class Moongen(ITrafficGenerator):
results = OrderedDict()
results[ResultsConstants.THROUGHPUT_RX_FPS] = (
- '{:,.6f}'.format(total_throughput_rx_fps))
+ '{:.6f}'.format(total_throughput_rx_fps))
results[ResultsConstants.THROUGHPUT_RX_MBPS] = (
- '{:,.3f}'.format(total_throughput_rx_mbps))
+ '{:.3f}'.format(total_throughput_rx_mbps))
results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
- '{:,.3f}'.format(total_throughput_rx_pct))
+ '{:.3f}'.format(total_throughput_rx_pct))
results[ResultsConstants.TX_RATE_FPS] = (
- '{:,.6f}'.format(total_throughput_tx_fps))
+ '{:.6f}'.format(total_throughput_tx_fps))
results[ResultsConstants.TX_RATE_MBPS] = (
- '{:,.3f}'.format(total_throughput_tx_mbps))
+ '{:.3f}'.format(total_throughput_tx_mbps))
results[ResultsConstants.TX_RATE_PERCENT] = (
- '{:,.3f}'.format(total_throughput_tx_pct))
+ '{:.3f}'.format(total_throughput_tx_pct))
results[ResultsConstants.MIN_LATENCY_NS] = (
- '{:,.3f}'.format(total_min_latency_ns))
+ '{:.3f}'.format(total_min_latency_ns))
results[ResultsConstants.MAX_LATENCY_NS] = (
- '{:,.3f}'.format(total_max_latency_ns))
+ '{:.3f}'.format(total_max_latency_ns))
results[ResultsConstants.AVG_LATENCY_NS] = (
- '{:,.3f}'.format(total_avg_latency_ns))
+ '{:.3f}'.format(total_avg_latency_ns))
return results
@@ -352,18 +368,18 @@ class Moongen(ITrafficGenerator):
:param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
:param duration: Time to wait to receive packets (secs)
"""
- self._logger.info("In moongen start_cont_traffic method")
- return NotImplementedError('Moongen continuous traffic not implemented')
+ self._logger.info("In Moongen start_cont_traffic method")
+ return NotImplementedError('moongen continuous traffic not implemented')
def stop_cont_traffic(self):
# Stop continuous transmission and return results.
- self._logger.info("In moongen stop_cont_traffic method")
+ self._logger.info("In Moongen stop_cont_traffic method")
def run_moongen_and_collect_results(self, test_run=1):
- """Execute MoonGen and transform results into VSPERF format
+ """Execute Moongen and transform results into VSPERF format
:param test_run: The number of tests to run
"""
- # Start MoonGen and create logfile of the run
+ # Start Moongen and create logfile of the run
connect_moongen = "ssh " + self._moongen_user + "@" + \
self._moongen_host_ip_addr
@@ -381,7 +397,7 @@ class Moongen(ITrafficGenerator):
logging.debug(error)
logging.debug(output)
raise RuntimeError(
- 'MOONGEN: Error starting MoonGen program at %s within %s' \
+ 'MOONGEN: Error starting Moongen program at %s within %s' \
% (self._moongen_host_ip_addr, self._moongen_base_dir))
cmd_moongen = "mkdir -p /tmp/moongen/" + str(test_run)
@@ -396,7 +412,7 @@ class Moongen(ITrafficGenerator):
logging.debug(error)
logging.debug(output)
raise RuntimeError(
- 'MOONGEN: Error obtaining MoonGen log from %s within %s' \
+ 'MOONGEN: Error obtaining Moongen log from %s within %s' \
% (self._moongen_host_ip_addr, self._moongen_base_dir))
cmd_moongen = " scp " + self._moongen_user + "@" + \
@@ -414,7 +430,7 @@ class Moongen(ITrafficGenerator):
logging.debug(error)
logging.debug(output)
raise RuntimeError(
- 'MOONGEN: Error obtaining MoonGen log from %s within %s' \
+ 'MOONGEN: Error obtaining Moongen log from %s within %s' \
% (self._moongen_host_ip_addr, self._moongen_base_dir))
log_file = "/tmp/moongen/" + str(test_run) + "/moongen-run.log"
@@ -443,7 +459,7 @@ class Moongen(ITrafficGenerator):
if not results_match:
logging.error('There was a problem parsing ' +\
- 'MoonGen REPORT section of MoonGen log file')
+ 'Moongen REPORT section of Moongen log file')
moongen_results = OrderedDict()
moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = 0
@@ -468,14 +484,25 @@ class Moongen(ITrafficGenerator):
if parameters_match:
frame_size = int(parameters_match.group(1))
else:
- logging.error('There was a problem parsing MoonGen ' +\
- 'PARAMETERS section of MoonGen log file')
+ logging.error('There was a problem parsing Moongen ' +\
+ 'PARAMETERS section of Moongen log file')
frame_size = 0
- if results_match and parameters_match:
+ # Each packet stream in the MoonGen report is prefaced with the
+ # words '[REPORT]Device'. Count the instances of this string to
+ # get the total aggregrate throughput. For example:
+ #
+ # - If num_traffic_streams = 1, there is a single
+ # unidirectional stream
+ #
+ # - If num_traffic_streams = 2, there is a bidirectional
+ # traffic stream
+ num_traffic_streams = mytext.count('[REPORT]Device')
+
+ if results_match and parameters_match and num_traffic_streams:
# Assume for now 10G link speed
- max_theoretical_mfps = (
- (10000000000 / 8) / (frame_size + 20))
+ max_theoretical_fps = (
+ num_traffic_streams * (self._moongen_line_speed / 8) / (frame_size + 20))
moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = (
float(results_match.group(6)) * 1000000)
@@ -484,8 +511,7 @@ class Moongen(ITrafficGenerator):
(float(results_match.group(6)) * frame_size + 20) * 8)
moongen_results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
- float(results_match.group(6)) * \
- 1000000 / max_theoretical_mfps * 100)
+ (100 * float(results_match.group(6)) * 1000000) / max_theoretical_fps)
moongen_results[ResultsConstants.TX_RATE_FPS] = (
float(results_match.group(5)) * 1000000)
@@ -494,8 +520,7 @@ class Moongen(ITrafficGenerator):
float(results_match.group(5)) * (frame_size + 20) * 8)
moongen_results[ResultsConstants.TX_RATE_PERCENT] = (
- float(results_match.group(5)) *
- 1000000 / max_theoretical_mfps * 100)
+ (100 * float(results_match.group(5)) * 1000000) / max_theoretical_fps)
moongen_results[ResultsConstants.B2B_TX_COUNT] = (
float(results_match.group(1)))
@@ -512,7 +537,7 @@ class Moongen(ITrafficGenerator):
return moongen_results
def send_rfc2544_throughput(self, traffic=None, duration=20,
- lossrate=0.0, trials=1):
+ lossrate=0.0, tests=1):
#
# Send traffic per RFC2544 throughput test specifications.
#
@@ -521,7 +546,7 @@ class Moongen(ITrafficGenerator):
# detected is found.
#
# :param traffic: Detailed "traffic" spec, see design docs for details
- # :param trials: Number of trials to execute
+ # :param tests: Number of tests to execute
# :param duration: Per iteration duration
# :param lossrate: Acceptable lossrate percentage
# :returns: dictionary of strings with following data:
@@ -557,7 +582,7 @@ class Moongen(ITrafficGenerator):
total_max_latency_ns = 0
total_avg_latency_ns = 0
- for test_run in range(1, trials+1):
+ for test_run in range(1, tests+1):
collected_results = (
Moongen.run_moongen_and_collect_results(self, test_run=test_run))
@@ -586,35 +611,35 @@ class Moongen(ITrafficGenerator):
results = OrderedDict()
results[ResultsConstants.THROUGHPUT_RX_FPS] = (
- '{:,.6f}'.format(total_throughput_rx_fps / trials))
+ '{:.6f}'.format(total_throughput_rx_fps / tests))
results[ResultsConstants.THROUGHPUT_RX_MBPS] = (
- '{:,.3f}'.format(total_throughput_rx_mbps / trials))
+ '{:.3f}'.format(total_throughput_rx_mbps / tests))
results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
- '{:,.3f}'.format(total_throughput_rx_pct / trials))
+ '{:.3f}'.format(total_throughput_rx_pct / tests))
results[ResultsConstants.TX_RATE_FPS] = (
- '{:,.6f}'.format(total_throughput_tx_fps / trials))
+ '{:.6f}'.format(total_throughput_tx_fps / tests))
results[ResultsConstants.TX_RATE_MBPS] = (
- '{:,.3f}'.format(total_throughput_tx_mbps / trials))
+ '{:.3f}'.format(total_throughput_tx_mbps / tests))
results[ResultsConstants.TX_RATE_PERCENT] = (
- '{:,.3f}'.format(total_throughput_tx_pct / trials))
+ '{:.3f}'.format(total_throughput_tx_pct / tests))
results[ResultsConstants.MIN_LATENCY_NS] = (
- '{:,.3f}'.format(total_min_latency_ns / trials))
+ '{:.3f}'.format(total_min_latency_ns / tests))
results[ResultsConstants.MAX_LATENCY_NS] = (
- '{:,.3f}'.format(total_max_latency_ns / trials))
+ '{:.3f}'.format(total_max_latency_ns / tests))
results[ResultsConstants.AVG_LATENCY_NS] = (
- '{:,.3f}'.format(total_avg_latency_ns / trials))
+ '{:.3f}'.format(total_avg_latency_ns / tests))
return results
- def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20,
+ def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
"""Non-blocking version of 'send_rfc2544_throughput'.
@@ -630,14 +655,14 @@ class Moongen(ITrafficGenerator):
self._logger.info('In moongen wait_rfc2544_throughput')
def send_rfc2544_back2back(self, traffic=None, duration=60,
- lossrate=0.0, trials=1):
+ lossrate=0.0, tests=1):
"""Send traffic per RFC2544 back2back test specifications.
Send packets at a fixed rate, using ``traffic``
configuration, for duration seconds.
:param traffic: Detailed "traffic" spec, see design docs for details
- :param trials: Number of trials to execute
+ :param tests: Number of tests to execute
:param duration: Per iteration duration
:param lossrate: Acceptable loss percentage
@@ -671,7 +696,7 @@ class Moongen(ITrafficGenerator):
results[ResultsConstants.SCAL_STREAM_TYPE] = 0
results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0
- for test_run in range(1, trials+1):
+ for test_run in range(1, tests+1):
collected_results = (
Moongen.run_moongen_and_collect_results(self, test_run=test_run))
@@ -701,28 +726,28 @@ class Moongen(ITrafficGenerator):
# Calculate average results
results[ResultsConstants.B2B_RX_FPS] = (
- results[ResultsConstants.B2B_RX_FPS] / trials)
+ results[ResultsConstants.B2B_RX_FPS] / tests)
results[ResultsConstants.B2B_RX_PERCENT] = (
- results[ResultsConstants.B2B_RX_PERCENT] / trials)
+ results[ResultsConstants.B2B_RX_PERCENT] / tests)
results[ResultsConstants.B2B_TX_FPS] = (
- results[ResultsConstants.B2B_TX_FPS] / trials)
+ results[ResultsConstants.B2B_TX_FPS] / tests)
results[ResultsConstants.B2B_TX_PERCENT] = (
- results[ResultsConstants.B2B_TX_PERCENT] / trials)
+ results[ResultsConstants.B2B_TX_PERCENT] / tests)
results[ResultsConstants.B2B_TX_COUNT] = (
- results[ResultsConstants.B2B_TX_COUNT] / trials)
+ results[ResultsConstants.B2B_TX_COUNT] / tests)
results[ResultsConstants.B2B_FRAMES] = (
- results[ResultsConstants.B2B_FRAMES] / trials)
+ results[ResultsConstants.B2B_FRAMES] / tests)
results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = (
- results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / trials)
+ results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / tests)
results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = (
- results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / trials)
+ results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / tests)
results[ResultsConstants.SCAL_STREAM_COUNT] = 0
results[ResultsConstants.SCAL_STREAM_TYPE] = 0
@@ -730,14 +755,14 @@ class Moongen(ITrafficGenerator):
return results
- def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20,
+ def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
#
# Non-blocking version of 'send_rfc2544_back2back'.
#
# Start transmission and immediately return. Do not wait for results.
#
- self._logger.info("In moongen start_rfc2544_back2back method")
+ self._logger.info("In Moongen start_rfc2544_back2back method")
return NotImplementedError(
'Moongen start back2back traffic not implemented')