Merge "add scenario opnfv_os-nosdn-bar-ha_daily.yaml for Barometer"
[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_dict, '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_dict, '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_dict, '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_dict, '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         prox_cmd = helper.build_config()
990         expected = "sudo bash -c 'cd /opt/nsb_bin; /opt/nsb_bin/prox -o cli -f  -f /tmp/prox.cfg '"
991         self.assertEqual(prox_cmd, expected)
992
993     def test__insert_additional_file(self):
994         vnfd_helper = mock.MagicMock()
995         ssh_helper = mock.MagicMock()
996         scenario_helper = mock.MagicMock()
997
998         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
999         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1000         res = helper._insert_additional_file('dofile("ipv4.lua")')
1001         self.assertEqual(res, 'dofile("/tmp/ipv4.lua")')
1002
1003     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1004     def test_generate_prox_config_file(self, mock_parser_type):
1005         def init(*args):
1006             if sections_data:
1007                 args[-1].extend(sections_data)
1008             return mock.MagicMock()
1009
1010         sections_data = []
1011
1012         mock_parser_type.side_effect = init
1013
1014         vnfd_helper = VnfdHelper(self.VNFD0)
1015         ssh_helper = mock.MagicMock()
1016         scenario_helper = mock.MagicMock()
1017
1018         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1019         helper.additional_files = {}
1020
1021         expected = []
1022         result = helper.generate_prox_config_file('a/b')
1023         self.assertEqual(result, expected)
1024
1025         helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"}
1026
1027         helper.remote_prox_file_name = 'remote'
1028         sections_data = [
1029             [
1030                 'lua',
1031                 [
1032                     ['dofile("ipv4.lua")', ''],
1033                 ],
1034             ],
1035             [
1036                 'port 0',
1037                 [
1038                     ['ip', ''],
1039                     ['mac', 'foo'],
1040                     ['dst mac', '@@1'],
1041                     ['tx port', '1'],
1042                 ],
1043             ],
1044             [
1045                 'port 2',
1046                 [
1047                     ['ip', ''],
1048                     ['$sut_mac0', '@@dst_mac0'],
1049                     ['tx port', '0'],
1050                     ['single', '@'],
1051                     ['user_table', 'dofile("ipv4.lua")'],
1052                     ['missing_addtional_file', 'dofile("nosuch")'],
1053                 ],
1054             ],
1055         ]
1056
1057         expected = [
1058             [
1059                 'lua',
1060                 [
1061                     ['dofile("/tmp/ipv4.lua")', ''],
1062                 ],
1063             ],
1064             [
1065                 'port 0',
1066                 [
1067                     ['ip', ''],
1068                     ['mac', 'hardware'],
1069                     ['dst mac', '00:00:00:00:00:03'],
1070                     ['tx port', '1'],
1071                 ],
1072             ],
1073             [
1074                 'port 2',
1075                 [
1076                     ['ip', ''],
1077                     ['$sut_mac0', '00 00 00 00 00 04'],
1078                     ['tx port', '0'],
1079                     ['single', '@'],
1080                     ['user_table', 'dofile("/tmp/ipv4.lua")'],
1081                     ['missing_addtional_file', 'dofile("nosuch")'],
1082                 ],
1083             ],
1084         ]
1085         result = helper.generate_prox_config_file('/c/d/e')
1086         self.assertEqual(result, expected, str(result))
1087
1088     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ConfigParser')
1089     def test_generate_prox_config_file_negative(self, mock_parser_type):
1090         def init(*args):
1091             args[-1].update(sections_data)
1092             return mock.MagicMock()
1093
1094         sections_data = {}
1095
1096         mock_parser_type.side_effect = init
1097
1098         vnfd_helper = mock.MagicMock()
1099         vnfd_helper.interfaces = []
1100         ssh_helper = mock.MagicMock()
1101         scenario_helper = mock.MagicMock()
1102
1103         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1104         helper.additional_files = {}
1105         helper.remote_prox_file_name = 'remote'
1106         vnfd_helper.interfaces = [
1107             {
1108                 'virtual-interface': {
1109                     'dpdk_port_num': 3,
1110                     'dst_mac': '00:00:00:de:ad:88',
1111                 },
1112             },
1113             {
1114                 'virtual-interface': {
1115                     'dpdk_port_num': 5,
1116                     'dst_mac': '00:00:00:de:ad:ff',
1117                 },
1118             },
1119             {
1120                 'virtual-interface': {
1121                     'dpdk_port_num': 7,
1122                     'dst_mac': '00:00:00:de:ad:ff',
1123                 },
1124             },
1125         ]
1126         sections_data = {
1127             'port 3': [
1128                 ['ip', ''],
1129                 ['mac', 'foo'],
1130                 ['dst mac', ''],
1131             ],
1132             'port 5': [
1133                 ['ip', ''],
1134                 ['dst mac', ''],
1135                 ['tx port', '0'],
1136                 ['???', 'dofile "here" 23'],
1137             ],
1138         }
1139
1140         with self.assertRaises(Exception):
1141             helper.generate_prox_config_file('a/b')
1142
1143     def test_generate_prox_lua_file(self):
1144         vnfd_helper = VnfdHelper(self.VNFD0)
1145         ssh_helper = mock.MagicMock()
1146         scenario_helper = mock.MagicMock()
1147
1148         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1149         helper.LUA_PARAMETER_NAME = 'sut'
1150
1151         expected = [
1152             'sut_hex_ip_port_0:"98 10 64 13"',
1153             'sut_ip_port_0:"152.16.100.19"',
1154             'gen_hex_ip_port_0:"98 10 64 13"',
1155             'gen_ip_port_0:"152.16.100.19"',
1156
1157             'sut_hex_ip_port_1:"98 10 28 13"',
1158             'sut_ip_port_1:"152.16.40.19"',
1159             'gen_hex_ip_port_1:"98 10 28 14"',
1160             'gen_ip_port_1:"152.16.40.20"',
1161         ]
1162         result = helper.generate_prox_lua_file()
1163         self.assertListEqual(result.splitlines(), expected)
1164
1165     def test_upload_prox_lua(self):
1166         def identity(*args):
1167             return args
1168
1169         vnfd_helper = mock.MagicMock()
1170         vnfd_helper.interfaces = []
1171         ssh_helper = mock.MagicMock()
1172         scenario_helper = mock.MagicMock()
1173
1174         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1175         helper.generate_prox_lua_file = mock.MagicMock(return_value=234)
1176         helper.put_string_to_file = identity
1177
1178         expected = ''
1179         result = helper.upload_prox_lua('my_dir', {})
1180         self.assertEqual(result, expected)
1181
1182         input_data = {
1183             'lua': {
1184                 'key1': 'value1 ("inside") tail',
1185                 'key2': 'value2',
1186                 'key3 ("key_side") head': 'value3',
1187             },
1188         }
1189
1190         expected = 234, 'my_dir/key_side'
1191         result = helper.upload_prox_lua('my_dir', input_data)
1192         self.assertEqual(result, expected)
1193
1194     def test_put_string_to_file(self):
1195         vnfd_helper = mock.MagicMock()
1196         vnfd_helper.interfaces = []
1197         ssh_helper = mock.MagicMock()
1198         scenario_helper = mock.MagicMock()
1199
1200         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1201
1202         expected = 'a/b'
1203         result = helper.put_string_to_file('my long string', 'a/b')
1204         self.assertEqual(result, expected)
1205
1206     def test__build_pipeline_kwarags(self):
1207         vnfd_helper = mock.MagicMock()
1208         ssh_helper = mock.MagicMock()
1209         ssh_helper.provision_tool.return_value = "/tmp/nosuch"
1210         scenario_helper = mock.MagicMock()
1211
1212         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1213         helper._build_pipeline_kwargs()
1214         self.assertEqual(helper.pipeline_kwargs, {'tool_path': '/tmp/nosuch', 'tool_dir': '/tmp'})
1215
1216     def test_copy_to_target(self):
1217         vnfd_helper = mock.MagicMock()
1218         vnfd_helper.interfaces = []
1219         ssh_helper = mock.MagicMock()
1220         scenario_helper = mock.MagicMock()
1221
1222         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1223         expected = '/tmp/c'
1224         result = helper.copy_to_target('a/b', 'c')
1225         self.assertEqual(result, expected)
1226
1227     def test_upload_prox_config(self):
1228         vnfd_helper = mock.MagicMock()
1229         vnfd_helper.interfaces = []
1230         ssh_helper = mock.MagicMock()
1231         scenario_helper = mock.MagicMock()
1232
1233         helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1234         helper.write_prox_config = mock.MagicMock(return_value='a long string')
1235         expected = '/tmp/a'
1236         result = helper.upload_prox_config('a', {})
1237         self.assertEqual(result, expected)
1238
1239
1240 class TestProxResourceHelper(unittest.TestCase):
1241
1242     VNFD0 = {
1243         'short-name': 'ProxVnf',
1244         'vdu': [
1245             {
1246                 'routing_table': [
1247                     {
1248                         'network': '152.16.100.20',
1249                         'netmask': '255.255.255.0',
1250                         'gateway': '152.16.100.20',
1251                         'if': 'xe0',
1252                     },
1253                     {
1254                         'network': '152.16.40.20',
1255                         'netmask': '255.255.255.0',
1256                         'gateway': '152.16.40.20',
1257                         'if': 'xe1',
1258                     },
1259                 ],
1260                 'description': 'PROX approximation using DPDK',
1261                 'name': 'proxvnf-baremetal',
1262                 'nd_route_tbl': [
1263                     {
1264                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1265                         'netmask': '112',
1266                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1267                         'if': 'xe0',
1268                     },
1269                     {
1270                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1271                         'netmask': '112',
1272                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1273                         'if': 'xe1',
1274                     },
1275                 ],
1276                 'id': 'proxvnf-baremetal',
1277                 'external-interface': [
1278                     {
1279                         'virtual-interface': {
1280                             'dst_mac': '00:00:00:00:00:04',
1281                             'vpci': '0000:05:00.0',
1282                             'local_ip': '152.16.100.19',
1283                             'type': 'PCI-PASSTHROUGH',
1284                             'vld_id': 'uplink_0',
1285                             'netmask': '255.255.255.0',
1286                             'dpdk_port_num': 0,
1287                             'bandwidth': '10 Gbps',
1288                             'driver': "i40e",
1289                             'dst_ip': '152.16.100.19',
1290                             'local_iface_name': 'xe0',
1291                             'local_mac': '00:00:00:00:00:02',
1292                             'ifname': 'xe0',
1293                         },
1294                         'vnfd-connection-point-ref': 'xe0',
1295                         'name': 'xe0',
1296                     },
1297                     {
1298                         'virtual-interface': {
1299                             'dst_mac': '00:00:00:00:00:03',
1300                             'vpci': '0000:05:00.1',
1301                             'local_ip': '152.16.40.19',
1302                             'type': 'PCI-PASSTHROUGH',
1303                             'vld_id': 'downlink_0',
1304                             'driver': "i40e",
1305                             'netmask': '255.255.255.0',
1306                             'dpdk_port_num': 1,
1307                             'bandwidth': '10 Gbps',
1308                             'dst_ip': '152.16.40.20',
1309                             'local_iface_name': 'xe1',
1310                             'local_mac': '00:00:00:00:00:01',
1311                             'ifname': 'xe1',
1312                         },
1313                         'vnfd-connection-point-ref': 'xe1',
1314                         'name': 'xe1',
1315                     },
1316                 ],
1317             },
1318         ],
1319         'description': 'PROX approximation using DPDK',
1320         'mgmt-interface': {
1321             'vdu-id': 'proxvnf-baremetal',
1322             'host': '1.2.1.1',
1323             'password': 'r00t',
1324             'user': 'root',
1325             'ip': '1.2.1.1',
1326         },
1327         'benchmark': {
1328             'kpi': [
1329                 'packets_in',
1330                 'packets_fwd',
1331                 'packets_dropped',
1332             ],
1333         },
1334         'id': 'ProxApproxVnf',
1335         'name': 'ProxVnf',
1336     }
1337
1338     VNFD = {
1339         'vnfd:vnfd-catalog': {
1340             'vnfd': [
1341                 VNFD0,
1342             ],
1343         },
1344     }
1345
1346     def test_line_rate_to_pps(self):
1347         expected = 0.25 * 1e8
1348         result = ProxResourceHelper.line_rate_to_pps(180, 4)
1349         self.assertEqual(result, expected)
1350
1351     def test_find_pci(self):
1352         input_str_list = [
1353             'no target here',
1354             'nor here',
1355             'and still not',
1356         ]
1357         result = ProxResourceHelper.find_pci('target', input_str_list)
1358         self.assertFalse(result)
1359
1360         input_str_list = [
1361             'no target here',
1362             'nor here',
1363             'this is a target',
1364             'did we miss it',
1365         ]
1366         result = ProxResourceHelper.find_pci('target', input_str_list)
1367         self.assertTrue(result)
1368
1369     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.RETRY_INTERVAL', 0)
1370     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1371     def test_sut(self, mock_socket_helper):
1372         helper = ProxResourceHelper(mock.MagicMock())
1373         self.assertIsNone(helper.client)
1374         result = helper.sut
1375         self.assertIsNotNone(result)
1376         self.assertIs(result, helper.client)
1377         self.assertIs(result, helper.sut)
1378
1379     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.SocketTopology')
1380     def test_cpu_topology(self, mock_socket_topology):
1381         mock_socket_topology.parse_cpuinfo.return_value = 432
1382
1383         setup_helper = mock.MagicMock()
1384         setup_helper.ssh_helper.execute.return_value = 0, 'output', ''
1385
1386         helper = ProxResourceHelper(setup_helper)
1387         self.assertIsNone(helper._cpu_topology)
1388         result = helper.cpu_topology
1389         self.assertEqual(result, 432)
1390         self.assertIs(result, helper._cpu_topology)
1391         self.assertIs(result, helper.cpu_topology)
1392
1393     def test_test_cores(self):
1394         setup_helper = mock.MagicMock()
1395         setup_helper.prox_config_dict = {}
1396
1397         helper = ProxResourceHelper(setup_helper)
1398         helper._cpu_topology = []
1399
1400         expected = []
1401         result = helper.test_cores
1402         self.assertEqual(result, expected)
1403
1404         setup_helper.prox_config_dict = [
1405             ('section1', []),
1406             ('section2', [
1407                 ('a', 'b'),
1408                 ('c', 'd'),
1409             ]),
1410             ('core 1s3', []),
1411             ('core 2s5', [
1412                 ('index', 8),
1413                 ('mode', ''),
1414             ]),
1415             ('core 3s1', [
1416                 ('index', 5),
1417                 ('mode', 'gen'),
1418             ]),
1419             ('core 4s9h', [
1420                 ('index', 7),
1421                 ('mode', 'gen'),
1422             ]),
1423         ]
1424
1425         helper = ProxResourceHelper(setup_helper)
1426         helper._cpu_topology = {
1427             1: {
1428                 3: {
1429                     'key1': (23, 32),
1430                     'key2': (12, 21),
1431                     'key3': (44, 33),
1432                 },
1433             },
1434             9: {
1435                 4: {
1436                     'key1': (44, 32),
1437                     'key2': (23, 21),
1438                     'key3': (12, 33),
1439                 },
1440             },
1441         }
1442
1443         self.assertIsNone(helper._test_cores)
1444         expected = [12, 23]
1445         result = helper.test_cores
1446         self.assertEqual(result, expected)
1447         self.assertIs(result, helper._test_cores)
1448         self.assertIs(result, helper.test_cores)
1449
1450     def test_get_test_type(self):
1451         setup_helper = mock.MagicMock()
1452         setup_helper.prox_config_dict = {}
1453
1454         helper = ProxResourceHelper(setup_helper)
1455         setup_helper.prox_config_dict = [
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_dict = {}
1483
1484         helper = ProxResourceHelper(setup_helper)
1485         helper._cpu_topology = {
1486             0: {
1487                 1: {
1488                     5: (5, 1, 0)
1489                 },
1490                 2: {
1491                     6: (6, 2, 0)
1492                 },
1493                 3: {
1494                     7: (7, 3, 0)
1495                 },
1496                 4: {
1497                     8: (8, 3, 0)
1498                 },
1499             }
1500         }
1501
1502         setup_helper.prox_config_dict = [
1503             ('section1', []),
1504             ('section2', [
1505                 ('a', 'b'),
1506                 ('c', 'd'),
1507             ]),
1508             ('core 1', []),
1509             ('core 2', [
1510                 ('index', 8),
1511                 ('mode', ''),
1512             ]),
1513             ('core 3', [
1514                 ('index', 5),
1515                 ('mode', 'gen'),
1516             ]),
1517             ('core 4', [
1518                 ('index', 7),
1519                 ('mode', 'gen'),
1520             ]),
1521         ]
1522
1523         expected = [7, 8]
1524         result = helper.get_cores(helper.PROX_CORE_GEN_MODE)
1525         self.assertEqual(result, expected)
1526
1527     def test_get_cores_mpls(self):
1528         setup_helper = mock.MagicMock()
1529         setup_helper.prox_config_dict = {}
1530
1531         helper = ProxResourceHelper(setup_helper)
1532         helper._cpu_topology = {
1533             0: {
1534                 1: {
1535                     5: (5, 1, 0)
1536                 },
1537                 2: {
1538                     6: (6, 2, 0)
1539                 },
1540                 3: {
1541                     7: (7, 3, 0)
1542                 },
1543                 4: {
1544                     8: (8, 3, 0)
1545                 },
1546             }
1547         }
1548
1549         setup_helper.prox_config_dict = [
1550             ('section1', []),
1551             ('section2', [
1552                 ('a', 'b'),
1553                 ('c', 'd'),
1554             ]),
1555             ('core 1', []),
1556             ('core 2', [
1557                 ('index', 8),
1558                 ('mode', ''),
1559             ]),
1560             ('core 3', [
1561                 ('index', 5),
1562                 ('mode', 'gen'),
1563                 ('name', 'tagged'),
1564             ]),
1565             ('core 4', [
1566                 ('index', 7),
1567                 ('mode', 'gen'),
1568                 ('name', 'udp'),
1569             ]),
1570         ]
1571
1572         expected_tagged = [7]
1573         expected_plain = [8]
1574         result_tagged, result_plain = helper.get_cores_mpls(helper.PROX_CORE_GEN_MODE)
1575         self.assertEqual(result_tagged, expected_tagged)
1576         self.assertEqual(result_plain, expected_plain)
1577
1578     def test_latency_cores(self):
1579         setup_helper = mock.MagicMock()
1580         setup_helper.prox_config_dict = {}
1581
1582         helper = ProxResourceHelper(setup_helper)
1583         helper._cpu_topology = []
1584
1585         expected = []
1586         result = helper.latency_cores
1587         self.assertEqual(result, expected)
1588
1589         setup_helper.prox_config_dict = [
1590             ('section1', []),
1591             ('section2', [
1592                 ('a', 'b'),
1593                 ('c', 'd'),
1594             ]),
1595             ('core 1s3', []),
1596             ('core 2s5', [
1597                 ('index', 8),
1598                 ('mode', ''),
1599             ]),
1600             ('core 3s1', [
1601                 ('index', 5),
1602                 ('mode', 'lat'),
1603             ]),
1604             ('core 4s9h', [
1605                 ('index', 7),
1606                 ('mode', 'lat'),
1607             ]),
1608         ]
1609
1610         helper = ProxResourceHelper(setup_helper)
1611         helper._cpu_topology = {
1612             1: {
1613                 3: {
1614                     'key1': (23, 32),
1615                     'key2': (12, 21),
1616                     'key3': (44, 33),
1617                 },
1618             },
1619             9: {
1620                 4: {
1621                     'key1': (44, 32),
1622                     'key2': (23, 21),
1623                     'key3': (12, 33),
1624                 },
1625             },
1626         }
1627
1628         self.assertIsNone(helper._latency_cores)
1629         expected = [12, 23]
1630         result = helper.latency_cores
1631         self.assertEqual(result, expected)
1632         self.assertIs(result, helper._latency_cores)
1633         self.assertIs(result, helper.latency_cores)
1634
1635     def test_run_traffic(self):
1636         setup_helper = mock.MagicMock()
1637         helper = ProxResourceHelper(setup_helper)
1638         traffic_proifle = mock.MagicMock(**{"done": True})
1639         helper.run_traffic(traffic_proifle)
1640         self.assertEqual(helper._terminated.value, 1)
1641
1642     def test__run_traffic_once(self):
1643         setup_helper = mock.MagicMock()
1644         helper = ProxResourceHelper(setup_helper)
1645         traffic_proifle = mock.MagicMock(**{"done": True})
1646         helper._run_traffic_once(traffic_proifle)
1647         self.assertEqual(helper._terminated.value, 1)
1648
1649     def test_start_collect(self):
1650         setup_helper = mock.MagicMock()
1651         helper = ProxResourceHelper(setup_helper)
1652         self.assertIsNone(helper.start_collect())
1653
1654     def test_terminate(self):
1655         setup_helper = mock.MagicMock()
1656         helper = ProxResourceHelper(setup_helper)
1657         with self.assertRaises(NotImplementedError):
1658             helper.terminate()
1659
1660     def test_up_post(self):
1661         setup_helper = mock.MagicMock()
1662         helper = ProxResourceHelper(setup_helper)
1663         helper.client = expected = mock.MagicMock()
1664         result = helper.up_post()
1665         self.assertEqual(result, expected)
1666
1667     def test_execute(self):
1668         setup_helper = mock.MagicMock()
1669         helper = ProxResourceHelper(setup_helper)
1670         helper.client = mock.MagicMock()
1671
1672         expected = helper.client.my_command()
1673         result = helper.execute('my_command')
1674         self.assertEqual(result, expected)
1675
1676         helper.client = object()
1677
1678         result = helper.execute('my_command')
1679         self.assertIsNone(result)
1680
1681     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1682     def test_traffic_context(self, mock_time):
1683         setup_helper = mock.MagicMock()
1684         setup_helper.prox_config_dict = {}
1685
1686         helper = ProxResourceHelper(setup_helper)
1687         helper._cpu_topology = {
1688             0: {
1689                 1: {
1690                     5: (5, 1, 0)
1691                 },
1692                 2: {
1693                     6: (6, 2, 0)
1694                 },
1695                 3: {
1696                     7: (7, 3, 0)
1697                 },
1698                 4: {
1699                     8: (8, 3, 0)
1700                 },
1701             }
1702         }
1703
1704         setup_helper.prox_config_dict = [
1705             ('global', [
1706                 ('name', helper.PROX_CORE_MPLS_TEST)
1707             ]),
1708             ('section1', []),
1709             ('section2', [
1710                 ('a', 'b'),
1711                 ('c', 'd'),
1712             ]),
1713             ('core 1', []),
1714             ('core 2', [
1715                 ('index', 8),
1716                 ('mode', ''),
1717             ]),
1718             ('core 3', [
1719                 ('index', 5),
1720                 ('mode', 'gen'),
1721                 ('name', 'tagged'),
1722             ]),
1723             ('core 4', [
1724                 ('index', 7),
1725                 ('mode', 'gen'),
1726                 ('name', 'udp'),
1727             ]),
1728         ]
1729
1730         setup_helper = mock.MagicMock()
1731         setup_helper.vnfd_helper.interfaces = []
1732
1733         client = mock.MagicMock()
1734         client.hz.return_value = 2
1735         client.port_stats.return_value = tuple(range(12))
1736
1737         helper.client = client
1738         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1739
1740         helper._test_cores = [3, 4]
1741
1742         with helper.traffic_context(64, 1):
1743             pass
1744
1745     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1746     def test_run_test(self, mock_time):
1747         @contextmanager
1748         def measure(*args, **kwargs):
1749             yield stats
1750
1751         bad_vnfd = copy.deepcopy(self.VNFD0)
1752         bad_vnfd['vdu'][0]['external-interface'].append({
1753             'virtual-interface': {
1754                 'dst_mac': '00:00:00:00:00:05',
1755                 'vpci': '0000:06:00.0',
1756                 'local_ip': '152.16.100.20',
1757                 'type': 'PCI-PASSTHROUGH',
1758                 'vld_id': 'uplink_1',
1759                 'netmask': '255.255.255.0',
1760                 'dpdk_port_num': 0,
1761                 'bandwidth': '10 Gbps',
1762                 'driver': "i40e",
1763                 'dst_ip': '152.16.100.20',
1764                 'local_iface_name': 'xe2',
1765                 'local_mac': '00:00:00:00:00:07',
1766                 'ifname': 'xe2',
1767             },
1768             'vnfd-connection-point-ref': 'xe2',
1769             'name': 'xe2',
1770         })
1771
1772         bad_vnfd_helper = VnfdHelper(bad_vnfd)
1773         setup_helper = mock.MagicMock()
1774         setup_helper.vnfd_helper = bad_vnfd_helper
1775
1776         stats = {
1777             'delta': TotStatsTuple(6, 7, 8, 9),
1778         }
1779
1780         client = mock.MagicMock()
1781         client.hz.return_value = 2
1782         client.measure_tot_stats = measure
1783         client.port_stats.return_value = tuple(range(12))
1784
1785         helper = ProxResourceHelper(setup_helper)
1786         helper.client = client
1787         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1788
1789         with self.assertRaises(AssertionError):
1790             helper.run_test(980, 15, 45)
1791
1792         vnfd_helper = VnfdHelper(self.VNFD0)
1793         setup_helper.vnfd_helper = vnfd_helper
1794         helper = ProxResourceHelper(setup_helper)
1795         helper.client = client
1796         helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8])
1797         helper._test_cores = [3, 4]
1798
1799         expected_test_data = ProxTestDataTuple(0.0, 2.0, 6, 7, 8, [3.3, 3.6, 3.8], 6, 7, 6.5e6)
1800         expected_port_samples = {
1801             'xe0': {'in_packets': 6, 'out_packets': 7},
1802             'xe1': {'in_packets': 6, 'out_packets': 7},
1803         }
1804         test_data, port_samples = helper.run_test(230, 60, 65)
1805         self.assertTupleEqual(test_data, expected_test_data)
1806         self.assertDictEqual(port_samples, expected_port_samples)
1807
1808     def test_get_latency(self):
1809         setup_helper = mock.MagicMock()
1810         setup_helper.vnfd_helper.interfaces = []
1811
1812         helper = ProxResourceHelper(setup_helper)
1813         helper._latency_cores = []
1814
1815         expected = []
1816         result = helper.get_latency()
1817         self.assertEqual(result, expected)
1818
1819         helper._latency_cores = [1, 2]
1820         helper.client = mock.MagicMock()
1821
1822         expected = helper.sut.lat_stats()
1823         result = helper.get_latency()
1824         self.assertIs(result, expected)
1825
1826     def test__get_logical_if_name(self):
1827         setup_helper = mock.MagicMock()
1828         setup_helper.vnfd_helper.interfaces = []
1829
1830         helper = ProxResourceHelper(setup_helper)
1831         helper._vpci_to_if_name_map = {
1832             'key1': 234,
1833             'key2': 432,
1834         }
1835
1836         expected = 234
1837         result = helper._get_logical_if_name('key1')
1838         self.assertEqual(result, expected)
1839
1840     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time')
1841     @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper')
1842     def test__connect(self, mock_socket_helper_type, mock_time):
1843         client = mock_socket_helper_type()
1844         client.connect.side_effect = chain(repeat(socket.error, 5), [None])
1845
1846         setup_helper = mock.MagicMock()
1847         setup_helper.vnfd_helper.interfaces = []
1848
1849         helper = ProxResourceHelper(setup_helper)
1850
1851         result = helper._connect()
1852         self.assertIs(result, client)
1853
1854         client.connect.side_effect = chain(repeat(socket.error, 65), [None])
1855
1856         with self.assertRaises(Exception):
1857             helper._connect()