Merge "[docs] Fix docs {un,}indent warnings in Testcase definitions"
[yardstick.git] / yardstick / tests / unit / network_services / libs / ixia_libs / test_ixnet_api.py
1 # Copyright (c) 2018 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 mock
16 import IxNetwork
17 import unittest
18
19 from copy import deepcopy
20
21 from yardstick.common import exceptions
22 from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
23
24
25 UPLINK = 'uplink'
26 DOWNLINK = 'downlink'
27
28 TRAFFIC_PARAMETERS = {
29     UPLINK: {
30         'id': 1,
31         'bidir': 'False',
32         'duration': 60,
33         'rate': 10000.5,
34         'rate_unit': 'fps',
35         'outer_l2': {
36             'framesize': {'64B': '25', '256B': '75'},
37             'QinQ': None
38         },
39         'outer_l3': {
40             'count': 512,
41             'srcseed': 10,
42             'dstseed': 20,
43             'dscp': 0,
44             'proto': 'udp',
45             'ttl': 32,
46             'dstip': '152.16.40.20',
47             'srcip': '152.16.100.20',
48             'dstmask': 24,
49             'srcmask': 24
50         },
51         'outer_l4': {
52             'seed': 1,
53             'count': 1,
54             'dstport': 2001,
55             'srcport': 1234,
56             'srcportmask': 0,
57             'dstportmask': 0
58         },
59         'traffic_type': 'continuous'
60     },
61     DOWNLINK: {
62         'id': 2,
63         'bidir': 'False',
64         'duration': 60,
65         'rate': 75.2,
66         'rate_unit': '%',
67         'outer_l2': {
68             'framesize': {'128B': '35', '1024B': '65'},
69             'QinQ': None
70         },
71         'outer_l3': {
72             'count': 1024,
73             'srcseed': 30,
74             'dstseed': 40,
75             'dscp': 0,
76             'proto': 'udp',
77             'ttl': 32,
78             'dstip': '2001::10',
79             'srcip': '2021::10',
80             'dstmask': 64,
81             'srcmask': 64
82         },
83         'outer_l4': {
84             'seed': 1,
85             'count': 1,
86             'dstport': 1234,
87             'srcport': 2001,
88             'srcportmask': 0,
89             'dstportmask': 0
90         },
91         'traffic_type': 'continuous'
92     }
93 }
94
95
96 class TestIxNextgen(unittest.TestCase):
97
98     def setUp(self):
99         self.ixnet = mock.Mock()
100         self.ixnet.execute = mock.Mock()
101         self.ixnet.getRoot.return_value = 'my_root'
102         self.ixnet_gen = ixnet_api.IxNextgen()
103         self.ixnet_gen._ixnet = self.ixnet
104
105     def test_get_config(self):
106         tg_cfg = {
107             'vdu': [
108                 {
109                     'external-interface': [
110                         {'virtual-interface': {'vpci': '0000:07:00.1'}},
111                         {'virtual-interface': {'vpci': '0001:08:01.2'}}
112                     ]
113                 },
114             ],
115             'mgmt-interface': {
116                 'ip': 'test1',
117                 'tg-config': {
118                     'dut_result_dir': 'test2',
119                     'version': 'test3',
120                     'ixchassis': 'test4',
121                     'tcl_port': 'test5',
122                 },
123             }
124         }
125
126         expected = {
127             'machine': 'test1',
128             'port': 'test5',
129             'chassis': 'test4',
130             'cards': ['0000', '0001'],
131             'ports': ['07', '08'],
132             'output_dir': 'test2',
133             'version': 'test3',
134             'bidir': True,
135         }
136
137         result = ixnet_api.IxNextgen.get_config(tg_cfg)
138         self.assertEqual(result, expected)
139
140     def test__get_config_element_by_flow_group_name(self):
141         self.ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
142                                                      ['fg_01']]
143         self.ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_01'
144         output = self.ixnet_gen._get_config_element_by_flow_group_name(
145             'flow_group_01')
146         self.assertEqual('traffic_item/configElement:flow_group_01', output)
147
148     def test__get_config_element_by_flow_group_name_no_match(self):
149         self.ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
150                                                      ['fg_01']]
151         self.ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_02'
152         output = self.ixnet_gen._get_config_element_by_flow_group_name(
153             'flow_group_01')
154         self.assertIsNone(output)
155
156     def test__get_stack_item(self):
157         self.ixnet_gen._ixnet.getList.return_value = ['tcp1', 'tcp2', 'udp']
158         with mock.patch.object(
159                 self.ixnet_gen, '_get_config_element_by_flow_group_name') as \
160                 mock_get_cfg_element:
161             mock_get_cfg_element.return_value = 'cfg_element'
162             output = self.ixnet_gen._get_stack_item(mock.ANY, ixnet_api.PROTO_TCP)
163         self.assertEqual(['tcp1', 'tcp2'], output)
164
165     def test__get_stack_item_no_config_element(self):
166         with mock.patch.object(
167                 self.ixnet_gen, '_get_config_element_by_flow_group_name',
168                 return_value=None):
169             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
170                 self.ixnet_gen._get_stack_item(mock.ANY, mock.ANY)
171
172     def test__get_field_in_stack_item(self):
173         self.ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
174         output = self.ixnet_gen._get_field_in_stack_item(mock.ANY, 'field2')
175         self.assertEqual('field2', output)
176
177     def test__get_field_in_stack_item_no_field_present(self):
178         self.ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
179         with self.assertRaises(exceptions.IxNetworkFieldNotPresentInStackItem):
180             self.ixnet_gen._get_field_in_stack_item(mock.ANY, 'field3')
181
182     def test__parse_framesize(self):
183         framesize = {'64B': '75', '512b': '25'}
184         output = self.ixnet_gen._parse_framesize(framesize)
185         self.assertEqual(2, len(output))
186         self.assertIn([64, 64, 75], output)
187         self.assertIn([512, 512, 25], output)
188
189     def test_add_topology(self):
190         self.ixnet_gen.ixnet.add.return_value = 'obj'
191         self.ixnet_gen.add_topology('topology 1', 'vports')
192         self.ixnet_gen.ixnet.add.assert_called_once_with('my_root', 'topology')
193         self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
194             'obj', '-name', 'topology 1', '-vports', 'vports')
195         self.ixnet_gen.ixnet.commit.assert_called_once()
196
197     def test_add_device_group(self):
198         self.ixnet_gen.ixnet.add.return_value = 'obj'
199         self.ixnet_gen.add_device_group('topology', 'device group 1', '1')
200         self.ixnet_gen.ixnet.add.assert_called_once_with('topology',
201                                                          'deviceGroup')
202         self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
203             'obj', '-name', 'device group 1', '-multiplier', '1')
204         self.ixnet_gen.ixnet.commit.assert_called_once()
205
206     def test_add_ethernet(self):
207         self.ixnet_gen.ixnet.add.return_value = 'obj'
208         self.ixnet_gen.add_ethernet('device_group', 'ethernet 1')
209         self.ixnet_gen.ixnet.add.assert_called_once_with('device_group',
210                                                          'ethernet')
211         self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
212             'obj', '-name', 'ethernet 1')
213         self.ixnet_gen.ixnet.commit.assert_called_once()
214
215     def test_add_vlans_single(self):
216         obj = 'ethernet'
217         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
218         self.ixnet_gen.ixnet.getList.return_value = ['vlan1', 'vlan2']
219         vlan1 = ixnet_api.Vlan(vlan_id=100, tp_id='ethertype88a8', prio=2)
220         vlan2 = ixnet_api.Vlan(vlan_id=101, tp_id='ethertype88a8', prio=3)
221         self.ixnet_gen.add_vlans(obj, [vlan1, vlan2])
222         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('ethernet',
223                                                                '-vlanCount', 2)
224         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('attr/singleValue',
225                                                                '-value', 100)
226         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('attr/singleValue',
227                                                                '-value', 101)
228         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('attr/singleValue',
229                                                                '-value', 2)
230         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('attr/singleValue',
231                                                                '-value', 3)
232         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
233             'attr/singleValue', '-value', 'ethertype88a8')
234         self.assertEqual(self.ixnet.commit.call_count, 2)
235
236     def test_add_vlans_increment(self):
237         obj = 'ethernet'
238         self.ixnet_gen.ixnet.add.return_value = 'obj'
239         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
240         self.ixnet_gen.ixnet.getList.return_value = ['vlan1']
241         vlan = ixnet_api.Vlan(vlan_id=100, vlan_id_step=1, prio=3, prio_step=2)
242         self.ixnet_gen.add_vlans(obj, [vlan])
243         self.ixnet.setMultiAttribute.assert_any_call('obj', '-start', 100,
244                                                      '-step', 1,
245                                                      '-direction', 'increment')
246         self.ixnet.setMultiAttribute.assert_any_call('obj', '-start', 3,
247                                                      '-step', 2,
248                                                      '-direction', 'increment')
249
250         self.assertEqual(self.ixnet.commit.call_count, 2)
251
252     def test_add_vlans_invalid(self):
253         vlans = []
254         self.assertRaises(RuntimeError, self.ixnet_gen.add_vlans, 'obj', vlans)
255
256     def test_add_ipv4(self):
257         self.ixnet_gen.ixnet.add.return_value = 'obj'
258         self.ixnet_gen.add_ipv4('ethernet 1', name='ipv4 1')
259         self.ixnet_gen.ixnet.add.assert_called_once_with('ethernet 1', 'ipv4')
260         self.ixnet_gen.ixnet.setAttribute.assert_called_once_with('obj',
261                                                                   '-name',
262                                                                   'ipv4 1')
263         self.assertEqual(self.ixnet.commit.call_count, 2)
264
265     def test_add_ipv4_single(self):
266         self.ixnet_gen.ixnet.add.return_value = 'obj'
267         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
268         self.ixnet_gen.add_ipv4('ethernet 1', name='ipv4 1', addr='100.1.1.100',
269                                 prefix='24', gateway='100.1.1.200')
270         self.ixnet_gen.ixnet.add.assert_called_once_with('ethernet 1', 'ipv4')
271         self.ixnet_gen.ixnet.setAttribute.assert_called_once_with('obj',
272                                                                   '-name',
273                                                                   'ipv4 1')
274         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
275             'attr/singleValue', '-value', '100.1.1.100')
276         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
277             'attr/singleValue', '-value', '24')
278         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
279             'attr/singleValue', '-value', '100.1.1.200')
280
281         self.assertEqual(self.ixnet.commit.call_count, 2)
282
283     def test_add_ipv4_counter(self):
284         self.ixnet_gen.ixnet.add.return_value = 'obj'
285         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
286         self.ixnet_gen.add_ipv4('ethernet 1', name='ipv4 1',
287                                 addr='100.1.1.100',
288                                 addr_step='1',
289                                 addr_direction='increment',
290                                 prefix='24',
291                                 gateway='100.1.1.200',
292                                 gw_step='1',
293                                 gw_direction='increment')
294         self.ixnet_gen.ixnet.add.assert_any_call('ethernet 1', 'ipv4')
295         self.ixnet_gen.ixnet.setAttribute.assert_called_once_with('obj',
296                                                                   '-name',
297                                                                   'ipv4 1')
298         self.ixnet_gen.ixnet.add.assert_any_call('attr', 'counter')
299         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('obj', '-start',
300                                                                '100.1.1.100',
301                                                                '-step', '1',
302                                                                '-direction',
303                                                                'increment')
304         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
305             'attr/singleValue', '-value', '24')
306         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call('obj', '-start',
307                                                                '100.1.1.200',
308                                                                '-step', '1',
309                                                                '-direction',
310                                                                'increment')
311         self.assertEqual(self.ixnet.commit.call_count, 2)
312
313     def test_add_pppox_client(self):
314         self.ixnet_gen.ixnet.add.return_value = 'obj'
315         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
316         self.ixnet_gen.add_pppox_client('ethernet 1', 'pap', 'user', 'pwd')
317         self.ixnet_gen.ixnet.add.assert_called_once_with('ethernet 1',
318                                                          'pppoxclient')
319
320         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
321             'attr/singleValue', '-value', 'pap')
322         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
323             'attr/singleValue', '-value', 'user')
324         self.ixnet_gen.ixnet.setMultiAttribute.assert_any_call(
325             'attr/singleValue', '-value', 'pwd')
326
327         self.assertEqual(self.ixnet.commit.call_count, 2)
328
329     def test_add_pppox_client_invalid_auth(self):
330         self.ixnet_gen.ixnet.add.return_value = 'obj'
331         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
332         self.assertRaises(NotImplementedError, self.ixnet_gen.add_pppox_client,
333                           'ethernet 1', 'invalid_auth', 'user', 'pwd')
334
335         self.ixnet_gen.ixnet.setMultiAttribute.assert_not_called()
336
337     def test_add_bgp(self):
338         self.ixnet_gen.ixnet.add.return_value = 'obj'
339         self.ixnet_gen.ixnet.getAttribute.return_value = 'attr'
340         self.ixnet_gen.add_bgp(ipv4='ipv4 1',
341                                dut_ip='10.0.0.1',
342                                local_as=65000,
343                                bgp_type='external')
344         self.ixnet_gen.ixnet.add.assert_called_once_with('ipv4 1', 'bgpIpv4Peer')
345         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
346             'attr/singleValue', '-value', '10.0.0.1')
347         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
348             'attr/singleValue', '-value', 65000)
349         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
350             'attr/singleValue', '-value', 'external')
351
352     @mock.patch.object(IxNetwork, 'IxNet')
353     def test_connect(self, mock_ixnet):
354         mock_ixnet.return_value = self.ixnet
355         with mock.patch.object(self.ixnet_gen, 'get_config') as mock_config:
356             mock_config.return_value = {'machine': 'machine_fake',
357                                         'port': 'port_fake',
358                                         'version': 12345}
359             self.ixnet_gen.connect(mock.ANY)
360
361         self.ixnet.connect.assert_called_once_with(
362             'machine_fake', '-port', 'port_fake', '-version', '12345')
363         mock_config.assert_called_once()
364
365     def test_connect_invalid_config_no_machine(self):
366         self.ixnet_gen.get_config = mock.Mock(return_value={
367             'port': 'port_fake',
368             'version': '12345'})
369         self.assertRaises(KeyError, self.ixnet_gen.connect, mock.ANY)
370         self.ixnet.connect.assert_not_called()
371
372     def test_connect_invalid_config_no_port(self):
373         self.ixnet_gen.get_config = mock.Mock(return_value={
374             'machine': 'machine_fake',
375             'version': '12345'})
376         self.assertRaises(KeyError, self.ixnet_gen.connect, mock.ANY)
377         self.ixnet.connect.assert_not_called()
378
379     def test_connect_invalid_config_no_version(self):
380         self.ixnet_gen.get_config = mock.Mock(return_value={
381             'machine': 'machine_fake',
382             'port': 'port_fake'})
383         self.assertRaises(KeyError, self.ixnet_gen.connect, mock.ANY)
384         self.ixnet.connect.assert_not_called()
385
386     def test_connect_no_config(self):
387         self.ixnet_gen.get_config = mock.Mock(return_value={})
388         self.assertRaises(KeyError, self.ixnet_gen.connect, mock.ANY)
389         self.ixnet.connect.assert_not_called()
390
391     def test_clear_config(self):
392         self.ixnet_gen.clear_config()
393         self.ixnet.execute.assert_called_once_with('newConfig')
394
395     @mock.patch.object(ixnet_api, 'log')
396     def test_assign_ports_2_ports(self, *args):
397         self.ixnet.getAttribute.side_effect = ['up', 'down']
398         config = {
399             'chassis': '1.1.1.1',
400             'cards': ['1', '2'],
401             'ports': ['2', '2']}
402         self.ixnet_gen._cfg = config
403
404         self.assertIsNone(self.ixnet_gen.assign_ports())
405         self.assertEqual(self.ixnet.execute.call_count, 1)
406         self.assertEqual(self.ixnet.commit.call_count, 3)
407         self.assertEqual(self.ixnet.getAttribute.call_count, 2)
408
409     @mock.patch.object(ixnet_api, 'log')
410     def test_assign_ports_port_down(self, mock_log):
411         self.ixnet.getAttribute.return_value = 'down'
412         config = {
413             'chassis': '1.1.1.1',
414             'cards': ['1', '2'],
415             'ports': ['3', '4']}
416         self.ixnet_gen._cfg = config
417         self.ixnet_gen.assign_ports()
418         mock_log.warning.assert_called()
419
420     def test_assign_ports_no_config(self):
421         self.ixnet_gen._cfg = {}
422         self.assertRaises(KeyError, self.ixnet_gen.assign_ports)
423
424     def test__create_traffic_item(self):
425         self.ixnet.add.return_value = 'my_new_traffic_item'
426         self.ixnet.remapIds.return_value = ['my_traffic_item_id']
427
428         self.ixnet_gen._create_traffic_item()
429         self.ixnet.add.assert_called_once_with(
430             'my_root/traffic', 'trafficItem')
431         self.ixnet.setMultiAttribute.assert_called_once_with(
432             'my_new_traffic_item', '-name', 'RFC2544', '-trafficType', 'raw')
433         self.assertEqual(2, self.ixnet.commit.call_count)
434         self.ixnet.remapIds.assert_called_once_with('my_new_traffic_item')
435         self.ixnet.setAttribute('my_traffic_item_id/tracking',
436                                 '-trackBy', 'trafficGroupId0')
437
438     def test__create_flow_groups(self):
439         uplink_endpoints = ['up_endp1', 'up_endp2']
440         downlink_endpoints = ['down_endp1', 'down_endp2']
441         self.ixnet_gen.ixnet.getList.side_effect = [['traffic_item'], ['1', '2']]
442         self.ixnet_gen.ixnet.add.side_effect = ['endp1', 'endp2', 'endp3',
443                                                 'endp4']
444         self.ixnet_gen._create_flow_groups(uplink_endpoints, downlink_endpoints)
445         self.ixnet_gen.ixnet.add.assert_has_calls([
446             mock.call('traffic_item', 'endpointSet'),
447             mock.call('traffic_item', 'endpointSet')])
448         self.ixnet_gen.ixnet.setMultiAttribute.assert_has_calls([
449             mock.call('endp1', '-name', '1', '-sources', ['up_endp1'],
450                       '-destinations', ['down_endp1']),
451             mock.call('endp2', '-name', '2', '-sources', ['down_endp1'],
452                       '-destinations', ['up_endp1']),
453             mock.call('endp3', '-name', '3', '-sources', ['up_endp2'],
454                       '-destinations', ['down_endp2']),
455             mock.call('endp4', '-name', '4', '-sources', ['down_endp2'],
456                       '-destinations', ['up_endp2'])])
457
458     def test__append_protocol_to_stack(self):
459
460         self.ixnet_gen._append_procotol_to_stack('my_protocol', 'prev_element')
461         self.ixnet.execute.assert_called_with(
462             'append', 'prev_element',
463             'my_root/traffic/protocolTemplate:"my_protocol"')
464
465     def test__setup_config_elements(self):
466         self.ixnet_gen.ixnet.getList.side_effect = [['traffic_item'],
467                                                ['cfg_element']]
468         with mock.patch.object(self.ixnet_gen, '_append_procotol_to_stack') as \
469                 mock_append_proto:
470             self.ixnet_gen._setup_config_elements()
471         mock_append_proto.assert_has_calls([
472             mock.call(ixnet_api.PROTO_UDP, 'cfg_element/stack:"ethernet-1"'),
473             mock.call(ixnet_api.PROTO_IPV4, 'cfg_element/stack:"ethernet-1"')])
474         self.ixnet_gen.ixnet.setAttribute.assert_has_calls([
475             mock.call('cfg_element/frameRateDistribution', '-portDistribution',
476                       'splitRateEvenly'),
477             mock.call('cfg_element/frameRateDistribution',
478                       '-streamDistribution', 'splitRateEvenly')])
479
480     @mock.patch.object(ixnet_api.IxNextgen, '_create_traffic_item')
481     @mock.patch.object(ixnet_api.IxNextgen, '_create_flow_groups')
482     @mock.patch.object(ixnet_api.IxNextgen, '_setup_config_elements')
483     def test_create_traffic_model(self, mock__setup_config_elements,
484                                   mock__create_flow_groups,
485                                   mock__create_traffic_item):
486         uplink_ports = ['port1', 'port3']
487         downlink_ports = ['port2', 'port4']
488         uplink_endpoints = ['port1/protocols', 'port3/protocols']
489         downlink_endpoints = ['port2/protocols', 'port4/protocols']
490         self.ixnet_gen.create_traffic_model(uplink_ports, downlink_ports)
491         mock__create_traffic_item.assert_called_once_with('raw')
492         mock__create_flow_groups.assert_called_once_with(uplink_endpoints,
493                                                          downlink_endpoints)
494         mock__setup_config_elements.assert_called_once()
495
496     @mock.patch.object(ixnet_api.IxNextgen, '_create_traffic_item')
497     @mock.patch.object(ixnet_api.IxNextgen, '_create_flow_groups')
498     @mock.patch.object(ixnet_api.IxNextgen, '_setup_config_elements')
499     def test_create_ipv4_traffic_model(self, mock__setup_config_elements,
500                                        mock__create_flow_groups,
501                                        mock__create_traffic_item):
502         uplink_topologies = ['up1', 'up3']
503         downlink_topologies = ['down2', 'down4']
504         self.ixnet_gen.create_ipv4_traffic_model(uplink_topologies,
505                                                  downlink_topologies)
506         mock__create_traffic_item.assert_called_once_with('ipv4')
507         mock__create_flow_groups.assert_called_once_with(uplink_topologies,
508                                                          downlink_topologies)
509         mock__setup_config_elements.assert_called_once_with(False)
510
511     def test__update_frame_mac(self):
512         with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item') as \
513                 mock_get_field:
514             mock_get_field.return_value = 'field_descriptor'
515             self.ixnet_gen._update_frame_mac('ethernet_descriptor', 'field', 'mac')
516         mock_get_field.assert_called_once_with('ethernet_descriptor', 'field')
517         self.ixnet_gen.ixnet.setMultiAttribute(
518             'field_descriptor', '-singleValue', 'mac', '-fieldValue', 'mac',
519             '-valueType', 'singleValue')
520         self.ixnet_gen.ixnet.commit.assert_called_once()
521
522     def test_update_frame(self):
523         with mock.patch.object(
524                 self.ixnet_gen, '_get_config_element_by_flow_group_name',
525                 return_value='cfg_element'), \
526                 mock.patch.object(self.ixnet_gen, '_update_frame_mac') as \
527                 mock_update_frame, \
528                 mock.patch.object(self.ixnet_gen, '_get_stack_item') as \
529                 mock_get_stack_item:
530             mock_get_stack_item.side_effect = [['item1'], ['item2'],
531                                                ['item3'], ['item4']]
532             self.ixnet_gen.update_frame(TRAFFIC_PARAMETERS, 50)
533
534         self.assertEqual(6, len(self.ixnet_gen.ixnet.setMultiAttribute.mock_calls))
535         self.assertEqual(4, len(mock_update_frame.mock_calls))
536
537         self.ixnet_gen.ixnet.setMultiAttribute.assert_has_calls([
538             mock.call('cfg_element/transmissionControl',
539                       '-type', 'continuous', '-duration', 50)
540         ])
541
542     def test_update_frame_qinq(self):
543         with mock.patch.object(self.ixnet_gen,
544                                '_get_config_element_by_flow_group_name',
545                                return_value='cfg_element'), \
546              mock.patch.object(self.ixnet_gen, '_update_frame_mac'),\
547              mock.patch.object(self.ixnet_gen, '_get_stack_item',
548                                return_value='item'), \
549              mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item',
550                                return_value='field'):
551
552             traffic_parameters = deepcopy(TRAFFIC_PARAMETERS)
553             traffic_parameters[UPLINK]['outer_l2']['QinQ'] = {
554                 'S-VLAN': {'id': 128,
555                            'priority': 1,
556                            'cfi': 0},
557                 'C-VLAN': {'id': 512,
558                            'priority': 0,
559                            'cfi': 2}
560             }
561
562             self.ixnet_gen.update_frame(traffic_parameters, 50)
563
564         self.ixnet_gen.ixnet.setMultiAttribute.assert_has_calls([
565             mock.call('field', '-auto', 'false', '-singleValue', '0x88a8',
566                       '-fieldValue', '0x88a8', '-valueType', 'singleValue'),
567             mock.call('field', '-auto', 'false', '-singleValue', 1,
568                       '-fieldValue', 1, '-valueType', 'singleValue'),
569             mock.call('field', '-auto', 'false', '-singleValue', 128,
570                       '-fieldValue', 128, '-valueType', 'singleValue'),
571             mock.call('field', '-auto', 'false', '-singleValue', 512,
572                       '-fieldValue', 512, '-valueType', 'singleValue'),
573             mock.call('field', '-auto', 'false', '-singleValue', 2,
574                       '-fieldValue', 2, '-valueType', 'singleValue')
575         ], any_order=True)
576
577     def test_update_frame_flow_not_present(self):
578         with mock.patch.object(
579                 self.ixnet_gen, '_get_config_element_by_flow_group_name',
580                 return_value=None):
581             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
582                 self.ixnet_gen.update_frame(TRAFFIC_PARAMETERS, 40)
583
584     def test_get_statistics(self):
585         port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
586         flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
587         with mock.patch.object(self.ixnet_gen, '_build_stats_map') as \
588                 mock_build_stats:
589             self.ixnet_gen.get_statistics()
590
591         mock_build_stats.assert_has_calls([
592             mock.call(port_statistics, self.ixnet_gen.PORT_STATS_NAME_MAP),
593             mock.call(flow_statistics, self.ixnet_gen.LATENCY_NAME_MAP)])
594
595     def test__set_flow_tracking(self):
596         self.ixnet_gen._ixnet.getList.return_value = ['traffic_item']
597         self.ixnet_gen._set_flow_tracking(track_by=['vlanVlanId0'])
598         self.ixnet_gen.ixnet.setAttribute.assert_called_once_with(
599             'traffic_item/tracking', '-trackBy', ['vlanVlanId0'])
600         self.assertEqual(self.ixnet.commit.call_count, 1)
601
602     def test__set_egress_flow_tracking(self):
603         self.ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
604                                                      ['encapsulation']]
605         self.ixnet_gen._set_egress_flow_tracking(encapsulation='Ethernet',
606                                                  offset='IPv4 TOS Precedence')
607         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
608             'traffic_item', '-egressEnabled', True)
609         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
610             'encapsulation', '-encapsulation', 'Ethernet')
611         self.ixnet_gen.ixnet.setAttribute.assert_any_call(
612             'encapsulation', '-offset', 'IPv4 TOS Precedence')
613         self.assertEqual(self.ixnet.commit.call_count, 2)
614
615     def test__update_ipv4_address(self):
616         with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item',
617                                return_value='field_desc'):
618             self.ixnet_gen._update_ipv4_address(mock.ANY, mock.ANY, '192.168.1.1',
619                                            100, 26, 25)
620         self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
621             'field_desc', '-seed', 100, '-fixedBits', '192.168.1.1',
622             '-randomMask', '0.0.0.63', '-valueType', 'random',
623             '-countValue', 25)
624
625     def test__update_udp_port(self):
626         with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item',
627                                return_value='field_desc'):
628             self.ixnet_gen._update_udp_port(mock.ANY, mock.ANY, 1234,
629                                             2, 0, 2)
630
631         self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
632             'field_desc',
633             '-auto', 'false',
634             '-seed', 1,
635             '-fixedBits', 1234,
636             '-randomMask', 0,
637             '-valueType', 'random',
638             '-countValue', 1)
639
640     def test_update_ip_packet(self):
641         with mock.patch.object(self.ixnet_gen, '_update_ipv4_address') as \
642                 mock_update_add, \
643                 mock.patch.object(self.ixnet_gen, '_get_stack_item'), \
644                 mock.patch.object(self.ixnet_gen,
645                 '_get_config_element_by_flow_group_name', return_value='celm'):
646             self.ixnet_gen.update_ip_packet(TRAFFIC_PARAMETERS)
647
648         self.assertEqual(4, len(mock_update_add.mock_calls))
649
650     def test_update_ip_packet_exception_no_config_element(self):
651         with mock.patch.object(self.ixnet_gen,
652                                '_get_config_element_by_flow_group_name',
653                                return_value=None):
654             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
655                 self.ixnet_gen.update_ip_packet(TRAFFIC_PARAMETERS)
656
657     def test_update_l4(self):
658         with mock.patch.object(self.ixnet_gen, '_update_udp_port') as \
659                 mock_update_udp, \
660                 mock.patch.object(self.ixnet_gen, '_get_stack_item'), \
661                 mock.patch.object(self.ixnet_gen,
662                 '_get_config_element_by_flow_group_name', return_value='celm'):
663             self.ixnet_gen.update_l4(TRAFFIC_PARAMETERS)
664
665         self.assertEqual(4, len(mock_update_udp.mock_calls))
666
667     def test_update_l4_exception_no_config_element(self):
668         with mock.patch.object(self.ixnet_gen,
669                                '_get_config_element_by_flow_group_name',
670                                return_value=None):
671             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
672                 self.ixnet_gen.update_l4(TRAFFIC_PARAMETERS)
673
674     def test_update_l4_exception_no_supported_proto(self):
675         traffic_parameters = {
676             UPLINK: {
677                 'id': 1,
678                 'outer_l3': {
679                     'proto': 'unsupported',
680                 },
681                 'outer_l4': {
682                     'seed': 1
683                 }
684             },
685         }
686         with mock.patch.object(self.ixnet_gen,
687                                '_get_config_element_by_flow_group_name',
688                                return_value='celm'):
689             with self.assertRaises(exceptions.IXIAUnsupportedProtocol):
690                 self.ixnet_gen.update_l4(traffic_parameters)
691
692     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
693     def test_start_traffic(self, mock_ixnextgen_get_traffic_state):
694         self.ixnet_gen._ixnet.getList.return_value = [0]
695
696         mock_ixnextgen_get_traffic_state.side_effect = [
697             'stopped', 'started', 'started', 'started']
698
699         result = self.ixnet_gen.start_traffic()
700         self.assertIsNone(result)
701         self.ixnet.getList.assert_called_once()
702         self.assertEqual(3, self.ixnet_gen._ixnet.execute.call_count)
703
704     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
705     def test_start_traffic_traffic_running(
706             self, mock_ixnextgen_get_traffic_state):
707         self.ixnet_gen._ixnet.getList.return_value = [0]
708         mock_ixnextgen_get_traffic_state.side_effect = [
709             'started', 'stopped', 'started']
710
711         result = self.ixnet_gen.start_traffic()
712         self.assertIsNone(result)
713         self.ixnet.getList.assert_called_once()
714         self.assertEqual(4, self.ixnet_gen._ixnet.execute.call_count)
715
716     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
717     def test_start_traffic_wait_for_traffic_to_stop(
718             self, mock_ixnextgen_get_traffic_state):
719         self.ixnet_gen._ixnet.getList.return_value = [0]
720         mock_ixnextgen_get_traffic_state.side_effect = [
721             'started', 'started', 'started', 'stopped', 'started']
722
723         result = self.ixnet_gen.start_traffic()
724         self.assertIsNone(result)
725         self.ixnet.getList.assert_called_once()
726         self.assertEqual(4, self.ixnet_gen._ixnet.execute.call_count)
727
728     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
729     def test_start_traffic_wait_for_traffic_start(
730             self, mock_ixnextgen_get_traffic_state):
731         self.ixnet_gen._ixnet.getList.return_value = [0]
732         mock_ixnextgen_get_traffic_state.side_effect = [
733             'stopped', 'stopped', 'stopped', 'started']
734
735         result = self.ixnet_gen.start_traffic()
736         self.assertIsNone(result)
737         self.ixnet.getList.assert_called_once()
738         self.assertEqual(3, self.ixnet_gen._ixnet.execute.call_count)
739
740     def test__get_protocol_status(self):
741         self.ixnet.getAttribute.return_value = ['up']
742         self.ixnet_gen._get_protocol_status('ipv4')
743         self.ixnet.getAttribute.assert_called_once_with('ipv4',
744                                                         '-sessionStatus')
745
746     @mock.patch.object(ixnet_api.IxNextgen, '_get_protocol_status')
747     def test_is_protocols_running(self, mock_ixnextgen_get_protocol_status):
748         mock_ixnextgen_get_protocol_status.return_value = 'up'
749         result = self.ixnet_gen.is_protocols_running(['ethernet', 'ipv4'])
750         self.assertTrue(result)
751
752     @mock.patch.object(ixnet_api.IxNextgen, '_get_protocol_status')
753     def test_is_protocols_stopped(self, mock_ixnextgen_get_protocol_status):
754         mock_ixnextgen_get_protocol_status.return_value = 'down'
755         result = self.ixnet_gen.is_protocols_running(['ethernet', 'ipv4'])
756         self.assertFalse(result)
757
758     def test_start_protocols(self):
759         self.ixnet_gen.start_protocols()
760         self.ixnet.execute.assert_called_once_with('startAllProtocols')
761
762     def test_stop_protocols(self):
763         self.ixnet_gen.stop_protocols()
764         self.ixnet.execute.assert_called_once_with('stopAllProtocols')
765
766     def test_get_vports(self):
767         self.ixnet_gen._ixnet.getRoot.return_value = 'root'
768         self.ixnet_gen.get_vports()
769         self.ixnet.getList.assert_called_once_with('root', 'vport')