1 # Copyright 2016 Red Hat Inc
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 # Bill Michalowski, Red Hat Inc.
17 # Andrew Theurer, Red Hat Inc.
19 Moongen Traffic Generator Model
24 from collections import OrderedDict
29 from conf import settings
30 from core.results.results_constants import ResultsConstants
31 from tools.pkt_gen.trafficgen.trafficgenhelper import (
34 from tools.pkt_gen.trafficgen.trafficgen import ITrafficGenerator
36 class Moongen(ITrafficGenerator):
37 """Moongen Traffic generator wrapper."""
38 _traffic_defaults = TRAFFIC_DEFAULTS.copy()
39 _logger = logging.getLogger(__name__)
42 """Moongen class constructor."""
43 self._logger.info("In moongen __init__ method")
45 self._moongen_host_ip_addr = (
46 settings.getValue('TRAFFICGEN_MOONGEN_HOST_IP_ADDR'))
47 self._moongen_base_dir = (
48 settings.getValue('TRAFFICGEN_MOONGEN_BASE_DIR'))
49 self._moongen_user = settings.getValue('TRAFFICGEN_MOONGEN_USER')
50 self._moongen_ports = settings.getValue('TRAFFICGEN_MOONGEN_PORTS')
53 def traffic_defaults(self):
54 """Default traffic values.
56 These can be expected to be constant across traffic generators,
57 so no setter is provided. Changes to the structure or contents
58 will likely break traffic generator implementations or tests
61 self._logger.info("In Moongen traffic_defaults method")
62 return self._traffic_defaults
64 def create_moongen_cfg_file(self, traffic, duration=60,
65 acceptable_loss_pct=1, one_shot=0):
66 """Create the Moongen configuration file from VSPERF's traffic profile
67 :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
68 :param duration: The length of time to generate packet throughput
69 :param acceptable_loss: Maximum packet loss acceptable
70 :param one_shot: No RFC 2544 binary search,
71 just packet flow at traffic specifics
73 logging.debug("traffic['frame_rate'] = " + \
74 str(traffic['frame_rate']))
76 logging.debug("traffic['multistream'] = " + \
77 str(traffic['multistream']))
79 logging.debug("traffic['stream_type'] = " + \
80 str(traffic['stream_type']))
82 logging.debug("traffic['l2']['srcmac'] = " + \
83 str(traffic['l2']['srcmac']))
85 logging.debug("traffic['l2']['dstmac'] = " + \
86 str(traffic['l2']['dstmac']))
88 logging.debug("traffic['l3']['proto'] = " + \
89 str(traffic['l3']['proto']))
91 logging.debug("traffic['l3']['srcip'] = " + \
92 str(traffic['l3']['srcip']))
94 logging.debug("traffic['l3']['dstip'] = " + \
95 str(traffic['l3']['dstip']))
97 logging.debug("traffic['l4']['srcport'] = " + \
98 str(traffic['l4']['srcport']))
100 logging.debug("traffic['l4']['dstport'] = " + \
101 str(traffic['l4']['dstport']))
103 logging.debug("traffic['vlan']['enabled'] = " + \
104 str(traffic['vlan']['enabled']))
106 logging.debug("traffic['vlan']['id'] = " + \
107 str(traffic['vlan']['id']))
109 logging.debug("traffic['vlan']['priority'] = " + \
110 str(traffic['vlan']['priority']))
112 logging.debug("traffic['vlan']['cfi'] = " + \
113 str(traffic['vlan']['cfi']))
115 logging.debug(traffic['l2']['framesize'])
117 out_file = open("opnfv-vsperf-cfg.lua", "wt")
119 out_file.write("VSPERF {\n")
121 out_file.write("testType = \"throughput\",\n")
123 out_file.write("runBidirec = " + \
124 traffic['bidir'].lower() + ",\n")
126 out_file.write("frameSize = " + \
127 str(traffic['l2']['framesize']) + ",\n")
129 out_file.write("srcMac = \"" + \
130 str(traffic['l2']['srcmac']) + "\",\n")
132 out_file.write("dstMac = \"" + \
133 str(traffic['l2']['dstmac']) + "\",\n")
135 out_file.write("srcIp = \"" + \
136 str(traffic['l3']['srcip']) + "\",\n")
138 out_file.write("dstIp = \"" + \
139 str(traffic['l3']['dstip']) + "\",\n")
141 if traffic['vlan']['enabled']:
142 out_file.write("vlanId = " + \
143 str(traffic['vlan']['id']) + ",\n")
145 out_file.write("searchRunTime = " + \
146 str(duration) + ",\n")
148 out_file.write("validationRunTime = " + \
149 str(duration) + ",\n")
151 out_file.write("acceptableLossPct = " + \
152 str(acceptable_loss_pct) + ",\n")
154 out_file.write("ports = " +\
155 str(self._moongen_ports) + ",\n")
158 out_file.write("oneShot = true,\n")
160 # Assume 10G line rates at the moment. Need to convert VSPERF
161 # frame_rate (percentage of line rate) to Mpps for Moongen
163 out_file.write("startRate = " + str((traffic['frame_rate'] / 100) * 14.88) + "\n")
164 out_file.write("}" + "\n")
167 copy_moongen_cfg = "scp opnfv-vsperf-cfg.lua " + \
168 self._moongen_user + "@" + \
169 self._moongen_host_ip_addr + ":" + \
170 self._moongen_base_dir + \
171 "/. && rm opnfv-vsperf-cfg.lua"
173 find_moongen = subprocess.Popen(copy_moongen_cfg,
175 stderr=subprocess.PIPE)
177 output, error = find_moongen.communicate()
180 logging.error(output)
182 raise RuntimeError('MOONGEN: Error copying configuration file')
185 """Connect to Moongen traffic generator
187 Verify that Moongen is on the system indicated by
188 the configuration file
190 self._logger.info("MOONGEN: In Moongen connect method...")
192 if self._moongen_host_ip_addr:
193 cmd_ping = "ping -c1 " + self._moongen_host_ip_addr
195 raise RuntimeError('MOONGEN: Moongen host not defined')
197 ping = subprocess.Popen(cmd_ping, shell=True, stderr=subprocess.PIPE)
198 output, error = ping.communicate()
201 self._logger.error(error)
202 self._logger.error(output)
203 raise RuntimeError('MOONGEN: Cannot ping Moongen host at ' + \
204 self._moongen_host_ip_addr)
206 connect_moongen = "ssh " + self._moongen_user + \
207 "@" + self._moongen_host_ip_addr
209 cmd_find_moongen = connect_moongen + " ls " + \
210 self._moongen_base_dir + "/examples/opnfv-vsperf.lua"
212 find_moongen = subprocess.Popen(cmd_find_moongen,
214 stderr=subprocess.PIPE)
216 output, error = find_moongen.communicate()
218 if find_moongen.returncode:
219 self._logger.error(error)
220 self._logger.error(output)
222 'MOONGEN: Cannot locate Moongen program at %s within %s' \
223 % (self._moongen_host_ip_addr, self._moongen_base_dir))
225 self._logger.info("MOONGEN: Moongen host successfully found...")
227 def disconnect(self):
228 """Disconnect from the traffic generator.
230 As with :func:`connect`, this function is optional.
232 Where implemented, this function should raise an exception on
237 self._logger.info("MOONGEN: In moongen disconnect method")
239 def send_burst_traffic(self, traffic=None, numpkts=100, duration=20):
240 """Send a burst of traffic.
242 Send a ``numpkts`` packets of traffic, using ``traffic``
243 configuration, with a timeout of ``time``.
245 :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
246 :param numpkts: Number of packets to send
247 :param duration: Time to wait to receive packets
249 :returns: dictionary of strings with following data:
253 - List of List of Rx Bytes,
254 - Payload Errors and Sequence Errors.
256 self._logger.info("In Moongen send_burst_traffic method")
257 return NotImplementedError('Moongen Burst traffic not implemented')
259 def send_cont_traffic(self, traffic=None, duration=20):
260 """Send a continuous flow of traffic
262 Send packets at ``frame rate``, using ``traffic`` configuration,
263 until timeout ``time`` occurs.
265 :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
266 :param duration: Time to wait to receive packets (secs)
267 :returns: dictionary of strings with following data:
268 - Tx Throughput (fps),
269 - Rx Throughput (fps),
270 - Tx Throughput (mbps),
271 - Rx Throughput (mbps),
272 - Tx Throughput (% linerate),
273 - Rx Throughput (% linerate),
278 self._logger.info("In Moongen send_cont_traffic method")
281 self._params['traffic'] = self.traffic_defaults.copy()
284 self._params['traffic'] = merge_spec(self._params['traffic'],
287 Moongen.create_moongen_cfg_file(self,
290 acceptable_loss_pct=100.0,
293 collected_results = Moongen.run_moongen_and_collect_results(self,
296 total_throughput_rx_fps = (
297 float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS]))
299 total_throughput_rx_mbps = (
300 float(collected_results[ResultsConstants.THROUGHPUT_RX_MBPS]))
302 total_throughput_rx_pct = (
303 float(collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT]))
305 total_throughput_tx_fps = (
306 float(collected_results[ResultsConstants.TX_RATE_FPS]))
308 total_throughput_tx_mbps = (
309 float(collected_results[ResultsConstants.TX_RATE_MBPS]))
311 total_throughput_tx_pct = (
312 float(collected_results[ResultsConstants.TX_RATE_PERCENT]))
314 total_min_latency_ns = 0
315 total_max_latency_ns = 0
316 total_avg_latency_ns = 0
318 results = OrderedDict()
319 results[ResultsConstants.THROUGHPUT_RX_FPS] = (
320 '{:,.6f}'.format(total_throughput_rx_fps))
322 results[ResultsConstants.THROUGHPUT_RX_MBPS] = (
323 '{:,.3f}'.format(total_throughput_rx_mbps))
325 results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
326 '{:,.3f}'.format(total_throughput_rx_pct))
328 results[ResultsConstants.TX_RATE_FPS] = (
329 '{:,.6f}'.format(total_throughput_tx_fps))
331 results[ResultsConstants.TX_RATE_MBPS] = (
332 '{:,.3f}'.format(total_throughput_tx_mbps))
334 results[ResultsConstants.TX_RATE_PERCENT] = (
335 '{:,.3f}'.format(total_throughput_tx_pct))
337 results[ResultsConstants.MIN_LATENCY_NS] = (
338 '{:,.3f}'.format(total_min_latency_ns))
340 results[ResultsConstants.MAX_LATENCY_NS] = (
341 '{:,.3f}'.format(total_max_latency_ns))
343 results[ResultsConstants.AVG_LATENCY_NS] = (
344 '{:,.3f}'.format(total_avg_latency_ns))
348 def start_cont_traffic(self, traffic=None, duration=20):
349 """ Non-blocking version of 'send_cont_traffic'.
351 Start transmission and immediately return. Do not wait for
353 :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags
354 :param duration: Time to wait to receive packets (secs)
356 self._logger.info("In Moongen start_cont_traffic method")
357 return NotImplementedError('moongen continuous traffic not implemented')
359 def stop_cont_traffic(self):
360 # Stop continuous transmission and return results.
361 self._logger.info("In Moongen stop_cont_traffic method")
363 def run_moongen_and_collect_results(self, test_run=1):
364 """Execute Moongen and transform results into VSPERF format
365 :param test_run: The number of tests to run
367 # Start Moongen and create logfile of the run
368 connect_moongen = "ssh " + self._moongen_user + "@" + \
369 self._moongen_host_ip_addr
371 cmd_moongen = " 'cd " + self._moongen_base_dir + \
372 "; ./build/MoonGen examples/opnfv-vsperf.lua | tee moongen_log.txt'"
374 cmd_start_moongen = connect_moongen + cmd_moongen
376 start_moongen = subprocess.Popen(cmd_start_moongen,
377 shell=True, stderr=subprocess.PIPE)
379 output, error = start_moongen.communicate()
381 if start_moongen.returncode:
383 logging.debug(output)
385 'MOONGEN: Error starting Moongen program at %s within %s' \
386 % (self._moongen_host_ip_addr, self._moongen_base_dir))
388 cmd_moongen = "mkdir -p /tmp/moongen/" + str(test_run)
390 moongen_create_log_dir = subprocess.Popen(cmd_moongen,
392 stderr=subprocess.PIPE)
394 output, error = moongen_create_log_dir.communicate()
396 if moongen_create_log_dir.returncode:
398 logging.debug(output)
400 'MOONGEN: Error obtaining Moongen log from %s within %s' \
401 % (self._moongen_host_ip_addr, self._moongen_base_dir))
403 cmd_moongen = " scp " + self._moongen_user + "@" + \
404 self._moongen_host_ip_addr + ":" + \
405 self._moongen_base_dir + "/moongen_log.txt /tmp/moongen/" + \
406 str(test_run) + "/moongen-run.log"
408 copy_moongen_log = subprocess.Popen(cmd_moongen,
410 stderr=subprocess.PIPE)
412 output, error = copy_moongen_log.communicate()
414 if copy_moongen_log.returncode:
416 logging.debug(output)
418 'MOONGEN: Error obtaining Moongen log from %s within %s' \
419 % (self._moongen_host_ip_addr, self._moongen_base_dir))
421 log_file = "/tmp/moongen/" + str(test_run) + "/moongen-run.log"
423 with open(log_file, 'r') as logfile_handle:
424 mytext = logfile_handle.read()
426 # REPORT results line
427 # match.group(1) = Tx frames
428 # match.group(2) = Rx frames
429 # match.group(3) = Frame loss (count)
430 # match.group(4) = Frame loss (percentage)
431 # match.group(5) = Tx Mpps
432 # match.group(6) = Rx Mpps
433 search_pattern = re.compile(
434 r'\[REPORT\]\s+total\:\s+'
435 r'Tx\s+frames\:\s+(\d+)\s+'
436 r'Rx\s+Frames\:\s+(\d+)\s+'
437 r'frame\s+loss\:\s+(\d+)\,'
438 r'\s+(\d+\.\d+|\d+)%\s+'
439 r'Tx\s+Mpps\:\s+(\d+.\d+|\d+)\s+'
440 r'Rx\s+Mpps\:\s+(\d+\.\d+|\d+)',
443 results_match = search_pattern.search(mytext)
445 if not results_match:
446 logging.error('There was a problem parsing ' +\
447 'Moongen REPORT section of Moongen log file')
449 moongen_results = OrderedDict()
450 moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = 0
451 moongen_results[ResultsConstants.THROUGHPUT_RX_MBPS] = 0
452 moongen_results[ResultsConstants.THROUGHPUT_RX_PERCENT] = 0
453 moongen_results[ResultsConstants.TX_RATE_FPS] = 0
454 moongen_results[ResultsConstants.TX_RATE_MBPS] = 0
455 moongen_results[ResultsConstants.TX_RATE_PERCENT] = 0
456 moongen_results[ResultsConstants.B2B_TX_COUNT] = 0
457 moongen_results[ResultsConstants.B2B_FRAMES] = 0
458 moongen_results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = 0
459 moongen_results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = 0
461 # find PARAMETERS line
462 # parameters_match.group(1) = Frame size
464 search_pattern = re.compile(
465 r'\[PARAMETERS\]\s+.*frameSize\:\s+(\d+)',
467 parameters_match = search_pattern.search(mytext)
470 frame_size = int(parameters_match.group(1))
472 logging.error('There was a problem parsing Moongen ' +\
473 'PARAMETERS section of Moongen log file')
476 if results_match and parameters_match:
477 # Assume for now 10G link speed
478 max_theoretical_mfps = (
479 (10000000000 / 8) / (frame_size + 20))
481 moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = (
482 float(results_match.group(6)) * 1000000)
484 moongen_results[ResultsConstants.THROUGHPUT_RX_MBPS] = (
485 (float(results_match.group(6)) * frame_size + 20) * 8)
487 moongen_results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
488 float(results_match.group(6)) * \
489 1000000 / max_theoretical_mfps * 100)
491 moongen_results[ResultsConstants.TX_RATE_FPS] = (
492 float(results_match.group(5)) * 1000000)
494 moongen_results[ResultsConstants.TX_RATE_MBPS] = (
495 float(results_match.group(5)) * (frame_size + 20) * 8)
497 moongen_results[ResultsConstants.TX_RATE_PERCENT] = (
498 float(results_match.group(5)) *
499 1000000 / max_theoretical_mfps * 100)
501 moongen_results[ResultsConstants.B2B_TX_COUNT] = (
502 float(results_match.group(1)))
504 moongen_results[ResultsConstants.B2B_FRAMES] = (
505 float(results_match.group(2)))
507 moongen_results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = (
508 float(results_match.group(3)))
510 moongen_results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = (
511 float(results_match.group(4)))
513 return moongen_results
515 def send_rfc2544_throughput(self, traffic=None, duration=20,
516 lossrate=0.0, trials=1):
518 # Send traffic per RFC2544 throughput test specifications.
520 # Send packets at a variable rate, using ``traffic``
521 # configuration, until minimum rate at which no packet loss is
524 # :param traffic: Detailed "traffic" spec, see design docs for details
525 # :param trials: Number of trials to execute
526 # :param duration: Per iteration duration
527 # :param lossrate: Acceptable lossrate percentage
528 # :returns: dictionary of strings with following data:
529 # - Tx Throughput (fps),
530 # - Rx Throughput (fps),
531 # - Tx Throughput (mbps),
532 # - Rx Throughput (mbps),
533 # - Tx Throughput (% linerate),
534 # - Rx Throughput (% linerate),
535 # - Min Latency (ns),
536 # - Max Latency (ns),
539 self._logger.info("In moongen send_rfc2544_throughput method")
541 self._params['traffic'] = self.traffic_defaults.copy()
544 self._params['traffic'] = merge_spec(self._params['traffic'],
546 Moongen.create_moongen_cfg_file(self,
549 acceptable_loss_pct=lossrate)
551 total_throughput_rx_fps = 0
552 total_throughput_rx_mbps = 0
553 total_throughput_rx_pct = 0
554 total_throughput_tx_fps = 0
555 total_throughput_tx_mbps = 0
556 total_throughput_tx_pct = 0
557 total_min_latency_ns = 0
558 total_max_latency_ns = 0
559 total_avg_latency_ns = 0
561 for test_run in range(1, trials+1):
562 collected_results = (
563 Moongen.run_moongen_and_collect_results(self, test_run=test_run))
565 total_throughput_rx_fps += (
566 float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS]))
568 total_throughput_rx_mbps += (
569 float(collected_results[ResultsConstants.THROUGHPUT_RX_MBPS]))
571 total_throughput_rx_pct += (
572 float(collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT]))
574 total_throughput_tx_fps += (
575 float(collected_results[ResultsConstants.TX_RATE_FPS]))
577 total_throughput_tx_mbps += (
578 float(collected_results[ResultsConstants.TX_RATE_MBPS]))
580 total_throughput_tx_pct += (
581 float(collected_results[ResultsConstants.TX_RATE_PERCENT]))
583 # Latency not supported now, leaving as placeholder
584 total_min_latency_ns = 0
585 total_max_latency_ns = 0
586 total_avg_latency_ns = 0
588 results = OrderedDict()
589 results[ResultsConstants.THROUGHPUT_RX_FPS] = (
590 '{:,.6f}'.format(total_throughput_rx_fps / trials))
592 results[ResultsConstants.THROUGHPUT_RX_MBPS] = (
593 '{:,.3f}'.format(total_throughput_rx_mbps / trials))
595 results[ResultsConstants.THROUGHPUT_RX_PERCENT] = (
596 '{:,.3f}'.format(total_throughput_rx_pct / trials))
598 results[ResultsConstants.TX_RATE_FPS] = (
599 '{:,.6f}'.format(total_throughput_tx_fps / trials))
601 results[ResultsConstants.TX_RATE_MBPS] = (
602 '{:,.3f}'.format(total_throughput_tx_mbps / trials))
604 results[ResultsConstants.TX_RATE_PERCENT] = (
605 '{:,.3f}'.format(total_throughput_tx_pct / trials))
607 results[ResultsConstants.MIN_LATENCY_NS] = (
608 '{:,.3f}'.format(total_min_latency_ns / trials))
610 results[ResultsConstants.MAX_LATENCY_NS] = (
611 '{:,.3f}'.format(total_max_latency_ns / trials))
613 results[ResultsConstants.AVG_LATENCY_NS] = (
614 '{:,.3f}'.format(total_avg_latency_ns / trials))
618 def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20,
620 """Non-blocking version of 'send_rfc2544_throughput'.
622 Start transmission and immediately return. Do not wait for
626 "MOONGEN: In moongen start_rfc2544_throughput method")
628 def wait_rfc2544_throughput(self):
629 """Wait for and return results of RFC2544 test.
631 self._logger.info('In moongen wait_rfc2544_throughput')
633 def send_rfc2544_back2back(self, traffic=None, duration=60,
634 lossrate=0.0, trials=1):
635 """Send traffic per RFC2544 back2back test specifications.
637 Send packets at a fixed rate, using ``traffic``
638 configuration, for duration seconds.
640 :param traffic: Detailed "traffic" spec, see design docs for details
641 :param trials: Number of trials to execute
642 :param duration: Per iteration duration
643 :param lossrate: Acceptable loss percentage
645 :returns: Named tuple of Rx Throughput (fps), Rx Throughput (mbps),
646 Tx Rate (% linerate), Rx Rate (% linerate), Tx Count (frames),
647 Back to Back Count (frames), Frame Loss (frames), Frame Loss (%)
648 :rtype: :class:`Back2BackResult`
651 self._params['traffic'] = self.traffic_defaults.copy()
654 self._params['traffic'] = merge_spec(self._params['traffic'],
657 Moongen.create_moongen_cfg_file(self,
660 acceptable_loss_pct=lossrate)
662 results = OrderedDict()
663 results[ResultsConstants.B2B_RX_FPS] = 0
664 results[ResultsConstants.B2B_TX_FPS] = 0
665 results[ResultsConstants.B2B_RX_PERCENT] = 0
666 results[ResultsConstants.B2B_TX_PERCENT] = 0
667 results[ResultsConstants.B2B_TX_COUNT] = 0
668 results[ResultsConstants.B2B_FRAMES] = 0
669 results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = 0
670 results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = 0
671 results[ResultsConstants.SCAL_STREAM_COUNT] = 0
672 results[ResultsConstants.SCAL_STREAM_TYPE] = 0
673 results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0
675 for test_run in range(1, trials+1):
676 collected_results = (
677 Moongen.run_moongen_and_collect_results(self, test_run=test_run))
679 results[ResultsConstants.B2B_RX_FPS] += (
680 float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS]))
682 results[ResultsConstants.B2B_RX_PERCENT] += (
683 float(collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT]))
685 results[ResultsConstants.B2B_TX_FPS] += (
686 float(collected_results[ResultsConstants.TX_RATE_FPS]))
688 results[ResultsConstants.B2B_TX_PERCENT] += (
689 float(collected_results[ResultsConstants.TX_RATE_PERCENT]))
691 results[ResultsConstants.B2B_TX_COUNT] += (
692 int(collected_results[ResultsConstants.B2B_TX_COUNT]))
694 results[ResultsConstants.B2B_FRAMES] += (
695 int(collected_results[ResultsConstants.B2B_FRAMES]))
697 results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] += (
698 int(collected_results[ResultsConstants.B2B_FRAME_LOSS_FRAMES]))
700 results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] += (
701 int(collected_results[ResultsConstants.B2B_FRAME_LOSS_PERCENT]))
703 # Calculate average results
704 results[ResultsConstants.B2B_RX_FPS] = (
705 results[ResultsConstants.B2B_RX_FPS] / trials)
707 results[ResultsConstants.B2B_RX_PERCENT] = (
708 results[ResultsConstants.B2B_RX_PERCENT] / trials)
710 results[ResultsConstants.B2B_TX_FPS] = (
711 results[ResultsConstants.B2B_TX_FPS] / trials)
713 results[ResultsConstants.B2B_TX_PERCENT] = (
714 results[ResultsConstants.B2B_TX_PERCENT] / trials)
716 results[ResultsConstants.B2B_TX_COUNT] = (
717 results[ResultsConstants.B2B_TX_COUNT] / trials)
719 results[ResultsConstants.B2B_FRAMES] = (
720 results[ResultsConstants.B2B_FRAMES] / trials)
722 results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = (
723 results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / trials)
725 results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = (
726 results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / trials)
728 results[ResultsConstants.SCAL_STREAM_COUNT] = 0
729 results[ResultsConstants.SCAL_STREAM_TYPE] = 0
730 results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0
734 def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20,
737 # Non-blocking version of 'send_rfc2544_back2back'.
739 # Start transmission and immediately return. Do not wait for results.
741 self._logger.info("In Moongen start_rfc2544_back2back method")
742 return NotImplementedError(
743 'Moongen start back2back traffic not implemented')
745 def wait_rfc2544_back2back(self):
746 self._logger.info("In moongen wait_rfc2544_back2back method")
748 # Wait and set results of RFC2544 test.
750 return NotImplementedError(
751 'Moongen wait back2back traffic not implemented')
753 if __name__ == "__main__":