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