Merge "Clean-up tests in test_vsperf_dpdk.py:VsperfDPDKTestCase"
[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 yardstick.common import exceptions
20 from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
21
22
23 UPLINK = 'uplink'
24 DOWNLINK = 'downlink'
25
26 TRAFFIC_PARAMETERS = {
27     UPLINK: {
28         'id': 1,
29         'bidir': 'False',
30         'duration': 60,
31         'rate': 10000.5,
32         'rate_unit': 'fps',
33         'outer_l2': {
34             'framesize': {'64B': '25', '256B': '75'}
35         },
36         'outer_l3': {
37             'count': 512,
38             'dscp': 0,
39             'dstip4': '152.16.40.20',
40             'proto': 'udp',
41             'srcip4': '152.16.100.20',
42             'ttl': 32
43         },
44         'outer_l3v4': {
45             'dscp': 0,
46             'dstip4': '152.16.40.20',
47             'proto': 'udp',
48             'srcip4': '152.16.100.20',
49             'ttl': 32
50         },
51         'outer_l3v6': {
52             'count': 1024,
53             'dscp': 0,
54             'dstip4': '152.16.100.20',
55             'proto': 'udp',
56             'srcip4': '152.16.40.20',
57             'ttl': 32
58         },
59         'outer_l4': {
60             'dstport': '2001',
61             'srcport': '1234'
62         },
63         'traffic_type': 'continuous'
64     },
65     DOWNLINK: {
66         'id': 2,
67         'bidir': 'False',
68         'duration': 60,
69         'rate': 75.2,
70         'rate_unit': '%',
71         'outer_l2': {
72             'framesize': {'128B': '35', '1024B': '65'}
73         },
74         'outer_l3': {
75             'count': 1024,
76             'dscp': 0,
77             'dstip4': '152.16.100.20',
78             'proto': 'udp',
79             'srcip4': '152.16.40.20',
80             'ttl': 32
81         },
82         'outer_l3v4': {
83             'count': 1024,
84             'dscp': 0,
85             'dstip4': '152.16.100.20',
86             'proto': 'udp',
87             'srcip4': '152.16.40.20',
88             'ttl': 32
89         },
90         'outer_l3v6': {
91             'count': 1024,
92             'dscp': 0,
93             'dstip4': '152.16.100.20',
94             'proto': 'udp',
95             'srcip4': '152.16.40.20',
96             'ttl': 32
97         },
98         'outer_l4': {
99             'dstport': '1234',
100             'srcport': '2001'
101         },
102         'traffic_type': 'continuous'
103     }
104 }
105
106
107 class TestIxNextgen(unittest.TestCase):
108
109     def setUp(self):
110         self.ixnet = mock.Mock()
111         self.ixnet.execute = mock.Mock()
112         self.ixnet.getRoot.return_value = 'my_root'
113
114     def test_get_config(self):
115         tg_cfg = {
116             'vdu': [
117                 {
118                     'external-interface': [
119                         {'virtual-interface': {'vpci': '0000:07:00.1'}},
120                         {'virtual-interface': {'vpci': '0001:08:01.2'}}
121                     ]
122                 },
123             ],
124             'mgmt-interface': {
125                 'ip': 'test1',
126                 'tg-config': {
127                     'dut_result_dir': 'test2',
128                     'version': 'test3',
129                     'ixchassis': 'test4',
130                     'tcl_port': 'test5',
131                 },
132             }
133         }
134
135         expected = {
136             'machine': 'test1',
137             'port': 'test5',
138             'chassis': 'test4',
139             'cards': ['0000', '0001'],
140             'ports': ['07', '08'],
141             'output_dir': 'test2',
142             'version': 'test3',
143             'bidir': True,
144         }
145
146         result = ixnet_api.IxNextgen.get_config(tg_cfg)
147         self.assertEqual(result, expected)
148
149     def test__get_config_element_by_flow_group_name(self):
150         ixnet_gen = ixnet_api.IxNextgen()
151         ixnet_gen._ixnet = self.ixnet
152         ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
153                                                 ['fg_01']]
154         ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_01'
155         output = ixnet_gen._get_config_element_by_flow_group_name(
156             'flow_group_01')
157         self.assertEqual('traffic_item/configElement:flow_group_01', output)
158
159     def test__get_config_element_by_flow_group_name_no_match(self):
160         ixnet_gen = ixnet_api.IxNextgen()
161         ixnet_gen._ixnet = self.ixnet
162         ixnet_gen._ixnet.getList.side_effect = [['traffic_item'],
163                                                 ['fg_01']]
164         ixnet_gen._ixnet.getAttribute.return_value = 'flow_group_02'
165         output = ixnet_gen._get_config_element_by_flow_group_name(
166             'flow_group_01')
167         self.assertIsNone(output)
168
169     def test__get_stack_item(self):
170         ixnet_gen = ixnet_api.IxNextgen()
171         ixnet_gen._ixnet = self.ixnet
172         ixnet_gen._ixnet.getList.return_value = ['tcp1', 'tcp2', 'udp']
173         with mock.patch.object(
174                 ixnet_gen, '_get_config_element_by_flow_group_name') as \
175                 mock_get_cfg_element:
176             mock_get_cfg_element.return_value = 'cfg_element'
177             output = ixnet_gen._get_stack_item(mock.ANY, ixnet_api.PROTO_TCP)
178         self.assertEqual(['tcp1', 'tcp2'], output)
179
180     def test__get_stack_item_no_config_element(self):
181         ixnet_gen = ixnet_api.IxNextgen()
182         ixnet_gen._ixnet = self.ixnet
183         with mock.patch.object(
184                 ixnet_gen, '_get_config_element_by_flow_group_name',
185                 return_value=None):
186             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
187                 ixnet_gen._get_stack_item(mock.ANY, mock.ANY)
188
189     def test__get_field_in_stack_item(self):
190         ixnet_gen = ixnet_api.IxNextgen()
191         ixnet_gen._ixnet = self.ixnet
192         ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
193         output = ixnet_gen._get_field_in_stack_item(mock.ANY, 'field2')
194         self.assertEqual('field2', output)
195
196     def test__get_field_in_stack_item_no_field_present(self):
197         ixnet_gen = ixnet_api.IxNextgen()
198         ixnet_gen._ixnet = self.ixnet
199         ixnet_gen._ixnet.getList.return_value = ['field1', 'field2']
200         with self.assertRaises(exceptions.IxNetworkFieldNotPresentInStackItem):
201             ixnet_gen._get_field_in_stack_item(mock.ANY, 'field3')
202
203     def test__parse_framesize(self):
204         ixnet_gen = ixnet_api.IxNextgen()
205         ixnet_gen._ixnet = self.ixnet
206         framesize = {'64B': '75', '512b': '25'}
207         output = ixnet_gen._parse_framesize(framesize)
208         self.assertEqual(2, len(output))
209         self.assertIn([64, 64, 75], output)
210         self.assertIn([512, 512, 25], output)
211
212     @mock.patch.object(IxNetwork, 'IxNet')
213     def test_connect(self, mock_ixnet):
214         mock_ixnet.return_value = self.ixnet
215         ixnet_gen = ixnet_api.IxNextgen()
216         with mock.patch.object(ixnet_gen, 'get_config') as mock_config:
217             mock_config.return_value = {'machine': 'machine_fake',
218                                         'port': 'port_fake',
219                                         'version': 12345}
220             ixnet_gen.connect(mock.ANY)
221
222         self.ixnet.connect.assert_called_once_with(
223             'machine_fake', '-port', 'port_fake', '-version', '12345')
224         mock_config.assert_called_once()
225
226     def test_connect_invalid_config_no_machine(self):
227         ixnet_gen = ixnet_api.IxNextgen()
228         ixnet_gen._ixnet = self.ixnet
229         ixnet_gen.get_config = mock.Mock(return_value={
230             'port': 'port_fake',
231             'version': '12345'})
232         self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
233         self.ixnet.connect.assert_not_called()
234
235     def test_connect_invalid_config_no_port(self):
236         ixnet_gen = ixnet_api.IxNextgen()
237         ixnet_gen._ixnet = self.ixnet
238         ixnet_gen.get_config = mock.Mock(return_value={
239             'machine': 'machine_fake',
240             'version': '12345'})
241         self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
242         self.ixnet.connect.assert_not_called()
243
244     def test_connect_invalid_config_no_version(self):
245         ixnet_gen = ixnet_api.IxNextgen()
246         ixnet_gen._ixnet = self.ixnet
247         ixnet_gen.get_config = mock.Mock(return_value={
248             'machine': 'machine_fake',
249             'port': 'port_fake'})
250         self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
251         self.ixnet.connect.assert_not_called()
252
253     def test_connect_no_config(self):
254         ixnet_gen = ixnet_api.IxNextgen()
255         ixnet_gen._ixnet = self.ixnet
256         ixnet_gen.get_config = mock.Mock(return_value={})
257         self.assertRaises(KeyError, ixnet_gen.connect, mock.ANY)
258         self.ixnet.connect.assert_not_called()
259
260     def test_clear_config(self):
261         ixnet_gen = ixnet_api.IxNextgen()
262         ixnet_gen._ixnet = self.ixnet
263         ixnet_gen.clear_config()
264         self.ixnet.execute.assert_called_once_with('newConfig')
265
266     @mock.patch.object(ixnet_api, 'log')
267     def test_assign_ports_2_ports(self, *args):
268         self.ixnet.getAttribute.side_effect = ['up', 'down']
269         config = {
270             'chassis': '1.1.1.1',
271             'cards': ['1', '2'],
272             'ports': ['2', '2']}
273         ixnet_gen = ixnet_api.IxNextgen()
274         ixnet_gen._ixnet = self.ixnet
275         ixnet_gen._cfg = config
276
277         self.assertIsNone(ixnet_gen.assign_ports())
278         self.assertEqual(self.ixnet.execute.call_count, 2)
279         self.assertEqual(self.ixnet.commit.call_count, 4)
280         self.assertEqual(self.ixnet.getAttribute.call_count, 2)
281
282     @mock.patch.object(ixnet_api, 'log')
283     def test_assign_ports_port_down(self, mock_log):
284         self.ixnet.getAttribute.return_value = 'down'
285         config = {
286             'chassis': '1.1.1.1',
287             'cards': ['1', '2'],
288             'ports': ['3', '4']}
289         ixnet_gen = ixnet_api.IxNextgen()
290         ixnet_gen._ixnet = self.ixnet
291         ixnet_gen._cfg = config
292         ixnet_gen.assign_ports()
293         mock_log.warning.assert_called()
294
295     def test_assign_ports_no_config(self):
296         ixnet_gen = ixnet_api.IxNextgen()
297         ixnet_gen._ixnet = self.ixnet
298         ixnet_gen._cfg = {}
299         self.assertRaises(KeyError, ixnet_gen.assign_ports)
300
301     def test__create_traffic_item(self):
302         ixnet_gen = ixnet_api.IxNextgen()
303         ixnet_gen._ixnet = self.ixnet
304         self.ixnet.add.return_value = 'my_new_traffic_item'
305         self.ixnet.remapIds.return_value = ['my_traffic_item_id']
306
307         ixnet_gen._create_traffic_item()
308         self.ixnet.add.assert_called_once_with(
309             'my_root/traffic', 'trafficItem')
310         self.ixnet.setMultiAttribute.assert_called_once_with(
311             'my_new_traffic_item', '-name', 'RFC2544', '-trafficType', 'raw')
312         self.assertEqual(2, self.ixnet.commit.call_count)
313         self.ixnet.remapIds.assert_called_once_with('my_new_traffic_item')
314         self.ixnet.setAttribute('my_traffic_item_id/tracking',
315                                 '-trackBy', 'trafficGroupId0')
316
317     def test__create_flow_groups(self):
318         ixnet_gen = ixnet_api.IxNextgen()
319         ixnet_gen._ixnet = self.ixnet
320         ixnet_gen.ixnet.getList.side_effect = [['traffic_item'], ['1', '2']]
321         ixnet_gen.ixnet.add.side_effect = ['endp1', 'endp2']
322         ixnet_gen._create_flow_groups()
323         ixnet_gen.ixnet.add.assert_has_calls([
324             mock.call('traffic_item', 'endpointSet'),
325             mock.call('traffic_item', 'endpointSet')])
326         ixnet_gen.ixnet.setMultiAttribute.assert_has_calls([
327             mock.call('endp1', '-name', '1', '-sources', ['1/protocols'],
328                       '-destinations', ['2/protocols']),
329             mock.call('endp2', '-name', '2', '-sources', ['2/protocols'],
330                       '-destinations', ['1/protocols'])])
331
332     def test__append_protocol_to_stack(self):
333         ixnet_gen = ixnet_api.IxNextgen()
334         ixnet_gen._ixnet = self.ixnet
335
336         ixnet_gen._append_procotol_to_stack('my_protocol', 'prev_element')
337         self.ixnet.execute.assert_called_with(
338             'append', 'prev_element',
339             'my_root/traffic/protocolTemplate:"my_protocol"')
340
341     def test__setup_config_elements(self):
342         ixnet_gen = ixnet_api.IxNextgen()
343         ixnet_gen._ixnet = self.ixnet
344         ixnet_gen.ixnet.getList.side_effect = [['traffic_item'],
345                                                ['cfg_element']]
346         with mock.patch.object(ixnet_gen, '_append_procotol_to_stack') as \
347                 mock_append_proto:
348             ixnet_gen._setup_config_elements()
349         mock_append_proto.assert_has_calls([
350             mock.call(ixnet_api.PROTO_UDP, 'cfg_element/stack:"ethernet-1"'),
351             mock.call(ixnet_api.PROTO_IPV4, 'cfg_element/stack:"ethernet-1"')])
352         ixnet_gen.ixnet.setAttribute.assert_has_calls([
353             mock.call('cfg_element/frameRateDistribution', '-portDistribution',
354                       'splitRateEvenly'),
355             mock.call('cfg_element/frameRateDistribution',
356                       '-streamDistribution', 'splitRateEvenly')])
357
358     @mock.patch.object(ixnet_api.IxNextgen, '_create_traffic_item')
359     @mock.patch.object(ixnet_api.IxNextgen, '_create_flow_groups')
360     @mock.patch.object(ixnet_api.IxNextgen, '_setup_config_elements')
361     def test_create_traffic_model(self, mock__setup_config_elements,
362                                   mock__create_flow_groups,
363                                   mock__create_traffic_item):
364         ixnet_gen = ixnet_api.IxNextgen()
365         ixnet_gen._ixnet = self.ixnet
366
367         ixnet_gen.create_traffic_model()
368         mock__create_traffic_item.assert_called_once()
369         mock__create_flow_groups.assert_called_once()
370         mock__setup_config_elements.assert_called_once()
371
372     def test__update_frame_mac(self):
373         ixnet_gen = ixnet_api.IxNextgen()
374         ixnet_gen._ixnet = self.ixnet
375         with mock.patch.object(ixnet_gen, '_get_field_in_stack_item') as \
376                 mock_get_field:
377             mock_get_field.return_value = 'field_descriptor'
378             ixnet_gen._update_frame_mac('ethernet_descriptor', 'field', 'mac')
379         mock_get_field.assert_called_once_with('ethernet_descriptor', 'field')
380         ixnet_gen.ixnet.setMultiAttribute(
381             'field_descriptor', '-singleValue', 'mac', '-fieldValue', 'mac',
382             '-valueType', 'singleValue')
383         ixnet_gen.ixnet.commit.assert_called_once()
384
385     def test_update_frame(self):
386         ixnet_gen = ixnet_api.IxNextgen()
387         ixnet_gen._ixnet = self.ixnet
388         with mock.patch.object(
389                 ixnet_gen, '_get_config_element_by_flow_group_name',
390                 return_value='cfg_element'), \
391                 mock.patch.object(ixnet_gen, '_update_frame_mac') as \
392                 mock_update_frame, \
393                 mock.patch.object(ixnet_gen, '_get_stack_item') as \
394                 mock_get_stack_item:
395             mock_get_stack_item.side_effect = [['item1'], ['item2'],
396                                                ['item3'], ['item4']]
397             ixnet_gen.update_frame(TRAFFIC_PARAMETERS)
398
399         self.assertEqual(6, len(ixnet_gen.ixnet.setMultiAttribute.mock_calls))
400         self.assertEqual(4, len(mock_update_frame.mock_calls))
401         ixnet_gen.ixnet.setMultiAttribute.assert_has_calls(
402             [mock.call('cfg_element/frameRate', '-rate', 10000.5,
403                        '-type', 'framesPerSecond'),
404              mock.call('cfg_element/frameRate', '-rate', 75.2, '-type',
405                        'percentLineRate')],
406             any_order=True)
407
408     def test_update_frame_flow_not_present(self):
409         ixnet_gen = ixnet_api.IxNextgen()
410         ixnet_gen._ixnet = self.ixnet
411         with mock.patch.object(
412                 ixnet_gen, '_get_config_element_by_flow_group_name',
413                 return_value=None):
414             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
415                 ixnet_gen.update_frame(TRAFFIC_PARAMETERS)
416
417     def test_get_statistics(self):
418         ixnet_gen = ixnet_api.IxNextgen()
419         port_statistics = '::ixNet::OBJ-/statistics/view:"Port Statistics"'
420         flow_statistics = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
421         with mock.patch.object(ixnet_gen, '_build_stats_map') as \
422                 mock_build_stats:
423             ixnet_gen.get_statistics()
424
425         mock_build_stats.assert_has_calls([
426             mock.call(port_statistics, ixnet_gen.PORT_STATS_NAME_MAP),
427             mock.call(flow_statistics, ixnet_gen.LATENCY_NAME_MAP)])
428
429     def test__update_ipv4_address(self):
430         ixnet_gen = ixnet_api.IxNextgen()
431         ixnet_gen._ixnet = self.ixnet
432         with mock.patch.object(ixnet_gen, '_get_field_in_stack_item',
433                                return_value='field_desc'):
434             ixnet_gen._update_ipv4_address(mock.ANY, mock.ANY, '192.168.1.1',
435                                            100, '255.255.255.0', 25)
436         ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
437             'field_desc', '-seed', 100, '-fixedBits', '192.168.1.1',
438             '-randomMask', '255.255.255.0', '-valueType', 'random',
439             '-countValue', 25)
440
441     def test_update_ip_packet(self):
442         ixnet_gen = ixnet_api.IxNextgen()
443         ixnet_gen._ixnet = self.ixnet
444         with mock.patch.object(ixnet_gen, '_update_ipv4_address') as \
445                 mock_update_add, \
446                 mock.patch.object(ixnet_gen, '_get_stack_item'), \
447                 mock.patch.object(ixnet_gen,
448                 '_get_config_element_by_flow_group_name', return_value='celm'):
449             ixnet_gen.update_ip_packet(TRAFFIC_PARAMETERS)
450
451         self.assertEqual(4, len(mock_update_add.mock_calls))
452
453     def test_update_ip_packet_exception_no_config_element(self):
454         ixnet_gen = ixnet_api.IxNextgen()
455         ixnet_gen._ixnet = self.ixnet
456         with mock.patch.object(ixnet_gen,
457                                '_get_config_element_by_flow_group_name',
458                                return_value=None):
459             with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
460                 ixnet_gen.update_ip_packet(TRAFFIC_PARAMETERS)
461
462     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
463     def test_start_traffic(self, mock_ixnextgen_get_traffic_state):
464         ixnet_gen = ixnet_api.IxNextgen()
465         ixnet_gen._ixnet = self.ixnet
466         ixnet_gen._ixnet.getList.return_value = [0]
467
468         mock_ixnextgen_get_traffic_state.side_effect = [
469             'stopped', 'started', 'started', 'started']
470
471         result = ixnet_gen.start_traffic()
472         self.assertIsNone(result)
473         self.ixnet.getList.assert_called_once()
474         self.assertEqual(3, ixnet_gen._ixnet.execute.call_count)
475
476     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
477     def test_start_traffic_traffic_running(
478             self, mock_ixnextgen_get_traffic_state):
479         ixnet_gen = ixnet_api.IxNextgen()
480         ixnet_gen._ixnet = self.ixnet
481         ixnet_gen._ixnet.getList.return_value = [0]
482         mock_ixnextgen_get_traffic_state.side_effect = [
483             'started', 'stopped', 'started']
484
485         result = ixnet_gen.start_traffic()
486         self.assertIsNone(result)
487         self.ixnet.getList.assert_called_once()
488         self.assertEqual(4, ixnet_gen._ixnet.execute.call_count)
489
490     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
491     def test_start_traffic_wait_for_traffic_to_stop(
492             self, mock_ixnextgen_get_traffic_state):
493         ixnet_gen = ixnet_api.IxNextgen()
494         ixnet_gen._ixnet = self.ixnet
495         ixnet_gen._ixnet.getList.return_value = [0]
496         mock_ixnextgen_get_traffic_state.side_effect = [
497             'started', 'started', 'started', 'stopped', 'started']
498
499         result = ixnet_gen.start_traffic()
500         self.assertIsNone(result)
501         self.ixnet.getList.assert_called_once()
502         self.assertEqual(4, ixnet_gen._ixnet.execute.call_count)
503
504     @mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
505     def test_start_traffic_wait_for_traffic_start(
506             self, mock_ixnextgen_get_traffic_state):
507         ixnet_gen = ixnet_api.IxNextgen()
508         ixnet_gen._ixnet = self.ixnet
509         ixnet_gen._ixnet.getList.return_value = [0]
510         mock_ixnextgen_get_traffic_state.side_effect = [
511             'stopped', 'stopped', 'stopped', 'started']
512
513         result = ixnet_gen.start_traffic()
514         self.assertIsNone(result)
515         self.ixnet.getList.assert_called_once()
516         self.assertEqual(3, ixnet_gen._ixnet.execute.call_count)