# See the License for the specific language governing permissions and
# limitations under the License.
-from __future__ import absolute_import
import logging
-import json
-from yardstick.network_services.traffic_profile.traffic_profile import \
- TrexProfile
+from yardstick.common import utils
+from yardstick.network_services.traffic_profile import base as tp_base
+from yardstick.network_services.traffic_profile import trex_traffic_profile
+
LOG = logging.getLogger(__name__)
-class IXIARFC2544Profile(TrexProfile):
- def _get_ixia_traffic_profile(self, profile_data, mac={},
- xfile=None, static_traffic={}):
+class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
+
+ UPLINK = 'uplink'
+ DOWNLINK = 'downlink'
+ DROP_PERCENT_ROUND = 6
+ RATE_ROUND = 5
+
+ def __init__(self, yaml_data):
+ super(IXIARFC2544Profile, self).__init__(yaml_data)
+ self.rate = self.config.frame_rate
+ self.rate_unit = self.config.rate_unit
+
+ def _get_ip_and_mask(self, ip_range):
+ _ip_range = ip_range.split('-')
+ if len(_ip_range) == 1:
+ return _ip_range[0], None
+
+ mask = utils.get_mask_from_ip_range(_ip_range[0], _ip_range[1])
+ return _ip_range[0], mask
+
+ def _get_fixed_and_mask(self, port_range):
+ _port_range = str(port_range).split('-')
+ if len(_port_range) == 1:
+ return int(_port_range[0]), 0
+
+ return int(_port_range[0]), int(_port_range[1])
+
+ def _get_ixia_traffic_profile(self, profile_data, mac=None):
+ mac = {} if mac is None else mac
result = {}
- if xfile:
- with open(xfile, 'r') as stream:
+ for traffickey, values in profile_data.items():
+ if not traffickey.startswith((self.UPLINK, self.DOWNLINK)):
+ continue
+
+ try:
+ # values should be single-item dict, so just grab the first item
try:
- static_traffic = json.load(stream)
- except Exception as exc:
- LOG.debug(exc)
-
- for traffickey, trafficvalue in static_traffic.items():
- traffic = static_traffic[traffickey]
- # outer_l2
- index = 0
- for key, value in profile_data[traffickey].items():
- framesize = value['outer_l2']['framesize']
- traffic['outer_l2']['framesize'] = framesize
- traffic['framesPerSecond'] = True
- traffic['bidir'] = False
- traffic['outer_l2']['srcmac'] = \
- mac["src_mac_{}".format(traffic['id'])]
- traffic['outer_l2']['dstmac'] = \
- mac["dst_mac_{}".format(traffic['id'])]
- # outer_l3
- if "outer_l3v6" in list(value.keys()):
- traffic['outer_l3'] = value['outer_l3v6']
- srcip4 = value['outer_l3v6']['srcip6']
- traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
- dstip4 = value['outer_l3v6']['dstip6']
- traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
+ key, value = next(iter(values.items()))
+ except StopIteration:
+ result[traffickey] = {}
+ continue
+
+ port_id = value.get('id', 1)
+ port_index = port_id - 1
+
+ if value.get('outer_l3v4'):
+ ip = value['outer_l3v4']
+ src_key, dst_key = 'srcip4', 'dstip4'
else:
- traffic['outer_l3'] = value['outer_l3v4']
- srcip4 = value['outer_l3v4']['srcip4']
- traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
- dstip4 = value['outer_l3v4']['dstip4']
- traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
-
- traffic['outer_l3']['type'] = key
- traffic['outer_l3']['count'] = value['outer_l3v4']['count']
- # outer_l4
- traffic['outer_l4'] = value['outer_l4']
- index = index + 1
- result.update({traffickey: traffic})
+ ip = value['outer_l3v6']
+ src_key, dst_key = 'srcip6', 'dstip6'
+
+ srcip, srcmask = self._get_ip_and_mask(ip[src_key])
+ dstip, dstmask = self._get_ip_and_mask(ip[dst_key])
+
+ outer_l4 = value.get('outer_l4')
+ src_port, src_port_mask = self._get_fixed_and_mask(outer_l4['srcport'])
+ dst_port, dst_port_mask = self._get_fixed_and_mask(outer_l4['dstport'])
+ result[traffickey] = {
+ 'bidir': False,
+ 'id': port_id,
+ 'rate': self.rate,
+ 'rate_unit': self.rate_unit,
+ 'outer_l2': {
+ 'framesize': value['outer_l2']['framesize'],
+ 'framesPerSecond': True,
+ 'QinQ': value['outer_l2'].get('QinQ'),
+ 'srcmac': mac['src_mac_{}'.format(port_index)],
+ 'dstmac': mac['dst_mac_{}'.format(port_index)],
+ },
+ 'outer_l3': {
+ 'count': ip['count'],
+ 'dscp': ip['dscp'],
+ 'ttl': ip['ttl'],
+ 'seed': ip['seed'],
+ 'srcip': srcip,
+ 'dstip': dstip,
+ 'srcmask': srcmask,
+ 'dstmask': dstmask,
+ 'type': key,
+ 'proto': ip['proto'],
+ },
+ 'outer_l4': {
+ 'srcport': src_port,
+ 'dstport': dst_port,
+ 'srcportmask': src_port_mask,
+ 'dstportmask': dst_port_mask,
+ 'count': outer_l4['count'],
+ 'seed': outer_l4['seed'],
+ }
+
+ }
+ except KeyError:
+ continue
return result
- def _ixia_traffic_generate(self, traffic_generator, traffic, ixia_obj):
- for key, value in traffic.items():
- if "public" in key or "private" in key:
- traffic[key]["iload"] = str(self.rate)
- ixia_obj.ix_update_frame(traffic)
- ixia_obj.ix_update_ether(traffic)
- ixia_obj.add_ip_header(traffic, 4)
- ixia_obj.ix_start_traffic()
- self.tmp_drop = 0
- self.tmp_throughput = 0
-
- def execute(self, traffic_generator, ixia_obj, mac={}, xfile=None):
+ def _ixia_traffic_generate(self, traffic, ixia_obj):
+ ixia_obj.update_frame(traffic, self.config.duration)
+ ixia_obj.update_ip_packet(traffic)
+ ixia_obj.update_l4(traffic)
+ ixia_obj.start_traffic()
+
+ def update_traffic_profile(self, traffic_generator):
+ def port_generator():
+ for vld_id, intfs in sorted(traffic_generator.networks.items()):
+ if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
+ continue
+ profile_data = self.params.get(vld_id)
+ if not profile_data:
+ continue
+ self.profile_data = profile_data
+ self.full_profile.update({vld_id: self.profile_data})
+ for intf in intfs:
+ yield traffic_generator.vnfd_helper.port_num(intf)
+
+ self.ports = [port for port in port_generator()]
+
+ def execute_traffic(self, traffic_generator, ixia_obj=None, mac=None):
+ mac = {} if mac is None else mac
+ first_run = self.first_run
if self.first_run:
+ self.first_run = False
self.full_profile = {}
self.pg_id = 0
- self.profile = 'private_1'
- for key, value in self.params.items():
- if "private" in key or "public" in key:
- self.profile_data = self.params[key]
- self.get_streams(self.profile_data)
- self.full_profile.update({key: self.profile_data})
- traffic = \
- self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
+ self.update_traffic_profile(traffic_generator)
self.max_rate = self.rate
- self.min_rate = 0
- self.get_multiplier()
- self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
-
- def get_multiplier(self):
- self.rate = round((self.max_rate + self.min_rate) / 2.0, 2)
- multiplier = round(self.rate / self.pps, 2)
- return str(multiplier)
+ self.min_rate = 0.0
+ else:
+ self.rate = round(float(self.max_rate + self.min_rate) / 2.0,
+ self.RATE_ROUND)
- def start_ixia_latency(self, traffic_generator, ixia_obj,
- mac={}, xfile=None):
traffic = self._get_ixia_traffic_profile(self.full_profile, mac)
- self._ixia_traffic_generate(traffic_generator, traffic,
- ixia_obj, xfile)
+ self._ixia_traffic_generate(traffic, ixia_obj)
+ return first_run
- def get_drop_percentage(self, traffic_generator, samples, tol_min,
- tolerance, ixia_obj, mac={}, xfile=None):
- status = 'Running'
+ def get_drop_percentage(self, samples, tol_min, tolerance,
+ first_run=False):
+ completed = False
drop_percent = 100
- in_packets = sum([samples[iface]['in_packets'] for iface in samples])
- out_packets = sum([samples[iface]['out_packets'] for iface in samples])
- rx_throughput = \
- sum([samples[iface]['RxThroughput'] for iface in samples])
- tx_throughput = \
- sum([samples[iface]['TxThroughput'] for iface in samples])
- packet_drop = abs(out_packets - in_packets)
+ num_ifaces = len(samples)
+ duration = self.config.duration
+ in_packets_sum = sum(
+ [samples[iface]['in_packets'] for iface in samples])
+ out_packets_sum = sum(
+ [samples[iface]['out_packets'] for iface in samples])
+ rx_throughput = sum(
+ [samples[iface]['RxThroughput'] for iface in samples])
+ rx_throughput = round(float(rx_throughput), 2)
+ tx_throughput = sum(
+ [samples[iface]['TxThroughput'] for iface in samples])
+ tx_throughput = round(float(tx_throughput), 2)
+ packet_drop = abs(out_packets_sum - in_packets_sum)
+
try:
- drop_percent = round((packet_drop / float(out_packets)) * 100, 2)
+ drop_percent = round(
+ (packet_drop / float(out_packets_sum)) * 100,
+ self.DROP_PERCENT_ROUND)
except ZeroDivisionError:
LOG.info('No traffic is flowing')
- samples['TxThroughput'] = round(tx_throughput / 1.0, 2)
- samples['RxThroughput'] = round(rx_throughput / 1.0, 2)
- samples['CurrentDropPercentage'] = drop_percent
- samples['Throughput'] = self.tmp_throughput
- samples['DropPercentage'] = self.tmp_drop
- if drop_percent > tolerance and self.tmp_throughput == 0:
- samples['Throughput'] = round(rx_throughput / 1.0, 2)
- samples['DropPercentage'] = drop_percent
- if self.first_run:
- max_supported_rate = out_packets / 30.0
- self.rate = max_supported_rate
- self.first_run = False
- if drop_percent <= tolerance:
- status = 'Completed'
+
+ samples['TxThroughput'] = tx_throughput
+ samples['RxThroughput'] = rx_throughput
+ samples['DropPercentage'] = drop_percent
+
+ if first_run:
+ completed = True if drop_percent <= tolerance else False
+ if (first_run and
+ self.rate_unit == tp_base.TrafficProfileConfig.RATE_FPS):
+ self.rate = float(out_packets_sum) / duration / num_ifaces
+
if drop_percent > tolerance:
self.max_rate = self.rate
elif drop_percent < tol_min:
self.min_rate = self.rate
- if drop_percent >= self.tmp_drop:
- self.tmp_drop = drop_percent
- self.tmp_throughput = round((rx_throughput / 1.0), 2)
- samples['Throughput'] = round(rx_throughput / 1.0, 2)
- samples['DropPercentage'] = drop_percent
else:
- samples['Throughput'] = round(rx_throughput / 1.0, 2)
- samples['DropPercentage'] = drop_percent
- return status, samples
- self.get_multiplier()
- traffic = self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
- self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
- return status, samples
+ completed = True
+
+ return completed, samples