Add vIPSEC VNF for running Crypto performance test case 49/65149/12
authortreyad <treyad@viosoft.com>
Thu, 15 Nov 2018 16:44:33 +0000 (08:44 -0800)
committerTarek Reyad <treyad@viosoft.com>
Thu, 21 Feb 2019 10:31:10 +0000 (10:31 +0000)
VNF life cycle
- instantiate
- collect_kpi
- terminate

JIRA: YARDSTICK-1484

Change-Id: I39fd24fdadbce6cee161c906fc95c16a36cb7cd8
Signed-off-by: treyad <treyad@viosoft.com>
yardstick/network_services/helpers/cpu.py
yardstick/network_services/vnf_generic/vnf/base.py
yardstick/network_services/vnf_generic/vnf/ipsec_vnf.py [new file with mode: 0644]
yardstick/network_services/vnf_generic/vnf/vpp_helpers.py [new file with mode: 0644]
yardstick/tests/unit/network_services/helpers/test_cpu.py
yardstick/tests/unit/network_services/vnf_generic/vnf/test_ipsec_vnf.py [new file with mode: 0644]
yardstick/tests/unit/network_services/vnf_generic/vnf/test_vpp_helpers.py [new file with mode: 0644]

index 8c21754..8cdd829 100644 (file)
@@ -33,11 +33,11 @@ class CpuSysCores(object):
         core_lines = {}
         for line in lines:
             if line.strip():
-                    name, value = line.split(":", 1)
-                    core_lines[name.strip()] = value.strip()
+                name, value = line.split(":", 1)
+                core_lines[name.strip()] = value.strip()
             else:
-                    core_details.append(core_lines)
-                    core_lines = {}
+                core_details.append(core_lines)
+                core_lines = {}
 
         return core_details
 
@@ -51,7 +51,7 @@ class CpuSysCores(object):
         lines = self._open_cpuinfo()
         core_details = self._get_core_details(lines)
         for core in core_details:
-            for k, v in core.items():
+            for k, _ in core.items():
                 if k == "physical id":
                     if core["physical id"] not in self.core_map:
                         self.core_map[core['physical id']] = []
@@ -60,6 +60,16 @@ class CpuSysCores(object):
 
         return self.core_map
 
