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