diff options
Diffstat (limited to 'nfvbench/traffic_gen/traffic_base.py')
-rw-r--r-- | nfvbench/traffic_gen/traffic_base.py | 57 |
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 |