aboutsummaryrefslogtreecommitdiffstats
path: root/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py')
-rw-r--r--tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py2239
1 files changed, 2239 insertions, 0 deletions
diff --git a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
new file mode 100644
index 000000000..af0d2ddde
--- /dev/null
+++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
@@ -0,0 +1,2239 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Intel 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.
+#
+
+# Unittest for yardstick.network_services.vnf_generic.vnf.sample_vnf
+
+from __future__ import absolute_import
+import unittest
+import mock
+from copy import deepcopy
+
+from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
+from yardstick.benchmark.contexts.base import Context
+from yardstick.network_services.nfvi.resource import ResourceProfile
+from yardstick.network_services.traffic_profile.base import TrafficProfile
+from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
+from yardstick.ssh import SSHError
+
+
+class MockError(BaseException):
+ pass
+
+
+STL_MOCKS = {
+ 'stl': mock.MagicMock(),
+ 'stl.trex_stl_lib': mock.MagicMock(),
+ 'stl.trex_stl_lib.base64': mock.MagicMock(),
+ 'stl.trex_stl_lib.binascii': mock.MagicMock(),
+ 'stl.trex_stl_lib.collections': mock.MagicMock(),
+ 'stl.trex_stl_lib.copy': mock.MagicMock(),
+ 'stl.trex_stl_lib.datetime': mock.MagicMock(),
+ 'stl.trex_stl_lib.functools': mock.MagicMock(),
+ 'stl.trex_stl_lib.imp': mock.MagicMock(),
+ 'stl.trex_stl_lib.inspect': mock.MagicMock(),
+ 'stl.trex_stl_lib.json': mock.MagicMock(),
+ 'stl.trex_stl_lib.linecache': mock.MagicMock(),
+ 'stl.trex_stl_lib.math': mock.MagicMock(),
+ 'stl.trex_stl_lib.os': mock.MagicMock(),
+ 'stl.trex_stl_lib.platform': mock.MagicMock(),
+ 'stl.trex_stl_lib.pprint': mock.MagicMock(),
+ 'stl.trex_stl_lib.random': mock.MagicMock(),
+ 'stl.trex_stl_lib.re': mock.MagicMock(),
+ 'stl.trex_stl_lib.scapy': mock.MagicMock(),
+ 'stl.trex_stl_lib.socket': mock.MagicMock(),
+ 'stl.trex_stl_lib.string': mock.MagicMock(),
+ 'stl.trex_stl_lib.struct': mock.MagicMock(),
+ 'stl.trex_stl_lib.sys': mock.MagicMock(),
+ 'stl.trex_stl_lib.threading': mock.MagicMock(),
+ 'stl.trex_stl_lib.time': mock.MagicMock(),
+ 'stl.trex_stl_lib.traceback': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_async_client': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_client': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_exceptions': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_ext': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_jsonrpc_client': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_packet_builder_interface': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_packet_builder_scapy': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_port': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_stats': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_streams': mock.MagicMock(),
+ 'stl.trex_stl_lib.trex_stl_types': mock.MagicMock(),
+ 'stl.trex_stl_lib.types': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.argparse': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.collections': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.common': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.json': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.os': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.parsing_opts': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.pwd': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.random': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.re': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.string': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.sys': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.text_opts': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.text_tables': mock.MagicMock(),
+ 'stl.trex_stl_lib.utils.texttable': mock.MagicMock(),
+ 'stl.trex_stl_lib.warnings': mock.MagicMock(),
+ 'stl.trex_stl_lib.yaml': mock.MagicMock(),
+ 'stl.trex_stl_lib.zlib': mock.MagicMock(),
+ 'stl.trex_stl_lib.zmq': mock.MagicMock(),
+}
+
+STLClient = mock.MagicMock()
+stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
+stl_patch.start()
+
+if stl_patch:
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import VnfSshHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFDeployHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import ResourceHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import Rfc2544ResourceHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import SetupEnvHelper
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
+ from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
+
+
+class TestVnfSshHelper(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ VNFD = {
+ 'vnfd:vnfd-catalog': {
+ 'vnfd': [
+ VNFD_0,
+ ]
+ }
+ }
+
+ def assertAll(self, iterable, message=None):
+ self.assertTrue(all(iterable), message)
+
+ def test_get_class(self):
+ self.assertIs(VnfSshHelper.get_class(), VnfSshHelper)
+
+ @mock.patch('yardstick.ssh.paramiko')
+ def test_copy(self, _):
+ ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
+ ssh_helper._run = mock.Mock()
+
+ ssh_helper.execute('ls')
+ self.assertTrue(ssh_helper.is_connected)
+ result = ssh_helper.copy()
+ self.assertIsInstance(result, VnfSshHelper)
+ self.assertFalse(result.is_connected)
+ self.assertEqual(result.bin_path, ssh_helper.bin_path)
+ self.assertEqual(result.host, ssh_helper.host)
+ self.assertEqual(result.port, ssh_helper.port)
+ self.assertEqual(result.user, ssh_helper.user)
+ self.assertEqual(result.password, ssh_helper.password)
+ self.assertEqual(result.key_filename, ssh_helper.key_filename)
+
+ @mock.patch('yardstick.ssh.paramiko')
+ def test_upload_config_file(self, mock_paramiko):
+ ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
+
+ self.assertFalse(ssh_helper.is_connected)
+ cfg_file = ssh_helper.upload_config_file('my/prefix', 'my content')
+ self.assertTrue(ssh_helper.is_connected)
+ self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
+ self.assertTrue(cfg_file.startswith('/tmp'))
+
+ cfg_file = ssh_helper.upload_config_file('/my/prefix', 'my content')
+ self.assertTrue(ssh_helper.is_connected)
+ self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
+ self.assertEqual(cfg_file, '/my/prefix')
+
+ def test_join_bin_path(self):
+ ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
+
+ expected_start = 'my'
+ expected_middle_list = ['bin']
+ expected_end = 'path'
+ result = ssh_helper.join_bin_path()
+ self.assertTrue(result.startswith(expected_start))
+ self.assertAll(middle in result for middle in expected_middle_list)
+ self.assertTrue(result.endswith(expected_end))
+
+ expected_middle_list.append(expected_end)
+ expected_end = 'some_file.sh'
+ result = ssh_helper.join_bin_path('some_file.sh')
+ self.assertTrue(result.startswith(expected_start))
+ self.assertAll(middle in result for middle in expected_middle_list)
+ self.assertTrue(result.endswith(expected_end))
+
+ expected_middle_list.append('some_dir')
+ expected_end = 'some_file.sh'
+ result = ssh_helper.join_bin_path('some_dir', 'some_file.sh')
+ self.assertTrue(result.startswith(expected_start))
+ self.assertAll(middle in result for middle in expected_middle_list)
+ self.assertTrue(result.endswith(expected_end))
+
+ @mock.patch('yardstick.ssh.paramiko')
+ @mock.patch('yardstick.ssh.provision_tool')
+ def test_provision_tool(self, mock_provision_tool, mock_paramiko):
+ ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
+
+ self.assertFalse(ssh_helper.is_connected)
+ ssh_helper.provision_tool()
+ self.assertTrue(ssh_helper.is_connected)
+ self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
+ self.assertEqual(mock_provision_tool.call_count, 1)
+
+ ssh_helper.provision_tool(tool_file='my_tool.sh')
+ self.assertTrue(ssh_helper.is_connected)
+ self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
+ self.assertEqual(mock_provision_tool.call_count, 2)
+
+ ssh_helper.provision_tool('tool_path', 'my_tool.sh')
+ self.assertTrue(ssh_helper.is_connected)
+ self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
+ self.assertEqual(mock_provision_tool.call_count, 3)
+
+
+class TestSetupEnvHelper(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ def test_build_config(self):
+ setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
+
+ with self.assertRaises(NotImplementedError):
+ setup_env_helper.build_config()
+
+ def test__get_ports_gateway(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ setup_env_helper = SetupEnvHelper(vnfd_helper, mock.Mock(), mock.Mock())
+ result = setup_env_helper._get_ports_gateway("xe0")
+ self.assertEqual(result, "152.16.100.20")
+
+ result = setup_env_helper._get_ports_gateway("xe123")
+ self.assertIsNone(result)
+
+ def test_setup_vnf_environment(self):
+ setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
+ self.assertIsNone(setup_env_helper.setup_vnf_environment())
+
+ def test_tear_down(self):
+ setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
+
+ with self.assertRaises(NotImplementedError):
+ setup_env_helper.tear_down()
+
+
+class TestDpdkVnfSetupEnvHelper(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'driver': 'i40e',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'driver': 'ixgbe',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ VNFD = {
+ 'vnfd:vnfd-catalog': {
+ 'vnfd': [
+ VNFD_0,
+ ]
+ }
+ }
+
+ def test__update_packet_type(self):
+ ip_pipeline_cfg = 'pkt_type = ipv4'
+ pkt_type = {'pkt_type': '1'}
+
+ expected = "pkt_type = 1"
+ result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
+ self.assertEqual(result, expected)
+
+ def test__update_packet_type_no_op(self):
+ ip_pipeline_cfg = 'pkt_type = ipv6'
+ pkt_type = {'pkt_type': '1'}
+
+ expected = "pkt_type = ipv6"
+ result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
+ self.assertEqual(result, expected)
+
+ def test__update_packet_type_multi_op(self):
+ ip_pipeline_cfg = 'pkt_type = ipv4\npkt_type = 1\npkt_type = ipv4'
+ pkt_type = {'pkt_type': '1'}
+
+ expected = 'pkt_type = 1\npkt_type = 1\npkt_type = 1'
+ result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
+ self.assertEqual(result, expected)
+
+ def test__update_traffic_type(self):
+ ip_pipeline_cfg = 'pkt_type = ipv4'
+
+ traffic_options = {"vnf_type": DpdkVnfSetupEnvHelper.APP_NAME, 'traffic_type': 4}
+ expected = "pkt_type = ipv4"
+ result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
+ self.assertEqual(result, expected)
+
+ def test__update_traffic_type_ipv6(self):
+ ip_pipeline_cfg = 'pkt_type = ipv4'
+
+ traffic_options = {"vnf_type": DpdkVnfSetupEnvHelper.APP_NAME, 'traffic_type': 6}
+ expected = "pkt_type = ipv6"
+ result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
+ self.assertEqual(result, expected)
+
+ def test__update_traffic_type_not_app_name(self):
+ ip_pipeline_cfg = 'traffic_type = 4'
+
+ vnf_type = ''.join(["Not", DpdkVnfSetupEnvHelper.APP_NAME])
+ traffic_options = {"vnf_type": vnf_type, 'traffic_type': 8}
+ expected = "traffic_type = 8"
+ result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
+ self.assertEqual(result, expected)
+
+ def test__setup_hugepages(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 0, '', ''
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ result = dpdk_setup_helper._setup_hugepages()
+ expect_start_list = ['awk', 'awk', 'echo']
+ expect_in_list = ['meminfo', 'nr_hugepages', '16']
+ call_args_iter = (args[0][0] for args in ssh_helper.execute.call_args_list)
+ self.assertIsNone(result)
+ self.assertEqual(ssh_helper.execute.call_count, 3)
+ for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, call_args_iter):
+ self.assertTrue(arg0.startswith(expect_start))
+ self.assertIn(expect_in, arg0)
+
+ def test__setup_hugepages_2_mb(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 0, '2048kB ', ''
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ result = dpdk_setup_helper._setup_hugepages()
+ expect_start_list = ['awk', 'awk', 'echo']
+ expect_in_list = ['meminfo', 'nr_hugepages', '16384']
+ call_args_iter = (args[0][0] for args in ssh_helper.execute.call_args_list)
+ self.assertIsNone(result)
+ self.assertEqual(ssh_helper.execute.call_count, 3)
+ for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, call_args_iter):
+ self.assertTrue(arg0.startswith(expect_start))
+ self.assertIn(expect_in, arg0)
+
+ def test__get_dpdk_port_num(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ expected = '0'
+ result = dpdk_setup_helper._get_dpdk_port_num('xe0')
+ self.assertEqual(result, expected)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.find_relative_file')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig')
+ def test_build_config(self, mock_multi_port_config_class, mock_find, _):
+ mock_multi_port_config = mock_multi_port_config_class()
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ scenario_helper.vnf_cfg = {}
+ scenario_helper.all_options = {}
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.all_ports = []
+
+ dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
+ result = dpdk_setup_helper.build_config()
+ self.assertEqual(result, expected)
+ self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2)
+ self.assertGreaterEqual(mock_find.call_count, 1)
+ self.assertGreaterEqual(mock_multi_port_config.generate_config.call_count, 1)
+ self.assertGreaterEqual(mock_multi_port_config.generate_script.call_count, 1)
+
+ def test__build_pipeline_kwargs(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.provision_tool.return_value = 'tool_path'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.CFG_CONFIG = 'config'
+ dpdk_setup_helper.CFG_SCRIPT = 'script'
+ dpdk_setup_helper.all_ports = [3, 4, 5]
+ dpdk_setup_helper.pipeline_kwargs = {}
+
+ expected = {
+ 'cfg_file': 'config',
+ 'script': 'script',
+ 'ports_len_hex': '0xf',
+ 'tool_path': 'tool_path',
+ }
+ dpdk_setup_helper._build_pipeline_kwargs()
+ self.assertDictEqual(dpdk_setup_helper.pipeline_kwargs, expected)
+
+ def test__get_app_cpu(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.provision_tool.return_value = 'tool_path'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ dpdk_setup_helper.CORES = expected = [5, 4, 3]
+ result = dpdk_setup_helper._get_app_cpu()
+ self.assertEqual(result, expected)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.CpuSysCores')
+ def test__get_app_cpu_no_cores_sw(self, mock_cpu_sys_cores_class):
+ mock_cpu_sys_cores = mock_cpu_sys_cores_class()
+ mock_cpu_sys_cores.get_core_socket.return_value = {
+ 'socket': [2, 4, 8, 10, 12],
+ }
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.provision_tool.return_value = 'tool_path'
+ scenario_helper = mock.Mock()
+ scenario_helper.vnf_cfg = {
+ 'worker_threads': '2',
+ }
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.CORES = []
+ dpdk_setup_helper.SW_DEFAULT_CORE = 1
+ dpdk_setup_helper.HW_DEFAULT_CORE = 2
+ dpdk_setup_helper.socket = 'socket'
+
+ expected = [2, 4, 8]
+ result = dpdk_setup_helper._get_app_cpu()
+ self.assertEqual(result, expected)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.CpuSysCores')
+ def test__get_app_cpu_no_cores_hw(self, mock_cpu_sys_cores_class):
+ mock_cpu_sys_cores = mock_cpu_sys_cores_class()
+ mock_cpu_sys_cores.get_core_socket.return_value = {
+ 'socket': [2, 4, 8, 10, 12],
+ }
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ scenario_helper.vnf_cfg = {
+ 'worker_threads': '2',
+ 'lb_config': 'HW',
+ }
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.CORES = []
+ dpdk_setup_helper.SW_DEFAULT_CORE = 1
+ dpdk_setup_helper.HW_DEFAULT_CORE = 2
+ dpdk_setup_helper.socket = 'socket'
+
+ expected = [2, 4, 8, 10]
+ result = dpdk_setup_helper._get_app_cpu()
+ self.assertEqual(result, expected)
+
+ def test__get_cpu_sibling_list(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = iter([(0, '5', ''), (0, '3,4', ''), (0, '10', '')])
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._get_app_cpu = mock.Mock(return_value=[])
+
+ expected = ['5', '3', '4', '10']
+ result = dpdk_setup_helper._get_cpu_sibling_list([1, 3, 7])
+ self.assertEqual(result, expected)
+
+ def test__get_cpu_sibling_list_no_core_arg(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = iter([(0, '5', ''), (0, '3,4', ''), (0, '10', '')])
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._get_app_cpu = mock.Mock(return_value=[1, 7])
+
+ expected = ['5', '3', '4']
+ result = dpdk_setup_helper._get_cpu_sibling_list()
+ self.assertEqual(result, expected)
+
+ def test__get_cpu_sibling_list_ssh_failure(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = iter([(0, '5', ''), SSHError, (0, '10', '')])
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._get_app_cpu = mock.Mock(return_value=[])
+
+ expected = []
+ result = dpdk_setup_helper._get_cpu_sibling_list([1, 3, 7])
+ self.assertEqual(result, expected)
+
+ def test__validate_cpu_cfg(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = iter([(0, '5', ''), (0, '3,4', ''), (0, '10', '')])
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._get_app_cpu = mock.Mock(return_value=[1, 3, 7])
+
+ expected = ['5', '3', '4', '10']
+ result = dpdk_setup_helper._validate_cpu_cfg()
+ self.assertEqual(result, expected)
+
+ def test__find_used_drivers(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ stdout = '''
+00:01.2 foo drv=name1
+00:01.4 drv foo=name2
+00:02.2 drv=name3
+00:02.3 drv=name4
+'''
+ ssh_helper.execute.return_value = 0, stdout, ''
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.used_drivers = None
+ dpdk_setup_helper._dpdk_nic_bind = ''
+ dpdk_setup_helper.bound_pci = [
+ 'pci 00:01.2',
+ 'pci 00:02.3',
+ ]
+
+ expected = {
+ '00:01.2': (0, 'name1'),
+ '00:02.3': (2, 'name4'),
+ }
+ dpdk_setup_helper._find_used_drivers()
+ self.assertEqual(dpdk_setup_helper.used_drivers, expected)
+
+ def test_dpdk_nic_bind(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.provision_tool.return_value = nic_bind = object()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ self.assertIsNone(dpdk_setup_helper._dpdk_nic_bind)
+ self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind)
+ self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind)
+ self.assertEqual(ssh_helper.provision_tool.call_count, 1)
+
+ # ensure provision tool is not called a second time
+ self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind)
+ self.assertEqual(ssh_helper.provision_tool.call_count, 1)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('yardstick.ssh.SSH')
+ def test_setup_vnf_environment(self, _, mock_time):
+ cores = ['3', '4']
+
+ vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 1, 'bad output', 'error output'
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.provision_tool.return_value = 'provision string'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._setup_hugepages = mock.Mock()
+ dpdk_setup_helper._validate_cpu_cfg = mock.Mock(return_value=cores)
+ dpdk_setup_helper._find_used_drivers = mock.Mock()
+ dpdk_setup_helper.used_drivers = {
+ '0000:05:00.0': (1, ''),
+ '0000:05:01.0': (3, ''),
+ }
+
+ result = dpdk_setup_helper.setup_vnf_environment()
+ self.assertIsInstance(result, ResourceProfile)
+ self.assertEqual(result.cores, cores)
+ self.assertEqual(vnfd_helper.interfaces[0]['dpdk_port_num'], 1)
+ self.assertNotIn('dpdk_port_num', vnfd_helper.interfaces[1])
+
+ def test__setup_dpdk_early_success(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 0, 'output', ''
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.provision_tool.return_value = 'provision string'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._setup_hugepages = mock.Mock()
+
+ self.assertIsNone(dpdk_setup_helper._setup_dpdk())
+ self.assertEqual(dpdk_setup_helper.ssh_helper.execute.call_count, 2)
+
+ @mock.patch('yardstick.ssh.SSH')
+ def test__setup_dpdk_short(self, _):
+ def execute_side(cmd, *args, **kwargs):
+ if 'joined_path' in cmd:
+ return 0, 'output', ''
+ return 1, 'bad output', 'error output'
+
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = execute_side
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.provision_tool.return_value = 'provision string'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._setup_hugepages = mock.Mock()
+
+ self.assertIsNone(dpdk_setup_helper._setup_dpdk())
+ self.assertEqual(dpdk_setup_helper.ssh_helper.execute.call_count, 3)
+
+ @mock.patch('yardstick.ssh.SSH')
+ def test__setup_resources(self, _):
+ vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
+
+ result = dpdk_setup_helper._setup_resources()
+ self.assertIsInstance(result, ResourceProfile)
+ self.assertEqual(dpdk_setup_helper.socket, 0)
+
+ @mock.patch('yardstick.ssh.SSH')
+ def test__setup_resources_socket_1(self, _):
+ vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
+ vnfd_helper.interfaces[0]['virtual-interface']['vpci'] = '0000:55:00.0'
+ vnfd_helper.interfaces[1]['virtual-interface']['vpci'] = '0000:35:00.0'
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
+
+ result = dpdk_setup_helper._setup_resources()
+ self.assertIsInstance(result, ResourceProfile)
+ self.assertEqual(dpdk_setup_helper.socket, 1)
+
+ def test__bind_dpdk_unforced(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ dpdk_setup_helper._bind_dpdk('x', 'y', force=False)
+ self.assertNotIn('--force', ssh_helper.execute.call_args_list[0][0][0])
+
+ def test__detect_and_bind_dpdk_short(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 0, 'output', ''
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+
+ self.assertIsNone(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b'))
+ self.assertEqual(ssh_helper.execute.call_count, 1)
+
+ def test__detect_and_bind_dpdk_fail_to_bind(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.return_value = 1, 'bad output', 'error output'
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._bind_dpdk = mock.Mock()
+
+ self.assertIsNone(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b'))
+ self.assertEqual(ssh_helper.execute.call_count, 2)
+
+ def test__detect_and_bind_dpdk(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ ssh_helper.execute.side_effect = iter([
+ (1, 'bad output', 'error output'),
+ (0, 'output', ''),
+ ])
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._bind_dpdk = mock.Mock()
+
+ self.assertEqual(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b'), 'output')
+ self.assertEqual(ssh_helper.execute.call_count, 2)
+
+ def test__bind_kernel_devices(self):
+ bind_iter = iter([
+ None,
+ 'output',
+ ])
+
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._detect_and_bind_dpdk = mock.Mock(side_effect=bind_iter)
+
+ self.assertIsNone(dpdk_setup_helper._bind_kernel_devices())
+
+ def test_tear_down(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper._dpdk_nic_bind = 'a'
+ dpdk_setup_helper.used_drivers = {
+ '0000:05:00.0': (1, 'd1'),
+ '0000:05:01.0': (3, 'd3'),
+ }
+
+ self.assertIsNone(dpdk_setup_helper.tear_down())
+
+
+class TestResourceHelper(unittest.TestCase):
+
+ def test_setup(self):
+ resource = object()
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ dpdk_setup_helper.setup_vnf_environment = mock.Mock(return_value=resource)
+ resource_helper = ResourceHelper(dpdk_setup_helper)
+
+ self.assertIsNone(resource_helper.setup())
+ self.assertIs(resource_helper.resource, resource)
+
+ def test_generate_cfg(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ resource_helper = ResourceHelper(dpdk_setup_helper)
+
+ self.assertIsNone(resource_helper.generate_cfg())
+
+ def test_stop_collect(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ resource_helper = ResourceHelper(dpdk_setup_helper)
+ resource_helper.resource = mock.Mock()
+
+ self.assertIsNone(resource_helper.stop_collect())
+
+ def test_stop_collect_none(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ resource_helper = ResourceHelper(dpdk_setup_helper)
+ resource_helper.resource = None
+
+ self.assertIsNone(resource_helper.stop_collect())
+
+class TestClientResourceHelper(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'driver': 'i40e',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'driver': 'ixgbe',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:13',
+ 'vpci': '0000:05:00.2',
+ 'driver': 'ixgbe',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.30',
+ 'local_mac': '00:00:00:00:00:11'
+ },
+ 'vnfd-connection-point-ref': 'xe2',
+ 'name': 'xe2'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ VNFD = {
+ 'vnfd:vnfd-catalog': {
+ 'vnfd': [
+ VNFD_0,
+ ],
+ },
+ }
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLStateError',
+ new_callable=lambda: MockError)
+ def test_get_stats_not_connected(self, mock_state_error, mock_logger):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.MagicMock()
+ client_resource_helper.client.get_stats.side_effect = mock_state_error
+
+ self.assertEqual(client_resource_helper.get_stats(), {})
+ self.assertEqual(client_resource_helper.client.get_stats.call_count, 1)
+
+ def test_generate_samples(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.MagicMock()
+ client_resource_helper._vpci_ascending = [
+ '0000:05:00.0',
+ '0000:05:00.1',
+ '0000:05:00.2',
+ ]
+ client_resource_helper.client.get_stats.return_value = {
+ 0: {
+ 'rx_pps': 5.5,
+ 'tx_pps': 4.9,
+ 'rx_bps': 234.78,
+ 'tx_bps': 243.11,
+ 'ipackets': 34251,
+ 'opackets': 52342,
+ },
+ 1: {
+ 'tx_pps': 5.9,
+ 'rx_bps': 434.78,
+ 'opackets': 48791,
+ },
+ }
+
+ expected = {
+ 'xe0': {
+ "rx_throughput_fps": 5.5,
+ "tx_throughput_fps": 4.9,
+ "rx_throughput_mbps": 234.78,
+ "tx_throughput_mbps": 243.11,
+ "in_packets": 34251,
+ "out_packets": 52342,
+ },
+ 'xe1': {
+ "rx_throughput_fps": 0.0,
+ "tx_throughput_fps": 5.9,
+ "rx_throughput_mbps": 434.78,
+ "tx_throughput_mbps": 0.0,
+ "in_packets": 0,
+ "out_packets": 48791,
+ },
+ 'xe2': {
+ "rx_throughput_fps": 0.0,
+ "tx_throughput_fps": 0.0,
+ "rx_throughput_mbps": 0.0,
+ "tx_throughput_mbps": 0.0,
+ "in_packets": 0,
+ "out_packets": 0,
+ },
+ }
+ result = client_resource_helper.generate_samples()
+ self.assertDictEqual(result, expected)
+
+ def test_generate_samples_with_key(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.MagicMock()
+ client_resource_helper._vpci_ascending = [
+ '0000:05:00.0',
+ '0000:05:00.1',
+ ]
+ client_resource_helper.client.get_stats.return_value = {
+ 'key_name': 'key_value',
+ 0: {
+ 'rx_pps': 5.5,
+ 'tx_pps': 4.9,
+ 'rx_bps': 234.78,
+ 'tx_bps': 243.11,
+ 'ipackets': 34251,
+ 'opackets': 52342,
+ },
+ 1: {
+ 'tx_pps': 5.9,
+ 'rx_bps': 434.78,
+ 'opackets': 48791,
+ },
+ }
+
+ expected = {
+ 'xe0': {
+ 'key_name': 'key_value',
+ "rx_throughput_fps": 5.5,
+ "tx_throughput_fps": 4.9,
+ "rx_throughput_mbps": 234.78,
+ "tx_throughput_mbps": 243.11,
+ "in_packets": 34251,
+ "out_packets": 52342,
+ },
+ 'xe1': {
+ 'key_name': 'key_value',
+ "rx_throughput_fps": 0.0,
+ "tx_throughput_fps": 5.9,
+ "rx_throughput_mbps": 434.78,
+ "tx_throughput_mbps": 0.0,
+ "in_packets": 0,
+ "out_packets": 48791,
+ },
+ }
+ result = client_resource_helper.generate_samples('key_name')
+ self.assertDictEqual(result, expected)
+
+ def test_generate_samples_with_key_and_default(self):
+ vnfd_helper = VnfdHelper(self.VNFD_0)
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.MagicMock()
+ client_resource_helper._vpci_ascending = [
+ '0000:05:00.0',
+ '0000:05:00.1',
+ ]
+ client_resource_helper.client.get_stats.return_value = {
+ 0: {
+ 'rx_pps': 5.5,
+ 'tx_pps': 4.9,
+ 'rx_bps': 234.78,
+ 'tx_bps': 243.11,
+ 'ipackets': 34251,
+ 'opackets': 52342,
+ },
+ 1: {
+ 'tx_pps': 5.9,
+ 'rx_bps': 434.78,
+ 'opackets': 48791,
+ },
+ }
+
+ expected = {
+ 'xe0': {
+ 'key_name': 'default',
+ "rx_throughput_fps": 5.5,
+ "tx_throughput_fps": 4.9,
+ "rx_throughput_mbps": 234.78,
+ "tx_throughput_mbps": 243.11,
+ "in_packets": 34251,
+ "out_packets": 52342,
+ },
+ 'xe1': {
+ 'key_name': 'default',
+ "rx_throughput_fps": 0.0,
+ "tx_throughput_fps": 5.9,
+ "rx_throughput_mbps": 434.78,
+ "tx_throughput_mbps": 0.0,
+ "in_packets": 0,
+ "out_packets": 48791,
+ },
+ }
+ result = client_resource_helper.generate_samples('key_name', 'default')
+ self.assertDictEqual(result, expected)
+
+ def test_clear_stats(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.Mock()
+
+ self.assertIsNone(client_resource_helper.clear_stats())
+ self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
+
+ def test_clear_stats_of_ports(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.Mock()
+
+ self.assertIsNone(client_resource_helper.clear_stats([3, 4]))
+ self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
+
+ def test_start(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.Mock()
+
+ self.assertIsNone(client_resource_helper.start())
+ self.assertEqual(client_resource_helper.client.start.call_count, 1)
+
+ def test_start_ports(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper.client = mock.Mock()
+
+ self.assertIsNone(client_resource_helper.start([3, 4]))
+ self.assertEqual(client_resource_helper.client.start.call_count, 1)
+
+ def test_collect_kpi_with_queue(self):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client_resource_helper._result = {'existing': 43, 'replaceable': 12}
+ client_resource_helper._queue = mock.Mock()
+ client_resource_helper._queue.empty.return_value = False
+ client_resource_helper._queue.get.return_value = {'incoming': 34, 'replaceable': 99}
+
+ expected = {
+ 'existing': 43,
+ 'incoming': 34,
+ 'replaceable': 99,
+ }
+ result = client_resource_helper.collect_kpi()
+ self.assertDictEqual(result, expected)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
+ new_callable=lambda: MockError)
+ def test__connect_with_failures(self, mock_error, mock_logger, mock_time):
+ vnfd_helper = VnfdHelper({})
+ ssh_helper = mock.Mock()
+ scenario_helper = mock.Mock()
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
+ client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
+ client = mock.MagicMock()
+ client.connect.side_effect = mock_error
+
+ self.assertIs(client_resource_helper._connect(client), client)
+
+
+class TestRfc2544ResourceHelper(unittest.TestCase):
+
+ RFC2544_CFG_1 = {
+ 'latency': True,
+ 'correlated_traffic': True,
+ 'allowed_drop_rate': '0.1 - 0.15',
+ }
+
+ RFC2544_CFG_2 = {
+ 'allowed_drop_rate': ' 0.25 - 0.05 ',
+ }
+
+ RFC2544_CFG_3 = {
+ 'allowed_drop_rate': '0.2',
+ }
+
+ RFC2544_CFG_4 = {
+ 'latency': True,
+ }
+
+ SCENARIO_CFG_1 = {
+ 'options': {
+ 'rfc2544': RFC2544_CFG_1,
+ }
+ }
+
+ SCENARIO_CFG_2 = {
+ 'options': {
+ 'rfc2544': RFC2544_CFG_2,
+ }
+ }
+
+ SCENARIO_CFG_3 = {
+ 'options': {
+ 'rfc2544': RFC2544_CFG_3,
+ }
+ }
+
+ SCENARIO_CFG_4 = {
+ 'options': {
+ 'rfc2544': RFC2544_CFG_4,
+ }
+ }
+
+ def test_property_rfc2544(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertIsNone(rfc2544_resource_helper._rfc2544)
+ self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
+ self.assertDictEqual(rfc2544_resource_helper._rfc2544, self.RFC2544_CFG_1)
+ scenario_helper.scenario_cfg = {} # ensure that resource_helper caches
+ self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
+
+ def test_property_tolerance_high(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertIsNone(rfc2544_resource_helper._tolerance_high)
+ self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
+ self.assertEqual(rfc2544_resource_helper._tolerance_high, 0.15)
+ scenario_helper.scenario_cfg = {} # ensure that resource_helper caches
+ self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
+
+ def test_property_tolerance_low(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertIsNone(rfc2544_resource_helper._tolerance_low)
+ self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
+ self.assertEqual(rfc2544_resource_helper._tolerance_low, 0.1)
+ scenario_helper.scenario_cfg = {} # ensure that resource_helper caches
+ self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
+
+ def test_property_tolerance_high_range_swap(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.25)
+
+ def test_property_tolerance_low_range_swap(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.05)
+
+ def test_property_tolerance_high_not_range(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.2)
+
+ def test_property_tolerance_low_not_range(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.2)
+
+ def test_property_tolerance_high_default(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.0001)
+
+ def test_property_tolerance_low_default(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.0001)
+
+ def test_property_latency(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertIsNone(rfc2544_resource_helper._latency)
+ self.assertTrue(rfc2544_resource_helper.latency)
+ self.assertTrue(rfc2544_resource_helper._latency)
+ scenario_helper.scenario_cfg = {} # ensure that resource_helper caches
+ self.assertTrue(rfc2544_resource_helper.latency)
+
+ def test_property_latency_default(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertFalse(rfc2544_resource_helper.latency)
+
+ def test_property_correlated_traffic(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertIsNone(rfc2544_resource_helper._correlated_traffic)
+ self.assertTrue(rfc2544_resource_helper.correlated_traffic)
+ self.assertTrue(rfc2544_resource_helper._correlated_traffic)
+ scenario_helper.scenario_cfg = {} # ensure that resource_helper caches
+ self.assertTrue(rfc2544_resource_helper.correlated_traffic)
+
+ def test_property_correlated_traffic_default(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
+ rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
+
+ self.assertFalse(rfc2544_resource_helper.correlated_traffic)
+
+
+class TestSampleVNFDeployHelper(unittest.TestCase):
+
+ @mock.patch('subprocess.check_output')
+ def test_deploy_vnfs_disabled(self, mock_check_output):
+ vnfd_helper = mock.Mock()
+ ssh_helper = mock.Mock()
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.execute.return_value = 1, 'bad output', 'error output'
+ ssh_helper.put.return_value = None
+ sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
+
+ self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
+ self.assertEqual(ssh_helper.execute.call_count, 0)
+ self.assertEqual(ssh_helper.put.call_count, 0)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('subprocess.check_output')
+ def test_deploy_vnfs(self, mock_check_output, mock_time):
+ vnfd_helper = mock.Mock()
+ ssh_helper = mock.Mock()
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.execute.return_value = 1, 'bad output', 'error output'
+ ssh_helper.put.return_value = None
+ sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
+ sample_vnf_deploy_helper.DISABLE_DEPLOY = False
+
+ self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
+ self.assertEqual(ssh_helper.execute.call_count, 5)
+ self.assertEqual(ssh_helper.put.call_count, 1)
+
+ @mock.patch('subprocess.check_output')
+ def test_deploy_vnfs_early_success(self, mock_check_output):
+ vnfd_helper = mock.Mock()
+ ssh_helper = mock.Mock()
+ ssh_helper.join_bin_path.return_value = 'joined_path'
+ ssh_helper.execute.return_value = 0, 'output', ''
+ ssh_helper.put.return_value = None
+ sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
+ sample_vnf_deploy_helper.DISABLE_DEPLOY = False
+
+ self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
+ self.assertEqual(ssh_helper.execute.call_count, 1)
+ self.assertEqual(ssh_helper.put.call_count, 0)
+
+
+class TestScenarioHelper(unittest.TestCase):
+
+ def test_property_task_path(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'task_path': 'my_path',
+ }
+
+ self.assertEqual(scenario_helper.task_path, 'my_path')
+
+ def test_property_nodes(self):
+ nodes = ['node1', 'node2']
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'nodes': nodes,
+ }
+
+ self.assertEqual(scenario_helper.nodes, nodes)
+
+ def test_property_all_options(self):
+ data = {
+ 'name1': {
+ 'key3': 'value3',
+ },
+ 'name2': {}
+ }
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'options': data,
+ }
+
+ self.assertDictEqual(scenario_helper.all_options, data)
+
+ def test_property_options(self):
+ data = {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ }
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'options': {
+ 'name1': data,
+ },
+ }
+
+ self.assertDictEqual(scenario_helper.options, data)
+
+ def test_property_vnf_cfg(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'options': {
+ 'name1': {
+ 'vnf_config': 'my_config',
+ },
+ },
+ }
+
+ self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
+
+ def test_property_vnf_cfg_default(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'options': {
+ 'name1': {},
+ },
+ }
+
+ self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
+
+ def test_property_topology(self):
+ scenario_helper = ScenarioHelper('name1')
+ scenario_helper.scenario_cfg = {
+ 'topology': 'my_topology',
+ }
+
+ self.assertEqual(scenario_helper.topology, 'my_topology')
+
+
+class TestSampleVnf(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ VNFD = {
+ 'vnfd:vnfd-catalog': {
+ 'vnfd': [
+ VNFD_0,
+ ]
+ }
+ }
+
+ TRAFFIC_PROFILE = {
+ "schema": "isb:traffic_profile:0.1",
+ "name": "fixed",
+ "description": "Fixed traffic profile to run UDP traffic",
+ "traffic_profile": {
+ "traffic_type": "FixedTraffic",
+ "frame_rate": 100, # pps
+ "flow_number": 10,
+ "frame_size": 64,
+ },
+ }
+
+ def test___init__(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+
+ self.assertEqual(sample_vnf.name, 'vnf1')
+ self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
+
+ # test the default setup helper is SetupEnvHelper, not subclass
+ self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
+
+ # test the default resource helper is ResourceHelper, not subclass
+ self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
+
+ def test___init___alt_types(self):
+ class MySetupEnvHelper(SetupEnvHelper):
+ pass
+
+
+ class MyResourceHelper(ResourceHelper):
+ pass
+
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
+
+ self.assertEqual(sample_vnf.name, 'vnf1')
+ self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
+
+ # test the default setup helper is MySetupEnvHelper, not subclass
+ self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
+
+ # test the default resource helper is MyResourceHelper, not subclass
+ self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
+
+ def test__get_port0localip6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '0064:ff9b:0:0:0:0:9810:6414'
+ result = sample_vnf._get_port0localip6()
+ self.assertEqual(result, expected)
+
+ def test__get_port1localip6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '0064:ff9b:0:0:0:0:9810:2814'
+ result = sample_vnf._get_port1localip6()
+ self.assertEqual(result, expected)
+
+ def test__get_port0prefixip6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '112'
+ result = sample_vnf._get_port0prefixlen6()
+ self.assertEqual(result, expected)
+
+ def test__get_port1prefixip6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '112'
+ result = sample_vnf._get_port1prefixlen6()
+ self.assertEqual(result, expected)
+
+ def test__get_port0gateway6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '0064:ff9b:0:0:0:0:9810:6414'
+ result = sample_vnf._get_port0gateway6()
+ self.assertEqual(result, expected)
+
+ def test__get_port1gateway6(self):
+ sample_vnf = SampleVNF('vnf1', self.VNFD_0)
+ expected = '0064:ff9b:0:0:0:0:9810:2814'
+ result = sample_vnf._get_port1gateway6()
+ self.assertEqual(result, expected)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
+ def test__start_vnf(self, mock_process_type):
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf._run = mock.Mock()
+
+ self.assertIsNone(sample_vnf.queue_wrapper)
+ self.assertIsNone(sample_vnf._vnf_process)
+ self.assertIsNone(sample_vnf._start_vnf())
+ self.assertIsNotNone(sample_vnf.queue_wrapper)
+ self.assertIsNotNone(sample_vnf._vnf_process)
+
+ @mock.patch("yardstick.ssh.SSH")
+ def test_instantiate(self, ssh):
+ mock_ssh(ssh)
+
+ nodes = {
+ 'vnf1': 'name1',
+ 'vnf2': 'name2',
+ }
+
+ context1 = mock.Mock()
+ context1._get_server.return_value = None
+ context2 = mock.Mock()
+ context2._get_server.return_value = context2
+
+ try:
+ Context.list.clear()
+ except AttributeError:
+ # clear() but works in Py2.7
+ Context.list[:] = []
+
+ Context.list.extend([
+ context1,
+ context2,
+ ])
+
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf._start_server = mock.Mock(return_value=0)
+ sample_vnf._vnf_process = mock.MagicMock()
+ sample_vnf._vnf_process._is_alive.return_value = 1
+ sample_vnf.ssh_helper = mock.MagicMock()
+ sample_vnf.deploy_helper = mock.MagicMock()
+ sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
+ scenario_cfg = {
+ 'nodes': nodes,
+ }
+
+ self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
+ self.assertEqual(sample_vnf.nfvi_context, context2)
+
+ @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
+ @mock.patch("yardstick.ssh.SSH")
+ def test_wait_for_instantiate_empty_queue(self, ssh, mock_time):
+ mock_ssh(ssh, exec_result=(1, "", ""))
+
+ queue_size_list = [
+ 0,
+ 1,
+ 0,
+ 1,
+ ]
+
+ queue_get_list = [
+ 'some output',
+ 'pipeline> ',
+ ]
+
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf._start_server = mock.Mock(return_value=0)
+ sample_vnf._vnf_process = mock.MagicMock()
+ sample_vnf._vnf_process.exitcode = 0
+ sample_vnf._vnf_process._is_alive.return_value = 1
+ sample_vnf.queue_wrapper = mock.Mock()
+ sample_vnf.q_out = mock.Mock()
+ sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
+ sample_vnf.q_out.get.side_effect = iter(queue_get_list)
+ sample_vnf.ssh_helper = mock.MagicMock()
+ sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
+ sample_vnf.resource_helper.start_collect = mock.MagicMock()
+
+ self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
+
+ @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
+ def test_vnf_execute_with_queue_data(self, mock_time):
+ queue_size_list = [
+ 1,
+ 1,
+ 0,
+ ]
+
+ queue_get_list = [
+ 'hello ',
+ 'world'
+ ]
+
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf.q_out = mock.Mock()
+ sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
+ sample_vnf.q_out.get.side_effect = iter(queue_get_list)
+
+ self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
+
+ def test_terminate_without_vnf_process(self):
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf.vnf_execute = mock.Mock()
+ sample_vnf.ssh_helper = mock.Mock()
+ sample_vnf._tear_down = mock.Mock()
+ sample_vnf.resource_helper = mock.Mock()
+
+ self.assertIsNone(sample_vnf.terminate())
+
+ def test_get_stats(self):
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf.APP_WORD = 'sample1'
+ sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
+
+ self.assertEqual(sample_vnf.get_stats(), 'the stats')
+
+ def test_collect_kpi(self):
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
+ sample_vnf.COLLECT_MAP = {
+ 'k1': 3,
+ 'k2': 1,
+ 'k3': 2,
+ }
+ sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
+ sample_vnf.resource_helper = mock.Mock()
+ sample_vnf.resource_helper.collect_kpi.return_value = {}
+
+ expected = {
+ 'k1': 27,
+ 'k2': 34,
+ 'k3': 91,
+ 'collect_stats': {},
+ }
+ result = sample_vnf.collect_kpi()
+ self.assertDictEqual(result, expected)
+
+ def test_collect_kpi_default(self):
+ vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
+ sample_vnf = SampleVNF('vnf1', vnfd)
+ sample_vnf.APP_NAME = 'sample1'
+ sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
+ sample_vnf.get_stats = mock.Mock(return_value='')
+
+ expected = {
+ 'packets_in': 0,
+ 'packets_fwd': 0,
+ 'packets_dropped': 0,
+ }
+ result = sample_vnf.collect_kpi()
+ self.assertDictEqual(result, expected)
+
+
+class TestSampleVNFTrafficGen(unittest.TestCase):
+
+ VNFD_0 = {
+ 'short-name': 'VpeVnf',
+ 'vdu': [
+ {
+ 'routing_table': [
+ {
+ 'network': '152.16.100.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.100.20',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '152.16.40.20',
+ 'netmask': '255.255.255.0',
+ 'gateway': '152.16.40.20',
+ 'if': 'xe1'
+ },
+ ],
+ 'description': 'VPE approximation using DPDK',
+ 'name': 'vpevnf-baremetal',
+ 'nd_route_tbl': [
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:6414',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0'
+ },
+ {
+ 'network': '0064:ff9b:0:0:0:0:9810:2814',
+ 'netmask': '112',
+ 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1'
+ },
+ ],
+ 'id': 'vpevnf-baremetal',
+ 'external-interface': [
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:03',
+ 'vpci': '0000:05:00.0',
+ 'driver': 'i40e',
+ 'local_ip': '152.16.100.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '0',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.100.20',
+ 'local_mac': '00:00:00:00:00:01'
+ },
+ 'vnfd-connection-point-ref': 'xe0',
+ 'name': 'xe0'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:04',
+ 'vpci': '0000:05:00.1',
+ 'driver': 'ixgbe',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.20',
+ 'local_mac': '00:00:00:00:00:02'
+ },
+ 'vnfd-connection-point-ref': 'xe1',
+ 'name': 'xe1'
+ },
+ {
+ 'virtual-interface': {
+ 'dst_mac': '00:00:00:00:00:13',
+ 'vpci': '0000:05:00.2',
+ 'driver': 'ixgbe',
+ 'local_ip': '152.16.40.19',
+ 'type': 'PCI-PASSTHROUGH',
+ 'netmask': '255.255.255.0',
+ 'dpdk_port_num': '1',
+ 'bandwidth': '10 Gbps',
+ 'dst_ip': '152.16.40.30',
+ 'local_mac': '00:00:00:00:00:11'
+ },
+ 'vnfd-connection-point-ref': 'xe2',
+ 'name': 'xe2'
+ },
+ ],
+ },
+ ],
+ 'description': 'Vpe approximation using DPDK',
+ 'mgmt-interface': {
+ 'vdu-id': 'vpevnf-baremetal',
+ 'host': '1.1.1.1',
+ 'password': 'r00t',
+ 'user': 'root',
+ 'ip': '1.1.1.1'
+ },
+ 'benchmark': {
+ 'kpi': [
+ 'packets_in',
+ 'packets_fwd',
+ 'packets_dropped',
+ ],
+ },
+ 'connection-point': [
+ {
+ 'type': 'VPORT',
+ 'name': 'xe0',
+ },
+ {
+ 'type': 'VPORT',
+ 'name': 'xe1',
+ },
+ ],
+ 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
+ }
+
+ VNFD = {
+ 'vnfd:vnfd-catalog': {
+ 'vnfd': [
+ VNFD_0,
+ ],
+ },
+ }
+
+ TRAFFIC_PROFILE = {
+ "schema": "isb:traffic_profile:0.1",
+ "name": "fixed",
+ "description": "Fixed traffic profile to run UDP traffic",
+ "traffic_profile": {
+ "traffic_type": "FixedTraffic",
+ "frame_rate": 100, # pps
+ "flow_number": 10,
+ "frame_size": 64,
+ },
+ }
+
+ def test__check_status(self):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+
+ with self.assertRaises(NotImplementedError):
+ sample_vnf_tg._check_status()
+
+ def test_listen_traffic(self):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+
+ sample_vnf_tg.listen_traffic(mock.Mock())
+
+ def test_verify_traffic(self):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+
+ sample_vnf_tg.verify_traffic(mock.Mock())
+
+ def test_terminate(self):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+ sample_vnf_tg._traffic_process = mock.Mock()
+
+ sample_vnf_tg.terminate()
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
+ def test_wait_for_instantiate(self, mock_logger, mock_time):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+ sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
+ sample_vnf_tg._tg_process = mock.Mock()
+ sample_vnf_tg._tg_process.is_alive.return_value = True
+ sample_vnf_tg._tg_process.exitcode = 234
+
+ self.assertEqual(sample_vnf_tg.wait_for_instantiate(), 234)
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
+ def test_wait_for_instantiate_not_alive(self, mock_logger, mock_time):
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+ sample_vnf_tg._check_status = mock.Mock(return_value=1)
+ sample_vnf_tg._tg_process = mock.Mock()
+ sample_vnf_tg._tg_process.is_alive.side_effect = iter([True, False])
+ sample_vnf_tg._tg_process.exitcode = 234
+
+ with self.assertRaises(RuntimeError):
+ sample_vnf_tg.wait_for_instantiate()
+
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
+ def test_wait_for_instantiate_delayed(self, mock_process, mock_logger, mock_time):
+ class MockClientStarted(mock.Mock):
+
+ def __init__(self, *args, **kwargs):
+ super(MockClientStarted, self).__init__(*args, **kwargs)
+ self.iter = iter([0, 0, 1])
+
+ @property
+ def value(self):
+ return next(self.iter)
+
+ mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
+ mock_traffic_profile.get_traffic_definition.return_value = "64"
+ mock_traffic_profile.execute.return_value = "64"
+ mock_traffic_profile.params = self.TRAFFIC_PROFILE
+
+ sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
+ sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
+ sample_vnf_tg._tg_process = mock.Mock()
+ sample_vnf_tg._tg_process.is_alive.return_value = True
+ sample_vnf_tg._tg_process.exitcode = 234
+ sample_vnf_tg.resource_helper = mock.Mock()
+ sample_vnf_tg.resource_helper.client_started = MockClientStarted()
+
+ self.assertTrue(sample_vnf_tg.run_traffic(mock_traffic_profile))
+ self.assertEqual(mock_time.sleep.call_count, 2)