+    def get_cpu_layout(self):
+        _, stdout, _ = self.connection.execute("lscpu -p")
+        cpuinfo = {}
+        cpuinfo['cpuinfo'] = list()
+        for line in stdout.split("\n"):
+            if line and line[0] != "#":
+                cpuinfo['cpuinfo'].append([CpuSysCores._str2int(x) for x in
+                                           line.split(",")])
+        return cpuinfo
+
     def validate_cpu_cfg(self, vnf_cfg=None):
         if vnf_cfg is None:
             vnf_cfg = {
@@ -78,3 +88,10 @@ class CpuSysCores(object):
                 return -1
 
         return 0
+
+    @staticmethod
+    def _str2int(string):
+        try:
+            return int(string)
+        except ValueError:
+            return 0
index 8064ae9..8ef96b7 100644 (file)
@@ -94,7 +94,7 @@ class VnfdHelper(dict):
         for interface in self.interfaces:
             virtual_intf = interface["virtual-interface"]
             if virtual_intf[key] == value:
-                return interface
+                return virtual_intf
         raise KeyError()
 
     def find_interface(self, **kwargs):
diff --git a/yardstick/network_services/vnf_generic/vnf/ipsec_vnf.py b/yardstick/network_services/vnf_generic/vnf/ipsec_vnf.py
new file mode 100644 (file)
index 0000000..75a8cce
--- /dev/null
@@ -0,0 +1,219 @@
+# Copyright (c) 2019 Viosoft 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 logging
+import re
+import time
+
+from yardstick.benchmark.contexts.base import Context
+from yardstick.common.process import check_if_process_failed
+from yardstick.network_services import constants
+from yardstick.network_services.helpers.cpu import CpuSysCores
+from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF
+from yardstick.network_services.vnf_generic.vnf.vpp_helpers import \
+    VppSetupEnvHelper
+
+LOG = logging.getLogger(__name__)
+
+
+class VipsecApproxSetupEnvHelper(VppSetupEnvHelper):
+    DEFAULT_IPSEC_VNF_CFG = {
+        'crypto_type': 'SW_cryptodev',
+        'rxq': 1,
+        'worker_config': '1C/1T',
+        'worker_threads': 1,
+    }
+
+    def __init__(self, vnfd_helper, ssh_helper, scenario_helper):
+        super(VipsecApproxSetupEnvHelper, self).__init__(
+            vnfd_helper, ssh_helper, scenario_helper)
+
+    def _get_crypto_type(self):
+        vnf_cfg = self.scenario_helper.options.get('vnf_config',
+                                                   self.DEFAULT_IPSEC_VNF_CFG)
+        return vnf_cfg.get('crypto_type', 'SW_cryptodev')
+
+    def _get_crypto_algorithms(self):
+        vpp_cfg = self.scenario_helper.all_options.get('vpp_config', {})
+        return vpp_cfg.get('crypto_algorithms', 'aes-gcm')
+
+    def _get_n_tunnels(self):
+        vpp_cfg = self.scenario_helper.all_options.get('vpp_config', {})
+        return vpp_cfg.get('tunnels', 1)
+
+    def _get_n_connections(self):
+        try:
+            flow_cfg = self.scenario_helper.all_options['flow']
+            return flow_cfg['count']
+        except KeyError:
+            raise KeyError("Missing flow definition in scenario section" +
+                           " of the task definition file")
+
+    def _get_flow_src_start_ip(self):
+        node_name = self.find_encrypted_data_interface()["node_name"]
+        try:
+            flow_cfg = self.scenario_helper.all_options['flow']
+            src_ips = flow_cfg['src_ip']
+            dst_ips = flow_cfg['dst_ip']
+        except KeyError:
+            raise KeyError("Missing flow definition in scenario section" +
+                           " of the task definition file")
+
+        for src, dst in zip(src_ips, dst_ips):
+            flow_src_start_ip, _ = src.split('-')
+            flow_dst_start_ip, _ = dst.split('-')
+
+            if node_name == "vnf__0":
+                return flow_src_start_ip
+            elif node_name == "vnf__1":
+                return flow_dst_start_ip
+
+    def _get_flow_dst_start_ip(self):
+        node_name = self.find_encrypted_data_interface()["node_name"]
+        try:
+            flow_cfg = self.scenario_helper.all_options['flow']
+            src_ips = flow_cfg['src_ip']
+            dst_ips = flow_cfg['dst_ip']
+        except KeyError:
+            raise KeyError("Missing flow definition in scenario section" +
+                           " of the task definition file")
+
+        for src, dst in zip(src_ips, dst_ips):
+            flow_src_start_ip, _ = src.split('-')
+            flow_dst_start_ip, _ = dst.split('-')
+
+            if node_name == "vnf__0":
+                return flow_dst_start_ip
+            elif node_name == "vnf__1":
+                return flow_src_start_ip
+
+    def build_config(self):
+        # TODO Implement later
+        pass
+
+    def setup_vnf_environment(self):
+        resource = super(VipsecApproxSetupEnvHelper,
+                         self).setup_vnf_environment()
+
+        self.start_vpp_service()
+
+        sys_cores = CpuSysCores(self.ssh_helper)
+        self._update_vnfd_helper(sys_cores.get_cpu_layout())
+
+        return resource
+
+    @staticmethod
+    def calculate_frame_size(frame_cfg):
+        if not frame_cfg:
+            return 64
+
+        imix_count = {size.upper().replace('B', ''): int(weight)
+                      for size, weight in frame_cfg.items()}
+        imix_sum = sum(imix_count.values())
+        if imix_sum <= 0:
+            return 64
+        packets_total = sum([int(size) * weight
+                             for size, weight in imix_count.items()])
+        return packets_total / imix_sum
+
+    def check_status(self):
+        ipsec_created = False
+        cmd = "vppctl show int"
+        _, stdout, _ = self.ssh_helper.execute(cmd)
+        entries = re.split(r"\n+", stdout)
+        tmp = [re.split(r"\s\s+", entry, 5) for entry in entries]
+
+        for item in tmp:
+            if isinstance(item, list):
+                if item[0] and item[0] != 'local0':
+                    if "ipsec" in item[0] and not ipsec_created:
+                        ipsec_created = True
+                    if len(item) > 2 and item[2] == 'down':
+                        return False
+        return ipsec_created
+
+    def get_vpp_statistics(self):
+        # TODO Implement later
+        return None
+
+    def create_ipsec_tunnels(self):
+        # TODO Implement later
+        pass
+
+    def find_raw_data_interface(self):
+        try:
+            return self.vnfd_helper.find_virtual_interface(vld_id="uplink_0")
+        except KeyError:
+            return self.vnfd_helper.find_virtual_interface(vld_id="downlink_0")
+
+    def find_encrypted_data_interface(self):
+        return self.vnfd_helper.find_virtual_interface(vld_id="ciphertext")
+
+
+class VipsecApproxVnf(SampleVNF):
+    """ This class handles vIPSEC VNF model-driver definitions """
+
+    APP_NAME = 'vIPSEC'
+    APP_WORD = 'vipsec'
+    WAIT_TIME = 20
+
+    def __init__(self, name, vnfd, setup_env_helper_type=None,
+                 resource_helper_type=None):
+        if setup_env_helper_type is None:
+            setup_env_helper_type = VipsecApproxSetupEnvHelper
+        super(VipsecApproxVnf, self).__init__(
+            name, vnfd, setup_env_helper_type,
+            resource_helper_type)
+
+    def _run(self):
+        # we can't share ssh paramiko objects to force new connection
+        self.ssh_helper.drop_connection()
+        # kill before starting
+        self.setup_helper.kill_vnf()
+        self._build_config()
+        self.setup_helper.create_ipsec_tunnels()
+
+    def wait_for_instantiate(self):
+        time.sleep(self.WAIT_TIME)
+        while True:
+            status = self.setup_helper.check_status()
+            if not self._vnf_process.is_alive() and not status:
+                raise RuntimeError("%s VNF process died." % self.APP_NAME)
+            LOG.info("Waiting for %s VNF to start.. ", self.APP_NAME)
+            time.sleep(self.WAIT_TIME_FOR_SCRIPT)
+            status = self.setup_helper.check_status()
+            if status:
+                LOG.info("%s VNF is up and running.", self.APP_NAME)
+                self._vnf_up_post()
+                return self._vnf_process.exitcode
+
+    def terminate(self):
+        self.setup_helper.kill_vnf()
+        self._tear_down()
+        self.resource_helper.stop_collect()
+        if self._vnf_process is not None:
+            # be proper and join first before we kill
+            LOG.debug("joining before terminate %s", self._vnf_process.name)
+            self._vnf_process.join(constants.PROCESS_JOIN_TIMEOUT)
+            self._vnf_process.terminate()
+
+    def collect_kpi(self):
+        # we can't get KPIs if the VNF is down
+        check_if_process_failed(self._vnf_process, 0.01)
+        physical_node = Context.get_physical_node_from_server(
+            self.scenario_helper.nodes[self.name])
+        result = {"physical_node": physical_node}
+        result["collect_stats"] = self.setup_helper.get_vpp_statistics()
+        LOG.debug("%s collect KPIs %s", self.APP_NAME, result)
+        return result
diff --git a/yardstick/network_services/vnf_generic/vnf/vpp_helpers.py b/yardstick/network_services/vnf_generic/vnf/vpp_helpers.py
new file mode 100644 (file)
index 0000000..86c42ec
--- /dev/null
@@ -0,0 +1,76 @@
+# Copyright (c) 2019 Viosoft 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 logging
+
+from yardstick.network_services.vnf_generic.vnf.sample_vnf import \
+    DpdkVnfSetupEnvHelper
+
+LOG = logging.getLogger(__name__)
+
+
+class VppSetupEnvHelper(DpdkVnfSetupEnvHelper):
+    APP_NAME = "vpp"
+    CFG_CONFIG = "/etc/vpp/startup.conf"
+    CFG_SCRIPT = ""
+    PIPELINE_COMMAND = ""
+    VNF_TYPE = "IPSEC"
+    VAT_BIN_NAME = 'vpp_api_test'
+
+    def __init__(self, vnfd_helper, ssh_helper, scenario_helper):
+        super(VppSetupEnvHelper, self).__init__(vnfd_helper, ssh_helper,
+                                                scenario_helper)
+
+    def kill_vnf(self):
+        ret_code, _, _ = \
+            self.ssh_helper.execute(
+                'service {name} stop'.format(name=self.APP_NAME))
+        if int(ret_code):
+            raise RuntimeError(
+                'Failed to stop service {name}'.format(name=self.APP_NAME))
+
+    def tear_down(self):
+        pass
+
+    def start_vpp_service(self):
+        ret_code, _, _ = \
+            self.ssh_helper.execute(
+                'service {name} restart'.format(name=self.APP_NAME))
+        if int(ret_code):
+            raise RuntimeError(
+                'Failed to start service {name}'.format(name=self.APP_NAME))
+
+    def _update_vnfd_helper(self, additional_data, iface_key=None):
+        for k, v in additional_data.items():
+            if iface_key is None:
+                if isinstance(v, dict) and k in self.vnfd_helper:
+                    self.vnfd_helper[k].update(v)
+                else:
+                    self.vnfd_helper[k] = v
+            else:
+                if isinstance(v,
+                              dict) and k in self.vnfd_helper.find_virtual_interface(
+                    ifname=iface_key):
+                    self.vnfd_helper.find_virtual_interface(ifname=iface_key)[
+                        k].update(v)
+                else:
+                    self.vnfd_helper.find_virtual_interface(ifname=iface_key)[
+                        k] = v
+
+    def get_value_by_interface_key(self, interface, key):
+        try:
+            return self.vnfd_helper.find_virtual_interface(
+                ifname=interface).get(key)
+        except (KeyError, ValueError):
+            return None
index 871fbf8..c28178d 100644 (file)
@@ -119,3 +119,25 @@ class TestCpuSysCores(unittest.TestCase):
             vnf_cfg = {'lb_config': 'SW', 'lb_count': 1, 'worker_config':
                        '1C/1T', 'worker_threads': 1}
             self.assertEqual(-1, cpu_topo.validate_cpu_cfg(vnf_cfg))
+
+    def test_get_cpu_layout(self):
+        with mock.patch("yardstick.ssh.SSH") as ssh:
+            ssh_mock = mock.Mock(autospec=ssh.SSH)
+            ssh_mock.execute = \
+                mock.Mock(
+                    return_value=(1, "# CPU,Core,Socket,Node,,L1d,L1i,L2,L3\n'"
+                                     "0,0,0,0,,0,0,0,0\n"
+                                     "1,1,0,0,,1,1,1,0\n", ""))
+            ssh_mock.put = \
+                mock.Mock(return_value=(1, "", ""))
+            cpu_topo = CpuSysCores(ssh_mock)
+            subprocess.check_output = mock.Mock(return_value=0)
+            self.assertEqual({'cpuinfo': [[0, 0, 0, 0, 0, 0, 0, 0, 0],
+                                          [1, 1, 0, 0, 0, 1, 1, 1, 0]]},
+                             cpu_topo.get_cpu_layout())
+
+    def test__str2int(self):
+        self.assertEqual(1, CpuSysCores._str2int("1"))
+
+    def test__str2int_error(self):
+        self.assertEqual(0, CpuSysCores._str2int("err"))
diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_ipsec_vnf.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_ipsec_vnf.py
new file mode 100644 (file)
index 0000000..f812630
--- /dev/null
@@ -0,0 +1,1327 @@
+# Copyright (c) 2019 Viosoft 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 unittest
+from multiprocessing import Process
+
+import mock
+
+from yardstick.benchmark.contexts import base as ctx_base
+from yardstick.common import utils
+from yardstick.network_services.nfvi.resource import ResourceProfile
+from yardstick.network_services.vnf_generic.vnf import ipsec_vnf
+from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
+from yardstick.network_services.vnf_generic.vnf.ipsec_vnf import \
+    VipsecApproxSetupEnvHelper
+from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import \
+    mock_ssh
+
+SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
+
+NAME = 'vnf__1'
+
+
+@mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Process")
+class TestVipsecApproxVnf(unittest.TestCase):
+    VNFD = {'vnfd:vnfd-catalog':
+        {'vnfd':
+            [{
+                "benchmark": {
+                    "kpi": [
+                        "packets_in",
+                        "packets_fwd",
+                        "packets_dropped"
+                    ]
+                },
+                "connection-point": [
+                    {
+                        "name": "xe0",
+                        "type": "VPORT"
+                    },
+                    {
+                        "name": "xe1",
+                        "type": "VPORT"
+                    }
+                ],
+                "description": "VPP IPsec",
+                "id": "VipsecApproxVnf",
+                "mgmt-interface": {
+                    "ip": "10.10.10.101",
+                    "password": "r00t",
+                    "user": "root",
+                    "vdu-id": "ipsecvnf-baremetal"
+                },
+                "name": "IpsecVnf",
+                "short-name": "IpsecVnf",
+                "vdu": [
+                    {
+                        "description": "VPP Ipsec",
+                        "external-interface": [
+                            {
+                                "name": "xe0",
+                                "virtual-interface": {
+                                    "dpdk_port_num": 0,
+                                    "driver": "igb_uio",
+                                    "dst_ip": "192.168.100.1",
+                                    "dst_mac": "90:e2:ba:7c:30:e8",
+                                    "ifname": "xe0",
+                                    "local_ip": "192.168.100.2",
+                                    "local_mac": "90:e2:ba:7c:41:a8",
+                                    "netmask": "255.255.255.0",
+                                    "network": {},
+                                    "node_name": "vnf__0",
+                                    "peer_ifname": "xe0",
+                                    "peer_intf": {
+                                        "dpdk_port_num": 0,
+                                        "driver": "igb_uio",
+                                        "dst_ip": "192.168.100.2",
+                                        "dst_mac": "90:e2:ba:7c:41:a8",
+                                        "ifname": "xe0",
+                                        "local_ip": "192.168.100.1",
+                                        "local_mac": "90:e2:ba:7c:30:e8",
+                                        "netmask": "255.255.255.0",
+                                        "network": {},
+                                        "node_name": "tg__0",
+                                        "peer_ifname": "xe0",
+                                        "peer_name": "vnf__0",
+                                        "vld_id": "uplink_0",
+                                        "vpci": "0000:81:00.0"
+                                    },
+                                    "peer_name": "tg__0",
+                                    "vld_id": "uplink_0",
+                                    "vpci": "0000:ff:06.0"
+                                },
+                                "vnfd-connection-point-ref": "xe0"
+                            },
+                            {
+                                "name": "xe1",
+                                "virtual-interface": {
+                                    "dpdk_port_num": 1,
+                                    "driver": "igb_uio",
+                                    "dst_ip": "1.1.1.2",
+                                    "dst_mac": "0a:b1:ec:fd:a2:66",
+                                    "ifname": "xe1",
+                                    "local_ip": "1.1.1.1",
+                                    "local_mac": "4e:90:85:d3:c5:13",
+                                    "netmask": "255.255.255.0",
+                                    "network": {},
+                                    "node_name": "vnf__0",
+                                    "peer_ifname": "xe1",
+                                    "peer_intf": {
+                                        "driver": "igb_uio",
+                                        "dst_ip": "1.1.1.1",
+                                        "dst_mac": "4e:90:85:d3:c5:13",
+                                        "ifname": "xe1",
+                                        "local_ip": "1.1.1.2",
+                                        "local_mac": "0a:b1:ec:fd:a2:66",
+                                        "netmask": "255.255.255.0",
+                                        "network": {},
+                                        "node_name": "vnf__1",
+                                        "peer_ifname": "xe1",
+                                        "peer_name": "vnf__0",
+                                        "vld_id": "ciphertext",
+                                        "vpci": "0000:00:07.0"
+                                    },
+                                    "peer_name": "vnf__1",
+                                    "vld_id": "ciphertext",
+                                    "vpci": "0000:ff:07.0"
+                                },
+                                "vnfd-connection-point-ref": "xe1"
+                            }
+                        ],
+                        "id": "ipsecvnf-baremetal",
+                        "name": "ipsecvnf-baremetal",
+                        "routing_table": []
+                    }
+                ]
+            }
+            ]}}
+
+    VNFD_ERROR = {'vnfd:vnfd-catalog':
+        {'vnfd':
+            [{
+                "benchmark": {
+                    "kpi": [
+                        "packets_in",
+                        "packets_fwd",
+                        "packets_dropped"
+                    ]
+                },
+                "connection-point": [
+                    {
+                        "name": "xe0",
+                        "type": "VPORT"
+                    },
+                    {
+                        "name": "xe1",
+                        "type": "VPORT"
+                    }
+                ],
+                "description": "VPP IPsec",
+                "id": "VipsecApproxVnf",
+                "mgmt-interface": {
+                    "ip": "10.10.10.101",
+                    "password": "r00t",
+                    "user": "root",
+                    "vdu-id": "ipsecvnf-baremetal"
+                },
+                "name": "IpsecVnf",
+                "short-name": "IpsecVnf",
+                "vdu": [
+                    {
+                        "description": "VPP Ipsec",
+                        "external-interface": [
+                            {
+                                "name": "xe0",
+                                "virtual-interface": {
+                                    "dpdk_port_num": 0,
+                                    "driver": "igb_uio",
+                                    "dst_ip": "192.168.100.1",
+                                    "dst_mac": "90:e2:ba:7c:30:e8",
+                                    "ifname": "xe0",
+                                    "local_ip": "192.168.100.2",
+                                    "local_mac": "90:e2:ba:7c:41:a8",
+                                    "netmask": "255.255.255.0",
+                                    "network": {},
+                                    "node_name": "vnf__0",
+                                    "peer_ifname": "xe0",
+                                    "peer_intf": {
+                                        "dpdk_port_num": 0,
+                                        "driver": "igb_uio",
+                                        "dst_ip": "192.168.100.2",
+                                        "dst_mac": "90:e2:ba:7c:41:a8",
+                                        "ifname": "xe0",
+                                        "local_ip": "192.168.100.1",
+                                        "local_mac": "90:e2:ba:7c:30:e8",
+                                        "netmask": "255.255.255.0",
+                                        "network": {},
+                                        "node_name": "tg__0",
+                                        "peer_ifname": "xe0",
+                                        "peer_name": "vnf__0",
+                                        "vld_id": "uplink_0",
+                                        "vpci": "0000:81:00.0"
+                                    },
+                                    "peer_name": "tg__0",
+                                    "vld_id": "uplink_1",
+                                    "vpci": "0000:ff:06.0"
+                                },
+                                "vnfd-connection-point-ref": "xe0"
+                            },
+                            {
+                                "name": "xe1",
+                                "virtual-interface": {
+                                    "dpdk_port_num": 1,
+                                    "driver": "igb_uio",
+                                    "dst_ip": "1.1.1.2",
+                                    "dst_mac": "0a:b1:ec:fd:a2:66",
+                                    "ifname": "xe1",
+                                    "local_ip": "1.1.1.1",
+                                    "local_mac": "4e:90:85:d3:c5:13",
+                                    "netmask": "255.255.255.0",
+                                    "network": {},
+                                    "node_name": "vnf__1",
+                                    "peer_ifname": "xe1",
+                                    "peer_intf": {
+                                        "driver": "igb_uio",
+                                        "dst_ip": "1.1.1.1",
+                                        "dst_mac": "4e:90:85:d3:c5:13",
+                                        "ifname": "xe1",
+                                        "local_ip": "1.1.1.2",
+                                        "local_mac": "0a:b1:ec:fd:a2:66",
+                                        "netmask": "255.255.255.0",
+                                        "network": {},
+                                        "node_name": "vnf__1",
+                                        "peer_ifname": "xe1",
+                                        "peer_name": "vnf__0",
+                                        "vld_id": "ciphertext",
+                                        "vpci": "0000:00:07.0"
+                                    },
+                                    "peer_name": "vnf__1",
+                                    "vld_id": "ciphertext",
+                                    "vpci": "0000:ff:07.0"
+                                },
+                                "vnfd-connection-point-ref": "xe1"
+                            }
+                        ],
+                        "id": "ipsecvnf-baremetal",
+                        "name": "ipsecvnf-baremetal",
+                        "routing_table": []
+                    }
+                ]
+            }
+            ]}}
+
+    scenario_cfg = {
+        "nodes": {
+            "tg__0": "trafficgen.yardstick-5486cc2f",
+            "vnf__0": "vnf0.yardstick-5486cc2f",
+            "vnf__1": "vnf1.yardstick-5486cc2f"
+        },
+        "options": {
+            "flow": {
+                "count": 1,
+                "dst_ip": [
+                    "20.0.0.0-20.0.0.100"
+                ],
+                "src_ip": [
+                    "10.0.0.0-10.0.0.100"
+                ]
+            },
+            "framesize": {
+                "downlink": {
+                    "64B": 100
+                },
+                "uplink": {
+                    "64B": 100
+                }
+            },
+            "rfc2544": {
+                "allowed_drop_rate": "0.0 - 0.005"
+            },
+            "tg__0": {
+                "collectd": {
+                    "interval": 1
+                },
+                "queues_per_port": 7
+            },
+            "traffic_type": 4,
+            "vnf__0": {
+                "collectd": {
+                    "interval": 1
+                },
+                "vnf_config": {
+                    "crypto_type": "SW_cryptodev",
+                    "rxq": 1,
+                    "worker_config": "1C/1T",
+                    "worker_threads": 4
+                }
+            },
+            "vnf__1": {
+                "collectd": {
+                    "interval": 1
+                },
+                "vnf_config": {
+                    "crypto_type": "SW_cryptodev",
+                    "rxq": 1,
+                    "worker_config": "1C/1T",
+                    "worker_threads": 4
+                }
+            },
+            "vpp_config": {
+                "crypto_algorithms": "aes-gcm",
+                "tunnel": 1
+            }
+        },
+        "runner": {
+            "duration": 500,
+            "interval": 10,
+            "object":
+                "yardstick.benchmark.scenarios.networking.vnf_generic.NetworkServiceTestCase",
+            "output_config": {
+                "DEFAULT": {
+                    "debug": "False",
+                    "dispatcher": [
+                        "influxdb"
+                    ]
+                },
+                "dispatcher_file": {
+                    "debug": "False",
+                    "dispatcher": "influxdb",
+                    "file_path": "/tmp/yardstick.out"
+                },
+                "dispatcher_http": {
+                    "debug": "False",
+                    "dispatcher": "influxdb",
+                    "target": "http://127.0.0.1:8000/results",
+                    "timeout": "20"
+                },
+                "dispatcher_influxdb": {
+                    "db_name": "yardstick",
+                    "debug": "False",
+                    "dispatcher": "influxdb",
+                    "password": "r00t",
+                    "target": "http://192.168.100.3:8086",
+                    "timeout": "20",
+                    "username": "root"
+                },
+                "nsb": {
+                    "bin_path": "/opt/nsb_bin",
+                    "debug": "False",
+                    "dispatcher": "influxdb",
+                    "trex_client_lib": "/opt/nsb_bin/trex_client/stl",
+                    "trex_path": "/opt/nsb_bin/trex/scripts"
+                }
+            },
+            "runner_id": 1105,
+            "type": "Duration"
+        },
+        "task_id": "5486cc2f-d4d3-4feb-b0df-5e0bcd584c9e",
+        "task_path": "samples/vnf_samples/nsut/ipsec",
+        "tc": "tc_baremetal_rfc2544_ipv4_1flow_sw_aesgcm_4cores_64B_trex",
+        "topology": "vpp-tg-topology-2.yaml",
+        "traffic_profile": "../../traffic_profiles/ipv4_throughput_latency_vpp.yaml",
+        "type": "NSPerf"
+    }
+
+    context_cfg = {
+        "networks": {},
+        "nodes": {
+            "tg__0": {
+                "VNF model": "../../vnf_descriptors/tg_vpp_tpl.yaml",
+                "ctx_type": "Node",
+                "interfaces": {
+                    "xe0": {
+                        "dpdk_port_num": 0,
+                        "driver": "igb_uio",
+                        "dst_ip": "192.168.100.2",
+                        "dst_mac": "90:e2:ba:7c:41:a8",
+                        "ifname": "xe0",
+                        "local_ip": "192.168.100.1",
+                        "local_mac": "90:e2:ba:7c:30:e8",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "tg__0",
+                        "peer_ifname": "xe0",
+                        "peer_intf": {
+                            "dpdk_port_num": 0,
+                            "driver": "igb_uio",
+                            "dst_ip": "192.168.100.1",
+                            "dst_mac": "90:e2:ba:7c:30:e8",
+                            "ifname": "xe0",
+                            "local_ip": "192.168.100.2",
+                            "local_mac": "90:e2:ba:7c:41:a8",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__0",
+                            "peer_ifname": "xe0",
+                            "peer_name": "tg__0",
+                            "vld_id": "uplink_0",
+                            "vpci": "0000:00:06.0"
+                        },
+                        "peer_name": "vnf__0",
+                        "vld_id": "uplink_0",
+                        "vpci": "0000:81:00.0"
+                    },
+                    "xe1": {
+                        "dpdk_port_num": 1,
+                        "driver": "igb_uio",
+                        "dst_ip": "192.168.101.2",
+                        "dst_mac": "90:e2:ba:7c:41:a9",
+                        "ifname": "xe1",
+                        "local_ip": "192.168.101.1",
+                        "local_mac": "90:e2:ba:7c:30:e9",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "tg__0",
+                        "peer_ifname": "xe0",
+                        "peer_intf": {
+                            "dpdk_port_num": 1,
+                            "driver": "igb_uio",
+                            "dst_ip": "192.168.101.1",
+                            "dst_mac": "90:e2:ba:7c:30:e9",
+                            "ifname": "xe0",
+                            "local_ip": "192.168.101.2",
+                            "local_mac": "90:e2:ba:7c:41:a9",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__1",
+                            "peer_ifname": "xe1",
+                            "peer_name": "tg__0",
+                            "vld_id": "downlink_0",
+                            "vpci": "0000:00:06.0"
+                        },
+                        "peer_name": "vnf__1",
+                        "vld_id": "downlink_0",
+                        "vpci": "0000:81:00.1"
+                    }
+                },
+                "ip": "10.10.10.10",
+                "member-vnf-index": "1",
+                "name": "trafficgen.yardstick-5486cc2f",
+                "password": "r00t",
+                "port": 22,
+                "role": "TrafficGen",
+                "user": "root",
+                "username": "root",
+                "vnfd-id-ref": "tg__0"
+            },
+            "vnf__0": {
+                "VNF model": "../../vnf_descriptors/vpp_vnfd.yaml",
+                "ctx_type": "Node",
+                "interfaces": {
+                    "xe0": {
+                        "dpdk_port_num": 0,
+                        "driver": "igb_uio",
+                        "dst_ip": "192.168.100.1",
+                        "dst_mac": "90:e2:ba:7c:30:e8",
+                        "ifname": "xe0",
+                        "local_ip": "192.168.100.2",
+                        "local_mac": "90:e2:ba:7c:41:a8",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "vnf__0",
+                        "peer_ifname": "xe0",
+                        "peer_intf": {
+                            "dpdk_port_num": 0,
+                            "driver": "igb_uio",
+                            "dst_ip": "192.168.100.2",
+                            "dst_mac": "90:e2:ba:7c:41:a8",
+                            "ifname": "xe0",
+                            "local_ip": "192.168.100.1",
+                            "local_mac": "90:e2:ba:7c:30:e8",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "tg__0",
+                            "peer_ifname": "xe0",
+                            "peer_name": "vnf__0",
+                            "vld_id": "uplink_0",
+                            "vpci": "0000:81:00.0"
+                        },
+                        "peer_name": "tg__0",
+                        "vld_id": "uplink_0",
+                        "vpci": "0000:00:06.0"
+                    },
+                    "xe1": {
+                        "dpdk_port_num": 1,
+                        "driver": "igb_uio",
+                        "dst_ip": "1.1.1.2",
+                        "dst_mac": "0a:b1:ec:fd:a2:66",
+                        "ifname": "xe1",
+                        "local_ip": "1.1.1.1",
+                        "local_mac": "4e:90:85:d3:c5:13",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "vnf__0",
+                        "peer_ifname": "xe1",
+                        "peer_intf": {
+                            "dpdk_port_num": 1,
+                            "driver": "igb_uio",
+                            "dst_ip": "1.1.1.1",
+                            "dst_mac": "4e:90:85:d3:c5:13",
+                            "ifname": "xe1",
+                            "local_ip": "1.1.1.2",
+                            "local_mac": "0a:b1:ec:fd:a2:66",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__1",
+                            "peer_ifname": "xe1",
+                            "peer_name": "vnf__0",
+                            "vld_id": "ciphertext",
+                            "vpci": "0000:00:07.0"
+                        },
+                        "peer_name": "vnf__1",
+                        "vld_id": "ciphertext",
+                        "vpci": "0000:00:07.0"
+                    }
+                },
+                "ip": "10.10.10.101",
+                "member-vnf-index": "2",
+                "name": "vnf0.yardstick-5486cc2f",
+                "password": "r00t",
+                "port": 22,
+                "role": "VirtualNetworkFunction",
+                "user": "root",
+                "username": "root",
+                "vnfd-id-ref": "vnf__0"
+            },
+            "vnf__1": {
+                "VNF model": "../../vnf_descriptors/vpp_vnfd.yaml",
+                "ctx_type": "Node",
+                "interfaces": {
+                    "xe0": {
+                        "dpdk_port_num": 0,
+                        "driver": "igb_uio",
+                        "dst_ip": "192.168.101.1",
+                        "dst_mac": "90:e2:ba:7c:30:e9",
+                        "ifname": "xe0",
+                        "local_ip": "192.168.101.2",
+                        "local_mac": "90:e2:ba:7c:41:a9",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "vnf__1",
+                        "peer_ifname": "xe1",
+                        "peer_intf": {
+                            "dpdk_port_num": 1,
+                            "driver": "igb_uio",
+                            "dst_ip": "192.168.101.2",
+                            "dst_mac": "90:e2:ba:7c:41:a9",
+                            "ifname": "xe1",
+                            "local_ip": "192.168.101.1",
+                            "local_mac": "90:e2:ba:7c:30:e9",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "tg__0",
+                            "peer_ifname": "xe0",
+                            "peer_name": "vnf__1",
+                            "vld_id": "downlink_0",
+                            "vpci": "0000:81:00.1"
+                        },
+                        "peer_name": "tg__0",
+                        "vld_id": "downlink_0",
+                        "vpci": "0000:00:06.0"
+                    },
+                    "xe1": {
+                        "dpdk_port_num": 1,
+                        "driver": "igb_uio",
+                        "dst_ip": "1.1.1.1",
+                        "dst_mac": "4e:90:85:d3:c5:13",
+                        "ifname": "xe1",
+                        "local_ip": "1.1.1.2",
+                        "local_mac": "0a:b1:ec:fd:a2:66",
+                        "netmask": "255.255.255.0",
+                        "network": {},
+                        "node_name": "vnf__1",
+                        "peer_ifname": "xe1",
+                        "peer_intf": {
+                            "dpdk_port_num": 1,
+                            "driver": "igb_uio",
+                            "dst_ip": "1.1.1.2",
+                            "dst_mac": "0a:b1:ec:fd:a2:66",
+                            "ifname": "xe1",
+                            "local_ip": "1.1.1.1",
+                            "local_mac": "4e:90:85:d3:c5:13",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__0",
+                            "peer_ifname": "xe1",
+                            "peer_name": "vnf__1",
+                            "vld_id": "ciphertext",
+                            "vpci": "0000:00:07.0"
+                        },
+                        "peer_name": "vnf__0",
+                        "vld_id": "ciphertext",
+                        "vpci": "0000:00:07.0"
+                    }
+                },
+                "ip": "10.10.10.102",
+                "member-vnf-index": "3",
+                "name": "vnf1.yardstick-5486cc2f",
+                "password": "r00t",
+                "port": 22,
+                "role": "VirtualNetworkFunction",
+                "user": "root",
+                "username": "root",
+                "vnfd-id-ref": "vnf__1"
+            }
+        }
+    }
+
+    def test___init__(self, *args):
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        self.assertIsNone(vipsec_vnf._vnf_process)
+
+    @mock.patch(SSH_HELPER)
+    def test__run(self, ssh, *args):
+        mock_ssh(ssh)
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf._build_config = mock.MagicMock()
+        vipsec_vnf.setup_helper.kill_vnf = mock.MagicMock()
+        vipsec_vnf.setup_helper.create_ipsec_tunnels = mock.MagicMock()
+        vipsec_vnf.queue_wrapper = mock.MagicMock()
+        vipsec_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
+        vipsec_vnf.vnf_cfg = {'lb_config': 'SW',
+                              'lb_count': 1,
+                              'worker_config': '1C/1T',
+                              'worker_threads': 1}
+        vipsec_vnf.all_options = {'traffic_type': '4',
+                                  'topology': 'nsb_test_case.yaml'}
+        vipsec_vnf._run()
+        # vipsec_vnf.setup_helper.ssh_helper.execute.assert_called_once()
+
+    @mock.patch(SSH_HELPER)
+    def test_wait_for_instantiate(self, ssh, *args):
+        mock_ssh(ssh)
+
+        mock_process = mock.Mock(autospec=Process)
+        mock_process.is_alive.return_value = True
+        mock_process.exitcode = 432
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf.resource_helper.resource = mock.MagicMock()
+        vipsec_vnf.setup_helper = mock.MagicMock()
+        vipsec_vnf.setup_helper.check_status.return_value = True
+        vipsec_vnf._vnf_process = mock_process
+        vipsec_vnf.WAIT_TIME = 0
+        self.assertEqual(vipsec_vnf.wait_for_instantiate(), 432)
+
+    @mock.patch(SSH_HELPER)
+    def test_wait_for_instantiate_crash(self, ssh, *args):
+        mock_ssh(ssh)
+
+        mock_process = mock.Mock(autospec=Process)
+        mock_process.is_alive.return_value = False
+        mock_process.exitcode = 432
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf.resource_helper.resource = mock.MagicMock()
+        vipsec_vnf.setup_helper = mock.MagicMock()
+        vipsec_vnf.setup_helper.check_status.return_value = False
+        vipsec_vnf._vnf_process = mock_process
+        vipsec_vnf.WAIT_TIME = 0
+        vipsec_vnf.WAIT_TIME_FOR_SCRIPT = 0
+
+        with self.assertRaises(RuntimeError) as raised:
+            vipsec_vnf.wait_for_instantiate()
+
+        self.assertIn('VNF process died', str(raised.exception))
+
+    @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server',
+                       return_value='mock_node')
+    @mock.patch.object(ipsec_vnf.VipsecApproxSetupEnvHelper,
+                       'get_vpp_statistics',
+                       return_value={'packets_in': 0, 'packets_fwd': 0,
+                                     'packets_dropped': 0})
+    @mock.patch(SSH_HELPER)
+    def test_collect_kpi(self, ssh, *args):
+        mock_ssh(ssh)
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf.scenario_helper.scenario_cfg = {
+            'nodes': {vipsec_vnf.name: "mock"}
+        }
+        result = {
+            'collect_stats': {'packets_in': 0, 'packets_fwd': 0,
+                              'packets_dropped': 0},
+            'physical_node': 'mock_node'
+        }
+        self.assertEqual(result, vipsec_vnf.collect_kpi())
+
+    @mock.patch.object(utils, 'find_relative_file')
+    @mock.patch(
+        "yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
+    @mock.patch(SSH_HELPER)
+    def test_instantiate(self, ssh, *args):
+        mock_ssh(ssh)
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf.deploy_helper = mock.MagicMock()
+        vipsec_vnf.resource_helper = mock.MagicMock()
+        vipsec_vnf._build_config = mock.MagicMock()
+        vipsec_vnf.WAIT_TIME = 0
+        self.scenario_cfg.update({"nodes": {"vnf__1": ""}})
+        self.assertIsNone(vipsec_vnf.instantiate(self.scenario_cfg,
+                                                 self.context_cfg))
+
+    @mock.patch.object(ipsec_vnf.VipsecApproxSetupEnvHelper, 'kill_vnf',
+                       return_value='')
+    @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
+    @mock.patch(SSH_HELPER)
+    def test_terminate(self, ssh, *args):
+        mock_ssh(ssh)
+
+        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+        vipsec_vnf = ipsec_vnf.VipsecApproxVnf(NAME, vnfd)
+        vipsec_vnf._vnf_process = mock.MagicMock()
+        vipsec_vnf._vnf_process.terminate = mock.Mock()
+        self.assertIsNone(vipsec_vnf.terminate())
+
+
+class TestVipsecApproxSetupEnvHelper(unittest.TestCase):
+    ALL_OPTIONS = {
+        "flow": {
+            "count": 1,
+            "dst_ip": [
+                "20.0.0.0-20.0.0.100"
+            ],
+            "src_ip": [
+                "10.0.0.0-10.0.0.100"
+            ]
+        },
+        "framesize": {
+            "downlink": {
+                "64B": 100
+            },
+            "uplink": {
+                "64B": 100
+            }
+        },
+        "rfc2544": {
+            "allowed_drop_rate": "0.0 - 0.005"
+        },
+        "tg__0": {
+            "collectd": {
+                "interval": 1
+            },
+            "queues_per_port": 7
+        },
+        "traffic_type": 4,
+        "vnf__0": {
+            "collectd": {
+                "interval": 1
+            },
+            "vnf_config": {
+                "crypto_type": "SW_cryptodev",
+                "rxq": 1,
+                "worker_config": "1C/1T",
+                "worker_threads": 4
+            }
+        },
+        "vnf__1": {
+            "collectd": {
+                "interval": 1
+            },
+            "vnf_config": {
+                "crypto_type": "SW_cryptodev",
+                "rxq": 1,
+                "worker_config": "1C/1T",
+                "worker_threads": 4
+            }
+        },
+        "vpp_config": {
+            "crypto_algorithms": "aes-gcm",
+            "tunnel": 1
+        }
+    }
+
+    ALL_OPTIONS_ERROR = {
+        "flow_error": {
+            "count": 1,
+            "dst_ip": [
+                "20.0.0.0-20.0.0.100"
+            ],
+            "src_ip": [
+                "10.0.0.0-10.0.0.100"
+            ]
+        },
+        "framesize": {
+            "downlink": {
+                "64B": 100
+            },
+            "uplink": {
+                "64B": 100
+            }
+        },
+        "rfc2544": {
+            "allowed_drop_rate": "0.0 - 0.005"
+        },
+        "tg__0": {
+            "collectd": {
+                "interval": 1
+            },
+            "queues_per_port": 7
+        },
+        "traffic_type": 4,
+        "vnf__0": {
+            "collectd": {
+                "interval": 1
+            },
+            "vnf_config": {
+                "crypto_type": "SW_cryptodev",
+                "rxq": 1,
+                "worker_config": "1C/1T",
+                "worker_threads": 4
+            }
+        },
+        "vnf__1": {
+            "collectd": {
+                "interval": 1
+            },
+            "vnf_config": {
+                "crypto_type": "SW_cryptodev",
+                "rxq": 1,
+                "worker_config": "1C/1T",
+                "worker_threads": 4
+            }
+        },
+        "vpp_config": {
+            "crypto_algorithms": "aes-gcm",
+            "tunnel": 1
+        }
+    }
+
+    OPTIONS = {
+        "collectd": {
+            "interval": 1
+        },
+        "vnf_config": {
+            "crypto_type": "SW_cryptodev",
+            "rxq": 1,
+            "worker_config": "1C/1T",
+            "worker_threads": 4
+        }
+    }
+
+    CPU_LAYOUT = {'cpuinfo': [[0, 0, 0, 0, 0, 0, 0, 0],
+                              [1, 0, 0, 0, 0, 1, 1, 0],
+                              [2, 1, 0, 0, 0, 2, 2, 1],
+                              [3, 1, 0, 0, 0, 3, 3, 1],
+                              [4, 2, 0, 0, 0, 4, 4, 2],
+                              [5, 2, 0, 0, 0, 5, 5, 2],
+                              [6, 3, 0, 0, 0, 6, 6, 3],
+                              [7, 3, 0, 0, 0, 7, 7, 3],
+                              [8, 4, 0, 0, 0, 8, 8, 4],
+                              [9, 5, 0, 1, 0, 9, 9, 4],
+                              [10, 6, 0, 1, 0, 10, 10, 5],
+                              [11, 6, 0, 1, 0, 11, 11, 5],
+                              [12, 7, 0, 1, 0, 12, 12, 6],
+                              [13, 7, 0, 1, 0, 13, 13, 6],
+                              [14, 8, 0, 1, 0, 14, 14, 7],
+                              [15, 8, 0, 1, 0, 15, 15, 7],
+                              [16, 9, 0, 1, 0, 16, 16, 8],
+                              [17, 9, 0, 1, 0, 17, 17, 8]]}
+
+    VPP_INTERFACES_DUMP = [
+        {
+            "sw_if_index": 0,
+            "sup_sw_if_index": 0,
+            "l2_address_length": 0,
+            "l2_address": [0, 0, 0, 0, 0, 0, 0, 0],
+            "interface_name": "local0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 0,
+            "link_speed": 0,
+            "mtu": 0,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        },
+        {
+            "sw_if_index": 1,
+            "sup_sw_if_index": 1,
+            "l2_address_length": 6,
+            "l2_address": [144, 226, 186, 124, 65, 168, 0, 0],
+            "interface_name": "TenGigabitEthernetff/6/0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 2,
+            "link_speed": 32,
+            "mtu": 9202,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        },
+        {
+            "sw_if_index": 2,
+            "sup_sw_if_index": 2,
+            "l2_address_length": 6,
+            "l2_address": [78, 144, 133, 211, 197, 19, 0, 0],
+            "interface_name": "VirtualFunctionEthernetff/7/0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 2,
+            "link_speed": 32,
+            "mtu": 9206,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        }
+    ]
+
+    VPP_INTERFACES_STATUS = \
+        '              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)' \
+        'Counter          Count     \n' \
+        'TenGigabitEthernetff/6/0          1     up         9000/0/0/0    \n' \
+        'VirtualFunctionEthernetff/7/0     2     up         9000/0/0/0    \n' \
+        'ipsec0                            2     up         9000/0/0/0    \n' \
+        'local0                            0     down          0/0/0/0      '
+
+    VPP_INTERFACES_STATUS_FALSE = \
+        '              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)' \
+        'Counter          Count     \n' \
+        'TenGigabitEthernetff/6/0          1     down         9000/0/0/0  \n' \
+        'VirtualFunctionEthernetff/7/0     2     down         9000/0/0/0  \n' \
+        'ipsec0                            2     down         9000/0/0/0  \n' \
+        'local0                            0     down          0/0/0/0      '
+
+    def test__get_crypto_type(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.options = self.OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('SW_cryptodev',
+                         ipsec_approx_setup_helper._get_crypto_type())
+
+    def test__get_crypto_algorithms(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('aes-gcm',
+                         ipsec_approx_setup_helper._get_crypto_algorithms())
+
+    def test__get_n_tunnels(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(1, ipsec_approx_setup_helper._get_n_tunnels())
+
+    def test__get_n_connections(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(1, ipsec_approx_setup_helper._get_n_connections())
+
+    def test__get_n_connections_error(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS_ERROR
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        with self.assertRaises(KeyError) as raised:
+            ipsec_approx_setup_helper._get_n_connections()
+        self.assertIn(
+            'Missing flow definition in scenario section of the task definition file',
+            str(raised.exception))
+
+    def test__get_flow_src_start_ip(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('10.0.0.0',
+                         ipsec_approx_setup_helper._get_flow_src_start_ip())
+
+    def test__get_flow_src_start_ip_vnf1(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD_ERROR['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('20.0.0.0',
+                         ipsec_approx_setup_helper._get_flow_src_start_ip())
+
+    def test__get_flow_src_start_ip_error(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS_ERROR
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        with self.assertRaises(KeyError) as raised:
+            ipsec_approx_setup_helper._get_flow_src_start_ip()
+        self.assertIn(
+            'Missing flow definition in scenario section of the task definition file',
+            str(raised.exception))
+
+    def test__get_flow_dst_start_ip(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('20.0.0.0',
+                         ipsec_approx_setup_helper._get_flow_dst_start_ip())
+
+    def test__get_flow_dst_start_ip_vnf1(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD_ERROR['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual('10.0.0.0',
+                         ipsec_approx_setup_helper._get_flow_dst_start_ip())
+
+    def test__get_flow_dst_start_ip_error(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        scenario_helper.all_options = self.ALL_OPTIONS_ERROR
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        with self.assertRaises(KeyError) as raised:
+            ipsec_approx_setup_helper._get_flow_dst_start_ip()
+        self.assertIn(
+            'Missing flow definition in scenario section of the task definition file',
+            str(raised.exception))
+
+    def test_build_config(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        ipsec_approx_setup_helper.build_config()
+
+    @mock.patch.object(utils, 'setup_hugepages')
+    def test_setup_vnf_environment(self, *args):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 0, '0', ''
+        scenario_helper = mock.Mock()
+        scenario_helper.nodes = [None, None]
+        scenario_helper.options = self.OPTIONS
+        scenario_helper.all_options = self.ALL_OPTIONS
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertIsInstance(
+            ipsec_approx_setup_helper.setup_vnf_environment(),
+            ResourceProfile)
+
+    def test_calculate_frame_size(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(16984 / 48,
+                         ipsec_approx_setup_helper.calculate_frame_size(
+                             {'64B': 28, '570B': 16, '1518B': 4}))
+
+    def test_calculate_frame_size_64(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(64,
+                         ipsec_approx_setup_helper.calculate_frame_size({}))
+
+    def test_calculate_frame_size_64_error(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(64,
+                         ipsec_approx_setup_helper.calculate_frame_size(
+                             {'64B': -28, '570B': 16, '1518B': 4}))
+
+    def test_check_status(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 0, self.VPP_INTERFACES_STATUS, ''
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertTrue(ipsec_approx_setup_helper.check_status())
+
+    def test_check_status_false(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 0, self.VPP_INTERFACES_STATUS_FALSE, ''
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertFalse(ipsec_approx_setup_helper.check_status())
+
+    def test_get_vpp_statistics(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        ipsec_approx_setup_helper.get_vpp_statistics()
+
+    def test_create_ipsec_tunnels(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        ipsec_approx_setup_helper.create_ipsec_tunnels()
+
+    def test_find_raw_data_interface(self):
+        expected = {'dpdk_port_num': 0,
+                    'driver': 'igb_uio',
+                    'dst_ip': '192.168.100.1',
+                    'dst_mac': '90:e2:ba:7c:30:e8',
+                    'ifname': 'xe0',
+                    'local_ip': '192.168.100.2',
+                    'local_mac': '90:e2:ba:7c:41:a8',
+                    'netmask': '255.255.255.0',
+                    'network': {},
+                    'node_name': 'vnf__0',
+                    'peer_ifname': 'xe0',
+                    'peer_intf': {'dpdk_port_num': 0,
+                                  'driver': 'igb_uio',
+                                  'dst_ip': '192.168.100.2',
+                                  'dst_mac': '90:e2:ba:7c:41:a8',
+                                  'ifname': 'xe0',
+                                  'local_ip': '192.168.100.1',
+                                  'local_mac': '90:e2:ba:7c:30:e8',
+                                  'netmask': '255.255.255.0',
+                                  'network': {},
+                                  'node_name': 'tg__0',
+                                  'peer_ifname': 'xe0',
+                                  'peer_name': 'vnf__0',
+                                  'vld_id': 'uplink_0',
+                                  'vpci': '0000:81:00.0'},
+                    'peer_name': 'tg__0',
+                    'vld_id': 'uplink_0',
+                    'vpci': '0000:ff:06.0'}
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(expected,
+                         ipsec_approx_setup_helper.find_raw_data_interface())
+
+    def test_find_raw_data_interface_error(self):
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD_ERROR['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        with self.assertRaises(KeyError):
+            ipsec_approx_setup_helper.find_raw_data_interface()
+
+    def test_find_encrypted_data_interface(self):
+        expected = {'dpdk_port_num': 1,
+                    'driver': 'igb_uio',
+                    'dst_ip': '1.1.1.2',
+                    'dst_mac': '0a:b1:ec:fd:a2:66',
+                    'ifname': 'xe1',
+                    'local_ip': '1.1.1.1',
+                    'local_mac': '4e:90:85:d3:c5:13',
+                    'netmask': '255.255.255.0',
+                    'network': {},
+                    'node_name': 'vnf__0',
+                    'peer_ifname': 'xe1',
+                    'peer_intf': {'driver': 'igb_uio',
+                                  'dst_ip': '1.1.1.1',
+                                  'dst_mac': '4e:90:85:d3:c5:13',
+                                  'ifname': 'xe1',
+                                  'local_ip': '1.1.1.2',
+                                  'local_mac': '0a:b1:ec:fd:a2:66',
+                                  'netmask': '255.255.255.0',
+                                  'network': {},
+                                  'node_name': 'vnf__1',
+                                  'peer_ifname': 'xe1',
+                                  'peer_name': 'vnf__0',
+                                  'vld_id': 'ciphertext',
+                                  'vpci': '0000:00:07.0'},
+                    'peer_name': 'vnf__1',
+                    'vld_id': 'ciphertext',
+                    'vpci': '0000:ff:07.0'}
+        vnfd_helper = VnfdHelper(
+            TestVipsecApproxVnf.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+
+        ipsec_approx_setup_helper = VipsecApproxSetupEnvHelper(vnfd_helper,
+                                                               ssh_helper,
+                                                               scenario_helper)
+        self.assertEqual(expected,
+                         ipsec_approx_setup_helper.find_encrypted_data_interface())
diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_vpp_helpers.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_vpp_helpers.py
new file mode 100644 (file)
index 0000000..597844c
--- /dev/null
@@ -0,0 +1,335 @@
+# Copyright (c) 2019 Viosoft 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 unittest
+
+import mock
+
+from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
+from yardstick.network_services.vnf_generic.vnf.vpp_helpers import \
+    VppSetupEnvHelper
+
+
+class TestVppSetupEnvHelper(unittest.TestCase):
+    VNFD_0 = {
+        "benchmark": {
+            "kpi": [
+                "packets_in",
+                "packets_fwd",
+                "packets_dropped"
+            ]
+        },
+        "connection-point": [
+            {
+                "name": "xe0",
+                "type": "VPORT"
+            },
+            {
+                "name": "xe1",
+                "type": "VPORT"
+            }
+        ],
+        "description": "VPP IPsec",
+        "id": "VipsecApproxVnf",
+        "mgmt-interface": {
+            "ip": "10.10.10.101",
+            "password": "r00t",
+            "user": "root",
+            "vdu-id": "ipsecvnf-baremetal"
+        },
+        "name": "IpsecVnf",
+        "short-name": "IpsecVnf",
+        "vdu": [
+            {
+                "description": "VPP Ipsec",
+                "external-interface": [
+                    {
+                        "name": "xe0",
+                        "virtual-interface": {
+                            "driver": "igb_uio",
+                            "dst_ip": "192.168.100.1",
+                            "dst_mac": "90:e2:ba:7c:30:e8",
+                            "ifname": "xe0",
+                            "local_ip": "192.168.100.2",
+                            "local_mac": "90:e2:ba:7c:41:a8",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__0",
+                            "peer_ifname": "xe0",
+                            "peer_intf": {
+                                "dpdk_port_num": 0,
+                                "driver": "igb_uio",
+                                "dst_ip": "192.168.100.2",
+                                "dst_mac": "90:e2:ba:7c:41:a8",
+                                "ifname": "xe0",
+                                "local_ip": "192.168.100.1",
+                                "local_mac": "90:e2:ba:7c:30:e8",
+                                "netmask": "255.255.255.0",
+                                "network": {},
+                                "node_name": "tg__0",
+                                "peer_ifname": "xe0",
+                                "peer_name": "vnf__0",
+                                "vld_id": "uplink_0",
+                                "vpci": "0000:81:00.0"
+                            },
+                            "peer_name": "tg__0",
+                            "vld_id": "uplink_0",
+                            "vpci": "0000:ff:06.0"
+                        },
+                        "vnfd-connection-point-ref": "xe0"
+                    },
+                    {
+                        "name": "xe1",
+                        "virtual-interface": {
+                            "driver": "igb_uio",
+                            "dst_ip": "1.1.1.2",
+                            "dst_mac": "0a:b1:ec:fd:a2:66",
+                            "ifname": "xe1",
+                            "local_ip": "1.1.1.1",
+                            "local_mac": "4e:90:85:d3:c5:13",
+                            "netmask": "255.255.255.0",
+                            "network": {},
+                            "node_name": "vnf__0",
+                            "peer_ifname": "xe1",
+                            "peer_intf": {
+                                "driver": "igb_uio",
+                                "dst_ip": "1.1.1.1",
+                                "dst_mac": "4e:90:85:d3:c5:13",
+                                "ifname": "xe1",
+                                "local_ip": "1.1.1.2",
+                                "local_mac": "0a:b1:ec:fd:a2:66",
+                                "netmask": "255.255.255.0",
+                                "network": {},
+                                "node_name": "vnf__1",
+                                "peer_ifname": "xe1",
+                                "peer_name": "vnf__0",
+                                "vld_id": "ciphertext",
+                                "vpci": "0000:00:07.0"
+                            },
+                            "peer_name": "vnf__1",
+                            "vld_id": "ciphertext",
+                            "vpci": "0000:ff:07.0"
+                        },
+                        "vnfd-connection-point-ref": "xe1"
+                    }
+                ],
+                "id": "ipsecvnf-baremetal",
+                "name": "ipsecvnf-baremetal",
+                "routing_table": []
+            }
+        ]
+    }
+
+    VNFD = {
+        'vnfd:vnfd-catalog': {
+            'vnfd': [
+                VNFD_0,
+            ],
+        },
+    }
+
+    VPP_INTERFACES_DUMP = [
+        {
+            "sw_if_index": 0,
+            "sup_sw_if_index": 0,
+            "l2_address_length": 0,
+            "l2_address": [0, 0, 0, 0, 0, 0, 0, 0],
+            "interface_name": "local0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 0,
+            "link_speed": 0,
+            "mtu": 0,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        },
+        {
+            "sw_if_index": 1,
+            "sup_sw_if_index": 1,
+            "l2_address_length": 6,
+            "l2_address": [144, 226, 186, 124, 65, 168, 0, 0],
+            "interface_name": "TenGigabitEthernetff/6/0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 2,
+            "link_speed": 32,
+            "mtu": 9202,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        },
+        {
+            "sw_if_index": 2,
+            "sup_sw_if_index": 2,
+            "l2_address_length": 6,
+            "l2_address": [78, 144, 133, 211, 197, 19, 0, 0],
+            "interface_name": "VirtualFunctionEthernetff/7/0",
+            "admin_up_down": 0,
+            "link_up_down": 0,
+            "link_duplex": 2,
+            "link_speed": 32,
+            "mtu": 9206,
+            "sub_id": 0,
+            "sub_dot1ad": 0,
+            "sub_number_of_tags": 0,
+            "sub_outer_vlan_id": 0,
+            "sub_inner_vlan_id": 0,
+            "sub_exact_match": 0,
+            "sub_default": 0,
+            "sub_outer_vlan_id_any": 0,
+            "sub_inner_vlan_id_any": 0,
+            "vtr_op": 0,
+            "vtr_push_dot1q": 0,
+            "vtr_tag1": 0,
+            "vtr_tag2": 0
+        }
+    ]
+
+    def test_kill_vnf(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 0, 0, 0
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper.kill_vnf()
+
+    def test_kill_vnf_error(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 1, 0, 0
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        with self.assertRaises(RuntimeError) as raised:
+            vpp_setup_env_helper.kill_vnf()
+
+        self.assertIn('Failed to stop service vpp', str(raised.exception))
+
+    def test_tear_down(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper.tear_down()
+
+    def test_start_vpp_service(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 0, 0, 0
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper.start_vpp_service()
+
+    def test_start_vpp_service_error(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        ssh_helper.execute.return_value = 1, 0, 0
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        with self.assertRaises(RuntimeError) as raised:
+            vpp_setup_env_helper.start_vpp_service()
+
+        self.assertIn('Failed to start service vpp', str(raised.exception))
+
+    def test__update_vnfd_helper(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper._update_vnfd_helper(
+            {'vpp-data': {'vpp-key': 'vpp-value'}})
+
+        self.assertEqual({'vpp-key': 'vpp-value'},
+                         vpp_setup_env_helper.vnfd_helper.get('vpp-data', {}))
+
+    def test__update_vnfd_helper_with_key(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper._update_vnfd_helper({'driver': 'qat'}, 'xe0')
+
+        self.assertEqual('qat',
+                         vpp_setup_env_helper.get_value_by_interface_key(
+                             'xe0', 'driver'))
+
+    def test__update_vnfd_helper_dict_without_key(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper._update_vnfd_helper(
+            {'mgmt-interface': {'name': 'net'}})
+
+        self.assertEqual({'ip': '10.10.10.101',
+                          'name': 'net',
+                          'password': 'r00t',
+                          'user': 'root',
+                          'vdu-id': 'ipsecvnf-baremetal'},
+                         vpp_setup_env_helper.vnfd_helper.get('mgmt-interface',
+                                                              {}))
+
+    def test_get_value_by_interface_key(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper._update_vnfd_helper(
+            {'vpp-data': {'vpp-key': 'vpp-value'}}, 'xe0')
+
+        self.assertEqual({'vpp-key': 'vpp-value'},
+                         vpp_setup_env_helper.get_value_by_interface_key(
+                             'xe0', 'vpp-data'))
+
+    def test_get_value_by_interface_key_error(self):
+        vnfd_helper = VnfdHelper(self.VNFD_0)
+        ssh_helper = mock.Mock()
+
+        scenario_helper = mock.Mock()
+        vpp_setup_env_helper = VppSetupEnvHelper(vnfd_helper, ssh_helper,
+                                                 scenario_helper)
+        vpp_setup_env_helper._update_vnfd_helper(
+            {'vpp-data': {'vpp-key': 'vpp-value'}}, 'xe0')
+
+        self.assertIsNone(vpp_setup_env_helper.get_value_by_interface_key(
+            'xe2', 'vpp-err'))