Fix QnQ issue 41/64641/18
authorJohn O Loughlin <john.oloughlin@intel.com>
Fri, 23 Nov 2018 11:38:14 +0000 (11:38 +0000)
committerAbhijit Sinha <abhijit.sinha@intel.com>
Tue, 5 Feb 2019 13:35:11 +0000 (13:35 +0000)
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 <john.oloughlin@intel.com>
Signed-off-by: Oleksandr Naumets <oleksandrx.naumets@intel.com>
yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py

index e0b7aa0..b26cc3a 100644 (file)
@@ -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)
 
index f8eec4f..7ecb57d 100644 (file)
@@ -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()
index 38ca26b..dfd07d2 100644 (file)
@@ -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:
index 9db8b7b..e0397d9 100644 (file)
@@ -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())