Fix minor issues with IxNet L3 rfc2544
[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 import ipaddress
21 from collections import OrderedDict
22
23 from yardstick.common import utils
24 from yardstick.common import exceptions
25 from yardstick.benchmark import contexts
26 from yardstick.benchmark.contexts import base as ctx_base
27 from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
28 from yardstick.network_services.traffic_profile import base as tp_base
29 from yardstick.network_services.vnf_generic.vnf import tg_rfc2544_ixia
30
31
32 TEST_FILE_YAML = 'nsb_test_case.yaml'
33
34 NAME = "tg__1"
35
36
37 class TestIxiaResourceHelper(unittest.TestCase):
38
39     def setUp(self):
40         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
41         self.mock_IxNextgen = self._mock_IxNextgen.start()
42         self.addCleanup(self._stop_mocks)
43
44     def _stop_mocks(self):
45         self._mock_IxNextgen.stop()
46
47     def test___init___with_custom_rfc_helper(self):
48         class MyRfcHelper(tg_rfc2544_ixia.IxiaRfc2544Helper):
49             pass
50
51         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(
52             mock.Mock(), MyRfcHelper)
53         self.assertIsInstance(ixia_resource_helper.rfc_helper, MyRfcHelper)
54
55     def test__init_ix_scenario(self):
56         mock_scenario = mock.Mock()
57         mock_scenario_helper = mock.Mock()
58         mock_scenario_helper.scenario_cfg = {'ixia_config': 'TestScenario',
59                                              'options': 'scenario_options'}
60         mock_setup_helper = mock.Mock(scenario_helper=mock_scenario_helper)
61         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(mock_setup_helper)
62         ixia_resource_helper._ixia_scenarios = {'TestScenario': mock_scenario}
63         ixia_resource_helper.client = 'client'
64         ixia_resource_helper.context_cfg = 'context'
65         ixia_resource_helper._init_ix_scenario()
66         mock_scenario.assert_called_once_with('client', 'context', 'scenario_options')
67
68     def test__init_ix_scenario_not_supported_cfg_type(self):
69         mock_scenario_helper = mock.Mock()
70         mock_scenario_helper.scenario_cfg = {'ixia_config': 'FakeScenario',
71                                              'options': 'scenario_options'}
72         mock_setup_helper = mock.Mock(scenario_helper=mock_scenario_helper)
73         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(mock_setup_helper)
74         ixia_resource_helper._ixia_scenarios = {'TestScenario': mock.Mock()}
75         with self.assertRaises(RuntimeError):
76             ixia_resource_helper._init_ix_scenario()
77
78     @mock.patch.object(tg_rfc2544_ixia.IxiaResourceHelper, '_init_ix_scenario')
79     def test_setup(self, mock__init_ix_scenario):
80         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(mock.Mock())
81         ixia_resource_helper.setup()
82         mock__init_ix_scenario.assert_called_once()
83
84     def test_stop_collect_with_client(self):
85         mock_client = mock.Mock()
86         ixia_resource_helper = tg_rfc2544_ixia.IxiaResourceHelper(mock.Mock())
87         ixia_resource_helper.client = mock_client
88         ixia_resource_helper._ix_scenario = mock.Mock()
89         ixia_resource_helper.stop_collect()
90         self.assertEqual(1, ixia_resource_helper._terminated.value)
91         ixia_resource_helper._ix_scenario.stop_protocols.assert_called_once()
92
93     def test_run_traffic(self):
94         mock_tprofile = mock.Mock()
95         mock_tprofile.config.duration = 10
96         mock_tprofile.get_drop_percentage.return_value = True, 'fake_samples'
97         ixia_rhelper = tg_rfc2544_ixia.IxiaResourceHelper(mock.Mock())
98         ixia_rhelper.rfc_helper = mock.Mock()
99         ixia_rhelper.vnfd_helper = mock.Mock()
100         ixia_rhelper._ix_scenario = mock.Mock()
101         ixia_rhelper.vnfd_helper.port_pairs.all_ports = []
102         with mock.patch.object(ixia_rhelper, 'generate_samples'), \
103                 mock.patch.object(ixia_rhelper, '_build_ports'), \
104                 mock.patch.object(ixia_rhelper, '_initialize_client'), \
105                 mock.patch.object(utils, 'wait_until_true'):
106             ixia_rhelper.run_traffic(mock_tprofile)
107
108         self.assertEqual('fake_samples', ixia_rhelper._queue.get())
109         mock_tprofile.update_traffic_profile.assert_called_once()
110
111
112 @mock.patch.object(tg_rfc2544_ixia, 'ixnet_api')
113 class TestIXIATrafficGen(unittest.TestCase):
114     VNFD = {'vnfd:vnfd-catalog':
115             {'vnfd':
116              [{'short-name': 'VpeVnf',
117                'vdu':
118                [{'routing_table':
119                              [{'network': '152.16.100.20',
120                                'netmask': '255.255.255.0',
121                                'gateway': '152.16.100.20',
122                                'if': 'xe0'},
123                               {'network': '152.16.40.20',
124                                'netmask': '255.255.255.0',
125                                'gateway': '152.16.40.20',
126                                'if': 'xe1'}],
127                              'description': 'VPE approximation using DPDK',
128                              'name': 'vpevnf-baremetal',
129                              'nd_route_tbl':
130                                  [{'network': '0064:ff9b:0:0:0:0:9810:6414',
131                                    'netmask': '112',
132                                    'gateway': '0064:ff9b:0:0:0:0:9810:6414',
133                                    'if': 'xe0'},
134                                   {'network': '0064:ff9b:0:0:0:0:9810:2814',
135                                    'netmask': '112',
136                                    'gateway': '0064:ff9b:0:0:0:0:9810:2814',
137                                    'if': 'xe1'}],
138                              'id': 'vpevnf-baremetal',
139                              'external-interface':
140                                  [{'virtual-interface':
141                                    {'dst_mac': '00:00:00:00:00:04',
142                                     'vpci': '0000:05:00.0',
143                                     'local_ip': '152.16.100.19',
144                                     'type': 'PCI-PASSTHROUGH',
145                                     'netmask': '255.255.255.0',
146                                     'dpdk_port_num': 0,
147                                     'bandwidth': '10 Gbps',
148                                     'driver': "i40e",
149                                     'dst_ip': '152.16.100.20',
150                                     'local_iface_name': 'xe0',
151                                     'local_mac': '00:00:00:00:00:02'},
152                                    'vnfd-connection-point-ref': 'xe0',
153                                    'name': 'xe0'},
154                                   {'virtual-interface':
155                                    {'dst_mac': '00:00:00:00:00:03',
156                                     'vpci': '0000:05:00.1',
157                                     'local_ip': '152.16.40.19',
158                                     'type': 'PCI-PASSTHROUGH',
159                                     'driver': "i40e",
160                                     'netmask': '255.255.255.0',
161                                     'dpdk_port_num': 1,
162                                     'bandwidth': '10 Gbps',
163                                     'dst_ip': '152.16.40.20',
164                                     'local_iface_name': 'xe1',
165                                     'local_mac': '00:00:00:00:00:01'},
166                                    'vnfd-connection-point-ref': 'xe1',
167                                    'name': 'xe1'}]}],
168                'description': 'Vpe approximation using DPDK',
169                'mgmt-interface':
170                {'vdu-id': 'vpevnf-baremetal',
171                 'host': '1.1.1.1',
172                 'password': 'r00t',
173                             'user': 'root',
174                             'ip': '1.1.1.1'},
175                'benchmark':
176                {'kpi': ['packets_in', 'packets_fwd',
177                         'packets_dropped']},
178                'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
179                                     {'type': 'VPORT', 'name': 'xe1'}],
180                'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}}
181
182     TRAFFIC_PROFILE = {
183         "schema": "isb:traffic_profile:0.1",
184         "name": "fixed",
185         "description": "Fixed traffic profile to run UDP traffic",
186         "traffic_profile": {
187             "traffic_type": "FixedTraffic",
188             "frame_rate": 100,  # pps
189             "flow_number": 10,
190             "frame_size": 64}}
191
192     TC_YAML = {'scenarios': [{'tc_options':
193                               {'rfc2544': {'allowed_drop_rate': '0.8 - 1'}},
194                               'runner': {'duration': 400,
195                                          'interval': 35, 'type': 'Duration'},
196                               'traffic_options':
197                                   {'flow': 'ipv4_1flow_Packets_vpe.yaml',
198                                    'imix': 'imix_voice.yaml'},
199                               'vnf_options': {'vpe': {'cfg': 'vpe_config'}},
200                               'traffic_profile': 'ipv4_throughput_vpe.yaml',
201                               'type': 'NSPerf',
202                               'nodes': {'tg__1': 'trafficgen_1.yardstick',
203                                         'vnf__1': 'vnf.yardstick'},
204                               'topology': 'vpe_vnf_topology.yaml'}],
205                'context': {'nfvi_type': 'baremetal',
206                            'type': contexts.CONTEXT_NODE,
207                            'name': 'yardstick',
208                            'file': '/etc/yardstick/nodes/pod.yaml'},
209                'schema': 'yardstick:task:0.1'}
210
211     def test___init__(self, *args):
212         with mock.patch("yardstick.ssh.SSH") as ssh:
213             ssh_mock = mock.Mock(autospec=ssh.SSH)
214             ssh_mock.execute = \
215                 mock.Mock(return_value=(0, "", ""))
216             ssh.from_node.return_value = ssh_mock
217             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
218             # NOTE(ralonsoh): check the object returned.
219             tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd, 'task_id')
220
221     def test_listen_traffic(self, *args):
222         with mock.patch("yardstick.ssh.SSH") as ssh:
223             ssh_mock = mock.Mock(autospec=ssh.SSH)
224             ssh_mock.execute = \
225                 mock.Mock(return_value=(0, "", ""))
226             ssh.from_node.return_value = ssh_mock
227             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
228             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd,
229                                                                'task_id')
230             self.assertIsNone(ixnet_traffic_gen.listen_traffic({}))
231
232     @mock.patch.object(ctx_base.Context, 'get_context_from_server', return_value='fake_context')
233     def test_instantiate(self, *args):
234         with mock.patch("yardstick.ssh.SSH") as ssh:
235             ssh_mock = mock.Mock(autospec=ssh.SSH)
236             ssh_mock.execute = \
237                 mock.Mock(return_value=(0, "", ""))
238             ssh_mock.run = \
239                 mock.Mock(return_value=(0, "", ""))
240             ssh.from_node.return_value = ssh_mock
241             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
242             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd,
243                                                                'task_id')
244             scenario_cfg = {'tc': "nsb_test_case",
245                             "topology": ""}
246             scenario_cfg.update(
247                 {
248                     'options': {
249                         'packetsize': 64,
250                         'traffic_type': 4,
251                         'rfc2544': {
252                             'allowed_drop_rate': '0.8 - 1'},
253                         'vnf__1': {
254                             'rules': 'acl_1rule.yaml',
255                             'vnf_config': {
256                                 'lb_config': 'SW',
257                                 'lb_count': 1,
258                                 'worker_config': '1C/1T',
259                                 'worker_threads': 1}}}})
260             scenario_cfg.update({
261                 'nodes': {ixnet_traffic_gen.name: "mock"}
262             })
263             ixnet_traffic_gen.topology = ""
264             ixnet_traffic_gen.get_ixobj = mock.MagicMock()
265             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
266             ixnet_traffic_gen._ixia_traffic_gen._connect = mock.Mock()
267             self.assertRaises(
268                 IOError,
269                 ixnet_traffic_gen.instantiate(scenario_cfg, {}))
270
271     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
272     def test_collect_kpi(self, *args):
273         with mock.patch("yardstick.ssh.SSH") as ssh:
274             ssh_mock = mock.Mock(autospec=ssh.SSH)
275             ssh_mock.execute = \
276                 mock.Mock(return_value=(0, "", ""))
277             ssh.from_node.return_value = ssh_mock
278
279             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
280             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd,
281                                                                'task_id')
282             ixnet_traffic_gen.scenario_helper.scenario_cfg = {
283                 'nodes': {ixnet_traffic_gen.name: "mock"}
284             }
285             ixnet_traffic_gen.data = {}
286             restult = ixnet_traffic_gen.collect_kpi()
287
288             expected = {'collect_stats': {},
289                         'physical_node': 'mock_node'}
290
291             self.assertEqual(expected, restult)
292
293     def test_terminate(self, *args):
294         with mock.patch("yardstick.ssh.SSH") as ssh:
295             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
296             ssh_mock = mock.Mock(autospec=ssh.SSH)
297             ssh_mock.execute = \
298                 mock.Mock(return_value=(0, "", ""))
299             ssh.from_node.return_value = ssh_mock
300             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(
301                 NAME, vnfd, 'task_id', resource_helper_type=mock.Mock())
302             ixnet_traffic_gen._terminated = mock.MagicMock()
303             ixnet_traffic_gen._terminated.value = 0
304             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
305             ixnet_traffic_gen._ixia_traffic_gen.ix_stop_traffic = mock.Mock()
306             ixnet_traffic_gen._traffic_process = mock.MagicMock()
307             ixnet_traffic_gen._traffic_process.terminate = mock.Mock()
308             self.assertIsNone(ixnet_traffic_gen.terminate())
309
310     def _get_file_abspath(self, filename):
311         curr_path = os.path.dirname(os.path.abspath(__file__))
312         file_path = os.path.join(curr_path, filename)
313         return file_path
314
315     def test__check_status(self, *args):
316         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
317         sut = tg_rfc2544_ixia.IxiaTrafficGen('vnf1', vnfd, 'task_id')
318         sut._check_status()
319
320     @mock.patch("yardstick.ssh.SSH")
321     def test_traffic_runner(self, mock_ssh, *args):
322         mock_traffic_profile = mock.Mock(autospec=tp_base.TrafficProfile)
323         mock_traffic_profile.get_traffic_definition.return_value = "64"
324         mock_traffic_profile.params = self.TRAFFIC_PROFILE
325         # traffic_profile.ports is standardized on port_num
326         mock_traffic_profile.ports = [0, 1]
327
328         mock_ssh_instance = mock.Mock(autospec=mock_ssh.SSH)
329         mock_ssh_instance.execute.return_value = 0, "", ""
330         mock_ssh_instance.run.return_value = 0, "", ""
331
332         mock_ssh.from_node.return_value = mock_ssh_instance
333
334         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
335         vnfd["mgmt-interface"].update({
336             'tg-config': {
337                 "ixchassis": "1.1.1.1",
338                 "py_bin_path": "/root",
339             }
340         })
341
342         samples = {}
343         name = ''
344         for ifname in range(1):
345             name = "xe{}".format(ifname)
346             samples[name] = {
347                 "Rx_Rate_Kbps": 20,
348                 "Tx_Rate_Kbps": 20,
349                 "Rx_Rate_Mbps": 10,
350                 "Tx_Rate_Mbps": 10,
351                 "RxThroughput": 10,
352                 "TxThroughput": 10,
353                 "Valid_Frames_Rx": 1000,
354                 "Frames_Tx": 1000,
355                 "in_packets": 1000,
356                 "out_packets": 1000,
357             }
358
359         samples.update({"CurrentDropPercentage": 0.0})
360
361         last_res = [
362             0,
363             {
364                 "Rx_Rate_Kbps": [20, 20],
365                 "Tx_Rate_Kbps": [20, 20],
366                 "Rx_Rate_Mbps": [10, 10],
367                 "Tx_Rate_Mbps": [10, 10],
368                 "CurrentDropPercentage": [0, 0],
369                 "RxThroughput": [10, 10],
370                 "TxThroughput": [10, 10],
371                 "Frames_Tx": [1000, 1000],
372                 "in_packets": [1000, 1000],
373                 "Valid_Frames_Rx": [1000, 1000],
374                 "out_packets": [1000, 1000],
375             },
376         ]
377
378         mock_traffic_profile.execute_traffic.return_value = [
379             'Completed', samples]
380         mock_traffic_profile.get_drop_percentage.return_value = [
381             'Completed', samples]
382
383         sut = tg_rfc2544_ixia.IxiaTrafficGen(name, vnfd, 'task_id')
384         sut.vnf_port_pairs = [[[0], [1]]]
385         sut.tc_file_name = self._get_file_abspath(TEST_FILE_YAML)
386         sut.topology = ""
387
388         sut.ssh_helper = mock.Mock()
389         sut._traffic_process = mock.MagicMock()
390         sut.generate_port_pairs = mock.Mock()
391
392         sut._ixia_traffic_gen = mock.MagicMock()
393         sut._ixia_traffic_gen.ix_get_statistics.return_value = last_res
394
395         sut.resource_helper.client = mock.MagicMock()
396         sut.resource_helper.client_started = mock.MagicMock()
397         sut.resource_helper.client_started.value = 1
398         sut.resource_helper.rfc_helper.iteration.value = 11
399         sut.resource_helper._ix_scenario = mock.Mock()
400
401         sut.scenario_helper.scenario_cfg = {
402             'options': {
403                 'packetsize': 64,
404                 'traffic_type': 4,
405                 'rfc2544': {
406                     'allowed_drop_rate': '0.8 - 1',
407                     'latency': True
408                 },
409                 'vnf__1': {
410                     'rules': 'acl_1rule.yaml',
411                     'vnf_config': {
412                         'lb_config': 'SW',
413                         'lb_count': 1,
414                         'worker_config': '1C/1T',
415                         'worker_threads': 1,
416                     },
417                 },
418             },
419             'task_path': '/path/to/task'
420         }
421
422         @mock.patch.object(six.moves.builtins, 'open', create=True)
423         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.open',
424                     mock.mock_open(), create=True)
425         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.LOG.exception')
426         def _traffic_runner(*args):
427             sut._setup_mq_producer = mock.Mock(return_value='mq_producer')
428             result = sut._traffic_runner(mock_traffic_profile, mock.ANY)
429             self.assertIsNone(result)
430
431         _traffic_runner()
432
433
434 class TestIxiaBasicScenario(unittest.TestCase):
435     def setUp(self):
436         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
437         self.mock_IxNextgen = self._mock_IxNextgen.start()
438         self.context_cfg = mock.Mock()
439         self.ixia_cfg = mock.Mock()
440         self.scenario = tg_rfc2544_ixia.IxiaBasicScenario(self.mock_IxNextgen,
441                                                           self.context_cfg,
442                                                           self.ixia_cfg)
443         self.addCleanup(self._stop_mocks)
444
445     def _stop_mocks(self):
446         self._mock_IxNextgen.stop()
447
448     def test___init___(self):
449         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaBasicScenario)
450         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
451
452     def test_create_traffic_model(self):
453         self.mock_IxNextgen.get_vports.return_value = [1, 2, 3, 4]
454         self.scenario.create_traffic_model()
455         self.scenario.client.get_vports.assert_called_once()
456         self.scenario.client.create_traffic_model.assert_called_once_with([1, 3], [2, 4])
457
458     def test_apply_config(self):
459         self.assertIsNone(self.scenario.apply_config())
460
461     def test_run_protocols(self):
462         self.assertIsNone(self.scenario.run_protocols())
463
464     def test_stop_protocols(self):
465         self.assertIsNone(self.scenario.stop_protocols())
466
467
468 class TestIxiaL3Scenario(TestIxiaBasicScenario):
469     IXIA_CFG = {
470         'flow': {
471             'src_ip': ['192.168.0.1-192.168.0.50'],
472             'dst_ip': ['192.168.1.1-192.168.1.150']
473         }
474     }
475
476     CONTEXT_CFG = {
477         'nodes': {
478             'tg__0': {
479                 'role': 'IxNet',
480                 'interfaces': {
481                     'xe0': {
482                         'vld_id': 'uplink_0',
483                         'local_ip': '10.1.1.1',
484                         'local_mac': 'aa:bb:cc:dd:ee:ff',
485                         'ifname': 'xe0'
486                     },
487                     'xe1': {
488                         'vld_id': 'downlink_0',
489                         'local_ip': '20.2.2.2',
490                         'local_mac': 'bb:bb:cc:dd:ee:ee',
491                         'ifname': 'xe1'
492                     }
493                 },
494                 'routing_table': [{
495                     'network': "152.16.100.20",
496                     'netmask': '255.255.0.0',
497                     'gateway': '152.16.100.21',
498                     'if': 'xe0'
499                 }]
500             }
501         }
502     }
503
504     def setUp(self):
505         super(TestIxiaL3Scenario, self).setUp()
506         self.ixia_cfg = self.IXIA_CFG
507         self.context_cfg = self.CONTEXT_CFG
508         self.scenario = tg_rfc2544_ixia.IxiaL3Scenario(self.mock_IxNextgen,
509                                                        self.context_cfg,
510                                                        self.ixia_cfg)
511
512     def test___init___(self):
513         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaL3Scenario)
514         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
515
516     def test_create_traffic_model(self):
517         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
518         self.scenario.create_traffic_model()
519         self.scenario.client.get_vports.assert_called_once()
520         self.scenario.client.create_ipv4_traffic_model.\
521             assert_called_once_with(['1/protocols/static'],
522                                     ['2/protocols/static'])
523
524     def test_apply_config(self):
525         self.scenario._add_interfaces = mock.Mock()
526         self.scenario._add_static_ips = mock.Mock()
527         self.assertIsNone(self.scenario.apply_config())
528
529     def test__add_static(self):
530         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
531         self.mock_IxNextgen.get_static_interface.side_effect = ['intf1',
532                                                                 'intf2']
533
534         self.scenario._add_static_ips()
535
536         self.mock_IxNextgen.get_static_interface.assert_any_call('1')
537         self.mock_IxNextgen.get_static_interface.assert_any_call('2')
538
539         self.scenario.client.add_static_ipv4.assert_any_call(
540             'intf1', '1', '192.168.0.1', 49, '32')
541         self.scenario.client.add_static_ipv4.assert_any_call(
542             'intf2', '2', '192.168.1.1', 149, '32')
543
544     def test__add_interfaces(self):
545         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
546
547         self.scenario._add_interfaces()
548
549         self.mock_IxNextgen.add_interface.assert_any_call('1',
550                                                           '10.1.1.1',
551                                                           'aa:bb:cc:dd:ee:ff',
552                                                           '152.16.100.21')
553         self.mock_IxNextgen.add_interface.assert_any_call('2',
554                                                           '20.2.2.2',
555                                                           'bb:bb:cc:dd:ee:ee',
556                                                           None)
557
558
559 class TestIxiaPppoeClientScenario(unittest.TestCase):
560
561     IXIA_CFG = {
562         'pppoe_client': {
563             'sessions_per_port': 4,
564             'sessions_per_svlan': 1,
565             's_vlan': 10,
566             'c_vlan': 20,
567             'ip': ['10.3.3.1', '10.4.4.1']
568         },
569         'ipv4_client': {
570             'sessions_per_port': 1,
571             'sessions_per_vlan': 1,
572             'vlan': 101,
573             'gateway_ip': ['10.1.1.1', '10.2.2.1'],
574             'ip': ['10.1.1.1', '10.2.2.1'],
575             'prefix': ['24', '24']
576         }
577     }
578
579     CONTEXT_CFG = {
580         'nodes': {'tg__0': {
581             'interfaces': {'xe0': {
582                 'local_ip': '10.1.1.1',
583                 'netmask': '255.255.255.0'
584                 }}}}}
585
586     def setUp(self):
587         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
588         self.mock_IxNextgen = self._mock_IxNextgen.start()
589         self.scenario = tg_rfc2544_ixia.IxiaPppoeClientScenario(
590             self.mock_IxNextgen, self.CONTEXT_CFG, self.IXIA_CFG)
591         tg_rfc2544_ixia.WAIT_PROTOCOLS_STARTED = 2
592         self.addCleanup(self._stop_mocks)
593
594     def _stop_mocks(self):
595         self._mock_IxNextgen.stop()
596
597     def test___init___(self):
598         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaPppoeClientScenario)
599         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
600
601     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
602                        '_fill_ixia_config')
603     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
604                        '_apply_access_network_config')
605     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
606                        '_apply_core_network_config')
607     def test_apply_config(self, mock_apply_core_net_cfg,
608                           mock_apply_access_net_cfg,
609                           mock_fill_ixia_config):
610         self.mock_IxNextgen.get_vports.return_value = [1, 2, 3, 4]
611         self.scenario.apply_config()
612         self.scenario.client.get_vports.assert_called_once()
613         self.assertEqual(self.scenario._uplink_vports, [1, 3])
614         self.assertEqual(self.scenario._downlink_vports, [2, 4])
615         mock_fill_ixia_config.assert_called_once()
616         mock_apply_core_net_cfg.assert_called_once()
617         mock_apply_access_net_cfg.assert_called_once()
618
619     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
620                        '_get_endpoints_src_dst_id_pairs')
621     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
622                        '_get_endpoints_src_dst_obj_pairs')
623     def test_create_traffic_model(self, mock_obj_pairs, mock_id_pairs):
624         uplink_endpoints = ['group1', 'group2']
625         downlink_endpoints = ['group3', 'group3']
626         mock_id_pairs.return_value = ['xe0', 'xe1', 'xe0', 'xe1']
627         mock_obj_pairs.return_value = ['group1', 'group3', 'group2', 'group3']
628         mock_tp = mock.Mock()
629         mock_tp.full_profile = {'uplink_0': 'data',
630                                 'downlink_0': 'data',
631                                 'uplink_1': 'data',
632                                 'downlink_1': 'data'
633                                 }
634         self.scenario.create_traffic_model(mock_tp)
635         mock_id_pairs.assert_called_once_with(mock_tp.full_profile)
636         mock_obj_pairs.assert_called_once_with(['xe0', 'xe1', 'xe0', 'xe1'])
637         self.scenario.client.create_ipv4_traffic_model.assert_called_once_with(
638             uplink_endpoints, downlink_endpoints)
639
640     def test__get_endpoints_src_dst_id_pairs(self):
641         full_tp = OrderedDict([
642             ('uplink_0', {'ipv4': {'port': 'xe0'}}),
643             ('downlink_0', {'ipv4': {'port': 'xe1'}}),
644             ('uplink_1', {'ipv4': {'port': 'xe0'}}),
645             ('downlink_1', {'ipv4': {'port': 'xe3'}})])
646         endpoints_src_dst_pairs = ['xe0', 'xe1', 'xe0', 'xe3']
647         res = self.scenario._get_endpoints_src_dst_id_pairs(full_tp)
648         self.assertEqual(res, endpoints_src_dst_pairs)
649
650     def test__get_endpoints_src_dst_id_pairs_wrong_flows_number(self):
651         full_tp = OrderedDict([
652             ('uplink_0', {'ipv4': {'port': 'xe0'}}),
653             ('downlink_0', {'ipv4': {'port': 'xe1'}}),
654             ('uplink_1', {'ipv4': {'port': 'xe0'}})])
655         with self.assertRaises(RuntimeError):
656             self.scenario._get_endpoints_src_dst_id_pairs(full_tp)
657
658     def test__get_endpoints_src_dst_id_pairs_no_port_key(self):
659         full_tp = OrderedDict([
660             ('uplink_0', {'ipv4': {'id': 1}}),
661             ('downlink_0', {'ipv4': {'id': 2}})])
662         self.assertEqual(
663             self.scenario._get_endpoints_src_dst_id_pairs(full_tp), [])
664
665     def test__get_endpoints_src_dst_obj_pairs_tp_with_port_key(self):
666         endpoints_id_pairs = ['xe0', 'xe1',
667                               'xe0', 'xe1',
668                               'xe0', 'xe3',
669                               'xe0', 'xe3']
670         ixia_cfg = {
671             'pppoe_client': {
672                 'sessions_per_port': 4,
673                 'sessions_per_svlan': 1
674             },
675             'flow': {
676                 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}],
677                 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}]
678             }
679         }
680
681         expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1',
682                            'tp1_dg3', 'tp4_dg1', 'tp1_dg4', 'tp4_dg1']
683
684         self.scenario._ixia_cfg = ixia_cfg
685         self.scenario._access_topologies = ['topology1', 'topology2']
686         self.scenario._core_topologies = ['topology3', 'topology4']
687         self.mock_IxNextgen.get_topology_device_groups.side_effect = \
688             [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'],
689              ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'],
690              ['tp3_dg1'],
691              ['tp4_dg1']]
692         res = self.scenario._get_endpoints_src_dst_obj_pairs(
693             endpoints_id_pairs)
694         self.assertEqual(res, expected_result)
695
696     def test__get_endpoints_src_dst_obj_pairs_default_flows_mapping(self):
697         endpoints_id_pairs = []
698         ixia_cfg = {
699             'pppoe_client': {
700                 'sessions_per_port': 4,
701                 'sessions_per_svlan': 1
702             },
703             'flow': {
704                 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}],
705                 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}]
706             }
707         }
708
709         expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1',
710                            'tp1_dg3', 'tp3_dg1', 'tp1_dg4', 'tp3_dg1',
711                            'tp2_dg1', 'tp4_dg1', 'tp2_dg2', 'tp4_dg1',
712                            'tp2_dg3', 'tp4_dg1', 'tp2_dg4', 'tp4_dg1']
713
714         self.scenario._ixia_cfg = ixia_cfg
715         self.scenario._access_topologies = ['topology1', 'topology2']
716         self.scenario._core_topologies = ['topology3', 'topology4']
717         self.mock_IxNextgen.get_topology_device_groups.side_effect = \
718             [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'],
719              ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'],
720              ['tp3_dg1'],
721              ['tp4_dg1']]
722         res = self.scenario._get_endpoints_src_dst_obj_pairs(
723             endpoints_id_pairs)
724         self.assertEqual(res, expected_result)
725
726     def test_run_protocols(self):
727         self.scenario.client.is_protocols_running.return_value = True
728         self.scenario.run_protocols()
729         self.scenario.client.start_protocols.assert_called_once()
730
731     def test_run_protocols_timeout_exception(self):
732         self.scenario.client.is_protocols_running.return_value = False
733         with self.assertRaises(exceptions.WaitTimeout):
734             self.scenario.run_protocols()
735         self.scenario.client.start_protocols.assert_called_once()
736
737     def test_stop_protocols(self):
738         self.scenario.stop_protocols()
739         self.scenario.client.stop_protocols.assert_called_once()
740
741     def test__get_intf_addr_str_type_input(self):
742         intf = '192.168.10.2/24'
743         ip, mask = self.scenario._get_intf_addr(intf)
744         self.assertEqual(ip, '192.168.10.2')
745         self.assertEqual(mask, 24)
746
747     def test__get_intf_addr_dict_type_input(self):
748         intf = {'tg__0': 'xe0'}
749         ip, mask = self.scenario._get_intf_addr(intf)
750         self.assertEqual(ip, '10.1.1.1')
751         self.assertEqual(mask, 24)
752
753     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario, '_get_intf_addr')
754     def test__fill_ixia_config(self, mock_get_intf_addr):
755
756         ixia_cfg = {
757             'pppoe_client': {
758                 'sessions_per_port': 4,
759                 'sessions_per_svlan': 1,
760                 's_vlan': 10,
761                 'c_vlan': 20,
762                 'ip': ['10.3.3.1/24', '10.4.4.1/24']
763             },
764             'ipv4_client': {
765                 'sessions_per_port': 1,
766                 'sessions_per_vlan': 1,
767                 'vlan': 101,
768                 'gateway_ip': ['10.1.1.1/24', '10.2.2.1/24'],
769                 'ip': ['10.1.1.1/24', '10.2.2.1/24']
770             }
771         }
772
773         mock_get_intf_addr.side_effect = [
774             ('10.3.3.1', '24'),
775             ('10.4.4.1', '24'),
776             ('10.1.1.1', '24'),
777             ('10.2.2.1', '24'),
778             ('10.1.1.1', '24'),
779             ('10.2.2.1', '24')
780         ]
781         self.scenario._ixia_cfg = ixia_cfg
782         self.scenario._fill_ixia_config()
783         self.assertEqual(mock_get_intf_addr.call_count, 6)
784         self.assertEqual(self.scenario._ixia_cfg['pppoe_client']['ip'],
785                          ['10.3.3.1', '10.4.4.1'])
786         self.assertEqual(self.scenario._ixia_cfg['ipv4_client']['ip'],
787                          ['10.1.1.1', '10.2.2.1'])
788         self.assertEqual(self.scenario._ixia_cfg['ipv4_client']['prefix'],
789                          ['24', '24'])
790
791     @mock.patch('yardstick.network_services.libs.ixia_libs.ixnet.ixnet_api.Vlan')
792     def test__apply_access_network_config_pap_auth(self, mock_vlan):
793         _ixia_cfg = {
794             'pppoe_client': {
795                 'sessions_per_port': 4,
796                 'sessions_per_svlan': 1,
797                 's_vlan': 10,
798                 'c_vlan': 20,
799                 'pap_user': 'test_pap',
800                 'pap_password': 'pap'
801                 }}
802         pap_user = _ixia_cfg['pppoe_client']['pap_user']
803         pap_passwd = _ixia_cfg['pppoe_client']['pap_password']
804         self.scenario._ixia_cfg = _ixia_cfg
805         self.scenario._uplink_vports = [0, 2]
806         self.scenario.client.add_topology.side_effect = ['Topology 1', 'Topology 2']
807         self.scenario.client.add_device_group.side_effect = ['Dg1', 'Dg2', 'Dg3',
808                                                              'Dg4', 'Dg5', 'Dg6',
809                                                              'Dg7', 'Dg8']
810         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2', 'Eth3',
811                                                          'Eth4', 'Eth5', 'Eth6',
812                                                          'Eth7', 'Eth8']
813         self.scenario._apply_access_network_config()
814         self.assertEqual(self.scenario.client.add_topology.call_count, 2)
815         self.assertEqual(self.scenario.client.add_device_group.call_count, 8)
816         self.assertEqual(self.scenario.client.add_ethernet.call_count, 8)
817         self.assertEqual(mock_vlan.call_count, 16)
818         self.assertEqual(self.scenario.client.add_vlans.call_count, 8)
819         self.assertEqual(self.scenario.client.add_pppox_client.call_count, 8)
820         self.scenario.client.add_topology.assert_has_calls([
821             mock.call('Topology access 0', 0),
822             mock.call('Topology access 1', 2)
823         ])
824         self.scenario.client.add_device_group.assert_has_calls([
825             mock.call('Topology 1', 'SVLAN 10', 1),
826             mock.call('Topology 1', 'SVLAN 11', 1),
827             mock.call('Topology 1', 'SVLAN 12', 1),
828             mock.call('Topology 1', 'SVLAN 13', 1),
829             mock.call('Topology 2', 'SVLAN 14', 1),
830             mock.call('Topology 2', 'SVLAN 15', 1),
831             mock.call('Topology 2', 'SVLAN 16', 1),
832             mock.call('Topology 2', 'SVLAN 17', 1)
833         ])
834         self.scenario.client.add_ethernet.assert_has_calls([
835             mock.call('Dg1', 'Ethernet'),
836             mock.call('Dg2', 'Ethernet'),
837             mock.call('Dg3', 'Ethernet'),
838             mock.call('Dg4', 'Ethernet'),
839             mock.call('Dg5', 'Ethernet'),
840             mock.call('Dg6', 'Ethernet'),
841             mock.call('Dg7', 'Ethernet'),
842             mock.call('Dg8', 'Ethernet')
843         ])
844         mock_vlan.assert_has_calls([
845             mock.call(vlan_id=10),
846             mock.call(vlan_id=20, vlan_id_step=1),
847             mock.call(vlan_id=11),
848             mock.call(vlan_id=20, vlan_id_step=1),
849             mock.call(vlan_id=12),
850             mock.call(vlan_id=20, vlan_id_step=1),
851             mock.call(vlan_id=13),
852             mock.call(vlan_id=20, vlan_id_step=1),
853             mock.call(vlan_id=14),
854             mock.call(vlan_id=20, vlan_id_step=1),
855             mock.call(vlan_id=15),
856             mock.call(vlan_id=20, vlan_id_step=1),
857             mock.call(vlan_id=16),
858             mock.call(vlan_id=20, vlan_id_step=1),
859             mock.call(vlan_id=17),
860             mock.call(vlan_id=20, vlan_id_step=1)
861         ])
862         self.scenario.client.add_pppox_client.assert_has_calls([
863             mock.call('Eth1', 'pap', pap_user, pap_passwd),
864             mock.call('Eth2', 'pap', pap_user, pap_passwd),
865             mock.call('Eth3', 'pap', pap_user, pap_passwd),
866             mock.call('Eth4', 'pap', pap_user, pap_passwd),
867             mock.call('Eth5', 'pap', pap_user, pap_passwd),
868             mock.call('Eth6', 'pap', pap_user, pap_passwd),
869             mock.call('Eth7', 'pap', pap_user, pap_passwd),
870             mock.call('Eth8', 'pap', pap_user, pap_passwd)
871         ])
872
873     def test__apply_access_network_config_chap_auth(self):
874         _ixia_cfg = {
875             'pppoe_client': {
876                 'sessions_per_port': 4,
877                 'sessions_per_svlan': 1,
878                 's_vlan': 10,
879                 'c_vlan': 20,
880                 'chap_user': 'test_chap',
881                 'chap_password': 'chap'
882             }}
883         chap_user = _ixia_cfg['pppoe_client']['chap_user']
884         chap_passwd = _ixia_cfg['pppoe_client']['chap_password']
885         self.scenario._ixia_cfg = _ixia_cfg
886         self.scenario._uplink_vports = [0, 2]
887         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2', 'Eth3',
888                                                          'Eth4', 'Eth5', 'Eth6',
889                                                          'Eth7', 'Eth8']
890         self.scenario._apply_access_network_config()
891         self.assertEqual(self.scenario.client.add_pppox_client.call_count, 8)
892         self.scenario.client.add_pppox_client.assert_has_calls([
893             mock.call('Eth1', 'chap', chap_user, chap_passwd),
894             mock.call('Eth2', 'chap', chap_user, chap_passwd),
895             mock.call('Eth3', 'chap', chap_user, chap_passwd),
896             mock.call('Eth4', 'chap', chap_user, chap_passwd),
897             mock.call('Eth5', 'chap', chap_user, chap_passwd),
898             mock.call('Eth6', 'chap', chap_user, chap_passwd),
899             mock.call('Eth7', 'chap', chap_user, chap_passwd),
900             mock.call('Eth8', 'chap', chap_user, chap_passwd)
901         ])
902
903     @mock.patch('yardstick.network_services.libs.ixia_libs.ixnet.ixnet_api.Vlan')
904     def test__apply_core_network_config_no_bgp_proto(self, mock_vlan):
905         self.scenario._downlink_vports = [1, 3]
906         self.scenario.client.add_topology.side_effect = ['Topology 1', 'Topology 2']
907         self.scenario.client.add_device_group.side_effect = ['Dg1', 'Dg2']
908         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2']
909         self.scenario._apply_core_network_config()
910         self.assertEqual(self.scenario.client.add_topology.call_count, 2)
911         self.assertEqual(self.scenario.client.add_device_group.call_count, 2)
912         self.assertEqual(self.scenario.client.add_ethernet.call_count, 2)
913         self.assertEqual(mock_vlan.call_count, 2)
914         self.assertEqual(self.scenario.client.add_vlans.call_count, 2)
915         self.assertEqual(self.scenario.client.add_ipv4.call_count, 2)
916         self.scenario.client.add_topology.assert_has_calls([
917             mock.call('Topology core 0', 1),
918             mock.call('Topology core 1', 3)
919         ])
920         self.scenario.client.add_device_group.assert_has_calls([
921             mock.call('Topology 1', 'Core port 0', 1),
922             mock.call('Topology 2', 'Core port 1', 1)
923         ])
924         self.scenario.client.add_ethernet.assert_has_calls([
925             mock.call('Dg1', 'Ethernet'),
926             mock.call('Dg2', 'Ethernet')
927         ])
928         mock_vlan.assert_has_calls([
929             mock.call(vlan_id=101),
930             mock.call(vlan_id=102)
931         ])
932         self.scenario.client.add_ipv4.assert_has_calls([
933             mock.call('Eth1', name='ipv4', addr=ipaddress.IPv4Address('10.1.1.2'),
934                       addr_step='0.0.0.1', prefix='24', gateway='10.1.1.1'),
935             mock.call('Eth2', name='ipv4', addr=ipaddress.IPv4Address('10.2.2.2'),
936                       addr_step='0.0.0.1', prefix='24', gateway='10.2.2.1')
937         ])
938         self.scenario.client.add_bgp.assert_not_called()
939
940     def test__apply_core_network_config_with_bgp_proto(self):
941         bgp_params = {
942             'bgp': {
943                 'bgp_type': 'external',
944                 'dut_ip': '10.0.0.1',
945                 'as_number': 65000
946             }
947         }
948         self.scenario._ixia_cfg['ipv4_client'].update(bgp_params)
949         self.scenario._downlink_vports = [1, 3]
950         self.scenario.client.add_ipv4.side_effect = ['ipv4_1', 'ipv4_2']
951         self.scenario._apply_core_network_config()
952         self.assertEqual(self.scenario.client.add_bgp.call_count, 2)
953         self.scenario.client.add_bgp.assert_has_calls([
954             mock.call('ipv4_1', dut_ip=bgp_params["bgp"]["dut_ip"],
955                       local_as=bgp_params["bgp"]["as_number"],
956                       bgp_type=bgp_params["bgp"]["bgp_type"]),
957             mock.call('ipv4_2', dut_ip=bgp_params["bgp"]["dut_ip"],
958                       local_as=bgp_params["bgp"]["as_number"],
959                       bgp_type=bgp_params["bgp"]["bgp_type"])
960         ])