NFVI support for standalone, baremetal and heat contexts
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_vpe_vnf.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15
16 from multiprocessing import Process, Queue
17 import os
18 import time
19
20 import mock
21 from six.moves import configparser
22 import unittest
23
24 from yardstick.tests import STL_MOCKS
25 from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath
26 from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
27 from yardstick.network_services.vnf_generic.vnf.base import QueueFileWrapper
28 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
29 from yardstick.benchmark.contexts import base as ctx_base
30
31
32 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
33
34 STLClient = mock.MagicMock()
35 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
36 stl_patch.start()
37
38 if stl_patch:
39     from yardstick.network_services.vnf_generic.vnf.vpe_vnf import ConfigCreate
40     from yardstick.network_services.nfvi.resource import ResourceProfile
41     from yardstick.network_services.vnf_generic.vnf.vpe_vnf import \
42         VpeApproxVnf, VpeApproxSetupEnvHelper
43
44
45 TEST_FILE_YAML = 'nsb_test_case.yaml'
46
47 NAME = 'vnf_1'
48
49 PING_OUTPUT_1 = "Pkts in: 101\r\n\tPkts dropped by AH: 100\r\n\tPkts dropped by other: 100"
50
51 MODULE_PATH = FileAbsPath(__file__)
52 get_file_abspath = MODULE_PATH.get_path
53
54
55 class TestConfigCreate(unittest.TestCase):
56
57     VNFD_0 = {
58         'short-name': 'VpeVnf',
59         'vdu': [
60             {
61                 'routing_table': [
62                     {
63                         'network': '152.16.100.20',
64                         'netmask': '255.255.255.0',
65                         'gateway': '152.16.100.20',
66                         'if': 'xe0'
67                     },
68                     {
69                         'network': '152.16.40.20',
70                         'netmask': '255.255.255.0',
71                         'gateway': '152.16.40.20',
72                         'if': 'xe1'
73                     },
74                 ],
75                 'description': 'VPE approximation using DPDK',
76                 'name': 'vpevnf-baremetal',
77                 'nd_route_tbl': [
78                     {
79                         'network': '0064:ff9b:0:0:0:0:9810:6414',
80                         'netmask': '112',
81                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
82                         'if': 'xe0'
83                     },
84                     {
85                         'network': '0064:ff9b:0:0:0:0:9810:2814',
86                         'netmask': '112',
87                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
88                         'if': 'xe1'
89                     },
90                 ],
91                 'id': 'vpevnf-baremetal',
92                 'external-interface': [
93                     {
94                         'virtual-interface': {
95                             'dst_mac': '00:00:00:00:00:03',
96                             'vpci': '0000:05:00.0',
97                             'local_ip': '152.16.100.19',
98                             'type': 'PCI-PASSTHROUGH',
99                             'netmask': '255.255.255.0',
100                             'dpdk_port_num': 0,
101                             'bandwidth': '10 Gbps',
102                             'dst_ip': '152.16.100.20',
103                             'local_mac': '00:00:00:00:00:01',
104                             'vld_id': 'uplink_0',
105                             'ifname': 'xe0',
106                         },
107                         'vnfd-connection-point-ref': 'xe0',
108                         'name': 'xe0'
109                     },
110                     {
111                         'virtual-interface': {
112                             'dst_mac': '00:00:00:00:00:04',
113                             'vpci': '0000:05:00.1',
114                             'local_ip': '152.16.40.19',
115                             'type': 'PCI-PASSTHROUGH',
116                             'netmask': '255.255.255.0',
117                             'dpdk_port_num': 1,
118                             'bandwidth': '10 Gbps',
119                             'dst_ip': '152.16.40.20',
120                             'local_mac': '00:00:00:00:00:02',
121                             'vld_id': 'downlink_0',
122                             'ifname': 'xe1',
123                         },
124                         'vnfd-connection-point-ref': 'xe1',
125                         'name': 'xe1'
126                     },
127                 ],
128             },
129         ],
130         'description': 'Vpe approximation using DPDK',
131         'mgmt-interface': {
132             'vdu-id': 'vpevnf-baremetal',
133             'host': '1.1.1.1',
134             'password': 'r00t',
135             'user': 'root',
136             'ip': '1.1.1.1'
137         },
138         'benchmark': {
139             'kpi': [
140                 'packets_in',
141                 'packets_fwd',
142                 'packets_dropped',
143             ],
144         },
145         'connection-point': [
146             {
147                 'type': 'VPORT',
148                 'name': 'xe0',
149             },
150             {
151                 'type': 'VPORT',
152                 'name': 'xe1',
153             },
154         ],
155         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
156     }
157
158     def test___init__(self):
159         vnfd_helper = VnfdHelper(self.VNFD_0)
160         config_create = ConfigCreate(vnfd_helper, 2)
161         self.assertEqual(config_create.uplink_ports, ['xe0'])
162         self.assertEqual(config_create.downlink_ports, ['xe1'])
163         self.assertEqual(config_create.socket, 2)
164
165     def test_dpdk_port_to_link_id(self):
166         vnfd_helper = VnfdHelper(self.VNFD_0)
167         config_create = ConfigCreate(vnfd_helper, 2)
168         self.assertEqual(config_create.dpdk_port_to_link_id_map, {'xe0': 0, 'xe1': 1})
169
170     def test_vpe_initialize(self):
171         vnfd_helper = VnfdHelper(self.VNFD_0)
172         config_create = ConfigCreate(vnfd_helper, 2)
173         config = configparser.ConfigParser()
174         config_create.vpe_initialize(config)
175         self.assertEqual(config.get('EAL', 'log_level'), '0')
176         self.assertEqual(config.get('PIPELINE0', 'type'), 'MASTER')
177         self.assertEqual(config.get('PIPELINE0', 'core'), 's2C0')
178         self.assertEqual(config.get('MEMPOOL0', 'pool_size'), '256K')
179         self.assertEqual(config.get('MEMPOOL1', 'pool_size'), '2M')
180
181     def test_vpe_rxq(self):
182         vnfd_helper = VnfdHelper(self.VNFD_0)
183         config_create = ConfigCreate(vnfd_helper, 2)
184         config = configparser.ConfigParser()
185         config_create.downlink_ports = ['xe0']
186         config_create.vpe_rxq(config)
187         self.assertEqual(config.get('RXQ0.0', 'mempool'), 'MEMPOOL1')
188
189     def test_get_sink_swq(self):
190         vnfd_helper = VnfdHelper(self.VNFD_0)
191         config_create = ConfigCreate(vnfd_helper, 2)
192         config = configparser.ConfigParser()
193         config.add_section('PIPELINE0')
194         config.set('PIPELINE0', 'key1', 'value1')
195         config.set('PIPELINE0', 'key2', 'value2 SINK')
196         config.set('PIPELINE0', 'key3', 'TM value3')
197         config.set('PIPELINE0', 'key4', 'value4')
198         config.set('PIPELINE0', 'key5', 'the SINK value5')
199
200         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key1', 5), 'SWQ-1')
201         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key2', 5), 'SWQ-1 SINK0')
202         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key3', 5), 'SWQ-1 TM5')
203         config_create.sw_q += 1
204         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key4', 5), 'SWQ0')
205         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key5', 5), 'SWQ0 SINK1')
206
207     def test_generate_vpe_script(self):
208         vnfd_helper = VnfdHelper(self.VNFD_0)
209         vpe_config_vnf = ConfigCreate(vnfd_helper, 2)
210         intf = [
211             {
212                 "name": 'xe1',
213                 "virtual-interface": {
214                     "dst_ip": "1.1.1.1",
215                     "dst_mac": "00:00:00:00:00:00:02",
216                 },
217             },
218             {
219                 "name": 'xe2',
220                 "virtual-interface": {
221                     "dst_ip": "1.1.1.1",
222                     "dst_mac": "00:00:00:00:00:00:02",
223                 },
224             },
225         ]
226         vpe_config_vnf.downlink_ports = ['xe1']
227         vpe_config_vnf.uplink_ports = ['xe2']
228         result = vpe_config_vnf.generate_vpe_script(intf)
229         self.assertIsInstance(result, str)
230         self.assertNotEqual(result, '')
231
232     def test_create_vpe_config(self):
233         vnfd_helper = VnfdHelper(self.VNFD_0)
234         config_create = ConfigCreate(vnfd_helper, 23)
235         config_create.downlink_ports = ['xe1']
236         config_create.uplink_ports = ['xe1']
237         curr_path = os.path.dirname(os.path.abspath(__file__))
238         vpe_cfg = "samples/vnf_samples/nsut/vpe/vpe_config"
239         vnf_cfg = os.path.join(curr_path, "../../../../..", vpe_cfg)
240         config_create.create_vpe_config(vnf_cfg)
241         os.system("git checkout -- %s" % vnf_cfg)
242
243
244 class TestVpeApproxVnf(unittest.TestCase):
245
246     VNFD_0 = {
247         'short-name': 'VpeVnf',
248         'vdu': [
249             {
250                 'routing_table': [
251                     {
252                         'network': '152.16.100.20',
253                         'netmask': '255.255.255.0',
254                         'gateway': '152.16.100.20',
255                         'if': 'xe0',
256                     },
257                     {
258                         'network': '152.16.40.20',
259                         'netmask': '255.255.255.0',
260                         'gateway': '152.16.40.20',
261                         'if': 'xe1',
262                     },
263                 ],
264                 'description': 'VPE approximation using DPDK',
265                 'name': 'vpevnf-baremetal',
266                 'nd_route_tbl': [
267                     {
268                         'network': '0064:ff9b:0:0:0:0:9810:6414',
269                         'netmask': '112',
270                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
271                         'if': 'xe0',
272                     },
273                     {
274                         'network': '0064:ff9b:0:0:0:0:9810:2814',
275                         'netmask': '112',
276                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
277                         'if': 'xe1',
278                     },
279                 ],
280                 'id': 'vpevnf-baremetal',
281                 'external-interface': [
282                     {
283                         'virtual-interface': {
284                             'dst_mac': '00:00:00:00:00:04',
285                             'vpci': '0000:05:00.0',
286                             'local_ip': '152.16.100.19',
287                             'type': 'PCI-PASSTHROUGH',
288                             'netmask': '255.255.255.0',
289                             'dpdk_port_num': 0,
290                             'bandwidth': '10 Gbps',
291                             'driver': "i40e",
292                             'dst_ip': '152.16.100.20',
293                             'local_iface_name': 'xe0',
294                             'local_mac': '00:00:00:00:00:02',
295                             'vld_id': 'uplink_0',
296                             'ifname': 'xe0',
297                         },
298                         'vnfd-connection-point-ref': 'xe0',
299                         'name': 'xe0',
300                     },
301                     {
302                         'virtual-interface': {
303                             'dst_mac': '00:00:00:00:00:03',
304                             'vpci': '0000:05:00.1',
305                             'local_ip': '152.16.40.19',
306                             'type': 'PCI-PASSTHROUGH',
307                             'driver': "i40e",
308                             'netmask': '255.255.255.0',
309                             'dpdk_port_num': 1,
310                             'bandwidth': '10 Gbps',
311                             'dst_ip': '152.16.40.20',
312                             'local_iface_name': 'xe1',
313                             'local_mac': '00:00:00:00:00:01',
314                             'vld_id': 'downlink_0',
315                             'ifname': 'xe1',
316                         },
317                         'vnfd-connection-point-ref': 'xe1',
318                         'name': 'xe1',
319                     },
320                 ],
321             },
322         ],
323         'description': 'Vpe approximation using DPDK',
324         'mgmt-interface': {
325             'vdu-id': 'vpevnf-baremetal',
326             'host': '1.2.1.1',
327             'password': 'r00t',
328             'user': 'root',
329             'ip': '1.2.1.1',
330         },
331         'benchmark': {
332             'kpi': [
333                 'packets_in',
334                 'packets_fwd',
335                 'packets_dropped',
336             ],
337         },
338         'connection-point': [
339             {
340                 'type': 'VPORT',
341                 'name': 'xe0',
342             },
343             {
344                 'type': 'VPORT',
345                 'name': 'xe1',
346             },
347         ],
348         'id': 'VpeApproxVnf',
349         'name': 'VPEVnfSsh',
350     }
351
352     VNFD = {
353         'vnfd:vnfd-catalog': {
354             'vnfd': [
355                 VNFD_0,
356             ],
357         },
358     }
359
360     SCENARIO_CFG = {
361         'options': {
362             'packetsize': 64,
363             'traffic_type': 4,
364             'rfc2544': {
365                 'allowed_drop_rate': '0.8 - 1',
366             },
367             'vnf__1': {
368                 'cfg': 'acl_1rule.yaml',
369                 'vnf_config': {
370                     'lb_config': 'SW',
371                     'lb_count': 1,
372                     'worker_config':
373                     '1C/1T',
374                     'worker_threads': 1,
375                 },
376             }
377         },
378         'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
379         'tc': 'tc_ipv4_1Mflow_64B_packetsize',
380         'runner': {
381             'object': 'NetworkServiceTestCase',
382             'interval': 35,
383             'output_filename': '/tmp/yardstick.out',
384             'runner_id': 74476,
385             'duration': 400,
386             'type': 'Duration',
387         },
388         'traffic_profile': 'ipv4_throughput_vpe.yaml',
389         'traffic_options': {
390             'flow': 'ipv4_Packets_vpe.yaml',
391             'imix': 'imix_voice.yaml',
392         },
393         'type': 'ISB',
394         'nodes': {
395             'tg__2': 'trafficgen_2.yardstick',
396             'tg__1': 'trafficgen_1.yardstick',
397             'vnf__1': 'vnf.yardstick',
398         },
399         'topology': 'vpe-tg-topology-baremetal.yaml',
400     }
401
402     CONTEXT_CFG = {
403         'nodes': {
404             'tg__2': {
405                 'member-vnf-index': '3',
406                 'role': 'TrafficGen',
407                 'name': 'trafficgen_2.yardstick',
408                 'vnfd-id-ref': 'tg__2',
409                 'ip': '1.2.1.1',
410                 'interfaces': {
411                     'xe0': {
412                         'local_iface_name': 'ens513f0',
413                         'vld_id': VpeApproxVnf.DOWNLINK,
414                         'netmask': '255.255.255.0',
415                         'local_ip': '152.16.40.20',
416                         'dst_mac': '00:00:00:00:00:01',
417                         'local_mac': '00:00:00:00:00:03',
418                         'dst_ip': '152.16.40.19',
419                         'driver': 'ixgbe',
420                         'vpci': '0000:02:00.0',
421                         'dpdk_port_num': 0,
422                     },
423                     'xe1': {
424                         'local_iface_name': 'ens513f1',
425                         'netmask': '255.255.255.0',
426                         'network': '202.16.100.0',
427                         'local_ip': '202.16.100.20',
428                         'local_mac': '00:1e:67:d0:60:5d',
429                         'driver': 'ixgbe',
430                         'vpci': '0000:02:00.1',
431                         'dpdk_port_num': 1,
432                     },
433                 },
434                 'password': 'r00t',
435                 'VNF model': 'l3fwd_vnf.yaml',
436                 'user': 'root',
437             },
438             'tg__1': {
439                 'member-vnf-index': '1',
440                 'role': 'TrafficGen',
441                 'name': 'trafficgen_1.yardstick',
442                 'vnfd-id-ref': 'tg__1',
443                 'ip': '1.2.1.1',
444                 'interfaces': {
445                     'xe0': {
446                         'local_iface_name': 'ens785f0',
447                         'vld_id': VpeApproxVnf.UPLINK,
448                         'netmask': '255.255.255.0',
449                         'local_ip': '152.16.100.20',
450                         'dst_mac': '00:00:00:00:00:02',
451                         'local_mac': '00:00:00:00:00:04',
452                         'dst_ip': '152.16.100.19',
453                         'driver': 'i40e',
454                         'vpci': '0000:05:00.0',
455                         'dpdk_port_num': 0,
456                     },
457                     'xe1': {
458                         'local_iface_name': 'ens785f1',
459                         'netmask': '255.255.255.0',
460                         'local_ip': '152.16.100.21',
461                         'local_mac': '00:00:00:00:00:01',
462                         'driver': 'i40e',
463                         'vpci': '0000:05:00.1',
464                         'dpdk_port_num': 1,
465                     },
466                 },
467                 'password': 'r00t',
468                 'VNF model': 'tg_rfc2544_tpl.yaml',
469                 'user': 'root',
470             },
471             'vnf__1': {
472                 'name': 'vnf.yardstick',
473                 'vnfd-id-ref': 'vnf__1',
474                 'ip': '1.2.1.1',
475                 'interfaces': {
476                     'xe0': {
477                         'local_iface_name': 'ens786f0',
478                         'vld_id': VpeApproxVnf.UPLINK,
479                         'netmask': '255.255.255.0',
480                         'local_ip': '152.16.100.19',
481                         'dst_mac': '00:00:00:00:00:04',
482                         'local_mac': '00:00:00:00:00:02',
483                         'dst_ip': '152.16.100.20',
484                         'driver': 'i40e',
485                         'vpci': '0000:05:00.0',
486                         'dpdk_port_num': 0,
487                     },
488                     'xe1': {
489                         'local_iface_name': 'ens786f1',
490                         'vld_id': VpeApproxVnf.DOWNLINK,
491                         'netmask': '255.255.255.0',
492                         'local_ip': '152.16.40.19',
493                         'dst_mac': '00:00:00:00:00:03',
494                         'local_mac': '00:00:00:00:00:01',
495                         'dst_ip': '152.16.40.20',
496                         'driver': 'i40e',
497                         'vpci': '0000:05:00.1',
498                         'dpdk_port_num': 1,
499                     },
500                 },
501                 'routing_table': [
502                     {
503                         'netmask': '255.255.255.0',
504                         'gateway': '152.16.100.20',
505                         'network': '152.16.100.20',
506                         'if': 'xe0',
507                     },
508                     {
509                         'netmask': '255.255.255.0',
510                         'gateway': '152.16.40.20',
511                         'network': '152.16.40.20',
512                         'if': 'xe1',
513                     },
514                 ],
515                 'member-vnf-index': '2',
516                 'host': '1.2.1.1',
517                 'role': 'vnf',
518                 'user': 'root',
519                 'nd_route_tbl': [
520                     {
521                         'netmask': '112',
522                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
523                         'network': '0064:ff9b:0:0:0:0:9810:6414',
524                         'if': 'xe0',
525                     },
526                     {
527                         'netmask': '112',
528                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
529                         'network': '0064:ff9b:0:0:0:0:9810:2814',
530                         'if': 'xe1',
531                     },
532                 ],
533                 'password': 'r00t',
534                 'VNF model': 'vpe_vnf.yaml',
535             },
536         },
537     }
538
539     def setUp(self):
540         self._mock_time_sleep = mock.patch.object(time, 'sleep')
541         self.mock_time_sleep = self._mock_time_sleep.start()
542         self.addCleanup(self._stop_mocks)
543
544     def _stop_mocks(self):
545         self._mock_time_sleep.stop()
546
547     def test___init__(self):
548         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
549         self.assertIsNone(vpe_approx_vnf._vnf_process)
550
551     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
552     @mock.patch(SSH_HELPER)
553     def test_collect_kpi_sa_not_running(self, ssh, *args):
554         mock_ssh(ssh)
555
556         resource = mock.Mock(autospec=ResourceProfile)
557         resource.check_if_system_agent_running.return_value = 1, ''
558         resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
559         resource.check_if_system_agent_running.return_value = (1, None)
560
561         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
562         vpe_approx_vnf.scenario_helper.scenario_cfg = {
563             'nodes': {vpe_approx_vnf.name: "mock"}
564         }
565         vpe_approx_vnf.q_in = mock.MagicMock()
566         vpe_approx_vnf.q_out = mock.MagicMock()
567         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
568         vpe_approx_vnf.resource_helper.resource = resource
569
570         expected = {
571             'physical_node': 'mock_node',
572             'pkt_in_down_stream': 0,
573             'pkt_in_up_stream': 0,
574             'pkt_drop_down_stream': 0,
575             'pkt_drop_up_stream': 0,
576             'collect_stats': {'core': {}},
577         }
578         self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
579
580     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
581     @mock.patch(SSH_HELPER)
582     def test_collect_kpi_sa_running(self, ssh, *args):
583         mock_ssh(ssh)
584
585         resource = mock.Mock(autospec=ResourceProfile)
586         resource.check_if_system_agent_running.return_value = 0, '1234'
587         resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
588
589         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
590         vpe_approx_vnf.scenario_helper.scenario_cfg = {
591             'nodes': {vpe_approx_vnf.name: "mock"}
592         }
593         vpe_approx_vnf.q_in = mock.MagicMock()
594         vpe_approx_vnf.q_out = mock.MagicMock()
595         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
596         vpe_approx_vnf.resource_helper.resource = resource
597
598         expected = {
599             'physical_node': 'mock_node',
600             'pkt_in_down_stream': 0,
601             'pkt_in_up_stream': 0,
602             'pkt_drop_down_stream': 0,
603             'pkt_drop_up_stream': 0,
604             'collect_stats': {'core': {'foo': 234}},
605         }
606         self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
607
608     @mock.patch(SSH_HELPER)
609     def test_vnf_execute(self, ssh):
610         mock_ssh(ssh)
611         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
612         vpe_approx_vnf.q_in = mock.MagicMock()
613         vpe_approx_vnf.q_out = mock.MagicMock()
614         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
615         self.assertEqual(vpe_approx_vnf.vnf_execute("quit", 0), '')
616
617     @mock.patch(SSH_HELPER)
618     def test_run_vpe(self, ssh):
619         mock_ssh(ssh)
620
621         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
622         vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML)
623         vpe_approx_vnf.vnf_cfg = {
624             'lb_config': 'SW',
625             'lb_count': 1,
626             'worker_config': '1C/1T',
627             'worker_threads': 1,
628         }
629         vpe_approx_vnf.scenario_helper.scenario_cfg = {
630             'options': {
631                 NAME: {
632                     'traffic_type': '4',
633                     'topology': 'nsb_test_case.yaml',
634                     'vnf_config': 'vpe_config',
635                 }
636             }
637         }
638         vpe_approx_vnf.topology = "nsb_test_case.yaml"
639         vpe_approx_vnf.nfvi_type = "baremetal"
640         vpe_approx_vnf._provide_config_file = mock.Mock()
641         vpe_approx_vnf._build_config = mock.MagicMock()
642
643         self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock)
644         self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock)
645         self.assertIsNone(vpe_approx_vnf._run())
646
647     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig")
648     @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.ConfigCreate")
649     @mock.patch("six.moves.builtins.open")
650     @mock.patch(SSH_HELPER)
651     def test_build_config(self, ssh, *args):
652         mock_ssh(ssh)
653         vpe_approx_vnf = VpeApproxSetupEnvHelper(mock.MagicMock(),
654                                                  mock.MagicMock(), mock.MagicMock())
655         vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML)
656         vpe_approx_vnf.generate_port_pairs = mock.Mock()
657         vpe_approx_vnf.vnf_cfg = {
658             'lb_config': 'SW',
659             'lb_count': 1,
660             'worker_config': '1C/1T',
661             'worker_threads': 1,
662         }
663         vpe_approx_vnf.scenario_helper.scenario_cfg = {
664             'options': {
665                 NAME: {
666                     'traffic_type': '4',
667                     'topology': 'nsb_test_case.yaml',
668                     'vnf_config': 'vpe_config',
669                 }
670             }
671         }
672         vpe_approx_vnf.topology = "nsb_test_case.yaml"
673         vpe_approx_vnf.nfvi_type = "baremetal"
674         vpe_approx_vnf._provide_config_file = mock.Mock()
675
676         vpe_approx_vnf.ssh_helper = mock.MagicMock()
677         vpe_approx_vnf.scenario_helper = mock.MagicMock()
678         vpe_approx_vnf.ssh_helper.bin_path = mock.Mock()
679         vpe_approx_vnf.ssh_helper.upload_config_file = mock.MagicMock()
680         self.assertIsNone(vpe_approx_vnf._build_vnf_ports())
681
682         vpe_approx_vnf.ssh_helper.provision_tool = mock.Mock(return_value='tool_path')
683         vpe_approx_vnf.ssh_helper.all_ports = mock.Mock()
684         vpe_approx_vnf.vnfd_helper.port_nums = mock.Mock(return_value=[0, 1])
685         vpe_approx_vnf.scenario_helper.vnf_cfg = {'lb_config': 'HW'}
686
687         expected = 'sudo tool_path -p 0x3 -f /tmp/vpe_config -s /tmp/vpe_script  --hwlb 3'
688         self.assertEqual(vpe_approx_vnf.build_config(), expected)
689
690     @mock.patch(SSH_HELPER)
691     def test_wait_for_instantiate(self, ssh):
692         mock_ssh(ssh)
693
694         mock_process = mock.Mock(autospec=Process)
695         mock_process.is_alive.return_value = True
696         mock_process.exitcode = 432
697
698         mock_q_out = mock.Mock(autospec=Queue)
699         mock_q_out.get.side_effect = iter(["pipeline>"])
700         mock_q_out.qsize.side_effect = range(1, -1, -1)
701
702         mock_resource = mock.MagicMock()
703
704         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
705         vpe_approx_vnf._vnf_process = mock_process
706         vpe_approx_vnf.q_out = mock_q_out
707         vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
708         vpe_approx_vnf.resource_helper.resource = mock_resource
709
710         vpe_approx_vnf.q_out.put("pipeline>")
711         self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
712
713     @mock.patch(SSH_HELPER)
714     def test_wait_for_instantiate_fragmented(self, ssh):
715         mock_ssh(ssh)
716
717         mock_process = mock.Mock(autospec=Process)
718         mock_process.is_alive.return_value = True
719         mock_process.exitcode = 432
720
721         # test that fragmented pipeline prompt is recognized
722         mock_q_out = mock.Mock(autospec=Queue)
723         mock_q_out.get.side_effect = iter(["wow pipel", "ine>"])
724         mock_q_out.qsize.side_effect = range(2, -1, -1)
725
726         mock_resource = mock.MagicMock()
727
728         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
729         vpe_approx_vnf._vnf_process = mock_process
730         vpe_approx_vnf.q_out = mock_q_out
731         vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
732         vpe_approx_vnf.resource_helper.resource = mock_resource
733
734         self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
735
736     @mock.patch(SSH_HELPER)
737     def test_wait_for_instantiate_crash(self, ssh):
738         mock_ssh(ssh, exec_result=(1, "", ""))
739
740         mock_process = mock.Mock(autospec=Process)
741         mock_process.is_alive.return_value = False
742         mock_process.exitcode = 432
743
744         mock_resource = mock.MagicMock()
745
746         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
747         vpe_approx_vnf._vnf_process = mock_process
748         vpe_approx_vnf.resource_helper.resource = mock_resource
749
750         with self.assertRaises(RuntimeError) as raised:
751             vpe_approx_vnf.wait_for_instantiate()
752
753         self.assertIn('VNF process died', str(raised.exception))
754
755     @mock.patch(SSH_HELPER)
756     def test_wait_for_instantiate_panic(self, ssh):
757         mock_ssh(ssh, exec_result=(1, "", ""))
758
759         mock_process = mock.Mock(autospec=Process)
760         mock_process.is_alive.return_value = True
761         mock_process.exitcode = 432
762
763         mock_resource = mock.MagicMock()
764
765         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
766         vpe_approx_vnf._vnf_process = mock_process
767         vpe_approx_vnf.resource_helper.resource = mock_resource
768
769         vpe_approx_vnf.q_out.put("PANIC")
770         with self.assertRaises(RuntimeError) as raised:
771             vpe_approx_vnf.wait_for_instantiate()
772
773         self.assertIn('Error starting', str(raised.exception))
774
775     @mock.patch(SSH_HELPER)
776     def test_wait_for_instantiate_panic_fragmented(self, ssh):
777         mock_ssh(ssh, exec_result=(1, "", ""))
778
779         mock_process = mock.Mock(autospec=Process)
780         mock_process.is_alive.return_value = True
781         mock_process.exitcode = 432
782
783         # test that fragmented PANIC is recognized
784         mock_q_out = mock.Mock(autospec=Queue)
785         mock_q_out.get.side_effect = iter(["omg PA", "NIC this is bad"])
786         mock_q_out.qsize.side_effect = range(2, -1, -1)
787
788         mock_resource = mock.MagicMock()
789
790         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
791         vpe_approx_vnf._vnf_process = mock_process
792         vpe_approx_vnf.q_out = mock_q_out
793         vpe_approx_vnf.resource_helper.resource = mock_resource
794
795         with self.assertRaises(RuntimeError) as raised:
796             vpe_approx_vnf.wait_for_instantiate()
797
798         self.assertIn('Error starting', str(raised.exception))
799
800     @mock.patch(SSH_HELPER)
801     def test_terminate(self, ssh):
802         mock_ssh(ssh)
803
804         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
805         vpe_approx_vnf._vnf_process = mock.MagicMock()
806         vpe_approx_vnf._resource_collect_stop = mock.Mock()
807         vpe_approx_vnf.resource_helper = mock.MagicMock()
808
809         self.assertIsNone(vpe_approx_vnf.terminate())