Add sipp trafficgen based SampleVNFTrafficGen 85/63985/24
authortreyad <treyad@viosoft.com>
Thu, 25 Oct 2018 05:02:42 +0000 (22:02 -0700)
committertreyad <treyad@viosoft.com>
Fri, 5 Apr 2019 10:02:13 +0000 (03:02 -0700)
This patch defines:
  - Generic VNF APIs to test Network service:
  --> instantiate: prepare the arguments for run sipp
  --> run_traffic: run sipp test and handle the result file
  --> collect_kpi: collect results and push to queue
  --> terminate

JIRA: YARDSTICK-1446

Change-Id: I7f6b7dd253164bb5c359ac866cb8cae81f504d65
Signed-off-by: treyad <treyad@viosoft.com>
samples/vnf_samples/traffic_profiles/sip.yaml [new file with mode: 0644]
yardstick/network_services/traffic_profile/__init__.py
yardstick/network_services/traffic_profile/sip.py [new file with mode: 0644]
yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py [new file with mode: 0644]
yardstick/tests/unit/network_services/traffic_profile/test_sip.py [new file with mode: 0644]
yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_imsbench_sipp.py [new file with mode: 0644]

diff --git a/samples/vnf_samples/traffic_profiles/sip.yaml b/samples/vnf_samples/traffic_profiles/sip.yaml
new file mode 100644 (file)
index 0000000..4925973
--- /dev/null
@@ -0,0 +1,25 @@
+# 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.
+
+schema: "nsb:traffic_profile:0.1"
+
+# This file is a template, it will be filled with values from tc.yaml before passing to the traffic generator
+
+name:            sip
+description:     Traffic profile to run sip
+traffic_profile:
+  traffic_type : SipProfile # defines traffic behavior - constant or look for highest possible throughput
+  frame_rate : 100  # pc of linerate
+  duration: {{ duration }}
+  enable_latency: False
index c5d8eff..85b3d54 100644 (file)
@@ -31,6 +31,7 @@ def register_modules():
         'yardstick.network_services.traffic_profile.pktgen',
         'yardstick.network_services.traffic_profile.landslide_profile',
         'yardstick.network_services.traffic_profile.vpp_rfc2544',
+        'yardstick.network_services.traffic_profile.sip',
     ]
 
     for module in modules:
diff --git a/yardstick/network_services/traffic_profile/sip.py b/yardstick/network_services/traffic_profile/sip.py
new file mode 100644 (file)
index 0000000..d185740
--- /dev/null
@@ -0,0 +1,32 @@
+# 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.
+
+from yardstick.network_services.traffic_profile import base
+
+
+class SipProfile(base.TrafficProfile):
+    """ Sipp Traffic profile """
+
+    def __init__(self, yaml_data):
+        super(SipProfile, self).__init__(yaml_data)
+        self.generator = None
+
+    def execute_traffic(self, traffic_generator=None):
+        if traffic_generator is not None and self.generator is None:
+            self.generator = traffic_generator
+
+    def is_ended(self):
+        if self.generator is not None:
+            return self.generator.is_ended()
+        return False
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py b/yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py
new file mode 100644 (file)
index 0000000..70557b8
--- /dev/null
@@ -0,0 +1,143 @@
+# 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 collections import deque
+
+from yardstick.network_services.vnf_generic.vnf import sample_vnf
+
+LOG = logging.getLogger(__name__)
+
+
+class SippSetupEnvHelper(sample_vnf.SetupEnvHelper):
+    APP_NAME = "ImsbenchSipp"
+
+
+class SippResourceHelper(sample_vnf.ClientResourceHelper):
+    pass
+
+
+class SippVnf(sample_vnf.SampleVNFTrafficGen):
+    """
+    This class calls the test script from TG machine, then gets the result file
+    from IMS machine. After that, the result file is handled line by line, and
+    is updated to database.
+    """
+
+    APP_NAME = "ImsbenchSipp"
+    APP_WORD = "ImsbenchSipp"
+    VNF_TYPE = "ImsbenchSipp"
+    HW_OFFLOADING_NFVI_TYPES = {'baremetal', 'sriov'}
+    RESULT = "/tmp/final_result.dat"
+    SIPP_RESULT = "/tmp/sipp_dat_files/final_result.dat"
+    LOCAL_PATH = "/tmp"
+    CMD = "./SIPp_benchmark.bash {} {} {} '{}'"
+
+    def __init__(self, name, vnfd, setup_env_helper_type=None,
+                 resource_helper_type=None):
+        if resource_helper_type is None:
+            resource_helper_type = SippResourceHelper
+        if setup_env_helper_type is None:
+            setup_env_helper_type = SippSetupEnvHelper
+        super(SippVnf, self).__init__(
+            name, vnfd, setup_env_helper_type, resource_helper_type)
+        self.params = ""
+        self.pcscf_ip = self.vnfd_helper.interfaces[0]["virtual-interface"]\
+            ["peer_intf"]["local_ip"]
+        self.sipp_ip = self.vnfd_helper.interfaces[0]["virtual-interface"]\
+            ["local_ip"]
+        self.media_ip = self.vnfd_helper.interfaces[1]["virtual-interface"]\
+            ["local_ip"]
+        self.queue = ""
+        self.count = 0
+
+    def instantiate(self, scenario_cfg, context_cfg):
+        super(SippVnf, self).instantiate(scenario_cfg, context_cfg)
+        scenario_cfg = {}
+        _params = [("port", 5060), ("start_user", 1), ("end_user", 10000),
+                    ("init_reg_cps", 50), ("init_reg_max", 5000), ("reg_cps", 50),
+                    ("reg_step", 10), ("rereg_cps", 10), ("rereg_step", 5),
+                    ("dereg_cps", 10), ("dereg_step", 5), ("msgc_cps", 10),
+                    ("msgc_step", 2), ("run_mode", "rtp"), ("call_cps", 10),
+                    ("hold_time", 15), ("call_step", 5)]
+
+        self.params = ';'.join([str(scenario_cfg.get("options", {}).get(k, v))
+                                for k, v in dict(_params).items()])
+
+    def wait_for_instantiate(self):
+        pass
+
+    def get_result_files(self):
+        self.ssh_helper.get(self.SIPP_RESULT, self.LOCAL_PATH, True)
+
+    # Example of result file:
+    # cat /tmp/final_result.dat
+    #   timestamp:1000 reg:100 reg_saps:0
+    #   timestamp:2000 reg:100 reg_saps:50
+    #   timestamp:3000 reg:100 reg_saps:50
+    #   timestamp:4000 reg:100 reg_saps:50
+    #   ...
+    #   reg_Requested_prereg:50
+    #   reg_Effective_prereg:49.49
+    #   reg_DOC:0
+    #   ...
+    @staticmethod
+    def handle_result_files(filename):
+        with open(filename, 'r') as f:
+            content = f.readlines()
+        result = [{k: round(float(v), 2) for k, v in [i.split(":", 1) for i in x.split()]}
+                  for x in content if x]
+        return deque(result)
+
+    def run_traffic(self, traffic_profile):
+        traffic_profile.execute_traffic(self)
+        cmd = self.CMD.format(self.sipp_ip, self.media_ip,
+                              self.pcscf_ip, self.params)
+        self.ssh_helper.execute(cmd, None, 3600, False)
+        self.get_result_files()
+        self.queue = self.handle_result_files(self.RESULT)
+
+    def collect_kpi(self):
+        result = {}
+        try:
+            result = self.queue.popleft()
+        except IndexError:
+            pass
+        return result
+
+    @staticmethod
+    def count_line_num(fname):
+        try:
+            with open(fname, 'r') as f:
+                return sum(1 for line in f)
+        except IOError:
+            return 0
+
+    def is_ended(self):
+        """
+        The test will end when the results are pushed into database.
+        It does not depend on the "duration" value, so this value will be set
+        enough big to make sure that the test will end before duration.
+        """
+        num_lines = self.count_line_num(self.RESULT)
+        if self.count == num_lines:
+            LOG.debug('TG IS ENDED.....................')
+            self.count = 0
+            return True
+        self.count += 1
+        return False
+
+    def terminate(self):
+        LOG.debug('TERMINATE:.....................')
+        self.resource_helper.terminate()
diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_sip.py b/yardstick/tests/unit/network_services/traffic_profile/test_sip.py
new file mode 100644 (file)
index 0000000..bf26ee4
--- /dev/null
@@ -0,0 +1,51 @@
+# 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.traffic_profile import sip
+
+
+class TestSipProfile(unittest.TestCase):
+
+    TRAFFIC_PROFILE = {
+        "schema": "nsb:traffic_profile:0.1",
+        "name": "sip",
+        "description": "Traffic profile to run sip",
+        "traffic_profile": {
+            "traffic_type": "SipProfile",
+            "frame_rate": 100,  # pps
+            "duration": 10,
+            "enable_latency": False}}
+
+    def setUp(self):
+        self.sip_profile = sip.SipProfile(self.TRAFFIC_PROFILE)
+
+    def test___init__(self):
+        self.assertIsNone(self.sip_profile.generator)
+
+    def test_execute_traffic(self):
+        self.sip_profile.generator = None
+        mock_traffic_generator = mock.Mock()
+        self.sip_profile.execute_traffic(mock_traffic_generator)
+        self.assertIsNotNone(self.sip_profile.generator)
+
+    def test_is_ended_true(self):
+        self.sip_profile.generator = mock.Mock(return_value=True)
+        self.assertTrue(self.sip_profile.is_ended())
+
+    def test_is_ended_false(self):
+        self.sip_profile.generator = None
+        self.assertFalse(self.sip_profile.is_ended())
diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_imsbench_sipp.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_imsbench_sipp.py
new file mode 100644 (file)
index 0000000..698b1b0
--- /dev/null
@@ -0,0 +1,481 @@
+# 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 mock
+import unittest
+from collections import deque
+
+from yardstick.network_services.vnf_generic.vnf import tg_imsbench_sipp
+from yardstick import ssh
+
+
+class TestSippVnf(unittest.TestCase):
+
+    VNFD = {
+        "short-name": "SippVnf",
+        "vdu": [
+            {
+                "id": "sippvnf-baremetal",
+                "routing_table": "",
+                "external-interface": [
+                    {
+                        "virtual-interface": {
+                            "vld_id": "ims_network",
+                            "peer_ifname": "xe0",
+                            "dst_mac": "90:e2:ba:7c:41:e8",
+                            "network": {},
+                            "local_ip": "10.80.3.11",
+                            "peer_intf": {
+                                "vld_id": "data_network",
+                                "peer_ifname": "xe1",
+                                "dst_mac": "90:e2:ba:7c:30:e8",
+                                "network": {},
+                                "local_ip": "10.80.3.7",
+                                "node_name": "vnf__0",
+                                "netmask": "255.255.255.0",
+                                "peer_name": "tg__0",
+                                "dst_ip": "10.80.3.11",
+                                "ifname": "xe0",
+                                "local_mac": "90:e2:ba:7c:41:a8"
+                            },
+                            "node_name": "tg__0",
+                            "netmask": "255.255.255.0",
+                            "peer_name": "vnf__1",
+                            "dst_ip": "10.80.3.7",
+                            "ifname": "xe0",
+                            "local_mac": "90:e2:ba:7c:30:e8"
+                        },
+                        "vnfd-connection-point-ref": "xe0",
+                        "name": "xe0"
+                    },
+                    {
+                        "virtual-interface": {
+                            "vld_id": "ims_network",
+                            "peer_ifname": "xe0",
+                            "dst_mac": "90:e2:ba:7c:41:e8",
+                            "network": {},
+                            "local_ip": "10.80.3.11",
+                            "peer_intf": {
+                                "vld_id": "data_network",
+                                "peer_ifname": "xe1",
+                                "dst_mac": "90:e2:ba:7c:30:e8",
+                                "network": {},
+                                "local_ip": "10.80.3.7",
+                                "peer_intf": {
+                                    "vld_id": "ims_network",
+                                    "peer_ifname": "xe0",
+                                    "dst_mac": "90:e2:ba:7c:41:e8",
+                                    "network": {},
+                                    "local_ip": "10.80.3.11",
+                                    "node_name": "tg__0",
+                                    "netmask": "255.255.255.0",
+                                    "peer_name": "vnf__1",
+                                    "dst_ip": "10.80.3.7",
+                                    "ifname": "xe0",
+                                    "local_mac": "90:e2:ba:7c:30:e8"
+                                },
+                                "node_name": "vnf__0",
+                                "netmask": "255.255.255.0",
+                                "peer_name": "tg__0",
+                                "dst_ip": "10.80.3.11",
+                                "ifname": "xe0",
+                                "local_mac": "90:e2:ba:7c:41:a8"
+                            },
+                            "node_name": "tg__0",
+                            "netmask": "255.255.255.0",
+                            "peer_name": "vnf__1",
+                            "dst_ip": "10.80.3.7",
+                            "ifname": "xe1",
+                            "local_mac": "90:e2:ba:7c:30:e8"
+                        },
+                        "vnfd-connection-point-ref": "xe1",
+                        "name": "xe1"
+                    }
+                ],
+                "name": "sippvnf-baremetal",
+                "description": "Sipp"
+            }
+        ],
+        "description": "ImsbenchSipp",
+        "mgmt-interface": {
+            "vdu-id": "sipp-baremetal",
+            "password": "r00t",
+            "user": "root",
+            "ip": "10.80.3.11"
+        },
+        "benchmark": {
+            "kpi": [
+                "packets_in",
+                "packets_fwd",
+                "packets_dropped"
+            ]
+        },
+        "id": "SippVnf",
+        "name": "SippVnf"
+    }
+
+    SCENARIO_CFG = {
+        "task_id": "ba636744-898e-4783-a4aa-0a79c60953cc",
+        "tc": "tc_vims_baremetal_sipp",
+        "runner": {
+            "interval": 1,
+            "output_config": {
+                "DEFAULT": {
+                    "debug": "False",
+                    "dispatcher": [
+                        "influxdb"
+                    ]
+                },
+                "nsb": {
+                    "debug": "False",
+                    "trex_client_lib": "/opt/nsb_bin/trex_client/stl",
+                    "bin_path": "/opt/nsb_bin",
+                    "trex_path": "/opt/nsb_bin/trex/scripts",
+                    "dispatcher": "influxdb"
+                },
+                "dispatcher_influxdb": {
+                    "username": "root",
+                    "target": "http://10.80.3.11:8086",
+                    "db_name": "yardstick",
+                    "timeout": "5",
+                    "debug": "False",
+                    "password": "root",
+                    "dispatcher": "influxdb"
+                },
+                "dispatcher_http": {
+                    "debug": "False",
+                    "dispatcher": "influxdb",
+                    "timeout": "5",
+                    "target": "http://127.0.0.1:8000/results"
+                },
+                "dispatcher_file": {
+                    "debug": "False",
+                    "backup_count": "0",
+                    "max_bytes": "0",
+                    "dispatcher": "influxdb",
+                    "file_path": "/tmp/yardstick.out"
+                }
+            },
+            "runner_id": 18148,
+            "duration": 60,
+            "type": "Vims"
+        },
+        "nodes": {
+            "vnf__0": "pcscf.yardstick-ba636744",
+            "vnf__1": "hss.yardstick-ba636744",
+            "tg__0": "sipp.yardstick-ba636744"
+        },
+        "topology": "vims-topology.yaml",
+        "type": "NSPerf",
+        "traffic_profile": "../../traffic_profiles/ipv4_throughput.yaml",
+        "task_path": "samples/vnf_samples/nsut/vims",
+        "options": {
+            "init_reg_max": 5000,
+            "end_user": 10000,
+            "reg_cps": 20,
+            "rereg_cps": 20,
+            "rereg_step": 10,
+            "wait_time": 5,
+            "start_user": 1,
+            "msgc_cps": 10,
+            "dereg_step": 10,
+            "call_cps": 10,
+            "reg_step": 10,
+            "init_reg_cps": 50,
+            "dereg_cps": 20,
+            "msgc_step": 5,
+            "call_step": 5,
+            "hold_time": 15,
+            "port": 5060,
+            "run_mode": "nortp"
+        }
+    }
+    CONTEXT_CFG = {
+        "nodes": {
+            "tg__0": {
+                "ip": "10.80.3.11",
+                "interfaces": {
+                    "xe0": {
+                        "vld_id": "ims_network",
+                        "peer_ifname": "xe0",
+                        "dst_mac": "90:e2:ba:7c:41:e8",
+                        "network": {},
+                        "local_ip": "10.80.3.11",
+                        "peer_intf": {
+                            "vld_id": "data_network",
+                            "peer_ifname": "xe1",
+                            "dst_mac": "90:e2:ba:7c:30:e8",
+                            "network": {},
+                            "local_ip": "10.80.3.7",
+                            "node_name": "vnf__0",
+                            "netmask": "255.255.255.0",
+                            "peer_name": "tg__0",
+                            "dst_ip": "10.80.3.11",
+                            "ifname": "xe0",
+                            "local_mac": "90:e2:ba:7c:41:a8"
+                        },
+                        "node_name": "tg__0",
+                        "netmask": "255.255.255.0",
+                        "peer_name": "vnf__1",
+                        "dst_ip": "10.80.3.7",
+                        "ifname": "xe0",
+                        "local_mac": "90:e2:ba:7c:30:e8"
+                    },
+                    "xe1": {
+                        "vld_id": "ims_network",
+                        "peer_ifname": "xe0",
+                        "dst_mac": "90:e2:ba:7c:41:e8",
+                        "network": {},
+                        "local_ip": "10.80.3.11",
+                        "peer_intf": {
+                            "vld_id": "data_network",
+                            "peer_ifname": "xe1",
+                            "dst_mac": "90:e2:ba:7c:30:e8",
+                            "network": {},
+                            "local_ip": "10.80.3.7",
+                            "peer_intf": {
+                                "vld_id": "ims_network",
+                                "peer_ifname": "xe0",
+                                "dst_mac": "90:e2:ba:7c:41:e8",
+                                "network": {},
+                                "local_ip": "10.80.3.11",
+                                "node_name": "tg__0",
+                                "netmask": "255.255.255.0",
+                                "peer_name": "vnf__1",
+                                "dst_ip": "10.80.3.7",
+                                "ifname": "xe0",
+                                "local_mac": "90:e2:ba:7c:30:e8"
+                            },
+                            "node_name": "vnf__0",
+                            "netmask": "255.255.255.0",
+                            "peer_name": "tg__0",
+                            "dst_ip": "10.80.3.11",
+                            "ifname": "xe0",
+                            "local_mac": "90:e2:ba:7c:41:a8"
+                        },
+                        "node_name": "tg__0",
+                        "netmask": "255.255.255.0",
+                        "peer_name": "vnf__1",
+                        "dst_ip": "10.80.3.7",
+                        "ifname": "xe1",
+                        "local_mac": "90:e2:ba:7c:30:e8"
+                    }
+                },
+                "user": "root",
+                "password": "r00t",
+                "VNF model": "../../vnf_descriptors/tg_sipp_vnfd.yaml",
+                "name": "sipp.yardstick-a75a3aff",
+                "vnfd-id-ref": "tg__0",
+                "member-vnf-index": "1",
+                "role": "TrafficGen",
+                "ctx_type": "Node"
+            },
+            "vnf__0": {
+                "ip": "10.80.3.7",
+                "interfaces": {
+                    "xe0": {
+                        "vld_id": "data_network",
+                        "peer_ifname": "xe1",
+                        "dst_mac": "90:e2:ba:7c:30:e8",
+                        "network": {},
+                        "local_ip": "10.80.3.7",
+                        "peer_intf": {
+                            "tg__0": {
+                                "vld_id": "ims_network",
+                                "peer_ifname": "xe0",
+                                "dst_mac": "90:e2:ba:7c:41:e8",
+                                "network": {},
+                                "local_ip": "10.80.3.11",
+                                "node_name": "tg__0",
+                                "netmask": "255.255.255.0",
+                                "peer_name": "vnf__1",
+                                "dst_ip": "10.80.3.7",
+                                "ifname": "xe1",
+                                "local_mac": "90:e2:ba:7c:30:e8"
+                            }
+                        },
+                        "node_name": "vnf__0",
+                        "netmask": "255.255.255.0",
+                        "peer_name": "tg__0",
+                        "dst_ip": "10.80.3.11",
+                        "ifname": "xe0",
+                        "local_mac": "90:e2:ba:7c:41:a8"
+                    }
+                },
+                "user": "root",
+                "password": "r00t",
+                "VNF model": "../../vnf_descriptors/vims_pcscf_vnfd.yaml",
+                "name": "pcscf.yardstick-a75a3aff",
+                "vnfd-id-ref": "vnf__0",
+                "member-vnf-index": "2",
+                "role": "VirtualNetworkFunction",
+                "ctx_type": "Node"
+            },
+            "vnf__1": {
+                "ip": "10.80.3.7",
+                "interfaces": {
+                    "xe0": {
+                        "vld_id": "ims_network",
+                        "peer_ifname": "xe1",
+                        "dst_mac": "90:e2:ba:7c:30:e8",
+                        "network": {},
+                        "local_ip": "10.80.3.7",
+                        "peer_intf": {
+                            "tg__0": {
+                                "vld_id": "ims_network",
+                                "peer_ifname": "xe0",
+                                "dst_mac": "90:e2:ba:7c:41:e8",
+                                "network": {},
+                                "local_ip": "10.80.3.11",
+                                "peer_intf": {
+                                    "vld_id": "data_network",
+                                    "peer_ifname": "xe1",
+                                    "dst_mac": "90:e2:ba:7c:30:e8",
+                                    "network": {},
+                                    "local_ip": "10.80.3.7",
+                                    "peer_intf": {
+                                        "vld_id": "ims_network",
+                                        "peer_ifname": "xe0",
+                                        "dst_mac": "90:e2:ba:7c:41:e8",
+                                        "network": {},
+                                        "local_ip": "10.80.3.11",
+                                        "node_name": "tg__0",
+                                        "netmask": "255.255.255.0",
+                                        "peer_name": "vnf__1",
+                                        "dst_ip": "10.80.3.7",
+                                        "ifname": "xe0",
+                                        "local_mac": "90:e2:ba:7c:30:e8"
+                                    },
+                                    "node_name": "vnf__0",
+                                    "netmask": "255.255.255.0",
+                                    "peer_name": "tg__0",
+                                    "dst_ip": "10.80.3.11",
+                                    "ifname": "xe0",
+                                    "local_mac": "90:e2:ba:7c:41:a8"
+                                },
+                                "node_name": "tg__0",
+                                "netmask": "255.255.255.0",
+                                "peer_name": "vnf__1",
+                                "dst_ip": "10.80.3.7",
+                                "ifname": "xe1",
+                                "local_mac": "90:e2:ba:7c:30:e8"
+                            }
+                        },
+                        "node_name": "vnf__1",
+                        "netmask": "255.255.255.0",
+                        "peer_name": "tg__0",
+                        "dst_ip": "10.80.3.11",
+                        "ifname": "xe0",
+                        "local_mac": "90:e2:ba:7c:41:e8"
+                    }
+                },
+                "user": "root",
+                "password": "r00t",
+                "VNF model": "../../vnf_descriptors/vims_hss_vnfd.yaml",
+                "name": "hss.yardstick-a75a3aff",
+                "vnfd-id-ref": "vnf__1",
+                "member-vnf-index": "3",
+                "role": "VirtualNetworkFunction",
+                "ctx_type": "Node"
+            }
+        },
+        "networks": {}
+    }
+
+    FILE = "timestamp:1000 reg:100 reg_saps:0"
+
+    QUEUE = {'reg_saps': 0.0, 'timestamp': 1000.0, 'reg': 100.0}
+
+    TRAFFIC_PROFILE = {
+        "schema": "nsb:traffic_profile:0.1",
+        "name": "sip",
+        "description": "Traffic profile to run sip",
+        "traffic_profile": {
+            "traffic_type": "SipProfile",
+            "frame_rate": 100,  # pps
+            "enable_latency": False
+        },
+    }
+
+    def setUp(self):
+        self._mock_ssh = mock.patch.object(ssh, 'SSH')
+        self.mock_ssh = self._mock_ssh.start()
+
+        self.addCleanup(self._stop_mocks)
+        self.sipp_vnf = tg_imsbench_sipp.SippVnf('tg__0', self.VNFD)
+
+    def _stop_mocks(self):
+        self._mock_ssh.stop()
+
+    def test___init__(self):
+        self.assertIsInstance(self.sipp_vnf.resource_helper,
+                              tg_imsbench_sipp.SippResourceHelper)
+
+    def test_wait_for_instantiate(self):
+        self.assertIsNone(self.sipp_vnf.wait_for_instantiate())
+
+    @mock.patch('six.moves.builtins.open', new_callable=mock.mock_open, read_data=FILE)
+    def test_handle_result_files(self, mock_file):
+        result_deque = deque([self.QUEUE])
+        file = "/tmp/test.txt"
+        test = self.sipp_vnf.handle_result_files(file)
+        self.assertEqual(result_deque, test)
+        mock_file.assert_called_with(file, 'r')
+
+    @mock.patch.object(ssh.SSH, 'get')
+    def test_get_result_files(self, mock_get):
+        self.sipp_vnf.get_result_files()
+        mock_get.assert_called()
+
+    def test_collect_kpi(self):
+        self.sipp_vnf.queue = deque([self.QUEUE])
+        self.assertEqual(self.QUEUE, self.sipp_vnf.collect_kpi())
+
+    def test_collect_kpi_empty(self):
+        self.sipp_vnf.queue = deque([])
+        self.assertEqual({}, self.sipp_vnf.collect_kpi())
+
+    @mock.patch('six.moves.builtins.open', new_callable=mock.mock_open, read_data=FILE)
+    def test_count_line_num(self, mock_file):
+        file = "/tmp/test.txt"
+        mock_file.return_value.__iter__.return_value = self.FILE.splitlines()
+        self.assertEqual(1, self.sipp_vnf.count_line_num(file))
+        mock_file.assert_called_with(file, 'r')
+
+    @mock.patch('six.moves.builtins.open', new_callable=mock.mock_open, read_data='')
+    def test_count_line_num_file_empty(self, mock_file):
+        file = "/tmp/test.txt"
+        self.assertEqual(0, self.sipp_vnf.count_line_num(file))
+        mock_file.assert_called_with(file, 'r')
+
+    @mock.patch('six.moves.builtins.open', new_callable=mock.mock_open, read_data=FILE)
+    def test_count_line_num_file_error(self, mock_file):
+        file = "/tmp/test.txt"
+        mock_file.side_effect = IOError()
+        self.assertEqual(0, self.sipp_vnf.count_line_num(file))
+
+    def test_is_ended_false(self):
+        self.sipp_vnf.count_line_num = mock.Mock(return_value=1)
+        not_end = self.sipp_vnf.is_ended()
+        self.assertFalse(not_end)
+
+    def test_is_ended_true(self):
+        self.sipp_vnf.count_line_num = mock.Mock(return_value=0)
+        end = self.sipp_vnf.is_ended()
+        self.assertTrue(end)
+
+    def test_terminate(self):
+        self.sipp_vnf.ssh_helper = mock.MagicMock()
+        self.sipp_vnf.resource_helper.ssh_helper = mock.MagicMock()
+        self.assertIsNone(self.sipp_vnf.terminate())