Merge "Adding Test Cases for Prox PktTouch Standalone SRIOV"
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_prox_vnf.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
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
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14 #
15
16 import errno
17 import os
18 import unittest
19 import mock
20 from copy import deepcopy
21
22 from yardstick.tests import STL_MOCKS
23 from yardstick.benchmark.contexts import base as ctx_base
24
25
26 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
27
28 STLClient = mock.MagicMock()
29 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
30 stl_patch.start()
31
32 if stl_patch:
33     from yardstick.network_services.vnf_generic.vnf import prox_vnf
34     from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
35
36
37 NAME = "vnf__1"
38
39
40 @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
41 class TestProxApproxVnf(unittest.TestCase):
42
43     VNFD0 = {
44         'short-name': 'ProxVnf',
45         'vdu': [
46             {
47                 'routing_table': [
48                     {
49                         'network': '152.16.100.20',
50                         'netmask': '255.255.255.0',
51                         'gateway': '152.16.100.20',
52                         'if': 'xe0',
53                     },
54                     {
55                         'network': '152.16.40.20',
56                         'netmask': '255.255.255.0',
57                         'gateway': '152.16.40.20',
58                         'if': 'xe1',
59                     },
60                 ],
61                 'description': 'PROX approximation using DPDK',
62                 'name': 'proxvnf-baremetal',
63                 'nd_route_tbl': [
64                     {
65                         'network': '0064:ff9b:0:0:0:0:9810:6414',
66                         'netmask': '112',
67                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
68                         'if': 'xe0',
69                     },
70                     {
71                         'network': '0064:ff9b:0:0:0:0:9810:2814',
72                         'netmask': '112',
73                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
74                         'if': 'xe1',
75                     },
76                 ],
77                 'id': 'proxvnf-baremetal',
78                 'external-interface': [
79                     {
80                         'virtual-interface': {
81                             'dst_mac': '00:00:00:00:00:04',
82                             'vpci': '0000:05:00.0',
83                             'local_ip': '152.16.100.19',
84                             'type': 'PCI-PASSTHROUGH',
85                             'vld_id': 'downlink_0',
86                             'ifname': 'xe1',
87                             'netmask': '255.255.255.0',
88                             'dpdk_port_num': 0,
89                             'bandwidth': '10 Gbps',
90                             'driver': "i40e",
91                             'dst_ip': '152.16.100.20',
92                             'local_iface_name': 'xe0',
93                             'local_mac': '00:00:00:00:00:02',
94                         },
95                         'vnfd-connection-point-ref': 'xe0',
96                         'name': 'xe0',
97                     },
98                     {
99                         'virtual-interface': {
100                             'dst_mac': '00:00:00:00:00:03',
101                             'vpci': '0000:05:00.1',
102                             'local_ip': '152.16.40.19',
103                             'type': 'PCI-PASSTHROUGH',
104                             'vld_id': 'uplink_0',
105                             'ifname': 'xe1',
106                             'driver': "i40e",
107                             'netmask': '255.255.255.0',
108                             'dpdk_port_num': 1,
109                             'bandwidth': '10 Gbps',
110                             'dst_ip': '152.16.40.20',
111                             'local_iface_name': 'xe1',
112                             'local_mac': '00:00:00:00:00:01',
113                         },
114                         'vnfd-connection-point-ref': 'xe1',
115                         'name': 'xe1',
116                     },
117                 ],
118             },
119         ],
120         'description': 'PROX approximation using DPDK',
121         'mgmt-interface': {
122             'vdu-id': 'proxvnf-baremetal',
123             'host': '1.2.1.1',
124             'password': 'r00t',
125             'user': 'root',
126             'ip': '1.2.1.1',
127         },
128         'benchmark': {
129             'kpi': [
130                 'packets_in',
131                 'packets_fwd',
132                 'packets_dropped',
133                 'curr_packets_fwd',
134                 'curr_packets_in'
135             ],
136         },
137         'connection-point': [
138             {
139                 'type': 'VPORT',
140                 'name': 'xe0',
141             },
142             {
143                 'type': 'VPORT',
144                 'name': 'xe1',
145             },
146         ],
147         'id': 'ProxApproxVnf',
148         'name': 'ProxVnf',
149     }
150
151     VNFD = {
152         'vnfd:vnfd-catalog': {
153             'vnfd': [
154                 VNFD0,
155             ],
156         },
157     }
158
159     SCENARIO_CFG = {
160         'task_path': "",
161         'nodes': {
162             'tg__1': 'trafficgen_1.yardstick',
163             'vnf__1': 'vnf.yardstick'},
164         'runner': {
165             'duration': 600, 'type': 'Duration'},
166         'topology': 'prox-tg-topology-2.yaml',
167         'traffic_profile': '../../traffic_profiles/prox_binsearch.yaml',
168         'type': 'NSPerf',
169         'options': {
170             'tg__1': {'prox_args': {'-e': '',
171                                     '-t': ''},
172                       'prox_config': 'configs/l3-gen-2.cfg',
173                       'prox_path':
174                           '/root/dppd-PROX-v035/build/prox'},
175             'vnf__1': {
176                 'prox_args': {'-t': ''},
177                 'prox_config': 'configs/l3-swap-2.cfg',
178                 'prox_path': '/root/dppd-PROX-v035/build/prox'}}}
179
180     CONTEXT_CFG = {
181         'nodes': {
182             'tg__2': {
183                 'member-vnf-index': '3',
184                 'role': 'TrafficGen',
185                 'name': 'trafficgen_2.yardstick',
186                 'vnfd-id-ref': 'tg__2',
187                 'ip': '1.2.1.1',
188                 'interfaces': {
189                     'xe0': {
190                         'local_iface_name': 'ens513f0',
191                         'vld_id': prox_vnf.ProxApproxVnf.DOWNLINK,
192                         'netmask': '255.255.255.0',
193                         'local_ip': '152.16.40.20',
194                         'dst_mac': '00:00:00:00:00:01',
195                         'local_mac': '00:00:00:00:00:03',
196                         'dst_ip': '152.16.40.19',
197                         'driver': 'ixgbe',
198                         'vpci': '0000:02:00.0',
199                         'dpdk_port_num': 0,
200                     },
201                     'xe1': {
202                         'local_iface_name': 'ens513f1',
203                         'netmask': '255.255.255.0',
204                         'network': '202.16.100.0',
205                         'local_ip': '202.16.100.20',
206                         'local_mac': '00:1e:67:d0:60:5d',
207                         'driver': 'ixgbe',
208                         'vpci': '0000:02:00.1',
209                         'dpdk_port_num': 1,
210                     },
211                 },
212                 'password': 'r00t',
213                 'VNF model': 'l3fwd_vnf.yaml',
214                 'user': 'root',
215             },
216             'tg__1': {
217                 'member-vnf-index': '1',
218                 'role': 'TrafficGen',
219                 'name': 'trafficgen_1.yardstick',
220                 'vnfd-id-ref': 'tg__1',
221                 'ip': '1.2.1.1',
222                 'interfaces': {
223                     'xe0': {
224                         'local_iface_name': 'ens785f0',
225                         'vld_id': prox_vnf.ProxApproxVnf.UPLINK,
226                         'netmask': '255.255.255.0',
227                         'local_ip': '152.16.100.20',
228                         'dst_mac': '00:00:00:00:00:02',
229                         'local_mac': '00:00:00:00:00:04',
230                         'dst_ip': '152.16.100.19',
231                         'driver': 'i40e',
232                         'vpci': '0000:05:00.0',
233                         'dpdk_port_num': 0,
234                     },
235                     'xe1': {
236                         'local_iface_name': 'ens785f1',
237                         'netmask': '255.255.255.0',
238                         'local_ip': '152.16.100.21',
239                         'local_mac': '00:00:00:00:00:01',
240                         'driver': 'i40e',
241                         'vpci': '0000:05:00.1',
242                         'dpdk_port_num': 1,
243                     },
244                 },
245                 'password': 'r00t',
246                 'VNF model': 'tg_rfc2544_tpl.yaml',
247                 'user': 'root',
248             },
249             'vnf__1': {
250                 'name': 'vnf.yardstick',
251                 'vnfd-id-ref': 'vnf__1',
252                 'ip': '1.2.1.1',
253                 'interfaces': {
254                     'xe0': {
255                         'local_iface_name': 'ens786f0',
256                         'vld_id': prox_vnf.ProxApproxVnf.UPLINK,
257                         'netmask': '255.255.255.0',
258                         'local_ip': '152.16.100.19',
259                         'dst_mac': '00:00:00:00:00:04',
260                         'local_mac': '00:00:00:00:00:02',
261                         'dst_ip': '152.16.100.20',
262                         'driver': 'i40e',
263                         'vpci': '0000:05:00.0',
264                         'dpdk_port_num': 0,
265                     },
266                     'xe1': {
267                         'local_iface_name': 'ens786f1',
268                         'vld_id': prox_vnf.ProxApproxVnf.DOWNLINK,
269                         'netmask': '255.255.255.0',
270                         'local_ip': '152.16.40.19',
271                         'dst_mac': '00:00:00:00:00:03',
272                         'local_mac': '00:00:00:00:00:01',
273                         'dst_ip': '152.16.40.20',
274                         'driver': 'i40e',
275                         'vpci': '0000:05:00.1',
276                         'dpdk_port_num': 1,
277                     },
278                 },
279                 'routing_table': [
280                     {
281                         'netmask': '255.255.255.0',
282                         'gateway': '152.16.100.20',
283                         'network': '152.16.100.20',
284                         'if': 'xe0',
285                     },
286                     {
287                         'netmask': '255.255.255.0',
288                         'gateway': '152.16.40.20',
289                         'network': '152.16.40.20',
290                         'if': 'xe1',
291                     },
292                 ],
293                 'member-vnf-index': '2',
294                 'host': '1.2.1.1',
295                 'role': 'vnf',
296                 'user': 'root',
297                 'nd_route_tbl': [
298                     {
299                         'netmask': '112',
300                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
301                         'network': '0064:ff9b:0:0:0:0:9810:6414',
302                         'if': 'xe0',
303                     },
304                     {
305                         'netmask': '112',
306                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
307                         'network': '0064:ff9b:0:0:0:0:9810:2814',
308                         'if': 'xe1',
309                     },
310                 ],
311                 'password': 'r00t',
312                 'VNF model': 'prox_vnf.yaml',
313             },
314         },
315     }
316
317     @mock.patch(SSH_HELPER)
318     def test___init__(self, ssh, *args):
319         mock_ssh(ssh)
320         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
321         self.assertIsNone(prox_approx_vnf._vnf_process)
322
323     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
324     @mock.patch(SSH_HELPER)
325     def test_collect_kpi_no_client(self, ssh, *args):
326         mock_ssh(ssh)
327
328         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
329         prox_approx_vnf.scenario_helper.scenario_cfg = {
330             'nodes': {prox_approx_vnf.name: "mock"}
331         }
332         prox_approx_vnf.resource_helper = None
333         expected = {
334             'physical_node': 'mock_node',
335             'packets_in': 0,
336             'packets_dropped': 0,
337             'packets_fwd': 0,
338             'curr_packets_in': 0,
339             'curr_packets_fwd': 0,
340             'collect_stats': {'core': {}}
341         }
342         result = prox_approx_vnf.collect_kpi()
343         self.assertEqual(result, expected)
344
345     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
346     @mock.patch(SSH_HELPER)
347     def test_collect_kpi(self, ssh, *args):
348         mock_ssh(ssh)
349
350         resource_helper = mock.MagicMock()
351         resource_helper.execute.return_value = (True,
352                                                 [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]])
353         resource_helper.collect_collectd_kpi.return_value = {'core': {'result': 234}}
354
355         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
356         prox_approx_vnf.scenario_helper.scenario_cfg = {
357             'nodes': {prox_approx_vnf.name: "mock"}
358         }
359         prox_approx_vnf.resource_helper = resource_helper
360         prox_approx_vnf.tsc_hz = 1000
361
362         expected = {
363             'curr_packets_in': 200,
364             'curr_packets_fwd': 400,
365             'physical_node': 'mock_node',
366             'packets_in': 2,
367             'packets_dropped': 2,
368             'packets_fwd': 4,
369             'collect_stats': {'core': {'result': 234}},
370         }
371         result = prox_approx_vnf.collect_kpi()
372         self.assertEqual(result['packets_in'], expected['packets_in'])
373         self.assertEqual(result['packets_dropped'], expected['packets_dropped'])
374         self.assertEqual(result['packets_fwd'], expected['packets_fwd'])
375         self.assertEqual(result['curr_packets_in'], expected['curr_packets_in'])
376         self.assertEqual(result['curr_packets_fwd'], expected['curr_packets_fwd'])
377
378     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
379     @mock.patch(SSH_HELPER)
380     def test_collect_kpi_bad_input(self, ssh, *args):
381         mock_ssh(ssh)
382
383         resource_helper = mock.MagicMock()
384         resource_helper.execute.return_value = (True,
385                                                 [[0, 'A', 'B', 'C', 'D', 'E'],
386                                                  ['F', 1, 2, 3, 4, 5]])
387
388         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
389         prox_approx_vnf.scenario_helper.scenario_cfg = {
390             'nodes': {prox_approx_vnf.name: "mock"}
391         }
392         prox_approx_vnf.resource_helper = resource_helper
393
394         result = prox_approx_vnf.collect_kpi()
395         self.assertDictEqual(result, {})
396
397     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
398     @mock.patch(SSH_HELPER)
399     def test_collect_kpi_bad_input2(self, ssh, *args):
400         mock_ssh(ssh)
401
402         resource_helper = mock.MagicMock()
403         resource_helper.execute.return_value = (False,
404                                                 [[0, 'A', 'B', 'C', 'D', 'E'],
405                                                  ['F', 1, 2, 3, 4, 5]])
406
407         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
408         prox_approx_vnf.scenario_helper.scenario_cfg = {
409             'nodes': {prox_approx_vnf.name: "mock"}
410         }
411         prox_approx_vnf.resource_helper = resource_helper
412
413         result = prox_approx_vnf.collect_kpi()
414         self.assertDictEqual(result, {})
415
416     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
417     @mock.patch(SSH_HELPER)
418     def test_collect_kpi_error(self, ssh, *args):
419         mock_ssh(ssh)
420
421         resource_helper = mock.MagicMock()
422         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, deepcopy(self.VNFD0),
423                                                  'task_id')
424         prox_approx_vnf.scenario_helper.scenario_cfg = {
425             'nodes': {prox_approx_vnf.name: "mock"}
426         }
427         prox_approx_vnf.resource_helper = resource_helper
428         prox_approx_vnf.vnfd_helper['vdu'][0]['external-interface'] = []
429         prox_approx_vnf.vnfd_helper.port_pairs.interfaces = []
430
431         with self.assertRaises(RuntimeError):
432             prox_approx_vnf.collect_kpi()
433
434     def _get_file_abspath(self, filename, *args):
435         curr_path = os.path.dirname(os.path.abspath(__file__))
436         file_path = os.path.join(curr_path, filename)
437         return file_path
438
439     @mock.patch('yardstick.common.utils.open', create=True)
440     @mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.open', create=True)
441     @mock.patch('yardstick.network_services.helpers.iniparser.open', create=True)
442     @mock.patch(SSH_HELPER)
443     def test_run_prox(self, ssh, *_):
444         mock_ssh(ssh)
445
446         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
447         prox_approx_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG
448         prox_approx_vnf.ssh_helper.join_bin_path.return_value = '/tool_path12/tool_file34'
449         prox_approx_vnf.setup_helper.remote_path = 'configs/file56.cfg'
450
451         expected = "sudo bash -c 'cd /tool_path12; " \
452                    "/tool_path12/tool_file34 -o cli -t  -f /tmp/l3-swap-2.cfg '"
453
454         prox_approx_vnf._run()
455         result = prox_approx_vnf.ssh_helper.run.call_args[0][0]
456         self.assertEqual(result, expected)
457
458     @mock.patch(SSH_HELPER)
459     def bad_test_instantiate(self, *args):
460         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
461         prox_approx_vnf.scenario_helper = mock.MagicMock()
462         prox_approx_vnf.setup_helper = mock.MagicMock()
463         # we can't mock super
464         prox_approx_vnf.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG)
465         prox_approx_vnf.setup_helper.build_config.assert_called_once()
466
467     @mock.patch(SSH_HELPER)
468     def test_wait_for_instantiate_panic(self, ssh, *args):
469         mock_ssh(ssh, exec_result=(1, "", ""))
470         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
471         prox_approx_vnf._vnf_process = mock.MagicMock(**{"is_alive.return_value": True})
472         prox_approx_vnf._run_prox = mock.Mock(return_value=0)
473         prox_approx_vnf.WAIT_TIME = 0
474         prox_approx_vnf.q_out.put("PANIC")
475         with self.assertRaises(RuntimeError):
476             prox_approx_vnf.wait_for_instantiate()
477
478     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket')
479     @mock.patch(SSH_HELPER)
480     def test_terminate(self, ssh, *args):
481         mock_ssh(ssh)
482         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
483         prox_approx_vnf._vnf_process = mock.MagicMock()
484         prox_approx_vnf._vnf_process.terminate = mock.Mock()
485         prox_approx_vnf.ssh_helper = mock.MagicMock()
486         prox_approx_vnf.setup_helper = mock.Mock()
487         prox_approx_vnf.resource_helper = mock.MagicMock()
488
489         self.assertIsNone(prox_approx_vnf.terminate())
490
491     @mock.patch(SSH_HELPER)
492     def test__vnf_up_post(self, ssh, *args):
493         mock_ssh(ssh)
494         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
495         prox_approx_vnf.resource_helper = resource_helper = mock.Mock()
496
497         prox_approx_vnf._vnf_up_post()
498         resource_helper.up_post.assert_called_once()
499
500     @mock.patch(SSH_HELPER)
501     def test_vnf_execute_oserror(self, ssh, *args):
502         mock_ssh(ssh)
503         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id')
504         prox_approx_vnf.resource_helper = resource_helper = mock.Mock()
505
506         resource_helper.execute.side_effect = OSError(errno.EPIPE, "")
507         prox_approx_vnf.vnf_execute("", _ignore_errors=True)
508
509         resource_helper.execute.side_effect = OSError(errno.ESHUTDOWN, "")
510         prox_approx_vnf.vnf_execute("", _ignore_errors=True)
511
512         resource_helper.execute.side_effect = OSError(errno.EADDRINUSE, "")
513         with self.assertRaises(OSError):
514             prox_approx_vnf.vnf_execute("", _ignore_errors=True)