diff options
Diffstat (limited to 'yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py')
-rw-r--r-- | yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py | 160 |
1 files changed, 121 insertions, 39 deletions
diff --git a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py index 6645d45fe..89a855480 100644 --- a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py +++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2018 Intel Corporation +# Copyright (c) 2016-2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ import ipaddress import logging +import re +import collections import IxNetwork @@ -62,6 +64,13 @@ SUPPORTED_TOS_FIELDS = [ 'reliability' ] +IP_PRIORITY_PATTERN = r'[^\w+]*.+(Raw priority|' \ + 'Precedence|' \ + 'Default PHB|' \ + 'Class selector PHB|' \ + 'Assured forwarding selector PHB|' \ + 'Expedited forwarding PHB)' + class Vlan(object): def __init__(self, @@ -85,12 +94,8 @@ class IxNextgen(object): # pragma: no cover "port_name": 'Port Name', "Frames_Tx": 'Frames Tx.', "Valid_Frames_Rx": 'Valid Frames Rx.', - "Frames_Tx_Rate": 'Frames Tx. Rate', - "Valid_Frames_Rx_Rate": 'Valid Frames Rx. Rate', - "Tx_Rate_Kbps": 'Tx. Rate (Kbps)', - "Rx_Rate_Kbps": 'Rx. Rate (Kbps)', - "Tx_Rate_Mbps": 'Tx. Rate (Mbps)', - "Rx_Rate_Mbps": 'Rx. Rate (Mbps)', + "Bytes_Tx": 'Bytes Tx.', + "Bytes_Rx": 'Bytes Rx.' } LATENCY_NAME_MAP = { @@ -99,6 +104,18 @@ class IxNextgen(object): # pragma: no cover "Store-Forward_Max_latency_ns": 'Store-Forward Max Latency (ns)', } + FLOWS_STATS_NAME_MAP = { + "Tx_Port": 'Tx Port', + "VLAN-ID": 'VLAN:VLAN-ID', + "IP_Priority": re.compile(IP_PRIORITY_PATTERN), + "Flow_Group": 'Flow Group', + "Tx_Frames": 'Tx Frames', + "Rx_Frames": 'Rx Frames', + "Store-Forward_Avg_latency_ns": 'Store-Forward Avg Latency (ns)', + "Store-Forward_Min_latency_ns": 'Store-Forward Min Latency (ns)', + "Store-Forward_Max_latency_ns": 'Store-Forward Max Latency (ns)' + } + PPPOX_CLIENT_PER_PORT_NAME_MAP = { 'subs_port': 'Port', 'Sessions_Up': 'Sessions Up', @@ -111,6 +128,18 @@ class IxNextgen(object): # pragma: no cover FLOW_STATISTICS = '::ixNet::OBJ-/statistics/view:"Flow Statistics"' PPPOX_CLIENT_PER_PORT = '::ixNet::OBJ-/statistics/view:"PPPoX Client Per Port"' + PPPOE_SCENARIO_STATS = { + 'port_statistics': PORT_STATISTICS, + 'flow_statistic': FLOW_STATISTICS, + 'pppox_client_per_port': PPPOX_CLIENT_PER_PORT + } + + PPPOE_SCENARIO_STATS_MAP = { + 'port_statistics': PORT_STATS_NAME_MAP, + 'flow_statistic': FLOWS_STATS_NAME_MAP, + 'pppox_client_per_port': PPPOX_CLIENT_PER_PORT_NAME_MAP + } + @staticmethod def get_config(tg_cfg): card = [] @@ -152,6 +181,9 @@ class IxNextgen(object): # pragma: no cover vports = self.ixnet.getList(self.ixnet.getRoot(), 'vport') return vports + def get_static_interface(self, vport): + return self.ixnet.getList(vport, 'interface') + def _get_config_element_by_flow_group_name(self, flow_group_name): """Get a config element using the flow group name @@ -369,7 +401,25 @@ class IxNextgen(object): # pragma: no cover '/traffic/protocolTemplate:"{}"'.format(protocol_name)) self.ixnet.execute('append', previous_element, protocol) - def _setup_config_elements(self, add_default_proto=True): + def is_qinq(self, flow_data): + for traffic_type in flow_data: + if flow_data[traffic_type]['outer_l2'].get('QinQ'): + return True + return False + + def _flows_settings(self, cfg): + flows_data = [] + res = [key for key in cfg.keys() if key.split('_')[0] in ['uplink', 'downlink']] + for i in range(len(res)): + uplink = 'uplink_{}'.format(i) + downlink = 'downlink_{}'.format(i) + if uplink in res: + flows_data.append(cfg[uplink]) + if downlink in res: + flows_data.append(cfg[downlink]) + return flows_data + + def _setup_config_elements(self, traffic_profile, add_default_proto=True): """Setup the config elements The traffic item is configured to allow individual configurations per @@ -385,7 +435,9 @@ class IxNextgen(object): # pragma: no cover 'trafficItem')[0] log.info('Split the frame rate distribution per config element') config_elements = self.ixnet.getList(traffic_item_id, 'configElement') - for config_element in config_elements: + flows = self._flows_settings(traffic_profile.params) + # TODO: check length of both lists, it should be equal!!! + for config_element, flow_data in zip(config_elements, flows): self.ixnet.setAttribute(config_element + '/frameRateDistribution', '-portDistribution', 'splitRateEvenly') self.ixnet.setAttribute(config_element + '/frameRateDistribution', @@ -396,8 +448,13 @@ class IxNextgen(object): # pragma: no cover PROTO_UDP, config_element + '/stack:"ethernet-1"') self._append_procotol_to_stack( PROTO_IPV4, config_element + '/stack:"ethernet-1"') + if self.is_qinq(flow_data): + self._append_procotol_to_stack( + PROTO_VLAN, config_element + '/stack:"ethernet-1"') + self._append_procotol_to_stack( + PROTO_VLAN, config_element + '/stack:"ethernet-1"') - def create_traffic_model(self, uplink_ports, downlink_ports): + def create_traffic_model(self, uplink_ports, downlink_ports, traffic_profile): """Create a traffic item and the needed flow groups Each flow group inside the traffic item (only one is present) @@ -412,9 +469,10 @@ class IxNextgen(object): # pragma: no cover uplink_endpoints = [port + '/protocols' for port in uplink_ports] downlink_endpoints = [port + '/protocols' for port in downlink_ports] self._create_flow_groups(uplink_endpoints, downlink_endpoints) - self._setup_config_elements() + self._setup_config_elements(traffic_profile=traffic_profile) - def create_ipv4_traffic_model(self, uplink_endpoints, downlink_endpoints): + def create_ipv4_traffic_model(self, uplink_endpoints, downlink_endpoints, + traffic_profile): """Create a traffic item and the needed flow groups Each flow group inside the traffic item (only one is present) @@ -427,7 +485,8 @@ class IxNextgen(object): # pragma: no cover """ self._create_traffic_item('ipv4') self._create_flow_groups(uplink_endpoints, downlink_endpoints) - self._setup_config_elements(False) + self._setup_config_elements(traffic_profile=traffic_profile, + add_default_proto=False) def _update_frame_mac(self, ethernet_descriptor, field, mac_address): """Set the MAC address in a config element stack Ethernet field @@ -494,11 +553,6 @@ class IxNextgen(object): # pragma: no cover '-fieldValue', ETHER_TYPE_802_1ad, '-valueType', SINGLE_VALUE) - self._append_procotol_to_stack( - PROTO_VLAN, config_element + '/stack:"ethernet-1"') - self._append_procotol_to_stack( - PROTO_VLAN, config_element + '/stack:"ethernet-1"') - self._update_vlan_tag(fg_id, s_vlan, S_VLAN) self._update_vlan_tag(fg_id, c_vlan, C_VLAN) @@ -728,6 +782,19 @@ class IxNextgen(object): # pragma: no cover 'getColumnValues', view_obj, data_ixia) for data_yardstick, data_ixia in name_map.items()} + def _get_view_page_stats(self, view_obj): + """Get full view page stats + + :param view_obj: view object, e.g. + '::ixNet::OBJ-/statistics/view:"Port Statistics"' + :return: (list) List of dicts. Each dict represents view page row + """ + view = view_obj + '/page' + column_headers = self.ixnet.getAttribute(view, '-columnCaptions') + view_rows = self.ixnet.getAttribute(view, '-rowValues') + view_page = [dict(zip(column_headers, row[0])) for row in view_rows] + return view_page + def _set_egress_flow_tracking(self, encapsulation, offset): """Set egress flow tracking options @@ -750,7 +817,7 @@ class IxNextgen(object): # pragma: no cover self.ixnet.setAttribute(enc_obj, '-offset', offset) self.ixnet.commit() - def _set_flow_tracking(self, track_by): + def set_flow_tracking(self, track_by): """Set flow tracking options :param track_by: list of tracking fields @@ -777,24 +844,39 @@ class IxNextgen(object): # pragma: no cover return stats def get_pppoe_scenario_statistics(self): - """Retrieve port, flow and PPPoE subscribers statistics - - "Port Statistics" parameters are stored in self.PORT_STATS_NAME_MAP. - "Flow Statistics" parameters are stored in self.LATENCY_NAME_MAP. - "PPPoX Client Per Port" parameters are stored in - self.PPPOE_CLIENT_PER_PORT_NAME_MAP - - :return: dictionary with the statistics; the keys of this dictionary - are PORT_STATS_NAME_MAP, LATENCY_NAME_MAP and - PPPOE_CLIENT_PER_PORT_NAME_MAP keys. - """ - stats = self._build_stats_map(self.PORT_STATISTICS, - self.PORT_STATS_NAME_MAP) - stats.update(self._build_stats_map(self.FLOW_STATISTICS, - self.LATENCY_NAME_MAP)) - stats.update(self._build_stats_map(self.PPPOX_CLIENT_PER_PORT, - self.PPPOX_CLIENT_PER_PORT_NAME_MAP)) - return stats + """Retrieve port, flow and PPPoE subscribers statistics""" + stats = collections.defaultdict(list) + result = collections.defaultdict(list) + for stat, view in self.PPPOE_SCENARIO_STATS.items(): + # Get view total pages number + total_pages = self.ixnet.getAttribute( + view + '/page', '-totalPages') + # Collect stats from all view pages + for page in range(1, int(total_pages) + 1): + current_page = int(self.ixnet.getAttribute( + view + '/page', '-currentPage')) + if page != int(current_page): + self.ixnet.setAttribute(view + '/page', '-currentPage', + str(page)) + self.ixnet.commit() + page_data = self._get_view_page_stats(view) + stats[stat].extend(page_data) + # Filter collected views stats + for stat in stats: + for view_row in stats[stat]: + filtered_row = {} + for key, value in self.PPPOE_SCENARIO_STATS_MAP[stat].items(): + if isinstance(value, str): + filtered_row.update({key: view_row[value]}) + # Handle keys which values are represented by regex + else: + for k in view_row.keys(): + if value.match(k): + value = value.match(k).group() + filtered_row.update({key: view_row[value]}) + break + result[stat].append(filtered_row) + return result def start_protocols(self): self.ixnet.execute('startAllProtocols') @@ -1038,7 +1120,7 @@ class IxNextgen(object): # pragma: no cover return obj - def add_static_ipv4(self, iface, vport, start_ip, count): + def add_static_ipv4(self, iface, vport, start_ip, count, mask='24'): """Add static IP range to the interface""" log.debug("add_static_ipv4: start_ip:'%s', count:'%s'", start_ip, count) @@ -1046,5 +1128,5 @@ class IxNextgen(object): # pragma: no cover self.ixnet.setMultiAttribute(obj, '-protocolInterface', iface, '-ipStart', start_ip, '-count', count, - '-enabled', 'true') + '-mask', mask, '-enabled', 'true') self.ixnet.commit() |