From f32f0fe4bfb370d7336e890c0c12322d2be2d587 Mon Sep 17 00:00:00 2001 From: Neha Vadnere Date: Tue, 25 Apr 2017 00:17:44 +0530 Subject: Adding new SRIOV Standalone Context This patch adds new SRIOV context to run VNFs with - random uuid generation, - mac address generation, - getting dpdk_nic_bind path, - ssh key based authentication, - printing log messages, - added apache2 licence JIRA: YARDSTICK-480 Change-Id: Ic8317eb9e7e4ecf270091c18be4782d1299ff087 Signed-off-by: Neha Vadnere Signed-off-by: Bindya N --- .../contexts/nodes_duplicate_sample_new.yaml | 112 ++++++ .../unit/benchmark/contexts/nodes_sample_new.yaml | 96 +++++ .../benchmark/contexts/sriov_sample_password.yaml | 52 +++ .../benchmark/contexts/sriov_sample_ssh_key.yaml | 54 +++ .../contexts/sriov_sample_write_to_file.txt | 1 + tests/unit/benchmark/contexts/test_sriov.py | 423 ++++++++++++++++++++ tests/unit/benchmark/contexts/test_standalone.py | 194 +++++++-- yardstick/benchmark/contexts/sriov.py | 432 +++++++++++++++++++++ yardstick/benchmark/contexts/standalone.py | 54 ++- 9 files changed, 1381 insertions(+), 37 deletions(-) create mode 100644 tests/unit/benchmark/contexts/nodes_duplicate_sample_new.yaml create mode 100644 tests/unit/benchmark/contexts/nodes_sample_new.yaml create mode 100644 tests/unit/benchmark/contexts/sriov_sample_password.yaml create mode 100644 tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml create mode 100644 tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt create mode 100644 tests/unit/benchmark/contexts/test_sriov.py create mode 100644 yardstick/benchmark/contexts/sriov.py diff --git a/tests/unit/benchmark/contexts/nodes_duplicate_sample_new.yaml b/tests/unit/benchmark/contexts/nodes_duplicate_sample_new.yaml new file mode 100644 index 000000000..48f4065a2 --- /dev/null +++ b/tests/unit/benchmark/contexts/nodes_duplicate_sample_new.yaml @@ -0,0 +1,112 @@ +# 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. + +nodes: +- + name: trafficgen_1 + role: TrafficGen + ip: 10.123.123.123 + user: root + auth_type: password + password: password + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.0" + driver: ixgbe + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.1" + driver: ixgbe + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" +- + name: sriov + role: Sriov + ip: 10.123.123.122 + user: root + auth_type: password + password: password + vf_macs: + - "00:00:00:00:00:00" + - "00:00:00:00:00:00" + phy_ports: # Physical ports to configure sriov + - "0000:06:00.0" + - "0000:06:00.1" + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu1.img" + +- + name: sriov + role: Sriov + ip: 10.123.123.111 + user: root + auth_type: password + password: password + vf_macs: + - "00:00:00:00:00:00" + - "00:00:00:00:00:00" + phy_ports: # Physical ports to configure sriov + - "0000:06:00.0" + - "0000:06:00.1" + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu1.img" + +- + name: vnf + role: vnf + ip: 10.123.123.121 + user: root + auth_type: password + password: password + host: 10.123.123.121 #BM host == ip, SRIOV & ovs-dpdk host == compute node. + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:06:00.0" + driver: i40e + dpdk_port_num: 0 + local_ip: "152.16.100.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:06:00.1" + driver: i40e + dpdk_port_num: 1 + local_ip: "152.16.40.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + 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" + 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" + diff --git a/tests/unit/benchmark/contexts/nodes_sample_new.yaml b/tests/unit/benchmark/contexts/nodes_sample_new.yaml new file mode 100644 index 000000000..a400bec03 --- /dev/null +++ b/tests/unit/benchmark/contexts/nodes_sample_new.yaml @@ -0,0 +1,96 @@ +# 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. + +nodes: +- + name: trafficgen_1 + role: TrafficGen + ip: 10.123.123.123 + user: root + auth_type: password + password: password + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.0" + driver: ixgbe + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.1" + driver: ixgbe + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" +- + name: sriov + role: Sriov + ip: 10.123.123.122 + user: root + auth_type: password + password: password + vf_macs: + - "00:00:00:00:00:00" + - "00:00:00:00:00:00" + phy_ports: # Physical ports to configure sriov + - "0000:06:00.0" + - "0000:06:00.1" + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu1.img" + +- + name: vnf + role: vnf + ip: 10.123.123.121 + user: root + auth_type: password + password: password + host: 10.123.123.121 #BM host == ip, SRIOV & ovs-dpdk host == compute node. + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:06:00.0" + driver: i40e + dpdk_port_num: 0 + local_ip: "152.16.100.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:06:00.1" + driver: i40e + dpdk_port_num: 1 + local_ip: "152.16.40.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:00" + 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" + 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" + diff --git a/tests/unit/benchmark/contexts/sriov_sample_password.yaml b/tests/unit/benchmark/contexts/sriov_sample_password.yaml new file mode 100644 index 000000000..4f60e46d5 --- /dev/null +++ b/tests/unit/benchmark/contexts/sriov_sample_password.yaml @@ -0,0 +1,52 @@ +# 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. + +nodes: +- + name: trafficgen_1 + role: TrafficGen + ip: 10.10.10.10 + auth_type: password + user: root + password: password + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.0" + driver: ixgbe + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "90:e2:ba:77:ce:68" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.1" + driver: ixgbe + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "90:e2:ba:77:ce:69" +- + name: sriov + role: Sriov + ip: 10.10.10.11 + auth_type: password + user: root + password: password + vf_macs: + - "00:00:00:71:7d:25" + - "00:00:00:71:7d:26" + phy_ports: # Physical ports to configure sriov + - "0000:06:00.0" + - "0000:06:00.1" + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu1.img" diff --git a/tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml b/tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml new file mode 100644 index 000000000..faa496771 --- /dev/null +++ b/tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml @@ -0,0 +1,54 @@ +# 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. + +nodes: +- + name: trafficgen_1 + role: TrafficGen + ip: 10.10.10.10 + auth_type: ssh_key + user: root + ssh_port: 22 + key_filename: /root/.ssh/id_rsa + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.0" + driver: ixgbe + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "90:e2:ba:77:ce:68" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:03:00.1" + driver: ixgbe + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "90:e2:ba:77:ce:69" +- + name: sriov + role: Sriov + ip: 10.10.10.11 + auth_type: ssh_key + user: root + ssh_port: 22 + key_filename: /root/.ssh/id_rsa + vf_macs: + - "00:00:00:71:7d:25" + - "00:00:00:71:7d:26" + phy_ports: # Physical ports to configure sriov + - "0000:06:00.0" + - "0000:06:00.1" + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu1.img" diff --git a/tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt b/tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt new file mode 100644 index 000000000..f0eec86f6 --- /dev/null +++ b/tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt @@ -0,0 +1 @@ +some content \ No newline at end of file diff --git a/tests/unit/benchmark/contexts/test_sriov.py b/tests/unit/benchmark/contexts/test_sriov.py new file mode 100644 index 000000000..e4d8f5e1a --- /dev/null +++ b/tests/unit/benchmark/contexts/test_sriov.py @@ -0,0 +1,423 @@ +# 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 os +import mock +import unittest + +from yardstick.benchmark.contexts import sriov + +NIC_INPUT = { + 'interface': {}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e'} +DRIVER = "i40e" +NIC_DETAILS = { + 'interface': {0: 'enp6s0f0', 1: 'enp6s0f1'}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e'} + +CORRECT_FILE_PATH = "/etc/yardstick/nodes/pod_sriov.yaml" +WRONG_FILE_PATH = "/etc/yardstick/wrong.yaml" +SAMPLE_FILE = "sriov_sample_write_to_file.txt" + +SRIOV = [{ + 'auth_type': 'ssh_key', + 'name': 'sriov', + 'ssh_port': 22, + 'ip': '10.10.10.11', + 'key_filename': '/root/.ssh/id_rsa', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + +SRIOV_PASSWORD = [{ + 'auth_type': 'password', + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.10.10.11', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + +vfnic = "i40evf" +PCIS = ['0000:06:00.0', '0000:06:00.1'] + + +class SriovTestCase(unittest.TestCase): + + NODES_SAMPLE_SSH = "sriov_sample_ssh_key.yaml" + NODES_SAMPLE_PASSWORD = "sriov_sample_password.yaml" + + def setUp(self): + self.test_context = sriov.Sriov() + + def test_construct(self): + self.assertIsNone(self.test_context.name) + self.assertIsNone(self.test_context.file_path) + self.assertEqual(self.test_context.nodes, []) + self.assertEqual(self.test_context.sriov, []) + self.assertFalse(self.test_context.vm_deploy) + self.assertTrue(self.test_context.first_run) + self.assertEqual(self.test_context.user, "") + self.assertEqual(self.test_context.ssh_ip, "") + self.assertEqual(self.test_context.passwd, "") + self.assertEqual(self.test_context.ssh_port, "") + self.assertEqual(self.test_context.auth_type, "") + + def test_init(self): + self.test_context.parse_pod_and_get_data = mock.Mock() + self.test_context.file_path = CORRECT_FILE_PATH + self.test_context.init() + self.assertIsNone(self.test_context.init()) + + def test_successful_init_with_ssh(self): + CORRECT_FILE_PATH = self._get_file_abspath(self.NODES_SAMPLE_SSH) + self.test_context.parse_pod_and_get_data(CORRECT_FILE_PATH) + + def test_successful_init_with_password(self): + CORRECT_FILE_PATH = self._get_file_abspath(self.NODES_SAMPLE_PASSWORD) + self.test_context.parse_pod_and_get_data(CORRECT_FILE_PATH) + + def test_unsuccessful_init(self): + self.assertRaises( + IOError, + lambda: self.test_context.parse_pod_and_get_data(WRONG_FILE_PATH)) + + @mock.patch('yardstick.network_services.utils.provision_tool', return_value="a") + def test_ssh_connection(self, mock_prov): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(1, "a", "")) + ssh.return_value = ssh_mock + mock_prov.provision_tool = mock.Mock() + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV_PASSWORD + self.assertIsNone(sriov_obj.ssh_remote_machine()) + + @mock.patch('yardstick.network_services.utils.provision_tool', return_value="a") + def test_ssh_connection_ssh_key(self, mock_prov): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(1, "a", "")) + ssh.return_value = ssh_mock + mock_prov.provision_tool = mock.Mock() + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV + sriov_obj.key_filename = '/root/.ssh/id_rsa' + self.assertIsNone(sriov_obj.ssh_remote_machine()) + + def test_get_nic_details(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, "eth0 eth1", "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.sriov = SRIOV + sriov_obj.connection = ssh_mock + self.assertIsNotNone(sriov_obj.get_nic_details()) + + def test_install_req_libs(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.first_run = True + sriov_obj.connection = ssh_mock + self.assertIsNone(sriov_obj.install_req_libs()) + + def test_configure_nics_for_sriov(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + nic_details = { + 'interface': {0: 'enp6s0f0', 1: 'enp6s0f1'}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e', + 'vf_pci': [{}, {}]} + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock((DRIVER), return_value=(0, "0 driver", "")) + ssh.return_value = ssh_mock + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + for i in range(len(NIC_DETAILS['pci'])): + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + ssh_mock.execute = \ + mock.Mock(return_value=( + 0, + "{'0':'06:02:00','1':'06:06:00'}", + "")) + sriov_obj.get_vf_datas = mock.Mock(return_value={ + '0000:06:00.0': '0000:06:02.0'}) + nic_details['vf_pci'][i] = sriov_obj.get_vf_datas.return_value + vf_pci = [[], []] + vf_pci[i] = sriov_obj.get_vf_datas.return_value + self.assertIsNotNone( + sriov_obj.configure_nics_for_sriov(DRIVER, NIC_DETAILS)) + + def test_setup_sriov_context(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + nic_details = { + 'interface': {0: 'enp6s0f0', 1: 'enp6s0f1'}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e', + 'vf_pci': [{'vf_pci': '06:02.00'}, {'vf_pci': '06:06.00'}]} + vf = [{'vf_pci': '06:02.00'}, {'vf_pci': '06:06.00'}] + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV + blacklist = "/etc/modprobe.d/blacklist.conf" + self.assertEqual(vfnic, "i40evf") + mock_sriov = mock.Mock() + mock_sriov.sriov_obj.read_from_file(blacklist) + sriov_obj.read_from_file = mock.Mock( + return_value="some random text") + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + sriov_obj.configure_nics_for_sriov = mock.Mock( + return_value=nic_details) + nic_details = sriov_obj.configure_nics_for_sriov.return_value + self.assertEqual(vf, nic_details['vf_pci']) + vf = [ + {'vf_pci': '06:02.00', 'mac': '00:00:00:00:00:0a'}, + {'vf_pci': '06:06.00', 'mac': '00:00:00:00:00:0b'}] + sriov_obj.add_sriov_interface = mock.Mock() + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh_mock.put = mock.Mock() + sriov_obj.check_output = mock.Mock(return_value=(1, {})) + self.assertIsNone( + sriov_obj.setup_sriov_context(PCIS, nic_details, DRIVER)) + + def test_setup_sriov_context_vm_already_present(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + nic_details = { + 'interface': {0: 'enp6s0f0', 1: 'enp6s0f1'}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e', + 'vf_pci': [{'vf_pci': '06:02.00'}, {'vf_pci': '06:06.00'}]} + vf = [{'vf_pci': '06:02.00'}, {'vf_pci': '06:06.00'}] + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV + blacklist = "/etc/modprobe.d/blacklist.conf" + self.assertEqual(vfnic, "i40evf") + mock_sriov = mock.Mock() + mock_sriov.sriov_obj.read_from_file(blacklist) + sriov_obj.read_from_file = mock.Mock( + return_value="some random text") + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + sriov_obj.configure_nics_for_sriov = mock.Mock( + return_value=nic_details) + nic_details = sriov_obj.configure_nics_for_sriov.return_value + self.assertEqual(vf, nic_details['vf_pci']) + vf = [ + {'vf_pci': '06:02.00', 'mac': '00:00:00:00:00:0a'}, + {'vf_pci': '06:06.00', 'mac': '00:00:00:00:00:0b'}] + sriov_obj.add_sriov_interface = mock.Mock() + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh_mock.put = mock.Mock() + sriov_obj.check_output = mock.Mock(return_value=(0, "vm1")) + self.assertIsNone(sriov_obj.setup_sriov_context( + PCIS, + nic_details, + DRIVER)) + + @mock.patch( + 'yardstick.benchmark.contexts.sriov', + return_value="Domain vm1 created from /tmp/vm_sriov.xml") + def test_is_vm_created(self, NIC_INPUT): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + mock_sriov = mock.Mock() + pcis = NIC_DETAILS['pci'] + driver = NIC_DETAILS['phy_driver'] + self.assertIsNotNone( + mock_sriov.sriov_obj.setup_sriov_context( + pcis, + NIC_DETAILS, + driver)) + + def test_add_sriov_interface(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + with mock.patch("xml.etree.ElementTree.parse") as parse: + with mock.patch("re.search") as re: + with mock.patch("xml.etree.ElementTree.SubElement") \ + as elem: + parse = mock.Mock(return_value="root") + re = mock.Mock() + elem = mock.Mock() + print("{0} {1} {2}".format(parse, re, elem)) + self.assertIsNone(sriov_obj.add_sriov_interface( + 0, + "0000:06:02.0", + "00:00:00:00:00:0a", + "/tmp/vm_sriov.xml")) + + def test_get_virtual_devices(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + pci_out = " \ + PCI_CLASS=20000 \ + PCI_ID=8086:154C \ + PCI_SUBSYS_ID=8086:0000 \ + PCI_SLOT_NAME=0000:06:02.0 \ + MODALIAS= \ + pci:v00008086d0000154Csv00008086sd00000000bc02sc00i00" + pci = "0000:06:00.0" + sriov_obj.check_output = mock.Mock(return_value=(0, pci_out)) + with mock.patch("re.search") as re: + re = mock.Mock(return_value="a") + print("{0}".format(re)) + self.assertIsNotNone(sriov_obj.get_virtual_devices(pci)) + + def test_get_vf_datas(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.get_virtual_devices = mock.Mock( + return_value={'0000:06:00.0': '0000:06:02.0'}) + with mock.patch("re.search") as re: + re = mock.Mock() + print("{0}".format(re)) + self.assertIsNotNone(sriov_obj.get_vf_datas( + 'vf_pci', + {'0000:06:00.0': '0000:06:02.0'}, + "00:00:00:00:00:0a")) + + def test_check_output(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + cmd = "command" + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + self.assertIsNotNone(sriov_obj.check_output(cmd, None)) + + def test_split_cpu_list_available(self): + with mock.patch("itertools.chain") as iter1: + iter1 = mock.Mock() + print("{0}".format(iter1)) + sriov_obj = sriov.Sriov() + self.assertIsNotNone(sriov_obj.split_cpu_list('0,5')) + + def test_split_cpu_list_null(self): + with mock.patch("itertools.chain") as iter1: + iter1 = mock.Mock() + print("{0}".format(iter1)) + sriov_obj = sriov.Sriov() + self.assertEqual(sriov_obj.split_cpu_list([]), []) + + def test_destroy_vm_successful(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV + sriov_obj.check_output = mock.Mock(return_value=(0, "vm1")) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh_mock.execute = \ + mock.Mock(return_value=(0, "0 i40e")) + ssh_mock.execute = \ + mock.Mock(return_value=(0, "0 i40e")) + self.assertIsNone(sriov_obj.destroy_vm()) + + def test_destroy_vm_unsuccessful(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, {}, "")) + ssh.return_value = ssh_mock + sriov_obj = sriov.Sriov() + sriov_obj.connection = ssh_mock + sriov_obj.sriov = SRIOV + sriov_obj.check_output = mock.Mock(return_value=(1, {})) + self.assertIsNone(sriov_obj.destroy_vm()) + + def test_read_from_file(self): + CORRECT_FILE_PATH = self._get_file_abspath(self.NODES_SAMPLE_PASSWORD) + sriov_obj = sriov.Sriov() + self.assertIsNotNone(sriov_obj.read_from_file(CORRECT_FILE_PATH)) + + def test_write_to_file(self): + sriov_obj = sriov.Sriov() + self.assertIsNone(sriov_obj.write_to_file(SAMPLE_FILE, "some content")) + + def _get_file_abspath(self, filename): + curr_path = os.path.dirname(os.path.abspath(__file__)) + file_path = os.path.join(curr_path, filename) + return file_path + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit/benchmark/contexts/test_standalone.py b/tests/unit/benchmark/contexts/test_standalone.py index a6fd776e8..ee25bb33b 100644 --- a/tests/unit/benchmark/contexts/test_standalone.py +++ b/tests/unit/benchmark/contexts/test_standalone.py @@ -20,111 +20,235 @@ from __future__ import absolute_import import os import unittest - +import mock from yardstick.benchmark.contexts import standalone +from yardstick.benchmark.contexts import sriov + +MOCKS = { + 'yardstick.benchmark.contexts': mock.MagicMock(), + 'yardstick.benchmark.contexts.sriov': mock.MagicMock(), + 'yardstick.benchmark.contexts.standalone': mock.MagicMock(), +} class StandaloneContextTestCase(unittest.TestCase): - NODES_SAMPLE = "standalone_sample.yaml" - NODES_DUPLICATE_SAMPLE = "standalone_duplicate_sample.yaml" + NODES_SAMPLE = "nodes_sample_new.yaml" + NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample_new.yaml" def setUp(self): self.test_context = standalone.StandaloneContext() def test_construct(self): - self.assertIsNone(self.test_context.name) self.assertIsNone(self.test_context.file_path) self.assertEqual(self.test_context.nodes, []) self.assertEqual(self.test_context.nfvi_node, []) def test_unsuccessful_init(self): - attrs = { 'name': 'foo', 'file': self._get_file_abspath("error_file") } - self.assertRaises(IOError, self.test_context.init, attrs) def test_successful_init(self): - attrs = { - 'name': 'foo', + 'name': 'sriov', 'file': self._get_file_abspath(self.NODES_SAMPLE) } + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + self.test_context.get_nfvi_obj = mock.Mock() self.test_context.init(attrs) - - self.assertEqual(self.test_context.name, "foo") + self.assertEqual(self.test_context.name, "sriov") self.assertEqual(len(self.test_context.nodes), 3) - self.assertEqual(len(self.test_context.nfvi_node), 1) - self.assertEqual(self.test_context.nfvi_node[0]["name"], "node2") + self.assertEqual(len(self.test_context.nfvi_node), 2) + self.assertEqual(self.test_context.nfvi_node[0]["name"], "sriov") def test__get_server_with_dic_attr_name(self): - attrs = { 'name': 'foo', 'file': self._get_file_abspath(self.NODES_SAMPLE) } - + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] self.test_context.init(attrs) - attr_name = {'name': 'foo.bar'} result = self.test_context._get_server(attr_name) - self.assertEqual(result, None) def test__get_server_not_found(self): - attrs = { 'name': 'foo', 'file': self._get_file_abspath(self.NODES_SAMPLE) } - + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] self.test_context.init(attrs) - attr_name = 'bar.foo' result = self.test_context._get_server(attr_name) - self.assertEqual(result, None) def test__get_server_duplicate(self): - attrs = { 'name': 'foo', 'file': self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE) } - + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] self.test_context.init(attrs) - - attr_name = 'node2.foo' - - self.assertRaises(ValueError, self.test_context._get_server, attr_name) + attr_name = 'sriov.foo' + self.assertRaises( + ValueError, + self.test_context._get_server, + attr_name) def test__get_server_found(self): - attrs = { - 'name': 'foo', + 'name': 'sriov', 'file': self._get_file_abspath(self.NODES_SAMPLE) } - + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] self.test_context.init(attrs) - - attr_name = 'node1.foo' + attr_name = 'sriov.sriov' result = self.test_context._get_server(attr_name) - - self.assertEqual(result['ip'], '1.1.1.1') - self.assertEqual(result['name'], 'node1.foo') + self.assertEqual(result['ip'], '10.123.123.122') + self.assertEqual(result['name'], 'sriov.sriov') self.assertEqual(result['user'], 'root') def test_deploy(self): + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + self.test_context.get_nfvi_obj = mock.MagicMock() + self.test_context.init(attrs) + self.test_context.nfvi_obj.ssh_remote_machine = mock.Mock() + self.test_context.nfvi_obj.first_run = True + self.test_context.nfvi_obj.get_nic_details = mock.Mock() + PORTS = ['0000:06:00.0', '0000:06:00.1'] + NIC_DETAILS = { + 'interface': {0: 'enp6s0f0', 1: 'enp6s0f1'}, + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'pci': ['0000:06:00.0', '0000:06:00.1'], + 'phy_driver': 'i40e'} + DRIVER = 'i40e' + result = self.test_context.nfvi_obj.setup_sriov_context( + PORTS, + NIC_DETAILS, + DRIVER) + print("{0}".format(result)) self.assertIsNone(self.test_context.deploy()) def test_undeploy(self): + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + self.test_context.get_nfvi_obj = mock.MagicMock() + self.test_context.init(attrs) + self.test_context.nfvi_obj.destroy_vm = mock.Mock() self.assertIsNone(self.test_context.undeploy()) + def test_get_nfvi_obj(self): + with mock.patch('yardstick.benchmark.contexts.sriov'): + attrs = { + 'name': 'sriov', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + self.test_context.init(attrs) + self.test_context.nfvi_obj.file_path = self._get_file_abspath( + self.NODES_SAMPLE) + self.test_context.nfvi_node = [{ + 'name': 'sriov', + 'vf_macs': ['00:00:00:71:7d:25', '00:00:00:71:7d:26'], + 'ip': '10.123.123.122', + 'role': 'Sriov', + 'user': 'root', + 'images': '/var/lib/libvirt/images/ubuntu1.img', + 'phy_driver': 'i40e', + 'password': 'password', + 'phy_ports': ['0000:06:00.0', '0000:06:00.1']}] + self.test_context.get_nfvi_obj = mock.MagicMock() + self.test_context.init(attrs) + self.test_context.get_context_impl = mock.Mock( + return_value=sriov.Sriov) + self.assertIsNotNone(self.test_context.get_nfvi_obj()) + + def test_get_context_impl_correct_obj(self): + with mock.patch.dict("sys.modules", MOCKS): + self.assertIsNotNone(self.test_context.get_context_impl('Sriov')) + + def test_get_context_impl_wrong_obj(self): + with mock.patch.dict("sys.modules", MOCKS): + self.assertRaises( + ValueError, + lambda: self.test_context.get_context_impl('wrong_object')) + def _get_file_abspath(self, filename): curr_path = os.path.dirname(os.path.abspath(__file__)) file_path = os.path.join(curr_path, filename) @@ -174,3 +298,5 @@ class StandaloneContextTestCase(unittest.TestCase): expected = network1 result = self.test_context._get_network(attr_name) self.assertDictEqual(result, expected) +if __name__ == '__main__': + unittest.main() diff --git a/yardstick/benchmark/contexts/sriov.py b/yardstick/benchmark/contexts/sriov.py new file mode 100644 index 000000000..5dc27bfae --- /dev/null +++ b/yardstick/benchmark/contexts/sriov.py @@ -0,0 +1,432 @@ +# 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 os +import yaml +import re +import time +import glob +import uuid +import random +import logging +import itertools +import xml.etree.ElementTree as ET +from yardstick import ssh +from yardstick.network_services.utils import get_nsb_option +from yardstick.network_services.utils import provision_tool +from yardstick.benchmark.contexts.standalone import StandaloneContext + +log = logging.getLogger(__name__) + +VM_TEMPLATE = """ + + vm1 + {random_uuid} + 102400 + 102400 + + + + 20 + + hvm + + + + + + + + + SandyBridge + + + + + + + + destroy + restart + restart + + /usr/bin/kvm-spice + + + + +
+ + +
+ + + +
+ + + +
+ + + +
+ + + + + + + + + + + + +