From 1ad8da59859f72c97321c9cf8a4f048fc57addd1 Mon Sep 17 00:00:00 2001 From: John O Loughlin Date: Fri, 23 Nov 2018 11:38:14 +0000 Subject: Fix QnQ issue Currently if multiple tests are run with a QnQ section defined the QnQ segment gets appended to the frame. This leads to invalid frames when the test is run for more than 1 iteration. With this patch the QnQ is updated if the QnQ segment has already been created. JIRA: YARDSTICK-1513 Change-Id: I4ba6ef89380ccf1cb8a132ff5bf048935a87f0c9 Signed-off-by: John O Loughlin Signed-off-by: Oleksandr Naumets --- .../libs/ixia_libs/ixnet/ixnet_api.py | 38 ++++++-- .../vnf_generic/vnf/tg_rfc2544_ixia.py | 2 +- .../libs/ixia_libs/test_ixnet_api.py | 101 ++++++++++++++++++++- .../vnf_generic/vnf/test_tg_rfc2544_ixia.py | 9 +- 4 files changed, 135 insertions(+), 15 deletions(-) (limited to 'yardstick') 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 e0b7aa000..b26cc3abb 100644 --- a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py +++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py @@ -405,7 +405,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 @@ -421,7 +439,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', @@ -432,8 +452,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) @@ -448,7 +473,7 @@ 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): """Create a traffic item and the needed flow groups @@ -530,11 +555,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) 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 f8eec4f4c..7ecb57dd1 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py @@ -65,7 +65,7 @@ class IxiaBasicScenario(object): self._uplink_vports = vports[::2] self._downlink_vports = vports[1::2] self.client.create_traffic_model(self._uplink_vports, - self._downlink_vports) + self._downlink_vports, traffic_profile) def _get_stats(self): return self.client.get_statistics() 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 index 38ca26b08..dfd07d28c 100644 --- 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 @@ -22,11 +22,47 @@ from collections import OrderedDict from yardstick.common import exceptions from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api +from yardstick.network_services.traffic_profile import ixia_rfc2544 UPLINK = 'uplink' DOWNLINK = 'downlink' +TRAFFIC_PROFILE = { + 'uplink_0': { + 'ipv4': { + 'outer_l2': { + 'framesize': { + '128B': '0', + '1518B': '0', + '64B': '0', + '373b': '0', + '256B': '0', + '1400B': '0', + '570B': '0'}}, + 'id': 1}}, + 'description': 'Traffic profile to run RFC2544 latency', + 'name': 'rfc2544', + 'schema': 'isb:traffic_profile:0.1', + 'traffic_profile': { + 'injection_time': None, + 'enable_latency': True, + 'frame_rate': '100%', + 'traffic_type': 'IXIARFC2544Profile'}, + 'downlink_0': { + 'ipv4': { + 'outer_l2': { + 'framesize': { + '128B': '0', + '1518B': '0', + '64B': '0', + '373b': '0', + '256B': '0', + '1400B': '0', + '570B': '0'}}, + 'id': 2}}} + + TRAFFIC_PARAMETERS = { UPLINK: { 'id': 1, @@ -506,12 +542,17 @@ class TestIxNextgen(unittest.TestCase): 'my_root/traffic/protocolTemplate:"my_protocol"') def test__setup_config_elements(self): + # the config parsed from some_file + yaml_data = {'traffic_profile': {} + } + traffic_profile = ixia_rfc2544.IXIARFC2544Profile(yaml_data) + traffic_profile.params = TRAFFIC_PROFILE self.ixnet_gen.ixnet.getList.side_effect = [['traffic_item'], ['cfg_element']] with mock.patch.object(self.ixnet_gen, '_append_procotol_to_stack') as \ mock_append_proto: - self.ixnet_gen._setup_config_elements() - mock_append_proto.assert_has_calls([ + self.ixnet_gen._setup_config_elements(traffic_profile=traffic_profile) + 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"')]) self.ixnet_gen.ixnet.setAttribute.assert_has_calls([ @@ -526,11 +567,15 @@ class TestIxNextgen(unittest.TestCase): def test_create_traffic_model(self, mock__setup_config_elements, mock__create_flow_groups, mock__create_traffic_item): + # the config parsed from some_file + yaml_data = {'traffic_profile': {}} + traffic_profile = ixia_rfc2544.IXIARFC2544Profile(yaml_data) uplink_ports = ['port1', 'port3'] downlink_ports = ['port2', 'port4'] uplink_endpoints = ['port1/protocols', 'port3/protocols'] downlink_endpoints = ['port2/protocols', 'port4/protocols'] - self.ixnet_gen.create_traffic_model(uplink_ports, downlink_ports) + self.ixnet_gen.create_traffic_model(uplink_ports, downlink_ports, + traffic_profile=traffic_profile) mock__create_traffic_item.assert_called_once_with('raw') mock__create_flow_groups.assert_called_once_with(uplink_endpoints, downlink_endpoints) @@ -551,6 +596,56 @@ class TestIxNextgen(unittest.TestCase): downlink_topologies) mock__setup_config_elements.assert_called_once_with(False) + def test_flows_settings(self): + cfg = {'uplink_0': { + 'ipv4': { + 'outer_l2': { + 'framesize': { + '128B': '0', + '1518B': '0', + '64B': '0', + '373b': '0', + '256B': '0', + '1400B': '0', + '570B': '0'}}, + 'id': 1}}} + + expected = [ + {'ipv4': { + 'id': 1, + 'outer_l2': { + 'framesize': { + '1518B': '0', + '1400B': '0', + '128B': '0', + '64B': '0', + '256B': '0', + '373b': '0', + '570B': '0'}}}}] + + self.assertEqual(expected, self.ixnet_gen._flows_settings(cfg=cfg)) + + def test_is_qinq(self): + flow_data = {'ipv4': { + 'outer_l2': {}, + 'id': 1}} + self.assertEqual(False, self.ixnet_gen.is_qinq(flow_data=flow_data)) + + flow_data = {'ipv4': { + 'outer_l2': { + 'QinQ': { + 'C-VLAN': { + 'priority': 0, + 'cfi': 0, + 'id': 512}, + 'S-VLAN': { + 'priority': 0, + 'cfi': 0, + 'id': 128}}, + }, + 'id': 1}} + self.assertEqual(True, self.ixnet_gen.is_qinq(flow_data=flow_data)) + def test__update_frame_mac(self): with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item') as \ mock_get_field: diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py index 9db8b7b00..e0397d948 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py @@ -28,6 +28,7 @@ from yardstick.benchmark.contexts import base as ctx_base from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api from yardstick.network_services.traffic_profile import base as tp_base from yardstick.network_services.vnf_generic.vnf import tg_rfc2544_ixia +from yardstick.network_services.traffic_profile import ixia_rfc2544 TEST_FILE_YAML = 'nsb_test_case.yaml' @@ -526,9 +527,13 @@ class TestIxiaBasicScenario(unittest.TestCase): def test_create_traffic_model(self): self.mock_IxNextgen.get_vports.return_value = [1, 2, 3, 4] - self.scenario.create_traffic_model() + yaml_data = {'traffic_profile': {} + } + traffic_profile = ixia_rfc2544.IXIARFC2544Profile(yaml_data) + self.scenario.create_traffic_model(traffic_profile) self.scenario.client.get_vports.assert_called_once() - self.scenario.client.create_traffic_model.assert_called_once_with([1, 3], [2, 4]) + self.scenario.client.create_traffic_model.assert_called_once_with( + [1, 3], [2, 4], traffic_profile) def test_apply_config(self): self.assertIsNone(self.scenario.apply_config()) -- cgit 1.2.3-korg