diff options
Diffstat (limited to 'yardstick/tests')
8 files changed, 1162 insertions, 62 deletions
diff --git a/yardstick/tests/unit/benchmark/core/test_report.py b/yardstick/tests/unit/benchmark/core/test_report.py index 3e80dcc45..11d017ff0 100644 --- a/yardstick/tests/unit/benchmark/core/test_report.py +++ b/yardstick/tests/unit/benchmark/core/test_report.py @@ -20,10 +20,10 @@ GOOD_YAML_NAME = 'fake_name' GOOD_TASK_ID = str(uuid.uuid4()) GOOD_DB_FIELDKEYS = [{'fieldKey': 'fake_key'}] GOOD_DB_TASK = [{ - 'fake_key': 0.000, - 'time': '0000-00-00T00:00:00.000000Z', + 'fake_key': 1.234, + 'time': '0000-00-00T12:34:56.789012Z', }] -GOOD_TIMESTAMP = ['00:00:00.000000'] +GOOD_TIMESTAMP = ['12:34:56.789012'] BAD_YAML_NAME = 'F@KE_NAME' BAD_TASK_ID = 'aaaaaa-aaaaaaaa-aaaaaaaaaa-aaaaaa' @@ -47,23 +47,23 @@ class JSTreeTestCase(unittest.TestCase): def test_format_for_jstree(self): data = [ - {'data': [0, ], 'name': 'tg__0.DropPackets'}, - {'data': [548, ], 'name': 'tg__0.LatencyAvg.5'}, - {'data': [1172, ], 'name': 'tg__0.LatencyAvg.6'}, - {'data': [1001, ], 'name': 'tg__0.LatencyMax.5'}, - {'data': [1468, ], 'name': 'tg__0.LatencyMax.6'}, - {'data': [18.11, ], 'name': 'tg__0.RxThroughput'}, - {'data': [18.11, ], 'name': 'tg__0.TxThroughput'}, - {'data': [0, ], 'name': 'tg__1.DropPackets'}, - {'data': [548, ], 'name': 'tg__1.LatencyAvg.5'}, - {'data': [1172, ], 'name': 'tg__1.LatencyAvg.6'}, - {'data': [1001, ], 'name': 'tg__1.LatencyMax.5'}, - {'data': [1468, ], 'name': 'tg__1.LatencyMax.6'}, - {'data': [18.1132084505, ], 'name': 'tg__1.RxThroughput'}, - {'data': [18.1157260383, ], 'name': 'tg__1.TxThroughput'}, - {'data': [9057888, ], 'name': 'vnf__0.curr_packets_in'}, - {'data': [0, ], 'name': 'vnf__0.packets_dropped'}, - {'data': [617825443, ], 'name': 'vnf__0.packets_fwd'}, + {'data': [0, ], 'label': 'tg__0.DropPackets'}, + {'data': [548, ], 'label': 'tg__0.LatencyAvg.5'}, + {'data': [1172, ], 'label': 'tg__0.LatencyAvg.6'}, + {'data': [1001, ], 'label': 'tg__0.LatencyMax.5'}, + {'data': [1468, ], 'label': 'tg__0.LatencyMax.6'}, + {'data': [18.11, ], 'label': 'tg__0.RxThroughput'}, + {'data': [18.11, ], 'label': 'tg__0.TxThroughput'}, + {'data': [0, ], 'label': 'tg__1.DropPackets'}, + {'data': [548, ], 'label': 'tg__1.LatencyAvg.5'}, + {'data': [1172, ], 'label': 'tg__1.LatencyAvg.6'}, + {'data': [1001, ], 'label': 'tg__1.LatencyMax.5'}, + {'data': [1468, ], 'label': 'tg__1.LatencyMax.6'}, + {'data': [18.1132084505, ], 'label': 'tg__1.RxThroughput'}, + {'data': [18.1157260383, ], 'label': 'tg__1.TxThroughput'}, + {'data': [9057888, ], 'label': 'vnf__0.curr_packets_in'}, + {'data': [0, ], 'label': 'vnf__0.packets_dropped'}, + {'data': [617825443, ], 'label': 'vnf__0.packets_fwd'}, ] expected_output = [ @@ -168,3 +168,15 @@ class ReportTestCase(unittest.TestCase): mock_tasks.assert_called_once_with() mock_keys.assert_called_once_with() self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp) + + @mock.patch.object(report.Report, '_get_tasks') + @mock.patch.object(report.Report, '_get_fieldkeys') + @mock.patch.object(report.Report, '_validate') + def test_generate_nsb(self, mock_valid, mock_keys, mock_tasks): + mock_tasks.return_value = GOOD_DB_TASK + mock_keys.return_value = GOOD_DB_FIELDKEYS + self.rep.generate_nsb(self.param) + mock_valid.assert_called_once_with(GOOD_YAML_NAME, GOOD_TASK_ID) + mock_tasks.assert_called_once_with() + mock_keys.assert_called_once_with() + self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp) diff --git a/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py b/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py index 0f68753fd..35455a49c 100644 --- a/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py +++ b/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py @@ -7,10 +7,6 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -# Unittest for -# yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal - -from __future__ import absolute_import import mock import unittest @@ -18,33 +14,44 @@ from yardstick.benchmark.scenarios.availability.attacker import \ attacker_baremetal -# pylint: disable=unused-argument -# disable this for now because I keep forgetting mock patch arg ordering +class ExecuteShellTestCase(unittest.TestCase): + def setUp(self): + self._mock_subprocess = mock.patch.object(attacker_baremetal, + 'subprocess') + self.mock_subprocess = self._mock_subprocess.start() -@mock.patch('yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal.subprocess') -class ExecuteShellTestCase(unittest.TestCase): + self.addCleanup(self._stop_mocks) - def test__fun_execute_shell_command_successful(self, mock_subprocess): - cmd = "env" - mock_subprocess.check_output.return_value = (0, 'unittest') - exitcode, _ = attacker_baremetal._execute_shell_command(cmd) + def _stop_mocks(self): + self._mock_subprocess.stop() + + def test__execute_shell_command_successful(self): + self.mock_subprocess.check_output.return_value = (0, 'unittest') + exitcode, _ = attacker_baremetal._execute_shell_command("env") self.assertEqual(exitcode, 0) - @mock.patch('yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal.LOG') - def test__fun_execute_shell_command_fail_cmd_exception(self, mock_log, mock_subprocess): - cmd = "env" - mock_subprocess.check_output.side_effect = RuntimeError - exitcode, _ = attacker_baremetal._execute_shell_command(cmd) + @mock.patch.object(attacker_baremetal, 'LOG') + def test__execute_shell_command_fail_cmd_exception(self, mock_log): + self.mock_subprocess.check_output.side_effect = RuntimeError + exitcode, _ = attacker_baremetal._execute_shell_command("env") self.assertEqual(exitcode, -1) mock_log.error.assert_called_once() -@mock.patch('yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal.subprocess') -@mock.patch('yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal.ssh') class AttackerBaremetalTestCase(unittest.TestCase): def setUp(self): + self._mock_ssh = mock.patch.object(attacker_baremetal, 'ssh') + self.mock_ssh = self._mock_ssh.start() + self._mock_subprocess = mock.patch.object(attacker_baremetal, + 'subprocess') + self.mock_subprocess = self._mock_subprocess.start() + self.addCleanup(self._stop_mocks) + + self.mock_ssh.SSH.from_node().execute.return_value = ( + 0, "running", '') + host = { "ipmi_ip": "10.20.0.5", "ipmi_user": "root", @@ -59,26 +66,26 @@ class AttackerBaremetalTestCase(unittest.TestCase): 'host': 'node1', } - def test__attacker_baremetal_all_successful(self, mock_ssh, mock_subprocess): - mock_ssh.SSH.from_node().execute.return_value = (0, "running", '') - ins = attacker_baremetal.BaremetalAttacker(self.attacker_cfg, - self.context) + self.ins = attacker_baremetal.BaremetalAttacker(self.attacker_cfg, + self.context) - ins.setup() - ins.inject_fault() - ins.recover() + def _stop_mocks(self): + self._mock_ssh.stop() + self._mock_subprocess.stop() - def test__attacker_baremetal_check_failuer(self, mock_ssh, mock_subprocess): - mock_ssh.SSH.from_node().execute.return_value = (0, "error check", '') - ins = attacker_baremetal.BaremetalAttacker(self.attacker_cfg, - self.context) - ins.setup() + def test__attacker_baremetal_all_successful(self): + self.ins.setup() + self.ins.inject_fault() + self.ins.recover() - def test__attacker_baremetal_recover_successful(self, mock_ssh, mock_subprocess): + def test__attacker_baremetal_check_failure(self): + self.mock_ssh.SSH.from_node().execute.return_value = ( + 0, "error check", '') + self.ins.setup() + def test__attacker_baremetal_recover_successful(self): self.attacker_cfg["jump_host"] = 'node1' self.context["node1"]["password"] = "123456" - mock_ssh.SSH.from_node().execute.return_value = (0, "running", '') ins = attacker_baremetal.BaremetalAttacker(self.attacker_cfg, self.context) diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py index bf613ca52..c1d902061 100644 --- a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py +++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py @@ -351,6 +351,37 @@ class TestIxNextgen(unittest.TestCase): self.ixnet_gen.ixnet.setAttribute.assert_any_call( 'attr/singleValue', '-value', 'external') + def test_add_interface(self): + self.ixnet_gen.ixnet.add.return_value = 'obj' + self.ixnet_gen.add_interface(vport='vport', + ip='10.0.0.2', + mac='00:00:00:00:00:00', + gateway='10.0.0.1') + self.ixnet_gen.ixnet.add.assert_any_call('vport', 'interface') + self.ixnet_gen.ixnet.add.assert_any_call('obj', 'ipv4') + self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call( + 'obj/ethernet', '-macAddress', '00:00:00:00:00:00') + self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call( + 'obj', '-ip', '10.0.0.2') + self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call( + 'obj', '-gateway', '10.0.0.1') + self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call( + 'obj', '-enabled', 'true') + + def test_add_static_ipv4(self): + self.ixnet_gen.ixnet.add.return_value = 'obj' + self.ixnet_gen.add_static_ipv4(iface='iface', + vport='vport', + start_ip='10.0.0.0', + count='100') + self.ixnet_gen.ixnet.add.assert_called_once_with( + 'vport/protocols/static', 'ip') + self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call( + 'obj', '-protocolInterface', 'iface', + '-ipStart', '10.0.0.0', + '-count', '100', + '-enabled', 'true') + @mock.patch.object(IxNetwork, 'IxNet') def test_connect(self, mock_ixnet): mock_ixnet.return_value = self.ixnet diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py index 5b39b6cd1..ef16676c7 100644 --- a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py +++ b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py @@ -16,6 +16,7 @@ import copy import mock import unittest +import collections from yardstick.network_services.traffic_profile import ixia_rfc2544 from yardstick.network_services.traffic_profile import trex_traffic_profile @@ -511,9 +512,7 @@ class TestIXIARFC2544Profile(unittest.TestCase): with mock.patch.object(rfc2544_profile, '_get_ixia_traffic_profile') \ as mock_get_tp, \ mock.patch.object(rfc2544_profile, '_ixia_traffic_generate') \ - as mock_tgenerate, \ - mock.patch.object(rfc2544_profile, 'update_traffic_profile') \ - as mock_update_tp: + as mock_tgenerate: mock_get_tp.return_value = 'fake_tprofile' output = rfc2544_profile.execute_traffic(mock.ANY, ixia_obj=mock.ANY) @@ -524,7 +523,6 @@ class TestIXIARFC2544Profile(unittest.TestCase): self.assertEqual(0, rfc2544_profile.min_rate) mock_get_tp.assert_called_once() mock_tgenerate.assert_called_once() - mock_update_tp.assert_called_once() def test_execute_traffic_not_first_run(self): rfc2544_profile = ixia_rfc2544.IXIARFC2544Profile(self.TRAFFIC_PROFILE) @@ -683,3 +681,37 @@ class TestIXIARFC2544Profile(unittest.TestCase): self.assertEqual(66.833, samples['RxThroughput']) self.assertEqual(0.099651, samples['DropPercentage']) self.assertEqual(33.45, rfc2544_profile.rate) + + +class TestIXIARFC2544PppoeScenarioProfile(unittest.TestCase): + + TRAFFIC_PROFILE = { + "schema": "nsb:traffic_profile:0.1", + "name": "fixed", + "description": "Fixed traffic profile to run UDP traffic", + "traffic_profile": { + "traffic_type": "FixedTraffic", + "frame_rate": 100}, + 'uplink_0': {'ipv4': {'port': 'xe0', 'id': 1}}, + 'downlink_0': {'ipv4': {'port': 'xe2', 'id': 2}}, + 'uplink_1': {'ipv4': {'port': 'xe1', 'id': 3}}, + 'downlink_1': {'ipv4': {'port': 'xe2', 'id': 4}} + } + + def setUp(self): + self.ixia_tp = ixia_rfc2544.IXIARFC2544PppoeScenarioProfile( + self.TRAFFIC_PROFILE) + + def test___init__(self): + self.assertIsInstance(self.ixia_tp.full_profile, + collections.OrderedDict) + + def test__get_flow_groups_params(self): + expected_tp = collections.OrderedDict([ + ('uplink_0', {'ipv4': {'id': 1, 'port': 'xe0'}}), + ('downlink_0', {'ipv4': {'id': 2, 'port': 'xe2'}}), + ('uplink_1', {'ipv4': {'id': 3, 'port': 'xe1'}}), + ('downlink_1', {'ipv4': {'id': 4, 'port': 'xe2'}})]) + + self.ixia_tp._get_flow_groups_params() + self.assertDictEqual(self.ixia_tp.full_profile, expected_tp) diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py b/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py new file mode 100644 index 000000000..59f37befa --- /dev/null +++ b/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py @@ -0,0 +1,55 @@ +# Copyright (c) 2018 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. + +import unittest +import mock + +from yardstick.network_services.traffic_profile import prox_irq + + +class TestProxIrqProfile(unittest.TestCase): + + def setUp(self): + self._mock_log_info = mock.patch.object(prox_irq.LOG, 'info') + self.mock_log_info = self._mock_log_info.start() + self.addCleanup(self._stop_mocks) + + def _stop_mocks(self): + self._mock_log_info.stop() + + def test_execute_1(self): + tp_config = { + 'traffic_profile': { + }, + } + + traffic_generator = mock.MagicMock() + attrs1 = {'get.return_value' : 10} + traffic_generator.scenario_helper.all_options.configure_mock(**attrs1) + + attrs2 = {'__getitem__.return_value' : 10, 'get.return_value': 10} + traffic_generator.scenario_helper.scenario_cfg["runner"].configure_mock(**attrs2) + + profile_helper = mock.MagicMock() + + profile = prox_irq.ProxIrqProfile(tp_config) + profile.init(mock.MagicMock()) + profile._profile_helper = profile_helper + + profile.execute_traffic(traffic_generator) + profile.run_test() + is_ended_flag = profile.is_ended() + + self.assertFalse(is_ended_flag) + self.assertEqual(profile.lower_bound, 10.0) diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index 6d1d8c6a1..31f08da3e 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -590,6 +590,27 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(result, expected) @mock.patch.object(prox_helpers.LOG, 'error') + def test_irq_core_stats(self, *args): + mock_socket = mock.MagicMock() + prox = prox_helpers.ProxSocketHelper(mock_socket) + prox.get_data = mock.MagicMock(return_value=('0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3')) + + data_0 = {"cpu": 0, 'bucket_0': 1, 'bucket_1': 2, 'bucket_2': 3, 'bucket_3': 4, + 'bucket_4': 5, 'bucket_5': 0, 'bucket_6': 1, 'bucket_7': 2, 'bucket_8': 3, + 'bucket_9': 4, 'bucket_10': 5, 'bucket_11': 0, 'bucket_12': 1, + "max_irq": 0, "overflow": 10} + + data_1 = {"cpu": 1, 'bucket_0': 1, 'bucket_1': 2, 'bucket_2': 3, 'bucket_3': 4, + 'bucket_4': 5, 'bucket_5': 0, 'bucket_6': 1, 'bucket_7': 2, 'bucket_8': 3, + 'bucket_9': 4, 'bucket_10': 5, 'bucket_11': 0, 'bucket_12': 1, + "max_irq": 0, "overflow": 10} + + expected = {"core_0": data_0, "core_1": data_1} + + result = prox.irq_core_stats([[0, 1], [1, 0]]) + self.assertDictEqual(result, expected) + + @mock.patch.object(prox_helpers.LOG, 'error') def test_multi_port_stats(self, *args): mock_socket = mock.MagicMock() prox = prox_helpers.ProxSocketHelper(mock_socket) @@ -2708,3 +2729,15 @@ class TestProxlwAFTRProfileHelper(unittest.TestCase): # negative pkt_size is the only way to make ratio > 1 helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0, line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + +class TestProxIrqProfileHelper(unittest.TestCase): + + def test_run_test(self, *args): + resource_helper = mock.MagicMock() + helper = prox_helpers.ProxIrqProfileHelper(resource_helper) + self.assertIsNone(helper._cores_tuple) + self.assertIsNone(helper._ports_tuple) + self.assertIsNone(helper._latency_cores) + self.assertIsNone(helper._test_cores) + self.assertIsNone(helper._cpu_topology) diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_irq.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_irq.py new file mode 100644 index 000000000..4eaa38c27 --- /dev/null +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_irq.py @@ -0,0 +1,828 @@ +# Copyright (c) 2017-2018 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. + +import unittest +import mock +import errno + +from yardstick.tests import STL_MOCKS +from yardstick.common import exceptions as y_exceptions +from yardstick.network_services.vnf_generic.vnf.prox_irq import ProxIrqGen +from yardstick.network_services.vnf_generic.vnf.prox_irq import ProxIrqVNF +from yardstick.benchmark.contexts import base as ctx_base + +SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' + +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 import prox_vnf + from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh + +VNF_NAME = "vnf__1" + +class TestProxIrqVNF(unittest.TestCase): + + SCENARIO_CFG = { + 'task_path': "", + 'nodes': { + 'tg__1': 'trafficgen_1.yardstick', + 'vnf__1': 'vnf.yardstick'}, + 'runner': { + 'duration': 600, 'type': 'Duration'}, + 'topology': 'prox-tg-topology-2.yaml', + 'traffic_profile': '../../traffic_profiles/prox_binsearch.yaml', + 'type': 'NSPerf', + 'options': { + 'tg__1': {'prox_args': {'-e': '', + '-t': ''}, + 'prox_config': 'configs/l3-gen-2.cfg', + 'prox_path': + '/root/dppd-PROX-v035/build/prox'}, + 'vnf__1': { + 'prox_args': {'-t': ''}, + 'prox_config': 'configs/l3-swap-2.cfg', + 'prox_path': '/root/dppd-PROX-v035/build/prox'}}} + + 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, + }, + } + + CONTEXT_CFG = { + 'nodes': { + 'tg__2': { + 'member-vnf-index': '3', + 'role': 'TrafficGen', + 'name': 'trafficgen_2.yardstick', + 'vnfd-id-ref': 'tg__2', + 'ip': '1.2.1.1', + 'interfaces': { + 'xe0': { + 'local_iface_name': 'ens513f0', + 'vld_id': prox_vnf.ProxApproxVnf.DOWNLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.20', + 'dst_mac': '00:00:00:00:00:01', + 'local_mac': '00:00:00:00:00:03', + 'dst_ip': '152.16.40.19', + 'driver': 'ixgbe', + 'vpci': '0000:02:00.0', + 'dpdk_port_num': 0, + }, + 'xe1': { + 'local_iface_name': 'ens513f1', + 'netmask': '255.255.255.0', + 'network': '202.16.100.0', + 'local_ip': '202.16.100.20', + 'local_mac': '00:1e:67:d0:60:5d', + 'driver': 'ixgbe', + 'vpci': '0000:02:00.1', + 'dpdk_port_num': 1, + }, + }, + 'password': 'r00t', + 'VNF model': 'l3fwd_vnf.yaml', + 'user': 'root', + }, + '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': prox_vnf.ProxApproxVnf.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': prox_vnf.ProxApproxVnf.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': prox_vnf.ProxApproxVnf.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': [ + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.100.20', + 'network': '152.16.100.20', + 'if': 'xe0', + }, + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.40.20', + 'network': '152.16.40.20', + 'if': 'xe1', + }, + ], + 'member-vnf-index': '2', + 'host': '1.2.1.1', + 'role': 'vnf', + 'user': 'root', + 'nd_route_tbl': [ + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:6414', + 'network': '0064:ff9b:0:0:0:0:9810:6414', + 'if': 'xe0', + }, + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:2814', + 'network': '0064:ff9b:0:0:0:0:9810:2814', + 'if': 'xe1', + }, + ], + 'password': 'r00t', + 'VNF model': 'prox_vnf.yaml', + }, + }, + } + + def test___init__(self): + prox_irq_vnf = ProxIrqVNF('vnf1', self.VNFD_0, 'task_id') + + self.assertEqual(prox_irq_vnf.name, 'vnf1') + self.assertDictEqual(prox_irq_vnf.vnfd_helper, self.VNFD_0) + + @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node') + @mock.patch(SSH_HELPER) + def test_collect_kpi(self, ssh, *args): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + resource_helper = mock.MagicMock() + + resource_helper = mock.MagicMock() + + core_1 = {'bucket_1': 1, 'bucket_2': 2, 'bucket_3': 3, 'bucket_4': 4, 'bucket_5': 5, + 'bucket_6': 6, 'bucket_7': 7, 'bucket_8': 8, 'bucket_9': 9, 'bucket_10': 10, + 'bucket_11': 11, 'bucket_12': 12, 'bucket_0': 100, 'cpu': 1, 'max_irq': 12, + 'overflow': 10} + core_2 = {'bucket_1': 1, 'bucket_2': 2, 'bucket_3': 3, 'bucket_4': 4, 'bucket_5': 5, + 'bucket_6': 0, 'bucket_7': 0, 'bucket_8': 0, 'bucket_9': 0, 'bucket_10': 0, + 'bucket_11': 0, 'bucket_12': 0, 'bucket_0': 100, 'cpu': 2, 'max_irq': 12, + 'overflow': 10} + + irq_data = {'core_1': core_1, 'core_2': core_2} + resource_helper.execute.return_value = (irq_data) + + build_config_file = mock.MagicMock() + build_config_file.return_value = None + + prox_irq_vnf = ProxIrqVNF(VNF_NAME, vnfd, 'task_id') + + startup = ["global", [["eal", "-4"]]] + master_0 = ["core 0", [["mode", "master"]]] + core_1 = ["core 1", [["mode", "irq"]]] + core_2 = ["core 2", [["mode", "irq"], ["task", "2"]]] + + prox_irq_vnf.setup_helper._prox_config_data = \ + [startup, master_0, core_1, core_2] + + prox_irq_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG + prox_irq_vnf.resource_helper = resource_helper + prox_irq_vnf.setup_helper.build_config_file = build_config_file + + result = prox_irq_vnf.collect_kpi() + self.assertDictEqual(result["collect_stats"], {}) + + result = prox_irq_vnf.collect_kpi() + self.assertFalse('bucket_10' in result["collect_stats"]['core_2']) + self.assertFalse('bucket_11' in result["collect_stats"]['core_2']) + self.assertFalse('bucket_12' in result["collect_stats"]['core_2']) + self.assertEqual(result["collect_stats"]['core_2']['max_irq'], 12) + + + @mock.patch(SSH_HELPER) + def test_vnf_execute_oserror(self, ssh, *args): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + prox_irq_vnf = ProxIrqVNF(VNF_NAME, vnfd, 'task_id') + prox_irq_vnf.resource_helper = resource_helper = mock.Mock() + + resource_helper.execute.side_effect = OSError(errno.EPIPE, "") + prox_irq_vnf.vnf_execute("", _ignore_errors=True) + + resource_helper.execute.side_effect = OSError(errno.ESHUTDOWN, "") + prox_irq_vnf.vnf_execute("", _ignore_errors=True) + + resource_helper.execute.side_effect = OSError(errno.EADDRINUSE, "") + with self.assertRaises(OSError): + prox_irq_vnf.vnf_execute("", _ignore_errors=True) + + @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') + @mock.patch(SSH_HELPER) + def test_terminate(self, ssh, *args): + mock_ssh(ssh) + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + + mock_ssh(ssh, exec_result=(1, "", "")) + prox_irq_vnf = ProxIrqVNF(VNF_NAME, vnfd, 'task_id') + + prox_irq_vnf._terminated = mock.MagicMock() + prox_irq_vnf._traffic_process = mock.MagicMock() + prox_irq_vnf._traffic_process.terminate = mock.Mock() + prox_irq_vnf.ssh_helper = mock.MagicMock() + prox_irq_vnf.setup_helper = mock.MagicMock() + prox_irq_vnf.resource_helper = mock.MagicMock() + prox_irq_vnf._vnf_wrapper.setup_helper = mock.MagicMock() + prox_irq_vnf._vnf_wrapper._vnf_process = mock.MagicMock(**{"is_alive.return_value": False}) + prox_irq_vnf._vnf_wrapper.resource_helper = mock.MagicMock() + + prox_irq_vnf._run_prox = mock.Mock(return_value=0) + prox_irq_vnf.q_in = mock.Mock() + prox_irq_vnf.q_out = mock.Mock() + + self.assertIsNone(prox_irq_vnf.terminate()) + + @mock.patch(SSH_HELPER) + def test_wait_for_instantiate_panic(self, ssh, *args): + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + + mock_ssh(ssh, exec_result=(1, "", "")) + prox_irq_vnf = ProxIrqVNF(VNF_NAME, vnfd, 'task_id') + + prox_irq_vnf._terminated = mock.MagicMock() + prox_irq_vnf._traffic_process = mock.MagicMock() + prox_irq_vnf._traffic_process.terminate = mock.Mock() + prox_irq_vnf.ssh_helper = mock.MagicMock() + prox_irq_vnf.setup_helper = mock.MagicMock() + prox_irq_vnf.resource_helper = mock.MagicMock() + prox_irq_vnf._vnf_wrapper.setup_helper = mock.MagicMock() + prox_irq_vnf._vnf_wrapper._vnf_process = mock.MagicMock(**{"is_alive.return_value": False}) + prox_irq_vnf._vnf_wrapper.resource_helper = mock.MagicMock() + + prox_irq_vnf._run_prox = mock.Mock(return_value=0) + prox_irq_vnf.q_in = mock.Mock() + prox_irq_vnf.q_out = mock.Mock() + prox_irq_vnf.WAIT_TIME = 0 + with self.assertRaises(RuntimeError): + prox_irq_vnf.wait_for_instantiate() + +class TestProxIrqGen(unittest.TestCase): + + SCENARIO_CFG = { + 'task_path': "", + 'nodes': { + 'tg__1': 'trafficgen_1.yardstick', + 'vnf__1': 'vnf.yardstick'}, + 'runner': { + 'duration': 600, 'type': 'Duration'}, + 'topology': 'prox-tg-topology-2.yaml', + 'traffic_profile': '../../traffic_profiles/prox_binsearch.yaml', + 'type': 'NSPerf', + 'options': { + 'tg__1': {'prox_args': {'-e': '', + '-t': ''}, + 'prox_config': 'configs/l3-gen-2.cfg', + 'prox_path': + '/root/dppd-PROX-v035/build/prox'}, + 'vnf__1': { + 'prox_args': {'-t': ''}, + 'prox_config': 'configs/l3-swap-2.cfg', + 'prox_path': '/root/dppd-PROX-v035/build/prox'}}} + + 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, + ], + }, + } + + 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, + }, + } + + CONTEXT_CFG = { + 'nodes': { + 'tg__2': { + 'member-vnf-index': '3', + 'role': 'TrafficGen', + 'name': 'trafficgen_2.yardstick', + 'vnfd-id-ref': 'tg__2', + 'ip': '1.2.1.1', + 'interfaces': { + 'xe0': { + 'local_iface_name': 'ens513f0', + 'vld_id': prox_vnf.ProxApproxVnf.DOWNLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.20', + 'dst_mac': '00:00:00:00:00:01', + 'local_mac': '00:00:00:00:00:03', + 'dst_ip': '152.16.40.19', + 'driver': 'ixgbe', + 'vpci': '0000:02:00.0', + 'dpdk_port_num': 0, + }, + 'xe1': { + 'local_iface_name': 'ens513f1', + 'netmask': '255.255.255.0', + 'network': '202.16.100.0', + 'local_ip': '202.16.100.20', + 'local_mac': '00:1e:67:d0:60:5d', + 'driver': 'ixgbe', + 'vpci': '0000:02:00.1', + 'dpdk_port_num': 1, + }, + }, + 'password': 'r00t', + 'VNF model': 'l3fwd_vnf.yaml', + 'user': 'root', + }, + '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': prox_vnf.ProxApproxVnf.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': prox_vnf.ProxApproxVnf.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': prox_vnf.ProxApproxVnf.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': [ + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.100.20', + 'network': '152.16.100.20', + 'if': 'xe0', + }, + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.40.20', + 'network': '152.16.40.20', + 'if': 'xe1', + }, + ], + 'member-vnf-index': '2', + 'host': '1.2.1.1', + 'role': 'vnf', + 'user': 'root', + 'nd_route_tbl': [ + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:6414', + 'network': '0064:ff9b:0:0:0:0:9810:6414', + 'if': 'xe0', + }, + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:2814', + 'network': '0064:ff9b:0:0:0:0:9810:2814', + 'if': 'xe1', + }, + ], + 'password': 'r00t', + 'VNF model': 'prox_vnf.yaml', + }, + }, + } + + + def test__check_status(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + + with self.assertRaises(NotImplementedError): + prox_irq_gen._check_status() + + def test_listen_traffic(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + + prox_irq_gen.listen_traffic(mock.Mock()) + + def test_verify_traffic(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + + prox_irq_gen.verify_traffic(mock.Mock()) + + mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') + @mock.patch(SSH_HELPER) + def test_terminate(self, ssh, *args): + mock_ssh(ssh) + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + prox_traffic_gen = ProxIrqGen(VNF_NAME, vnfd, 'task_id') + prox_traffic_gen._terminated = mock.MagicMock() + prox_traffic_gen._traffic_process = mock.MagicMock() + prox_traffic_gen._traffic_process.terminate = mock.Mock() + prox_traffic_gen.ssh_helper = mock.MagicMock() + prox_traffic_gen.setup_helper = mock.MagicMock() + prox_traffic_gen.resource_helper = mock.MagicMock() + prox_traffic_gen._vnf_wrapper.setup_helper = mock.MagicMock() + prox_traffic_gen._vnf_wrapper._vnf_process = mock.MagicMock() + prox_traffic_gen._vnf_wrapper.resource_helper = mock.MagicMock() + self.assertIsNone(prox_traffic_gen.terminate()) + + def test__wait_for_process(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + with mock.patch.object(prox_irq_gen, '_check_status', + return_value=0) as mock_status, \ + mock.patch.object(prox_irq_gen, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(prox_irq_gen._wait_for_process(), 234) + mock_proc.is_alive.assert_called_once() + mock_status.assert_called_once() + + def test__wait_for_process_not_alive(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + with mock.patch.object(prox_irq_gen, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = False + self.assertRaises(RuntimeError, prox_irq_gen._wait_for_process) + mock_proc.is_alive.assert_called_once() + + def test__wait_for_process_delayed(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + with mock.patch.object(prox_irq_gen, '_check_status', + side_effect=[1, 0]) as mock_status, \ + mock.patch.object(prox_irq_gen, + '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(prox_irq_gen._wait_for_process(), 234) + mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()]) + mock_status.assert_has_calls([mock.call(), mock.call()]) + + def test_scale(self): + prox_irq_gen = ProxIrqGen('tg1', self.VNFD_0, 'task_id') + self.assertRaises(y_exceptions.FunctionNotImplemented, + prox_irq_gen.scale) + + @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node') + @mock.patch(SSH_HELPER) + def test_collect_kpi(self, ssh, *args): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + resource_helper = mock.MagicMock() + + core_1 = {'bucket_1': 1, 'bucket_2': 2, 'bucket_3': 3, 'bucket_4': 4, 'bucket_5': 5, + 'bucket_6': 6, 'bucket_7': 7, 'bucket_8': 8, 'bucket_9': 9, 'bucket_10': 10, + 'bucket_11': 11, 'bucket_12': 12, 'bucket_0': 100, 'cpu': 1, 'max_irq': 12, + 'overflow': 10} + core_2 = {'bucket_1': 1, 'bucket_2': 2, 'bucket_3': 3, 'bucket_4': 4, 'bucket_5': 5, + 'bucket_6': 0, 'bucket_7': 0, 'bucket_8': 0, 'bucket_9': 0, 'bucket_10': 0, + 'bucket_11': 0, 'bucket_12': 0, 'bucket_0': 100, 'cpu': 2, 'max_irq': 12, + 'overflow': 10} + + irq_data = {'core_1': core_1, 'core_2': core_2} + resource_helper.sut.irq_core_stats.return_value = (irq_data) + + build_config_file = mock.MagicMock() + build_config_file.return_value = None + + prox_irq_gen = ProxIrqGen(VNF_NAME, vnfd, 'task_id') + + startup = ["global", [["eal", "-4"]]] + master_0 = ["core 0", [["mode", "master"]]] + core_1 = ["core 1", [["mode", "irq"]]] + core_2 = ["core 2", [["mode", "irq"], ["task", "2"]]] + + prox_irq_gen.setup_helper._prox_config_data = \ + [startup, master_0, core_1, core_2] + + prox_irq_gen.scenario_helper.scenario_cfg = self.SCENARIO_CFG + prox_irq_gen.resource_helper = resource_helper + prox_irq_gen.setup_helper.build_config_file = build_config_file + + result = prox_irq_gen.collect_kpi() + self.assertDictEqual(result["collect_stats"], {}) + + result = prox_irq_gen.collect_kpi() + self.assertFalse('bucket_10' in result["collect_stats"]['core_2']) + self.assertFalse('bucket_11' in result["collect_stats"]['core_2']) + self.assertFalse('bucket_12' in result["collect_stats"]['core_2']) + self.assertEqual(result["collect_stats"]['core_2']['max_irq'], 12) diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py index e22398847..65bf56f1e 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py @@ -18,6 +18,7 @@ import mock import six import unittest import ipaddress +from collections import OrderedDict from yardstick.common import utils from yardstick.common import exceptions @@ -105,6 +106,7 @@ class TestIxiaResourceHelper(unittest.TestCase): ixia_rhelper.run_traffic(mock_tprofile) self.assertEqual('fake_samples', ixia_rhelper._queue.get()) + mock_tprofile.update_traffic_profile.assert_called_once() @mock.patch.object(tg_rfc2544_ixia, 'ixnet_api') @@ -524,12 +526,112 @@ class TestIxiaPppoeClientScenario(unittest.TestCase): mock_apply_core_net_cfg.assert_called_once() mock_apply_access_net_cfg.assert_called_once() - def test_create_traffic_model(self): - self.scenario._access_topologies = 'access' - self.scenario._core_topologies = 'core' - self.scenario.create_traffic_model() + @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario, + '_get_endpoints_src_dst_id_pairs') + @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario, + '_get_endpoints_src_dst_obj_pairs') + def test_create_traffic_model(self, mock_obj_pairs, mock_id_pairs): + uplink_endpoints = ['group1', 'group2'] + downlink_endpoints = ['group3', 'group3'] + mock_id_pairs.return_value = ['xe0', 'xe1', 'xe0', 'xe1'] + mock_obj_pairs.return_value = ['group1', 'group3', 'group2', 'group3'] + mock_tp = mock.Mock() + mock_tp.full_profile = {'uplink_0': 'data', + 'downlink_0': 'data', + 'uplink_1': 'data', + 'downlink_1': 'data' + } + self.scenario.create_traffic_model(mock_tp) + mock_id_pairs.assert_called_once_with(mock_tp.full_profile) + mock_obj_pairs.assert_called_once_with(['xe0', 'xe1', 'xe0', 'xe1']) self.scenario.client.create_ipv4_traffic_model.assert_called_once_with( - 'access', 'core') + uplink_endpoints, downlink_endpoints) + + def test__get_endpoints_src_dst_id_pairs(self): + full_tp = OrderedDict([ + ('uplink_0', {'ipv4': {'port': 'xe0'}}), + ('downlink_0', {'ipv4': {'port': 'xe1'}}), + ('uplink_1', {'ipv4': {'port': 'xe0'}}), + ('downlink_1', {'ipv4': {'port': 'xe3'}})]) + endpoints_src_dst_pairs = ['xe0', 'xe1', 'xe0', 'xe3'] + res = self.scenario._get_endpoints_src_dst_id_pairs(full_tp) + self.assertEqual(res, endpoints_src_dst_pairs) + + def test__get_endpoints_src_dst_id_pairs_wrong_flows_number(self): + full_tp = OrderedDict([ + ('uplink_0', {'ipv4': {'port': 'xe0'}}), + ('downlink_0', {'ipv4': {'port': 'xe1'}}), + ('uplink_1', {'ipv4': {'port': 'xe0'}})]) + with self.assertRaises(RuntimeError): + self.scenario._get_endpoints_src_dst_id_pairs(full_tp) + + def test__get_endpoints_src_dst_id_pairs_no_port_key(self): + full_tp = OrderedDict([ + ('uplink_0', {'ipv4': {'id': 1}}), + ('downlink_0', {'ipv4': {'id': 2}})]) + self.assertEqual( + self.scenario._get_endpoints_src_dst_id_pairs(full_tp), []) + + def test__get_endpoints_src_dst_obj_pairs_tp_with_port_key(self): + endpoints_id_pairs = ['xe0', 'xe1', + 'xe0', 'xe1', + 'xe0', 'xe3', + 'xe0', 'xe3'] + ixia_cfg = { + 'pppoe_client': { + 'sessions_per_port': 4, + 'sessions_per_svlan': 1 + }, + 'flow': { + 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}], + 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}] + } + } + + expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1', + 'tp1_dg3', 'tp4_dg1', 'tp1_dg4', 'tp4_dg1'] + + self.scenario._ixia_cfg = ixia_cfg + self.scenario._access_topologies = ['topology1', 'topology2'] + self.scenario._core_topologies = ['topology3', 'topology4'] + self.mock_IxNextgen.get_topology_device_groups.side_effect = \ + [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'], + ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'], + ['tp3_dg1'], + ['tp4_dg1']] + res = self.scenario._get_endpoints_src_dst_obj_pairs( + endpoints_id_pairs) + self.assertEqual(res, expected_result) + + def test__get_endpoints_src_dst_obj_pairs_default_flows_mapping(self): + endpoints_id_pairs = [] + ixia_cfg = { + 'pppoe_client': { + 'sessions_per_port': 4, + 'sessions_per_svlan': 1 + }, + 'flow': { + 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}], + 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}] + } + } + + expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1', + 'tp1_dg3', 'tp3_dg1', 'tp1_dg4', 'tp3_dg1', + 'tp2_dg1', 'tp4_dg1', 'tp2_dg2', 'tp4_dg1', + 'tp2_dg3', 'tp4_dg1', 'tp2_dg4', 'tp4_dg1'] + + self.scenario._ixia_cfg = ixia_cfg + self.scenario._access_topologies = ['topology1', 'topology2'] + self.scenario._core_topologies = ['topology3', 'topology4'] + self.mock_IxNextgen.get_topology_device_groups.side_effect = \ + [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'], + ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'], + ['tp3_dg1'], + ['tp4_dg1']] + res = self.scenario._get_endpoints_src_dst_obj_pairs( + endpoints_id_pairs) + self.assertEqual(res, expected_result) def test_run_protocols(self): self.scenario.client.is_protocols_running.return_value = True |