Merge "Test case override of traffic profile settings."
[yardstick.git] / yardstick / tests / unit / benchmark / scenarios / networking / test_pktgen.py
1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import mock
11 import unittest
12 import logging
13
14 from oslo_serialization import jsonutils
15
16 from yardstick import ssh
17 from yardstick.benchmark.scenarios.networking import pktgen
18 from yardstick.common import exceptions as y_exc
19
20
21 logging.disable(logging.CRITICAL)
22
23
24 class PktgenTestCase(unittest.TestCase):
25
26     def setUp(self):
27         self.context_cfg = {
28             'host': {
29                 'ip': '172.16.0.137',
30                 'user': 'root',
31                 'key_filename': 'mykey.key'
32             },
33             'target': {
34                 'ip': '172.16.0.138',
35                 'user': 'root',
36                 'key_filename': 'mykey.key',
37                 'ipaddr': '172.16.0.138'
38             }
39         }
40         self.scenario_cfg = {
41             'options': {'packetsize': 60}
42         }
43
44         self._mock_SSH = mock.patch.object(ssh, 'SSH')
45         self.mock_SSH = self._mock_SSH.start()
46
47         self.mock_SSH.from_node().execute.return_value = (0, '', '')
48         self.mock_SSH.from_node().run.return_value = 0
49
50         self.addCleanup(self._stop_mock)
51
52         self.scenario = pktgen.Pktgen(self.scenario_cfg, self.context_cfg)
53         self.scenario.setup()
54
55     def _stop_mock(self):
56         self._mock_SSH.stop()
57
58     def test_setup_successful(self):
59         self.assertIsNotNone(self.scenario.server)
60         self.assertIsNotNone(self.scenario.client)
61         self.assertTrue(self.scenario.setup_done)
62
63     def test_iptables_setup_successful(self):
64         self.scenario.number_of_ports = 10
65         self.scenario._iptables_setup()
66
67         self.mock_SSH.from_node().run.assert_called_with(
68             "sudo iptables -F; "
69             "sudo iptables -A INPUT -p udp --dport 1000:%s -j DROP"
70             % 1010, timeout=60)
71
72     def test_iptables_setup_unsuccessful(self):
73         self.scenario.number_of_ports = 10
74         self.mock_SSH.from_node().run.side_effect = y_exc.SSHError
75
76         with self.assertRaises(y_exc.SSHError):
77             self.scenario._iptables_setup()
78
79     def test_iptables_get_result_successful(self):
80         self.scenario.number_of_ports = 10
81         self.mock_SSH.from_node().execute.return_value = (0, '150000', '')
82
83         result = self.scenario._iptables_get_result()
84
85         self.assertEqual(result, 150000)
86         self.mock_SSH.from_node().execute.assert_called_with(
87             "sudo iptables -L INPUT -vnx |"
88             "awk '/dpts:1000:%s/ {{printf \"%%s\", $1}}'"
89             % 1010, raise_on_error=True)
90
91     def test_iptables_get_result_unsuccessful(self):
92         self.scenario.number_of_ports = 10
93         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
94
95         with self.assertRaises(y_exc.SSHError):
96             self.scenario._iptables_get_result()
97
98     def test_run_successful_no_sla(self):
99         self.scenario._iptables_get_result = mock.Mock(return_value=149300)
100         sample_output = jsonutils.dumps({"packets_per_second": 9753,
101                                          "errors": 0,
102                                          "packets_sent": 149776,
103                                          "packetsize": 60,
104                                          "flows": 110,
105                                          "ppm": 3179})
106         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
107
108         result = {}
109         self.scenario.run(result)
110
111         expected_result = jsonutils.loads(sample_output)
112         expected_result["packets_received"] = 149300
113         expected_result["packetsize"] = 60
114         self.assertEqual(result, expected_result)
115
116     def test_run_successful_sla(self):
117         self.scenario_cfg['sla'] = {'max_ppm': 10000}
118         scenario = pktgen.Pktgen(self.scenario_cfg, self.context_cfg)
119         scenario.setup()
120         scenario._iptables_get_result = mock.Mock(return_value=149300)
121         sample_output = jsonutils.dumps({"packets_per_second": 9753,
122                                          "errors": 0,
123                                          "packets_sent": 149776,
124                                          "packetsize": 60,
125                                          "flows": 110,
126                                          "ppm": 3179})
127         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
128
129         result = {}
130         scenario.run(result)
131
132         expected_result = jsonutils.loads(sample_output)
133         expected_result["packets_received"] = 149300
134         expected_result["packetsize"] = 60
135         self.assertEqual(result, expected_result)
136
137     def test_run_unsuccessful_sla(self):
138         self.scenario_cfg['sla'] = {'max_ppm': 1000}
139         scenario = pktgen.Pktgen(self.scenario_cfg, self.context_cfg)
140         scenario.setup()
141         scenario._iptables_get_result = mock.Mock(return_value=149300)
142         sample_output = jsonutils.dumps({"packets_per_second": 9753,
143                                          "errors": 0,
144                                          "packets_sent": 149776,
145                                          "packetsize": 60,
146                                          "flows": 110})
147         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
148
149         with self.assertRaises(y_exc.SLAValidationError):
150             scenario.run({})
151
152     def test_run_ssh_error_not_caught(self):
153         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
154
155         with self.assertRaises(y_exc.SSHError):
156             self.scenario.run({})
157
158     def test_get_vnic_driver_name(self):
159         self.mock_SSH.from_node().execute.return_value = (0, 'ixgbevf', '')
160         vnic_driver_name = self.scenario._get_vnic_driver_name()
161
162         self.assertEqual(vnic_driver_name, 'ixgbevf')
163
164     def test_get_vnic_driver_name_unsuccessful(self):
165         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
166
167         with self.assertRaises(y_exc.SSHError):
168             self.scenario._get_vnic_driver_name()
169
170     def test_get_sriov_queue_number(self):
171         self.mock_SSH.from_node().execute.return_value = (0, '2', '')
172
173         self.scenario.queue_number = self.scenario._get_sriov_queue_number()
174         self.assertEqual(self.scenario.queue_number, 2)
175
176     def test_get_sriov_queue_number_unsuccessful(self):
177         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
178
179         with self.assertRaises(y_exc.SSHError):
180             self.scenario._get_sriov_queue_number()
181
182     def test_get_available_queue_number(self):
183         self.mock_SSH.from_node().execute.return_value = (0, '4', '')
184
185         self.assertEqual(self.scenario._get_available_queue_number(), 4)
186         self.mock_SSH.from_node().execute.assert_called_with(
187             "sudo ethtool -l eth0 | grep Combined | head -1 |"
188             "awk '{printf $2}'", raise_on_error=True)
189
190     def test_get_available_queue_number_unsuccessful(self):
191         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
192
193         with self.assertRaises(y_exc.SSHError):
194             self.scenario._get_available_queue_number()
195
196     def test_get_usable_queue_number(self):
197         self.mock_SSH.from_node().execute.return_value = (0, '1', '')
198
199         self.assertEqual(self.scenario._get_usable_queue_number(), 1)
200         self.mock_SSH.from_node().execute.assert_called_with(
201             "sudo ethtool -l eth0 | grep Combined | tail -1 |"
202             "awk '{printf $2}'", raise_on_error=True)
203
204     def test_get_usable_queue_number_unsuccessful(self):
205         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
206
207         with self.assertRaises(y_exc.SSHError):
208             self.scenario._get_usable_queue_number()
209
210     def test_enable_ovs_multiqueue(self):
211         self.scenario._get_usable_queue_number = mock.Mock(return_value=1)
212         self.scenario._get_available_queue_number = mock.Mock(return_value=4)
213         self.scenario.queue_number = self.scenario._enable_ovs_multiqueue()
214
215         self.assertEqual(self.scenario.queue_number, 4)
216         self.mock_SSH.from_node().run.assert_has_calls(
217             (mock.call("sudo ethtool -L eth0 combined 4"),
218              mock.call("sudo ethtool -L eth0 combined 4")))
219
220     def test_enable_ovs_multiqueue_1q(self):
221         self.scenario._get_usable_queue_number = mock.Mock(return_value=1)
222         self.scenario._get_available_queue_number = mock.Mock(return_value=1)
223         self.scenario.queue_number = self.scenario._enable_ovs_multiqueue()
224
225         self.assertEqual(self.scenario.queue_number, 1)
226         self.mock_SSH.from_node().run.assert_not_called()
227
228     def test_enable_ovs_multiqueue_unsuccessful(self):
229         self.mock_SSH.from_node().run.side_effect = y_exc.SSHError
230         self.scenario._get_usable_queue_number = mock.Mock(return_value=1)
231         self.scenario._get_available_queue_number = mock.Mock(return_value=4)
232
233         with self.assertRaises(y_exc.SSHError):
234             self.scenario._enable_ovs_multiqueue()
235
236     def test_setup_irqmapping_ovs(self):
237         self.mock_SSH.from_node().execute.return_value = (0, '10', '')
238         self.scenario._setup_irqmapping_ovs(4)
239
240         self.mock_SSH.from_node().run.assert_called_with(
241             "echo 8 | sudo tee /proc/irq/10/smp_affinity")
242
243     def test_setup_irqmapping_ovs_1q(self):
244         self.mock_SSH.from_node().execute.return_value = (0, '10', '')
245         self.scenario._setup_irqmapping_ovs(1)
246
247         self.mock_SSH.from_node().run.assert_called_with(
248             "echo 1 | sudo tee /proc/irq/10/smp_affinity")
249
250     def test_setup_irqmapping_ovs_unsuccessful(self):
251         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
252
253         with self.assertRaises(y_exc.SSHError):
254             self.scenario._setup_irqmapping_ovs(4)
255
256     def test_setup_irqmapping_ovs_1q_unsuccessful(self):
257         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
258
259         with self.assertRaises(y_exc.SSHError):
260             self.scenario._setup_irqmapping_ovs(1)
261
262     def test_setup_irqmapping_sriov(self):
263         self.mock_SSH.from_node().execute.return_value = (0, '10', '')
264         self.scenario._setup_irqmapping_sriov(2)
265
266         self.mock_SSH.from_node().run.assert_called_with(
267             "echo 2 | sudo tee /proc/irq/10/smp_affinity")
268
269     def test_setup_irqmapping_sriov_1q(self):
270         self.mock_SSH.from_node().execute.return_value = (0, '10', '')
271         self.scenario._setup_irqmapping_sriov(1)
272
273         self.mock_SSH.from_node().run.assert_called_with(
274             "echo 1 | sudo tee /proc/irq/10/smp_affinity")
275
276     def test_setup_irqmapping_sriov_unsuccessful(self):
277         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
278
279         with self.assertRaises(y_exc.SSHError):
280             self.scenario._setup_irqmapping_sriov(2)
281
282     def test_setup_irqmapping_sriov_1q_unsuccessful(self):
283         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
284
285         with self.assertRaises(y_exc.SSHError):
286             self.scenario._setup_irqmapping_sriov(1)
287
288     def test_is_irqbalance_disabled(self):
289         self.mock_SSH.from_node().execute.return_value = (0, '', '')
290
291         self.assertFalse(self.scenario._is_irqbalance_disabled())
292         self.mock_SSH.from_node().execute.assert_called_with(
293             "grep ENABLED /etc/default/irqbalance", raise_on_error=True)
294
295     def test_is_irqbalance_disabled_unsuccessful(self):
296         self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
297
298         with self.assertRaises(y_exc.SSHError):
299             self.scenario._is_irqbalance_disabled()
300
301     def test_disable_irqbalance(self):
302         self.scenario._disable_irqbalance()
303
304         self.mock_SSH.from_node().run.assert_called_with(
305             "sudo service irqbalance disable")
306
307     def test_disable_irqbalance_unsuccessful(self):
308         self.mock_SSH.from_node().run.side_effect = y_exc.SSHError
309
310         with self.assertRaises(y_exc.SSHError):
311             self.scenario._disable_irqbalance()
312
313     def test_multiqueue_setup_ovs(self):
314         self.mock_SSH.from_node().execute.return_value = (0, '4', '')
315         self.scenario._is_irqbalance_disabled = mock.Mock(return_value=False)
316         self.scenario._get_vnic_driver_name = mock.Mock(
317             return_value="virtio_net")
318         self.scenario._get_usable_queue_number = mock.Mock(return_value=1)
319         self.scenario._get_available_queue_number = mock.Mock(return_value=4)
320
321         self.scenario.multiqueue_setup()
322
323         self.assertEqual(self.scenario.queue_number, 4)
324         self.assertTrue(self.scenario.multiqueue_setup_done)
325
326     def test_multiqueue_setup_ovs_1q(self):
327         self.mock_SSH.from_node().execute.return_value = (0, '1', '')
328         self.scenario._is_irqbalance_disabled = mock.Mock(return_value=False)
329         self.scenario._get_vnic_driver_name = mock.Mock(
330             return_value="virtio_net")
331         self.scenario._get_usable_queue_number = mock.Mock(return_value=1)
332         self.scenario._get_available_queue_number = mock.Mock(return_value=1)
333
334         self.scenario.multiqueue_setup()
335
336         self.assertEqual(self.scenario.queue_number, 1)
337         self.assertTrue(self.scenario.multiqueue_setup_done)
338
339     def test_multiqueue_setup_sriov(self):
340         self.mock_SSH.from_node().execute.return_value = (0, '2', '')
341         self.scenario._is_irqbalance_disabled = mock.Mock(return_value=False)
342         self.scenario._get_vnic_driver_name = mock.Mock(return_value="ixgbevf")
343
344         self.scenario.multiqueue_setup()
345
346         self.assertEqual(self.scenario.queue_number, 2)
347         self.assertTrue(self.scenario.multiqueue_setup_done)
348
349     def test_multiqueue_setup_sriov_1q(self):
350         self.mock_SSH.from_node().execute.return_value = (0, '1', '')
351         self.scenario._is_irqbalance_disabled = mock.Mock(return_value=False)
352         self.scenario._get_vnic_driver_name = mock.Mock(return_value="ixgbevf")
353
354         self.scenario.multiqueue_setup()
355
356         self.assertEqual(self.scenario.queue_number, 1)
357         self.assertTrue(self.scenario.multiqueue_setup_done)
358
359     def test_run_with_setup_done(self):
360         scenario_cfg = {
361             'options': {
362                 'packetsize': 60,
363                 'number_of_ports': 10,
364                 'duration': 20,
365                 'multiqueue': True},
366             'sla': {
367                 'max_ppm': 1}
368         }
369         scenario = pktgen.Pktgen(scenario_cfg, self.context_cfg)
370         scenario.server = self.mock_SSH.from_node()
371         scenario.client = self.mock_SSH.from_node()
372         scenario.setup_done = True
373         scenario.multiqueue_setup_done = True
374         scenario._iptables_get_result = mock.Mock(return_value=149300)
375
376         sample_output = jsonutils.dumps({"packets_per_second": 9753,
377                                          "errors": 0,
378                                          "packets_sent": 149300,
379                                          "flows": 110,
380                                          "ppm": 0})
381         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
382
383         result = {}
384         scenario.run(result)
385
386         expected_result = jsonutils.loads(sample_output)
387         expected_result["packets_received"] = 149300
388         expected_result["packetsize"] = 60
389         self.assertEqual(result, expected_result)
390
391     def test_run_with_ovs_multiqueque(self):
392         scenario_cfg = {
393             'options': {
394                 'packetsize': 60,
395                 'number_of_ports': 10,
396                 'duration': 20,
397                 'multiqueue': True},
398             'sla': {'max_ppm': 1}
399         }
400         scenario = pktgen.Pktgen(scenario_cfg, self.context_cfg)
401         scenario.setup()
402         scenario._get_vnic_driver_name = mock.Mock(return_value="virtio_net")
403         scenario._get_usable_queue_number = mock.Mock(return_value=1)
404         scenario._get_available_queue_number = mock.Mock(return_value=4)
405         scenario._enable_ovs_multiqueue = mock.Mock(return_value=4)
406         scenario._setup_irqmapping_ovs = mock.Mock()
407         scenario._iptables_get_result = mock.Mock(return_value=149300)
408
409         sample_output = jsonutils.dumps({"packets_per_second": 9753,
410                                          "errors": 0,
411                                          "packets_sent": 149300,
412                                          "flows": 110,
413                                          "ppm": 0})
414         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
415
416         result = {}
417         scenario.run(result)
418
419         expected_result = jsonutils.loads(sample_output)
420         expected_result["packets_received"] = 149300
421         expected_result["packetsize"] = 60
422         self.assertEqual(result, expected_result)
423
424     def test_run_with_sriov_multiqueque(self):
425         scenario_cfg = {
426             'options': {
427                 'packetsize': 60,
428                 'number_of_ports': 10,
429                 'duration': 20,
430                 'multiqueue': True},
431             'sla': {'max_ppm': 1}
432         }
433         scenario = pktgen.Pktgen(scenario_cfg, self.context_cfg)
434         scenario.setup()
435         scenario._get_vnic_driver_name = mock.Mock(return_value="ixgbevf")
436         scenario._get_sriov_queue_number = mock.Mock(return_value=2)
437         scenario._setup_irqmapping_sriov = mock.Mock()
438         scenario._iptables_get_result = mock.Mock(return_value=149300)
439
440         sample_output = jsonutils.dumps({"packets_per_second": 9753,
441                                          "errors": 0,
442                                          "packets_sent": 149300,
443                                          "flows": 110,
444                                          "ppm": 0})
445         self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
446
447         result = {}
448         scenario.run(result)
449
450         expected_result = jsonutils.loads(sample_output)
451         expected_result["packets_received"] = 149300
452         expected_result["packetsize"] = 60
453         self.assertEqual(result, expected_result)