Merge "Update: assign static IP to VM for standalone"
[yardstick.git] / yardstick / tests / unit / network_services / traffic_profile / test_rfc2544.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 datetime
16
17 import mock
18 from trex_stl_lib import api as Pkt
19 from trex_stl_lib import trex_stl_client
20 from trex_stl_lib import trex_stl_packet_builder_scapy
21 from trex_stl_lib import trex_stl_streams
22
23 from yardstick.common import constants
24 from yardstick.network_services.traffic_profile import rfc2544
25 from yardstick.tests.unit import base
26
27
28 class TestRFC2544Profile(base.BaseUnitTestCase):
29     TRAFFIC_PROFILE = {
30         "schema": "isb:traffic_profile:0.1",
31         "name": "fixed",
32         "description": "Fixed traffic profile to run UDP traffic",
33         "traffic_profile": {
34             "traffic_type": "FixedTraffic",
35             "frame_rate": 100,
36             "flow_number": 10,
37             "frame_size": 64}}
38
39     PROFILE = {'description': 'Traffic profile to run RFC2544 latency',
40                'name': 'rfc2544',
41                'traffic_profile': {'traffic_type': 'RFC2544Profile',
42                                    'frame_rate': 100},
43                'downlink_0':
44                    {'ipv4':
45                         {'outer_l2':
46                              {'framesize':
47                                   {'64B': '100', '1518B': '0',
48                                    '128B': '0', '1400B': '0',
49                                    '256B': '0', '373b': '0',
50                                    '570B': '0'}},
51                          'outer_l3v4':
52                              {'dstip4': '1.1.1.1-1.15.255.255',
53                               'proto': 'udp',
54                               'srcip4': '90.90.1.1-90.105.255.255',
55                               'dscp': 0, 'ttl': 32, 'count': 1},
56                          'outer_l4':
57                              {'srcport': '2001',
58                               'dsrport': '1234', 'count': 1}}},
59                'uplink_0':
60                    {'ipv4':
61                         {'outer_l2':
62                              {'framesize':
63                                   {'64B': '100', '1518B': '0',
64                                    '128B': '0', '1400B': '0',
65                                    '256B': '0', '373b': '0',
66                                    '570B': '0'}},
67                          'outer_l3v4':
68                              {'dstip4': '9.9.1.1-90.105.255.255',
69                               'proto': 'udp',
70                               'srcip4': '1.1.1.1-1.15.255.255',
71                               'dscp': 0, 'ttl': 32, 'count': 1},
72                          'outer_l4':
73                              {'dstport': '2001',
74                               'srcport': '1234', 'count': 1}}},
75                'schema': 'isb:traffic_profile:0.1'}
76
77     def test___init__(self):
78         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
79         self.assertEqual(rfc2544_profile.max_rate, rfc2544_profile.rate)
80         self.assertEqual(0, rfc2544_profile.min_rate)
81
82     def test_stop_traffic(self):
83         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
84         mock_generator = mock.Mock()
85         rfc2544_profile.stop_traffic(traffic_generator=mock_generator)
86         mock_generator.client.stop.assert_called_once()
87         mock_generator.client.reset.assert_called_once()
88         mock_generator.client.remove_all_streams.assert_called_once()
89
90     def test_execute_traffic(self):
91         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
92         mock_generator = mock.Mock()
93         mock_generator.networks = {
94             'downlink_0': ['xe0', 'xe1'],
95             'uplink_0': ['xe2', 'xe3'],
96             'downlink_1': []}
97         mock_generator.port_num.side_effect = [10, 20, 30, 40]
98         mock_generator.rfc2544_helper.correlated_traffic = False
99         rfc2544_profile.params = {
100             'downlink_0': 'profile1',
101             'uplink_0': 'profile2'}
102
103         with mock.patch.object(rfc2544_profile, '_create_profile') as \
104                 mock_create_profile:
105             rfc2544_profile.execute_traffic(traffic_generator=mock_generator)
106         mock_create_profile.assert_has_calls([
107             mock.call('profile1', rfc2544_profile.rate, mock.ANY, False),
108             mock.call('profile1', rfc2544_profile.rate, mock.ANY, False),
109             mock.call('profile2', rfc2544_profile.rate, mock.ANY, False),
110             mock.call('profile2', rfc2544_profile.rate, mock.ANY, False)])
111         mock_generator.client.add_streams.assert_has_calls([
112             mock.call(mock.ANY, ports=[10]),
113             mock.call(mock.ANY, ports=[20]),
114             mock.call(mock.ANY, ports=[30]),
115             mock.call(mock.ANY, ports=[40])])
116         mock_generator.client.start(ports=[10, 20, 30, 40],
117                                     duration=rfc2544_profile.config.duration,
118                                     force=True)
119
120     @mock.patch.object(trex_stl_streams, 'STLProfile')
121     def test__create_profile(self, mock_stl_profile):
122         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
123         port_pg_id = mock.ANY
124         profile_data = {'packetid_1': {'outer_l2': {'framesize': 'imix_info'}}}
125         rate = 100
126         with mock.patch.object(rfc2544_profile, '_create_imix_data') as \
127                 mock_create_imix, \
128                 mock.patch.object(rfc2544_profile, '_create_vm') as \
129                 mock_create_vm, \
130                 mock.patch.object(rfc2544_profile, '_create_streams') as \
131                 mock_create_streams:
132             mock_create_imix.return_value = 'imix_data'
133             mock_create_streams.return_value = ['stream1']
134             rfc2544_profile._create_profile(profile_data, rate, port_pg_id,
135                                             True)
136
137         mock_create_imix.assert_called_once_with('imix_info')
138         mock_create_vm.assert_called_once_with(
139             {'outer_l2': {'framesize': 'imix_info'}})
140         mock_create_streams.assert_called_once_with('imix_data', 100,
141                                                     port_pg_id, True)
142         mock_stl_profile.assert_called_once_with(['stream1'])
143
144     def test__create_imix_data_mode_DIB(self):
145         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
146         data = {'64B': 50, '128B': 50}
147         self.assertEqual(
148             {'64': 50.0, '128': 50.0},
149             rfc2544_profile._create_imix_data(
150                 data, weight_mode=constants.DISTRIBUTION_IN_BYTES))
151         data = {'64B': 1, '128b': 3}
152         self.assertEqual(
153             {'64': 25.0, '128': 75.0},
154             rfc2544_profile._create_imix_data(
155                 data, weight_mode=constants.DISTRIBUTION_IN_BYTES))
156         data = {}
157         self.assertEqual(
158             {},
159             rfc2544_profile._create_imix_data(
160                 data, weight_mode=constants.DISTRIBUTION_IN_BYTES))
161
162     def test__create_imix_data_mode_DIP(self):
163         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
164         data = {'64B': 25, '128B': 25, '512B': 25, '1518B': 25}
165         byte_total = 64 * 25 + 128 * 25 + 512 * 25 + 1518 * 25
166         self.assertEqual(
167             {'64': 64 * 25.0 * 100 / byte_total,
168              '128': 128 * 25.0 * 100 / byte_total,
169              '512': 512 * 25.0 * 100 / byte_total,
170              '1518': 1518 * 25.0 * 100/ byte_total},
171             rfc2544_profile._create_imix_data(
172                 data, weight_mode=constants.DISTRIBUTION_IN_PACKETS))
173         data = {}
174         self.assertEqual(
175             {},
176             rfc2544_profile._create_imix_data(
177                 data, weight_mode=constants.DISTRIBUTION_IN_PACKETS))
178         data = {'64B': 100}
179         self.assertEqual(
180             {'64': 100.0},
181             rfc2544_profile._create_imix_data(
182                 data, weight_mode=constants.DISTRIBUTION_IN_PACKETS))
183
184     def test__create_vm(self):
185         packet = {'outer_l2': 'l2_definition'}
186         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
187         with mock.patch.object(rfc2544_profile, '_set_outer_l2_fields') as \
188                 mock_l2_fileds:
189             rfc2544_profile._create_vm(packet)
190         mock_l2_fileds.assert_called_once_with('l2_definition')
191
192     @mock.patch.object(trex_stl_packet_builder_scapy, 'STLPktBuilder',
193                        return_value='packet')
194     def test__create_single_packet(self, mock_pktbuilder):
195         size = 128
196         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
197         rfc2544_profile.ether_packet = Pkt.Eth()
198         rfc2544_profile.ip_packet = Pkt.IP()
199         rfc2544_profile.udp_packet = Pkt.UDP()
200         rfc2544_profile.trex_vm = 'trex_vm'
201         base_pkt = (rfc2544_profile.ether_packet / rfc2544_profile.ip_packet /
202                     rfc2544_profile.udp_packet)
203         pad = (size - len(base_pkt)) * 'x'
204         output = rfc2544_profile._create_single_packet(size=size)
205         mock_pktbuilder.assert_called_once_with(pkt=base_pkt / pad,
206                                                 vm='trex_vm')
207         self.assertEqual(output, 'packet')
208
209     @mock.patch.object(trex_stl_packet_builder_scapy, 'STLPktBuilder',
210                        return_value='packet')
211     def test__create_single_packet_qinq(self, mock_pktbuilder):
212         size = 128
213         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
214         rfc2544_profile.ether_packet = Pkt.Eth()
215         rfc2544_profile.ip_packet = Pkt.IP()
216         rfc2544_profile.udp_packet = Pkt.UDP()
217         rfc2544_profile.trex_vm = 'trex_vm'
218         rfc2544_profile.qinq = True
219         rfc2544_profile.qinq_packet = Pkt.Dot1Q(vlan=1) / Pkt.Dot1Q(vlan=2)
220         base_pkt = (rfc2544_profile.ether_packet /
221                     rfc2544_profile.qinq_packet / rfc2544_profile.ip_packet /
222                     rfc2544_profile.udp_packet)
223         pad = (size - len(base_pkt)) * 'x'
224         output = rfc2544_profile._create_single_packet(size=size)
225         mock_pktbuilder.assert_called_once_with(pkt=base_pkt / pad,
226                                                 vm='trex_vm')
227         self.assertEqual(output, 'packet')
228
229     @mock.patch.object(trex_stl_streams, 'STLFlowLatencyStats')
230     @mock.patch.object(trex_stl_streams, 'STLTXCont')
231     @mock.patch.object(trex_stl_client, 'STLStream')
232     def test__create_streams(self, mock_stream, mock_txcont, mock_latency):
233         imix_data = {'64': 25, '512': 75}
234         rate = 35
235         port_pg_id = rfc2544.PortPgIDMap()
236         port_pg_id.add_port(10)
237         mock_stream.side_effect = ['stream1', 'stream2']
238         mock_txcont.side_effect = ['txcont1', 'txcont2']
239         mock_latency.side_effect = ['latency1', 'latency2']
240         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
241         with mock.patch.object(rfc2544_profile, '_create_single_packet'):
242             output = rfc2544_profile._create_streams(imix_data, rate,
243                                                      port_pg_id, True)
244         self.assertEqual(['stream1', 'stream2'], output)
245         mock_latency.assert_has_calls([
246             mock.call(pg_id=1), mock.call(pg_id=2)])
247         mock_txcont.assert_has_calls([
248             mock.call(percentage=float(25 * 35) / 100),
249             mock.call(percentage=float(75 * 35) / 100)], any_order=True)
250
251     def test_get_drop_percentage(self):
252         rfc2544_profile = rfc2544.RFC2544Profile(self.TRAFFIC_PROFILE)
253         samples = [
254             {'xe1': {'tx_throughput_fps': 110,
255                      'rx_throughput_fps': 101,
256                      'out_packets': 2100,
257                      'in_packets': 2010,
258                      'timestamp': datetime.datetime(2000, 1, 1, 1, 1, 1, 1)},
259              'xe2': {'tx_throughput_fps': 210,
260                      'rx_throughput_fps': 201,
261                      'out_packets': 4100,
262                      'in_packets': 4010,
263                      'timestamp': datetime.datetime(2000, 1, 1, 1, 1, 1, 1)}},
264             {'xe1': {'tx_throughput_fps': 156,
265                      'rx_throughput_fps': 108,
266                      'out_packets': 2110,
267                      'in_packets': 2040,
268                      'latency': 'Latency1',
269                      'timestamp': datetime.datetime(2000, 1, 1, 1, 1, 1, 31)},
270              'xe2': {'tx_throughput_fps': 253,
271                      'rx_throughput_fps': 215,
272                      'out_packets': 4150,
273                      'in_packets': 4010,
274                      'latency': 'Latency2',
275                      'timestamp': datetime.datetime(2000, 1, 1, 1, 1, 1, 31)}}
276         ]
277         completed, output = rfc2544_profile.get_drop_percentage(
278             samples, 0, 0, False)
279         expected = {'DropPercentage': 50.0,
280                     'Latency': {'xe1': 'Latency1', 'xe2': 'Latency2'},
281                     'RxThroughput': 1000000.0,
282                     'TxThroughput': 2000000.0,
283                     'CurrentDropPercentage': 50.0,
284                     'Rate': 100.0,
285                     'Throughput': 1000000.0}
286         self.assertEqual(expected, output)
287         self.assertFalse(completed)
288
289
290 class PortPgIDMapTestCase(base.BaseUnitTestCase):
291
292     def test_add_port(self):
293         port_pg_id_map = rfc2544.PortPgIDMap()
294         port_pg_id_map.add_port(10)
295         self.assertEqual(10, port_pg_id_map._last_port)
296         self.assertEqual([], port_pg_id_map._port_pg_id_map[10])
297
298     def test_get_pg_ids(self):
299         port_pg_id_map = rfc2544.PortPgIDMap()
300         port_pg_id_map.add_port(10)
301         port_pg_id_map.increase_pg_id()
302         port_pg_id_map.increase_pg_id()
303         port_pg_id_map.add_port(20)
304         port_pg_id_map.increase_pg_id()
305         self.assertEqual([1, 2], port_pg_id_map.get_pg_ids(10))
306         self.assertEqual([3], port_pg_id_map.get_pg_ids(20))
307         self.assertEqual([], port_pg_id_map.get_pg_ids(30))
308
309     def test_increase_pg_id_no_port(self):
310         port_pg_id_map = rfc2544.PortPgIDMap()
311         self.assertIsNone(port_pg_id_map.increase_pg_id())
312
313     def test_increase_pg_id_last_port(self):
314         port_pg_id_map = rfc2544.PortPgIDMap()
315         port_pg_id_map.add_port(10)
316         self.assertEqual(1, port_pg_id_map.increase_pg_id())
317         self.assertEqual([1], port_pg_id_map.get_pg_ids(10))
318         self.assertEqual(10, port_pg_id_map._last_port)
319
320     def test_increase_pg_id(self):
321         port_pg_id_map = rfc2544.PortPgIDMap()
322         port_pg_id_map.add_port(10)
323         port_pg_id_map.increase_pg_id()
324         self.assertEqual(2, port_pg_id_map.increase_pg_id(port=20))
325         self.assertEqual([1], port_pg_id_map.get_pg_ids(10))
326         self.assertEqual([2], port_pg_id_map.get_pg_ids(20))
327         self.assertEqual(20, port_pg_id_map._last_port)