1 # Copyright (c) 2016-2017 Intel Corporation
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
20 from yardstick import ssh
21 from yardstick.benchmark.contexts import base
22 from yardstick.benchmark.contexts.standalone import model
23 from yardstick.benchmark.contexts.standalone import sriov
26 class SriovContextTestCase(unittest.TestCase):
28 NODES_SAMPLE = "nodes_sample.yaml"
29 NODES_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
30 NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
33 'name': 'StandaloneSriov',
34 'task_id': '1234567890',
42 'mgmt': {'cidr': '152.16.100.10/24'},
44 'phy_port': "0000:05:00.0",
45 'vpci': "0000:00:07.0",
46 'cidr': '152.16.100.10/24',
48 'mac': "00:00:00:00:00:01",
49 'vf_pci': {'vf_pci': 0},
50 'gateway_ip': '152.16.100.20'},
52 'phy_port': "0000:05:00.1",
53 'vpci': "0000:00:08.0",
54 'cidr': '152.16.40.10/24',
56 'vf_pci': {'vf_pci': 0},
57 'mac': "00:00:00:00:00:01",
58 'gateway_ip': '152.16.100.20'},
64 'task_id': '1234567890',
65 'file': self._get_file_abspath(self.NODES_SRIOV_SAMPLE),
67 self.sriov = sriov.SriovContext()
68 self.addCleanup(self._remove_contexts)
71 def _remove_contexts():
72 for context in base.Context.list:
73 context._delete_context()
74 base.Context.list = []
76 @mock.patch.object(model, 'StandaloneContextHelper')
77 @mock.patch.object(model, 'Libvirt')
78 @mock.patch.object(model, 'Server')
79 def test___init__(self, mock_helper, mock_libvirt, mock_server):
80 # pylint: disable=unused-argument
81 # NOTE(ralonsoh): this test doesn't cover function execution.
82 self.sriov.helper = mock_helper
83 self.sriov.vnf_node = mock_server
84 self.assertIsNone(self.sriov.file_path)
85 self.assertTrue(self.sriov.first_run)
88 self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
89 self.assertIsNone(self.sriov.init(self.ATTRS))
91 @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
92 def test_deploy(self, *args):
93 # NOTE(ralonsoh): this test doesn't cover function execution.
94 self.sriov.vm_deploy = False
95 self.assertIsNone(self.sriov.deploy())
97 self.sriov.vm_deploy = True
98 self.sriov.host_mgmt = {}
99 self.sriov.install_req_libs = mock.Mock()
100 self.sriov.get_nic_details = mock.Mock(return_value={})
101 self.sriov.setup_sriov_context = mock.Mock(return_value={})
102 self.sriov.wait_for_vnfs_to_start = mock.Mock(return_value={})
103 self.assertIsNone(self.sriov.deploy())
105 @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
106 @mock.patch.object(model, 'Libvirt')
107 def test_undeploy(self, mock_libvirt, mock_ssh):
108 # pylint: disable=unused-argument
109 # NOTE(ralonsoh): the pylint exception should be removed.
110 self.sriov.vm_deploy = False
111 self.assertIsNone(self.sriov.undeploy())
113 self.sriov.vm_deploy = True
114 self.sriov.connection = mock_ssh
115 self.sriov.vm_names = ['vm_0', 'vm_1']
116 self.sriov.drivers = ['vm_0', 'vm_1']
117 self.assertIsNone(self.sriov.undeploy())
119 def _get_file_abspath(self, filename):
120 curr_path = os.path.dirname(os.path.abspath(__file__))
121 file_path = os.path.join(curr_path, filename)
124 def test__get_server_with_dic_attr_name(self):
126 self.sriov.init(self.attrs)
128 attr_name = {'name': 'foo.bar'}
129 result = self.sriov._get_server(attr_name)
131 self.assertEqual(result, None)
133 def test__get_server_not_found(self):
135 self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
136 self.sriov.init(self.attrs)
138 attr_name = 'bar.foo'
139 result = self.sriov._get_server(attr_name)
141 self.assertEqual(result, None)
143 def test__get_server_mismatch(self):
145 self.sriov.init(self.attrs)
147 attr_name = 'bar.foo1'
148 result = self.sriov._get_server(attr_name)
150 self.assertEqual(result, None)
152 def test__get_server_duplicate(self):
154 self.attrs['file'] = self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE)
156 self.sriov.init(self.attrs)
158 attr_name = 'node1.foo-12345678'
159 with self.assertRaises(ValueError):
160 self.sriov._get_server(attr_name)
162 def test__get_server_found(self):
164 self.sriov.init(self.attrs)
166 attr_name = 'node1.foo-12345678'
167 result = self.sriov._get_server(attr_name)
169 self.assertEqual(result['ip'], '10.229.47.137')
170 self.assertEqual(result['name'], 'node1.foo-12345678')
171 self.assertEqual(result['user'], 'root')
172 self.assertEqual(result['key_filename'], '/root/.yardstick_key')
174 def test__get_physical_node_for_server(self):
176 attrs.update({'servers': {'server1': {}}})
177 self.sriov.init(attrs)
179 # When server is not from this context
180 result = self.sriov._get_physical_node_for_server('server1.another-context')
181 self.assertIsNone(result)
183 # When node_name is not from this context
184 result = self.sriov._get_physical_node_for_server('fake.foo-12345678')
185 self.assertIsNone(result)
187 result = self.sriov._get_physical_node_for_server('server1.foo-12345678')
188 self.assertEqual(result, 'node5.foo')
190 def test__get_server_no_task_id(self):
191 self.attrs['flags'] = {'no_setup': True}
192 self.sriov.init(self.attrs)
194 attr_name = 'node1.foo'
195 result = self.sriov._get_server(attr_name)
197 self.assertEqual(result['ip'], '10.229.47.137')
198 self.assertEqual(result['name'], 'node1.foo')
199 self.assertEqual(result['user'], 'root')
200 self.assertEqual(result['key_filename'], '/root/.yardstick_key')
202 # TODO(elfoley): Split this test
203 # There are at least two sets of inputs/outputs
204 def test__get_network(self):
208 'segmentation_id': 'seg54',
209 'network_type': 'type_a',
210 'physical_network': 'phys',
216 self.sriov.networks = {
222 self.assertIsNone(self.sriov._get_network(attr_name))
224 attr_name = {'vld_id': 'vld777'}
225 self.assertIsNone(self.sriov._get_network(attr_name))
227 self.assertIsNone(self.sriov._get_network(None))
230 self.assertIsNone(self.sriov._get_network(attr_name))
232 attr_name = {'vld_id': 'vld999'}
236 "segmentation_id": None,
237 "network_type": None,
238 "physical_network": None,
240 result = self.sriov._get_network(attr_name)
241 self.assertDictEqual(result, expected)
245 result = self.sriov._get_network(attr_name)
246 self.assertDictEqual(result, expected)
248 def test_configure_nics_for_sriov(self):
249 with mock.patch("yardstick.ssh.SSH") as ssh:
250 ssh_mock = mock.Mock(autospec=ssh.SSH)
252 mock.Mock(return_value=(0, "a", ""))
253 ssh.return_value = ssh_mock
254 self.sriov.vm_deploy = True
255 self.sriov.connection = ssh_mock
256 self.sriov.vm_names = ['vm_0', 'vm_1']
257 self.sriov.drivers = []
258 self.sriov.networks = self.NETWORKS
259 self.sriov.helper.get_mac_address = mock.Mock(return_value="")
260 self.sriov._get_vf_data = mock.Mock(return_value="")
261 self.assertIsNone(self.sriov.configure_nics_for_sriov())
263 @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
264 @mock.patch.object(model.Libvirt, 'add_sriov_interfaces',
265 return_value='out_xml')
266 def test__enable_interfaces(self, mock_add_sriov, mock_ssh):
267 self.sriov.vm_deploy = True
268 self.sriov.connection = mock_ssh
269 self.sriov.vm_names = ['vm_0', 'vm_1']
270 self.sriov.drivers = []
271 self.sriov.networks = self.NETWORKS
274 self.sriov._enable_interfaces(0, 0, ['private_0'], 'test'))
275 mock_add_sriov.assert_called_once_with(
276 '0000:00:0a.0', 0, self.NETWORKS['private_0']['mac'], 'test')
278 @mock.patch.object(model.Libvirt, 'build_vm_xml')
279 @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
280 @mock.patch.object(model.Libvirt, 'write_file')
281 @mock.patch.object(model.Libvirt, 'virsh_create_vm')
282 def test_setup_sriov_context(self, mock_create_vm, mock_write_file,
283 mock_check, mock_build_vm_xml):
284 self.sriov.servers = {
287 'mgmt': {'cidr': '152.16.100.10/24'},
288 'xe0': ['private_0'],
293 connection = mock.Mock()
294 self.sriov.connection = connection
295 self.sriov.host_mgmt = {'ip': '1.2.3.4'}
296 self.sriov.vm_flavor = 'flavor'
297 self.sriov.networks = 'networks'
298 self.sriov.configure_nics_for_sriov = mock.Mock()
299 cfg = '/tmp/vm_sriov_0.xml'
301 xml_out = mock.Mock()
302 mock_build_vm_xml.return_value = (xml_out, '00:00:00:00:00:01')
304 with mock.patch.object(self.sriov, 'vnf_node') as mock_vnf_node, \
305 mock.patch.object(self.sriov, '_enable_interfaces') as \
306 mock_enable_interfaces:
307 mock_enable_interfaces.return_value = 'out_xml'
308 mock_vnf_node.generate_vnf_instance = mock.Mock(
310 nodes_out = self.sriov.setup_sriov_context()
311 self.assertEqual(['node'], nodes_out)
312 mock_vnf_node.generate_vnf_instance.assert_called_once_with(
313 'flavor', 'networks', '1.2.3.4', 'vnf_0',
314 self.sriov.servers['vnf_0'], '00:00:00:00:00:01')
315 mock_build_vm_xml.assert_called_once_with(
316 connection, 'flavor', vm_name, 0)
317 mock_create_vm.assert_called_once_with(connection, cfg)
318 mock_check.assert_called_once_with(vm_name, connection)
319 mock_write_file.assert_called_once_with(cfg, 'out_xml')
320 mock_enable_interfaces.assert_has_calls([
321 mock.call(0, mock.ANY, ['private_0'], mock.ANY),
322 mock.call(0, mock.ANY, ['public_0'], mock.ANY)], any_order=True)
324 def test__get_vf_data(self):
325 with mock.patch("yardstick.ssh.SSH") as ssh:
326 ssh_mock = mock.Mock(autospec=ssh.SSH)
328 mock.Mock(return_value=(0, "a", ""))
330 mock.Mock(return_value=(0, "a", ""))
331 ssh.return_value = ssh_mock
332 self.sriov.vm_deploy = True
333 self.sriov.connection = ssh_mock
334 self.sriov.vm_names = ['vm_0', 'vm_1']
335 self.sriov.drivers = []
336 self.sriov.servers = {
339 'mgmt': {'cidr': '152.16.100.10/24'},
340 'xe0': ['private_0'],
345 self.sriov.networks = self.NETWORKS
346 self.sriov.helper.get_virtual_devices = mock.Mock(
347 return_value={'0000:00:01.0': ''})
348 self.assertIsNotNone(self.sriov._get_vf_data(
349 '0000:00:01.0', '00:00:00:00:00:01', 'if0'))