aboutsummaryrefslogtreecommitdiffstats
path: root/nfvbench/traffic_gen/traffic_base.py
diff options
context:
space:
mode:
Diffstat (limited to 'nfvbench/traffic_gen/traffic_base.py')
-rw-r--r--nfvbench/traffic_gen/traffic_base.py57
1 files changed, 45 insertions, 12 deletions
diff --git a/nfvbench/traffic_gen/traffic_base.py b/nfvbench/traffic_gen/traffic_base.py
index 0360591..30aec6e 100644
--- a/nfvbench/traffic_gen/traffic_base.py
+++ b/nfvbench/traffic_gen/traffic_base.py
@@ -16,7 +16,9 @@ import abc
import sys
from nfvbench.log import LOG
-import traffic_utils
+from . import traffic_utils
+from hdrh.histogram import HdrHistogram
+from functools import reduce
class Latency(object):
@@ -27,29 +29,42 @@ class Latency(object):
latency_list: aggregate all latency values from list if not None
"""
- self.min_usec = sys.maxint
+ self.min_usec = sys.maxsize
self.max_usec = 0
self.avg_usec = 0
+ self.hdrh = None
if latency_list:
+ hdrh_list = []
for lat in latency_list:
if lat.available():
self.min_usec = min(self.min_usec, lat.min_usec)
self.max_usec = max(self.max_usec, lat.max_usec)
self.avg_usec += lat.avg_usec
+ if lat.hdrh_available():
+ hdrh_list.append(HdrHistogram.decode(lat.hdrh))
+
+ # aggregate histograms if any
+ if hdrh_list:
+ def add_hdrh(x, y):
+ x.add(y)
+ return x
+ decoded_hdrh = reduce(add_hdrh, hdrh_list)
+ self.hdrh = HdrHistogram.encode(decoded_hdrh).decode('utf-8')
+
# round to nearest usec
self.avg_usec = int(round(float(self.avg_usec) / len(latency_list)))
def available(self):
"""Return True if latency information is available."""
- return self.min_usec != sys.maxint
+ return self.min_usec != sys.maxsize
+ def hdrh_available(self):
+ """Return True if latency histogram information is available."""
+ return self.hdrh is not None
class TrafficGeneratorException(Exception):
"""Exception for traffic generator."""
- pass
-
-
class AbstractTrafficGenerator(object):
def __init__(self, traffic_client):
@@ -68,7 +83,7 @@ class AbstractTrafficGenerator(object):
return None
@abc.abstractmethod
- def create_traffic(self, l2frame_size, rates, bidirectional, latency=True):
+ def create_traffic(self, l2frame_size, rates, bidirectional, latency=True, e2e=False):
# Must be implemented by sub classes
return None
@@ -84,7 +99,7 @@ class AbstractTrafficGenerator(object):
LOG.info('Modified traffic stream for port %s, new rate=%s.', port, self.rates[port_index])
@abc.abstractmethod
- def get_stats(self):
+ def get_stats(self, ifstats):
# Must be implemented by sub classes
return None
@@ -105,7 +120,6 @@ class AbstractTrafficGenerator(object):
def clear_streamblock(self):
"""Clear all streams from the traffic generator."""
- pass
@abc.abstractmethod
def resolve_arp(self):
@@ -115,7 +129,6 @@ class AbstractTrafficGenerator(object):
else a dict of list of dest macs indexed by port#
the dest macs in the list are indexed by the chain id
"""
- pass
@abc.abstractmethod
def get_macs(self):
@@ -123,7 +136,6 @@ class AbstractTrafficGenerator(object):
return: a list of MAC addresses indexed by the port#
"""
- pass
@abc.abstractmethod
def get_port_speed_gbps(self):
@@ -131,4 +143,25 @@ class AbstractTrafficGenerator(object):
return: a list of speed in Gbps indexed by the port#
"""
- pass
+
+ def get_theoretical_rates(self, avg_packet_size):
+
+ result = {}
+
+ # actual interface speed? (may be a virtual override)
+ intf_speed = self.config.intf_speed_used
+
+ if hasattr(self.config, 'user_info') and self.config.user_info is not None:
+ if "extra_encapsulation_bytes" in self.config.user_info:
+ frame_size_full_encapsulation = avg_packet_size + self.config.user_info[
+ "extra_encapsulation_bytes"]
+ result['theoretical_tx_rate_pps'] = traffic_utils.bps_to_pps(
+ intf_speed, frame_size_full_encapsulation) * 2
+ result['theoretical_tx_rate_bps'] = traffic_utils.pps_to_bps(
+ result['theoretical_tx_rate_pps'], avg_packet_size)
+ else:
+ result['theoretical_tx_rate_pps'] = traffic_utils.bps_to_pps(intf_speed,
+ avg_packet_size) * 2
+ result['theoretical_tx_rate_bps'] = traffic_utils.pps_to_bps(
+ result['theoretical_tx_rate_pps'], avg_packet_size)
+ return result