Create Dockerfile to create a yardstick-image of docker
[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)
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)
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             'collect_stats': {'core': {}}
339         }
340         result = prox_approx_vnf.collect_kpi()
341         self.assertEqual(result, expected)
342
343     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
344     @mock.patch(SSH_HELPER)
345     def test_collect_kpi(self, ssh, *args):
346         mock_ssh(ssh)
347
348         resource_helper = mock.MagicMock()
349         resource_helper.execute.return_value = [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5],
350                                                 [2, 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 5]]
351         resource_helper.collect_collectd_kpi.return_value = {'core': {'result': 234}}
352
353         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
354         prox_approx_vnf.scenario_helper.scenario_cfg = {
355             'nodes': {prox_approx_vnf.name: "mock"}
356         }
357         prox_approx_vnf.resource_helper = resource_helper
358
359         expected = {
360             'physical_node': 'mock_node',
361             'packets_in': 4,
362             'packets_dropped': 4,
363             'packets_fwd': 8,
364             'collect_stats': {'core': {'result': 234}},
365         }
366         result = prox_approx_vnf.collect_kpi()
367         self.assertEqual(result['packets_in'], expected['packets_in'])
368         self.assertEqual(result['packets_dropped'], expected['packets_dropped'])
369         self.assertEqual(result['packets_fwd'], expected['packets_fwd'])
370         self.assertNotEqual(result['packets_fwd'], 0)
371         self.assertNotEqual(result['packets_fwd'], 0)
372
373     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
374     @mock.patch(SSH_HELPER)
375     def test_collect_kpi_error(self, ssh, *args):
376         mock_ssh(ssh)
377
378         resource_helper = mock.MagicMock()
379         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, deepcopy(self.VNFD0))
380         prox_approx_vnf.scenario_helper.scenario_cfg = {
381             'nodes': {prox_approx_vnf.name: "mock"}
382         }
383         prox_approx_vnf.resource_helper = resource_helper
384         prox_approx_vnf.vnfd_helper['vdu'][0]['external-interface'] = []
385         prox_approx_vnf.vnfd_helper.port_pairs.interfaces = []
386
387         with self.assertRaises(RuntimeError):
388             prox_approx_vnf.collect_kpi()
389
390     def _get_file_abspath(self, filename, *args):
391         curr_path = os.path.dirname(os.path.abspath(__file__))
392         file_path = os.path.join(curr_path, filename)
393         return file_path
394
395     @mock.patch('yardstick.common.utils.open', create=True)
396     @mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.open', create=True)
397     @mock.patch('yardstick.network_services.helpers.iniparser.open', create=True)
398     @mock.patch(SSH_HELPER)
399     def test_run_prox(self, ssh, *_):
400         mock_ssh(ssh)
401
402         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
403         prox_approx_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG
404         prox_approx_vnf.ssh_helper.join_bin_path.return_value = '/tool_path12/tool_file34'
405         prox_approx_vnf.setup_helper.remote_path = 'configs/file56.cfg'
406
407         expected = "sudo bash -c 'cd /tool_path12; " \
408                    "/tool_path12/tool_file34 -o cli -t  -f /tmp/l3-swap-2.cfg '"
409
410         prox_approx_vnf._run()
411         result = prox_approx_vnf.ssh_helper.run.call_args[0][0]
412         self.assertEqual(result, expected)
413
414     @mock.patch(SSH_HELPER)
415     def bad_test_instantiate(self, *args):
416         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
417         prox_approx_vnf.scenario_helper = mock.MagicMock()
418         prox_approx_vnf.setup_helper = mock.MagicMock()
419         # we can't mock super
420         prox_approx_vnf.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG)
421         prox_approx_vnf.setup_helper.build_config.assert_called_once()
422
423     @mock.patch(SSH_HELPER)
424     def test_wait_for_instantiate_panic(self, ssh, *args):
425         mock_ssh(ssh, exec_result=(1, "", ""))
426         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
427         prox_approx_vnf._vnf_process = mock.MagicMock(**{"is_alive.return_value": True})
428         prox_approx_vnf._run_prox = mock.Mock(return_value=0)
429         prox_approx_vnf.WAIT_TIME = 0
430         prox_approx_vnf.q_out.put("PANIC")
431         with self.assertRaises(RuntimeError):
432             prox_approx_vnf.wait_for_instantiate()
433
434     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket')
435     @mock.patch(SSH_HELPER)
436     def test_terminate(self, ssh, *args):
437         mock_ssh(ssh)
438         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
439         prox_approx_vnf._vnf_process = mock.MagicMock()
440         prox_approx_vnf._vnf_process.terminate = mock.Mock()
441         prox_approx_vnf.ssh_helper = mock.MagicMock()
442         prox_approx_vnf.setup_helper = mock.Mock()
443         prox_approx_vnf.resource_helper = mock.MagicMock()
444
445         self.assertIsNone(prox_approx_vnf.terminate())
446
447     @mock.patch(SSH_HELPER)
448     def test__vnf_up_post(self, ssh, *args):
449         mock_ssh(ssh)
450         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
451         prox_approx_vnf.resource_helper = resource_helper = mock.Mock()
452
453         prox_approx_vnf._vnf_up_post()
454         resource_helper.up_post.assert_called_once()
455
456     @mock.patch(SSH_HELPER)
457     def test_vnf_execute_oserror(self, ssh, *args):
458         mock_ssh(ssh)
459         prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0)
460         prox_approx_vnf.resource_helper = resource_helper = mock.Mock()
461
462         resource_helper.execute.side_effect = OSError(errno.EPIPE, "")
463         prox_approx_vnf.vnf_execute("", _ignore_errors=True)
464
465         resource_helper.execute.side_effect = OSError(errno.ESHUTDOWN, "")
466         prox_approx_vnf.vnf_execute("", _ignore_errors=True)
467
468         resource_helper.execute.side_effect = OSError(errno.EADDRINUSE, "")
469         with self.assertRaises(OSError):
470             prox_approx_vnf.vnf_execute("", _ignore_errors=True)