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