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