Create a SampleVNF MQ consumer class
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_acl_vnf.py
index f75fa22..01fc19a 100644 (file)
 # 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 unittest
 import mock
 import os
+import re
+import copy
 
-from yardstick.tests import STL_MOCKS
-from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
 from yardstick.common import utils
-
-
-STLClient = mock.MagicMock()
-stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
-stl_patch.start()
-
-if stl_patch:
-    from yardstick.network_services.vnf_generic.vnf.acl_vnf import AclApproxVnf
-    from yardstick.network_services.nfvi.resource import ResourceProfile
-    from yardstick.network_services.vnf_generic.vnf.acl_vnf import AclApproxSetupEnvSetupEnvHelper
+from yardstick.common import exceptions
+from yardstick.benchmark.contexts import base as ctx_base
+from yardstick.network_services.vnf_generic.vnf import acl_vnf
+from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
+from yardstick.network_services.nfvi.resource import ResourceProfile
+from yardstick.network_services.vnf_generic.vnf.acl_vnf import AclApproxSetupEnvSetupEnvHelper
+from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
 
 
 TEST_FILE_YAML = 'nsb_test_case.yaml'
@@ -142,7 +138,7 @@ class TestAclApproxVnf(unittest.TestCase):
                               'ip': '1.2.1.1',
                               'interfaces':
                               {'xe0': {'local_iface_name': 'ens513f0',
-                                       'vld_id': AclApproxVnf.DOWNLINK,
+                                       'vld_id': acl_vnf.AclApproxVnf.DOWNLINK,
                                        'netmask': '255.255.255.0',
                                        'local_ip': '152.16.40.20',
                                        'dst_mac': '00:00:00:00:00:01',
@@ -170,7 +166,7 @@ class TestAclApproxVnf(unittest.TestCase):
                               'ip': '1.2.1.1',
                               'interfaces':
                               {'xe0': {'local_iface_name': 'ens785f0',
-                                       'vld_id': AclApproxVnf.UPLINK,
+                                       'vld_id': acl_vnf.AclApproxVnf.UPLINK,
                                        'netmask': '255.255.255.0',
                                        'local_ip': '152.16.100.20',
                                        'dst_mac': '00:00:00:00:00:02',
@@ -195,7 +191,7 @@ class TestAclApproxVnf(unittest.TestCase):
                               'ip': '1.2.1.1',
                               'interfaces':
                               {'xe0': {'local_iface_name': 'ens786f0',
-                                       'vld_id': AclApproxVnf.UPLINK,
+                                       'vld_id': acl_vnf.AclApproxVnf.UPLINK,
                                        'netmask': '255.255.255.0',
                                        'local_ip': '152.16.100.19',
                                        'dst_mac': '00:00:00:00:00:04',
@@ -205,7 +201,7 @@ class TestAclApproxVnf(unittest.TestCase):
                                        'vpci': '0000:05:00.0',
                                        'dpdk_port_num': 0},
                                'xe1': {'local_iface_name': 'ens786f1',
-                                       'vld_id': AclApproxVnf.DOWNLINK,
+                                       'vld_id': acl_vnf.AclApproxVnf.DOWNLINK,
                                        'netmask': '255.255.255.0',
                                        'local_ip': '152.16.40.19',
                                        'dst_mac': '00:00:00:00:00:03',
@@ -241,22 +237,31 @@ class TestAclApproxVnf(unittest.TestCase):
 
     def test___init__(self, *args):
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         self.assertIsNone(acl_approx_vnf._vnf_process)
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
+    @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
     @mock.patch(SSH_HELPER)
     def test_collect_kpi(self, ssh, *args):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
+        acl_approx_vnf.scenario_helper.scenario_cfg = {
+            'nodes': {acl_approx_vnf.name: "mock"}
+        }
         acl_approx_vnf.q_in = mock.MagicMock()
         acl_approx_vnf.q_out = mock.MagicMock()
         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
         acl_approx_vnf.resource = mock.Mock(autospec=ResourceProfile)
         acl_approx_vnf.vnf_execute = mock.Mock(return_value="")
-        result = {'packets_dropped': 0, 'packets_fwd': 0, 'packets_in': 0}
+        result = {
+            'physical_node': 'mock_node',
+            'packets_dropped': 0,
+            'packets_fwd': 0,
+            'packets_in': 0
+        }
         self.assertEqual(result, acl_approx_vnf.collect_kpi())
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
@@ -265,7 +270,7 @@ class TestAclApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         acl_approx_vnf.q_in = mock.MagicMock()
         acl_approx_vnf.q_out = mock.MagicMock()
         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
@@ -277,7 +282,7 @@ class TestAclApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         acl_approx_vnf.q_in = mock.MagicMock()
         acl_approx_vnf.q_out = mock.MagicMock()
         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
@@ -298,7 +303,7 @@ class TestAclApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         acl_approx_vnf._build_config = mock.MagicMock()
         acl_approx_vnf.queue_wrapper = mock.MagicMock()
         acl_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
@@ -311,7 +316,6 @@ class TestAclApproxVnf(unittest.TestCase):
         acl_approx_vnf._run()
         acl_approx_vnf.ssh_helper.run.assert_called_once()
 
-    @mock.patch("yardstick.network_services.vnf_generic.vnf.acl_vnf.YangModel")
     @mock.patch.object(utils, 'find_relative_file')
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
     @mock.patch(SSH_HELPER)
@@ -319,7 +323,7 @@ class TestAclApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         acl_approx_vnf.deploy_helper = mock.MagicMock()
         acl_approx_vnf.resource_helper = mock.MagicMock()
         acl_approx_vnf._build_config = mock.MagicMock()
@@ -337,7 +341,7 @@ class TestAclApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        acl_approx_vnf = AclApproxVnf(name, vnfd)
+        acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd, 'task_id')
         acl_approx_vnf._vnf_process = mock.MagicMock()
         acl_approx_vnf._vnf_process.terminate = mock.Mock()
         acl_approx_vnf.used_drivers = {"01:01.0": "i40e",
@@ -350,6 +354,145 @@ class TestAclApproxVnf(unittest.TestCase):
 
 class TestAclApproxSetupEnvSetupEnvHelper(unittest.TestCase):
 
+    ACL_CONFIG = {"access-list-entries": [{
+                     "actions": [
+                       "count",
+                       {"fwd": {
+                           "port": 0
+                         }
+                       }
+                     ],
+                     "matches": {
+                       "destination-ipv4-network": "152.16.0.0/24",
+                       "destination-port-range": {
+                         "lower-port": 0,
+                         "upper-port": 65535
+                       },
+                       "source-ipv4-network": "0.0.0.0/0",
+                       "source-port-range": {
+                         "lower-port": 0,
+                         "upper-port": 65535
+                       },
+                       "protocol-mask": 255,
+                       "protocol": 127,
+                       "priority": 1
+                     },
+                     "rule-name": "rule1588"
+                   }
+                 ]}
+
+    def test_get_default_flows(self):
+        """Check if default ACL SampleVNF CLI commands are
+        generated correctly"""
+        ssh_helper = mock.Mock()
+        vnfd_helper = VnfdHelper({'vdu': [
+            {'external-interface': [
+                {
+                    'virtual-interface': {
+                        'local_ip': '152.16.100.19',
+                        'netmask': '255.255.255.0',
+                        'dpdk_port_num': 0,
+                        'dst_ip': '152.16.100.20',
+                        'vld_id': 'uplink_0',
+                        'ifname': 'xe0',
+                    },
+                    'vnfd-connection-point-ref': 'xe0',
+                    'name': 'xe0'
+                },
+                {
+                    'virtual-interface': {
+                        'local_ip': '152.16.40.19',
+                        'netmask': '255.255.255.0',
+                        'dpdk_port_num': 1,
+                        'dst_ip': '152.16.40.20',
+                        'vld_id': 'downlink_0',
+                        'ifname': 'xe1',
+                    },
+                    'vnfd-connection-point-ref': 'xe1',
+                    'name': 'xe1'
+                }
+            ]}
+        ]})
+        setup_helper = AclApproxSetupEnvSetupEnvHelper(vnfd_helper, ssh_helper, None)
+        self.check_acl_commands(setup_helper.get_flows_config(), [
+            # format: (<cli pattern>, <number of expected matches>)
+            ("^p action add [0-9]+ accept$", 2),
+            ("^p action add [0-9]+ count$", 2),
+            ("^p action add [0-9]+ fwd 1$", 1),
+            ("^p action add [0-9]+ fwd 0$", 1),
+            ("^p acl add 1 152.16.100.0 24 152.16.40.0 24 0 65535 0 65535 0 0 [0-9]+$", 1),
+            ("^p acl add 1 152.16.40.0 24 152.16.100.0 24 0 65535 0 65535 0 0 [0-9]+$", 1),
+            ("^p acl applyruleset$", 1)
+        ])
+
+    @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
+    def test_get_flows_config(self, get_default_flows):
+        """Check if provided ACL config can be converted to
+        ACL SampleVNF CLI commands correctly"""
+        ssh_helper = mock.Mock()
+        setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
+        get_default_flows.return_value = ({}, [])
+        self.check_acl_commands(setup_helper.get_flows_config(self.ACL_CONFIG), [
+            # format: (<cli pattern>, <number of expected matches>)
+            ("^p action add [0-9]+ count$", 1),
+            ("^p action add [0-9]+ fwd 0$", 1),
+            ("^p acl add 1 0.0.0.0 0 152.16.0.0 24 0 65535 0 65535 127 0 [0-9]+$", 1),
+            ("^p acl applyruleset$", 1)
+        ])
+
+    @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
+    def test_get_flows_config_invalid_action(self, get_default_flows):
+        """Check if incorrect ACL config fails to convert
+        to ACL SampleVNF CLI commands"""
+        ssh_helper = mock.Mock()
+        setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
+        get_default_flows.return_value = ({}, [])
+        # duplicate config and add invald action
+        acl_config = copy.deepcopy(self.ACL_CONFIG)
+        acl_config['access-list-entries'][0]["actions"].append({"xnat": {}})
+        self.assertRaises(exceptions.AclUknownActionTemplate,
+            setup_helper.get_flows_config, acl_config)
+
+    @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
+    def test_get_flows_config_invalid_action_param(self, get_default_flows):
+        """Check if ACL config with invalid action parameter fails to convert
+        to ACL SampleVNF CLI commands"""
+        ssh_helper = mock.Mock()
+        setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
+        get_default_flows.return_value = ({}, [])
+        # duplicate config and add action with invalid parameter
+        acl_config = copy.deepcopy(self.ACL_CONFIG)
+        acl_config['access-list-entries'][0]["actions"].append(
+            {"nat": {"xport": 0}})
+        self.assertRaises(exceptions.AclMissingActionArguments,
+            setup_helper.get_flows_config, acl_config)
+
+    def check_acl_commands(self, config, expected_cli_patterns):
+        """Check if expected ACL CLI commands (given as a list of patterns,
+        `expected_cli_patterns` parameter) present in SampleVNF ACL
+        configuration (given as a multiline string, `config` parameter)"""
+        # Example of expected config:
+        # ---------------------------
+        # p action add 1 accept
+        # p action add 1 fwd 1
+        # p action add 2 accept
+        # p action add 2 count
+        # p action add 2 fwd 0
+        # p acl add 1 152.16.100.0 24 152.16.40.0 24 0 65535 0 65535 0 0 1
+        # p acl add 1 152.16.40.0 24 152.16.100.0 24 0 65535 0 65535 0 0 2
+        # p acl applyruleset
+        # ---------------------------
+        # NOTE: The config above consists of actions ids, which are actually
+        # unknown (generated at runtime), thus it's incorrect just to compare
+        # the example ACL config above with the configuration returned by
+        # get_flows_config() function. It's more correct to use CLI patterns
+        # (RE) to find the required SampleVNF CLI commands in the multiline
+        # string (SampleVNF ACL configuration).
+        for pattern, num_of_match in expected_cli_patterns:
+            # format: (<cli pattern>, <number of expected matches>)
+            result = re.findall(pattern, config, re.MULTILINE)
+            self.assertEqual(len(result), num_of_match)
+
     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open')
     @mock.patch.object(utils, 'find_relative_file')
     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig')
@@ -359,14 +502,17 @@ class TestAclApproxSetupEnvSetupEnvHelper(unittest.TestCase):
         ssh_helper = mock.Mock()
         scenario_helper = mock.Mock()
         scenario_helper.vnf_cfg = {'lb_config': 'HW'}
+        scenario_helper.options = {}
         scenario_helper.all_options = {}
 
         acl_approx_setup_helper = AclApproxSetupEnvSetupEnvHelper(vnfd_helper,
                                                                   ssh_helper,
                                                                   scenario_helper)
 
+        acl_approx_setup_helper.get_flows_config = mock.Mock()
         acl_approx_setup_helper.ssh_helper.provision_tool = mock.Mock(return_value='tool_path')
         acl_approx_setup_helper.ssh_helper.all_ports = mock.Mock()
         acl_approx_setup_helper.vnfd_helper.port_nums = mock.Mock(return_value=[0, 1])
         expected = 'sudo tool_path -p 0x3 -f /tmp/acl_config -s /tmp/acl_script  --hwlb 3'
         self.assertEqual(acl_approx_setup_helper.build_config(), expected)
+        acl_approx_setup_helper.get_flows_config.assert_called_once()