diff options
Diffstat (limited to 'tests/unit/network_services')
12 files changed, 563 insertions, 317 deletions
diff --git a/tests/unit/network_services/helpers/test_samplevnf_helper.py b/tests/unit/network_services/helpers/test_samplevnf_helper.py index bff3a7722..05acdfaa9 100644 --- a/tests/unit/network_services/helpers/test_samplevnf_helper.py +++ b/tests/unit/network_services/helpers/test_samplevnf_helper.py @@ -797,7 +797,7 @@ class TestMultiPortConfig(unittest.TestCase): def test_generate_arp_route_tbl(self, *_): topology_file = mock.Mock() config_tpl = mock.Mock() - tmp_file = mock.Mock() + tmp_file = "" vnfd_mock = mock.MagicMock() vnfd_mock.port_num.side_effect = ['32', '1', '987'] vnfd_mock.find_interface.side_effect = [ diff --git a/tests/unit/network_services/nfvi/test_resource.py b/tests/unit/network_services/nfvi/test_resource.py index f3244fdbd..5c2f890e8 100644 --- a/tests/unit/network_services/nfvi/test_resource.py +++ b/tests/unit/network_services/nfvi/test_resource.py @@ -99,7 +99,7 @@ class TestResourceProfile(unittest.TestCase): port_names = \ self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]['vdu'][0]['external-interface'] self.resource_profile = \ - ResourceProfile(mgmt, port_names, [1, 2, 3]) + ResourceProfile(mgmt, port_names) self.resource_profile.connection = self.ssh_mock def test___init__(self): @@ -134,10 +134,6 @@ class TestResourceProfile(unittest.TestCase): self.assertIsNone( self.resource_profile._prepare_collectd_conf("/opt/nsb_bin")) - def test__setup_intel_pmu(self): - self.assertIsNone( - self.resource_profile._setup_intel_pmu(self.ssh_mock, "/opt/nsb_bin")) - def test__setup_ovs_stats(self): self.assertIsNone( self.resource_profile._setup_ovs_stats(self.ssh_mock)) diff --git a/tests/unit/network_services/test_utils.py b/tests/unit/network_services/test_utils.py index 993adbeae..bf98a4474 100644 --- a/tests/unit/network_services/test_utils.py +++ b/tests/unit/network_services/test_utils.py @@ -15,8 +15,6 @@ # Unittest for yardstick.network_services.utils -from __future__ import absolute_import - import os import unittest import mock @@ -62,3 +60,84 @@ class UtilsTestCase(unittest.TestCase): ssh.return_value = ssh_mock tool_path = utils.provision_tool(ssh_mock, self.DPDK_PATH) self.assertEqual(tool_path, self.DPDK_PATH) + + +class PciAddressTestCase(unittest.TestCase): + + PCI_ADDRESS_DBSF = '000A:07:03.2' + PCI_ADDRESS_BSF = '06:02.1' + PCI_ADDRESS_DBSF_MULTILINE_1 = '0001:08:04.3\nother text\n' + PCI_ADDRESS_DBSF_MULTILINE_2 = 'first line\n 0001:08:04.3 \nother text\n' + # Will match and return the first address found. + PCI_ADDRESS_DBSF_MULTILINE_3 = ' 0001:08:04.1 \n 05:03.1 \nother\n' + PCI_ADDRESS_BSF_MULTILINE_1 = 'first line\n 08:04.3 \n 0002:05:03.1\n' + BAD_INPUT_1 = 'no address found' + BAD_INPUT_2 = '001:08:04.1' + BAD_INPUT_3 = '08:4.1' + + def test_pciaddress_dbsf(self): + pci_address = utils.PciAddress(PciAddressTestCase.PCI_ADDRESS_DBSF) + self.assertEqual('000a', pci_address.domain) + self.assertEqual('07', pci_address.bus) + self.assertEqual('03', pci_address.slot) + self.assertEqual('2', pci_address.function) + + def test_pciaddress_bsf(self): + pci_address = utils.PciAddress(PciAddressTestCase.PCI_ADDRESS_BSF) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('06', pci_address.bus) + self.assertEqual('02', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_dbsf_multiline_1(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_1) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_dbsf_multiline_2(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_2) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_dbsf_multiline_3(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_3) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_bsf_multiline_1(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_BSF_MULTILINE_1) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_bad_input_no_address(self): + with self.assertRaises(ValueError) as exception: + utils.PciAddress(PciAddressTestCase.BAD_INPUT_1) + self.assertEqual('Invalid PCI address: {}'.format( + PciAddressTestCase.BAD_INPUT_1), str(exception.exception)) + + def test_pciaddress_bad_input_dbsf_bad_formatted(self): + # In this test case, the domain has only 3 characters instead of 4. + pci_address = utils.PciAddress( + PciAddressTestCase.BAD_INPUT_2) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_bad_input_bsf_bad_formatted(self): + with self.assertRaises(ValueError) as exception: + utils.PciAddress(PciAddressTestCase.BAD_INPUT_3) + self.assertEqual('Invalid PCI address: {}'.format( + PciAddressTestCase.BAD_INPUT_3), str(exception.exception)) diff --git a/tests/unit/network_services/traffic_profile/test_prox_mpls.py b/tests/unit/network_services/traffic_profile/test_prox_mpls.py deleted file mode 100644 index 00a690d2a..000000000 --- a/tests/unit/network_services/traffic_profile/test_prox_mpls.py +++ /dev/null @@ -1,95 +0,0 @@ -# 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. -# - -from __future__ import absolute_import - -import unittest -import mock - -from tests.unit import STL_MOCKS - -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.prox_helpers import ProxTestDataTuple - from yardstick.network_services.traffic_profile.prox_mpls_tag_untag import ProxMplsTagUntagProfile - - -class TestProxMplsTagUntagProfile(unittest.TestCase): - - def test_mpls_1(self): - def target(*args, **kwargs): - runs.append(args[2]) - if args[2] < 0 or args[2] > 100: - raise RuntimeError(' '.join([str(args), str(runs)])) - if args[2] > 75.0: - return fail_tuple, {} - return success_tuple, {} - - tp_config = { - 'traffic_profile': { - 'packet_sizes': [200], - }, - } - - runs = [] - success_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.1, 5.2, 5.3], 995, 1000, 123.4) - fail_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.6, 5.7, 5.8], 850, 1000, 123.4) - - traffic_generator = mock.MagicMock() - - profile = ProxMplsTagUntagProfile(tp_config) - profile.init(mock.MagicMock()) - profile._profile_helper = profile_helper = mock.MagicMock() - profile_helper.run_test = target - - profile.execute_traffic(traffic_generator) - self.assertEqual(round(profile.current_lower, 2), 74.69) - self.assertEqual(round(profile.current_upper, 2), 75.39) - self.assertEqual(len(runs), 8) - - def test_mpls_2(self): - def target(*args, **kwargs): - runs.append(args[2]) - if args[2] < 0 or args[2] > 100: - raise RuntimeError(' '.join([str(args), str(runs)])) - if args[2] > 25.0: - return fail_tuple, {} - return success_tuple, {} - - tp_config = { - 'traffic_profile': { - 'packet_sizes': [200], - 'test_precision': 2.0, - }, - } - - runs = [] - success_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.1, 5.2, 5.3], 995, 1000, 123.4) - fail_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.6, 5.7, 5.8], 850, 1000, 123.4) - - traffic_generator = mock.MagicMock() - - profile = ProxMplsTagUntagProfile(tp_config) - profile.init(mock.MagicMock()) - profile._profile_helper = profile_helper = mock.MagicMock() - profile_helper.run_test = target - - profile.execute_traffic(traffic_generator) - self.assertEqual(round(profile.current_lower, 2), 24.06) - self.assertEqual(round(profile.current_upper, 2), 25.47) - self.assertEqual(len(runs), 7) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_base.py b/tests/unit/network_services/vnf_generic/vnf/test_base.py index 478ce186b..f812d67ef 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_base.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_base.py @@ -243,31 +243,13 @@ class TestGenericVNF(unittest.TestCase): class TestGenericTrafficGen(unittest.TestCase): - def test___init__(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - assert generic_traffic_gen.name == "vnf1" - - def test_listen_traffic(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertIsNone(generic_traffic_gen.listen_traffic(traffic_profile)) - - def test_run_traffic(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertRaises(NotImplementedError, - generic_traffic_gen.run_traffic, traffic_profile) - - def test_terminate(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - self.assertRaises(NotImplementedError, generic_traffic_gen.terminate) - def test_verify_traffic(self): + def test_definition(self): + """Make sure that the abstract class cannot be instantiated""" vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertIsNone(generic_traffic_gen.verify_traffic(traffic_profile)) + name = 'vnf1' + with self.assertRaises(TypeError) as exc: + GenericTrafficGen(name, vnfd) + msg = ("Can't instantiate abstract class GenericTrafficGen with " + "abstract methods run_traffic, terminate") + self.assertEqual(msg, str(exc.exception)) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py index b0ef1da91..832509ea7 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py @@ -72,13 +72,12 @@ link 1 up self.assertNotIn("This is a header", out) def test__get_cgnapt_config(self): - vnfd_helper = mock.Mock() + vnfd_helper = mock.MagicMock() vnfd_helper.port_pairs.uplink_ports = [{"name": 'a'}, {"name": "b"}, {"name": "c"}] helper = CgnaptApproxSetupEnvHelper(vnfd_helper, mock.Mock(), mock.Mock()) - helper._get_ports_gateway = mock.Mock(side_effect=[3, 5, 2]) - result = helper._get_cgnapt_config([{"name": 'a'}, {}, {"name": "b"}, {}, {"name": "c"}]) - self.assertEqual(result, [3, 5, 2]) + result = helper._get_cgnapt_config() + self.assertIsNotNone(result) def test_scale(self): helper = CgnaptApproxSetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock()) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index 3c073812c..84eb5dc0d 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -44,6 +44,7 @@ if stl_patch: from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxMplsProfileHelper from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxBngProfileHelper from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxVpeProfileHelper + from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxlwAFTRProfileHelper class TestCoreTuple(unittest.TestCase): @@ -533,20 +534,6 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.hz() self.assertEqual(result, expected) - def test_rx_stats(self, mock_time): - core_stats = [ - '3,4,5,6', - '7,8,9,10,NaN', - '11,12,13,14,15', - ] - - mock_socket = mock.MagicMock() - prox = ProxSocketHelper(mock_socket) - prox.get_data = mock.MagicMock(side_effect=core_stats) - expected = 21, 24, 27, 14 - result = prox.rx_stats([3, 4, 5], 16) - self.assertEqual(result, expected) - def test_core_stats(self, mock_time): core_stats = [ '3,4,5,6', @@ -2215,3 +2202,117 @@ class TestProxVpeProfileHelper(unittest.TestCase): helper.run_test(120, 5, 6.5) helper.run_test(-1000, 5, 6.5) # negative pkt_size is the only way to make ratio > 1 + + +class TestProxlwAFTRProfileHelper(unittest.TestCase): + + def test_lwaftr_cores(self): + resource_helper = mock.MagicMock() + resource_helper.setup_helper.prox_config_data = [ + ('section1', []), + ('section2', [ + ('a', 'b'), + ('c', 'd'), + ]), + ('core 1', []), + ('core 2', [ + ('index', 8), + ('mode', ''), + ]), + ('core 3', [ + ('index', 5), + ('mode', 'gen'), + ('name', 'tun'), + ]), + ('core 4', [ + ('index', 7), + ('mode', 'gen'), + ('name', 'inet'), + ]), + ] + + helper = ProxlwAFTRProfileHelper(resource_helper) + helper._cpu_topology = { + 0: { + 1: { + 5: (5, 1, 0) + }, + 2: { + 6: (6, 2, 0) + }, + 3: { + 7: (7, 3, 0) + }, + 4: { + 8: (8, 3, 0) + }, + } + } + + expected_tun = [7] + expected_inet = [8] + expected_combined = (expected_tun, expected_inet) + + self.assertIsNone(helper._cores_tuple) + self.assertEqual(helper.tun_cores, expected_tun) + self.assertEqual(helper.inet_cores, expected_inet) + self.assertEqual(helper._cores_tuple, expected_combined) + + def test_tun_ports(self): + resource_helper = mock.MagicMock() + resource_helper.setup_helper.prox_config_data = [ + ('section1', []), + ('section2', [ + ('a', 'b'), + ('c', 'd'), + ]), + ('port 3', [ + ('index', '5'), + ('name', 'lwB4'), + ('mac', 'hardware'), + ]), + ('port 4', [ + ('index', '7'), + ('name', 'inet'), + ('mac', 'hardware'), + ]), + ] + + helper = ProxlwAFTRProfileHelper(resource_helper) + helper._port_list = { + 0: { + 1: { + 5: 'lwB4' + }, + 2: { + 6: 'inet' + }, + 3: { + 7: 'lwB4' + }, + 4: { + 8: 'inet' + }, + } + } + + expected_tun = [3] + expected_inet = [4] + expected_combined = (expected_tun, expected_inet) + + self.assertIsNone(helper._ports_tuple) + self.assertEqual(helper.tun_ports, expected_tun) + self.assertEqual(helper.inet_ports, expected_inet) + self.assertEqual(helper._ports_tuple, expected_combined) + + @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') + def test_run_test(self, _): + resource_helper = mock.MagicMock() + resource_helper.step_delta = 0.4 + resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2)) + resource_helper.sut.port_stats.return_value = list(range(10)) + + helper = ProxlwAFTRProfileHelper(resource_helper) + + helper.run_test(120, 5, 6.5) + helper.run_test(-1000, 5, 6.5) # negative pkt_size is the only way to make ratio > 1 diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py index a6d40877d..e29e8ddcd 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py @@ -348,9 +348,9 @@ class TestProxApproxVnf(unittest.TestCase): prox_approx_vnf.resource_helper = resource_helper expected = { - 'packets_in': 7, + 'packets_in': 6, 'packets_dropped': 1, - 'packets_fwd': 6, + 'packets_fwd': 7, 'collect_stats': {'core': {'result': 234}}, } result = prox_approx_vnf.collect_kpi() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py new file mode 100644 index 000000000..9ed6fd5b3 --- /dev/null +++ b/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-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. +# + +from __future__ import absolute_import + +import unittest +import mock + +from tests.unit import STL_MOCKS +from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh + + +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.router_vnf import RouterVNF + + +TEST_FILE_YAML = 'nsb_test_case.yaml' +SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' + + +name = 'vnf__1' + + +class TestRouterVNF(unittest.TestCase): + VNFD = {'vnfd:vnfd-catalog': + {'vnfd': + [{'short-name': 'RouterVNF', + 'vdu': + [{'routing_table': [], + 'description': 'RouterVNF', + 'name': 'router-baremetal', + 'nd_route_tbl': [], + 'id': 'router-baremetal', + 'external-interface': + [{'virtual-interface': + {'dst_mac': '00:00:00:00:00:04', + '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', + 'driver': "i40e", + 'dst_ip': '152.16.100.20', + 'local_iface_name': 'xe0', + 'local_mac': '00:00:00:00:00:02'}, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0'}, + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:03', + 'vpci': '0000:05:00.1', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'driver': "i40e", + 'netmask': '255.255.255.0', + 'dpdk_port_num': 1, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_iface_name': 'xe1', + 'local_mac': '00:00:00:00:00:01'}, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1'}]}], + 'description': 'RouterVNF', + 'mgmt-interface': + {'vdu-id': 'router-baremetal', + 'host': '1.2.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.2.1.1'}, + 'benchmark': + {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, + 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, + {'type': 'VPORT', 'name': 'xe1'}], + 'id': 'RouterVNF', 'name': 'VPEVnfSsh'}]}} + + scenario_cfg = {'nodes': {'cpt__0': 'compute_0.compute_nodes', + 'tg__0': 'trafficgen_1.baremetal', + 'vnf__0': 'vnf.yardstick'}, + 'options': {'flow': {'count': 128000, + 'dst_ip': ['10.0.3.26-10.0.3.105'], + 'dst_port': ['2001-2004'], + 'src_ip': ['10.0.2.26-10.0.2.105'], + 'src_port': ['1234-1238']}, + 'framesize': {'downlink': {'1024B': 100}, + 'uplink': {'1024B': 100}}, + 'rfc2544': {'allowed_drop_rate': '0.0001 - 0.1'}, + 'tg__0': {'queues_per_port': 7}, + 'traffic_type': 4, + 'vnf__0': {'nfvi_enable': True}}, + 'runner': {'interval': 35, + 'iterations': 10, + 'type': 'Iteration'}, + 'topology': 'router-tg-topology.yaml', + 'traffic_profile': '../../traffic_profiles/ipv4_throughput.yaml', + 'type': 'NSPerf'} + + context_cfg = {'nodes': {'tg__1': + {'member-vnf-index': '1', + 'role': 'TrafficGen', + 'name': 'trafficgen_1.yardstick', + 'vnfd-id-ref': 'tg__1', + 'ip': '1.2.1.1', + 'interfaces': + {'xe0': {'local_iface_name': 'ens785f0', + 'vld_id': RouterVNF.UPLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.20', + 'dst_mac': '00:00:00:00:00:02', + 'local_mac': '00:00:00:00:00:04', + 'dst_ip': '152.16.100.19', + 'driver': 'i40e', + 'vpci': '0000:05:00.0', + 'dpdk_port_num': 0}, + 'xe1': {'local_iface_name': 'ens785f1', + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.21', + 'local_mac': '00:00:00:00:00:01', + 'driver': 'i40e', + 'vpci': '0000:05:00.1', + 'dpdk_port_num': 1}}, + 'password': 'r00t', + 'VNF model': 'tg_rfc2544_tpl.yaml', + 'user': 'root'}, + 'vnf__1': + {'name': 'vnf.yardstick', + 'vnfd-id-ref': 'vnf__1', + 'ip': '1.2.1.1', + 'interfaces': + {'xe0': {'local_iface_name': 'ens786f0', + 'vld_id': RouterVNF.UPLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.19', + 'dst_mac': '00:00:00:00:00:04', + 'local_mac': '00:00:00:00:00:02', + 'dst_ip': '152.16.100.20', + 'driver': 'i40e', + 'vpci': '0000:05:00.0', + 'dpdk_port_num': 0}, + 'xe1': {'local_iface_name': 'ens786f1', + 'vld_id': RouterVNF.DOWNLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.19', + 'dst_mac': '00:00:00:00:00:03', + 'local_mac': '00:00:00:00:00:01', + 'dst_ip': '152.16.40.20', + 'driver': 'i40e', + 'vpci': '0000:05:00.1', + 'dpdk_port_num': 1}}, + 'routing_table': [], + 'member-vnf-index': '2', + 'host': '1.2.1.1', + 'role': 'vnf', + 'user': 'root', + 'nd_route_tbl': [], + 'password': 'r00t', + 'VNF model': 'router_vnf.yaml'}}} + + IP_SHOW_STATS_OUTPUT = """\ +2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether d4:c9:ef:52:7c:4d brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped overrun mcast + 2781945429 3202213 0 0 0 30131 + RX errors: length crc frame fifo missed + 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 646221183 2145799 0 0 0 0 + TX errors: aborted fifo window heartbeat + 0 0 0 0 +""" + STATS = { + 'RX:bytes': '2781945429', + 'RX:dropped': '0', + 'RX:errors': '0', + 'RX:mcast': '30131', + 'RX:overrun': '0', + 'RX:packets': '3202213', + 'RX errors:length': '0', + 'RX errors:crc': '0', + 'RX errors:frame': '0', + 'RX errors:fifo': '0', + 'RX errors:missed': '0', + 'TX:bytes': '646221183', + 'TX:carrier': '0', + 'TX:collsns': '0', + 'TX:dropped': '0', + 'TX:errors': '0', + 'TX:packets': '2145799', + 'TX errors:aborted': '0', + 'TX errors:fifo': '0', + 'TX errors:window': '0', + 'TX errors:heartbeat': '0', + } + + def test___init__(self): + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + self.assertIsNone(router_vnf._vnf_process) + + def test_get_stats(self): + stats = RouterVNF.get_stats(self.IP_SHOW_STATS_OUTPUT) + self.assertDictEqual(stats, self.STATS) + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") + @mock.patch(SSH_HELPER) + def test_collect_kpi(self, ssh, _): + m = mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.ssh_helper = m + result = {'packets_dropped': 0, 'packets_fwd': 0, 'packets_in': 0, 'link_stats': {}} + self.assertEqual(result, router_vnf.collect_kpi()) + + @mock.patch(SSH_HELPER) + def test_run_router(self, ssh): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.scenario_helper.scenario_cfg = self.scenario_cfg + router_vnf._run() + router_vnf.ssh_helper.drop_connection.assert_called_once() + + @mock.patch("yardstick.network_services.vnf_generic.vnf.router_vnf.Context") + @mock.patch(SSH_HELPER) + def test_instantiate(self, ssh, _): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.WAIT_TIME = 0 + router_vnf.INTERFACE_WAIT = 0 + self.scenario_cfg.update({"nodes": {"vnf__1": ""}}) + self.assertIsNone(router_vnf.instantiate(self.scenario_cfg, + self.context_cfg)) + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") + @mock.patch(SSH_HELPER) + def test_terminate(self, ssh, _): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf._vnf_process = mock.MagicMock() + router_vnf._vnf_process.terminate = mock.Mock() + self.assertEqual(None, router_vnf.terminate()) + +if __name__ == '__main__': + unittest.main() 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 index c41da2c45..85b10c5a9 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py @@ -29,7 +29,6 @@ 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): @@ -360,15 +359,6 @@ class TestSetupEnvHelper(unittest.TestCase): 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()) @@ -618,111 +608,6 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): 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) - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch('yardstick.ssh.SSH') def test_setup_vnf_environment(self, _, mock_time): @@ -1506,8 +1391,9 @@ class TestRfc2544ResourceHelper(unittest.TestCase): class TestSampleVNFDeployHelper(unittest.TestCase): + @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch('subprocess.check_output') - def test_deploy_vnfs_disabled(self, mock_check_output): + def test_deploy_vnfs_disabled(self, mock_check_output, mock_time): vnfd_helper = mock.Mock() ssh_helper = mock.Mock() ssh_helper.join_bin_path.return_value = 'joined_path' @@ -2136,55 +2022,32 @@ class TestSampleVNFTrafficGen(unittest.TestCase): 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): + def test__wait_for_process(self): 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): + with mock.patch.object(sample_vnf_tg, '_check_status', + return_value=0) as mock_status, \ + mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(sample_vnf_tg._wait_for_process(), 234) + mock_proc.is_alive.assert_called_once() + mock_status.assert_called_once() + + def test__wait_for_process_not_alive(self): 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_traffic.return_value = "64" - mock_traffic_profile.params = self.TRAFFIC_PROFILE + with mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = False + self.assertRaises(RuntimeError, sample_vnf_tg._wait_for_process) + mock_proc.is_alive.assert_called_once() + def test__wait_for_process_delayed(self): 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) + with mock.patch.object(sample_vnf_tg, '_check_status', + side_effect=[1, 0]) as mock_status, \ + mock.patch.object(sample_vnf_tg, + '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(sample_vnf_tg._wait_for_process(), 234) + mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()]) + mock_status.assert_has_calls([mock.call(), mock.call()]) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py index c1b2d27eb..ab3570740 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py @@ -228,7 +228,7 @@ class TestPingTrafficGen(unittest.TestCase): CMD_KWARGS = { 'target_ip': u'152.16.100.20', 'local_ip': u'152.16.100.19', - 'local_if_name': u'xe0', + 'local_if_name': u'xe0_fake', } @mock.patch("yardstick.ssh.SSH") @@ -270,7 +270,7 @@ class TestPingTrafficGen(unittest.TestCase): mock_ssh(ssh, spec=VnfSshHelper, exec_result=(0, "success", "")) ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) ping_traffic_gen.setup_helper.ssh_helper = mock.MagicMock( - **{"execute.return_value": (0, "success", "")}) + **{"execute.return_value": (0, "xe0_fake", "")}) self.assertIsInstance(ping_traffic_gen.ssh_helper, mock.Mock) self.assertEqual(ping_traffic_gen._result, {}) @@ -278,12 +278,12 @@ class TestPingTrafficGen(unittest.TestCase): self.assertEqual( ping_traffic_gen.vnfd_helper.interfaces[0]['virtual-interface']['local_iface_name'], - 'success') + 'xe0_fake') self.assertEqual(self.CMD_KWARGS, ping_traffic_gen.resource_helper.cmd_kwargs) self.assertIsNotNone(ping_traffic_gen._result) @mock.patch("yardstick.ssh.SSH") - def test_listen_traffic(self, ssh): + def test_listen_traffic(self, *args): ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) self.assertIsNone(ping_traffic_gen.listen_traffic({})) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py index d08c62e0b..a2a5058fc 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py @@ -18,6 +18,8 @@ from __future__ import absolute_import import unittest + +import copy import mock SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' @@ -75,6 +77,8 @@ class TestTrexTrafficGen(unittest.TestCase): 'driver': "i40e", 'dst_ip': '152.16.100.20', 'local_iface_name': 'xe0', + 'vld_id': 'downlink_0', + 'ifname': 'xe0', 'local_mac': '00:00:00:00:00:02'}, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0'}, @@ -89,6 +93,8 @@ class TestTrexTrafficGen(unittest.TestCase): 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', + 'vld_id': 'uplink_0', + 'ifname': 'xe1', 'local_mac': '00:00:00:00:00:01'}, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1'}]}], @@ -386,6 +392,8 @@ class TestTrexTrafficGen(unittest.TestCase): self.sut._connect_client.get_stats = mock.Mock(return_value="0") self.sut.resource_helper.RUN_DURATION = 0 self.sut.resource_helper.QUEUE_WAIT_TIME = 0 + # must generate cfg before we can run traffic so Trex port mapping is created + self.sut.resource_helper.generate_cfg() self.sut._traffic_runner(mock_traffic_profile) @mock.patch(SSH_HELPER) @@ -397,6 +405,52 @@ class TestTrexTrafficGen(unittest.TestCase): self.assertIsNone(trex_traffic_gen.resource_helper.generate_cfg()) @mock.patch(SSH_HELPER) + def test_build_ports_reversed_pci_ordering(self, ssh): + mock_ssh(ssh) + vnfd = copy.deepcopy(self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]) + vnfd['vdu'][0]['external-interface'] = [ + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:04', + 'vpci': '0000:05:00.0', + 'local_ip': '152.16.100.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 2, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.20', + 'local_iface_name': 'xe0', + 'vld_id': 'downlink_0', + 'ifname': 'xe0', + 'local_mac': '00:00:00:00:00:02'}, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0'}, + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:03', + 'vpci': '0000:04:00.0', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'driver': "i40e", + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_iface_name': 'xe1', + 'vld_id': 'uplink_0', + 'ifname': 'xe1', + 'local_mac': '00:00:00:00:00:01'}, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1'}] + trex_traffic_gen = TrexTrafficGen(NAME, vnfd) + trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock() + trex_traffic_gen.resource_helper.generate_cfg() + trex_traffic_gen.resource_helper._build_ports() + self.assertEqual(sorted(trex_traffic_gen.resource_helper.all_ports), [0, 1]) + # there is a gap in ordering + self.assertEqual(dict(trex_traffic_gen.resource_helper.dpdk_to_trex_port_map), + {0: 0, 2: 1}) + + @mock.patch(SSH_HELPER) def test_run_traffic(self, ssh): mock_ssh(ssh) |