1 # Copyright 2016 Cisco Systems, Inc. All rights reserved.
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # 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, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
20 from nfvbench.log import LOG
21 from . import traffic_utils
24 class Latency(object):
25 """A class to hold latency data."""
27 def __init__(self, latency_list=None):
28 """Create a latency instance.
30 latency_list: aggregate all latency values from list if not None
32 self.min_usec = sys.maxsize
37 for lat in latency_list:
39 self.min_usec = min(self.min_usec, lat.min_usec)
40 self.max_usec = max(self.max_usec, lat.max_usec)
41 self.avg_usec += lat.avg_usec
42 # round to nearest usec
43 self.avg_usec = int(round(float(self.avg_usec) / len(latency_list)))
46 """Return True if latency information is available."""
47 return self.min_usec != sys.maxsize
50 class TrafficGeneratorException(Exception):
51 """Exception for traffic generator."""
53 class AbstractTrafficGenerator(object):
55 def __init__(self, traffic_client):
56 self.traffic_client = traffic_client
57 self.generator_config = traffic_client.generator_config
58 self.config = traffic_client.config
61 def get_version(self):
62 # Must be implemented by sub classes
67 # Must be implemented by sub classes
71 def create_traffic(self, l2frame_size, rates, bidirectional, latency=True, e2e=False):
72 # Must be implemented by sub classes
75 def modify_rate(self, rate, reverse):
76 """Change the rate per port.
78 rate: new rate in % (0 to 100)
79 reverse: 0 for port 0, 1 for port 1
81 port_index = int(reverse)
82 port = self.port_handle[port_index]
83 self.rates[port_index] = traffic_utils.to_rate_str(rate)
84 LOG.info('Modified traffic stream for port %s, new rate=%s.', port, self.rates[port_index])
87 def get_stats(self, ifstats):
88 # Must be implemented by sub classes
92 def start_traffic(self):
93 # Must be implemented by sub classes
97 def stop_traffic(self):
98 # Must be implemented by sub classes
103 """Cleanup the traffic generator."""
106 def clear_streamblock(self):
107 """Clear all streams from the traffic generator."""
110 def resolve_arp(self):
111 """Resolve all configured remote IP addresses.
113 return: None if ARP failed to resolve for all IP addresses
114 else a dict of list of dest macs indexed by port#
115 the dest macs in the list are indexed by the chain id
120 """Return the local port MAC addresses.
122 return: a list of MAC addresses indexed by the port#
126 def get_port_speed_gbps(self):
127 """Return the local port speeds.
129 return: a list of speed in Gbps indexed by the port#
132 def get_theoretical_rates(self, avg_packet_size):
136 intf_speeds = self.get_port_speed_gbps()
137 tg_if_speed = bitmath.parse_string(str(intf_speeds[0]) + 'Gb').bits
138 intf_speed = tg_if_speed
140 if hasattr(self.config, 'intf_speed') and self.config.intf_speed is not None:
141 # in case of limitation due to config, TG speed is not accurate
142 # value is overridden by conf
143 if self.config.intf_speed != tg_if_speed:
144 intf_speed = bitmath.parse_string(self.config.intf_speed.replace('ps', '')).bits
146 if hasattr(self.config, 'user_info') and self.config.user_info is not None:
147 if "extra_encapsulation_bytes" in self.config.user_info:
148 frame_size_full_encapsulation = avg_packet_size + self.config.user_info[
149 "extra_encapsulation_bytes"]
150 result['theoretical_tx_rate_pps'] = traffic_utils.bps_to_pps(
151 intf_speed, frame_size_full_encapsulation) * 2
152 result['theoretical_tx_rate_bps'] = traffic_utils.pps_to_bps(
153 result['theoretical_tx_rate_pps'], avg_packet_size)
155 result['theoretical_tx_rate_pps'] = traffic_utils.bps_to_pps(intf_speed,
157 result['theoretical_tx_rate_bps'] = traffic_utils.pps_to_bps(
158 result['theoretical_tx_rate_pps'], avg_packet_size)