f34faaec7c3db43b28d93a0d2e420b66c7f07e65
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_tg_rfc2544_ixia.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 os
16
17 import mock
18 import six
19 import unittest
20
21 from yardstick.benchmark import contexts
22 from yardstick.benchmark.contexts import base as ctx_base
23 from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
24 from yardstick.network_services.traffic_profile import base as tp_base
25 from yardstick.network_services.vnf_generic.vnf import tg_rfc2544_ixia
26
27
28 TEST_FILE_YAML = 'nsb_test_case.yaml'
29
30 NAME = "tg__1"
31
32
33 class TestIxiaResourceHelper(unittest.TestCase):
34
35     def setUp(self):
36         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
37         self.mock_IxNextgen = self._mock_IxNextgen.start()
38         self.addCleanup(self._stop_mocks)
39
40     def _stop_mocks(self):
41         self._mock_IxNextgen.stop()
42
43     def test___init___with_custom_rfc_helper(self):
44         class MyRfcHelper(tg_rfc2544_ixia.IxiaRfc2544Helper):
45             pass
46
47         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(
48             mock.Mock(), MyRfcHelper)
49         self.assertIsInstance(ixia_resource_helper.rfc_helper, MyRfcHelper)
50
51     def test_stop_collect_with_client(self):
52         mock_client = mock.Mock()
53         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(mock.Mock())
54         ixia_resource_helper.client = mock_client
55         ixia_resource_helper.stop_collect()
56         self.assertEqual(1, ixia_resource_helper._terminated.value)
57
58     def test_run_traffic(self):
59         mock_tprofile = mock.Mock()
60         mock_tprofile.get_drop_percentage.return_value = True, 'fake_samples'
61         ixia_rhelper = tg_rfc2544_ixia.IxiaResourceHelper(mock.Mock())
62         ixia_rhelper.rfc_helper = mock.Mock()
63         ixia_rhelper.vnfd_helper = mock.Mock()
64         ixia_rhelper.vnfd_helper.port_pairs.all_ports = []
65         with mock.patch.object(ixia_rhelper, 'generate_samples'), \
66                 mock.patch.object(ixia_rhelper, '_build_ports'), \
67                 mock.patch.object(ixia_rhelper, '_initialize_client'):
68             ixia_rhelper.run_traffic(mock_tprofile)
69
70         self.assertEqual('fake_samples', ixia_rhelper._queue.get())
71
72
73 @mock.patch.object(tg_rfc2544_ixia, 'ixnet_api')
74 class TestIXIATrafficGen(unittest.TestCase):
75     VNFD = {'vnfd:vnfd-catalog':
76             {'vnfd':
77              [{'short-name': 'VpeVnf',
78                'vdu':
79                [{'routing_table':
80                              [{'network': '152.16.100.20',
81                                'netmask': '255.255.255.0',
82                                'gateway': '152.16.100.20',
83                                'if': 'xe0'},
84                               {'network': '152.16.40.20',
85                                'netmask': '255.255.255.0',
86                                'gateway': '152.16.40.20',
87                                'if': 'xe1'}],
88                              'description': 'VPE approximation using DPDK',
89                              'name': 'vpevnf-baremetal',
90                              'nd_route_tbl':
91                                  [{'network': '0064:ff9b:0:0:0:0:9810:6414',
92                                    'netmask': '112',
93                                    'gateway': '0064:ff9b:0:0:0:0:9810:6414',
94                                    'if': 'xe0'},
95                                   {'network': '0064:ff9b:0:0:0:0:9810:2814',
96                                    'netmask': '112',
97                                    'gateway': '0064:ff9b:0:0:0:0:9810:2814',
98                                    'if': 'xe1'}],
99                              'id': 'vpevnf-baremetal',
100                              'external-interface':
101                                  [{'virtual-interface':
102                                    {'dst_mac': '00:00:00:00:00:04',
103                                     'vpci': '0000:05:00.0',
104                                     'local_ip': '152.16.100.19',
105                                     'type': 'PCI-PASSTHROUGH',
106                                     'netmask': '255.255.255.0',
107                                     'dpdk_port_num': 0,
108                                     'bandwidth': '10 Gbps',
109                                     'driver': "i40e",
110                                     'dst_ip': '152.16.100.20',
111                                     'local_iface_name': 'xe0',
112                                     'local_mac': '00:00:00:00:00:02'},
113                                    'vnfd-connection-point-ref': 'xe0',
114                                    'name': 'xe0'},
115                                   {'virtual-interface':
116                                    {'dst_mac': '00:00:00:00:00:03',
117                                     'vpci': '0000:05:00.1',
118                                     'local_ip': '152.16.40.19',
119                                     'type': 'PCI-PASSTHROUGH',
120                                     'driver': "i40e",
121                                     'netmask': '255.255.255.0',
122                                     'dpdk_port_num': 1,
123                                     'bandwidth': '10 Gbps',
124                                     'dst_ip': '152.16.40.20',
125                                     'local_iface_name': 'xe1',
126                                     'local_mac': '00:00:00:00:00:01'},
127                                    'vnfd-connection-point-ref': 'xe1',
128                                    'name': 'xe1'}]}],
129                'description': 'Vpe approximation using DPDK',
130                'mgmt-interface':
131                {'vdu-id': 'vpevnf-baremetal',
132                 'host': '1.1.1.1',
133                 'password': 'r00t',
134                             'user': 'root',
135                             'ip': '1.1.1.1'},
136                'benchmark':
137                {'kpi': ['packets_in', 'packets_fwd',
138                         'packets_dropped']},
139                'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
140                                     {'type': 'VPORT', 'name': 'xe1'}],
141                'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}}
142
143     TRAFFIC_PROFILE = {
144         "schema": "isb:traffic_profile:0.1",
145         "name": "fixed",
146         "description": "Fixed traffic profile to run UDP traffic",
147         "traffic_profile": {
148             "traffic_type": "FixedTraffic",
149             "frame_rate": 100,  # pps
150             "flow_number": 10,
151             "frame_size": 64}}
152
153     TC_YAML = {'scenarios': [{'tc_options':
154                               {'rfc2544': {'allowed_drop_rate': '0.8 - 1'}},
155                               'runner': {'duration': 400,
156                                          'interval': 35, 'type': 'Duration'},
157                               'traffic_options':
158                                   {'flow': 'ipv4_1flow_Packets_vpe.yaml',
159                                    'imix': 'imix_voice.yaml'},
160                               'vnf_options': {'vpe': {'cfg': 'vpe_config'}},
161                               'traffic_profile': 'ipv4_throughput_vpe.yaml',
162                               'type': 'NSPerf',
163                               'nodes': {'tg__1': 'trafficgen_1.yardstick',
164                                         'vnf__1': 'vnf.yardstick'},
165                               'topology': 'vpe_vnf_topology.yaml'}],
166                'context': {'nfvi_type': 'baremetal',
167                            'type': contexts.CONTEXT_NODE,
168                            'name': 'yardstick',
169                            'file': '/etc/yardstick/nodes/pod.yaml'},
170                'schema': 'yardstick:task:0.1'}
171
172     def test___init__(self, *args):
173         with mock.patch("yardstick.ssh.SSH") as ssh:
174             ssh_mock = mock.Mock(autospec=ssh.SSH)
175             ssh_mock.execute = \
176                 mock.Mock(return_value=(0, "", ""))
177             ssh.from_node.return_value = ssh_mock
178             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
179             # NOTE(ralonsoh): check the object returned.
180             tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
181
182     def test_listen_traffic(self, *args):
183         with mock.patch("yardstick.ssh.SSH") as ssh:
184             ssh_mock = mock.Mock(autospec=ssh.SSH)
185             ssh_mock.execute = \
186                 mock.Mock(return_value=(0, "", ""))
187             ssh.from_node.return_value = ssh_mock
188             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
189             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
190             self.assertIsNone(ixnet_traffic_gen.listen_traffic({}))
191
192     @mock.patch.object(ctx_base.Context, 'get_context_from_server', return_value='fake_context')
193     def test_instantiate(self, *args):
194         with mock.patch("yardstick.ssh.SSH") as ssh:
195             ssh_mock = mock.Mock(autospec=ssh.SSH)
196             ssh_mock.execute = \
197                 mock.Mock(return_value=(0, "", ""))
198             ssh_mock.run = \
199                 mock.Mock(return_value=(0, "", ""))
200             ssh.from_node.return_value = ssh_mock
201             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
202             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
203             scenario_cfg = {'tc': "nsb_test_case", "topology": "",
204                             'ixia_profile': "ixload.cfg"}
205             scenario_cfg.update(
206                 {
207                     'options': {
208                         'packetsize': 64,
209                         'traffic_type': 4,
210                         'rfc2544': {
211                             'allowed_drop_rate': '0.8 - 1'},
212                         'vnf__1': {
213                             'rules': 'acl_1rule.yaml',
214                             'vnf_config': {
215                                 'lb_config': 'SW',
216                                 'lb_count': 1,
217                                 'worker_config': '1C/1T',
218                                 'worker_threads': 1}}}})
219             scenario_cfg.update({
220                 'nodes': {ixnet_traffic_gen.name: "mock"}
221             })
222             ixnet_traffic_gen.topology = ""
223             ixnet_traffic_gen.get_ixobj = mock.MagicMock()
224             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
225             ixnet_traffic_gen._ixia_traffic_gen._connect = mock.Mock()
226             self.assertRaises(
227                 IOError,
228                 ixnet_traffic_gen.instantiate(scenario_cfg, {}))
229
230     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
231     def test_collect_kpi(self, *args):
232         with mock.patch("yardstick.ssh.SSH") as ssh:
233             ssh_mock = mock.Mock(autospec=ssh.SSH)
234             ssh_mock.execute = \
235                 mock.Mock(return_value=(0, "", ""))
236             ssh.from_node.return_value = ssh_mock
237
238             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
239             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
240             ixnet_traffic_gen.scenario_helper.scenario_cfg = {
241                 'nodes': {ixnet_traffic_gen.name: "mock"}
242             }
243             ixnet_traffic_gen.data = {}
244             restult = ixnet_traffic_gen.collect_kpi()
245
246             expected = {'collect_stats': {},
247                         'physical_node': 'mock_node'}
248
249             self.assertEqual(expected, restult)
250
251     def test_terminate(self, *args):
252         with mock.patch("yardstick.ssh.SSH") as ssh:
253             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
254             ssh_mock = mock.Mock(autospec=ssh.SSH)
255             ssh_mock.execute = \
256                 mock.Mock(return_value=(0, "", ""))
257             ssh.from_node.return_value = ssh_mock
258             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
259             ixnet_traffic_gen._terminated = mock.MagicMock()
260             ixnet_traffic_gen._terminated.value = 0
261             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
262             ixnet_traffic_gen._ixia_traffic_gen.ix_stop_traffic = mock.Mock()
263             ixnet_traffic_gen._traffic_process = mock.MagicMock()
264             ixnet_traffic_gen._traffic_process.terminate = mock.Mock()
265             self.assertIsNone(ixnet_traffic_gen.terminate())
266
267     def _get_file_abspath(self, filename):
268         curr_path = os.path.dirname(os.path.abspath(__file__))
269         file_path = os.path.join(curr_path, filename)
270         return file_path
271
272     def test__check_status(self, *args):
273         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
274         sut = tg_rfc2544_ixia.IxiaTrafficGen('vnf1', vnfd)
275         sut._check_status()
276
277     @mock.patch("yardstick.ssh.SSH")
278     def test_traffic_runner(self, mock_ssh, *args):
279         mock_traffic_profile = mock.Mock(autospec=tp_base.TrafficProfile)
280         mock_traffic_profile.get_traffic_definition.return_value = "64"
281         mock_traffic_profile.params = self.TRAFFIC_PROFILE
282         # traffic_profile.ports is standardized on port_num
283         mock_traffic_profile.ports = [0, 1]
284
285         mock_ssh_instance = mock.Mock(autospec=mock_ssh.SSH)
286         mock_ssh_instance.execute.return_value = 0, "", ""
287         mock_ssh_instance.run.return_value = 0, "", ""
288
289         mock_ssh.from_node.return_value = mock_ssh_instance
290
291         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
292         vnfd["mgmt-interface"].update({
293             'tg-config': {
294                 "ixchassis": "1.1.1.1",
295                 "py_bin_path": "/root",
296             }
297         })
298
299         samples = {}
300         name = ''
301         for ifname in range(1):
302             name = "xe{}".format(ifname)
303             samples[name] = {
304                 "Rx_Rate_Kbps": 20,
305                 "Tx_Rate_Kbps": 20,
306                 "Rx_Rate_Mbps": 10,
307                 "Tx_Rate_Mbps": 10,
308                 "RxThroughput": 10,
309                 "TxThroughput": 10,
310                 "Valid_Frames_Rx": 1000,
311                 "Frames_Tx": 1000,
312                 "in_packets": 1000,
313                 "out_packets": 1000,
314             }
315
316         samples.update({"CurrentDropPercentage": 0.0})
317
318         last_res = [
319             0,
320             {
321                 "Rx_Rate_Kbps": [20, 20],
322                 "Tx_Rate_Kbps": [20, 20],
323                 "Rx_Rate_Mbps": [10, 10],
324                 "Tx_Rate_Mbps": [10, 10],
325                 "CurrentDropPercentage": [0, 0],
326                 "RxThroughput": [10, 10],
327                 "TxThroughput": [10, 10],
328                 "Frames_Tx": [1000, 1000],
329                 "in_packets": [1000, 1000],
330                 "Valid_Frames_Rx": [1000, 1000],
331                 "out_packets": [1000, 1000],
332             },
333         ]
334
335         mock_traffic_profile.execute_traffic.return_value = [
336             'Completed', samples]
337         mock_traffic_profile.get_drop_percentage.return_value = [
338             'Completed', samples]
339
340         sut = tg_rfc2544_ixia.IxiaTrafficGen(name, vnfd)
341         sut.vnf_port_pairs = [[[0], [1]]]
342         sut.tc_file_name = self._get_file_abspath(TEST_FILE_YAML)
343         sut.topology = ""
344
345         sut.ssh_helper = mock.Mock()
346         sut._traffic_process = mock.MagicMock()
347         sut.generate_port_pairs = mock.Mock()
348
349         sut._ixia_traffic_gen = mock.MagicMock()
350         sut._ixia_traffic_gen.ix_get_statistics.return_value = last_res
351
352         sut.resource_helper.client = mock.MagicMock()
353         sut.resource_helper.client_started = mock.MagicMock()
354         sut.resource_helper.client_started.value = 1
355         sut.resource_helper.rfc_helper.iteration.value = 11
356
357         sut.scenario_helper.scenario_cfg = {
358             'options': {
359                 'packetsize': 64,
360                 'traffic_type': 4,
361                 'rfc2544': {
362                     'allowed_drop_rate': '0.8 - 1',
363                     'latency': True
364                 },
365                 'vnf__1': {
366                     'rules': 'acl_1rule.yaml',
367                     'vnf_config': {
368                         'lb_config': 'SW',
369                         'lb_count': 1,
370                         'worker_config': '1C/1T',
371                         'worker_threads': 1,
372                     },
373                 },
374             },
375             'ixia_profile': '/path/to/profile',
376             'task_path': '/path/to/task'
377         }
378
379         @mock.patch.object(six.moves.builtins, 'open', create=True)
380         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.open',
381                     mock.mock_open(), create=True)
382         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.LOG.exception')
383         def _traffic_runner(*args):
384             sut._setup_mq_producer = mock.Mock(return_value='mq_producer')
385             result = sut._traffic_runner(mock_traffic_profile, mock.ANY)
386             self.assertIsNone(result)
387
388         _traffic_runner()