NSB sync: clean-up draft IPC implementation (part 1)
[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)
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             self.assertIsNone(ixnet_traffic_gen.listen_traffic({}))
230
231     @mock.patch.object(ctx_base.Context, 'get_context_from_server', return_value='fake_context')
232     def test_instantiate(self, *args):
233         with mock.patch("yardstick.ssh.SSH") as ssh:
234             ssh_mock = mock.Mock(autospec=ssh.SSH)
235             ssh_mock.execute = \
236                 mock.Mock(return_value=(0, "", ""))
237             ssh_mock.run = \
238                 mock.Mock(return_value=(0, "", ""))
239             ssh.from_node.return_value = ssh_mock
240             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
241             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
242             scenario_cfg = {'tc': "nsb_test_case",
243                             "topology": ""}
244             scenario_cfg.update(
245                 {
246                     'options': {
247                         'packetsize': 64,
248                         'traffic_type': 4,
249                         'rfc2544': {
250                             'allowed_drop_rate': '0.8 - 1'},
251                         'vnf__1': {
252                             'rules': 'acl_1rule.yaml',
253                             'vnf_config': {
254                                 'lb_config': 'SW',
255                                 'lb_count': 1,
256                                 'worker_config': '1C/1T',
257                                 'worker_threads': 1}}}})
258             scenario_cfg.update({
259                 'nodes': {ixnet_traffic_gen.name: "mock"}
260             })
261             ixnet_traffic_gen.topology = ""
262             ixnet_traffic_gen.get_ixobj = mock.MagicMock()
263             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
264             ixnet_traffic_gen._ixia_traffic_gen._connect = mock.Mock()
265             self.assertRaises(
266                 IOError,
267                 ixnet_traffic_gen.instantiate(scenario_cfg, {}))
268
269     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
270     def test_collect_kpi(self, *args):
271         with mock.patch("yardstick.ssh.SSH") as ssh:
272             ssh_mock = mock.Mock(autospec=ssh.SSH)
273             ssh_mock.execute = \
274                 mock.Mock(return_value=(0, "", ""))
275             ssh.from_node.return_value = ssh_mock
276
277             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
278             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(NAME, vnfd)
279             ixnet_traffic_gen.scenario_helper.scenario_cfg = {
280                 'nodes': {ixnet_traffic_gen.name: "mock"}
281             }
282             ixnet_traffic_gen.data = {}
283             restult = ixnet_traffic_gen.collect_kpi()
284
285             expected = {'collect_stats': {},
286                         'physical_node': 'mock_node'}
287
288             self.assertEqual(expected, restult)
289
290     def test_terminate(self, *args):
291         with mock.patch("yardstick.ssh.SSH") as ssh:
292             vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
293             ssh_mock = mock.Mock(autospec=ssh.SSH)
294             ssh_mock.execute = \
295                 mock.Mock(return_value=(0, "", ""))
296             ssh.from_node.return_value = ssh_mock
297             ixnet_traffic_gen = tg_rfc2544_ixia.IxiaTrafficGen(
298                 NAME, vnfd, resource_helper_type=mock.Mock())
299             ixnet_traffic_gen._terminated = mock.MagicMock()
300             ixnet_traffic_gen._terminated.value = 0
301             ixnet_traffic_gen._ixia_traffic_gen = mock.MagicMock()
302             ixnet_traffic_gen._ixia_traffic_gen.ix_stop_traffic = mock.Mock()
303             ixnet_traffic_gen._traffic_process = mock.MagicMock()
304             ixnet_traffic_gen._traffic_process.terminate = mock.Mock()
305             self.assertIsNone(ixnet_traffic_gen.terminate())
306
307     def _get_file_abspath(self, filename):
308         curr_path = os.path.dirname(os.path.abspath(__file__))
309         file_path = os.path.join(curr_path, filename)
310         return file_path
311
312     def test__check_status(self, *args):
313         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
314         sut = tg_rfc2544_ixia.IxiaTrafficGen('vnf1', vnfd)
315         sut._check_status()
316
317     @mock.patch("yardstick.ssh.SSH")
318     def test_traffic_runner(self, mock_ssh, *args):
319         mock_traffic_profile = mock.Mock(autospec=tp_base.TrafficProfile)
320         mock_traffic_profile.get_traffic_definition.return_value = "64"
321         mock_traffic_profile.params = self.TRAFFIC_PROFILE
322         # traffic_profile.ports is standardized on port_num
323         mock_traffic_profile.ports = [0, 1]
324
325         mock_ssh_instance = mock.Mock(autospec=mock_ssh.SSH)
326         mock_ssh_instance.execute.return_value = 0, "", ""
327         mock_ssh_instance.run.return_value = 0, "", ""
328
329         mock_ssh.from_node.return_value = mock_ssh_instance
330
331         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
332         vnfd["mgmt-interface"].update({
333             'tg-config': {
334                 "ixchassis": "1.1.1.1",
335                 "py_bin_path": "/root",
336             }
337         })
338
339         samples = {}
340         name = ''
341         for ifname in range(1):
342             name = "xe{}".format(ifname)
343             samples[name] = {
344                 "Rx_Rate_Kbps": 20,
345                 "Tx_Rate_Kbps": 20,
346                 "Rx_Rate_Mbps": 10,
347                 "Tx_Rate_Mbps": 10,
348                 "RxThroughput": 10,
349                 "TxThroughput": 10,
350                 "Valid_Frames_Rx": 1000,
351                 "Frames_Tx": 1000,
352                 "in_packets": 1000,
353                 "out_packets": 1000,
354             }
355
356         samples.update({"CurrentDropPercentage": 0.0})
357
358         last_res = [
359             0,
360             {
361                 "Rx_Rate_Kbps": [20, 20],
362                 "Tx_Rate_Kbps": [20, 20],
363                 "Rx_Rate_Mbps": [10, 10],
364                 "Tx_Rate_Mbps": [10, 10],
365                 "CurrentDropPercentage": [0, 0],
366                 "RxThroughput": [10, 10],
367                 "TxThroughput": [10, 10],
368                 "Frames_Tx": [1000, 1000],
369                 "in_packets": [1000, 1000],
370                 "Valid_Frames_Rx": [1000, 1000],
371                 "out_packets": [1000, 1000],
372             },
373         ]
374
375         mock_traffic_profile.execute_traffic.return_value = [
376             'Completed', samples]
377         mock_traffic_profile.get_drop_percentage.return_value = [
378             'Completed', samples]
379
380         sut = tg_rfc2544_ixia.IxiaTrafficGen(name, vnfd)
381         sut.vnf_port_pairs = [[[0], [1]]]
382         sut.tc_file_name = self._get_file_abspath(TEST_FILE_YAML)
383         sut.topology = ""
384
385         sut.ssh_helper = mock.Mock()
386         sut._traffic_process = mock.MagicMock()
387         sut.generate_port_pairs = mock.Mock()
388
389         sut._ixia_traffic_gen = mock.MagicMock()
390         sut._ixia_traffic_gen.ix_get_statistics.return_value = last_res
391
392         sut.resource_helper.client = mock.MagicMock()
393         sut.resource_helper.client_started = mock.MagicMock()
394         sut.resource_helper.client_started.value = 1
395         sut.resource_helper.rfc_helper.iteration.value = 11
396         sut.resource_helper._ix_scenario = mock.Mock()
397
398         sut.scenario_helper.scenario_cfg = {
399             'options': {
400                 'packetsize': 64,
401                 'traffic_type': 4,
402                 'rfc2544': {
403                     'allowed_drop_rate': '0.8 - 1',
404                     'latency': True
405                 },
406                 'vnf__1': {
407                     'rules': 'acl_1rule.yaml',
408                     'vnf_config': {
409                         'lb_config': 'SW',
410                         'lb_count': 1,
411                         'worker_config': '1C/1T',
412                         'worker_threads': 1,
413                     },
414                 },
415             },
416             'task_path': '/path/to/task'
417         }
418
419         @mock.patch.object(six.moves.builtins, 'open', create=True)
420         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.open',
421                     mock.mock_open(), create=True)
422         @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.LOG.exception')
423         def _traffic_runner(*args):
424             result = sut._traffic_runner(mock_traffic_profile)
425             self.assertIsNone(result)
426
427         _traffic_runner()
428
429
430 class TestIxiaBasicScenario(unittest.TestCase):
431     def setUp(self):
432         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
433         self.mock_IxNextgen = self._mock_IxNextgen.start()
434         self.context_cfg = mock.Mock()
435         self.ixia_cfg = mock.Mock()
436         self.scenario = tg_rfc2544_ixia.IxiaBasicScenario(self.mock_IxNextgen,
437                                                           self.context_cfg,
438                                                           self.ixia_cfg)
439         self.addCleanup(self._stop_mocks)
440
441     def _stop_mocks(self):
442         self._mock_IxNextgen.stop()
443
444     def test___init___(self):
445         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaBasicScenario)
446         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
447
448     def test_create_traffic_model(self):
449         self.mock_IxNextgen.get_vports.return_value = [1, 2, 3, 4]
450         self.scenario.create_traffic_model()
451         self.scenario.client.get_vports.assert_called_once()
452         self.scenario.client.create_traffic_model.assert_called_once_with([1, 3], [2, 4])
453
454     def test_apply_config(self):
455         self.assertIsNone(self.scenario.apply_config())
456
457     def test_run_protocols(self):
458         self.assertIsNone(self.scenario.run_protocols())
459
460     def test_stop_protocols(self):
461         self.assertIsNone(self.scenario.stop_protocols())
462
463
464 class TestIxiaL3Scenario(TestIxiaBasicScenario):
465     IXIA_CFG = {
466         'flow': {
467             'src_ip': ['192.168.0.1-192.168.0.50'],
468             'dst_ip': ['192.168.1.1-192.168.1.150']
469         }
470     }
471
472     CONTEXT_CFG = {
473         'nodes': {
474             'tg__0': {
475                 'role': 'IxNet',
476                 'interfaces': {
477                     'xe0': {
478                         'vld_id': 'uplink_0',
479                         'local_ip': '10.1.1.1',
480                         'local_mac': 'aa:bb:cc:dd:ee:ff',
481                         'ifname': 'xe0'
482                     },
483                     'xe1': {
484                         'vld_id': 'downlink_0',
485                         'local_ip': '20.2.2.2',
486                         'local_mac': 'bb:bb:cc:dd:ee:ee',
487                         'ifname': 'xe1'
488                     }
489                 },
490                 'routing_table': [{
491                     'network': "152.16.100.20",
492                     'netmask': '255.255.0.0',
493                     'gateway': '152.16.100.21',
494                     'if': 'xe0'
495                 }]
496             }
497         }
498     }
499
500     def setUp(self):
501         super(TestIxiaL3Scenario, self).setUp()
502         self.ixia_cfg = self.IXIA_CFG
503         self.context_cfg = self.CONTEXT_CFG
504         self.scenario = tg_rfc2544_ixia.IxiaL3Scenario(self.mock_IxNextgen,
505                                                        self.context_cfg,
506                                                        self.ixia_cfg)
507
508     def test___init___(self):
509         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaL3Scenario)
510         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
511
512     def test_create_traffic_model(self):
513         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
514         self.scenario.create_traffic_model()
515         self.scenario.client.get_vports.assert_called_once()
516         self.scenario.client.create_ipv4_traffic_model.\
517             assert_called_once_with(['1/protocols/static'],
518                                     ['2/protocols/static'])
519
520     def test_apply_config(self):
521         self.scenario._add_interfaces = mock.Mock()
522         self.scenario._add_static_ips = mock.Mock()
523         self.assertIsNone(self.scenario.apply_config())
524
525     def test__add_static(self):
526         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
527         self.mock_IxNextgen.get_static_interface.side_effect = ['intf1',
528                                                                 'intf2']
529
530         self.scenario._add_static_ips()
531
532         self.mock_IxNextgen.get_static_interface.assert_any_call('1')
533         self.mock_IxNextgen.get_static_interface.assert_any_call('2')
534
535         self.scenario.client.add_static_ipv4.assert_any_call(
536             'intf1', '1', '192.168.0.1', 49, '32')
537         self.scenario.client.add_static_ipv4.assert_any_call(
538             'intf2', '2', '192.168.1.1', 149, '32')
539
540     def test__add_interfaces(self):
541         self.mock_IxNextgen.get_vports.return_value = ['1', '2']
542
543         self.scenario._add_interfaces()
544
545         self.mock_IxNextgen.add_interface.assert_any_call('1',
546                                                           '10.1.1.1',
547                                                           'aa:bb:cc:dd:ee:ff',
548                                                           '152.16.100.21')
549         self.mock_IxNextgen.add_interface.assert_any_call('2',
550                                                           '20.2.2.2',
551                                                           'bb:bb:cc:dd:ee:ee',
552                                                           None)
553
554
555 class TestIxiaPppoeClientScenario(unittest.TestCase):
556
557     IXIA_CFG = {
558         'pppoe_client': {
559             'sessions_per_port': 4,
560             'sessions_per_svlan': 1,
561             's_vlan': 10,
562             'c_vlan': 20,
563             'ip': ['10.3.3.1', '10.4.4.1']
564         },
565         'ipv4_client': {
566             'sessions_per_port': 1,
567             'sessions_per_vlan': 1,
568             'vlan': 101,
569             'gateway_ip': ['10.1.1.1', '10.2.2.1'],
570             'ip': ['10.1.1.1', '10.2.2.1'],
571             'prefix': ['24', '24']
572         }
573     }
574
575     CONTEXT_CFG = {
576         'nodes': {'tg__0': {
577             'interfaces': {'xe0': {
578                 'local_ip': '10.1.1.1',
579                 'netmask': '255.255.255.0'
580                 }}}}}
581
582     def setUp(self):
583         self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
584         self.mock_IxNextgen = self._mock_IxNextgen.start()
585         self.scenario = tg_rfc2544_ixia.IxiaPppoeClientScenario(
586             self.mock_IxNextgen, self.CONTEXT_CFG, self.IXIA_CFG)
587         tg_rfc2544_ixia.WAIT_PROTOCOLS_STARTED = 2
588         self.addCleanup(self._stop_mocks)
589
590     def _stop_mocks(self):
591         self._mock_IxNextgen.stop()
592
593     def test___init___(self):
594         self.assertIsInstance(self.scenario, tg_rfc2544_ixia.IxiaPppoeClientScenario)
595         self.assertEqual(self.scenario.client, self.mock_IxNextgen)
596
597     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
598                        '_fill_ixia_config')
599     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
600                        '_apply_access_network_config')
601     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
602                        '_apply_core_network_config')
603     def test_apply_config(self, mock_apply_core_net_cfg,
604                           mock_apply_access_net_cfg,
605                           mock_fill_ixia_config):
606         self.mock_IxNextgen.get_vports.return_value = [1, 2, 3, 4]
607         self.scenario.apply_config()
608         self.scenario.client.get_vports.assert_called_once()
609         self.assertEqual(self.scenario._uplink_vports, [1, 3])
610         self.assertEqual(self.scenario._downlink_vports, [2, 4])
611         mock_fill_ixia_config.assert_called_once()
612         mock_apply_core_net_cfg.assert_called_once()
613         mock_apply_access_net_cfg.assert_called_once()
614
615     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
616                        '_get_endpoints_src_dst_id_pairs')
617     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
618                        '_get_endpoints_src_dst_obj_pairs')
619     def test_create_traffic_model(self, mock_obj_pairs, mock_id_pairs):
620         uplink_endpoints = ['group1', 'group2']
621         downlink_endpoints = ['group3', 'group3']
622         mock_id_pairs.return_value = ['xe0', 'xe1', 'xe0', 'xe1']
623         mock_obj_pairs.return_value = ['group1', 'group3', 'group2', 'group3']
624         mock_tp = mock.Mock()
625         mock_tp.full_profile = {'uplink_0': 'data',
626                                 'downlink_0': 'data',
627                                 'uplink_1': 'data',
628                                 'downlink_1': 'data'
629                                 }
630         self.scenario.create_traffic_model(mock_tp)
631         mock_id_pairs.assert_called_once_with(mock_tp.full_profile)
632         mock_obj_pairs.assert_called_once_with(['xe0', 'xe1', 'xe0', 'xe1'])
633         self.scenario.client.create_ipv4_traffic_model.assert_called_once_with(
634             uplink_endpoints, downlink_endpoints)
635
636     def test__get_endpoints_src_dst_id_pairs(self):
637         full_tp = OrderedDict([
638             ('uplink_0', {'ipv4': {'port': 'xe0'}}),
639             ('downlink_0', {'ipv4': {'port': 'xe1'}}),
640             ('uplink_1', {'ipv4': {'port': 'xe0'}}),
641             ('downlink_1', {'ipv4': {'port': 'xe3'}})])
642         endpoints_src_dst_pairs = ['xe0', 'xe1', 'xe0', 'xe3']
643         res = self.scenario._get_endpoints_src_dst_id_pairs(full_tp)
644         self.assertEqual(res, endpoints_src_dst_pairs)
645
646     def test__get_endpoints_src_dst_id_pairs_wrong_flows_number(self):
647         full_tp = OrderedDict([
648             ('uplink_0', {'ipv4': {'port': 'xe0'}}),
649             ('downlink_0', {'ipv4': {'port': 'xe1'}}),
650             ('uplink_1', {'ipv4': {'port': 'xe0'}})])
651         with self.assertRaises(RuntimeError):
652             self.scenario._get_endpoints_src_dst_id_pairs(full_tp)
653
654     def test__get_endpoints_src_dst_id_pairs_no_port_key(self):
655         full_tp = OrderedDict([
656             ('uplink_0', {'ipv4': {'id': 1}}),
657             ('downlink_0', {'ipv4': {'id': 2}})])
658         self.assertEqual(
659             self.scenario._get_endpoints_src_dst_id_pairs(full_tp), [])
660
661     def test__get_endpoints_src_dst_obj_pairs_tp_with_port_key(self):
662         endpoints_id_pairs = ['xe0', 'xe1',
663                               'xe0', 'xe1',
664                               'xe0', 'xe3',
665                               'xe0', 'xe3']
666         ixia_cfg = {
667             'pppoe_client': {
668                 'sessions_per_port': 4,
669                 'sessions_per_svlan': 1
670             },
671             'flow': {
672                 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}],
673                 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}]
674             }
675         }
676
677         expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1',
678                            'tp1_dg3', 'tp4_dg1', 'tp1_dg4', 'tp4_dg1']
679
680         self.scenario._ixia_cfg = ixia_cfg
681         self.scenario._access_topologies = ['topology1', 'topology2']
682         self.scenario._core_topologies = ['topology3', 'topology4']
683         self.mock_IxNextgen.get_topology_device_groups.side_effect = \
684             [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'],
685              ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'],
686              ['tp3_dg1'],
687              ['tp4_dg1']]
688         res = self.scenario._get_endpoints_src_dst_obj_pairs(
689             endpoints_id_pairs)
690         self.assertEqual(res, expected_result)
691
692     def test__get_endpoints_src_dst_obj_pairs_default_flows_mapping(self):
693         endpoints_id_pairs = []
694         ixia_cfg = {
695             'pppoe_client': {
696                 'sessions_per_port': 4,
697                 'sessions_per_svlan': 1
698             },
699             'flow': {
700                 'src_ip': [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}],
701                 'dst_ip': [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}]
702             }
703         }
704
705         expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1',
706                            'tp1_dg3', 'tp3_dg1', 'tp1_dg4', 'tp3_dg1',
707                            'tp2_dg1', 'tp4_dg1', 'tp2_dg2', 'tp4_dg1',
708                            'tp2_dg3', 'tp4_dg1', 'tp2_dg4', 'tp4_dg1']
709
710         self.scenario._ixia_cfg = ixia_cfg
711         self.scenario._access_topologies = ['topology1', 'topology2']
712         self.scenario._core_topologies = ['topology3', 'topology4']
713         self.mock_IxNextgen.get_topology_device_groups.side_effect = \
714             [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'],
715              ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'],
716              ['tp3_dg1'],
717              ['tp4_dg1']]
718         res = self.scenario._get_endpoints_src_dst_obj_pairs(
719             endpoints_id_pairs)
720         self.assertEqual(res, expected_result)
721
722     def test_run_protocols(self):
723         self.scenario.client.is_protocols_running.return_value = True
724         self.scenario.run_protocols()
725         self.scenario.client.start_protocols.assert_called_once()
726
727     def test_run_protocols_timeout_exception(self):
728         self.scenario.client.is_protocols_running.return_value = False
729         with self.assertRaises(exceptions.WaitTimeout):
730             self.scenario.run_protocols()
731         self.scenario.client.start_protocols.assert_called_once()
732
733     def test_stop_protocols(self):
734         self.scenario.stop_protocols()
735         self.scenario.client.stop_protocols.assert_called_once()
736
737     def test__get_intf_addr_str_type_input(self):
738         intf = '192.168.10.2/24'
739         ip, mask = self.scenario._get_intf_addr(intf)
740         self.assertEqual(ip, '192.168.10.2')
741         self.assertEqual(mask, 24)
742
743     def test__get_intf_addr_dict_type_input(self):
744         intf = {'tg__0': 'xe0'}
745         ip, mask = self.scenario._get_intf_addr(intf)
746         self.assertEqual(ip, '10.1.1.1')
747         self.assertEqual(mask, 24)
748
749     @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario, '_get_intf_addr')
750     def test__fill_ixia_config(self, mock_get_intf_addr):
751
752         ixia_cfg = {
753             'pppoe_client': {
754                 'sessions_per_port': 4,
755                 'sessions_per_svlan': 1,
756                 's_vlan': 10,
757                 'c_vlan': 20,
758                 'ip': ['10.3.3.1/24', '10.4.4.1/24']
759             },
760             'ipv4_client': {
761                 'sessions_per_port': 1,
762                 'sessions_per_vlan': 1,
763                 'vlan': 101,
764                 'gateway_ip': ['10.1.1.1/24', '10.2.2.1/24'],
765                 'ip': ['10.1.1.1/24', '10.2.2.1/24']
766             }
767         }
768
769         mock_get_intf_addr.side_effect = [
770             ('10.3.3.1', '24'),
771             ('10.4.4.1', '24'),
772             ('10.1.1.1', '24'),
773             ('10.2.2.1', '24'),
774             ('10.1.1.1', '24'),
775             ('10.2.2.1', '24')
776         ]
777         self.scenario._ixia_cfg = ixia_cfg
778         self.scenario._fill_ixia_config()
779         self.assertEqual(mock_get_intf_addr.call_count, 6)
780         self.assertEqual(self.scenario._ixia_cfg['pppoe_client']['ip'],
781                          ['10.3.3.1', '10.4.4.1'])
782         self.assertEqual(self.scenario._ixia_cfg['ipv4_client']['ip'],
783                          ['10.1.1.1', '10.2.2.1'])
784         self.assertEqual(self.scenario._ixia_cfg['ipv4_client']['prefix'],
785                          ['24', '24'])
786
787     @mock.patch('yardstick.network_services.libs.ixia_libs.ixnet.ixnet_api.Vlan')
788     def test__apply_access_network_config_pap_auth(self, mock_vlan):
789         _ixia_cfg = {
790             'pppoe_client': {
791                 'sessions_per_port': 4,
792                 'sessions_per_svlan': 1,
793                 's_vlan': 10,
794                 'c_vlan': 20,
795                 'pap_user': 'test_pap',
796                 'pap_password': 'pap'
797                 }}
798         pap_user = _ixia_cfg['pppoe_client']['pap_user']
799         pap_passwd = _ixia_cfg['pppoe_client']['pap_password']
800         self.scenario._ixia_cfg = _ixia_cfg
801         self.scenario._uplink_vports = [0, 2]
802         self.scenario.client.add_topology.side_effect = ['Topology 1', 'Topology 2']
803         self.scenario.client.add_device_group.side_effect = ['Dg1', 'Dg2', 'Dg3',
804                                                              'Dg4', 'Dg5', 'Dg6',
805                                                              'Dg7', 'Dg8']
806         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2', 'Eth3',
807                                                          'Eth4', 'Eth5', 'Eth6',
808                                                          'Eth7', 'Eth8']
809         self.scenario._apply_access_network_config()
810         self.assertEqual(self.scenario.client.add_topology.call_count, 2)
811         self.assertEqual(self.scenario.client.add_device_group.call_count, 8)
812         self.assertEqual(self.scenario.client.add_ethernet.call_count, 8)
813         self.assertEqual(mock_vlan.call_count, 16)
814         self.assertEqual(self.scenario.client.add_vlans.call_count, 8)
815         self.assertEqual(self.scenario.client.add_pppox_client.call_count, 8)
816         self.scenario.client.add_topology.assert_has_calls([
817             mock.call('Topology access 0', 0),
818             mock.call('Topology access 1', 2)
819         ])
820         self.scenario.client.add_device_group.assert_has_calls([
821             mock.call('Topology 1', 'SVLAN 10', 1),
822             mock.call('Topology 1', 'SVLAN 11', 1),
823             mock.call('Topology 1', 'SVLAN 12', 1),
824             mock.call('Topology 1', 'SVLAN 13', 1),
825             mock.call('Topology 2', 'SVLAN 14', 1),
826             mock.call('Topology 2', 'SVLAN 15', 1),
827             mock.call('Topology 2', 'SVLAN 16', 1),
828             mock.call('Topology 2', 'SVLAN 17', 1)
829         ])
830         self.scenario.client.add_ethernet.assert_has_calls([
831             mock.call('Dg1', 'Ethernet'),
832             mock.call('Dg2', 'Ethernet'),
833             mock.call('Dg3', 'Ethernet'),
834             mock.call('Dg4', 'Ethernet'),
835             mock.call('Dg5', 'Ethernet'),
836             mock.call('Dg6', 'Ethernet'),
837             mock.call('Dg7', 'Ethernet'),
838             mock.call('Dg8', 'Ethernet')
839         ])
840         mock_vlan.assert_has_calls([
841             mock.call(vlan_id=10),
842             mock.call(vlan_id=20, vlan_id_step=1),
843             mock.call(vlan_id=11),
844             mock.call(vlan_id=20, vlan_id_step=1),
845             mock.call(vlan_id=12),
846             mock.call(vlan_id=20, vlan_id_step=1),
847             mock.call(vlan_id=13),
848             mock.call(vlan_id=20, vlan_id_step=1),
849             mock.call(vlan_id=14),
850             mock.call(vlan_id=20, vlan_id_step=1),
851             mock.call(vlan_id=15),
852             mock.call(vlan_id=20, vlan_id_step=1),
853             mock.call(vlan_id=16),
854             mock.call(vlan_id=20, vlan_id_step=1),
855             mock.call(vlan_id=17),
856             mock.call(vlan_id=20, vlan_id_step=1)
857         ])
858         self.scenario.client.add_pppox_client.assert_has_calls([
859             mock.call('Eth1', 'pap', pap_user, pap_passwd),
860             mock.call('Eth2', 'pap', pap_user, pap_passwd),
861             mock.call('Eth3', 'pap', pap_user, pap_passwd),
862             mock.call('Eth4', 'pap', pap_user, pap_passwd),
863             mock.call('Eth5', 'pap', pap_user, pap_passwd),
864             mock.call('Eth6', 'pap', pap_user, pap_passwd),
865             mock.call('Eth7', 'pap', pap_user, pap_passwd),
866             mock.call('Eth8', 'pap', pap_user, pap_passwd)
867         ])
868
869     def test__apply_access_network_config_chap_auth(self):
870         _ixia_cfg = {
871             'pppoe_client': {
872                 'sessions_per_port': 4,
873                 'sessions_per_svlan': 1,
874                 's_vlan': 10,
875                 'c_vlan': 20,
876                 'chap_user': 'test_chap',
877                 'chap_password': 'chap'
878             }}
879         chap_user = _ixia_cfg['pppoe_client']['chap_user']
880         chap_passwd = _ixia_cfg['pppoe_client']['chap_password']
881         self.scenario._ixia_cfg = _ixia_cfg
882         self.scenario._uplink_vports = [0, 2]
883         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2', 'Eth3',
884                                                          'Eth4', 'Eth5', 'Eth6',
885                                                          'Eth7', 'Eth8']
886         self.scenario._apply_access_network_config()
887         self.assertEqual(self.scenario.client.add_pppox_client.call_count, 8)
888         self.scenario.client.add_pppox_client.assert_has_calls([
889             mock.call('Eth1', 'chap', chap_user, chap_passwd),
890             mock.call('Eth2', 'chap', chap_user, chap_passwd),
891             mock.call('Eth3', 'chap', chap_user, chap_passwd),
892             mock.call('Eth4', 'chap', chap_user, chap_passwd),
893             mock.call('Eth5', 'chap', chap_user, chap_passwd),
894             mock.call('Eth6', 'chap', chap_user, chap_passwd),
895             mock.call('Eth7', 'chap', chap_user, chap_passwd),
896             mock.call('Eth8', 'chap', chap_user, chap_passwd)
897         ])
898
899     @mock.patch('yardstick.network_services.libs.ixia_libs.ixnet.ixnet_api.Vlan')
900     def test__apply_core_network_config_no_bgp_proto(self, mock_vlan):
901         self.scenario._downlink_vports = [1, 3]
902         self.scenario.client.add_topology.side_effect = ['Topology 1', 'Topology 2']
903         self.scenario.client.add_device_group.side_effect = ['Dg1', 'Dg2']
904         self.scenario.client.add_ethernet.side_effect = ['Eth1', 'Eth2']
905         self.scenario._apply_core_network_config()
906         self.assertEqual(self.scenario.client.add_topology.call_count, 2)
907         self.assertEqual(self.scenario.client.add_device_group.call_count, 2)
908         self.assertEqual(self.scenario.client.add_ethernet.call_count, 2)
909         self.assertEqual(mock_vlan.call_count, 2)
910         self.assertEqual(self.scenario.client.add_vlans.call_count, 2)
911         self.assertEqual(self.scenario.client.add_ipv4.call_count, 2)
912         self.scenario.client.add_topology.assert_has_calls([
913             mock.call('Topology core 0', 1),
914             mock.call('Topology core 1', 3)
915         ])
916         self.scenario.client.add_device_group.assert_has_calls([
917             mock.call('Topology 1', 'Core port 0', 1),
918             mock.call('Topology 2', 'Core port 1', 1)
919         ])
920         self.scenario.client.add_ethernet.assert_has_calls([
921             mock.call('Dg1', 'Ethernet'),
922             mock.call('Dg2', 'Ethernet')
923         ])
924         mock_vlan.assert_has_calls([
925             mock.call(vlan_id=101),
926             mock.call(vlan_id=102)
927         ])
928         self.scenario.client.add_ipv4.assert_has_calls([
929             mock.call('Eth1', name='ipv4', addr=ipaddress.IPv4Address('10.1.1.2'),
930                       addr_step='0.0.0.1', prefix='24', gateway='10.1.1.1'),
931             mock.call('Eth2', name='ipv4', addr=ipaddress.IPv4Address('10.2.2.2'),
932                       addr_step='0.0.0.1', prefix='24', gateway='10.2.2.1')
933         ])
934         self.scenario.client.add_bgp.assert_not_called()
935
936     def test__apply_core_network_config_with_bgp_proto(self):
937         bgp_params = {
938             'bgp': {
939                 'bgp_type': 'external',
940                 'dut_ip': '10.0.0.1',
941                 'as_number': 65000
942             }
943         }
944         self.scenario._ixia_cfg['ipv4_client'].update(bgp_params)
945         self.scenario._downlink_vports = [1, 3]
946         self.scenario.client.add_ipv4.side_effect = ['ipv4_1', 'ipv4_2']
947         self.scenario._apply_core_network_config()
948         self.assertEqual(self.scenario.client.add_bgp.call_count, 2)
949         self.scenario.client.add_bgp.assert_has_calls([
950             mock.call('ipv4_1', dut_ip=bgp_params["bgp"]["dut_ip"],
951                       local_as=bgp_params["bgp"]["as_number"],
952                       bgp_type=bgp_params["bgp"]["bgp_type"]),
953             mock.call('ipv4_2', dut_ip=bgp_params["bgp"]["dut_ip"],
954                       local_as=bgp_params["bgp"]["as_number"],
955                       bgp_type=bgp_params["bgp"]["bgp_type"])
956         ])