Merge "Prohibit the importation of a list of libraries"
[yardstick.git] / tests / unit / network_services / vnf_generic / vnf / test_tg_trex.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 copy
17 import mock
18
19 import unittest
20
21 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
22 from tests.unit import STL_MOCKS
23
24
25 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
26 NAME = 'vnf_1'
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.tg_trex import \
34         TrexTrafficGen, TrexResourceHelper
35     from yardstick.network_services.traffic_profile.base import TrafficProfile
36
37
38 class TestTrexTrafficGen(unittest.TestCase):
39     VNFD = {'vnfd:vnfd-catalog':
40                 {'vnfd':
41                      [{'short-name': 'VpeVnf',
42                        'vdu':
43                            [{'routing_table':
44                                  [{'network': '152.16.100.20',
45                                    'netmask': '255.255.255.0',
46                                    'gateway': '152.16.100.20',
47                                    'if': 'xe0'},
48                                   {'network': '152.16.40.20',
49                                    'netmask': '255.255.255.0',
50                                    'gateway': '152.16.40.20',
51                                    'if': 'xe1'}],
52                              'description': 'VPE approximation using DPDK',
53                              'name': 'vpevnf-baremetal',
54                              'nd_route_tbl':
55                                  [{'network': '0064:ff9b:0:0:0:0:9810:6414',
56                                    'netmask': '112',
57                                    'gateway': '0064:ff9b:0:0:0:0:9810:6414',
58                                    'if': 'xe0'},
59                                   {'network': '0064:ff9b:0:0:0:0:9810:2814',
60                                    'netmask': '112',
61                                    'gateway': '0064:ff9b:0:0:0:0:9810:2814',
62                                    'if': 'xe1'}],
63                              'id': 'vpevnf-baremetal',
64                              'external-interface':
65                                  [{'virtual-interface':
66                                        {'dst_mac': '00:00:00:00:00:04',
67                                         'vpci': '0000:05:00.0',
68                                         'local_ip': '152.16.100.19',
69                                         'type': 'PCI-PASSTHROUGH',
70                                         'netmask': '255.255.255.0',
71                                         'dpdk_port_num': 0,
72                                         'bandwidth': '10 Gbps',
73                                         'driver': "i40e",
74                                         'dst_ip': '152.16.100.20',
75                                         'local_iface_name': 'xe0',
76                                         'vld_id': 'downlink_0',
77                                         'ifname': 'xe0',
78                                         'local_mac': '00:00:00:00:00:02'},
79                                    'vnfd-connection-point-ref': 'xe0',
80                                    'name': 'xe0'},
81                                   {'virtual-interface':
82                                        {'dst_mac': '00:00:00:00:00:03',
83                                         'vpci': '0000:05:00.1',
84                                         'local_ip': '152.16.40.19',
85                                         'type': 'PCI-PASSTHROUGH',
86                                         'driver': "i40e",
87                                         'netmask': '255.255.255.0',
88                                         'dpdk_port_num': 1,
89                                         'bandwidth': '10 Gbps',
90                                         'dst_ip': '152.16.40.20',
91                                         'local_iface_name': 'xe1',
92                                         'vld_id': 'uplink_0',
93                                         'ifname': 'xe1',
94                                         'local_mac': '00:00:00:00:00:01'},
95                                    'vnfd-connection-point-ref': 'xe1',
96                                    'name': 'xe1'}]}],
97                        'description': 'Vpe approximation using DPDK',
98                        'mgmt-interface':
99                            {'vdu-id': 'vpevnf-baremetal',
100                             'host': '1.1.1.1',
101                             'password': 'r00t',
102                             'user': 'root',
103                             'ip': '1.1.1.1'},
104                        'benchmark':
105                            {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']},
106                        'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
107                                             {'type': 'VPORT', 'name': 'xe1'}],
108                        'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}}
109
110     TRAFFIC_PROFILE = {
111         "schema": "isb:traffic_profile:0.1",
112         "name": "fixed",
113         "description": "Fixed traffic profile to run UDP traffic",
114         "traffic_profile": {
115             "traffic_type": "FixedTraffic",
116             "frame_rate": 100,  # pps
117             "flow_number": 10,
118             "frame_size": 64
119         },
120     }
121
122     SCENARIO_CFG = {
123         "options": {
124             "packetsize": 64,
125             "traffic_type": 4,
126             "rfc2544": {
127                 "allowed_drop_rate": "0.8 - 1",
128             },
129             "vnf__1": {
130                 "rules": "acl_1rule.yaml",
131                 "vnf_config": {
132                     "lb_config": "SW",
133                     "lb_count": 1,
134                     "worker_config": "1C/1T",
135                     "worker_threads": 1,
136                 }
137             }
138         },
139         "task_id": "a70bdf4a-8e67-47a3-9dc1-273c14506eb7",
140         "tc": "tc_ipv4_1Mflow_64B_packetsize",
141         "runner": {
142             "object": "NetworkServiceTestCase",
143             "interval": 35,
144             "output_filename": "/tmp/yardstick.out",
145             "runner_id": 74476, "duration": 400,
146             "type": "Duration"
147         },
148         "traffic_profile": "ipv4_throughput_acl.yaml",
149         "traffic_options": {
150             "flow": "ipv4_Packets_acl.yaml",
151             "imix": "imix_voice.yaml"
152         },
153         "type": "ISB",
154         "nodes": {
155             "tg__2": "trafficgen_2.yardstick",
156             "tg__1": "trafficgen_1.yardstick",
157             "vnf__1": "vnf.yardstick"
158         },
159         "topology": "udpreplay-tg-topology-baremetal.yaml"
160     }
161
162     CONTEXT_CFG = {
163         "nodes": {
164             "vnf__1": {
165                 "vnfd-id-ref": "vnf__1",
166                 "ip": "1.2.1.1",
167                 "interfaces": {
168                     "xe0": {
169                         "local_iface_name": "ens786f0",
170                         "vld_id": TrafficProfile.UPLINK,
171                         "netmask": "255.255.255.0",
172                         "vpci": "0000:05:00.0",
173                         "local_ip": "152.16.100.19",
174                         "driver": "i40e",
175                         "dst_ip": "152.16.100.20",
176                         "local_mac": "00:00:00:00:00:02",
177                         "dst_mac": "00:00:00:00:00:04",
178                         "dpdk_port_num": 0
179                     },
180                     "xe1": {
181                         "local_iface_name": "ens786f1",
182                         "vld_id": TrafficProfile.DOWNLINK,
183                         "netmask": "255.255.255.0",
184                         "vpci": "0000:05:00.1",
185                         "local_ip": "152.16.40.19",
186                         "driver": "i40e",
187                         "dst_ip": "152.16.40.20",
188                         "local_mac": "00:00:00:00:00:01",
189                         "dst_mac": "00:00:00:00:00:03",
190                         "dpdk_port_num": 1
191                     }
192                 },
193                 "host": "1.2.1.1",
194                 "user": "root",
195                 "nd_route_tbl": [
196                     {
197                         "netmask": "112",
198                         "if": "xe0",
199                         "gateway": "0064:ff9b:0:0:0:0:9810:6414",
200                         "network": "0064:ff9b:0:0:0:0:9810:6414"
201                     },
202                     {
203                         "netmask": "112",
204                         "if": "xe1",
205                         "gateway": "0064:ff9b:0:0:0:0:9810:2814",
206                         "network": "0064:ff9b:0:0:0:0:9810:2814"
207                     }
208                 ],
209                 "password": "r00t",
210                 "VNF model": "udp_replay.yaml",
211                 "name": "vnf.yardstick",
212                 "member-vnf-index": "2",
213                 "routing_table": [
214                     {
215                         "netmask": "255.255.255.0",
216                         "if": "xe0",
217                         "gateway": "152.16.100.20",
218                         "network": "152.16.100.20"
219                     },
220                     {
221                         "netmask": "255.255.255.0",
222                         "if": "xe1",
223                         "gateway": "152.16.40.20",
224                         "network": "152.16.40.20"
225                     }
226                 ],
227                 "role": "vnf"
228             },
229             "trafficgen_2.yardstick": {
230                 "member-vnf-index": "3",
231                 "role": "TrafficGen",
232                 "name": "trafficgen_2.yardstick",
233                 "vnfd-id-ref": "tg__2",
234                 "ip": "1.2.1.1",
235                 "interfaces": {
236                     "xe0": {
237                         "local_iface_name": "ens513f0",
238                         "vld_id": TrafficProfile.DOWNLINK,
239                         "netmask": "255.255.255.0",
240                         "vpci": "0000:02:00.0",
241                         "local_ip": "152.16.40.20",
242                         "driver": "ixgbe",
243                         "dst_ip": "152.16.40.19",
244                         "local_mac": "00:00:00:00:00:03",
245                         "dst_mac": "00:00:00:00:00:01",
246                         "dpdk_port_num": 0
247                     },
248                     "xe1": {
249                         "local_iface_name": "ens513f1",
250                         "netmask": "255.255.255.0",
251                         "network": "202.16.100.0",
252                         "local_ip": "202.16.100.20",
253                         "driver": "ixgbe",
254                         "local_mac": "00:1e:67:d0:60:5d",
255                         "vpci": "0000:02:00.1",
256                         "dpdk_port_num": 1
257                     }
258                 },
259                 "password": "r00t",
260                 "VNF model": "l3fwd_vnf.yaml",
261                 "user": "root"
262             },
263             "trafficgen_1.yardstick": {
264                 "member-vnf-index": "1",
265                 "role": "TrafficGen",
266                 "name": "trafficgen_1.yardstick",
267                 "vnfd-id-ref": "tg__1",
268                 "ip": "1.2.1.1",
269                 "interfaces": {
270                     "xe0": {
271                         "local_iface_name": "ens785f0",
272                         "vld_id": TrafficProfile.UPLINK,
273                         "netmask": "255.255.255.0",
274                         "vpci": "0000:05:00.0",
275                         "local_ip": "152.16.100.20",
276                         "driver": "i40e",
277                         "dst_ip": "152.16.100.19",
278                         "local_mac": "00:00:00:00:00:04",
279                         "dst_mac": "00:00:00:00:00:02",
280                         "dpdk_port_num": 0
281                     },
282                     "xe1": {
283                         "local_ip": "152.16.100.21",
284                         "driver": "i40e",
285                         "vpci": "0000:05:00.1",
286                         "dpdk_port_num": 1,
287                         "local_iface_name": "ens785f1",
288                         "netmask": "255.255.255.0",
289                         "local_mac": "00:00:00:00:00:01"
290                     }
291                 },
292                 "password": "r00t",
293                 "VNF model": "tg_rfc2544_tpl.yaml",
294                 "user": "root"
295             }
296         }
297     }
298
299     @mock.patch(SSH_HELPER)
300     def test___init__(self, ssh):
301         mock_ssh(ssh)
302         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
303         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
304         self.assertIsInstance(trex_traffic_gen.resource_helper, TrexResourceHelper)
305
306     @mock.patch(SSH_HELPER)
307     def test_collect_kpi(self, ssh):
308         mock_ssh(ssh)
309         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
310         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
311         trex_traffic_gen.resource_helper._queue.put({})
312         result = trex_traffic_gen.collect_kpi()
313         self.assertEqual({}, result)
314
315     @mock.patch(SSH_HELPER)
316     def test_listen_traffic(self, ssh):
317         mock_ssh(ssh)
318         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
319         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
320         self.assertIsNone(trex_traffic_gen.listen_traffic({}))
321
322     @mock.patch(SSH_HELPER)
323     def test_instantiate(self, ssh):
324         mock_ssh(ssh)
325
326         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
327         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
328         trex_traffic_gen._start_server = mock.Mock(return_value=0)
329         trex_traffic_gen._tg_process = mock.MagicMock()
330         trex_traffic_gen._tg_process.start = mock.Mock()
331         trex_traffic_gen._tg_process.exitcode = 0
332         trex_traffic_gen._tg_process._is_alive = mock.Mock(return_value=1)
333         trex_traffic_gen.ssh_helper = mock.MagicMock()
334         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
335         trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
336
337         self.assertIsNone(trex_traffic_gen.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG))
338
339     @mock.patch(SSH_HELPER)
340     def test_instantiate_error(self, ssh):
341         mock_ssh(ssh, exec_result=(1, "", ""))
342
343         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
344         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
345         trex_traffic_gen._start_server = mock.Mock(return_value=0)
346         trex_traffic_gen._tg_process = mock.MagicMock()
347         trex_traffic_gen._tg_process.start = mock.Mock()
348         trex_traffic_gen._tg_process._is_alive = mock.Mock(return_value=0)
349         trex_traffic_gen.ssh_helper = mock.MagicMock()
350         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
351         trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
352         self.assertIsNone(trex_traffic_gen.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG))
353
354     @mock.patch(SSH_HELPER)
355     def test__start_server(self, ssh):
356         mock_ssh(ssh)
357         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
358         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
359         trex_traffic_gen.ssh_helper = mock.MagicMock()
360         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
361         trex_traffic_gen.scenario_helper.scenario_cfg = {}
362         self.assertIsNone(trex_traffic_gen._start_server())
363
364     @mock.patch(SSH_HELPER)
365     def test__start_server_multiple_queues(self, ssh):
366         mock_ssh(ssh)
367         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
368         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
369         trex_traffic_gen.ssh_helper = mock.MagicMock()
370         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
371         trex_traffic_gen.scenario_helper.scenario_cfg = {"options": {NAME: {"queues_per_port": 2}}}
372         self.assertIsNone(trex_traffic_gen._start_server())
373
374     @mock.patch(SSH_HELPER)
375     def test__traffic_runner(self, ssh):
376         mock_ssh(ssh)
377
378         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
379         mock_traffic_profile.get_traffic_definition.return_value = "64"
380         mock_traffic_profile.execute_traffic.return_value = "64"
381         mock_traffic_profile.params = self.TRAFFIC_PROFILE
382
383         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
384         self.sut = TrexTrafficGen(NAME, vnfd)
385         self.sut.ssh_helper = mock.Mock()
386         self.sut.ssh_helper.run = mock.Mock()
387         self.sut._connect_client = mock.Mock(autospec=STLClient)
388         self.sut._connect_client.get_stats = mock.Mock(return_value="0")
389         self.sut.resource_helper.RUN_DURATION = 0
390         self.sut.resource_helper.QUEUE_WAIT_TIME = 0
391         # must generate cfg before we can run traffic so Trex port mapping is created
392         self.sut.resource_helper.generate_cfg()
393         self.sut._traffic_runner(mock_traffic_profile)
394
395     @mock.patch(SSH_HELPER)
396     def test__generate_trex_cfg(self, ssh):
397         mock_ssh(ssh)
398         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
399         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
400         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
401         self.assertIsNone(trex_traffic_gen.resource_helper.generate_cfg())
402
403     @mock.patch(SSH_HELPER)
404     def test_build_ports_reversed_pci_ordering(self, ssh):
405         mock_ssh(ssh)
406         vnfd = copy.deepcopy(self.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
407         vnfd['vdu'][0]['external-interface'] = [
408             {'virtual-interface':
409                  {'dst_mac': '00:00:00:00:00:04',
410                   'vpci': '0000:05:00.0',
411                   'local_ip': '152.16.100.19',
412                   'type': 'PCI-PASSTHROUGH',
413                   'netmask': '255.255.255.0',
414                   'dpdk_port_num': 2,
415                   'bandwidth': '10 Gbps',
416                   'driver': "i40e",
417                   'dst_ip': '152.16.100.20',
418                   'local_iface_name': 'xe0',
419                   'vld_id': 'downlink_0',
420                   'ifname': 'xe0',
421                   'local_mac': '00:00:00:00:00:02'},
422              'vnfd-connection-point-ref': 'xe0',
423              'name': 'xe0'},
424             {'virtual-interface':
425                  {'dst_mac': '00:00:00:00:00:03',
426                   'vpci': '0000:04:00.0',
427                   'local_ip': '152.16.40.19',
428                   'type': 'PCI-PASSTHROUGH',
429                   'driver': "i40e",
430                   'netmask': '255.255.255.0',
431                   'dpdk_port_num': 0,
432                   'bandwidth': '10 Gbps',
433                   'dst_ip': '152.16.40.20',
434                   'local_iface_name': 'xe1',
435                   'vld_id': 'uplink_0',
436                   'ifname': 'xe1',
437                   'local_mac': '00:00:00:00:00:01'},
438              'vnfd-connection-point-ref': 'xe1',
439              'name': 'xe1'}]
440         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
441         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
442         trex_traffic_gen.resource_helper.generate_cfg()
443         trex_traffic_gen.resource_helper._build_ports()
444         self.assertEqual(sorted(trex_traffic_gen.resource_helper.all_ports), [0, 1])
445         # there is a gap in ordering
446         self.assertEqual(dict(trex_traffic_gen.resource_helper.dpdk_to_trex_port_map),
447                          {0: 0, 2: 1})
448
449     @mock.patch(SSH_HELPER)
450     def test_run_traffic(self, ssh):
451         mock_ssh(ssh)
452
453         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
454         mock_traffic_profile.get_traffic_definition.return_value = "64"
455         mock_traffic_profile.params = self.TRAFFIC_PROFILE
456
457         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
458         self.sut = TrexTrafficGen(NAME, vnfd)
459         self.sut.ssh_helper = mock.Mock()
460         self.sut.ssh_helper.run = mock.Mock()
461         self.sut._traffic_runner = mock.Mock(return_value=0)
462         self.sut.resource_helper.client_started.value = 1
463         result = self.sut.run_traffic(mock_traffic_profile)
464         self.sut._traffic_process.terminate()
465         self.assertIsNotNone(result)
466
467     @mock.patch(SSH_HELPER)
468     def test_terminate(self, ssh):
469         mock_ssh(ssh)
470         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
471         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
472         trex_traffic_gen.ssh_helper = mock.MagicMock()
473         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
474         self.assertIsNone(trex_traffic_gen.terminate())
475
476     @mock.patch(SSH_HELPER)
477     def test__connect_client(self, ssh):
478         mock_ssh(ssh)
479         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
480         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
481         client = mock.Mock(autospec=STLClient)
482         client.connect = mock.Mock(return_value=0)
483         self.assertIsNotNone(trex_traffic_gen.resource_helper._connect(client))