summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yardstick/common/exceptions.py12
-rw-r--r--yardstick/network_services/libs/ixia_libs/ixnet/__init__.py (renamed from yardstick/network_services/libs/ixia_libs/IxNet/__init__.py)0
-rw-r--r--yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py (renamed from yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py)359
-rw-r--r--yardstick/network_services/traffic_profile/ixia_rfc2544.py3
-rw-r--r--yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py26
-rw-r--r--yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py973
-rw-r--r--yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py406
7 files changed, 621 insertions, 1158 deletions
diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py
index 0b1698289..966b15cf8 100644
--- a/yardstick/common/exceptions.py
+++ b/yardstick/common/exceptions.py
@@ -297,3 +297,15 @@ class ScenarioCreateImageError(YardstickException):
class ScenarioDeleteImageError(YardstickException):
message = 'Glance Delete Image Scenario failed'
+
+
+class IxNetworkClientNotConnected(YardstickException):
+ message = 'IxNetwork client not connected to a TCL server'
+
+
+class IxNetworkFlowNotPresent(YardstickException):
+ message = 'Flow Group "%(flow_group)s" is not present'
+
+
+class IxNetworkFieldNotPresentInStackItem(YardstickException):
+ message = 'Field "%(field_name)s" not present in stack item %(stack_item)s'
diff --git a/yardstick/network_services/libs/ixia_libs/IxNet/__init__.py b/yardstick/network_services/libs/ixia_libs/ixnet/__init__.py
index e69de29bb..e69de29bb 100644
--- a/yardstick/network_services/libs/ixia_libs/IxNet/__init__.py
+++ b/yardstick/network_services/libs/ixia_libs/ixnet/__init__.py
diff --git a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
index 0cf2a4126..70d0eeed8 100644
--- a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py
+++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
@@ -14,10 +14,10 @@
import logging
-import re
-from itertools import product
import IxNetwork
+from yardstick.common import exceptions
+
log = logging.getLogger(__name__)
@@ -30,57 +30,8 @@ PROTO_TCP = 'tcp'
PROTO_VLAN = 'vlan'
-class TrafficStreamHelper(object):
-
- TEMPLATE = '{0.traffic_item}/{0.stream}:{0.param_id}/{1}'
-
- def __init__(self, traffic_item, stream, param_id):
- super(TrafficStreamHelper, self).__init__()
- self.traffic_item = traffic_item
- self.stream = stream
- self.param_id = param_id
-
- def __getattr__(self, item):
- return self.TEMPLATE.format(self, item)
-
-
-class FramesizeHelper(object):
-
- def __init__(self):
- super(FramesizeHelper, self).__init__()
- self.weighted_pairs = []
- self.weighted_range_pairs = []
-
- @property
- def weighted_pairs_arg(self):
- return '-weightedPairs', self.weighted_pairs
-
- @property
- def weighted_range_pairs_arg(self):
- return '-weightedRangePairs', self.weighted_range_pairs
-
- def make_args(self, *args):
- return self.weighted_pairs_arg + self.weighted_range_pairs_arg + args
-
- def populate_data(self, framesize_data):
- for key, value in framesize_data.items():
- if value == '0':
- continue
-
- replaced = re.sub('[Bb]', '', key)
- self.weighted_pairs.extend([
- replaced,
- value,
- ])
- pairs = [
- replaced,
- replaced,
- value,
- ]
- self.weighted_range_pairs.append(pairs)
-
-
-class IxNextgen(object):
+# NOTE(ralonsoh): this pragma will be removed in the last patch of this series
+class IxNextgen(object): # pragma: no cover
PORT_STATS_NAME_MAP = {
"stat_name": 'Stat Name',
@@ -135,59 +86,61 @@ class IxNextgen(object):
return cfg
- def __init__(self, ixnet=None):
- self.ixnet = ixnet
- self._objRefs = dict()
+ def __init__(self): # pragma: no cover
+ self._ixnet = None
self._cfg = None
self._params = None
self._bidir = None
+ @property
+ def ixnet(self): # pragma: no cover
+ if self._ixnet:
+ return self._ixnet
+ raise exceptions.IxNetworkClientNotConnected()
+
+ def _get_config_element_by_flow_group_name(self, flow_group_name):
+ """Get a config element using the flow group name
+
+ Each named flow group contains one config element (by configuration).
+ According to the documentation, "configElements" is a list and "each
+ item in this list is aligned to the sequential order of your endpoint
+ list".
+
+ :param flow_group_name: (str) flow group name; this parameter is
+ always a number (converted to string) starting
+ from "1".
+ :return: (str) config element reference ID or None.
+ """
+ traffic_item = self.ixnet.getList(self.ixnet.getRoot() + '/traffic',
+ 'trafficItem')[0]
+ flow_groups = self.ixnet.getList(traffic_item, 'endpointSet')
+ for flow_group in flow_groups:
+ if (str(self.ixnet.getAttribute(flow_group, '-name')) ==
+ flow_group_name):
+ return traffic_item + '/configElement:' + flow_group_name
+
+ @staticmethod
+ def _parse_framesize(framesize):
+ """Parse "framesize" config param. to return a list of weighted pairs
+
+ :param framesize: dictionary of frame sizes and weights
+ :return: list of paired frame sizes and weights
+ """
+ weighted_range_pairs = []
+ for size, weight in framesize.items():
+ weighted_range_pairs.append(int(size.upper().replace('B', '')))
+ weighted_range_pairs.append(int(weight))
+ return weighted_range_pairs
+
def iter_over_get_lists(self, x1, x2, y2, offset=0):
for x in self.ixnet.getList(x1, x2):
y_list = self.ixnet.getList(x, y2)
for i, y in enumerate(y_list, offset):
yield x, y, i
- def set_random_ip_multi_attribute(self, ipv4, seed, fixed_bits, random_mask, l3_count):
- self.ixnet.setMultiAttribute(
- ipv4,
- '-seed', str(seed),
- '-fixedBits', str(fixed_bits),
- '-randomMask', str(random_mask),
- '-valueType', 'random',
- '-countValue', str(l3_count))
-
- def set_random_ip_multi_attributes(self, ip, version, seeds, l3):
- try:
- random_mask = self.RANDOM_MASK_MAP[version]
- except KeyError:
- raise ValueError('Unknown version %s' % version)
-
- l3_count = l3['count']
- if "srcIp" in ip:
- fixed_bits = l3['srcip4']
- self.set_random_ip_multi_attribute(ip, seeds[0], fixed_bits, random_mask, l3_count)
- if "dstIp" in ip:
- fixed_bits = l3['dstip4']
- self.set_random_ip_multi_attribute(ip, seeds[1], fixed_bits, random_mask, l3_count)
-
- def add_ip_header(self, params, version):
- for _, ep, i in self.iter_over_get_lists('/traffic', 'trafficItem', "configElement", 1):
- iter1 = (v['outer_l3'] for v in params.values() if str(v['id']) == str(i))
- try:
- l3 = next(iter1, {})
- seeds = self.MODE_SEEDS_MAP.get(i, self.MODE_SEEDS_DEFAULT)[1]
- except (KeyError, IndexError):
- continue
-
- for _, ip_bits, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
- self.set_random_ip_multi_attributes(ip_bits, version, seeds, l3)
-
- self.ixnet.commit()
-
def connect(self, tg_cfg):
self._cfg = self.get_config(tg_cfg)
- self.ixnet = IxNetwork.IxNet()
+ self._ixnet = IxNetwork.IxNet()
machine = self._cfg['machine']
port = str(self._cfg['port'])
@@ -255,19 +208,21 @@ class IxNextgen(object):
vports = self.ixnet.getList(self.ixnet.getRoot(), 'vport')
uplink_ports = vports[::2]
downlink_ports = vports[1::2]
+ index = 0
for up, down in zip(uplink_ports, downlink_ports):
log.info('FGs: %s <--> %s', up, down)
endpoint_set_1 = self.ixnet.add(traffic_item_id, 'endpointSet')
endpoint_set_2 = self.ixnet.add(traffic_item_id, 'endpointSet')
self.ixnet.setMultiAttribute(
- endpoint_set_1,
- '-sources', [up + ' /protocols'],
+ endpoint_set_1, '-name', str(index + 1),
+ '-sources', [up + '/protocols'],
'-destinations', [down + '/protocols'])
self.ixnet.setMultiAttribute(
- endpoint_set_2,
- '-sources', [down + ' /protocols'],
+ endpoint_set_2, '-name', str(index + 2),
+ '-sources', [down + '/protocols'],
'-destinations', [up + '/protocols'])
self.ixnet.commit()
+ index += 2
def _append_procotol_to_stack(self, protocol_name, previous_element):
"""Append a new element in the packet definition stack"""
@@ -317,87 +272,134 @@ class IxNextgen(object):
self._create_flow_groups()
self._setup_config_elements()
- def ix_update_frame(self, params):
- streams = ["configElement"]
-
- for param in params.values():
- framesize_data = FramesizeHelper()
- traffic_items = self.ixnet.getList('/traffic', 'trafficItem')
- param_id = param['id']
- for traffic_item, stream in product(traffic_items, streams):
- helper = TrafficStreamHelper(traffic_item, stream, param_id)
-
- self.ixnet.setMultiAttribute(helper.transmissionControl,
- '-type', '{0}'.format(param.get('traffic_type',
- 'fixedDuration')),
- '-duration', '{0}'.format(param.get('duration',
- "30")))
-
- stream_frame_rate_path = helper.frameRate
- self.ixnet.setMultiAttribute(stream_frame_rate_path, '-rate', param['iload'])
- if param['outer_l2']['framesPerSecond']:
- self.ixnet.setMultiAttribute(stream_frame_rate_path,
- '-type', 'framesPerSecond')
-
- framesize_data.populate_data(param['outer_l2']['framesize'])
-
- make_attr_args = framesize_data.make_args('-incrementFrom', '66',
- '-randomMin', '66',
- '-quadGaussian', [],
- '-type', 'weightedPairs',
- '-presetDistribution', 'cisco',
- '-incrementTo', '1518')
-
- self.ixnet.setMultiAttribute(helper.frameSize, *make_attr_args)
-
- self.ixnet.commit()
-
- def update_ether_multi_attribute(self, ether, mac_addr):
- self.ixnet.setMultiAttribute(ether,
- '-singleValue', mac_addr,
- '-fieldValue', mac_addr,
+ def _get_field_in_stack_item(self, stack_item, field_name):
+ """List all fields in a stack item an return t
+
+ :param stack_item: (str) stack item descriptor
+ :param field_name: (str) field name
+ :return: (str) field descriptor
+ """
+ fields = self.ixnet.getList(stack_item, 'field')
+ for field in (field for field in fields if field_name in field):
+ return field
+ raise exceptions.IxNetworkFieldNotPresentInStackItem(
+ field_name=field_name, stack_item=stack_item)
+
+ def _update_frame_mac(self, ethernet_descriptor, field, mac_address):
+ """Set the MAC address in a config element stack Ethernet field
+
+ :param ethernet_descriptor: (str) ethernet descriptor, e.g.:
+ /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"
+ :param field: (str) field name, e.g.: destinationAddress
+ :param mac_address: (str) MAC address
+ """
+ field_descriptor = self._get_field_in_stack_item(ethernet_descriptor,
+ field)
+ self.ixnet.setMultiAttribute(field_descriptor,
+ '-singleValue', mac_address,
+ '-fieldValue', mac_address,
'-valueType', 'singleValue')
+ self.ixnet.commit()
- def update_ether_multi_attributes(self, ether, l2):
- if "ethernet.header.destinationAddress" in ether:
- self.update_ether_multi_attribute(ether, str(l2.get('dstmac', "00:00:00:00:00:02")))
+ def update_frame(self, traffic):
+ """Update the L2 frame
- if "ethernet.header.sourceAddress" in ether:
- self.update_ether_multi_attribute(ether, str(l2.get('srcmac', "00:00:00:00:00:01")))
+ This function updates the L2 frame options:
+ - Traffic type: "continuous", "fixedDuration".
+ - Duration: in case of traffic_type="fixedDuration", amount of seconds
+ to inject traffic.
+ - Rate: in frames per seconds or percentage.
+ - Type of rate: "framesPerSecond" ("bitsPerSecond" and
+ "percentLineRate" no used)
+ - Frame size: custom IMIX [1] definition; a list of packet size in
+ bytes and the weight. E.g.:
+ [64, 10, 128, 15, 512, 5]
- def ix_update_ether(self, params):
- for _, ep, index in self.iter_over_get_lists('/traffic', 'trafficItem',
- "configElement", 1):
- iter1 = (v['outer_l2'] for v in params.values() if str(v['id']) == str(index))
- try:
- l2 = next(iter1, {})
- except KeyError:
- continue
+ [1] https://en.wikipedia.org/wiki/Internet_Mix
- for _, ether, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
- self.update_ether_multi_attributes(ether, l2)
+ :param traffic: list of traffic elements; each traffic element contains
+ the injection parameter for each flow group.
+ """
+ for traffic_param in traffic.values():
+ config_element = self._get_config_element_by_flow_group_name(
+ str(traffic_param['id']))
+ if not config_element:
+ raise exceptions.IxNetworkFlowNotPresent(
+ flow_group=traffic_param['id'])
+
+ type = traffic_param.get('traffic_type', 'fixedDuration')
+ duration = traffic_param.get('duration', 30)
+ rate = traffic_param['iload']
+ weighted_range_pairs = self._parse_framesize(
+ traffic_param['outer_l2']['framesize'])
+ srcmac = str(traffic_param.get('srcmac', '00:00:00:00:00:01'))
+ dstmac = str(traffic_param.get('dstmac', '00:00:00:00:00:02'))
+ # NOTE(ralonsoh): add QinQ tagging when
+ # traffic_param['outer_l2']['QinQ'] exists.
+ # s_vlan = traffic_param['outer_l2']['QinQ']['S-VLAN']
+ # c_vlan = traffic_param['outer_l2']['QinQ']['C-VLAN']
- self.ixnet.commit()
+ self.ixnet.setMultiAttribute(
+ config_element + '/transmissionControl',
+ '-type', type, '-duration', duration)
+ self.ixnet.setMultiAttribute(
+ config_element + '/frameRate',
+ '-rate', rate, '-type', 'framesPerSecond')
+ self.ixnet.setMultiAttribute(
+ config_element + '/frameSize',
+ '-type', 'weightedPairs',
+ '-weightedRangePairs', weighted_range_pairs)
+ self.ixnet.commit()
- def ix_update_udp(self, params):
- pass
+ self._update_frame_mac(
+ config_element + '/stack:"ethernet-1"',
+ 'destinationAddress', dstmac)
+ self._update_frame_mac(
+ config_element + '/stack:"ethernet-1"',
+ 'sourceAddress', srcmac)
- def ix_update_tcp(self, params):
- pass
+ def set_random_ip_multi_attribute(self, ipv4, seed, fixed_bits, random_mask, l3_count):
+ self.ixnet.setMultiAttribute(
+ ipv4,
+ '-seed', str(seed),
+ '-fixedBits', str(fixed_bits),
+ '-randomMask', str(random_mask),
+ '-valueType', 'random',
+ '-countValue', str(l3_count))
- def ix_start_traffic(self):
- tis = self.ixnet.getList('/traffic', 'trafficItem')
- for ti in tis:
- self.ixnet.execute('generate', [ti])
- self.ixnet.execute('apply', '/traffic')
- self.ixnet.execute('start', '/traffic')
+ # NOTE(ralonsoh): to be updated in next patchset
+ # pragma: no cover
+ def set_random_ip_multi_attributes(self, ip, version, seeds, l3):
+ try:
+ random_mask = self.RANDOM_MASK_MAP[version]
+ except KeyError:
+ raise ValueError('Unknown version %s' % version)
- def ix_stop_traffic(self):
- tis = self.ixnet.getList('/traffic', 'trafficItem')
- for _ in tis:
- self.ixnet.execute('stop', '/traffic')
+ l3_count = l3['count']
+ if 'srcIp' in ip:
+ fixed_bits = l3['srcip4']
+ self.set_random_ip_multi_attribute(ip, seeds[0], fixed_bits, random_mask, l3_count)
+ if 'dstIp' in ip:
+ fixed_bits = l3['dstip4']
+ self.set_random_ip_multi_attribute(ip, seeds[1], fixed_bits, random_mask, l3_count)
+
+ # NOTE(ralonsoh): to be updated in next patchset
+ # pragma: no cover
+ def add_ip_header(self, params, version):
+ for _, ep, i in self.iter_over_get_lists('/traffic', 'trafficItem', "configElement", 1):
+ iter1 = (v['outer_l3'] for v in params.values() if str(v['id']) == str(i))
+ try:
+ l3 = next(iter1, {})
+ seeds = self.MODE_SEEDS_MAP.get(i, self.MODE_SEEDS_DEFAULT)[1]
+ except (KeyError, IndexError):
+ continue
- def build_stats_map(self, view_obj, name_map):
+ for _, ip_bits, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
+ self.set_random_ip_multi_attributes(ip_bits, version, seeds, l3)
+
+ self.ixnet.commit()
+
+ def _build_stats_map(self, view_obj, name_map):
return {data_yardstick: self.ixnet.execute(
'getColumnValues', view_obj, data_ixia)
for data_yardstick, data_ixia in name_map.items()}
@@ -413,7 +415,24 @@ class IxNextgen(object):
"""
port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
- stats = self.build_stats_map(port_statistics, self.PORT_STATS_NAME_MAP)
- stats.update(self.build_stats_map(flow_statistics,
+ stats = self._build_stats_map(port_statistics,
+ self.PORT_STATS_NAME_MAP)
+ stats.update(self._build_stats_map(flow_statistics,
self.LATENCY_NAME_MAP))
return stats
+
+ # NOTE(ralonsoh): to be updated in next patchset
+ # pragma: no cover
+ def ix_start_traffic(self):
+ tis = self.ixnet.getList('/traffic', 'trafficItem')
+ for ti in tis:
+ self.ixnet.execute('generate', [ti])
+ self.ixnet.execute('apply', '/traffic')
+ self.ixnet.execute('start', '/traffic')
+
+ # NOTE(ralonsoh): to be updated in next patchset
+ # pragma: no cover
+ def ix_stop_traffic(self):
+ tis = self.ixnet.getList('/traffic', 'trafficItem')
+ for _ in tis:
+ self.ixnet.execute('stop', '/traffic')
diff --git a/yardstick/network_services/traffic_profile/ixia_rfc2544.py b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
index 7f047226b..ec354c8df 100644
--- a/yardstick/network_services/traffic_profile/ixia_rfc2544.py
+++ b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
@@ -83,8 +83,7 @@ class IXIARFC2544Profile(TrexProfile):
for key, value in traffic.items():
if key.startswith((self.UPLINK, self.DOWNLINK)):
value["iload"] = str(self.rate)
- ixia_obj.ix_update_frame(traffic)
- ixia_obj.ix_update_ether(traffic)
+ ixia_obj.update_frame(traffic)
ixia_obj.add_ip_header(traffic, 4)
ixia_obj.ix_start_traffic()
self.tmp_drop = 0
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
index f8799c88b..deb0a8023 100644
--- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
+++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
@@ -74,8 +74,6 @@ class IxiaResourceHelper(ClientResourceHelper):
def generate_samples(self, ports, key=None, default=None):
stats = self.get_stats()
- last_result = stats[1]
- latency = stats[0]
samples = {}
# this is not DPDK port num, but this is whatever number we gave
@@ -86,19 +84,21 @@ class IxiaResourceHelper(ClientResourceHelper):
intf = self.vnfd_helper.find_interface_by_port(port_num)
port_name = intf["name"]
samples[port_name] = {
- "rx_throughput_kps": float(last_result["Rx_Rate_Kbps"][port_num]),
- "tx_throughput_kps": float(last_result["Tx_Rate_Kbps"][port_num]),
- "rx_throughput_mbps": float(last_result["Rx_Rate_Mbps"][port_num]),
- "tx_throughput_mbps": float(last_result["Tx_Rate_Mbps"][port_num]),
- "in_packets": int(last_result["Valid_Frames_Rx"][port_num]),
- "out_packets": int(last_result["Frames_Tx"][port_num]),
- "RxThroughput": int(last_result["Valid_Frames_Rx"][port_num]) / 30,
- "TxThroughput": int(last_result["Frames_Tx"][port_num]) / 30,
+ "rx_throughput_kps": float(stats["Rx_Rate_Kbps"][port_num]),
+ "tx_throughput_kps": float(stats["Tx_Rate_Kbps"][port_num]),
+ "rx_throughput_mbps": float(stats["Rx_Rate_Mbps"][port_num]),
+ "tx_throughput_mbps": float(stats["Tx_Rate_Mbps"][port_num]),
+ "in_packets": int(stats["Valid_Frames_Rx"][port_num]),
+ "out_packets": int(stats["Frames_Tx"][port_num]),
+ # NOTE(ralonsoh): we need to make the traffic injection
+ # time variable.
+ "RxThroughput": int(stats["Valid_Frames_Rx"][port_num]) / 30,
+ "TxThroughput": int(stats["Frames_Tx"][port_num]) / 30,
}
if key:
- avg_latency = latency["Store-Forward_Avg_latency_ns"][port_num]
- min_latency = latency["Store-Forward_Min_latency_ns"][port_num]
- max_latency = latency["Store-Forward_Max_latency_ns"][port_num]
+ avg_latency = stats["Store-Forward_Avg_latency_ns"][port_num]
+ min_latency = stats["Store-Forward_Min_latency_ns"][port_num]
+ max_latency = stats["Store-Forward_Max_latency_ns"][port_num]
samples[port_name][key] = \
{"Store-Forward_Avg_latency_ns": avg_latency,
"Store-Forward_Min_latency_ns": min_latency,
diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
deleted file mode 100644
index deae69314..000000000
--- a/yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
+++ /dev/null
@@ -1,973 +0,0 @@
-# Copyright (c) 2016-2017 Intel Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import mock
-import IxNetwork
-import unittest
-
-from yardstick.network_services.libs.ixia_libs.IxNet import IxNet
-
-
-UPLINK = 'uplink'
-DOWNLINK = 'downlink'
-
-
-class TestIxNextgen(unittest.TestCase):
-
- def setUp(self):
- self.ixnet = mock.Mock()
- self.ixnet.execute = mock.Mock()
-
- def test___init__(self):
- ixnet_gen = IxNet.IxNextgen()
- self.assertIsNone(ixnet_gen.ixnet)
- self.assertTrue(isinstance(ixnet_gen._objRefs, dict))
- self.assertIsNone(ixnet_gen._cfg)
- self.assertIsNone(ixnet_gen._params)
- self.assertIsNone(ixnet_gen._bidir)
-
- def test___init__ixnet(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- self.assertIsNotNone(ixnet_gen.ixnet)
-
- @mock.patch.object(IxNetwork, 'IxNet')
- def test_connect(self, mock_ixnet):
- mock_ixnet.return_value = self.ixnet
- ixnet_gen = IxNet.IxNextgen()
- with mock.patch.object(ixnet_gen, 'get_config') as mock_config:
- mock_config.return_value = {'machine': 'machine_fake',
- 'port': 'port_fake',
- 'version': 12345}
- ixnet_gen.connect(mock.ANY)
-
- self.ixnet.connect.assert_called_once_with(
- 'machine_fake', '-port', 'port_fake', '-version', '12345')
- mock_config.assert_called_once()
-
- def test_connect_invalid_config_no_machine(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.get_config = mock.Mock(return_value={
- 'port': 'port_fake',
- 'version': '12345'})
- self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
- self.ixnet.connect.assert_not_called()
-
- def test_connect_invalid_config_no_port(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.get_config = mock.Mock(return_value={
- 'machine': 'machine_fake',
- 'version': '12345'})
- self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
- self.ixnet.connect.assert_not_called()
-
- def test_connect_invalid_config_no_version(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.get_config = mock.Mock(return_value={
- 'machine': 'machine_fake',
- 'port': 'port_fake'})
- self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
- self.ixnet.connect.assert_not_called()
-
- def test_connect_no_config(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.get_config = mock.Mock(return_value={})
- self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
- self.ixnet.connect.assert_not_called()
-
- def test_clear_config(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.clear_config()
- self.ixnet.execute.assert_called_once_with('newConfig')
-
- def test_assign_ports_2_ports(self):
- self.ixnet.getAttribute.side_effect = ['up', 'down']
-
- config = {
- 'chassis': '1.1.1.1',
- 'cards': ['1', '2'],
- 'ports': ['2', '2'],
- }
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen._cfg = config
-
- self.assertIsNone(ixnet_gen.assign_ports())
-
- self.assertEqual(self.ixnet.execute.call_count, 2)
- self.assertEqual(self.ixnet.commit.call_count, 4)
- self.assertEqual(self.ixnet.getAttribute.call_count, 2)
-
- @mock.patch.object(IxNet, 'log')
- def test_assign_ports_port_down(self, mock_log):
- self.ixnet.getAttribute.return_value = 'down'
-
- config = {
- 'chassis': '1.1.1.1',
- 'cards': ['1', '2'],
- 'ports': ['3', '4'],
- }
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen._cfg = config
- ixnet_gen.assign_ports()
- mock_log.warning.assert_called()
-
- def test_assign_ports_no_config(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen._cfg = {}
-
- self.assertRaises(KeyError, ixnet_gen.assign_ports)
-
- def test__create_traffic_item(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- self.ixnet.getRoot.return_value = 'rootyrootroot'
- self.ixnet.add.return_value = 'my_new_traffic_item'
- self.ixnet.remapIds.return_value = ['my_traffic_item_id']
-
- ixnet_gen._create_traffic_item()
-
- self.ixnet.add.assert_called_once_with(
- 'rootyrootroot/traffic', 'trafficItem')
- self.ixnet.setMultiAttribute.assert_called_once_with(
- 'my_new_traffic_item', '-name', 'RFC2544', '-trafficType', 'raw')
- self.assertEqual(2, self.ixnet.commit.call_count)
- self.ixnet.remapIds.assert_called_once_with('my_new_traffic_item')
- self.ixnet.setAttribute('my_traffic_item_id/tracking',
- '-trackBy', 'trafficGroupId0')
-
- def test__create_flow_groups(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- self.ixnet.getRoot.return_value = 'rootyrootroot'
- ixnet_gen.ixnet.getList.side_effect = [['traffic_item'], ['1', '2']]
- ixnet_gen.ixnet.add.side_effect = ['endp1', 'endp2']
- ixnet_gen._create_flow_groups()
- ixnet_gen.ixnet.add.assert_has_calls([
- mock.call('traffic_item', 'endpointSet'),
- mock.call('traffic_item', 'endpointSet')])
- ixnet_gen.ixnet.setMultiAttribute.asser_has_calls([
- mock.call('endp1', '-sources', ['1/protocols'], '-destinations',
- ['2/protocols']),
- mock.call('endp2', '-sources', ['2/protocols'], '-destinations',
- ['1/protocols'])])
-
- def test__append_protocol_to_stack(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- self.ixnet.getRoot.return_value = 'my_root'
-
- ixnet_gen._append_procotol_to_stack('my_protocol', 'prev_element')
- self.ixnet.execute.assert_called_with(
- 'append', 'prev_element',
- 'my_root/traffic/protocolTemplate:"my_protocol"')
-
- def test__setup_config_elements(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
- ixnet_gen.ixnet.getRoot.return_value = 'root_element'
- ixnet_gen.ixnet.getList.side_effect = [['traffic_item'],
- ['cfg_element']]
- with mock.patch.object(ixnet_gen, '_append_procotol_to_stack') as \
- mock_append_proto:
- ixnet_gen._setup_config_elements()
- mock_append_proto.assert_has_calls([
- mock.call(IxNet.PROTO_UDP, 'cfg_element/stack:"ethernet-1"'),
- mock.call(IxNet.PROTO_IPV4, 'cfg_element/stack:"ethernet-1"')])
- ixnet_gen.ixnet.setAttribute.assert_has_calls([
- mock.call('cfg_element/frameRateDistribution', '-portDistribution',
- 'splitRateEvenly'),
- mock.call('cfg_element/frameRateDistribution',
- '-streamDistribution', 'splitRateEvenly')])
-
- @mock.patch.object(IxNet.IxNextgen, '_create_traffic_item')
- @mock.patch.object(IxNet.IxNextgen, '_create_flow_groups')
- @mock.patch.object(IxNet.IxNextgen, '_setup_config_elements')
- def test_create_traffic_model(self, mock__setup_config_elements,
- mock__create_flow_groups,
- mock__create_traffic_item):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- ixnet_gen.create_traffic_model()
- mock__create_traffic_item.assert_called_once()
- mock__create_flow_groups.assert_called_once()
- mock__setup_config_elements.assert_called_once()
-
- def test_ix_update_frame(self):
- static_traffic_params = {
- UPLINK: {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": {
- "64B": "100",
- "1KB": "0",
- },
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- DOWNLINK: {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": False,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.remapIds.return_value = ["0"]
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
- self.ixnet.getList.side_effect = [
- [1],
- [1],
- [1],
- [
- "ethernet.header.destinationAddress",
- "ethernet.header.sourceAddress",
- ],
- ]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_update_frame(static_traffic_params)
- self.assertIsNone(result)
- self.assertEqual(self.ixnet.setMultiAttribute.call_count, 7)
- self.assertEqual(self.ixnet.commit.call_count, 2)
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_update_ether_multi_attribute(self):
- pass
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_update_ether_multi_attributes(self):
- pass
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_update_ether(self):
- pass
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_ix_update_udp(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_update_udp({})
- self.assertIsNone(result)
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_ix_update_tcp(self):
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_update_tcp({})
- self.assertIsNone(result)
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_ix_start_traffic(self):
- self.ixnet.getList.return_value = [0]
- self.ixnet.getAttribute.return_value = 'down'
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_start_traffic()
- self.assertIsNone(result)
- self.ixnet.getList.assert_called_once()
- self.assertEqual(self.ixnet.execute.call_count, 3)
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_ix_stop_traffic(self):
- self.ixnet.getList.return_value = [0]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_stop_traffic()
- self.assertIsNone(result)
- self.ixnet.getList.assert_called_once()
- self.ixnet.execute.assert_called_once()
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_build_stats_map(self):
- pass
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_get_statistics(self):
- self.ixnet.execute.return_value = ""
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.get_statistics()
- self.assertIsNotNone(result)
- self.assertEqual(self.ixnet.execute.call_count, 12)
-
- # NOTE(ralonsoh): to be updated in next patchset
- def test_add_ip_header_v4(self):
- static_traffic_params = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "count": 1024,
- "ttl": 32
- },
- "outer_l3v4": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.remapIds.return_value = ["0"]
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
- self.ixnet.getList.side_effect = [[1], [0], [0], ["srcIp", "dstIp"]]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.add_ip_header(static_traffic_params,
- IxNet.IP_VERSION_4)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_called()
- self.ixnet.commit.assert_called_once()
-
- def test_add_ip_header_v4_nothing_to_do(self):
- static_traffic_params = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "count": 1024,
- "ttl": 32
- },
- "outer_l3v4": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.remapIds.return_value = ["0"]
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
- self.ixnet.getList.side_effect = [[1], [0, 1], [0], ["srcIp", "dstIp"]]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.add_ip_header(static_traffic_params,
- IxNet.IP_VERSION_4)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_called()
- self.ixnet.commit.assert_called_once()
-
- def test_add_ip_header_v6(self):
- static_traffic_profile = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.getList.side_effect = [[1], [1], [1], ["srcIp", "dstIp"]]
- self.ixnet.remapIds.return_value = ["0"]
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.add_ip_header(static_traffic_profile,
- IxNet.IP_VERSION_6)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_called()
- self.ixnet.commit.assert_called_once()
-
- def test_add_ip_header_v6_nothing_to_do(self):
- static_traffic_params = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "count": 1024,
- "ttl": 32
- },
- "outer_l3v6": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": True,
- "framesize": {"64B": "100"},
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.getList.side_effect = [[1], [0, 1], [1], ["srcIP", "dstIP"]]
- self.ixnet.remapIds.return_value = ["0"]
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.add_ip_header(static_traffic_params,
- IxNet.IP_VERSION_6)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_not_called()
-
- def test_set_random_ip_multi_attributes_bad_ip_version(self):
- bad_ip_version = object()
- ixnet_gen = IxNet.IxNextgen(mock.Mock())
- with self.assertRaises(ValueError):
- ixnet_gen.set_random_ip_multi_attributes(
- mock.Mock(), bad_ip_version, mock.Mock(), mock.Mock())
-
- def test_get_config(self):
- tg_cfg = {
- "vdu": [
- {
- "external-interface": [
- {
- "virtual-interface": {
- "vpci": "0000:07:00.1",
- },
- },
- {
- "virtual-interface": {
- "vpci": "0001:08:01.2",
- },
- },
- ],
- },
- ],
- "mgmt-interface": {
- "ip": "test1",
- "tg-config": {
- "dut_result_dir": "test2",
- "version": "test3",
- "ixchassis": "test4",
- "tcl_port": "test5",
- },
- }
- }
-
- expected = {
- 'machine': 'test1',
- 'port': 'test5',
- 'chassis': 'test4',
- 'cards': ['0000', '0001'],
- 'ports': ['07', '08'],
- 'output_dir': 'test2',
- 'version': 'test3',
- 'bidir': True,
- }
-
- result = IxNet.IxNextgen.get_config(tg_cfg)
- self.assertEqual(result, expected)
-
- def test_ix_update_ether(self):
- static_traffic_params = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:03",
- "framesPerSecond": True,
- "framesize": 64,
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l2": {
- "dstmac": "00:00:00:00:00:04",
- "framesPerSecond": True,
- "framesize": 64,
- "srcmac": "00:00:00:00:00:01"
- },
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
- self.ixnet.getList.side_effect = [
- [1],
- [1],
- [1],
- [
- "ethernet.header.destinationAddress",
- "ethernet.header.sourceAddress",
- ],
- ]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_update_ether(static_traffic_params)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_called()
-
- def test_ix_update_ether_nothing_to_do(self):
- static_traffic_params = {
- "uplink_0": {
- "id": 1,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l3": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "dscp": 0,
- "dstip4": "152.16.40.20",
- "proto": "udp",
- "srcip4": "152.16.100.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "2001",
- "srcport": "1234"
- },
- "traffic_type": "continuous"
- },
- "downlink_0": {
- "id": 2,
- "bidir": "False",
- "duration": 60,
- "iload": "100",
- "outer_l3": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v4": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l3v6": {
- "count": 1024,
- "dscp": 0,
- "dstip4": "152.16.100.20",
- "proto": "udp",
- "srcip4": "152.16.40.20",
- "ttl": 32
- },
- "outer_l4": {
- "dstport": "1234",
- "srcport": "2001"
- },
- "traffic_type": "continuous"
- }
- }
-
- self.ixnet.setMultiAttribute.return_value = [1]
- self.ixnet.commit.return_value = [1]
- self.ixnet.getList.side_effect = [
- [1],
- [1],
- [1],
- [
- "ethernet.header.destinationAddress",
- "ethernet.header.sourceAddress",
- ],
- ]
-
- ixnet_gen = IxNet.IxNextgen(self.ixnet)
-
- result = ixnet_gen.ix_update_ether(static_traffic_params)
- self.assertIsNone(result)
- self.ixnet.setMultiAttribute.assert_not_called()
diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
new file mode 100644
index 000000000..5bc2d8b16
--- /dev/null
+++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
@@ -0,0 +1,406 @@
+# Copyright (c) 2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import mock
+import IxNetwork
+import unittest
+
+from yardstick.common import exceptions
+from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
+
+
+UPLINK = 'uplink'
+DOWNLINK = 'downlink'
+
+TRAFFIC_PARAMETERS = {
+ UPLINK: {
+ 'id': 1,
+ 'bidir': 'False',
+ 'duration': 60,
+ 'iload': '100',
+ 'outer_l2': {
+ 'framesize': {'64B': '25', '256B': '75'}
+ },
+ 'outer_l3': {
+ 'dscp': 0,
+ 'dstip4': '152.16.40.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.100.20',
+ 'ttl': 32
+ },
+ 'outer_l3v4': {
+ 'dscp': 0,
+ 'dstip4': '152.16.40.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.100.20',
+ 'ttl': 32
+ },
+ 'outer_l3v6': {
+ 'count': 1024,
+ 'dscp': 0,
+ 'dstip4': '152.16.100.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.40.20',
+ 'ttl': 32
+ },
+ 'outer_l4': {
+ 'dstport': '2001',
+ 'srcport': '1234'
+ },
+ 'traffic_type': 'continuous'
+ },
+ DOWNLINK: {
+ 'id': 2,
+ 'bidir': 'False',
+ 'duration': 60,
+ 'iload': '100',
+ 'outer_l2': {
+ 'framesize': {'128B': '35', '1024B': '65'}
+ },
+ 'outer_l3': {
+ 'count': 1024,
+ 'dscp': 0,
+ 'dstip4': '152.16.100.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.40.20',
+ 'ttl': 32
+ },
+ 'outer_l3v4': {
+ 'count': 1024,
+ 'dscp': 0,
+ 'dstip4': '152.16.100.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.40.20',
+ 'ttl': 32
+ },
+ 'outer_l3v6': {
+ 'count': 1024,
+ 'dscp': 0,
+ 'dstip4': '152.16.100.20',
+ 'proto': 'udp',
+ 'srcip4': '152.16.40.20',
+ 'ttl': 32
+ },
+ 'outer_l4': {
+ 'dstport': '1234',
+ 'srcport': '2001'
+ },
+ 'traffic_type': 'continuous'
+ }
+}
+
+
+class TestIxNextgen(unittest.TestCase):
+
+ def setUp(self):
+ self.ixnet = mock.Mock()
+ self.ixnet.execute = mock.Mock()
+ self.ixnet.getRoot.return_value = 'my_root'
+
+ def test_get_config(self):
+ tg_cfg = {
+ 'vdu': [
+ {
+ 'external-interface': [
+ {'virtual-interface': {'vpci': '0000:07:00.1'}},
+ {'virtual-interface': {'vpci': '0001:08:01.2'}}
+ ]
+ },
+ ],
+ 'mgmt-interface': {
+ 'ip': 'test1',
+ 'tg-config': {
+ 'dut_result_dir': 'test2',
+ 'version': 'test3',
+ 'ixchassis': 'test4',
+ 'tcl_port': 'test5',
+ },
+ }
+ }
+
+ expected = {
+ 'machine': 'test1',
+ 'port': 'test5',
+ 'chassis': 'test4',
+ 'cards': ['0000', '0001'],
+ 'ports': ['07', '08'],
+ 'output_dir': 'test2',
+ 'version': 'test3',
+ 'bidir': True,
+ }
+
+ result = ixnet_api.IxNextgen.get_config(tg_cfg)
+ self.assertEqual(result, expected)
+
+ def test__get_config_element_by_flow_group_name(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
+ ['fg_01']]
+ ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_01'
+ output = ixnet_gen._get_config_element_by_flow_group_name(
+ 'flow_group_01')
+ self.assertEqual('traffic_item/configElement:flow_group_01', output)
+
+ def test__get_config_element_by_flow_group_name_no_match(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
+ ['fg_01']]
+ ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_02'
+ output = ixnet_gen._get_config_element_by_flow_group_name(
+ 'flow_group_01')
+ self.assertIsNone(output)
+
+ def test__parse_framesize(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ framesize = {'64B': '75', '512b': '25'}
+ output = ixnet_gen._parse_framesize(framesize)
+ for idx in range(len(framesize)):
+ if output[idx * 2] == 64:
+ self.assertEqual(75, output[idx * 2 + 1])
+ elif output[idx * 2] == 512:
+ self.assertEqual(25, output[idx * 2 + 1])
+ else:
+ raise self.failureException('Framesize (64, 512) not present')
+
+ @mock.patch.object(IxNetwork, 'IxNet')
+ def test_connect(self, mock_ixnet):
+ mock_ixnet.return_value = self.ixnet
+ ixnet_gen = ixnet_api.IxNextgen()
+ with mock.patch.object(ixnet_gen, 'get_config') as mock_config:
+ mock_config.return_value = {'machine': 'machine_fake',
+ 'port': 'port_fake',
+ 'version': 12345}
+ ixnet_gen.connect(mock.ANY)
+
+ self.ixnet.connect.assert_called_once_with(
+ 'machine_fake', '-port', 'port_fake', '-version', '12345')
+ mock_config.assert_called_once()
+
+ def test_connect_invalid_config_no_machine(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.get_config = mock.Mock(return_value={
+ 'port': 'port_fake',
+ 'version': '12345'})
+ self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
+ self.ixnet.connect.assert_not_called()
+
+ def test_connect_invalid_config_no_port(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.get_config = mock.Mock(return_value={
+ 'machine': 'machine_fake',
+ 'version': '12345'})
+ self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
+ self.ixnet.connect.assert_not_called()
+
+ def test_connect_invalid_config_no_version(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.get_config = mock.Mock(return_value={
+ 'machine': 'machine_fake',
+ 'port': 'port_fake'})
+ self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
+ self.ixnet.connect.assert_not_called()
+
+ def test_connect_no_config(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.get_config = mock.Mock(return_value={})
+ self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
+ self.ixnet.connect.assert_not_called()
+
+ def test_clear_config(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.clear_config()
+ self.ixnet.execute.assert_called_once_with('newConfig')
+
+ @mock.patch.object(ixnet_api, 'log')
+ def test_assign_ports_2_ports(self, *args):
+ self.ixnet.getAttribute.side_effect = ['up', 'down']
+ config = {
+ 'chassis': '1.1.1.1',
+ 'cards': ['1', '2'],
+ 'ports': ['2', '2']}
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._cfg = config
+
+ self.assertIsNone(ixnet_gen.assign_ports())
+ self.assertEqual(self.ixnet.execute.call_count, 2)
+ self.assertEqual(self.ixnet.commit.call_count, 4)
+ self.assertEqual(self.ixnet.getAttribute.call_count, 2)
+
+ @mock.patch.object(ixnet_api, 'log')
+ def test_assign_ports_port_down(self, mock_log):
+ self.ixnet.getAttribute.return_value = 'down'
+ config = {
+ 'chassis': '1.1.1.1',
+ 'cards': ['1', '2'],
+ 'ports': ['3', '4']}
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._cfg = config
+ ixnet_gen.assign_ports()
+ mock_log.warning.assert_called()
+
+ def test_assign_ports_no_config(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._cfg = {}
+ self.assertRaises(KeyError, ixnet_gen.assign_ports)
+
+ def test__create_traffic_item(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ self.ixnet.add.return_value = 'my_new_traffic_item'
+ self.ixnet.remapIds.return_value = ['my_traffic_item_id']
+
+ ixnet_gen._create_traffic_item()
+ self.ixnet.add.assert_called_once_with(
+ 'my_root/traffic', 'trafficItem')
+ self.ixnet.setMultiAttribute.assert_called_once_with(
+ 'my_new_traffic_item', '-name', 'RFC2544', '-trafficType', 'raw')
+ self.assertEqual(2, self.ixnet.commit.call_count)
+ self.ixnet.remapIds.assert_called_once_with('my_new_traffic_item')
+ self.ixnet.setAttribute('my_traffic_item_id/tracking',
+ '-trackBy', 'trafficGroupId0')
+
+ def test__create_flow_groups(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.ixnet.getList.side_effect = [['traffic_item'], ['1', '2']]
+ ixnet_gen.ixnet.add.side_effect = ['endp1', 'endp2']
+ ixnet_gen._create_flow_groups()
+ ixnet_gen.ixnet.add.assert_has_calls([
+ mock.call('traffic_item', 'endpointSet'),
+ mock.call('traffic_item', 'endpointSet')])
+ ixnet_gen.ixnet.setMultiAttribute.assert_has_calls([
+ mock.call('endp1', '-name', '1', '-sources', ['1/protocols'],
+ '-destinations', ['2/protocols']),
+ mock.call('endp2', '-name', '2', '-sources', ['2/protocols'],
+ '-destinations', ['1/protocols'])])
+
+ def test__append_protocol_to_stack(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+
+ ixnet_gen._append_procotol_to_stack('my_protocol', 'prev_element')
+ self.ixnet.execute.assert_called_with(
+ 'append', 'prev_element',
+ 'my_root/traffic/protocolTemplate:"my_protocol"')
+
+ def test__setup_config_elements(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.ixnet.getList.side_effect = [['traffic_item'],
+ ['cfg_element']]
+ with mock.patch.object(ixnet_gen, '_append_procotol_to_stack') as \
+ mock_append_proto:
+ ixnet_gen._setup_config_elements()
+ mock_append_proto.assert_has_calls([
+ mock.call(ixnet_api.PROTO_UDP, 'cfg_element/stack:"ethernet-1"'),
+ mock.call(ixnet_api.PROTO_IPV4, 'cfg_element/stack:"ethernet-1"')])
+ ixnet_gen.ixnet.setAttribute.assert_has_calls([
+ mock.call('cfg_element/frameRateDistribution', '-portDistribution',
+ 'splitRateEvenly'),
+ mock.call('cfg_element/frameRateDistribution',
+ '-streamDistribution', 'splitRateEvenly')])
+
+ @mock.patch.object(ixnet_api.IxNextgen, '_create_traffic_item')
+ @mock.patch.object(ixnet_api.IxNextgen, '_create_flow_groups')
+ @mock.patch.object(ixnet_api.IxNextgen, '_setup_config_elements')
+ def test_create_traffic_model(self, mock__setup_config_elements,
+ mock__create_flow_groups,
+ mock__create_traffic_item):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+
+ ixnet_gen.create_traffic_model()
+ mock__create_traffic_item.assert_called_once()
+ mock__create_flow_groups.assert_called_once()
+ mock__setup_config_elements.assert_called_once()
+
+ def test__get_field_in_stack_item(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
+ output = ixnet_gen._get_field_in_stack_item(mock.ANY, 'field2')
+ self.assertEqual('field2', output)
+
+ def test__get_field_in_stack_item_field_not_present(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
+ with self.assertRaises(exceptions.IxNetworkFieldNotPresentInStackItem):
+ ixnet_gen._get_field_in_stack_item(mock.ANY, 'field3')
+
+ def test__update_frame_mac(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ with mock.patch.object(ixnet_gen, '_get_field_in_stack_item') as \
+ mock_get_field:
+ mock_get_field.return_value = 'field_descriptor'
+ ixnet_gen._update_frame_mac('ethernet_descriptor', 'field', 'mac')
+ mock_get_field.assert_called_once_with('ethernet_descriptor', 'field')
+ ixnet_gen.ixnet.setMultiAttribute(
+ 'field_descriptor', '-singleValue', 'mac', '-fieldValue', 'mac',
+ '-valueType', 'singleValue')
+ ixnet_gen.ixnet.commit.assert_called_once()
+
+ def test_update_frame(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ with mock.patch.object(
+ ixnet_gen, '_get_config_element_by_flow_group_name',
+ return_value='cfg_element'), \
+ mock.patch.object(ixnet_gen, '_update_frame_mac') as \
+ mock_update_frame:
+ ixnet_gen.update_frame(TRAFFIC_PARAMETERS)
+
+ self.assertEqual(6, len(ixnet_gen.ixnet.setMultiAttribute.mock_calls))
+ self.assertEqual(4, len(mock_update_frame.mock_calls))
+
+ def test_update_frame_flow_not_present(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ with mock.patch.object(
+ ixnet_gen, '_get_config_element_by_flow_group_name',
+ return_value=None):
+ with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
+ ixnet_gen.update_frame(TRAFFIC_PARAMETERS)
+
+ def test_set_random_ip_multi_attribute(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ ixnet_gen._ixnet = self.ixnet
+ ixnet_gen.set_random_ip_multi_attribute('ipv4', 20, 30, 40, 100)
+ ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
+ 'ipv4', '-seed', '20', '-fixedBits', '30', '-randomMask', '40',
+ '-valueType', 'random', '-countValue', '100')
+
+ def test_get_statistics(self):
+ ixnet_gen = ixnet_api.IxNextgen()
+ port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
+ flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
+ with mock.patch.object(ixnet_gen, '_build_stats_map') as \
+ mock_build_stats:
+ ixnet_gen.get_statistics()
+
+ mock_build_stats.assert_has_calls([
+ mock.call(port_statistics, ixnet_gen.PORT_STATS_NAME_MAP),
+ mock.call(flow_statistics, ixnet_gen.LATENCY_NAME_MAP)])