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