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
17 from traffic_base import AbstractTrafficGenerator
20 def convert_rates(l2frame_size, rate, intf_speed):
21 avg_packet_size = get_average_packet_size(l2frame_size)
22 if 'rate_pps' in rate:
23 initial_rate_type = 'rate_pps'
24 pps = rate['rate_pps']
25 bps = pps_to_bps(pps, avg_packet_size)
26 load = bps_to_load(bps, intf_speed)
27 elif 'rate_bps' in rate:
28 initial_rate_type = 'rate_bps'
29 bps = rate['rate_bps']
30 load = bps_to_load(bps, intf_speed)
31 pps = bps_to_pps(bps, avg_packet_size)
32 elif 'rate_percent' in rate:
33 initial_rate_type = 'rate_percent'
34 load = rate['rate_percent']
35 bps = load_to_bps(load, intf_speed)
36 pps = bps_to_pps(bps, avg_packet_size)
38 raise Exception('Traffic config needs to have a rate type key')
41 'initial_rate_type': initial_rate_type,
48 def get_average_packet_size(l2frame_size):
49 if l2frame_size.upper() == 'IMIX':
50 return AbstractTrafficGenerator.imix_avg_l2_size
52 return float(l2frame_size)
55 def load_to_bps(load_percentage, intf_speed):
56 return float(load_percentage) / 100.0 * intf_speed
59 def bps_to_load(bps, intf_speed):
60 return float(bps) / intf_speed * 100.0
63 def bps_to_pps(bps, avg_packet_size):
64 return float(bps) / (avg_packet_size + 20.0) / 8
67 def pps_to_bps(pps, avg_packet_size):
68 return float(pps) * (avg_packet_size + 20.0) * 8
71 def weighted_avg(weight, count):
73 return sum(map(lambda x: x[0] * x[1], zip(weight, count))) / sum(weight)
83 def parse_rate_str(rate_str):
84 if rate_str.endswith('pps'):
85 rate_pps = rate_str[:-3]
87 raise Exception('%s is missing a numeric value' % rate_str)
89 multiplier = multiplier_map[rate_pps[-1].upper()]
90 rate_pps = rate_pps[:-1]
93 rate_pps = int(rate_pps.strip()) * multiplier
95 raise Exception('%s is out of valid range' % rate_str)
96 return {'rate_pps': str(rate_pps)}
97 elif rate_str.endswith('ps'):
98 rate = rate_str.replace('ps', '').strip()
99 bit_rate = bitmath.parse_string(rate).bits
101 raise Exception('%s is out of valid range' % rate_str)
102 return {'rate_bps': str(int(bit_rate))}
103 elif rate_str.endswith('%'):
104 rate_percent = float(rate_str.replace('%', '').strip())
105 if rate_percent <= 0 or rate_percent > 100.0:
106 raise Exception('%s is out of valid range (must be 1-100%%)' % rate_str)
107 return {'rate_percent': str(rate_percent)}
109 raise Exception('Unknown rate string format %s' % rate_str)
112 def divide_rate(rate, divisor):
113 if 'rate_pps' in rate:
115 value = int(rate[key])
116 elif 'rate_bps' in rate:
118 value = int(rate[key])
121 value = float(rate[key])
124 rate[key] = str(value) if value else str(1)
128 def to_rate_str(rate):
129 if 'rate_pps' in rate:
130 pps = rate['rate_pps']
131 return '{}pps'.format(pps)
132 elif 'rate_bps' in rate:
133 bps = rate['rate_bps']
134 return '{}bps'.format(bps)
135 elif 'rate_percent' in rate:
136 load = rate['rate_percent']
137 return '{}%'.format(load)
143 """Replaces every occurence of 'N/A' with float nan."""
144 for k, v in d.iteritems():
145 if isinstance(v, dict):
152 """Converts MAC address to integer representation."""
153 return int(mac.translate(None, ":.- "), 16)
157 """Converts integer representation of MAC address to hex string."""
158 mac = format(i, 'x').zfill(12)
159 blocks = [mac[x:x + 2] for x in xrange(0, len(mac), 2)]
160 return ':'.join(blocks)