Merge "utils: create TASK_LOG_DIR if it doesn't exist"
[yardstick.git] / tests / unit / network_services / vnf_generic / vnf / test_tg_prox.py
1 # Copyright (c) 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 from __future__ import absolute_import
17 import unittest
18 import mock
19
20 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
21
22
23 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
24 NAME = 'vnf__1'
25
26
27 STL_MOCKS = {
28     'stl': mock.MagicMock(),
29     'stl.trex_stl_lib': mock.MagicMock(),
30     'stl.trex_stl_lib.base64': mock.MagicMock(),
31     'stl.trex_stl_lib.binascii': mock.MagicMock(),
32     'stl.trex_stl_lib.collections': mock.MagicMock(),
33     'stl.trex_stl_lib.copy': mock.MagicMock(),
34     'stl.trex_stl_lib.datetime': mock.MagicMock(),
35     'stl.trex_stl_lib.functools': mock.MagicMock(),
36     'stl.trex_stl_lib.imp': mock.MagicMock(),
37     'stl.trex_stl_lib.inspect': mock.MagicMock(),
38     'stl.trex_stl_lib.json': mock.MagicMock(),
39     'stl.trex_stl_lib.linecache': mock.MagicMock(),
40     'stl.trex_stl_lib.math': mock.MagicMock(),
41     'stl.trex_stl_lib.os': mock.MagicMock(),
42     'stl.trex_stl_lib.platform': mock.MagicMock(),
43     'stl.trex_stl_lib.pprint': mock.MagicMock(),
44     'stl.trex_stl_lib.random': mock.MagicMock(),
45     'stl.trex_stl_lib.re': mock.MagicMock(),
46     'stl.trex_stl_lib.scapy': mock.MagicMock(),
47     'stl.trex_stl_lib.socket': mock.MagicMock(),
48     'stl.trex_stl_lib.string': mock.MagicMock(),
49     'stl.trex_stl_lib.struct': mock.MagicMock(),
50     'stl.trex_stl_lib.sys': mock.MagicMock(),
51     'stl.trex_stl_lib.threading': mock.MagicMock(),
52     'stl.trex_stl_lib.time': mock.MagicMock(),
53     'stl.trex_stl_lib.traceback': mock.MagicMock(),
54     'stl.trex_stl_lib.trex_stl_async_client': mock.MagicMock(),
55     'stl.trex_stl_lib.trex_stl_client': mock.MagicMock(),
56     'stl.trex_stl_lib.trex_stl_exceptions': mock.MagicMock(),
57     'stl.trex_stl_lib.trex_stl_ext': mock.MagicMock(),
58     'stl.trex_stl_lib.trex_stl_jsonrpc_client': mock.MagicMock(),
59     'stl.trex_stl_lib.trex_stl_packet_builder_interface': mock.MagicMock(),
60     'stl.trex_stl_lib.trex_stl_packet_builder_scapy': mock.MagicMock(),
61     'stl.trex_stl_lib.trex_stl_port': mock.MagicMock(),
62     'stl.trex_stl_lib.trex_stl_stats': mock.MagicMock(),
63     'stl.trex_stl_lib.trex_stl_streams': mock.MagicMock(),
64     'stl.trex_stl_lib.trex_stl_types': mock.MagicMock(),
65     'stl.trex_stl_lib.types': mock.MagicMock(),
66     'stl.trex_stl_lib.utils': mock.MagicMock(),
67     'stl.trex_stl_lib.utils.argparse': mock.MagicMock(),
68     'stl.trex_stl_lib.utils.collections': mock.MagicMock(),
69     'stl.trex_stl_lib.utils.common': mock.MagicMock(),
70     'stl.trex_stl_lib.utils.json': mock.MagicMock(),
71     'stl.trex_stl_lib.utils.os': mock.MagicMock(),
72     'stl.trex_stl_lib.utils.parsing_opts': mock.MagicMock(),
73     'stl.trex_stl_lib.utils.pwd': mock.MagicMock(),
74     'stl.trex_stl_lib.utils.random': mock.MagicMock(),
75     'stl.trex_stl_lib.utils.re': mock.MagicMock(),
76     'stl.trex_stl_lib.utils.string': mock.MagicMock(),
77     'stl.trex_stl_lib.utils.sys': mock.MagicMock(),
78     'stl.trex_stl_lib.utils.text_opts': mock.MagicMock(),
79     'stl.trex_stl_lib.utils.text_tables': mock.MagicMock(),
80     'stl.trex_stl_lib.utils.texttable': mock.MagicMock(),
81     'stl.trex_stl_lib.warnings': mock.MagicMock(),
82     'stl.trex_stl_lib.yaml': mock.MagicMock(),
83     'stl.trex_stl_lib.zlib': mock.MagicMock(),
84     'stl.trex_stl_lib.zmq': mock.MagicMock(),
85 }
86
87 STLClient = mock.MagicMock()
88 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
89 stl_patch.start()
90
91 if stl_patch:
92     from yardstick.network_services.vnf_generic.vnf.tg_prox import ProxTrafficGen
93     from yardstick.network_services.traffic_profile.base import TrafficProfile
94
95
96 @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
97 class TestProxTrafficGen(unittest.TestCase):
98     VNFD0 = {
99         'short-name': 'ProxVnf',
100         'vdu': [
101             {
102                 'routing_table': [
103                     {
104                         'network': '152.16.100.20',
105                         'netmask': '255.255.255.0',
106                         'gateway': '152.16.100.20',
107                         'if': 'xe0',
108                     },
109                     {
110                         'network': '152.16.40.20',
111                         'netmask': '255.255.255.0',
112                         'gateway': '152.16.40.20',
113                         'if': 'xe1',
114                     },
115                 ],
116                 'description': 'PROX approximation using DPDK',
117                 'name': 'proxvnf-baremetal',
118                 'nd_route_tbl': [
119                     {
120                         'network': '0064:ff9b:0:0:0:0:9810:6414',
121                         'netmask': '112',
122                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
123                         'if': 'xe0',
124                     },
125                     {
126                         'network': '0064:ff9b:0:0:0:0:9810:2814',
127                         'netmask': '112',
128                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
129                         'if': 'xe1',
130                     },
131                 ],
132                 'id': 'proxvnf-baremetal',
133                 'external-interface': [
134                     {
135                         'virtual-interface': {
136                             'dst_mac': '00:00:00:00:00:04',
137                             'vpci': '0000:05:00.0',
138                             'local_ip': '152.16.100.19',
139                             'type': 'PCI-PASSTHROUGH',
140                             'vld_id': '',
141                             'netmask': '255.255.255.0',
142                             'dpdk_port_num': '0',
143                             'bandwidth': '10 Gbps',
144                             'driver': "i40e",
145                             'dst_ip': '152.16.100.20',
146                             'local_iface_name': 'xe0',
147                             'local_mac': '00:00:00:00:00:02',
148                         },
149                         'vnfd-connection-point-ref': 'xe0',
150                         'name': 'xe0',
151                     },
152                     {
153                         'virtual-interface': {
154                             'dst_mac': '00:00:00:00:00:03',
155                             'vpci': '0000:05:00.1',
156                             'local_ip': '152.16.40.19',
157                             'type': 'PCI-PASSTHROUGH',
158                             'vld_id': '',
159                             'driver': "i40e",
160                             'netmask': '255.255.255.0',
161                             'dpdk_port_num': '1',
162                             'bandwidth': '10 Gbps',
163                             'dst_ip': '152.16.40.20',
164                             'local_iface_name': 'xe1',
165                             'local_mac': '00:00:00:00:00:01',
166                         },
167                         'vnfd-connection-point-ref': 'xe1',
168                         'name': 'xe1',
169                     },
170                 ],
171             },
172         ],
173         'description': 'PROX approximation using DPDK',
174         'mgmt-interface': {
175             'vdu-id': 'proxvnf-baremetal',
176             'host': '1.2.1.1',
177             'password': 'r00t',
178             'user': 'root',
179             'ip': '1.2.1.1',
180         },
181         'benchmark': {
182             'kpi': [
183                 'packets_in',
184                 'packets_fwd',
185                 'packets_dropped',
186             ],
187         },
188         'connection-point': [
189             {
190                 'type': 'VPORT',
191                 'name': 'xe0',
192             },
193             {
194                 'type': 'VPORT',
195                 'name': 'xe1',
196             },
197         ],
198         'id': 'ProxApproxVnf',
199         'name': 'ProxVnf',
200     }
201
202     VNFD = {
203         'vnfd:vnfd-catalog': {
204             'vnfd': [
205                 VNFD0,
206             ],
207         },
208     }
209
210     SCENARIO_CFG = {
211         'task_path': "",
212         'nodes': {
213             'tg__1': 'trafficgen_1.yardstick',
214             'vnf__1': 'vnf.yardstick'},
215         'runner': {
216             'duration': 600, 'type': 'Duration'},
217         'topology': 'prox-tg-topology-2.yaml',
218         'traffic_profile': '../../traffic_profiles/prox_binsearch.yaml',
219         'type': 'NSPerf',
220         'options': {
221             'tg__1': {'prox_args': {'-e': '',
222                                     '-t': ''},
223                       'prox_config': 'configs/l3-gen-2.cfg',
224                       'prox_path':
225                           '/root/dppd-PROX-v035/build/prox'},
226             'vnf__1': {
227                 'prox_args': {'-t': ''},
228                 'prox_config': 'configs/l3-swap-2.cfg',
229                 'prox_path': '/root/dppd-PROX-v035/build/prox'}}}
230
231     CONTEXT_CFG = {
232         'nodes': {
233             'tg__2': {
234                 'member-vnf-index': '3',
235                 'role': 'TrafficGen',
236                 'name': 'trafficgen_2.yardstick',
237                 'vnfd-id-ref': 'tg__2',
238                 'ip': '1.2.1.1',
239                 'interfaces': {
240                     'xe0': {
241                         'local_iface_name': 'ens513f0',
242                         'vld_id': 'public',
243                         'netmask': '255.255.255.0',
244                         'local_ip': '152.16.40.20',
245                         'dst_mac': '00:00:00:00:00:01',
246                         'local_mac': '00:00:00:00:00:03',
247                         'dst_ip': '152.16.40.19',
248                         'driver': 'ixgbe',
249                         'vpci': '0000:02:00.0',
250                         'dpdk_port_num': 0,
251                     },
252                     'xe1': {
253                         'local_iface_name': 'ens513f1',
254                         'netmask': '255.255.255.0',
255                         'network': '202.16.100.0',
256                         'local_ip': '202.16.100.20',
257                         'local_mac': '00:1e:67:d0:60:5d',
258                         'driver': 'ixgbe',
259                         'vpci': '0000:02:00.1',
260                         'dpdk_port_num': 1,
261                     },
262                 },
263                 'password': 'r00t',
264                 'VNF model': 'l3fwd_vnf.yaml',
265                 'user': 'root',
266             },
267             'tg__1': {
268                 'member-vnf-index': '1',
269                 'role': 'TrafficGen',
270                 'name': 'trafficgen_1.yardstick',
271                 'vnfd-id-ref': 'tg__1',
272                 'ip': '1.2.1.1',
273                 'interfaces': {
274                     'xe0': {
275                         'local_iface_name': 'ens785f0',
276                         'vld_id': 'private',
277                         'netmask': '255.255.255.0',
278                         'local_ip': '152.16.100.20',
279                         'dst_mac': '00:00:00:00:00:02',
280                         'local_mac': '00:00:00:00:00:04',
281                         'dst_ip': '152.16.100.19',
282                         'driver': 'i40e',
283                         'vpci': '0000:05:00.0',
284                         'dpdk_port_num': 0,
285                     },
286                     'xe1': {
287                         'local_iface_name': 'ens785f1',
288                         'netmask': '255.255.255.0',
289                         'local_ip': '152.16.100.21',
290                         'local_mac': '00:00:00:00:00:01',
291                         'driver': 'i40e',
292                         'vpci': '0000:05:00.1',
293                         'dpdk_port_num': 1,
294                     },
295                 },
296                 'password': 'r00t',
297                 'VNF model': 'tg_rfc2544_tpl.yaml',
298                 'user': 'root',
299             },
300             'vnf__1': {
301                 'name': 'vnf.yardstick',
302                 'vnfd-id-ref': 'vnf__1',
303                 'ip': '1.2.1.1',
304                 'interfaces': {
305                     'xe0': {
306                         'local_iface_name': 'ens786f0',
307                         'vld_id': 'private',
308                         'netmask': '255.255.255.0',
309                         'local_ip': '152.16.100.19',
310                         'dst_mac': '00:00:00:00:00:04',
311                         'local_mac': '00:00:00:00:00:02',
312                         'dst_ip': '152.16.100.20',
313                         'driver': 'i40e',
314                         'vpci': '0000:05:00.0',
315                         'dpdk_port_num': 0,
316                     },
317                     'xe1': {
318                         'local_iface_name': 'ens786f1',
319                         'vld_id': 'public',
320                         'netmask': '255.255.255.0',
321                         'local_ip': '152.16.40.19',
322                         'dst_mac': '00:00:00:00:00:03',
323                         'local_mac': '00:00:00:00:00:01',
324                         'dst_ip': '152.16.40.20',
325                         'driver': 'i40e',
326                         'vpci': '0000:05:00.1',
327                         'dpdk_port_num': 1,
328                     },
329                 },
330                 'routing_table': [
331                     {
332                         'netmask': '255.255.255.0',
333                         'gateway': '152.16.100.20',
334                         'network': '152.16.100.20',
335                         'if': 'xe0',
336                     },
337                     {
338                         'netmask': '255.255.255.0',
339                         'gateway': '152.16.40.20',
340                         'network': '152.16.40.20',
341                         'if': 'xe1',
342                     },
343                 ],
344                 'member-vnf-index': '2',
345                 'host': '1.2.1.1',
346                 'role': 'vnf',
347                 'user': 'root',
348                 'nd_route_tbl': [
349                     {
350                         'netmask': '112',
351                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
352                         'network': '0064:ff9b:0:0:0:0:9810:6414',
353                         'if': 'xe0',
354                     },
355                     {
356                         'netmask': '112',
357                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
358                         'network': '0064:ff9b:0:0:0:0:9810:2814',
359                         'if': 'xe1',
360                     },
361                 ],
362                 'password': 'r00t',
363                 'VNF model': 'prox_vnf.yaml',
364             },
365         },
366     }
367
368     TRAFFIC_PROFILE = {
369         'description': 'Binary search for max no-drop throughput over given packet sizes',
370         'name': 'prox_binsearch',
371         'schema': 'nsb:traffic_profile:0.1',
372         'traffic_profile': {
373             'duration': 5,
374             'lower_bound': 0.0,
375             'packet_sizes': [64, 65],
376             'test_precision': 1.0,
377             'tolerated_loss': 0.0,
378             'traffic_type': 'ProxBinSearchProfile',
379             'upper_bound': 100.0}}
380
381     @mock.patch(SSH_HELPER)
382     def test___init__(self, ssh, mock_time):
383         mock_ssh(ssh)
384         prox_traffic_gen = ProxTrafficGen(NAME, self.VNFD0)
385         self.assertIsNone(prox_traffic_gen._tg_process)
386         self.assertIsNone(prox_traffic_gen._traffic_process)
387
388     @mock.patch(SSH_HELPER)
389     def test_collect_kpi(self, ssh, mock_time):
390         mock_ssh(ssh)
391
392         prox_traffic_gen = ProxTrafficGen(NAME, self.VNFD0)
393         prox_traffic_gen._queue = mock.MagicMock()
394         self.assertEqual({}, prox_traffic_gen.collect_kpi())
395
396     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.CpuSysCores')
397     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file')
398     @mock.patch(SSH_HELPER)
399     def test_instantiate(self, ssh, mock_find, mock_cpu_sys_cores, mock_time):
400         mock_ssh(ssh)
401
402         mock_cpu_sys_cores.get_core_socket.return_value = {'0': '01234'}
403
404         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
405         mock_traffic_profile.get_traffic_definition.return_value = "64"
406         mock_traffic_profile.params = self.TRAFFIC_PROFILE
407
408         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
409         prox_traffic_gen = ProxTrafficGen(NAME, vnfd)
410         prox_traffic_gen.ssh_helper = mock.MagicMock(
411             **{"execute.return_value": (0, "", ""), "bin_path": ""})
412         prox_traffic_gen.setup_helper._setup_resources = mock.MagicMock()
413         prox_traffic_gen.setup_hugepages = mock.MagicMock()
414         prox_traffic_gen.generate_prox_config_file = mock.MagicMock()
415         prox_traffic_gen.upload_prox_config = mock.MagicMock()
416         prox_traffic_gen.setup_helper._find_used_drivers = mock.MagicMock()
417         prox_traffic_gen.setup_helper.used_drivers = {}
418         prox_traffic_gen.setup_helper.bound_pci = []
419         prox_traffic_gen._start_server = mock.Mock(return_value=0)
420         prox_traffic_gen._tg_process = mock.MagicMock()
421         prox_traffic_gen._tg_process.start = mock.Mock()
422         prox_traffic_gen._tg_process.exitcode = 0
423         prox_traffic_gen._tg_process._is_alive = mock.Mock(return_value=1)
424         prox_traffic_gen.ssh_helper = mock.MagicMock()
425         prox_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
426         scenario_cfg = {
427             'task_path': '',
428             'options': {'tg__1': {'prox_args': {'-e': '',
429                                                 '-t': ''},
430                                       'prox_config': 'configs/l3-gen-2.cfg',
431                                       'prox_path': '/root/dppd-PROX-v035/build/prox'},
432                             'vnf__1': {'prox_args': {'-t': ''},
433                                        'prox_config': 'configs/l3-swap-2.cfg',
434                                        'prox_path': '/root/dppd-PROX-v035/build/prox'}
435                             }
436         }
437         prox_traffic_gen.instantiate(scenario_cfg, {})
438
439     @mock.patch(SSH_HELPER)
440     def test__traffic_runner(self, ssh, mock_time):
441         mock_ssh(ssh)
442
443         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
444         mock_traffic_profile.get_traffic_definition.return_value = "64"
445         mock_traffic_profile.execute.return_value = "64"
446         mock_traffic_profile.params = self.TRAFFIC_PROFILE
447
448         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
449         sut = ProxTrafficGen(NAME, vnfd)
450         sut.prox_config_dict = {}
451         sut._get_socket = mock.MagicMock()
452         sut.ssh_helper = mock.Mock()
453         sut.ssh_helper.run = mock.Mock()
454         sut._vpci_ascending = ["0000:05:00.0", "0000:05:00.1"]
455         sut._connect_client = mock.Mock(autospec=STLClient)
456         sut._connect_client.get_stats = mock.Mock(return_value="0")
457         sut._traffic_runner(mock_traffic_profile)
458
459     @mock.patch(SSH_HELPER)
460     def test_scale(self, ssh, mock_time):
461         mock_ssh(ssh, exec_result=(1, "", ""))
462         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
463         prox_traffic_gen = ProxTrafficGen(NAME, vnfd)
464         with self.assertRaises(NotImplementedError):
465             prox_traffic_gen.scale('')
466
467     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket')
468     @mock.patch(SSH_HELPER)
469     def test_listen_traffic(self, ssh, mock_socket, mock_time):
470         mock_ssh(ssh)
471         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
472         prox_traffic_gen = ProxTrafficGen(NAME, vnfd)
473         self.assertIsNone(prox_traffic_gen.listen_traffic(mock.Mock()))
474
475     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket')
476     @mock.patch(SSH_HELPER)
477     def test_terminate(self, ssh, mock_socket, mock_time):
478         mock_ssh(ssh)
479         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
480         prox_traffic_gen = ProxTrafficGen(NAME, vnfd)
481         prox_traffic_gen._terminated = mock.MagicMock()
482         prox_traffic_gen._traffic_process = mock.MagicMock()
483         prox_traffic_gen._traffic_process.terminate = mock.Mock()
484         prox_traffic_gen.ssh_helper = mock.MagicMock()
485         prox_traffic_gen.setup_helper = mock.MagicMock()
486         prox_traffic_gen.resource_helper = mock.MagicMock()
487         self.assertEqual(None, prox_traffic_gen.terminate())