Merge "yardstick setup ansible, including load_images"
[yardstick.git] / tests / unit / network_services / vnf_generic / vnf / test_tg_ping.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016-2017 Intel Corporation
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 from __future__ import absolute_import
19 import unittest
20 import mock
21 from multiprocessing import Queue
22
23 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
24
25 SSH_HELPER = "yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper"
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_ping import PingParser, PingTrafficGen
93     from yardstick.network_services.traffic_profile.base import TrafficProfile
94     from yardstick.network_services.vnf_generic.vnf.sample_vnf import VnfSshHelper
95
96
97 class TestPingParser(unittest.TestCase):
98     def test___init__(self):
99         q_out = Queue()
100         ping_parser = PingParser(q_out)
101         self.assertIsNotNone(ping_parser.queue)
102
103     def test_clear(self):
104         sample_out = """
105 64 bytes from 10.102.22.93: icmp_seq=3 ttl=64 time=0.296 ms
106          """
107         q_out = Queue()
108         ping_parser = PingParser(q_out)
109         ping_parser.write(sample_out)
110         ping_parser.clear()
111         self.assertEqual(True, q_out.empty())
112
113     def test_close(self):
114         q_out = Queue()
115         ping_parser = PingParser(q_out)
116         self.assertIsNone(ping_parser.close())
117
118     def test_write(self):
119         sample_out = """
120 64 bytes from 10.102.22.93: icmp_seq=3 ttl=64 time=0.296 ms
121          """
122         q_out = Queue()
123         ping_parser = PingParser(q_out)
124         ping_parser.write(sample_out)
125
126         self.assertEqual({"packets_received": 3.0, "rtt": 0.296}, q_out.get())
127
128
129 class TestPingTrafficGen(unittest.TestCase):
130
131     VNFD_0_EXT_IF_0 = {
132         'virtual-interface': {
133             'dst_mac': '00:00:00:00:00:04',
134             'vpci': '0000:05:00.0',
135             'local_ip': u'152.16.100.19',
136             'type': 'PCI-PASSTHROUGH',
137             'netmask': '255.255.255.0',
138             'dpdk_port_num': '0',
139             'bandwidth': '10 Gbps',
140             'driver': "i40e",
141             'dst_ip': u'152.16.100.20',
142             'local_iface_name': 'xe0',
143             'local_mac': '00:00:00:00:00:02',
144         },
145         'vnfd-connection-point-ref': 'xe0',
146         'name': 'xe0',
147     }
148
149     VNFD_0_EXT_IF_1 = {
150         'virtual-interface': {
151             'dst_mac': '00:00:00:00:00:03',
152             'vpci': '0000:05:00.1',
153             'local_ip': u'152.16.40.19',
154             'type': 'PCI-PASSTHROUGH',
155             'driver': "i40e",
156             'netmask': '255.255.255.0',
157             'dpdk_port_num': '1',
158             'bandwidth': '10 Gbps',
159             'dst_ip': u'152.16.40.20',
160             'local_iface_name': 'xe1',
161             'local_mac': '00:00:00:00:00:01',
162         },
163        'vnfd-connection-point-ref': 'xe1',
164        'name': 'xe1',
165     }
166
167     VNFD_0_EXT_IF_LIST = [
168         VNFD_0_EXT_IF_0,
169         VNFD_0_EXT_IF_1,
170     ]
171
172     VNFD_0 = {
173         'short-name': 'VpeVnf',
174         'vdu': [
175             {
176                 'routing_table': [
177                     {
178                         'network': u'152.16.100.20',
179                         'netmask': u'255.255.255.0',
180                         'gateway': u'152.16.100.20',
181                         'if': 'xe0',
182                     },
183                     {
184                         'network': u'152.16.40.20',
185                         'netmask': u'255.255.255.0',
186                         'gateway': u'152.16.40.20',
187                         'if': 'xe1',
188                     },
189                 ],
190                 'description': 'VPE approximation using DPDK',
191                 'name': 'vpevnf-baremetal',
192                 'nd_route_tbl': [
193                     {
194                         'network': '0064:ff9b:0:0:0:0:9810:6414',
195                         'netmask': '112',
196                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
197                         'if': 'xe0',
198                     },
199                     {
200                         'network': '0064:ff9b:0:0:0:0:9810:2814',
201                         'netmask': '112',
202                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
203                         'if': 'xe1',
204                     },
205                 ],
206                 'id': 'vpevnf-baremetal',
207                 'external-interface': VNFD_0_EXT_IF_LIST,
208             },
209         ],
210         'description': 'Vpe approximation using DPDK',
211         'mgmt-interface': {
212         'vdu-id': 'vpevnf-baremetal',
213             'host': '1.1.1.1',
214             'password': 'r00t',
215             'user': 'root',
216             'ip': '1.1.1.1',
217         },
218         'benchmark': {
219             'kpi': [
220                 'packets_in',
221                 'packets_fwd',
222                 'packets_dropped',
223             ],
224         },
225         'connection-point': [
226             {
227                 'type': 'VPORT',
228                 'name': 'xe0',
229             },
230             {
231                 'type': 'VPORT',
232                 'name': 'xe1',
233             },
234         ],
235         'id': 'VpeApproxVnf',
236         'name': 'VPEVnfSsh',
237     }
238
239     VNFD = {
240         'vnfd:vnfd-catalog': {
241             'vnfd': [
242                 VNFD_0,
243             ],
244         },
245     }
246
247     TRAFFIC_PROFILE = {
248         "schema": "isb:traffic_profile:0.1",
249         "name": "fixed",
250         "description": "Fixed traffic profile to run UDP traffic",
251         "traffic_profile": {
252             "traffic_type": "FixedTraffic",
253             "frame_rate": 100,  # pps
254             "flow_number": 10,
255             "frame_size": 64,
256         },
257     }
258
259     @mock.patch("yardstick.ssh.SSH")
260     def test___init__(self, ssh):
261         ssh.from_node.return_value.execute.return_value = 0, "success", ""
262         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
263         self.assertIsNotNone(ping_traffic_gen._queue)
264
265     @mock.patch("yardstick.ssh.SSH")
266     def test__bind_device_kernel_with_failure(self, ssh):
267         mock_ssh(ssh)
268
269         execute_result_data = [
270             (1, 'bad stdout messages', 'error messages'),
271             (0, '', ''),
272             (0, 'if_name_1', ''),
273             (0, 'if_name_2', ''),
274         ]
275         ssh.from_node.return_value.execute.side_effect = iter(execute_result_data)
276         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
277         ext_ifs = ping_traffic_gen.vnfd_helper.interfaces
278         self.assertNotEqual(ext_ifs[0]['virtual-interface']['local_iface_name'], 'if_name_1')
279         self.assertNotEqual(ext_ifs[1]['virtual-interface']['local_iface_name'], 'if_name_2')
280
281     @mock.patch("yardstick.ssh.SSH")
282     def test_collect_kpi(self, ssh):
283         mock_ssh(ssh, exec_result=(0, "success", ""))
284         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
285         ping_traffic_gen._queue = Queue()
286         ping_traffic_gen._queue.put({})
287         ping_traffic_gen.collect_kpi()
288         self.assertEqual(ping_traffic_gen._result, {})
289
290     @mock.patch(SSH_HELPER)
291     def test_instantiate(self, ssh):
292         mock_ssh(ssh, spec=VnfSshHelper, exec_result=(0, "success", ""))
293         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
294         ping_traffic_gen.setup_helper.ssh_helper = mock.MagicMock(
295             **{"execute.return_value": (0, "", "")})
296         self.assertIsInstance(ping_traffic_gen.ssh_helper, mock.Mock)
297         self.assertEqual(ping_traffic_gen._result, {})
298         self.assertIsNone(ping_traffic_gen.instantiate({}, {}))
299         self.assertIsNotNone(ping_traffic_gen._result)
300
301     @mock.patch("yardstick.ssh.SSH")
302     def test_listen_traffic(self, ssh):
303         ssh.from_node.return_value.execute.return_value = 0, "success", ""
304         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
305         self.assertIsNone(ping_traffic_gen.listen_traffic({}))
306
307     @mock.patch(SSH_HELPER)
308     def test_run_traffic_process(self, ssh):
309         mock_ssh(ssh)
310
311         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
312         mock_traffic_profile.get_traffic_definition.return_value = "64"
313         mock_traffic_profile.params = self.TRAFFIC_PROFILE
314
315         ssh.from_node.return_value.execute.return_value = 0, "success", ""
316         ssh.from_node.return_value.run.return_value = 0, "success", ""
317
318         sut = PingTrafficGen('vnf1', self.VNFD_0)
319         sut._traffic_runner(mock_traffic_profile)
320         sut.ssh_helper.run.assert_called_with(
321             "ping -s 64 152.16.100.20",
322             stdout=sut._parser, keep_stdin_open=True, pty=True)
323
324     @mock.patch("yardstick.ssh.SSH")
325     def test_scale_negative(self, ssh):
326         ssh.from_node.return_value.execute.return_value = 0, "success", ""
327         ssh.from_node.return_value.run.return_value = 0, "success", ""
328
329         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
330         ping_traffic_gen.scale()
331
332     @mock.patch("yardstick.ssh.SSH")
333     def test_terminate(self, ssh):
334         ssh.from_node.return_value.execute.return_value = 0, "success", ""
335         ssh.from_node.return_value.run.return_value = 0, "success", ""
336
337         ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0)
338         self.assertIsNone(ping_traffic_gen.terminate())