Merge "Addition of IRQ Mode to NSB NFVI (PROX)"
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_prox_helpers.py
1 # Copyright (c) 2016-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 from itertools import repeat, chain
16 import os
17 import socket
18 import time
19
20 import mock
21 import unittest
22
23 from yardstick.common import utils
24 from yardstick.network_services import constants
25 from yardstick.network_services.vnf_generic.vnf import base as vnf_base
26 from yardstick.network_services.vnf_generic.vnf import prox_helpers
27 from yardstick.network_services.vnf_generic.vnf import sample_vnf
28
29
30 class TestCoreTuple(unittest.TestCase):
31     def test___init__(self):
32         core_tuple = prox_helpers.CoreSocketTuple('core 5s6')
33         self.assertEqual(core_tuple.core_id, 5)
34         self.assertEqual(core_tuple.socket_id, 6)
35         self.assertFalse(core_tuple.is_hyperthread())
36
37         core_tuple = prox_helpers.CoreSocketTuple('core 5s6h')
38         self.assertEqual(core_tuple.core_id, 5)
39         self.assertEqual(core_tuple.socket_id, 6)
40         self.assertTrue(core_tuple.is_hyperthread())
41
42     def test___init__negative(self):
43         bad_inputs = [
44             '',
45             '5',
46             '5s',
47             '6h',
48             '5s6',
49             'core',
50             'core h',
51             'core 5s',
52             'core 5 6',
53             'core 5 6h',
54             'core 5d6',
55             'core 5d6h',
56             1,
57             2.3,
58             [],
59             {},
60             object(),
61         ]
62
63         for bad_input in bad_inputs:
64             with self.assertRaises(ValueError):
65                 prox_helpers.CoreSocketTuple(bad_input)
66
67     def test_find_in_topology(self):
68         topology_in = {
69             6: {
70                 5: {
71                     'key1': ['a', 'b'],
72                     'key2': ['c', 'd'],
73                 },
74             },
75         }
76
77         core_tuple = prox_helpers.CoreSocketTuple('core 5s6')
78
79         expected = 'a'
80         result = core_tuple.find_in_topology(topology_in)
81         self.assertEqual(result, expected)
82
83         core_tuple = prox_helpers.CoreSocketTuple('core 5s6h')
84
85         expected = 'c'
86         result = core_tuple.find_in_topology(topology_in)
87         self.assertEqual(result, expected)
88
89     def test_find_in_topology_negative(self):
90         core_tuple = prox_helpers.CoreSocketTuple('core 6s5')
91         with self.assertRaises(ValueError):
92             # no socket key
93             core_tuple.find_in_topology({})
94
95         with self.assertRaises(ValueError):
96             # no core key
97             core_tuple.find_in_topology({5: {}})
98
99         with self.assertRaises(ValueError):
100             # no first value (as needed by non-hyperthread core)
101             core_tuple.find_in_topology({5: {6: {'key1': []}}})
102
103         core_tuple = prox_helpers.CoreSocketTuple('core 6s5h')
104         with self.assertRaises(ValueError):
105             # no second value (as needed by hyperthread core)
106             core_tuple.find_in_topology({5: {6: {'key1': ['e']}}})
107
108
109 class TestTotStatsTuple(unittest.TestCase):
110     def test___new___negative(self):
111         with self.assertRaises(TypeError):
112             # no values
113             prox_helpers.TotStatsTuple()
114
115         with self.assertRaises(TypeError):
116             # one, non-integer value
117             prox_helpers.TotStatsTuple('a')
118
119         with self.assertRaises(TypeError):
120             # too many values
121             prox_helpers.TotStatsTuple(3, 4, 5, 6, 7)
122
123
124 class TestProxTestDataTuple(unittest.TestCase):
125     def test___init__(self):
126         prox_test_data = prox_helpers.ProxTestDataTuple(
127             1, 2, 3, 4, 5, 6, 7, 8, 9)
128         self.assertEqual(prox_test_data.tolerated, 1)
129         self.assertEqual(prox_test_data.tsc_hz, 2)
130         self.assertEqual(prox_test_data.delta_rx, 3)
131         self.assertEqual(prox_test_data.delta_tx, 4)
132         self.assertEqual(prox_test_data.delta_tsc, 5)
133         self.assertEqual(prox_test_data.latency, 6)
134         self.assertEqual(prox_test_data.rx_total, 7)
135         self.assertEqual(prox_test_data.tx_total, 8)
136         self.assertEqual(prox_test_data.requested_pps, 9)
137
138     def test_properties(self):
139         prox_test_data = prox_helpers.ProxTestDataTuple(
140             1, 2, 3, 4, 5, 6, 7, 8, 9)
141         self.assertEqual(prox_test_data.pkt_loss, 12.5)
142         self.assertEqual(prox_test_data.tx_mpps, 1.6 / 1e6)
143         self.assertEqual(prox_test_data.can_be_lost, 0)
144         self.assertEqual(prox_test_data.drop_total, 1)
145         self.assertFalse(prox_test_data.success)
146
147         prox_test_data = prox_helpers.ProxTestDataTuple(
148             10, 2, 3, 4, 5, 6, 997, 998, 9)
149         self.assertTrue(prox_test_data.success)
150
151     def test_pkt_loss_zero_division(self):
152         prox_test_data = prox_helpers.ProxTestDataTuple(
153             1, 2, 3, 4, 5, 6, 7, 0, 9)
154         self.assertEqual(prox_test_data.pkt_loss, 100.0)
155
156     def test_get_samples(self):
157         prox_test_data = prox_helpers.ProxTestDataTuple(
158             1, 2, 3, 4, 5, [6.1, 6.9, 6.4], 7, 8, 9)
159
160         expected = {
161             "Throughput": 1.2 / 1e6,
162             "DropPackets": 12.5,
163             "CurrentDropPackets": 12.5,
164             "RequestedTxThroughput": 9 / 1e6,
165             "TxThroughput": 1.6 / 1e6,
166             "RxThroughput": 1.2 / 1e6,
167             "PktSize": 64,
168             "PortSample": 1,
169             "LatencyMin": 6.1,
170             "LatencyMax": 6.9,
171             "LatencyAvg": 6.4,
172         }
173         result = prox_test_data.get_samples(64, port_samples={"PortSample": 1})
174         self.assertDictEqual(result, expected)
175
176         expected = {
177             "Throughput": 1.2 / 1e6,
178             "DropPackets": 0.123,
179             "CurrentDropPackets": 0.123,
180             "RequestedTxThroughput": 9 / 1e6,
181             "TxThroughput": 1.6 / 1e6,
182             "RxThroughput": 1.2 / 1e6,
183             "PktSize": 64,
184             "LatencyMin": 6.1,
185             "LatencyMax": 6.9,
186             "LatencyAvg": 6.4,
187         }
188         result = prox_test_data.get_samples(64, 0.123)
189         self.assertDictEqual(result, expected)
190
191     @mock.patch('yardstick.LOG_RESULT', create=True)
192     def test_log_data(self, mock_logger):
193         my_mock_logger = mock.MagicMock()
194         prox_test_data = prox_helpers.ProxTestDataTuple(
195             1, 2, 3, 4, 5, [6.1, 6.9, 6.4], 7, 8, 9)
196         prox_test_data.log_data()
197
198         my_mock_logger.debug.assert_not_called()
199         mock_logger.debug.assert_not_called()
200
201         mock_logger.debug.reset_mock()
202         prox_test_data.log_data(my_mock_logger)
203         my_mock_logger.assert_not_called()
204         mock_logger.debug.assert_not_called()
205
206
207 class TestPacketDump(unittest.TestCase):
208     PAYLOAD = "payload"
209
210     def test__init__(self):
211         prox_helpers.PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
212
213     def test___str__(self):
214         expected = '<PacketDump port: port_id payload: {}>'.format(self.PAYLOAD)
215         dump1 = prox_helpers.PacketDump(
216             "port_id", len(self.PAYLOAD), self.PAYLOAD)
217         self.assertEqual(str(dump1), expected)
218
219     def test_port_id(self):
220         p = prox_helpers.PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
221         self.assertEqual(p.port_id, "port_id")
222
223     def test_data_len(self):
224         p = prox_helpers.PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
225         self.assertEqual(p.data_len, len(self.PAYLOAD))
226
227     def test_payload(self):
228         p = prox_helpers.PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
229         self.assertEqual(p.payload(), self.PAYLOAD)
230
231         self.assertEqual(p.payload(3), self.PAYLOAD[3:])
232
233         self.assertEqual(p.payload(end=3), self.PAYLOAD[:4])
234
235         self.assertEqual(p.payload(2, 4), self.PAYLOAD[2:5])
236
237
238 PACKET_DUMP_1 = """\
239 pktdump,3,11
240 hello world
241 """
242
243 PACKET_DUMP_2 = """\
244 pktdump,3,11
245 hello world
246 pktdump,2,9
247 brown fox jumped over
248 pktdump,4,8
249 lazy
250 dog
251 """
252
253 PACKET_DUMP_NON_1 = """\
254 not_a_dump,1,2
255 other data
256 """
257
258 PACKET_DUMP_MIXED_1 = """\
259 pktdump,3,11
260 hello world
261 not_a_dump,1,2
262 other data
263 """
264
265 PACKET_DUMP_BAD_1 = """\
266 pktdump,one,12
267 bad port id
268 """
269
270 PACKET_DUMP_BAD_2 = """\
271 pktdump,3,twelve
272 bad data length
273 """
274
275 PACKET_DUMP_BAD_3 = """\
276 pktdump,3
277 no data length value
278 """
279
280
281 class TestProxSocketHelper(unittest.TestCase):
282
283     def setUp(self):
284         self._mock_time_sleep = mock.patch.object(time, 'sleep')
285         self.mock_time_sleep = self._mock_time_sleep.start()
286         self.addCleanup(self._stop_mocks)
287
288     def _stop_mocks(self):
289         self._mock_time_sleep.stop()
290
291     @mock.patch.object(prox_helpers, 'socket')
292     def test___init__(self, mock_socket):
293         expected = mock_socket.socket()
294         prox = prox_helpers.ProxSocketHelper()
295         result = prox._sock
296         self.assertEqual(result, expected)
297
298     def test_connect(self):
299         mock_sock = mock.MagicMock()
300         prox = prox_helpers.ProxSocketHelper(mock_sock)
301         prox.connect('10.20.30.40', 23456)
302         mock_sock.connect.assert_called_once()
303
304     def test_get_sock(self):
305         mock_sock = mock.MagicMock()
306         prox = prox_helpers.ProxSocketHelper(mock_sock)
307         result = prox.get_socket()
308         self.assertIs(result, mock_sock)
309
310     # TODO(elfoley): Split this into three tests
311     @mock.patch.object(prox_helpers, 'select')
312     def test_get_data(self, mock_select):
313         mock_select.select.side_effect = [[1], [0]]
314         mock_socket = mock.MagicMock()
315         mock_recv = mock_socket.recv()
316         mock_recv.decode.return_value = ""
317         prox = prox_helpers.ProxSocketHelper(mock_socket)
318         ret = prox.get_data()
319         self.assertEqual(ret, "")
320         self.assertEqual(len(prox._pkt_dumps), 0)
321
322         mock_select.select.reset_mock()
323         mock_select.select.side_effect = chain([['a'], ['']],
324                                                repeat([1], 3))
325         mock_recv.decode.return_value = PACKET_DUMP_1
326         ret = prox.get_data()
327         self.assertEqual(mock_select.select.call_count, 2)
328         self.assertEqual(ret, 'pktdump,3,11')
329         self.assertEqual(len(prox._pkt_dumps), 1)
330
331         mock_select.select.reset_mock()
332         mock_select.select.side_effect = chain([[object()], [None]],
333                                                repeat([1], 3))
334         mock_recv.decode.return_value = PACKET_DUMP_2
335         ret = prox.get_data()
336         self.assertEqual(mock_select.select.call_count, 1)
337         self.assertEqual(ret, 'jumped over')
338         self.assertEqual(len(prox._pkt_dumps), 3)
339
340     @mock.patch.object(prox_helpers, 'select')
341     def test_get_string(self, mock_select):
342         mock_select.select.side_effect = [[1], [0]]
343         mock_socket = mock.MagicMock()
344         mock_recv = mock_socket.recv()
345         mock_recv.decode.return_value = ""
346         prox = prox_helpers.ProxSocketHelper(mock_socket)
347         status, ret = prox.get_string()
348         self.assertEqual(ret, "")
349         self.assertTrue(status)
350         self.assertEqual(len(prox._pkt_dumps), 0)
351
352     @mock.patch.object(prox_helpers, 'select')
353     def test_get_string2(self, mock_select):
354         mock_select.select.side_effect = chain([['a'], ['']],
355                                                repeat([1], 3))
356         mock_socket = mock.MagicMock()
357         mock_recv = mock_socket.recv()
358         mock_recv.decode.return_value = PACKET_DUMP_1
359         prox = prox_helpers.ProxSocketHelper(mock_socket)
360         status, ret = prox.get_string()
361         self.assertEqual(mock_select.select.call_count, 2)
362         self.assertEqual(ret, 'pktdump,3,11')
363         self.assertTrue(status)
364         self.assertEqual(len(prox._pkt_dumps), 1)
365
366     @mock.patch.object(prox_helpers, 'select')
367     def test_get_string3(self, mock_select):
368         mock_select.select.side_effect = chain([[object()], [None]],
369                                                repeat([1], 3))
370         mock_socket = mock.MagicMock()
371         mock_recv = mock_socket.recv()
372         mock_recv.decode.return_value = PACKET_DUMP_2
373         prox = prox_helpers.ProxSocketHelper(mock_socket)
374         status, ret = prox.get_string()
375         self.assertTrue(status)
376         self.assertTrue(mock_select.select.assert_called_once)
377         self.assertEqual(ret, 'jumped over')
378         self.assertEqual(len(prox._pkt_dumps), 2)
379
380     def test__parse_socket_data_mixed_data(self):
381         prox = prox_helpers.ProxSocketHelper(mock.MagicMock())
382         ret, _ = prox._parse_socket_data(PACKET_DUMP_NON_1, False)
383         self.assertEqual(ret, 'not_a_dump,1,2')
384         self.assertEqual(len(prox._pkt_dumps), 0)
385
386         ret, _ = prox._parse_socket_data(PACKET_DUMP_MIXED_1, False)
387         self.assertEqual(ret, 'not_a_dump,1,2')
388         self.assertEqual(len(prox._pkt_dumps), 1)
389
390     def test__parse_socket_data_bad_data(self):
391         prox = prox_helpers.ProxSocketHelper(mock.MagicMock())
392         with self.assertRaises(ValueError):
393             prox._parse_socket_data(PACKET_DUMP_BAD_1, False)
394
395         with self.assertRaises(ValueError):
396             prox._parse_socket_data(PACKET_DUMP_BAD_2, False)
397
398         ret, _ = prox._parse_socket_data(PACKET_DUMP_BAD_3, False)
399         self.assertEqual(ret, 'pktdump,3')
400
401     def test__parse_socket_data_pkt_dump_only(self):
402         prox = prox_helpers.ProxSocketHelper(mock.MagicMock())
403         ret, _ = prox._parse_socket_data('', True)
404         self.assertFalse(ret)
405
406         ret, _ = prox._parse_socket_data(PACKET_DUMP_1, True)
407         self.assertTrue(ret)
408
409         ret, _ = prox._parse_socket_data(PACKET_DUMP_2, True)
410         self.assertTrue(ret)
411
412     def test_put_command(self):
413         mock_socket = mock.MagicMock()
414         prox = prox_helpers.ProxSocketHelper(mock_socket)
415         prox.put_command("data")
416         mock_socket.sendall.assert_called_once()
417
418     def test_put_command_socket_error(self):
419         mock_socket = mock.MagicMock()
420         mock_socket.sendall.side_effect = OSError
421         prox = prox_helpers.ProxSocketHelper(mock_socket)
422         prox.put_command("data")
423         mock_socket.sendall.assert_called_once()
424
425     def test_get_packet_dump(self):
426         mock_socket = mock.MagicMock()
427         prox = prox_helpers.ProxSocketHelper(mock_socket)
428         prox._pkt_dumps = []
429         self.assertIsNone(prox.get_packet_dump())
430
431         prox._pkt_dumps = [234]
432         self.assertEqual(prox.get_packet_dump(), 234)
433         self.assertEqual(prox._pkt_dumps, [])
434
435     def test_stop_all_reset(self):
436         mock_socket = mock.MagicMock()
437         prox = prox_helpers.ProxSocketHelper(mock_socket)
438         prox.stop_all_reset()
439         mock_socket.sendall.assert_called()
440
441     def test_stop_all(self):
442         mock_socket = mock.MagicMock()
443         prox = prox_helpers.ProxSocketHelper(mock_socket)
444         prox.stop_all()
445         mock_socket.sendall.assert_called()
446
447     def test_stop(self):
448         mock_socket = mock.MagicMock()
449         prox = prox_helpers.ProxSocketHelper(mock_socket)
450         prox.stop([3, 4, 5], 16)
451         mock_socket.sendall.assert_called()
452
453     def test_start_all(self):
454         mock_socket = mock.MagicMock()
455         prox = prox_helpers.ProxSocketHelper(mock_socket)
456         prox.start_all()
457         mock_socket.sendall.assert_called()
458
459     def test_start(self):
460         mock_socket = mock.MagicMock()
461         prox = prox_helpers.ProxSocketHelper(mock_socket)
462         prox.start([3, 4, 5])
463         mock_socket.sendall.assert_called()
464
465     def test_reset_stats(self):
466         mock_socket = mock.MagicMock()
467         prox = prox_helpers.ProxSocketHelper(mock_socket)
468         prox.reset_stats()
469         mock_socket.sendall.assert_called()
470
471     def test_set_pkt_size(self):
472         mock_socket = mock.MagicMock()
473         prox = prox_helpers.ProxSocketHelper(mock_socket)
474         prox.set_pkt_size([3, 4, 5], 1024)
475         self.assertEqual(mock_socket.sendall.call_count, 3)
476
477     def test_set_value(self):
478         mock_socket = mock.MagicMock()
479         prox = prox_helpers.ProxSocketHelper(mock_socket)
480         prox.set_value([3, 4, 5], 10, 20, 30)
481         self.assertEqual(mock_socket.sendall.call_count, 3)
482
483     def test_reset_values(self):
484         mock_socket = mock.MagicMock()
485         prox = prox_helpers.ProxSocketHelper(mock_socket)
486         prox.reset_values([3, 4, 5])
487         self.assertEqual(mock_socket.sendall.call_count, 3)
488
489     def test_set_speed(self):
490         mock_socket = mock.MagicMock()
491         prox = prox_helpers.ProxSocketHelper(mock_socket)
492         prox.set_speed([3, 4, 5], 1000)
493         self.assertEqual(mock_socket.sendall.call_count, 3)
494
495     def test_slope_speed(self):
496         core_data = [
497             {
498                 'cores': [3, 4, 5],
499                 'speed': 1000,
500             },
501             {
502                 'cores': [9, 10, 11],
503                 'speed': '500.5',
504             },
505         ]
506
507         mock_socket = mock.MagicMock()
508         prox = prox_helpers.ProxSocketHelper(mock_socket)
509         prox.set_speed = set_speed = mock.MagicMock()
510         prox.slope_speed(core_data, 5)
511         self.assertEqual(set_speed.call_count, 20)
512
513         set_speed.reset_mock()
514         prox.slope_speed(core_data, 5, 5)
515         self.assertEqual(set_speed.call_count, 10)
516
517     def test_set_pps(self):
518         mock_socket = mock.MagicMock()
519         prox = prox_helpers.ProxSocketHelper(mock_socket)
520         prox.set_pps([3, 4, 5], 1000, 512)
521         self.assertEqual(mock_socket.sendall.call_count, 3)
522
523     def test_lat_stats(self):
524         latency_output = [
525             '1, 2 , 3',  # has white space
526             '4,5',  # too short
527             '7,8,9,10.5,11',  # too long with float, but float is in unused portion
528             'twelve,13,14',  # value as English word
529             '15,16.2,17',  # float in used portion
530         ]
531
532         mock_socket = mock.MagicMock()
533         prox = prox_helpers.ProxSocketHelper(mock_socket)
534         prox.get_data = mock.MagicMock(side_effect=latency_output)
535
536         expected = (
537             {
538                 3: 1,
539                 5: 7,
540             },
541             {
542                 3: 2,
543                 5: 8,
544             },
545             {
546                 3: 3,
547                 5: 9,
548             },
549         )
550         result = prox.lat_stats([3, 4, 5, 6, 7], 16)
551         self.assertEqual(mock_socket.sendall.call_count, 5)
552         self.assertEqual(result, expected)
553
554     def test_get_all_tot_stats_error(self):
555         mock_socket = mock.MagicMock()
556         prox = prox_helpers.ProxSocketHelper(mock_socket)
557         prox.get_data = mock.MagicMock(return_value='3,4,5')
558         expected = [0, 0, 0, 0]
559         result = prox.get_all_tot_stats()
560         self.assertEqual(result, expected)
561
562     def test_get_all_tot_stats(self):
563         mock_socket = mock.MagicMock()
564         prox = prox_helpers.ProxSocketHelper(mock_socket)
565         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
566         expected = 3, 4, 5, 6
567         result = prox.get_all_tot_stats()
568         self.assertEqual(result, expected)
569
570     def test_hz(self):
571         mock_socket = mock.MagicMock()
572         prox = prox_helpers.ProxSocketHelper(mock_socket)
573         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
574         expected = 6
575         result = prox.hz()
576         self.assertEqual(result, expected)
577
578     def test_core_stats(self):
579         core_stats = [
580             '3,4,5,6',
581             '7,8,9,10,NaN',
582             '11,12,13,14,15',
583         ]
584
585         mock_socket = mock.MagicMock()
586         prox = prox_helpers.ProxSocketHelper(mock_socket)
587         prox.get_data = mock.MagicMock(side_effect=core_stats)
588         expected = 21, 24, 27, 14
589         result = prox.core_stats([3, 4, 5], 16)
590         self.assertEqual(result, expected)
591
592     @mock.patch.object(prox_helpers.LOG, 'error')
593     def test_irq_core_stats(self, *args):
594         mock_socket = mock.MagicMock()
595         prox = prox_helpers.ProxSocketHelper(mock_socket)
596         prox.get_data = mock.MagicMock(return_value=('0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3'))
597
598         data_0 = {"cpu": 0, 'bucket_0': 1, 'bucket_1': 2, 'bucket_2': 3, 'bucket_3': 4,
599                   'bucket_4': 5, 'bucket_5': 0, 'bucket_6': 1, 'bucket_7': 2, 'bucket_8': 3,
600                   'bucket_9': 4, 'bucket_10': 5, 'bucket_11': 0, 'bucket_12': 1,
601                   "max_irq": 0, "overflow": 10}
602
603         data_1 = {"cpu": 1, 'bucket_0': 1, 'bucket_1': 2, 'bucket_2': 3, 'bucket_3': 4,
604                   'bucket_4': 5, 'bucket_5': 0, 'bucket_6': 1, 'bucket_7': 2, 'bucket_8': 3,
605                   'bucket_9': 4, 'bucket_10': 5, 'bucket_11': 0, 'bucket_12': 1,
606                   "max_irq": 0, "overflow": 10}
607
608         expected = {"core_0": data_0, "core_1": data_1}
609
610         result = prox.irq_core_stats([[0, 1], [1, 0]])
611         self.assertDictEqual(result, expected)
612
613     @mock.patch.object(prox_helpers.LOG, 'error')
614     def test_multi_port_stats(self, *args):
615         mock_socket = mock.MagicMock()
616         prox = prox_helpers.ProxSocketHelper(mock_socket)
617         prox.get_string = mock.MagicMock(return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5'))
618         expected = [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]]
619         status, result = prox.multi_port_stats([0, 1])
620         self.assertEqual(result, expected)
621         self.assertEqual(status, True)
622
623         prox.get_string = mock.MagicMock(
624             return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5'))
625         status, result = prox.multi_port_stats([0])
626         self.assertEqual(status, False)
627
628         prox.get_string = mock.MagicMock(
629             return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5'))
630         status, result = prox.multi_port_stats([0, 1, 2])
631         self.assertEqual(status, False)
632
633         prox.get_string = mock.MagicMock(
634             return_value=(True, '0,1,2,3;1,1,2,3,4,5'))
635         status, result = prox.multi_port_stats([0, 1])
636         self.assertEqual(status, False)
637
638         prox.get_string = mock.MagicMock(
639             return_value=(True, '99,1,2,3,4,5;1,1,2,3,4,5'))
640         status, result = prox.multi_port_stats([0, 1])
641         self.assertEqual(status, False)
642
643         prox.get_string = mock.MagicMock(
644             return_value=(True, '99,1,2,3,4,5;1,1,2,3,4,5'))
645         status, result = prox.multi_port_stats([99, 1])
646         expected = [[99, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]]
647         self.assertEqual(status, True)
648         self.assertEqual(result, expected)
649
650         prox.get_string = mock.MagicMock(
651             return_value=(True,
652                           '2,21,22,23,24,25;1,11,12,13,14,15;0,1,2,3,4,5'))
653
654         sample1 = [0, 1, 2, 3, 4, 5]
655         sample2 = [1, 11, 12, 13, 14, 15]
656         sample3 = [2, 21, 22, 23, 24, 25]
657         expected = [sample3, sample2, sample1]
658         status, result = prox.multi_port_stats([1, 2, 0])
659         self.assertTrue(status)
660         self.assertListEqual(result, expected)
661
662         prox.get_string = mock.MagicMock(
663             return_value=(True, '6,21,22,23,24,25;1,11,12,13,14,15;0,1,2,3,4,5'))
664         ok, result = prox.multi_port_stats([1, 6, 0])
665         sample1 = [6, 21, 22, 23, 24, 25]
666         sample2 = [1, 11, 12, 13, 14, 15]
667         sample3 = [0, 1, 2, 3, 4, 5]
668         expected = [sample1, sample2, sample3]
669         self.assertListEqual(result, expected)
670         self.assertTrue(ok)
671
672     @mock.patch.object(prox_helpers.LOG, 'error')
673     def test_multi_port_stats_diff(self, *args):
674         mock_socket = mock.MagicMock()
675         prox = prox_helpers.ProxSocketHelper(mock_socket)
676         prox.get_string = mock.MagicMock(return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5'))
677         _, t1 = prox.multi_port_stats([0, 1])
678
679         prox.get_string = mock.MagicMock(return_value=(True, '0,2,4,6,8,6;1,4,8,16,32,6'))
680         _, t2 = prox.multi_port_stats([0, 1])
681
682         prox.get_string = mock.MagicMock(return_value=(True, '0,1,1,1,1,1;1,1,1,1,1,1'))
683         _, t3 = prox.multi_port_stats([0, 1])
684
685         prox.get_string = mock.MagicMock(return_value=(True, '0,2,2,2,2,2;1,2,2,2,2,2'))
686         _, t4 = prox.multi_port_stats([0, 1])
687
688         expected = [[0, 1.0, 2.0, 0, 0, 1], [1, 3.0, 6.0, 0, 0, 1]]
689         result = prox.multi_port_stats_diff(t1, t2, 1)
690
691         self.assertListEqual(result, expected)
692
693         result = prox.multi_port_stats_diff(t4, t3, 1)
694         expected = [[0, 1.0, 1.0, 0, 0, 1], [1, 1.0, 1.0, 0, 0, 1]]
695
696         self.assertListEqual(result, expected)
697
698         prox.get_string = mock.MagicMock(return_value=(True, '0,2,4,6,8,10'))
699         ok, t5 = prox.multi_port_stats([0, 1])
700         self.assertFalse(ok)
701         self.assertListEqual(t5, [])
702
703         result = prox.multi_port_stats_diff(t5, t4, 1)
704         expected = [[0, 0.0, 0.0, 0, 0, 0], [1, 0.0, 0.0, 0, 0, 0]]
705         self.assertListEqual(result, expected)
706
707         prox.get_string = mock.MagicMock(return_value=(True, '0,10,10,20,30,0;1,30,40,50,60,0'))
708         _, t6 = prox.multi_port_stats([0, 1])
709
710         prox.get_string = \
711             mock.MagicMock(return_value=(True, '0,100,100,100,100,0;1,100,100,100,100,0'))
712         _, t7 = prox.multi_port_stats([0, 1])
713
714         result = prox.multi_port_stats_diff(t6, t7, 1)
715         expected = [[0, 0.0, 0.0, 0, 0, 0], [1, 0.0, 0.0, 0, 0, 0]]
716         self.assertListEqual(result, expected)
717
718         result = prox.multi_port_stats_diff(t1, t2, 0)
719         expected = [[0, 0.0, 0.0, 0, 0, 1], [1, 0.0, 0.0, 0, 0, 1]]
720         self.assertListEqual(result, expected)
721
722     @mock.patch.object(prox_helpers.LOG, 'error')
723     def test_multi_port_stats_tuple(self, *args):
724         mock_socket = mock.MagicMock()
725         prox = prox_helpers.ProxSocketHelper(mock_socket)
726         prox.get_string = mock.MagicMock(return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5'))
727         _, result1 = prox.multi_port_stats([0, 1])
728         prox.get_string = mock.MagicMock(return_value=(True, '0,2,4,6,8,6;1,4,8,16,32,6'))
729         _, result2 = prox.multi_port_stats([0, 1])
730
731         result = prox.multi_port_stats_diff(result1, result2, 1)
732
733         vnfd_helper = mock.MagicMock()
734         vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
735
736         expected = {'xe0': {'in_packets': 1.0, 'out_packets': 2.0},
737                     'xe1': {'in_packets': 3.0, 'out_packets': 6.0}}
738         live_stats = prox.multi_port_stats_tuple(result, vnfd_helper.ports_iter())
739         self.assertDictEqual(live_stats, expected)
740
741         live_stats = prox.multi_port_stats_tuple(result, None)
742         expected = {}
743         self.assertDictEqual(live_stats, expected)
744
745         live_stats = prox.multi_port_stats_tuple(None, vnfd_helper.ports_iter())
746         self.assertDictEqual(live_stats, expected)
747
748     def test_port_stats(self):
749         port_stats = [
750             ','.join(str(n) for n in range(3, 15)),
751             ','.join(str(n) for n in range(8, 32, 2)),
752             ','.join(str(n) for n in range(5, 89, 7)),
753         ]
754
755         mock_socket = mock.MagicMock()
756         prox = prox_helpers.ProxSocketHelper(mock_socket)
757         prox.get_data = mock.MagicMock(side_effect=port_stats)
758         expected = [16, 26, 36, 46, 56, 66, 76, 86, 96, 106, 116, 126]
759         result = prox.port_stats([3, 4, 5])
760         self.assertEqual(result, expected)
761
762     def test_measure_tot_stats(self):
763         start_tot = 3, 4, 5, 6
764         end_tot = 7, 9, 11, 13
765         delta_tot = 4, 5, 6, 7
766
767         get_data_output = [
768             ','.join(str(n) for n in start_tot),
769             ','.join(str(n) for n in end_tot),
770         ]
771
772         mock_socket = mock.MagicMock()
773         prox = prox_helpers.ProxSocketHelper(mock_socket)
774         prox.get_data = mock.MagicMock(side_effect=get_data_output)
775         expected = {
776             'start_tot': start_tot,
777             'end_tot': end_tot,
778             'delta': delta_tot,
779         }
780         with prox.measure_tot_stats() as result:
781             pass
782         self.assertEqual(result, expected)
783
784     def test_tot_stats(self):
785         mock_socket = mock.MagicMock()
786         prox = prox_helpers.ProxSocketHelper(mock_socket)
787         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
788         expected = 3, 4, 5
789         result = prox.tot_stats()
790         self.assertEqual(result, expected)
791
792     def test_tot_ierrors(self):
793         mock_socket = mock.MagicMock()
794         prox = prox_helpers.ProxSocketHelper(mock_socket)
795         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
796         expected = 3, 3
797         result = prox.tot_ierrors()
798         self.assertEqual(result, expected)
799
800     def test_set_count(self):
801         mock_socket = mock.MagicMock()
802         prox = prox_helpers.ProxSocketHelper(mock_socket)
803         prox.set_count(432, [3, 4, 5])
804         self.assertEqual(mock_socket.sendall.call_count, 3)
805
806     def test_dump_rx(self):
807         mock_socket = mock.MagicMock()
808         prox = prox_helpers.ProxSocketHelper(mock_socket)
809         prox.dump_rx(3, 5, 8)
810         mock_socket.sendall.assert_called_once()
811
812     def test_quit(self):
813         mock_socket = mock.MagicMock()
814         prox = prox_helpers.ProxSocketHelper(mock_socket)
815         prox.quit()
816         mock_socket.sendall.assert_called()
817
818     def test_force_quit(self):
819         mock_socket = mock.MagicMock()
820         prox = prox_helpers.ProxSocketHelper(mock_socket)
821         prox.force_quit()
822         mock_socket.sendall.assert_called()
823
824
825 class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase):
826
827     VNFD0 = {
828         'short-name': 'ProxVnf',
829         'vdu': [
830             {
831                 'routing_table': [
832                     {
833                         'network': '152.16.100.20',
834                         'netmask': '255.255.255.0',
835                         'gateway': '152.16.100.20',
836                         'if': 'xe0',
837                     },
838                     {
839                         'network': '152.16.40.20',
840                         'netmask': '255.255.255.0',
841                         'gateway': '152.16.40.20',
842                         'if': 'xe1',
843                     },
844                 ],
845                 'description': 'PROX approximation using DPDK',
846                 'name': 'proxvnf-baremetal',
847                 'nd_route_tbl': [
848                     {
849                         'network': '0064:ff9b:0:0:0:0:9810:6414',
850                         'netmask': '112',
851                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
852                         'if': 'xe0',
853                     },
854                     {
855                         'network': '0064:ff9b:0:0:0:0:9810:2814',
856                         'netmask': '112',
857                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
858                         'if': 'xe1',
859                     },
860                 ],
861                 'id': 'proxvnf-baremetal',
862                 'external-interface': [
863                     {
864                         'virtual-interface': {
865                             'dst_mac': '00:00:00:00:00:04',
866                             'vpci': '0000:05:00.0',
867                             'local_ip': '152.16.100.19',
868                             'type': 'PCI-PASSTHROUGH',
869                             'vld_id': 'uplink_0',
870                             'netmask': '255.255.255.0',
871                             'dpdk_port_num': 0,
872                             'bandwidth': '10 Gbps',
873                             'driver': "i40e",
874                             'dst_ip': '152.16.100.19',
875                             'local_iface_name': 'xe0',
876                             'local_mac': '00:00:00:00:00:02',
877                             'ifname': 'xe0',
878                         },
879                         'vnfd-connection-point-ref': 'xe0',
880                         'name': 'xe0',
881                     },
882                     {
883                         'virtual-interface': {
884                             'dst_mac': '00:00:00:00:00:03',
885                             'vpci': '0000:05:00.1',
886                             'local_ip': '152.16.40.19',
887                             'type': 'PCI-PASSTHROUGH',
888                             'vld_id': 'downlink_0',
889                             'driver': "i40e",
890                             'netmask': '255.255.255.0',
891                             'dpdk_port_num': 1,
892                             'bandwidth': '10 Gbps',
893                             'dst_ip': '152.16.40.20',
894                             'local_iface_name': 'xe1',
895                             'local_mac': '00:00:00:00:00:01',
896                             'ifname': 'xe1',
897                         },
898                         'vnfd-connection-point-ref': 'xe1',
899                         'name': 'xe1',
900                     },
901                 ],
902             },
903         ],
904         'description': 'PROX approximation using DPDK',
905         'mgmt-interface': {
906             'vdu-id': 'proxvnf-baremetal',
907             'host': '1.2.1.1',
908             'password': 'r00t',
909             'user': 'root',
910             'ip': '1.2.1.1',
911         },
912         'benchmark': {
913             'kpi': [
914                 'packets_in',
915                 'packets_fwd',
916                 'packets_dropped',
917             ],
918         },
919         'id': 'ProxApproxVnf',
920         'name': 'ProxVnf',
921     }
922
923     VNFD = {
924         'vnfd:vnfd-catalog': {
925             'vnfd': [
926                 VNFD0,
927             ],
928         },
929     }
930
931     def test_global_section(self):
932         setup_helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
933             mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
934
935         setup_helper._prox_config_data = [('a', [])]
936
937         with self.assertRaises(KeyError):
938             _ = setup_helper.global_section
939
940         global_section = (
941             'global', [
942                 ('not_name', 'other data'),
943                 ('name_not', 'more data'),
944                 ('name', 'prox type'),
945             ],
946         )
947
948         setup_helper._prox_config_data = [
949             ('section1', []),
950             ('section2', [
951                 ('a', 'b'),
952                 ('c', 'd'),
953             ]),
954             ('core 1', []),
955             ('core 2', [
956                 ('index', 8),
957                 ('mode', ''),
958             ]),
959             global_section,
960             ('core 3', [
961                 ('index', 5),
962                 ('mode', 'gen'),
963                 ('name', 'tagged'),
964             ]),
965             ('section3', [
966                 ('key1', 'value1'),
967                 ('key2', 'value2'),
968                 ('key3', 'value3'),
969             ]),
970             ('core 4', [
971                 ('index', 7),
972                 ('mode', 'gen'),
973                 ('name', 'udp'),
974             ]),
975         ]
976
977         result = setup_helper.global_section
978         self.assertEqual(result, global_section[1])
979
980     def test_find_in_section(self):
981         setup_helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
982             mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
983
984         setup_helper._prox_config_data = [
985             ('global', [
986                 ('not_name', 'other data'),
987                 ('name_not', 'more data'),
988                 ('name', 'prox type'),
989             ]),
990             ('section1', []),
991             ('section2', [
992                 ('a', 'b'),
993                 ('c', 'd'),
994             ]),
995             ('core 1', []),
996             ('core 2', [
997                 ('index', 8),
998                 ('mode', ''),
999             ]),
1000             ('core 3', [
1001                 ('index', 5),
1002                 ('mode', 'gen'),
1003                 ('name', 'tagged'),
1004             ]),
1005             ('section3', [
1006                 ('key1', 'value1'),
1007                 ('key2', 'value2'),
1008                 ('key3', 'value3'),
1009             ]),
1010             ('core 4', [
1011                 ('index', 7),
1012                 ('mode', 'gen'),
1013                 ('name', 'udp'),
1014             ]),
1015         ]
1016
1017         expected = 'value3'
1018         result = setup_helper.find_in_section('section3', 'key3')
1019         self.assertEqual(result, expected)
1020
1021         expected = 'default value'
1022         result = setup_helper.find_in_section('section3', 'key4', 'default value')
1023         self.assertEqual(result, expected)
1024
1025         with self.assertRaises(KeyError):
1026             setup_helper.find_in_section('section4', 'key1')
1027
1028         with self.assertRaises(KeyError):
1029             setup_helper.find_in_section('section1', 'key1')
1030
1031     def test__replace_quoted_with_value(self):
1032         # empty string
1033         input_str = ''
1034         expected = ''
1035         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1036                   _replace_quoted_with_value(input_str, 'cat'))
1037         self.assertEqual(result, expected)
1038
1039         # no quoted substring
1040         input_str = 'lion tiger bear'
1041         expected = 'lion tiger bear'
1042         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1043                   _replace_quoted_with_value(input_str, 'cat'))
1044         self.assertEqual(result, expected)
1045
1046         # partially quoted substring
1047         input_str = 'lion "tiger bear'
1048         expected = 'lion "tiger bear'
1049         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1050                   _replace_quoted_with_value(input_str, 'cat'))
1051         self.assertEqual(result, expected)
1052
1053         # one quoted substring
1054         input_str = 'lion "tiger" bear'
1055         expected = 'lion "cat" bear'
1056         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1057                   _replace_quoted_with_value(input_str, 'cat'))
1058         self.assertEqual(result, expected)
1059
1060         # two quoted substrings
1061         input_str = 'lion "tiger" bear "shark" whale'
1062         expected = 'lion "cat" bear "shark" whale'
1063         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1064                   _replace_quoted_with_value(input_str, 'cat'))
1065         self.assertEqual(result, expected)
1066
1067         # two quoted substrings, both replaced
1068         input_str = 'lion "tiger" bear "shark" whale'
1069         expected = 'lion "cat" bear "cat" whale'
1070         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1071                   _replace_quoted_with_value(input_str, 'cat', 2))
1072         self.assertEqual(result, expected)
1073
1074     def test__get_tx_port(self):
1075         # no data
1076         input_data = {'section1': []}
1077         expected = -1
1078         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1079                   _get_tx_port('section1', input_data))
1080         self.assertEqual(result, expected)
1081
1082         # data for other section
1083         input_data = {
1084             'section1': [],
1085             'section2': [
1086                 ('rx port', '3'),
1087                 ('tx port', '4'),
1088             ],
1089         }
1090         expected = -1
1091         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1092                   _get_tx_port('section1', input_data))
1093         self.assertEqual(result, expected)
1094
1095         # data for section
1096         input_data['section1'] = section1 = [
1097             ('rx port', '4', 'more', 432),
1098             ('tx port', '3'),
1099         ]
1100         expected = 3
1101         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1102                   _get_tx_port('section1', input_data))
1103         self.assertEqual(result, expected)
1104
1105         # more data for section,
1106         section1.extend([
1107             ('rx port', '2'),
1108             ('tx port', '1', 'and more', 234),
1109         ])
1110         expected = 1
1111         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1112                   _get_tx_port('section1', input_data))
1113         self.assertEqual(result, expected)
1114
1115     # TODO(elfoley): Split this into several smaller tests
1116     def test_write_prox_config(self):
1117         input_data = {}
1118         expected = ''
1119         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1120                   write_prox_config(input_data))
1121         self.assertEqual(result, expected)
1122
1123         input_data = [
1124             [
1125                 'section1',
1126                 [],
1127             ],
1128         ]
1129         expected = '[section1]'
1130         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1131                   write_prox_config(input_data))
1132         self.assertEqual(result, expected)
1133
1134         input_data = [
1135             [
1136                 'section1',
1137                 [],
1138             ],
1139             [
1140                 'section2',
1141                 [
1142                     ['key1', 'value1'],
1143                     ['__name__', 'not this one'],
1144                     ['key2', None],
1145                     ['key3', 234],
1146                     ['key4', 'multi-line\nvalue'],
1147                 ],
1148             ],
1149         ]
1150         expected = os.linesep.join([
1151             '[section1]',
1152             '[section2]',
1153             'key1=value1',
1154             'key2',
1155             'key3=234',
1156             'key4=multi-line\n\tvalue',
1157         ])
1158         result = (prox_helpers.ProxDpdkVnfSetupEnvHelper.
1159                   write_prox_config(input_data))
1160         self.assertEqual(result, expected)
1161
1162     def test_prox_config_data(self):
1163         setup_helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1164             mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
1165
1166         setup_helper.config_queue = config_queue = mock.MagicMock()
1167         config_queue.get.return_value = expected = [('s', [('a', 3), ('b', 45)])]
1168
1169         result = setup_helper.prox_config_data
1170         self.assertEqual(result, expected)
1171
1172     @mock.patch.object(utils, 'find_relative_file')
1173     def test_build_config_file_no_additional_file(self, mock_find_path):
1174         vnf1 = {
1175             'prox_args': {'-c': ""},
1176             'prox_path': 'd',
1177             'prox_config': 'e/f',
1178             'prox_generate_parameter': False,
1179         }
1180
1181         mock_find_path.side_effect = ['1', '2']
1182
1183         vnfd_helper = mock.MagicMock()
1184         ssh_helper = mock.MagicMock()
1185         scenario_helper = sample_vnf.ScenarioHelper('vnf1')
1186         scenario_helper.scenario_cfg = {
1187             'task_path': 'a/b',
1188             'options': {
1189                 'vnf1': vnf1,
1190             },
1191         }
1192
1193         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1194             vnfd_helper, ssh_helper, scenario_helper)
1195         helper.copy_to_target = mock.MagicMock(return_value='3')
1196         helper.generate_prox_config_file = mock.MagicMock(return_value='4')
1197         helper.upload_prox_config = mock.MagicMock(return_value='5')
1198
1199         self.assertEqual(helper.additional_files, {})
1200         self.assertNotEqual(helper._prox_config_data, '4')
1201         self.assertNotEqual(helper.remote_path, '5')
1202         helper.build_config_file()
1203         self.assertEqual(helper.additional_files, {})
1204         self.assertEqual(helper._prox_config_data, '4')
1205         self.assertEqual(helper.remote_path, '5')
1206
1207     @mock.patch.object(utils, 'find_relative_file')
1208     def test_build_config_file_additional_file_string(self, mock_find_path):
1209         vnf1 = {
1210             'prox_args': {'-c': ""},
1211             'prox_path': 'd',
1212             'prox_config': 'e/f',
1213             'prox_files': 'g/h.i',
1214             'prox_generate_parameter': True,
1215         }
1216
1217         mock_find_path.side_effect = ['1', '2']
1218         vnfd_helper = mock.MagicMock()
1219         ssh_helper = mock.MagicMock()
1220         scenario_helper = sample_vnf.ScenarioHelper('vnf1')
1221         scenario_helper.scenario_cfg = {
1222             'task_path': 'a/b',
1223             'options': {
1224                 'vnf1': vnf1,
1225             },
1226         }
1227
1228         vnfd_helper.port_pairs.all_ports = ['xe0', 'xe1', 'xe2', 'xe3']
1229         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1230             vnfd_helper, ssh_helper, scenario_helper)
1231         helper.copy_to_target = mock.MagicMock(side_effect=['33', '34', '35'])
1232         helper.generate_prox_config_file = mock.MagicMock(return_value='44')
1233         helper.upload_prox_config = mock.MagicMock(return_value='55')
1234
1235         self.assertEqual(helper.additional_files, {})
1236         expected = {'h.i': '33'}
1237         helper.build_config_file()
1238         self.assertDictEqual(helper.additional_files, expected)
1239
1240     @mock.patch.object(utils, 'find_relative_file')
1241     def test_build_config_file_additional_file(self, mock_find_path):
1242         vnf1 = {
1243             'prox_args': {'-c': ""},
1244             'prox_path': 'd',
1245             'prox_config': 'e/f',
1246             'prox_files': [
1247                 'g/h.i',
1248                 'j/k/l',
1249                 'm_n',
1250             ],
1251         }
1252
1253         mock_find_path.side_effect = ['1', '2'] + [str(i) for i in range(len(vnf1['prox_files']))]
1254         vnfd_helper = mock.MagicMock()
1255         ssh_helper = mock.MagicMock()
1256         scenario_helper = sample_vnf.ScenarioHelper('vnf1')
1257         scenario_helper.scenario_cfg = {
1258             'task_path': 'a/b',
1259             'options': {
1260                 'vnf1': vnf1,
1261             },
1262         }
1263
1264         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1265             vnfd_helper, ssh_helper, scenario_helper)
1266         helper.copy_to_target = mock.MagicMock(side_effect=['33', '34', '35'])
1267         helper.generate_prox_config_file = mock.MagicMock(return_value='44')
1268         helper.upload_prox_config = mock.MagicMock(return_value='55')
1269
1270         self.assertEqual(helper.additional_files, {})
1271         self.assertNotEqual(helper._prox_config_data, '44')
1272         self.assertNotEqual(helper.remote_path, '55')
1273         expected = {'h.i': '33', 'l': '34', 'm_n': '35'}
1274         helper.build_config_file()
1275         self.assertDictEqual(helper.additional_files, expected)
1276         self.assertEqual(helper._prox_config_data, '44')
1277         self.assertEqual(helper.remote_path, '55')
1278
1279     def test_build_config(self):
1280         vnf1 = {
1281             'prox_args': {'-f': ""},
1282             'prox_path': '/opt/nsb_bin/prox',
1283             'prox_config': 'configs/gen_l2fwd-2.cfg',
1284             'prox_files': [
1285                 'g/h.i',
1286                 'j/k/l',
1287                 'm_n',
1288             ],
1289         }
1290
1291         vnfd_helper = mock.Mock()
1292         ssh_helper = mock.Mock()
1293         ssh_helper.join_bin_path.return_value = '/opt/nsb_bin/prox'
1294         scenario_helper = sample_vnf.ScenarioHelper('vnf1')
1295         scenario_helper.scenario_cfg = {
1296             'task_path': 'a/b',
1297             'options': {
1298                 'vnf1': vnf1,
1299             },
1300         }
1301
1302         expected = ("sudo bash -c 'cd /opt/nsb_bin; /opt/nsb_bin/prox -o cli "
1303                     "-f  -f /tmp/prox.cfg '")
1304
1305         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1306             vnfd_helper, ssh_helper, scenario_helper)
1307         with mock.patch.object(helper, 'build_config_file') as mock_cfg_file:
1308             helper.remote_path = '/tmp/prox.cfg'
1309             prox_cmd = helper.build_config()
1310             self.assertEqual(prox_cmd, expected)
1311             mock_cfg_file.assert_called_once()
1312
1313     def test__insert_additional_file(self):
1314         vnfd_helper = mock.MagicMock()
1315         ssh_helper = mock.MagicMock()
1316         scenario_helper = mock.MagicMock()
1317
1318         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1319             vnfd_helper, ssh_helper, scenario_helper)
1320         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1321         res = helper._insert_additional_file('dofile("ipv4.lua")')
1322         self.assertEqual(res, 'dofile("/tmp/ipv4.lua")')
1323
1324     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1325     def test_generate_prox_config_file(self, mock_parser_type):
1326         def init(*args):
1327             if sections_data:
1328                 args[-1].extend(sections_data)
1329             return mock.MagicMock()
1330
1331         sections_data = []
1332
1333         mock_parser_type.side_effect = init
1334
1335         vnfd_helper = vnf_base.VnfdHelper(self.VNFD0)
1336         ssh_helper = mock.MagicMock()
1337         scenario_helper = mock.MagicMock()
1338
1339         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1340             vnfd_helper, ssh_helper, scenario_helper)
1341         helper.additional_files = {}
1342
1343         expected = []
1344         result = helper.generate_prox_config_file('a/b')
1345         self.assertEqual(result, expected)
1346
1347         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1348
1349         helper.remote_prox_file_name = 'remote'
1350         sections_data = [
1351             [
1352                 'lua',
1353                 [
1354                     ['dofile("ipv4.lua")', ''],
1355                 ],
1356             ],
1357             [
1358                 'port 0',
1359                 [
1360                     ['ip', ''],
1361                     ['mac', 'foo'],
1362                     ['dst mac', '@@1'],
1363                     ['tx port', '1'],
1364                 ],
1365             ],
1366             [
1367                 'port 2',
1368                 [
1369                     ['ip', ''],
1370                     ['$sut_mac0', '@@dst_mac0'],
1371                     ['tx port', '0'],
1372                     ['single', '@'],
1373                     ['user_table', 'dofile("ipv4.lua")'],
1374                     ['missing_addtional_file', 'dofile("nosuch")'],
1375                 ],
1376             ],
1377         ]
1378
1379         expected = [
1380             [
1381                 'lua',
1382                 [
1383                     ['dofile("/tmp/ipv4.lua")', ''],
1384                 ],
1385             ],
1386             [
1387                 'port 0',
1388                 [
1389                     ['ip', ''],
1390                     ['mac', 'hardware'],
1391                     ['dst mac', '00:00:00:00:00:03'],
1392                     ['tx port', '1'],
1393                 ],
1394             ],
1395             [
1396                 'port 2',
1397                 [
1398                     ['ip', ''],
1399                     ['$sut_mac0', '00 00 00 00 00 04'],
1400                     ['tx port', '0'],
1401                     ['single', '@'],
1402                     ['user_table', 'dofile("/tmp/ipv4.lua")'],
1403                     ['missing_addtional_file', 'dofile("nosuch")'],
1404                 ],
1405             ],
1406         ]
1407         result = helper.generate_prox_config_file('/c/d/e')
1408         self.assertEqual(result, expected, str(result))
1409
1410     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1411     def test_generate_prox_config_file_negative(self, mock_parser_type):
1412         def init(*args):
1413             args[-1].update(sections_data)
1414             return mock.MagicMock()
1415
1416         sections_data = {}
1417
1418         mock_parser_type.side_effect = init
1419
1420         vnfd_helper = mock.MagicMock()
1421         vnfd_helper.interfaces = []
1422         ssh_helper = mock.MagicMock()
1423         scenario_helper = mock.MagicMock()
1424
1425         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1426             vnfd_helper, ssh_helper, scenario_helper)
1427         helper.additional_files = {}
1428         helper.remote_prox_file_name = 'remote'
1429         vnfd_helper.interfaces = [
1430             {
1431                 'virtual-interface': {
1432                     'dpdk_port_num': 3,
1433                     'dst_mac': '00:00:00:de:ad:88',
1434                 },
1435             },
1436             {
1437                 'virtual-interface': {
1438                     'dpdk_port_num': 5,
1439                     'dst_mac': '00:00:00:de:ad:ff',
1440                 },
1441             },
1442             {
1443                 'virtual-interface': {
1444                     'dpdk_port_num': 7,
1445                     'dst_mac': '00:00:00:de:ad:ff',
1446                 },
1447             },
1448         ]
1449         sections_data = {
1450             'port 3': [
1451                 ['ip', ''],
1452                 ['mac', 'foo'],
1453                 ['dst mac', ''],
1454             ],
1455             'port 5': [
1456                 ['ip', ''],
1457                 ['dst mac', ''],
1458                 ['tx port', '0'],
1459                 ['???', 'dofile "here" 23'],
1460             ],
1461         }
1462
1463         with self.assertRaises(Exception):
1464             helper.generate_prox_config_file('a/b')
1465
1466     def test_put_string_to_file(self):
1467         vnfd_helper = mock.MagicMock()
1468         vnfd_helper.interfaces = []
1469         ssh_helper = mock.MagicMock()
1470         scenario_helper = mock.MagicMock()
1471
1472         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1473             vnfd_helper, ssh_helper, scenario_helper)
1474
1475         expected = 'a/b'
1476         result = helper.put_string_to_file('my long string', 'a/b')
1477         self.assertEqual(result, expected)
1478
1479     def test_copy_to_target(self):
1480         vnfd_helper = mock.MagicMock()
1481         vnfd_helper.interfaces = []
1482         ssh_helper = mock.MagicMock()
1483         scenario_helper = mock.MagicMock()
1484
1485         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1486             vnfd_helper, ssh_helper, scenario_helper)
1487         expected = '/tmp/c'
1488         result = helper.copy_to_target('a/b', 'c')
1489         self.assertEqual(result, expected)
1490
1491     def test_upload_prox_config(self):
1492         vnfd_helper = mock.MagicMock()
1493         vnfd_helper.interfaces = []
1494         ssh_helper = mock.MagicMock()
1495         scenario_helper = mock.MagicMock()
1496
1497         helper = prox_helpers.ProxDpdkVnfSetupEnvHelper(
1498             vnfd_helper, ssh_helper, scenario_helper)
1499         helper.write_prox_config = mock.MagicMock(return_value='a long string')
1500         expected = '/tmp/a'
1501         result = helper.upload_prox_config('a', {})
1502         self.assertEqual(result, expected)
1503
1504
1505 class TestProxResourceHelper(unittest.TestCase):
1506
1507     VNFD0 = {
1508         'short-name': 'ProxVnf',
1509         'vdu': [
1510             {
1511                 'routing_table': [
1512                     {
1513                         'network': '152.16.100.20',
1514                         'netmask': '255.255.255.0',
1515                         'gateway': '152.16.100.20',
1516                         'if': 'xe0',
1517                     },
1518                     {
1519                         'network': '152.16.40.20',
1520                         'netmask': '255.255.255.0',
1521                         'gateway': '152.16.40.20',
1522                         'if': 'xe1',
1523                     },
1524                 ],
1525                 'description': 'PROX approximation using DPDK',
1526                 'name': 'proxvnf-baremetal',
1527                 'nd_route_tbl': [
1528                     {
1529                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1530                         'netmask': '112',
1531                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1532                         'if': 'xe0',
1533                     },
1534                     {
1535                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1536                         'netmask': '112',
1537                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1538                         'if': 'xe1',
1539                     },
1540                 ],
1541                 'id': 'proxvnf-baremetal',
1542                 'external-interface': [
1543                     {
1544                         'virtual-interface': {
1545                             'dst_mac': '00:00:00:00:00:04',
1546                             'vpci': '0000:05:00.0',
1547                             'local_ip': '152.16.100.19',
1548                             'type': 'PCI-PASSTHROUGH',
1549                             'vld_id': 'uplink_0',
1550                             'netmask': '255.255.255.0',
1551                             'dpdk_port_num': 0,
1552                             'bandwidth': '10 Gbps',
1553                             'driver': "i40e",
1554                             'dst_ip': '152.16.100.19',
1555                             'local_iface_name': 'xe0',
1556                             'local_mac': '00:00:00:00:00:02',
1557                             'ifname': 'xe0',
1558                         },
1559                         'vnfd-connection-point-ref': 'xe0',
1560                         'name': 'xe0',
1561                     },
1562                     {
1563                         'virtual-interface': {
1564                             'dst_mac': '00:00:00:00:00:03',
1565                             'vpci': '0000:05:00.1',
1566                             'local_ip': '152.16.40.19',
1567                             'type': 'PCI-PASSTHROUGH',
1568                             'vld_id': 'downlink_0',
1569                             'driver': "i40e",
1570                             'netmask': '255.255.255.0',
1571                             'dpdk_port_num': 1,
1572                             'bandwidth': '10 Gbps',
1573                             'dst_ip': '152.16.40.20',
1574                             'local_iface_name': 'xe1',
1575                             'local_mac': '00:00:00:00:00:01',
1576                             'ifname': 'xe1',
1577                         },
1578                         'vnfd-connection-point-ref': 'xe1',
1579                         'name': 'xe1',
1580                     },
1581                 ],
1582             },
1583         ],
1584         'description': 'PROX approximation using DPDK',
1585         'mgmt-interface': {
1586             'vdu-id': 'proxvnf-baremetal',
1587             'host': '1.2.1.1',
1588             'password': 'r00t',
1589             'user': 'root',
1590             'ip': '1.2.1.1',
1591         },
1592         'benchmark': {
1593             'kpi': [
1594                 'packets_in',
1595                 'packets_fwd',
1596                 'packets_dropped',
1597             ],
1598         },
1599         'id': 'ProxApproxVnf',
1600         'name': 'ProxVnf',
1601     }
1602
1603     VNFD = {
1604         'vnfd:vnfd-catalog': {
1605             'vnfd': [
1606                 VNFD0,
1607             ],
1608         },
1609     }
1610
1611     def test_find_pci(self):
1612         input_str_list = [
1613             'no target here',
1614             'nor here',
1615             'and still not',
1616         ]
1617         result = prox_helpers.ProxResourceHelper.find_pci('target',
1618                                                           input_str_list)
1619         self.assertFalse(result)
1620
1621         input_str_list = [
1622             'no target here',
1623             'nor here',
1624             'this is a target',
1625             'did we miss it',
1626         ]
1627         result = prox_helpers.ProxResourceHelper.find_pci('target',
1628                                                           input_str_list)
1629         self.assertTrue(result)
1630
1631     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.RETRY_INTERVAL', 0)
1632     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1633     def test_sut(self, *args):
1634         helper = prox_helpers.ProxResourceHelper(mock.MagicMock())
1635         self.assertIsNone(helper.client)
1636         result = helper.sut
1637         self.assertIsNotNone(result)
1638         self.assertIs(result, helper.client)
1639         self.assertIs(result, helper.sut)
1640
1641     def test_test_type(self):
1642         setup_helper = mock.MagicMock()
1643         setup_helper.find_in_section.return_value = expected = 'prox type'
1644
1645         helper = prox_helpers.ProxResourceHelper(setup_helper)
1646
1647         self.assertIsNone(helper._test_type)
1648         self.assertEqual(helper.test_type, expected)
1649         self.assertEqual(helper._test_type, expected)
1650         self.assertEqual(helper.test_type, expected)
1651
1652     def test_collect_collectd_kpi(self):
1653         helper = prox_helpers.ProxResourceHelper(mock.MagicMock())
1654         helper.resource = resource = mock.MagicMock()
1655
1656         resource.check_if_system_agent_running.return_value = 0, '1234'
1657         resource.amqp_collect_nfvi_kpi.return_value = 543
1658         resource.check_if_system_agent_running.return_value = (0, None)
1659
1660         expected = {'core': 543}
1661         result = helper.collect_collectd_kpi()
1662         self.assertDictEqual(result, expected)
1663
1664     def test_collect_kpi(self):
1665         helper = prox_helpers.ProxResourceHelper(mock.MagicMock())
1666         helper._queue = queue = mock.MagicMock()
1667         helper._result = {'z': 123}
1668
1669         helper.client = mock.MagicMock()
1670         helper.client.hz.return_value = 1
1671         helper.client.multi_port_stats.return_value = \
1672             (True, [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]])
1673         helper.client.multi_port_stats_diff.return_value = \
1674             ([0, 1, 2, 3, 4, 5, 6, 7])
1675         helper.client.multi_port_stats_tuple.return_value = \
1676             {"xe0": {"in_packets": 1, "out_packets": 2}}
1677         helper.resource = resource = mock.MagicMock()
1678
1679         vnfd_helper = mock.MagicMock()
1680         vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
1681         helper.vnfd_helper = vnfd_helper
1682
1683         resource.check_if_system_agent_running.return_value = 0, '1234'
1684         resource.amqp_collect_nfvi_kpi.return_value = 543
1685         resource.check_if_system_agent_running.return_value = (0, None)
1686
1687         queue.empty.return_value = False
1688         queue.get.return_value = {'a': 789}
1689
1690         expected = {'z': 123, 'a': 789,
1691                     'collect_stats': {'core': 543},
1692                     'live_stats': {'xe0': {'in_packets': 1, 'out_packets': 2}}}
1693         result = helper.collect_kpi()
1694         self.assertDictEqual(result, expected)
1695
1696     def test_collect_kpi_no_hz(self):
1697         helper = prox_helpers.ProxResourceHelper(mock.MagicMock())
1698         helper._queue = queue = mock.MagicMock()
1699         helper._result = {'z': 123}
1700
1701         helper.client = mock.MagicMock()
1702         helper.client.multi_port_stats.return_value = \
1703             (True, [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]])
1704         helper.client.multi_port_stats_diff.return_value = \
1705             ([0, 1, 2, 3, 4, 5, 6, 7])
1706         helper.client.multi_port_stats_tuple.return_value = \
1707             {"xe0": {"in_packets": 1, "out_packets": 2}}
1708         helper.resource = resource = mock.MagicMock()
1709
1710         vnfd_helper = mock.MagicMock()
1711         vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
1712         helper.vnfd_helper = vnfd_helper
1713
1714         resource.check_if_system_agent_running.return_value = 0, '1234'
1715         resource.amqp_collect_nfvi_kpi.return_value = 543
1716         resource.check_if_system_agent_running.return_value = (0, None)
1717
1718         queue.empty.return_value = False
1719         queue.get.return_value = {'a': 789}
1720
1721         expected = {'z': 123, 'a': 789,
1722                     'collect_stats': {'core': 543},
1723                     'live_stats': {'xe0': {'in_packets': 1, 'out_packets': 2}}}
1724         result = helper.collect_kpi()
1725         self.assertDictEqual(result, expected)
1726
1727     def test_collect_kpi_bad_data(self):
1728         helper = prox_helpers.ProxResourceHelper(mock.MagicMock())
1729         helper._queue = queue = mock.MagicMock()
1730         helper._result = {'z': 123}
1731
1732         helper.client = mock.MagicMock()
1733         helper.client.multi_port_stats.return_value = \
1734             (False, [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]])
1735         helper.client.multi_port_stats_diff.return_value = \
1736             ([0, 1, 2, 3, 4, 5, 6, 7])
1737         helper.client.multi_port_stats_tuple.return_value = \
1738             {"xe0": {"in_packets": 1, "out_packets": 2}}
1739         helper.resource = resource = mock.MagicMock()
1740
1741         vnfd_helper = mock.MagicMock()
1742         vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
1743         helper.vnfd_helper = vnfd_helper
1744
1745         resource.check_if_system_agent_running.return_value = 0, '1234'
1746         resource.amqp_collect_nfvi_kpi.return_value = 543
1747         resource.check_if_system_agent_running.return_value = (0, None)
1748
1749         queue.empty.return_value = False
1750         queue.get.return_value = {'a': 789}
1751
1752         expected = {'z': 123, 'a': 789,
1753                     'collect_stats': {'core': 543}}
1754         result = helper.collect_kpi()
1755         self.assertDictEqual(result, expected)
1756
1757     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1758     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1759     def test__connect(self, mock_socket_helper_type, *args):
1760         client = mock_socket_helper_type()
1761         client.connect.side_effect = chain(repeat(socket.error, 5), [None])
1762
1763         setup_helper = mock.MagicMock()
1764         setup_helper.vnfd_helper.interfaces = []
1765
1766         helper = prox_helpers.ProxResourceHelper(setup_helper)
1767
1768         result = helper._connect()
1769         self.assertIs(result, client)
1770
1771         client.connect.side_effect = chain(repeat(socket.error, 65), [None])
1772
1773         with self.assertRaises(Exception):
1774             helper._connect()
1775
1776     def test_run_traffic(self):
1777         setup_helper = mock.MagicMock()
1778         helper = prox_helpers.ProxResourceHelper(setup_helper)
1779         traffic_profile = mock.MagicMock()
1780         traffic_profile.done.is_set.return_value = True
1781         helper.run_traffic(traffic_profile)
1782         self.assertEqual(helper._terminated.value, 1)
1783
1784     def test__run_traffic_once(self):
1785         setup_helper = mock.MagicMock()
1786         helper = prox_helpers.ProxResourceHelper(setup_helper)
1787         traffic_profile = mock.MagicMock()
1788         traffic_profile.done.is_set.return_value = True
1789         helper._run_traffic_once(traffic_profile)
1790         self.assertEqual(helper._terminated.value, 1)
1791
1792     def test_start_collect(self):
1793         setup_helper = mock.MagicMock()
1794         helper = prox_helpers.ProxResourceHelper(setup_helper)
1795         helper.resource = resource = mock.MagicMock()
1796         self.assertIsNone(helper.start_collect())
1797         resource.start.assert_called_once()
1798
1799     def test_terminate(self):
1800         setup_helper = mock.MagicMock()
1801         helper = prox_helpers.ProxResourceHelper(setup_helper)
1802         with self.assertRaises(NotImplementedError):
1803             helper.terminate()
1804
1805     def test_up_post(self):
1806         setup_helper = mock.MagicMock()
1807         helper = prox_helpers.ProxResourceHelper(setup_helper)
1808         helper.client = expected = mock.MagicMock()
1809         result = helper.up_post()
1810         self.assertEqual(result, expected)
1811
1812     def test_execute(self):
1813         setup_helper = mock.MagicMock()
1814         helper = prox_helpers.ProxResourceHelper(setup_helper)
1815         helper.client = mock.MagicMock()
1816
1817         expected = helper.client.my_command()
1818         result = helper.execute('my_command')
1819         self.assertEqual(result, expected)
1820
1821         # TODO(elfoley): Make this a separate test: test_execute_no_client
1822         helper.client = object()
1823
1824         result = helper.execute('my_command')
1825         self.assertIsNone(result)
1826
1827
1828 class TestProxDataHelper(unittest.TestCase):
1829
1830     def test_totals_and_pps(self):
1831         pkt_size = 180
1832         vnfd_helper = mock.MagicMock()
1833         vnfd_helper.port_pairs.all_ports = list(range(4))
1834
1835         sut = mock.MagicMock()
1836         sut.multi_port_stats.return_value = (True,
1837                                              [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5],
1838                                               [2, 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 5]])
1839
1840         data_helper = prox_helpers.ProxDataHelper(
1841             vnfd_helper, sut, pkt_size, 25, None,
1842             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1843
1844         self.assertEqual(data_helper.rx_total, 4)
1845         self.assertEqual(data_helper.tx_total, 8)
1846         self.assertEqual(data_helper.requested_pps, 6250000.0)
1847
1848         vnfd_helper = mock.MagicMock()
1849         vnfd_helper.port_pairs.all_ports = [3, 4]
1850
1851         sut = mock.MagicMock()
1852         sut.multi_port_stats.return_value = (True,
1853                                              [[3, 1, 2, 3, 4, 5], [4, 1, 2, 3, 4, 5]])
1854
1855         data_helper = prox_helpers.ProxDataHelper(
1856             vnfd_helper, sut, pkt_size, 25, None,
1857             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1858
1859         self.assertEqual(data_helper.rx_total, 2)
1860         self.assertEqual(data_helper.tx_total, 4)
1861         self.assertEqual(data_helper.requested_pps, 3125000.0)
1862
1863         vnfd_helper = mock.MagicMock()
1864         vnfd_helper.port_pairs.all_ports = [0, 1, 2, 3, 4, 6, 7]
1865
1866         sut = mock.MagicMock()
1867         sut.multi_port_stats.return_value = (True,
1868                                              [[8, 1, 2, 3, 4, 5], [9, 1, 2, 3, 4, 5]])
1869
1870         data_helper = prox_helpers.ProxDataHelper(
1871             vnfd_helper, sut, pkt_size, 25, None,
1872             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1873
1874         self.assertEqual(data_helper.rx_total, 2)
1875         self.assertEqual(data_helper.tx_total, 4)
1876         self.assertEqual(data_helper.requested_pps, 10937500.0)
1877
1878         vnfd_helper = mock.MagicMock()
1879         vnfd_helper.port_pairs.all_ports = []
1880
1881         sut = mock.MagicMock()
1882         sut.multi_port_stats.return_value = (True,
1883                                              [[8, 1, 2, 3, 4, 5], [9, 1, 2, 3, 4, 5]])
1884
1885         data_helper = prox_helpers.ProxDataHelper(
1886             vnfd_helper, sut, pkt_size, 25, None,
1887             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1888
1889         self.assertEqual(data_helper.rx_total, 2)
1890         self.assertEqual(data_helper.tx_total, 4)
1891         self.assertEqual(data_helper.requested_pps, 0.0)
1892
1893     def test_totals_and_pps2(self):
1894         pkt_size = 180
1895         vnfd_helper = mock.MagicMock()
1896         vnfd_helper.port_pairs.all_ports = list(range(4))
1897
1898         sut = mock.MagicMock()
1899         sut.multi_port_stats.return_value = (True,
1900                                              [[0, 'A', 2, 3, 4, 5], [1, 'B', 'C', 3, 4, 5],
1901                                               ['D', 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 'F']])
1902
1903         data_helper = prox_helpers.ProxDataHelper(
1904             vnfd_helper, sut, pkt_size, 25, None,
1905             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1906
1907         self.assertEqual(data_helper.rx_total, 0)
1908         self.assertEqual(data_helper.tx_total, 0)
1909         self.assertEqual(data_helper.requested_pps, 0)
1910
1911     def test_samples(self):
1912         vnfd_helper = mock.MagicMock()
1913         vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
1914
1915         sut = mock.MagicMock()
1916         sut.multi_port_stats.return_value = (True, [[0, 1, 2, 3, 4, 5], [1, 11, 12, 3, 4, 5]])
1917
1918         data_helper = prox_helpers.ProxDataHelper(
1919             vnfd_helper, sut, None, None, None, None)
1920
1921         expected = {
1922             'xe0': {
1923                 'in_packets': 1,
1924                 'out_packets': 2,
1925             },
1926             'xe1': {
1927                 'in_packets': 11,
1928                 'out_packets': 12,
1929             },
1930         }
1931         result = data_helper.samples
1932         self.assertDictEqual(result, expected)
1933
1934     def test_samples2(self):
1935         vnfd_helper = mock.MagicMock()
1936         vnfd_helper.ports_iter.return_value = [('xe1', 3), ('xe2', 7)]
1937
1938         sut = mock.MagicMock()
1939         sut.multi_port_stats.return_value = (True, [[3, 1, 2, 3, 4, 5], [7, 11, 12, 3, 4, 5]])
1940
1941         data_helper = prox_helpers.ProxDataHelper(
1942             vnfd_helper, sut, None, None, None, None)
1943
1944         expected = {
1945             'xe1': {
1946                 'in_packets': 1,
1947                 'out_packets': 2,
1948             },
1949             'xe2': {
1950                 'in_packets': 11,
1951                 'out_packets': 12,
1952             },
1953         }
1954         result = data_helper.samples
1955         self.assertDictEqual(result, expected)
1956
1957     def test___enter__(self):
1958         vnfd_helper = mock.MagicMock()
1959         vnfd_helper.port_pairs.all_ports = list(range(4))
1960         vnfd_helper.ports_iter.return_value = [('xe1', 3), ('xe2', 7)]
1961
1962         sut = mock.MagicMock()
1963
1964         data_helper = prox_helpers.ProxDataHelper(vnfd_helper, sut, None, None,
1965             5.4, constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
1966         data_helper._totals_and_pps = 12, 32, 4.5
1967         data_helper.tsc_hz = 9.8
1968         data_helper.measured_stats = {
1969             'delta': prox_helpers.TotStatsTuple(6.1, 6.2, 6.3, 6.4)}
1970         data_helper.latency = 7
1971
1972         self.assertIsNone(data_helper.result_tuple)
1973         self.assertEqual(data_helper.line_speed, 10000000000)
1974
1975         expected = prox_helpers.ProxTestDataTuple(
1976             5.4, 9.8, 6.1, 6.2, 6.3, 7, 12, 32, 4.5)
1977         with data_helper:
1978             pass
1979
1980         result = data_helper.result_tuple
1981         self.assertEqual(result, expected)
1982
1983         data_helper.make_tuple()
1984         self.assertIs(data_helper.result_tuple, result)
1985
1986     def test___enter___negative(self):
1987         vnfd_helper = mock.MagicMock()
1988
1989         data_helper = prox_helpers.ProxDataHelper(
1990             vnfd_helper, None, None, None, None, None)
1991
1992         vnfd_helper.port_pairs.all_ports = []
1993         with self.assertRaises(AssertionError):
1994             with data_helper:
1995                 pass
1996
1997         vnfd_helper.port_pairs.all_ports = [0, 1, 2]
1998         with self.assertRaises(AssertionError):
1999             with data_helper:
2000                 pass
2001
2002     def test_measure_tot_stats(self):
2003         vnfd_helper = mock.MagicMock()
2004         vnfd_helper.port_pairs.all_ports = list(range(4))
2005
2006         start = (3, 4, 1, 2)
2007         end = (9, 7, 6, 8)
2008
2009         sut = prox_helpers.ProxSocketHelper(mock.MagicMock())
2010         sut.get_all_tot_stats = mock.MagicMock(side_effect=[start, end])
2011
2012         data_helper = prox_helpers.ProxDataHelper(
2013             vnfd_helper, sut, None, None, 5.4, None)
2014
2015         self.assertIsNone(data_helper.measured_stats)
2016
2017         expected = {
2018             'start_tot': start,
2019             'end_tot': end,
2020             'delta': prox_helpers.TotStatsTuple(6, 3, 5, 6),
2021         }
2022         with data_helper.measure_tot_stats():
2023             pass
2024
2025         self.assertEqual(data_helper.measured_stats, expected)
2026
2027     def test_capture_tsc_hz(self):
2028         vnfd_helper = mock.MagicMock()
2029         vnfd_helper.port_pairs.all_ports = list(range(4))
2030
2031         sut = mock.MagicMock()
2032         sut.hz.return_value = '54.6'
2033
2034         data_helper = prox_helpers.ProxDataHelper(
2035             vnfd_helper, sut, None, None, None, None)
2036
2037         self.assertIsNone(data_helper.tsc_hz)
2038
2039         expected = 54.6
2040         data_helper.capture_tsc_hz()
2041         self.assertEqual(data_helper.tsc_hz, expected)
2042
2043
2044 class TestProxProfileHelper(unittest.TestCase):
2045
2046     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.utils')
2047     def test_get_cls(self, mock_utils):
2048         mock_type1 = mock.MagicMock()
2049         mock_type1.__prox_profile_type__ = 'another_type'
2050         mock_type2 = mock.MagicMock()
2051         mock_type2.__prox_profile_type__ = 'my_type'
2052         mock_utils.itersubclasses.return_value = [mock_type1, mock_type2]
2053
2054         self.assertEqual(prox_helpers.ProxProfileHelper.get_cls('my_type'),
2055                          mock_type2)
2056
2057     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.utils')
2058     def test_get_cls_default(self, mock_utils):
2059         mock_utils.itersubclasses.return_value = []
2060         prox_helpers.ProxProfileHelper.get_cls('my_type')
2061
2062     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.SocketTopology')
2063     def test_cpu_topology(self, mock_socket_topology):
2064         mock_socket_topology.parse_cpuinfo.return_value = 432
2065
2066         resource_helper = mock.MagicMock()
2067         resource_helper.setup_helper.ssh_helper.execute.return_value = 0, 'output', ''
2068
2069         helper = prox_helpers.ProxProfileHelper(resource_helper)
2070         self.assertIsNone(helper._cpu_topology)
2071         result = helper.cpu_topology
2072         self.assertEqual(result, 432)
2073         self.assertIs(result, helper._cpu_topology)
2074         self.assertIs(result, helper.cpu_topology)
2075
2076     # TODO(elfoley): Split this test; there are two sets of inputs/outputs
2077     def test_test_cores(self):
2078         resource_helper = mock.MagicMock()
2079         resource_helper.setup_helper.prox_config_data = []
2080
2081         helper = prox_helpers.ProxProfileHelper(resource_helper)
2082         helper._cpu_topology = []
2083
2084         expected = []
2085         result = helper.test_cores
2086         self.assertEqual(result, expected)
2087
2088         resource_helper.setup_helper.prox_config_data = [
2089             ('section1', []),
2090             ('section2', [
2091                 ('a', 'b'),
2092                 ('c', 'd'),
2093             ]),
2094             ('core 1s3', []),
2095             ('core 2s5', [
2096                 ('index', 8),
2097                 ('mode', ''),
2098             ]),
2099             ('core 3s1', [
2100                 ('index', 5),
2101                 ('mode', 'gen'),
2102             ]),
2103             ('core 4s9h', [
2104                 ('index', 7),
2105                 ('mode', 'gen'),
2106             ]),
2107         ]
2108
2109         helper = prox_helpers.ProxProfileHelper(resource_helper)
2110         helper._cpu_topology = {
2111             1: {
2112                 3: {
2113                     'key1': (23, 32),
2114                     'key2': (12, 21),
2115                     'key3': (44, 33),
2116                 },
2117             },
2118             9: {
2119                 4: {
2120                     'key1': (44, 32),
2121                     'key2': (23, 21),
2122                     'key3': (12, 33),
2123                 },
2124             },
2125         }
2126
2127         self.assertIsNone(helper._test_cores)
2128         expected = [3, 4]
2129         result = helper.test_cores
2130         self.assertEqual(result, expected)
2131         self.assertIs(result, helper._test_cores)
2132         self.assertIs(result, helper.test_cores)
2133
2134     # TODO(elfoley): Split this test; there are two sets of inputs/outputs
2135     def test_latency_cores(self):
2136         resource_helper = mock.MagicMock()
2137         resource_helper.setup_helper.prox_config_data = []
2138
2139         helper = prox_helpers.ProxProfileHelper(resource_helper)
2140         helper._cpu_topology = []
2141
2142         expected = []
2143         result = helper.latency_cores
2144         self.assertEqual(result, expected)
2145
2146         resource_helper.setup_helper.prox_config_data = [
2147             ('section1', []),
2148             ('section2', [
2149                 ('a', 'b'),
2150                 ('c', 'd'),
2151             ]),
2152             ('core 1s3', []),
2153             ('core 2s5', [
2154                 ('index', 8),
2155                 ('mode', ''),
2156             ]),
2157             ('core 3s1', [
2158                 ('index', 5),
2159                 ('mode', 'lat'),
2160             ]),
2161             ('core 4s9h', [
2162                 ('index', 7),
2163                 ('mode', 'lat'),
2164             ]),
2165         ]
2166
2167         helper = prox_helpers.ProxProfileHelper(resource_helper)
2168         helper._cpu_topology = {
2169             1: {
2170                 3: {
2171                     'key1': (23, 32),
2172                     'key2': (12, 21),
2173                     'key3': (44, 33),
2174                 },
2175             },
2176             9: {
2177                 4: {
2178                     'key1': (44, 32),
2179                     'key2': (23, 21),
2180                     'key3': (12, 33),
2181                 },
2182             },
2183         }
2184
2185         self.assertIsNone(helper._latency_cores)
2186         expected = [3, 4]
2187         result = helper.latency_cores
2188         self.assertEqual(result, expected)
2189         self.assertIs(result, helper._latency_cores)
2190         self.assertIs(result, helper.latency_cores)
2191
2192     def test_all_rx_cores(self):
2193         helper = prox_helpers.ProxBngProfileHelper(mock.MagicMock())
2194         helper._latency_cores = expected = [3, 4, 6]
2195         helper._test_cores = [5, 2, 1]
2196
2197         result = helper.all_rx_cores
2198         self.assertEqual(result, expected)
2199
2200     def test_get_cores(self):
2201         resource_helper = mock.MagicMock()
2202         resource_helper.setup_helper.prox_config_data = [
2203             ('section1', []),
2204             ('section2', [
2205                 ('a', 'b'),
2206                 ('c', 'd'),
2207             ]),
2208             ('core 1', []),
2209             ('core 2', [
2210                 ('index', 8),
2211                 ('mode', ''),
2212             ]),
2213             ('core 3', [
2214                 ('index', 5),
2215                 ('mode', 'gen'),
2216             ]),
2217             ('core 4', [
2218                 ('index', 7),
2219                 ('mode', 'gen'),
2220             ]),
2221         ]
2222
2223         helper = prox_helpers.ProxProfileHelper(resource_helper)
2224         helper._cpu_topology = {
2225             0: {
2226                 1: {
2227                     5: (5, 1, 0)
2228                 },
2229                 2: {
2230                     6: (6, 2, 0)
2231                 },
2232                 3: {
2233                     7: (7, 3, 0)
2234                 },
2235                 4: {
2236                     8: (8, 3, 0)
2237                 },
2238             }
2239         }
2240
2241         expected = [3, 4]
2242         result = helper.get_cores(helper.PROX_CORE_GEN_MODE)
2243         self.assertEqual(result, expected)
2244
2245     def test_get_latency(self):
2246         resource_helper = mock.MagicMock()
2247         resource_helper.setup_helper.vnfd_helper.interfaces = []
2248
2249         helper = prox_helpers.ProxProfileHelper(resource_helper)
2250         helper._latency_cores = []
2251
2252         expected = []
2253         result = helper.get_latency()
2254         self.assertEqual(result, expected)
2255
2256         helper._latency_cores = [1, 2]
2257         helper.client = mock.MagicMock()
2258
2259         expected = helper.sut.lat_stats()
2260         result = helper.get_latency()
2261         self.assertIs(result, expected)
2262
2263     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
2264     def test_traffic_context(self, *args):
2265         setup_helper = mock.MagicMock()
2266         setup_helper.vnfd_helper.interfaces = []
2267
2268         helper = prox_helpers.ProxProfileHelper(setup_helper)
2269         helper._cpu_topology = {
2270             0: {
2271                 1: {
2272                     5: (5, 1, 0)
2273                 },
2274                 2: {
2275                     6: (6, 2, 0)
2276                 },
2277                 3: {
2278                     7: (7, 3, 0)
2279                 },
2280                 4: {
2281                     8: (8, 3, 0)
2282                 },
2283             }
2284         }
2285
2286         setup_helper.prox_config_data = [
2287             ('global', [
2288                 ('not_name', 'other data'),
2289                 ('name_not', 'more data'),
2290                 ('name', helper.__prox_profile_type__),
2291             ]),
2292             ('section1', []),
2293             ('section2', [
2294                 ('a', 'b'),
2295                 ('c', 'd'),
2296             ]),
2297             ('core 1', []),
2298             ('core 2', [
2299                 ('index', 8),
2300                 ('mode', ''),
2301             ]),
2302             ('core 3', [
2303                 ('index', 5),
2304                 ('mode', 'gen'),
2305                 ('name', 'tagged'),
2306             ]),
2307             ('core 4', [
2308                 ('index', 7),
2309                 ('mode', 'gen'),
2310                 ('name', 'udp'),
2311             ]),
2312         ]
2313
2314         client = mock.MagicMock()
2315         client.hz.return_value = 2
2316
2317         helper.client = client
2318         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
2319
2320         helper._test_cores = [3, 4]
2321
2322         with helper.traffic_context(64, 1):
2323             pass
2324
2325     def test_run_test(self, *args):
2326         resource_helper = mock.MagicMock()
2327         resource_helper.step_delta = 0.4
2328         resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2))
2329         resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5],
2330                                                                     [1, 1, 2, 3, 4, 5]])
2331
2332         helper = prox_helpers.ProxProfileHelper(resource_helper)
2333
2334         helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0,
2335                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2336         self.assertTrue(resource_helper.sut.multi_port_stats.called)
2337         self.assertTrue(resource_helper.sut.stop_all.called)
2338         self.assertTrue(resource_helper.sut.reset_stats.called)
2339
2340 class TestProxMplsProfileHelper(unittest.TestCase):
2341
2342     def test_mpls_cores(self):
2343         resource_helper = mock.MagicMock()
2344         resource_helper.setup_helper.prox_config_data = [
2345             ('section1', []),
2346             ('section2', [
2347                 ('a', 'b'),
2348                 ('c', 'd'),
2349             ]),
2350             ('core 1', []),
2351             ('core 2', [
2352                 ('index', 8),
2353                 ('mode', ''),
2354             ]),
2355             ('core 3', [
2356                 ('index', 5),
2357                 ('mode', 'gen'),
2358                 ('name', 'tagged'),
2359             ]),
2360             ('core 4', [
2361                 ('index', 7),
2362                 ('mode', 'gen'),
2363                 ('name', 'udp'),
2364             ]),
2365         ]
2366
2367         helper = prox_helpers.ProxMplsProfileHelper(resource_helper)
2368         helper._cpu_topology = {
2369             0: {
2370                 1: {
2371                     5: (5, 1, 0)
2372                 },
2373                 2: {
2374                     6: (6, 2, 0)
2375                 },
2376                 3: {
2377                     7: (7, 3, 0)
2378                 },
2379                 4: {
2380                     8: (8, 3, 0)
2381                 },
2382             }
2383         }
2384
2385         expected_tagged = [3]
2386         expected_plain = [4]
2387         self.assertIsNone(helper._cores_tuple)
2388         self.assertEqual(helper.tagged_cores, expected_tagged)
2389         self.assertEqual(helper.plain_cores, expected_plain)
2390         self.assertEqual(helper._cores_tuple, (expected_tagged, expected_plain))
2391
2392     def test_traffic_context(self):
2393         setup_helper = mock.MagicMock()
2394         helper = prox_helpers.ProxMplsProfileHelper(setup_helper)
2395
2396         with helper.traffic_context(120, 5.4):
2397             pass
2398
2399
2400 class TestProxBngProfileHelper(unittest.TestCase):
2401
2402     def test_bng_cores(self):
2403         resource_helper = mock.MagicMock()
2404         resource_helper.setup_helper.prox_config_data = [
2405             ('section1', []),
2406             ('section2', [
2407                 ('a', 'b'),
2408                 ('c', 'd'),
2409             ]),
2410             ('core 1', []),
2411             ('core 2', [
2412                 ('index', 8),
2413                 ('mode', ''),
2414             ]),
2415             ('core 3', [
2416                 ('index', 5),
2417                 ('mode', 'gen'),
2418                 ('name', 'cpe'),
2419             ]),
2420             ('core 4', [
2421                 ('index', 7),
2422                 ('mode', 'gen'),
2423                 ('name', 'inet'),
2424             ]),
2425             ('core 6', [
2426                 ('index', 3),
2427                 ('mode', 'gen'),
2428                 ('name', 'arp_task'),
2429             ]),
2430             ('core 9', [
2431                 ('index', 2),
2432                 ('mode', 'gen'),
2433                 ('name', 'arp'),
2434             ]),
2435         ]
2436
2437         helper = prox_helpers.ProxBngProfileHelper(resource_helper)
2438         helper._cpu_topology = {
2439             0: {
2440                 1: {
2441                     5: (5, 1, 0)
2442                 },
2443                 2: {
2444                     6: (6, 2, 0)
2445                 },
2446                 3: {
2447                     7: (7, 3, 0)
2448                 },
2449                 4: {
2450                     8: (8, 3, 0)
2451                 },
2452                 6: {
2453                     1: (4, 8, 0)
2454                 },
2455                 9: {
2456                     2: (3, 7, 0)
2457                 },
2458             }
2459         }
2460
2461         expected_cpe = [3]
2462         expected_inet = [4]
2463         expected_arp = [6, 9]
2464         expected_arp_task = [0, 6]
2465         expected_combined = (expected_cpe, expected_inet, expected_arp, expected_arp_task)
2466
2467         self.assertIsNone(helper._cores_tuple)
2468         self.assertEqual(helper.cpe_cores, expected_cpe)
2469         self.assertEqual(helper.inet_cores, expected_inet)
2470         self.assertEqual(helper.arp_cores, expected_arp)
2471         self.assertEqual(helper.arp_task_cores, expected_arp_task)
2472         self.assertEqual(helper._cores_tuple, expected_combined)
2473
2474     def test_run_test(self, *args):
2475         resource_helper = mock.MagicMock()
2476         resource_helper.step_delta = 0.4
2477         resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2))
2478         resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5],
2479                                                                     [1, 1, 2, 3, 4, 5]])
2480
2481         helper = prox_helpers.ProxBngProfileHelper(resource_helper)
2482
2483         helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0,
2484                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2485         self.assertTrue(resource_helper.sut.multi_port_stats.called)
2486         self.assertTrue(resource_helper.sut.stop_all.called)
2487         self.assertTrue(resource_helper.sut.reset_stats.called)
2488
2489         resource_helper.reset_mock()
2490
2491         # negative pkt_size is the only way to make ratio > 1
2492         helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0,
2493                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2494
2495         self.assertTrue(resource_helper.sut.multi_port_stats.called)
2496         self.assertTrue(resource_helper.sut.stop_all.called)
2497         self.assertTrue(resource_helper.sut.reset_stats.called)
2498
2499 class TestProxVpeProfileHelper(unittest.TestCase):
2500
2501     def test_vpe_cores(self):
2502         resource_helper = mock.MagicMock()
2503         resource_helper.setup_helper.prox_config_data = [
2504             ('section1', []),
2505             ('section2', [
2506                 ('a', 'b'),
2507                 ('c', 'd'),
2508             ]),
2509             ('core 1', []),
2510             ('core 2', [
2511                 ('index', 8),
2512                 ('mode', ''),
2513             ]),
2514             ('core 3', [
2515                 ('index', 5),
2516                 ('mode', 'gen'),
2517                 ('name', 'cpe'),
2518             ]),
2519             ('core 4', [
2520                 ('index', 7),
2521                 ('mode', 'gen'),
2522                 ('name', 'inet'),
2523             ]),
2524         ]
2525
2526         helper = prox_helpers.ProxVpeProfileHelper(resource_helper)
2527         helper._cpu_topology = {
2528             0: {
2529                 1: {
2530                     5: (5, 1, 0)
2531                 },
2532                 2: {
2533                     6: (6, 2, 0)
2534                 },
2535                 3: {
2536                     7: (7, 3, 0)
2537                 },
2538                 4: {
2539                     8: (8, 3, 0)
2540                 },
2541             }
2542         }
2543
2544         expected_cpe = [3]
2545         expected_inet = [4]
2546         expected_combined = (expected_cpe, expected_inet)
2547
2548         self.assertIsNone(helper._cores_tuple)
2549         self.assertEqual(helper.cpe_cores, expected_cpe)
2550         self.assertEqual(helper.inet_cores, expected_inet)
2551         self.assertEqual(helper._cores_tuple, expected_combined)
2552
2553     def test_vpe_ports(self):
2554         resource_helper = mock.MagicMock()
2555         resource_helper.setup_helper.prox_config_data = [
2556             ('section1', []),
2557             ('section2', [
2558                 ('a', 'b'),
2559                 ('c', 'd'),
2560             ]),
2561             ('port 3', [
2562                 ('index', '5'),
2563                 ('name', 'cpe'),
2564                 ('mac', 'hardware'),
2565             ]),
2566             ('port 4', [
2567                 ('index', '7'),
2568                 ('name', 'inet'),
2569                 ('mac', 'hardware'),
2570             ]),
2571         ]
2572
2573         helper = prox_helpers.ProxVpeProfileHelper(resource_helper)
2574         helper._port_list = {
2575             0: {
2576                 1: {
2577                     5: 'cpe'
2578                 },
2579                 2: {
2580                     6: 'inet'
2581                 },
2582                 3: {
2583                     7: 'cpe'
2584                 },
2585                 4: {
2586                     8: 'inet'
2587                 },
2588             }
2589         }
2590
2591         expected_cpe = [3]
2592         expected_inet = [4]
2593         expected_combined = (expected_cpe, expected_inet)
2594
2595         self.assertIsNone(helper._ports_tuple)
2596         self.assertEqual(helper.cpe_ports, expected_cpe)
2597         self.assertEqual(helper.inet_ports, expected_inet)
2598         self.assertEqual(helper._ports_tuple, expected_combined)
2599
2600     def test_run_test(self, *args):
2601         resource_helper = mock.MagicMock()
2602         resource_helper.step_delta = 0.4
2603         resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2))
2604         resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5],
2605                                                                     [1, 1, 2, 3, 4, 5]])
2606
2607         helper = prox_helpers.ProxVpeProfileHelper(resource_helper)
2608
2609         helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0,
2610                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2611
2612         # negative pkt_size is the only way to make ratio > 1
2613         helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0,
2614                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2615
2616 class TestProxlwAFTRProfileHelper(unittest.TestCase):
2617
2618     def test_lwaftr_cores(self):
2619         resource_helper = mock.MagicMock()
2620         resource_helper.setup_helper.prox_config_data = [
2621             ('section1', []),
2622             ('section2', [
2623                 ('a', 'b'),
2624                 ('c', 'd'),
2625             ]),
2626             ('core 1', []),
2627             ('core 2', [
2628                 ('index', 8),
2629                 ('mode', ''),
2630             ]),
2631             ('core 3', [
2632                 ('index', 5),
2633                 ('mode', 'gen'),
2634                 ('name', 'tun'),
2635             ]),
2636             ('core 4', [
2637                 ('index', 7),
2638                 ('mode', 'gen'),
2639                 ('name', 'inet'),
2640             ]),
2641         ]
2642
2643         helper = prox_helpers.ProxlwAFTRProfileHelper(resource_helper)
2644         helper._cpu_topology = {
2645             0: {
2646                 1: {
2647                     5: (5, 1, 0)
2648                 },
2649                 2: {
2650                     6: (6, 2, 0)
2651                 },
2652                 3: {
2653                     7: (7, 3, 0)
2654                 },
2655                 4: {
2656                     8: (8, 3, 0)
2657                 },
2658             }
2659         }
2660
2661         expected_tun = [3]
2662         expected_inet = [4]
2663         expected_combined = (expected_tun, expected_inet)
2664
2665         self.assertIsNone(helper._cores_tuple)
2666         self.assertEqual(helper.tun_cores, expected_tun)
2667         self.assertEqual(helper.inet_cores, expected_inet)
2668         self.assertEqual(helper._cores_tuple, expected_combined)
2669
2670     def test_tun_ports(self):
2671         resource_helper = mock.MagicMock()
2672         resource_helper.setup_helper.prox_config_data = [
2673             ('section1', []),
2674             ('section2', [
2675                 ('a', 'b'),
2676                 ('c', 'd'),
2677             ]),
2678             ('port 3', [
2679                 ('index', '5'),
2680                 ('name', 'lwB4'),
2681                 ('mac', 'hardware'),
2682             ]),
2683             ('port 4', [
2684                 ('index', '7'),
2685                 ('name', 'inet'),
2686                 ('mac', 'hardware'),
2687             ]),
2688         ]
2689
2690         helper = prox_helpers.ProxlwAFTRProfileHelper(resource_helper)
2691         helper._port_list = {
2692             0: {
2693                 1: {
2694                     5: 'lwB4'
2695                 },
2696                 2: {
2697                     6: 'inet'
2698                 },
2699                 3: {
2700                     7: 'lwB4'
2701                 },
2702                 4: {
2703                     8: 'inet'
2704                 },
2705             }
2706         }
2707
2708         expected_tun = [3]
2709         expected_inet = [4]
2710         expected_combined = (expected_tun, expected_inet)
2711
2712         self.assertIsNone(helper._ports_tuple)
2713         self.assertEqual(helper.tun_ports, expected_tun)
2714         self.assertEqual(helper.inet_ports, expected_inet)
2715         self.assertEqual(helper._ports_tuple, expected_combined)
2716
2717     def test_run_test(self, *args):
2718         resource_helper = mock.MagicMock()
2719         resource_helper.step_delta = 0.4
2720         resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2))
2721         resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 2, 4, 6, 5],
2722                                                                     [1, 1, 2, 3, 4, 5]])
2723
2724         helper = prox_helpers.ProxlwAFTRProfileHelper(resource_helper)
2725
2726         helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0,
2727                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2728
2729         # negative pkt_size is the only way to make ratio > 1
2730         helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0,
2731                         line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
2732
2733
2734 class TestProxIrqProfileHelper(unittest.TestCase):
2735
2736     def test_run_test(self, *args):
2737         resource_helper = mock.MagicMock()
2738         helper = prox_helpers.ProxIrqProfileHelper(resource_helper)
2739         self.assertIsNone(helper._cores_tuple)
2740         self.assertIsNone(helper._ports_tuple)
2741         self.assertIsNone(helper._latency_cores)
2742         self.assertIsNone(helper._test_cores)
2743         self.assertIsNone(helper._cpu_topology)