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