prox: pass prox_config_dict between Processes using queue
[yardstick.git] / tests / unit / network_services / vnf_generic / vnf / test_prox_helpers.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016-2017 Intel Corporation
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 from __future__ import absolute_import
19
20 import copy
21 import os
22 import socket
23 import unittest
24 from itertools import repeat, chain
25 from contextlib import contextmanager
26 import mock
27
28 from tests.unit import STL_MOCKS
29 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
30
31 STLClient = mock.MagicMock()
32 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
33 stl_patch.start()
34
35 if stl_patch:
36     from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper
37     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxSocketHelper
38     from yardstick.network_services.vnf_generic.vnf.prox_helpers import PacketDump
39     from yardstick.network_services.vnf_generic.vnf.prox_helpers import CoreSocketTuple
40     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxTestDataTuple
41     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxDpdkVnfSetupEnvHelper
42     from yardstick.network_services.vnf_generic.vnf.prox_helpers import TotStatsTuple
43     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxResourceHelper
44
45
46 class TestCoreTuple(unittest.TestCase):
47     def test___init__(self):
48         core_tuple = CoreSocketTuple('core 5s6')
49         self.assertEqual(core_tuple.core_id, 5)
50         self.assertEqual(core_tuple.socket_id, 6)
51         self.assertFalse(core_tuple.is_hyperthread())
52
53         core_tuple = CoreSocketTuple('core 5s6h')
54         self.assertEqual(core_tuple.core_id, 5)
55         self.assertEqual(core_tuple.socket_id, 6)
56         self.assertTrue(core_tuple.is_hyperthread())
57
58     def test___init__negative(self):
59         bad_inputs = [
60             '',
61             '5',
62             '5s',
63             '6h',
64             '5s6',
65             'core',
66             'core h',
67             'core 5s',
68             'core 5 6',
69             'core 5 6h',
70             'core 5d6',
71             'core 5d6h',
72             1,
73             2.3,
74             [],
75             {},
76             object(),
77         ]
78
79         for bad_input in bad_inputs:
80             with self.assertRaises(ValueError):
81                 CoreSocketTuple(bad_input)
82
83     def test_find_in_topology(self):
84         topology_in = {
85             6: {
86                 5: {
87                     'key1': ['a', 'b'],
88                     'key2': ['c', 'd'],
89                 },
90             },
91         }
92
93         core_tuple = CoreSocketTuple('core 5s6')
94
95         expected = 'a'
96         result = core_tuple.find_in_topology(topology_in)
97         self.assertEqual(result, expected)
98
99         core_tuple = CoreSocketTuple('core 5s6h')
100
101         expected = 'c'
102         result = core_tuple.find_in_topology(topology_in)
103         self.assertEqual(result, expected)
104
105     def test_find_in_topology_negative(self):
106         core_tuple = CoreSocketTuple('core 6s5')
107         with self.assertRaises(ValueError):
108             # no socket key
109             core_tuple.find_in_topology({})
110
111         with self.assertRaises(ValueError):
112             # no core key
113             core_tuple.find_in_topology({5: {}})
114
115         with self.assertRaises(ValueError):
116             # no first value (as needed by non-hyperthread core)
117             core_tuple.find_in_topology({5: {6: {'key1': []}}})
118
119         core_tuple = CoreSocketTuple('core 6s5h')
120         with self.assertRaises(ValueError):
121             # no second value (as needed by hyperthread core)
122             core_tuple.find_in_topology({5: {6: {'key1': ['e']}}})
123
124
125 class TestTotStatsTuple(unittest.TestCase):
126     def test___new___negative(self):
127         with self.assertRaises(TypeError):
128             # no values
129             TotStatsTuple()
130
131         with self.assertRaises(TypeError):
132             # one, non-integer value
133             TotStatsTuple('a')
134
135         with self.assertRaises(TypeError):
136             # too many values
137             TotStatsTuple(3, 4, 5, 6, 7)
138
139
140 class TestProxTestDataTuple(unittest.TestCase):
141     def test___init__(self):
142         prox_test_data = ProxTestDataTuple(1, 2, 3, 4, 5, 6, 7, 8, 9)
143         self.assertEqual(prox_test_data.tolerated, 1)
144         self.assertEqual(prox_test_data.tsc_hz, 2)
145         self.assertEqual(prox_test_data.delta_rx, 3)
146         self.assertEqual(prox_test_data.delta_tx, 4)
147         self.assertEqual(prox_test_data.delta_tsc, 5)
148         self.assertEqual(prox_test_data.latency, 6)
149         self.assertEqual(prox_test_data.rx_total, 7)
150         self.assertEqual(prox_test_data.tx_total, 8)
151         self.assertEqual(prox_test_data.pps, 9)
152
153     def test_properties(self):
154         prox_test_data = ProxTestDataTuple(1, 2, 3, 4, 5, 6, 7, 8, 9)
155         self.assertEqual(prox_test_data.pkt_loss, 12.5)
156         self.assertEqual(prox_test_data.mpps, 1.6 / 1e6)
157         self.assertEqual(prox_test_data.can_be_lost, 0)
158         self.assertEqual(prox_test_data.drop_total, 1)
159         self.assertFalse(prox_test_data.success)
160
161         prox_test_data = ProxTestDataTuple(10, 2, 3, 4, 5, 6, 997, 998, 9)
162         self.assertTrue(prox_test_data.success)
163
164     def test_pkt_loss_zero_division(self):
165         prox_test_data = ProxTestDataTuple(1, 2, 3, 4, 5, 6, 7, 0, 9)
166         self.assertEqual(prox_test_data.pkt_loss, 100.0)
167
168     def test_get_samples(self):
169         prox_test_data = ProxTestDataTuple(1, 2, 3, 4, 5, [6.1, 6.9, 6.4], 7, 8, 9)
170
171         expected = {
172             "Throughput": 1.6 / 1e6,
173             "DropPackets": 12.5,
174             "CurrentDropPackets": 12.5,
175             "TxThroughput": 9 / 1e6,
176             "RxThroughput": 1.6 / 1e6,
177             "PktSize": 64,
178             "PortSample": 1,
179             "LatencyMin": 6.1,
180             "LatencyMax": 6.9,
181             "LatencyAvg": 6.4,
182         }
183         result = prox_test_data.get_samples(64, port_samples={"PortSample": 1})
184         self.assertDictEqual(result, expected)
185
186         expected = {
187             "Throughput": 1.6 / 1e6,
188             "DropPackets": 0.123,
189             "CurrentDropPackets": 0.123,
190             "TxThroughput": 9 / 1e6,
191             "RxThroughput": 1.6 / 1e6,
192             "PktSize": 64,
193             "LatencyMin": 6.1,
194             "LatencyMax": 6.9,
195             "LatencyAvg": 6.4,
196         }
197         result = prox_test_data.get_samples(64, 0.123)
198         self.assertDictEqual(result, expected)
199
200     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.LOG')
201     def test_log_data(self, mock_logger):
202         my_mock_logger = mock.MagicMock()
203         prox_test_data = ProxTestDataTuple(1, 2, 3, 4, 5, [6.1, 6.9, 6.4], 7, 8, 9)
204         prox_test_data.log_data()
205         self.assertEqual(my_mock_logger.debug.call_count, 0)
206         self.assertEqual(mock_logger.debug.call_count, 2)
207
208         mock_logger.debug.reset_mock()
209         prox_test_data.log_data(my_mock_logger)
210         self.assertEqual(my_mock_logger.debug.call_count, 2)
211         self.assertEqual(mock_logger.debug.call_count, 0)
212
213
214 class TestPacketDump(unittest.TestCase):
215     PAYLOAD = "payload"
216
217     def test__init__(self):
218         PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
219
220     def test___str__(self):
221         expected = '<PacketDump port: port_id payload: {}>'.format(self.PAYLOAD)
222         dump1 = PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
223         self.assertEqual(str(dump1), expected)
224
225     def test_port_id(self):
226         p = PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
227         self.assertEqual(p.port_id, "port_id")
228
229     def test_data_len(self):
230         p = PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
231         self.assertEqual(p.data_len, len(self.PAYLOAD))
232
233     def test_payload(self):
234         p = PacketDump("port_id", len(self.PAYLOAD), self.PAYLOAD)
235         self.assertEqual(p.payload(), self.PAYLOAD)
236
237         self.assertEqual(p.payload(3), self.PAYLOAD[3:])
238
239         self.assertEqual(p.payload(end=3), self.PAYLOAD[:4])
240
241         self.assertEqual(p.payload(2, 4), self.PAYLOAD[2:5])
242
243
244 PACKET_DUMP_1 = """\
245 pktdump,3,11
246 hello world
247 """
248
249 PACKET_DUMP_2 = """\
250 pktdump,3,11
251 hello world
252 pktdump,2,9
253 brown fox jumped over
254 pktdump,4,8
255 lazy
256 dog
257 """
258
259 PACKET_DUMP_NON_1 = """\
260 not_a_dump,1,2
261 other data
262 """
263
264 PACKET_DUMP_MIXED_1 = """\
265 pktdump,3,11
266 hello world
267 not_a_dump,1,2
268 other data
269 """
270
271 PACKET_DUMP_BAD_1 = """\
272 pktdump,one,12
273 bad port id
274 """
275
276 PACKET_DUMP_BAD_2 = """\
277 pktdump,3,twelve
278 bad data length
279 """
280
281 PACKET_DUMP_BAD_3 = """\
282 pktdump,3
283 no data length value
284 """
285
286
287 @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
288 class TestProxSocketHelper(unittest.TestCase):
289     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket')
290     def test___init__(self, mock_socket, mock_time):
291         expected = mock_socket.socket()
292         prox = ProxSocketHelper()
293         result = prox._sock
294         self.assertEqual(result, expected)
295
296     def test_connect(self, mock_time):
297         mock_sock = mock.MagicMock()
298         prox = ProxSocketHelper(mock_sock)
299         prox.connect('10.20.30.40', 23456)
300         self.assertEqual(mock_sock.connect.call_count, 1)
301
302     def test_get_sock(self, mock_time):
303         mock_sock = mock.MagicMock()
304         prox = ProxSocketHelper(mock_sock)
305         result = prox.get_socket()
306         self.assertIs(result, mock_sock)
307
308     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.select')
309     def test_get_data(self, mock_select, mock_time):
310         mock_select.select.side_effect = [[1], [0]]
311         mock_socket = mock.MagicMock()
312         mock_recv = mock_socket.recv()
313         mock_recv.decode.return_value = ""
314         prox = ProxSocketHelper(mock_socket)
315         ret = prox.get_data()
316         self.assertEqual(ret, "")
317         self.assertEqual(len(prox._pkt_dumps), 0)
318
319         mock_select.select.reset_mock()
320         mock_select.select.side_effect = chain([['a'], ['']], repeat([1], 3))
321         mock_recv.decode.return_value = PACKET_DUMP_1
322         ret = prox.get_data()
323         self.assertEqual(mock_select.select.call_count, 2)
324         self.assertEqual(ret, 'pktdump,3,11')
325         self.assertEqual(len(prox._pkt_dumps), 1)
326
327         mock_select.select.reset_mock()
328         mock_select.select.side_effect = chain([[object()], [None]], repeat([1], 3))
329         mock_recv.decode.return_value = PACKET_DUMP_2
330         ret = prox.get_data()
331         self.assertEqual(mock_select.select.call_count, 2)
332         self.assertEqual(ret, 'jumped over')
333         self.assertEqual(len(prox._pkt_dumps), 3)
334
335     def test__parse_socket_data_mixed_data(self, mock_time):
336         prox = ProxSocketHelper(mock.MagicMock())
337         ret = prox._parse_socket_data(PACKET_DUMP_NON_1, False)
338         self.assertEqual(ret, 'not_a_dump,1,2')
339         self.assertEqual(len(prox._pkt_dumps), 0)
340
341         ret = prox._parse_socket_data(PACKET_DUMP_MIXED_1, False)
342         self.assertEqual(ret, 'not_a_dump,1,2')
343         self.assertEqual(len(prox._pkt_dumps), 1)
344
345     def test__parse_socket_data_bad_data(self, mock_time):
346         prox = ProxSocketHelper(mock.MagicMock())
347         with self.assertRaises(ValueError):
348             prox._parse_socket_data(PACKET_DUMP_BAD_1, False)
349
350         with self.assertRaises(ValueError):
351             prox._parse_socket_data(PACKET_DUMP_BAD_2, False)
352
353         ret = prox._parse_socket_data(PACKET_DUMP_BAD_3, False)
354         self.assertEqual(ret, 'pktdump,3')
355
356     def test__parse_socket_data_pkt_dump_only(self, mock_time):
357         prox = ProxSocketHelper(mock.MagicMock())
358         ret = prox._parse_socket_data('', True)
359         self.assertFalse(ret)
360
361         ret = prox._parse_socket_data(PACKET_DUMP_1, True)
362         self.assertTrue(ret)
363
364         ret = prox._parse_socket_data(PACKET_DUMP_2, True)
365         self.assertTrue(ret)
366
367     def test_put_command(self, mock_time):
368         mock_socket = mock.MagicMock()
369         prox = ProxSocketHelper(mock_socket)
370         prox.put_command("data")
371         mock_socket.sendall.assert_called_once()
372
373     def test_put_command_socket_error(self, mock_time):
374         mock_socket = mock.MagicMock()
375         mock_socket.sendall.side_effect = OSError
376         prox = ProxSocketHelper(mock_socket)
377         prox.put_command("data")
378         mock_socket.sendall.assert_called_once()
379
380     def test_get_packet_dump(self, mock_time):
381         mock_socket = mock.MagicMock()
382         prox = ProxSocketHelper(mock_socket)
383         prox._pkt_dumps = []
384         self.assertIsNone(prox.get_packet_dump())
385
386         prox._pkt_dumps = [234]
387         self.assertEqual(prox.get_packet_dump(), 234)
388         self.assertEqual(prox._pkt_dumps, [])
389
390     def test_stop_all_reset(self, mock_time):
391         mock_socket = mock.MagicMock()
392         prox = ProxSocketHelper(mock_socket)
393         prox.stop_all_reset()
394         mock_socket.sendall.assert_called()
395
396     def test_stop_all(self, mock_time):
397         mock_socket = mock.MagicMock()
398         prox = ProxSocketHelper(mock_socket)
399         prox.stop_all()
400         mock_socket.sendall.assert_called()
401
402     def test_stop(self, mock_time):
403         mock_socket = mock.MagicMock()
404         prox = ProxSocketHelper(mock_socket)
405         prox.stop([3, 4, 5], 16)
406         mock_socket.sendall.assert_called()
407
408     def test_start_all(self, mock_time):
409         mock_socket = mock.MagicMock()
410         prox = ProxSocketHelper(mock_socket)
411         prox.start_all()
412         mock_socket.sendall.assert_called()
413
414     def test_start(self, mock_time):
415         mock_socket = mock.MagicMock()
416         prox = ProxSocketHelper(mock_socket)
417         prox.start([3, 4, 5])
418         mock_socket.sendall.assert_called()
419
420     def test_reset_stats(self, mock_time):
421         mock_socket = mock.MagicMock()
422         prox = ProxSocketHelper(mock_socket)
423         prox.reset_stats()
424         mock_socket.sendall.assert_called()
425
426     def test_set_pkt_size(self, mock_time):
427         mock_socket = mock.MagicMock()
428         prox = ProxSocketHelper(mock_socket)
429         prox.set_pkt_size([3, 4, 5], 1024)
430         self.assertEqual(mock_socket.sendall.call_count, 3)
431
432     def test_set_value(self, mock_time):
433         mock_socket = mock.MagicMock()
434         prox = ProxSocketHelper(mock_socket)
435         prox.set_value([3, 4, 5], 10, 20, 30)
436         self.assertEqual(mock_socket.sendall.call_count, 3)
437
438     def test_reset_values(self, mock_time):
439         mock_socket = mock.MagicMock()
440         prox = ProxSocketHelper(mock_socket)
441         prox.reset_values([3, 4, 5])
442         self.assertEqual(mock_socket.sendall.call_count, 3)
443
444     def test_set_speed(self, mock_time):
445         mock_socket = mock.MagicMock()
446         prox = ProxSocketHelper(mock_socket)
447         prox.set_speed([3, 4, 5], 1000)
448         self.assertEqual(mock_socket.sendall.call_count, 3)
449
450     def test_slope_speed(self, mock_time):
451         core_data = [
452             {
453                 'cores': [3, 4, 5],
454                 'speed': 1000,
455             },
456             {
457                 'cores': [9, 10, 11],
458                 'speed': '500.5',
459             },
460         ]
461
462         mock_socket = mock.MagicMock()
463         prox = ProxSocketHelper(mock_socket)
464         prox.set_speed = set_speed = mock.MagicMock()
465         prox.slope_speed(core_data, 5)
466         self.assertEqual(set_speed.call_count, 20)
467
468         set_speed.reset_mock()
469         prox.slope_speed(core_data, 5, 5)
470         self.assertEqual(set_speed.call_count, 10)
471
472     def test_set_pps(self, mock_time):
473         mock_socket = mock.MagicMock()
474         prox = ProxSocketHelper(mock_socket)
475         prox.set_pps([3, 4, 5], 1000, 512)
476         self.assertEqual(mock_socket.sendall.call_count, 3)
477
478     def test_lat_stats(self, mock_time):
479         latency_output = [
480             '1, 2 , 3',  # has white space
481             '4,5',  # too short
482             '7,8,9,10.5,11',  # too long with float, but float is in unused portion
483             'twelve,13,14',  # value as English word
484             '15,16.2,17',  # float in used portion
485         ]
486
487         mock_socket = mock.MagicMock()
488         prox = ProxSocketHelper(mock_socket)
489         prox.get_data = mock.MagicMock(side_effect=latency_output)
490
491         expected = (
492             {
493                 3: 1,
494                 5: 7,
495             },
496             {
497                 3: 2,
498                 5: 8,
499             },
500             {
501                 3: 3,
502                 5: 9,
503             },
504         )
505         result = prox.lat_stats([3, 4, 5, 6, 7], 16)
506         self.assertEqual(mock_socket.sendall.call_count, 5)
507         self.assertEqual(result, expected)
508
509     def test_get_all_tot_stats_error(self, mock_time):
510         mock_socket = mock.MagicMock()
511         prox = ProxSocketHelper(mock_socket)
512         prox.get_data = mock.MagicMock(return_value='3,4,5')
513         expected = [0, 0, 0, 0]
514         result = prox.get_all_tot_stats()
515         self.assertEqual(result, expected)
516
517     def test_get_all_tot_stats(self, mock_time):
518         mock_socket = mock.MagicMock()
519         prox = ProxSocketHelper(mock_socket)
520         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
521         expected = 3, 4, 5, 6
522         result = prox.get_all_tot_stats()
523         self.assertEqual(result, expected)
524
525     def test_hz(self, mock_time):
526         mock_socket = mock.MagicMock()
527         prox = ProxSocketHelper(mock_socket)
528         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
529         expected = 6
530         result = prox.hz()
531         self.assertEqual(result, expected)
532
533     def test_rx_stats(self, mock_time):
534         core_stats = [
535             '3,4,5,6',
536             '7,8,9,10,NaN',
537             '11,12,13,14,15',
538         ]
539
540         mock_socket = mock.MagicMock()
541         prox = ProxSocketHelper(mock_socket)
542         prox.get_data = mock.MagicMock(side_effect=core_stats)
543         expected = 21, 24, 27, 14
544         result = prox.rx_stats([3, 4, 5], 16)
545         self.assertEqual(result, expected)
546
547     def test_core_stats(self, mock_time):
548         core_stats = [
549             '3,4,5,6',
550             '7,8,9,10,NaN',
551             '11,12,13,14,15',
552         ]
553
554         mock_socket = mock.MagicMock()
555         prox = ProxSocketHelper(mock_socket)
556         prox.get_data = mock.MagicMock(side_effect=core_stats)
557         expected = 21, 24, 27, 14
558         result = prox.core_stats([3, 4, 5], 16)
559         self.assertEqual(result, expected)
560
561     def test_port_stats(self, mock_time):
562         port_stats = [
563             ','.join(str(n) for n in range(3, 15)),
564             ','.join(str(n) for n in range(8, 32, 2)),
565             ','.join(str(n) for n in range(5, 89, 7)),
566         ]
567
568         mock_socket = mock.MagicMock()
569         prox = ProxSocketHelper(mock_socket)
570         prox.get_data = mock.MagicMock(side_effect=port_stats)
571         expected = [16, 26, 36, 46, 56, 66, 76, 86, 96, 106, 116, 126]
572         result = prox.port_stats([3, 4, 5])
573         self.assertEqual(result, expected)
574
575     def test_measure_tot_stats(self, mock_time):
576         start_tot = 3, 4, 5, 6
577         end_tot = 7, 9, 11, 13
578         delta_tot = 4, 5, 6, 7
579
580         get_data_output = [
581             ','.join(str(n) for n in start_tot),
582             ','.join(str(n) for n in end_tot),
583         ]
584
585         mock_socket = mock.MagicMock()
586         prox = ProxSocketHelper(mock_socket)
587         prox.get_data = mock.MagicMock(side_effect=get_data_output)
588         expected = {
589             'start_tot': start_tot,
590             'end_tot': end_tot,
591             'delta': delta_tot,
592         }
593         with prox.measure_tot_stats() as result:
594             pass
595         self.assertEqual(result, expected)
596
597     def test_tot_stats(self, mock_time):
598         mock_socket = mock.MagicMock()
599         prox = ProxSocketHelper(mock_socket)
600         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
601         expected = 3, 4, 5
602         result = prox.tot_stats()
603         self.assertEqual(result, expected)
604
605     def test_tot_ierrors(self, mock_time):
606         mock_socket = mock.MagicMock()
607         prox = ProxSocketHelper(mock_socket)
608         prox.get_data = mock.MagicMock(return_value='3,4,5,6')
609         expected = 3, 3
610         result = prox.tot_ierrors()
611         self.assertEqual(result, expected)
612
613     def test_set_count(self, mock_time):
614         mock_socket = mock.MagicMock()
615         prox = ProxSocketHelper(mock_socket)
616         prox.set_count(432, [3, 4, 5])
617         self.assertEqual(mock_socket.sendall.call_count, 3)
618
619     def test_dump_rx(self, mock_time):
620         mock_socket = mock.MagicMock()
621         prox = ProxSocketHelper(mock_socket)
622         prox.dump_rx(3, 5, 8)
623         self.assertEqual(mock_socket.sendall.call_count, 1)
624
625     def test_quit(self, mock_time):
626         mock_socket = mock.MagicMock()
627         prox = ProxSocketHelper(mock_socket)
628         prox.quit()
629         mock_socket.sendall.assert_called()
630
631     def test_force_quit(self, mock_time):
632         mock_socket = mock.MagicMock()
633         prox = ProxSocketHelper(mock_socket)
634         prox.force_quit()
635         mock_socket.sendall.assert_called()
636
637
638 class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase):
639
640     VNFD0 = {
641         'short-name': 'ProxVnf',
642         'vdu': [
643             {
644                 'routing_table': [
645                     {
646                         'network': '152.16.100.20',
647                         'netmask': '255.255.255.0',
648                         'gateway': '152.16.100.20',
649                         'if': 'xe0',
650                     },
651                     {
652                         'network': '152.16.40.20',
653                         'netmask': '255.255.255.0',
654                         'gateway': '152.16.40.20',
655                         'if': 'xe1',
656                     },
657                 ],
658                 'description': 'PROX approximation using DPDK',
659                 'name': 'proxvnf-baremetal',
660                 'nd_route_tbl': [
661                     {
662                         'network': '0064:ff9b:0:0:0:0:9810:6414',
663                         'netmask': '112',
664                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
665                         'if': 'xe0',
666                     },
667                     {
668                         'network': '0064:ff9b:0:0:0:0:9810:2814',
669                         'netmask': '112',
670                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
671                         'if': 'xe1',
672                     },
673                 ],
674                 'id': 'proxvnf-baremetal',
675                 'external-interface': [
676                     {
677                         'virtual-interface': {
678                             'dst_mac': '00:00:00:00:00:04',
679                             'vpci': '0000:05:00.0',
680                             'local_ip': '152.16.100.19',
681                             'type': 'PCI-PASSTHROUGH',
682                             'vld_id': 'uplink_0',
683                             'netmask': '255.255.255.0',
684                             'dpdk_port_num': 0,
685                             'bandwidth': '10 Gbps',
686                             'driver': "i40e",
687                             'dst_ip': '152.16.100.19',
688                             'local_iface_name': 'xe0',
689                             'local_mac': '00:00:00:00:00:02',
690                             'ifname': 'xe0',
691                         },
692                         'vnfd-connection-point-ref': 'xe0',
693                         'name': 'xe0',
694                     },
695                     {
696                         'virtual-interface': {
697                             'dst_mac': '00:00:00:00:00:03',
698                             'vpci': '0000:05:00.1',
699                             'local_ip': '152.16.40.19',
700                             'type': 'PCI-PASSTHROUGH',
701                             'vld_id': 'downlink_0',
702                             'driver': "i40e",
703                             'netmask': '255.255.255.0',
704                             'dpdk_port_num': 1,
705                             'bandwidth': '10 Gbps',
706                             'dst_ip': '152.16.40.20',
707                             'local_iface_name': 'xe1',
708                             'local_mac': '00:00:00:00:00:01',
709                             'ifname': 'xe1',
710                         },
711                         'vnfd-connection-point-ref': 'xe1',
712                         'name': 'xe1',
713                     },
714                 ],
715             },
716         ],
717         'description': 'PROX approximation using DPDK',
718         'mgmt-interface': {
719             'vdu-id': 'proxvnf-baremetal',
720             'host': '1.2.1.1',
721             'password': 'r00t',
722             'user': 'root',
723             'ip': '1.2.1.1',
724         },
725         'benchmark': {
726             'kpi': [
727                 'packets_in',
728                 'packets_fwd',
729                 'packets_dropped',
730             ],
731         },
732         'id': 'ProxApproxVnf',
733         'name': 'ProxVnf',
734     }
735
736     VNFD = {
737         'vnfd:vnfd-catalog': {
738             'vnfd': [
739                 VNFD0,
740             ],
741         },
742     }
743
744     def test__replace_quoted_with_value(self):
745         # empty string
746         input_str = ''
747         expected = ''
748         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat')
749         self.assertEqual(result, expected)
750
751         # no quoted substring
752         input_str = 'lion tiger bear'
753         expected = 'lion tiger bear'
754         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat')
755         self.assertEqual(result, expected)
756
757         # partially quoted substring
758         input_str = 'lion "tiger bear'
759         expected = 'lion "tiger bear'
760         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat')
761         self.assertEqual(result, expected)
762
763         # one quoted substring
764         input_str = 'lion "tiger" bear'
765         expected = 'lion "cat" bear'
766         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat')
767         self.assertEqual(result, expected)
768
769         # two quoted substrings
770         input_str = 'lion "tiger" bear "shark" whale'
771         expected = 'lion "cat" bear "shark" whale'
772         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat')
773         self.assertEqual(result, expected)
774
775         # two quoted substrings, both replaced
776         input_str = 'lion "tiger" bear "shark" whale'
777         expected = 'lion "cat" bear "cat" whale'
778         result = ProxDpdkVnfSetupEnvHelper._replace_quoted_with_value(input_str, 'cat', 2)
779         self.assertEqual(result, expected)
780
781     def test__get_tx_port(self):
782         # no data
783         input_data = {'section1': []}
784         expected = -1
785         result = ProxDpdkVnfSetupEnvHelper._get_tx_port('section1', input_data)
786         self.assertEqual(result, expected)
787
788         # data for other section
789         input_data = {
790             'section1': [],
791             'section2': [
792                 ('rx port', '3'),
793                 ('tx port', '4'),
794             ],
795         }
796         expected = -1
797         result = ProxDpdkVnfSetupEnvHelper._get_tx_port('section1', input_data)
798         self.assertEqual(result, expected)
799
800         # data for section
801         input_data['section1'] = section1 = [
802             ('rx port', '4', 'more', 432),
803             ('tx port', '3'),
804         ]
805         expected = 3
806         result = ProxDpdkVnfSetupEnvHelper._get_tx_port('section1', input_data)
807         self.assertEqual(result, expected)
808
809         # more data for section,
810         section1.extend([
811             ('rx port', '2'),
812             ('tx port', '1', 'and more', 234),
813         ])
814         expected = 1
815         result = ProxDpdkVnfSetupEnvHelper._get_tx_port('section1', input_data)
816         self.assertEqual(result, expected)
817
818     def test_write_prox_config(self):
819         input_data = {}
820         expected = ''
821         result = ProxDpdkVnfSetupEnvHelper.write_prox_config(input_data)
822         self.assertEqual(result, expected)
823
824         input_data = [
825             [
826                 'section1',
827                 [],
828             ],
829         ]
830         expected = '[section1]'
831         result = ProxDpdkVnfSetupEnvHelper.write_prox_config(input_data)
832         self.assertEqual(result, expected)
833
834         input_data = [
835             [
836                 'section1',
837                 [],
838             ],
839             [
840                 'section2',
841                 [
842                     ['key1', 'value1'],
843                     ['__name__', 'not this one'],
844                     ['key2', None],
845                     ['key3', 234],
846                     ['key4', 'multi-line\nvalue'],
847                 ],
848             ],
849         ]
850         expected = os.linesep.join([
851             '[section1]',
852             '[section2]',
853             'key1=value1',
854             'key2',
855             'key3=234',
856             'key4=multi-line\n\tvalue',
857         ])
858         result = ProxDpdkVnfSetupEnvHelper.write_prox_config(input_data)
859         self.assertEqual(result, expected)
860
861     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file')
862     def test_build_config_file_no_additional_file(self, mock_find_path):
863         vnf1 = {
864             'prox_args': {'-c': ""},
865             'prox_path': 'd',
866             'prox_config': 'e/f',
867         }
868
869         mock_find_path.side_effect = ['1', '2']
870
871         vnfd_helper = mock.MagicMock()
872         ssh_helper = mock.MagicMock()
873         scenario_helper = ScenarioHelper('vnf1')
874         scenario_helper.scenario_cfg = {
875             'task_path': 'a/b',
876             'options': {
877                 'vnf1': vnf1,
878             },
879         }
880
881         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
882         helper.copy_to_target = mock.MagicMock(return_value='3')
883         helper.generate_prox_config_file = mock.MagicMock(return_value='4')
884         helper.upload_prox_config = mock.MagicMock(return_value='5')
885
886         self.assertEqual(helper.additional_files, {})
887         self.assertNotEqual(helper._prox_config_data, '4')
888         self.assertNotEqual(helper.remote_path, '5')
889         helper.build_config_file()
890         self.assertEqual(helper.additional_files, {})
891         self.assertEqual(helper._prox_config_data, '4')
892         self.assertEqual(helper.remote_path, '5')
893
894     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file')
895     def test_build_config_file_additional_file_string(self, mock_find_path):
896         vnf1 = {
897             'prox_args': {'-c': ""},
898             'prox_path': 'd',
899             'prox_config': 'e/f',
900             'prox_files': 'g/h.i',
901         }
902
903         mock_find_path.side_effect = ['1', '2']
904         vnfd_helper = mock.MagicMock()
905         ssh_helper = mock.MagicMock()
906         scenario_helper = ScenarioHelper('vnf1')
907         scenario_helper.scenario_cfg = {
908             'task_path': 'a/b',
909             'options': {
910                 'vnf1': vnf1,
911             },
912         }
913
914         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
915         helper.copy_to_target = mock.MagicMock(side_effect=['33', '34', '35'])
916         helper.generate_prox_config_file = mock.MagicMock(return_value='44')
917         helper.upload_prox_config = mock.MagicMock(return_value='55')
918
919         self.assertEqual(helper.additional_files, {})
920         expected = {'h.i': '33'}
921         helper.build_config_file()
922         self.assertDictEqual(helper.additional_files, expected)
923
924     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file')
925     def test_build_config_file_additional_file(self, mock_find_path):
926         vnf1 = {
927             'prox_args': {'-c': ""},
928             'prox_path': 'd',
929             'prox_config': 'e/f',
930             'prox_files': [
931                 'g/h.i',
932                 'j/k/l',
933                 'm_n',
934             ],
935         }
936
937         mock_find_path.side_effect = ['1', '2']
938         vnfd_helper = mock.MagicMock()
939         ssh_helper = mock.MagicMock()
940         scenario_helper = ScenarioHelper('vnf1')
941         scenario_helper.scenario_cfg = {
942             'task_path': 'a/b',
943             'options': {
944                 'vnf1': vnf1,
945             },
946         }
947
948         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
949         helper.copy_to_target = mock.MagicMock(side_effect=['33', '34', '35'])
950         helper.generate_prox_config_file = mock.MagicMock(return_value='44')
951         helper.upload_prox_config = mock.MagicMock(return_value='55')
952
953         self.assertEqual(helper.additional_files, {})
954         self.assertNotEqual(helper._prox_config_data, '44')
955         self.assertNotEqual(helper.remote_path, '55')
956         expected = {'h.i': '33', 'l': '34', 'm_n': '35'}
957         helper.build_config_file()
958         self.assertDictEqual(helper.additional_files, expected)
959         self.assertEqual(helper._prox_config_data, '44')
960         self.assertEqual(helper.remote_path, '55')
961
962     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file')
963     def test_build_config(self, mock_find_path):
964         vnf1 = {
965             'prox_args': {'-f': ""},
966             'prox_path': '/opt/nsb_bin/prox',
967             'prox_config': 'configs/gen_l2fwd-2.cfg',
968             'prox_files': [
969                 'g/h.i',
970                 'j/k/l',
971                 'm_n',
972             ],
973         }
974
975         mock_find_path.side_effect = ['1', '2']
976         vnfd_helper = mock.MagicMock()
977         ssh_helper = mock.MagicMock()
978         ssh_helper.provision_tool.return_value = "/opt/nsb_bin/prox"
979         scenario_helper = ScenarioHelper('vnf1')
980         scenario_helper.scenario_cfg = {
981             'task_path': 'a/b',
982             'options': {
983                 'vnf1': vnf1,
984             },
985         }
986
987         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
988         helper.remote_path = "/tmp/prox.cfg"
989         expected = "sudo bash -c 'cd /opt/nsb_bin; /opt/nsb_bin/prox -o cli -f  -f /tmp/prox.cfg '"
990         with mock.patch.object(helper, "build_config_file") as mock_build_config:
991             prox_cmd = helper.build_config()
992             self.assertEqual(prox_cmd, expected)
993
994     def test__insert_additional_file(self):
995         vnfd_helper = mock.MagicMock()
996         ssh_helper = mock.MagicMock()
997         scenario_helper = mock.MagicMock()
998
999         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1000         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1001         res = helper._insert_additional_file('dofile("ipv4.lua")')
1002         self.assertEqual(res, 'dofile("/tmp/ipv4.lua")')
1003
1004     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1005     def test_generate_prox_config_file(self, mock_parser_type):
1006         def init(*args):
1007             if sections_data:
1008                 args[-1].extend(sections_data)
1009             return mock.MagicMock()
1010
1011         sections_data = []
1012
1013         mock_parser_type.side_effect = init
1014
1015         vnfd_helper = VnfdHelper(self.VNFD0)
1016         ssh_helper = mock.MagicMock()
1017         scenario_helper = mock.MagicMock()
1018
1019         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1020         helper.additional_files = {}
1021
1022         expected = []
1023         result = helper.generate_prox_config_file('a/b')
1024         self.assertEqual(result, expected)
1025
1026         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1027
1028         helper.remote_prox_file_name = 'remote'
1029         sections_data = [
1030             [
1031                 'lua',
1032                 [
1033                     ['dofile("ipv4.lua")', ''],
1034                 ],
1035             ],
1036             [
1037                 'port 0',
1038                 [
1039                     ['ip', ''],
1040                     ['mac', 'foo'],
1041                     ['dst mac', '@@1'],
1042                     ['tx port', '1'],
1043                 ],
1044             ],
1045             [
1046                 'port 2',
1047                 [
1048                     ['ip', ''],
1049                     ['$sut_mac0', '@@dst_mac0'],
1050                     ['tx port', '0'],
1051                     ['single', '@'],
1052                     ['user_table', 'dofile("ipv4.lua")'],
1053                     ['missing_addtional_file', 'dofile("nosuch")'],
1054                 ],
1055             ],
1056         ]
1057
1058         expected = [
1059             [
1060                 'lua',
1061                 [
1062                     ['dofile("/tmp/ipv4.lua")', ''],
1063                 ],
1064             ],
1065             [
1066                 'port 0',
1067                 [
1068                     ['ip', ''],
1069                     ['mac', 'hardware'],
1070                     ['dst mac', '00:00:00:00:00:03'],
1071                     ['tx port', '1'],
1072                 ],
1073             ],
1074             [
1075                 'port 2',
1076                 [
1077                     ['ip', ''],
1078                     ['$sut_mac0', '00 00 00 00 00 04'],
1079                     ['tx port', '0'],
1080                     ['single', '@'],
1081                     ['user_table', 'dofile("/tmp/ipv4.lua")'],
1082                     ['missing_addtional_file', 'dofile("nosuch")'],
1083                 ],
1084             ],
1085         ]
1086         result = helper.generate_prox_config_file('/c/d/e')
1087         self.assertEqual(result, expected, str(result))
1088
1089     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1090     def test_generate_prox_config_file_negative(self, mock_parser_type):
1091         def init(*args):
1092             args[-1].update(sections_data)
1093             return mock.MagicMock()
1094
1095         sections_data = {}
1096
1097         mock_parser_type.side_effect = init
1098
1099         vnfd_helper = mock.MagicMock()
1100         vnfd_helper.interfaces = []
1101         ssh_helper = mock.MagicMock()
1102         scenario_helper = mock.MagicMock()
1103
1104         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1105         helper.additional_files = {}
1106         helper.remote_prox_file_name = 'remote'
1107         vnfd_helper.interfaces = [
1108             {
1109                 'virtual-interface': {
1110                     'dpdk_port_num': 3,
1111                     'dst_mac': '00:00:00:de:ad:88',
1112                 },
1113             },
1114             {
1115                 'virtual-interface': {
1116                     'dpdk_port_num': 5,
1117                     'dst_mac': '00:00:00:de:ad:ff',
1118                 },
1119             },
1120             {
1121                 'virtual-interface': {
1122                     'dpdk_port_num': 7,
1123                     'dst_mac': '00:00:00:de:ad:ff',
1124                 },
1125             },
1126         ]
1127         sections_data = {
1128             'port 3': [
1129                 ['ip', ''],
1130                 ['mac', 'foo'],
1131                 ['dst mac', ''],
1132             ],
1133             'port 5': [
1134                 ['ip', ''],
1135                 ['dst mac', ''],
1136                 ['tx port', '0'],
1137                 ['???', 'dofile "here" 23'],
1138             ],
1139         }
1140
1141         with self.assertRaises(Exception):
1142             helper.generate_prox_config_file('a/b')
1143
1144     def test_generate_prox_lua_file(self):
1145         vnfd_helper = VnfdHelper(self.VNFD0)
1146         ssh_helper = mock.MagicMock()
1147         scenario_helper = mock.MagicMock()
1148
1149         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1150         helper.LUA_PARAMETER_NAME = 'sut'
1151
1152         expected = [
1153             'sut_hex_ip_port_0:"98 10 64 13"',
1154             'sut_ip_port_0:"152.16.100.19"',
1155             'gen_hex_ip_port_0:"98 10 64 13"',
1156             'gen_ip_port_0:"152.16.100.19"',
1157
1158             'sut_hex_ip_port_1:"98 10 28 13"',
1159             'sut_ip_port_1:"152.16.40.19"',
1160             'gen_hex_ip_port_1:"98 10 28 14"',
1161             'gen_ip_port_1:"152.16.40.20"',
1162         ]
1163         result = helper.generate_prox_lua_file()
1164         self.assertListEqual(result.splitlines(), expected)
1165
1166     def test_upload_prox_lua(self):
1167         def identity(*args):
1168             return args
1169
1170         vnfd_helper = mock.MagicMock()
1171         vnfd_helper.interfaces = []
1172         ssh_helper = mock.MagicMock()
1173         scenario_helper = mock.MagicMock()
1174
1175         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1176         helper.generate_prox_lua_file = mock.MagicMock(return_value=234)
1177         helper.put_string_to_file = identity
1178
1179         expected = ''
1180         result = helper.upload_prox_lua('my_dir', {})
1181         self.assertEqual(result, expected)
1182
1183         input_data = {
1184             'lua': {
1185                 'key1': 'value1 ("inside") tail',
1186                 'key2': 'value2',
1187                 'key3 ("key_side") head': 'value3',
1188             },
1189         }
1190
1191         expected = 234, 'my_dir/key_side'
1192         result = helper.upload_prox_lua('my_dir', input_data)
1193         self.assertEqual(result, expected)
1194
1195     def test_put_string_to_file(self):
1196         vnfd_helper = mock.MagicMock()
1197         vnfd_helper.interfaces = []
1198         ssh_helper = mock.MagicMock()
1199         scenario_helper = mock.MagicMock()
1200
1201         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1202
1203         expected = 'a/b'
1204         result = helper.put_string_to_file('my long string', 'a/b')
1205         self.assertEqual(result, expected)
1206
1207     def test__build_pipeline_kwarags(self):
1208         vnfd_helper = mock.MagicMock()
1209         ssh_helper = mock.MagicMock()
1210         ssh_helper.provision_tool.return_value = "/tmp/nosuch"
1211         scenario_helper = mock.MagicMock()
1212
1213         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1214         helper._build_pipeline_kwargs()
1215         self.assertEqual(helper.pipeline_kwargs, {'tool_path': '/tmp/nosuch', 'tool_dir': '/tmp'})
1216
1217     def test_copy_to_target(self):
1218         vnfd_helper = mock.MagicMock()
1219         vnfd_helper.interfaces = []
1220         ssh_helper = mock.MagicMock()
1221         scenario_helper = mock.MagicMock()
1222
1223         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1224         expected = '/tmp/c'
1225         result = helper.copy_to_target('a/b', 'c')
1226         self.assertEqual(result, expected)
1227
1228     def test_upload_prox_config(self):
1229         vnfd_helper = mock.MagicMock()
1230         vnfd_helper.interfaces = []
1231         ssh_helper = mock.MagicMock()
1232         scenario_helper = mock.MagicMock()
1233
1234         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1235         helper.write_prox_config = mock.MagicMock(return_value='a long string')
1236         expected = '/tmp/a'
1237         result = helper.upload_prox_config('a', {})
1238         self.assertEqual(result, expected)
1239
1240
1241 class TestProxResourceHelper(unittest.TestCase):
1242
1243     VNFD0 = {
1244         'short-name': 'ProxVnf',
1245         'vdu': [
1246             {
1247                 'routing_table': [
1248                     {
1249                         'network': '152.16.100.20',
1250                         'netmask': '255.255.255.0',
1251                         'gateway': '152.16.100.20',
1252                         'if': 'xe0',
1253                     },
1254                     {
1255                         'network': '152.16.40.20',
1256                         'netmask': '255.255.255.0',
1257                         'gateway': '152.16.40.20',
1258                         'if': 'xe1',
1259                     },
1260                 ],
1261                 'description': 'PROX approximation using DPDK',
1262                 'name': 'proxvnf-baremetal',
1263                 'nd_route_tbl': [
1264                     {
1265                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1266                         'netmask': '112',
1267                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1268                         'if': 'xe0',
1269                     },
1270                     {
1271                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1272                         'netmask': '112',
1273                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1274                         'if': 'xe1',
1275                     },
1276                 ],
1277                 'id': 'proxvnf-baremetal',
1278                 'external-interface': [
1279                     {
1280                         'virtual-interface': {
1281                             'dst_mac': '00:00:00:00:00:04',
1282                             'vpci': '0000:05:00.0',
1283                             'local_ip': '152.16.100.19',
1284                             'type': 'PCI-PASSTHROUGH',
1285                             'vld_id': 'uplink_0',
1286                             'netmask': '255.255.255.0',
1287                             'dpdk_port_num': 0,
1288                             'bandwidth': '10 Gbps',
1289                             'driver': "i40e",
1290                             'dst_ip': '152.16.100.19',
1291                             'local_iface_name': 'xe0',
1292                             'local_mac': '00:00:00:00:00:02',
1293                             'ifname': 'xe0',
1294                         },
1295                         'vnfd-connection-point-ref': 'xe0',
1296                         'name': 'xe0',
1297                     },
1298                     {
1299                         'virtual-interface': {
1300                             'dst_mac': '00:00:00:00:00:03',
1301                             'vpci': '0000:05:00.1',
1302                             'local_ip': '152.16.40.19',
1303                             'type': 'PCI-PASSTHROUGH',
1304                             'vld_id': 'downlink_0',
1305                             'driver': "i40e",
1306                             'netmask': '255.255.255.0',
1307                             'dpdk_port_num': 1,
1308                             'bandwidth': '10 Gbps',
1309                             'dst_ip': '152.16.40.20',
1310                             'local_iface_name': 'xe1',
1311                             'local_mac': '00:00:00:00:00:01',
1312                             'ifname': 'xe1',
1313                         },
1314                         'vnfd-connection-point-ref': 'xe1',
1315                         'name': 'xe1',
1316                     },
1317                 ],
1318             },
1319         ],
1320         'description': 'PROX approximation using DPDK',
1321         'mgmt-interface': {
1322             'vdu-id': 'proxvnf-baremetal',
1323             'host': '1.2.1.1',
1324             'password': 'r00t',
1325             'user': 'root',
1326             'ip': '1.2.1.1',
1327         },
1328         'benchmark': {
1329             'kpi': [
1330                 'packets_in',
1331                 'packets_fwd',
1332                 'packets_dropped',
1333             ],
1334         },
1335         'id': 'ProxApproxVnf',
1336         'name': 'ProxVnf',
1337     }
1338
1339     VNFD = {
1340         'vnfd:vnfd-catalog': {
1341             'vnfd': [
1342                 VNFD0,
1343             ],
1344         },
1345     }
1346
1347     def test_line_rate_to_pps(self):
1348         expected = 0.25 * 1e8
1349         result = ProxResourceHelper.line_rate_to_pps(180, 4)
1350         self.assertEqual(result, expected)
1351
1352     def test_find_pci(self):
1353         input_str_list = [
1354             'no target here',
1355             'nor here',
1356             'and still not',
1357         ]
1358         result = ProxResourceHelper.find_pci('target', input_str_list)
1359         self.assertFalse(result)
1360
1361         input_str_list = [
1362             'no target here',
1363             'nor here',
1364             'this is a target',
1365             'did we miss it',
1366         ]
1367         result = ProxResourceHelper.find_pci('target', input_str_list)
1368         self.assertTrue(result)
1369
1370     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.RETRY_INTERVAL', 0)
1371     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1372     def test_sut(self, mock_socket_helper):
1373         helper = ProxResourceHelper(mock.MagicMock())
1374         self.assertIsNone(helper.client)
1375         result = helper.sut
1376         self.assertIsNotNone(result)
1377         self.assertIs(result, helper.client)
1378         self.assertIs(result, helper.sut)
1379
1380     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.SocketTopology')
1381     def test_cpu_topology(self, mock_socket_topology):
1382         mock_socket_topology.parse_cpuinfo.return_value = 432
1383
1384         setup_helper = mock.MagicMock()
1385         setup_helper.ssh_helper.execute.return_value = 0, 'output', ''
1386
1387         helper = ProxResourceHelper(setup_helper)
1388         self.assertIsNone(helper._cpu_topology)
1389         result = helper.cpu_topology
1390         self.assertEqual(result, 432)
1391         self.assertIs(result, helper._cpu_topology)
1392         self.assertIs(result, helper.cpu_topology)
1393
1394     def test_test_cores(self):
1395         setup_helper = mock.MagicMock()
1396         setup_helper.prox_config_data = []
1397
1398         helper = ProxResourceHelper(setup_helper)
1399         helper._cpu_topology = []
1400
1401         expected = []
1402         result = helper.test_cores
1403         self.assertEqual(result, expected)
1404
1405         setup_helper.prox_config_data = [
1406             ('section1', []),
1407             ('section2', [
1408                 ('a', 'b'),
1409                 ('c', 'd'),
1410             ]),
1411             ('core 1s3', []),
1412             ('core 2s5', [
1413                 ('index', 8),
1414                 ('mode', ''),
1415             ]),
1416             ('core 3s1', [
1417                 ('index', 5),
1418                 ('mode', 'gen'),
1419             ]),
1420             ('core 4s9h', [
1421                 ('index', 7),
1422                 ('mode', 'gen'),
1423             ]),
1424         ]
1425
1426         helper = ProxResourceHelper(setup_helper)
1427         helper._cpu_topology = {
1428             1: {
1429                 3: {
1430                     'key1': (23, 32),
1431                     'key2': (12, 21),
1432                     'key3': (44, 33),
1433                 },
1434             },
1435             9: {
1436                 4: {
1437                     'key1': (44, 32),
1438                     'key2': (23, 21),
1439                     'key3': (12, 33),
1440                 },
1441             },
1442         }
1443
1444         self.assertIsNone(helper._test_cores)
1445         expected = [12, 23]
1446         result = helper.test_cores
1447         self.assertEqual(result, expected)
1448         self.assertIs(result, helper._test_cores)
1449         self.assertIs(result, helper.test_cores)
1450
1451     def test_get_test_type(self):
1452         setup_helper = mock.MagicMock()
1453         helper = ProxResourceHelper(setup_helper)
1454
1455         setup_helper.prox_config_data = [
1456             ('global', [
1457                 ('name', helper.PROX_CORE_MPLS_TEST)
1458             ]),
1459             ('section2', [
1460                 ('a', 'b'),
1461                 ('c', 'd'),
1462             ]),
1463             ('core 1', []),
1464             ('core 2', [
1465                 ('index', 8),
1466                 ('mode', ''),
1467             ]),
1468             ('core 3', [
1469                 ('index', 5),
1470                 ('mode', 'gen'),
1471             ]),
1472             ('core 4', [
1473                 ('index', 7),
1474                 ('mode', 'gen'),
1475             ]),
1476         ]
1477         test_type = helper.get_test_type()
1478         self.assertEqual(test_type, helper.PROX_CORE_MPLS_TEST)
1479
1480     def test_get_cores(self):
1481         setup_helper = mock.MagicMock()
1482         setup_helper.prox_config_data = [
1483             ('section1', []),
1484             ('section2', [
1485                 ('a', 'b'),
1486                 ('c', 'd'),
1487             ]),
1488             ('core 1', []),
1489             ('core 2', [
1490                 ('index', 8),
1491                 ('mode', ''),
1492             ]),
1493             ('core 3', [
1494                 ('index', 5),
1495                 ('mode', 'gen'),
1496             ]),
1497             ('core 4', [
1498                 ('index', 7),
1499                 ('mode', 'gen'),
1500             ]),
1501         ]
1502
1503         helper = ProxResourceHelper(setup_helper)
1504         helper._cpu_topology = {
1505             0: {
1506                 1: {
1507                     5: (5, 1, 0)
1508                 },
1509                 2: {
1510                     6: (6, 2, 0)
1511                 },
1512                 3: {
1513                     7: (7, 3, 0)
1514                 },
1515                 4: {
1516                     8: (8, 3, 0)
1517                 },
1518             }
1519         }
1520
1521         expected = [7, 8]
1522         result = helper.get_cores(helper.PROX_CORE_GEN_MODE)
1523         self.assertEqual(result, expected)
1524
1525     def test_get_cores_mpls(self):
1526         setup_helper = mock.MagicMock()
1527         setup_helper.prox_config_data = [
1528             ('section1', []),
1529             ('section2', [
1530                 ('a', 'b'),
1531                 ('c', 'd'),
1532             ]),
1533             ('core 1', []),
1534             ('core 2', [
1535                 ('index', 8),
1536                 ('mode', ''),
1537             ]),
1538             ('core 3', [
1539                 ('index', 5),
1540                 ('mode', 'gen'),
1541                 ('name', 'tagged'),
1542             ]),
1543             ('core 4', [
1544                 ('index', 7),
1545                 ('mode', 'gen'),
1546                 ('name', 'udp'),
1547             ]),
1548         ]
1549
1550         helper = ProxResourceHelper(setup_helper)
1551         helper._cpu_topology = {
1552             0: {
1553                 1: {
1554                     5: (5, 1, 0)
1555                 },
1556                 2: {
1557                     6: (6, 2, 0)
1558                 },
1559                 3: {
1560                     7: (7, 3, 0)
1561                 },
1562                 4: {
1563                     8: (8, 3, 0)
1564                 },
1565             }
1566         }
1567
1568         expected_tagged = [7]
1569         expected_plain = [8]
1570         result_tagged, result_plain = helper.get_cores_mpls(helper.PROX_CORE_GEN_MODE)
1571         self.assertEqual(result_tagged, expected_tagged)
1572         self.assertEqual(result_plain, expected_plain)
1573
1574     def test_latency_cores(self):
1575         setup_helper = mock.MagicMock()
1576         setup_helper.prox_config_data= []
1577
1578         helper = ProxResourceHelper(setup_helper)
1579         helper._cpu_topology = []
1580
1581         expected = []
1582         result = helper.latency_cores
1583         self.assertEqual(result, expected)
1584
1585         setup_helper.prox_config_data = [
1586             ('section1', []),
1587             ('section2', [
1588                 ('a', 'b'),
1589                 ('c', 'd'),
1590             ]),
1591             ('core 1s3', []),
1592             ('core 2s5', [
1593                 ('index', 8),
1594                 ('mode', ''),
1595             ]),
1596             ('core 3s1', [
1597                 ('index', 5),
1598                 ('mode', 'lat'),
1599             ]),
1600             ('core 4s9h', [
1601                 ('index', 7),
1602                 ('mode', 'lat'),
1603             ]),
1604         ]
1605
1606         helper = ProxResourceHelper(setup_helper)
1607         helper._cpu_topology = {
1608             1: {
1609                 3: {
1610                     'key1': (23, 32),
1611                     'key2': (12, 21),
1612                     'key3': (44, 33),
1613                 },
1614             },
1615             9: {
1616                 4: {
1617                     'key1': (44, 32),
1618                     'key2': (23, 21),
1619                     'key3': (12, 33),
1620                 },
1621             },
1622         }
1623
1624         self.assertIsNone(helper._latency_cores)
1625         expected = [12, 23]
1626         result = helper.latency_cores
1627         self.assertEqual(result, expected)
1628         self.assertIs(result, helper._latency_cores)
1629         self.assertIs(result, helper.latency_cores)
1630
1631     def test_run_traffic(self):
1632         setup_helper = mock.MagicMock()
1633         helper = ProxResourceHelper(setup_helper)
1634         traffic_proifle = mock.MagicMock(**{"done": True})
1635         helper.run_traffic(traffic_proifle)
1636         self.assertEqual(helper._terminated.value, 1)
1637
1638     def test__run_traffic_once(self):
1639         setup_helper = mock.MagicMock()
1640         helper = ProxResourceHelper(setup_helper)
1641         traffic_proifle = mock.MagicMock(**{"done": True})
1642         helper._run_traffic_once(traffic_proifle)
1643         self.assertEqual(helper._terminated.value, 1)
1644
1645     def test_start_collect(self):
1646         setup_helper = mock.MagicMock()
1647         helper = ProxResourceHelper(setup_helper)
1648         helper.resource = resource = mock.MagicMock()
1649         self.assertIsNone(helper.start_collect())
1650         resource.start.assert_called_once()
1651
1652     def test_terminate(self):
1653         setup_helper = mock.MagicMock()
1654         helper = ProxResourceHelper(setup_helper)
1655         with self.assertRaises(NotImplementedError):
1656             helper.terminate()
1657
1658     def test_up_post(self):
1659         setup_helper = mock.MagicMock()
1660         helper = ProxResourceHelper(setup_helper)
1661         helper.client = expected = mock.MagicMock()
1662         result = helper.up_post()
1663         self.assertEqual(result, expected)
1664
1665     def test_execute(self):
1666         setup_helper = mock.MagicMock()
1667         helper = ProxResourceHelper(setup_helper)
1668         helper.client = mock.MagicMock()
1669
1670         expected = helper.client.my_command()
1671         result = helper.execute('my_command')
1672         self.assertEqual(result, expected)
1673
1674         helper.client = object()
1675
1676         result = helper.execute('my_command')
1677         self.assertIsNone(result)
1678
1679     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1680     def test_traffic_context(self, mock_time):
1681         setup_helper = mock.MagicMock()
1682         setup_helper.vnfd_helper.interfaces = []
1683
1684         helper = ProxResourceHelper(setup_helper)
1685         helper._cpu_topology = {
1686             0: {
1687                 1: {
1688                     5: (5, 1, 0)
1689                 },
1690                 2: {
1691                     6: (6, 2, 0)
1692                 },
1693                 3: {
1694                     7: (7, 3, 0)
1695                 },
1696                 4: {
1697                     8: (8, 3, 0)
1698                 },
1699             }
1700         }
1701
1702         setup_helper.prox_config_data = [
1703             ('global', [
1704                 ('name', helper.PROX_CORE_MPLS_TEST)
1705             ]),
1706             ('section1', []),
1707             ('section2', [
1708                 ('a', 'b'),
1709                 ('c', 'd'),
1710             ]),
1711             ('core 1', []),
1712             ('core 2', [
1713                 ('index', 8),
1714                 ('mode', ''),
1715             ]),
1716             ('core 3', [
1717                 ('index', 5),
1718                 ('mode', 'gen'),
1719                 ('name', 'tagged'),
1720             ]),
1721             ('core 4', [
1722                 ('index', 7),
1723                 ('mode', 'gen'),
1724                 ('name', 'udp'),
1725             ]),
1726         ]
1727
1728
1729         client = mock.MagicMock()
1730         client.hz.return_value = 2
1731         client.port_stats.return_value = tuple(range(12))
1732
1733         helper.client = client
1734         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1735
1736         helper._test_cores = [3, 4]
1737
1738         with helper.traffic_context(64, 1):
1739             pass
1740
1741     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1742     def test_run_test(self, mock_time):
1743         @contextmanager
1744         def measure(*args, **kwargs):
1745             yield stats
1746
1747         bad_vnfd = copy.deepcopy(self.VNFD0)
1748         bad_vnfd['vdu'][0]['external-interface'].append({
1749             'virtual-interface': {
1750                 'dst_mac': '00:00:00:00:00:05',
1751                 'vpci': '0000:06:00.0',
1752                 'local_ip': '152.16.100.20',
1753                 'type': 'PCI-PASSTHROUGH',
1754                 'vld_id': 'uplink_1',
1755                 'netmask': '255.255.255.0',
1756                 'dpdk_port_num': 0,
1757                 'bandwidth': '10 Gbps',
1758                 'driver': "i40e",
1759                 'dst_ip': '152.16.100.20',
1760                 'local_iface_name': 'xe2',
1761                 'local_mac': '00:00:00:00:00:07',
1762                 'ifname': 'xe2',
1763             },
1764             'vnfd-connection-point-ref': 'xe2',
1765             'name': 'xe2',
1766         })
1767
1768         bad_vnfd_helper = VnfdHelper(bad_vnfd)
1769         setup_helper = mock.MagicMock()
1770         setup_helper.vnfd_helper = bad_vnfd_helper
1771
1772         stats = {
1773             'delta': TotStatsTuple(6, 7, 8, 9),
1774         }
1775
1776         client = mock.MagicMock()
1777         client.hz.return_value = 2
1778         client.measure_tot_stats = measure
1779         client.port_stats.return_value = tuple(range(12))
1780
1781         helper = ProxResourceHelper(setup_helper)
1782         helper.client = client
1783         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1784
1785         with self.assertRaises(AssertionError):
1786             helper.run_test(980, 15, 45)
1787
1788         vnfd_helper = VnfdHelper(self.VNFD0)
1789         setup_helper.vnfd_helper = vnfd_helper
1790         helper = ProxResourceHelper(setup_helper)
1791         helper.client = client
1792         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1793         helper._test_cores = [3, 4]
1794
1795         expected_test_data = ProxTestDataTuple(0.0, 2.0, 6, 7, 8, [3.3, 3.6, 3.8], 6, 7, 6.5e6)
1796         expected_port_samples = {
1797             'xe0': {'in_packets': 6, 'out_packets': 7},
1798             'xe1': {'in_packets': 6, 'out_packets': 7},
1799         }
1800         test_data, port_samples = helper.run_test(230, 60, 65)
1801         self.assertTupleEqual(test_data, expected_test_data)
1802         self.assertDictEqual(port_samples, expected_port_samples)
1803
1804     def test_get_latency(self):
1805         setup_helper = mock.MagicMock()
1806         setup_helper.vnfd_helper.interfaces = []
1807
1808         helper = ProxResourceHelper(setup_helper)
1809         helper._latency_cores = []
1810
1811         expected = []
1812         result = helper.get_latency()
1813         self.assertEqual(result, expected)
1814
1815         helper._latency_cores = [1, 2]
1816         helper.client = mock.MagicMock()
1817
1818         expected = helper.sut.lat_stats()
1819         result = helper.get_latency()
1820         self.assertIs(result, expected)
1821
1822     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1823     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1824     def test__connect(self, mock_socket_helper_type, mock_time):
1825         client = mock_socket_helper_type()
1826         client.connect.side_effect = chain(repeat(socket.error, 5), [None])
1827
1828         setup_helper = mock.MagicMock()
1829         setup_helper.vnfd_helper.interfaces = []
1830
1831         helper = ProxResourceHelper(setup_helper)
1832
1833         result = helper._connect()
1834         self.assertIs(result, client)
1835
1836         client.connect.side_effect = chain(repeat(socket.error, 65), [None])
1837
1838         with self.assertRaises(Exception):
1839             helper._connect()