Sample CGNAPT VNF
[yardstick.git] / tests / unit / network_services / vnf_generic / vnf / test_vpe_vnf.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 os
21 import unittest
22
23 import six.moves.configparser as configparser
24 import mock
25 from multiprocessing import Process, Queue
26
27 from yardstick.network_services.vnf_generic.vnf.base import QueueFileWrapper
28
29 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
30
31 STL_MOCKS = {
32     'stl': mock.MagicMock(),
33     'stl.trex_stl_lib': mock.MagicMock(),
34     'stl.trex_stl_lib.base64': mock.MagicMock(),
35     'stl.trex_stl_lib.binascii': mock.MagicMock(),
36     'stl.trex_stl_lib.collections': mock.MagicMock(),
37     'stl.trex_stl_lib.copy': mock.MagicMock(),
38     'stl.trex_stl_lib.datetime': mock.MagicMock(),
39     'stl.trex_stl_lib.functools': mock.MagicMock(),
40     'stl.trex_stl_lib.imp': mock.MagicMock(),
41     'stl.trex_stl_lib.inspect': mock.MagicMock(),
42     'stl.trex_stl_lib.json': mock.MagicMock(),
43     'stl.trex_stl_lib.linecache': mock.MagicMock(),
44     'stl.trex_stl_lib.math': mock.MagicMock(),
45     'stl.trex_stl_lib.os': mock.MagicMock(),
46     'stl.trex_stl_lib.platform': mock.MagicMock(),
47     'stl.trex_stl_lib.pprint': mock.MagicMock(),
48     'stl.trex_stl_lib.random': mock.MagicMock(),
49     'stl.trex_stl_lib.re': mock.MagicMock(),
50     'stl.trex_stl_lib.scapy': mock.MagicMock(),
51     'stl.trex_stl_lib.socket': mock.MagicMock(),
52     'stl.trex_stl_lib.string': mock.MagicMock(),
53     'stl.trex_stl_lib.struct': mock.MagicMock(),
54     'stl.trex_stl_lib.sys': mock.MagicMock(),
55     'stl.trex_stl_lib.threading': mock.MagicMock(),
56     'stl.trex_stl_lib.time': mock.MagicMock(),
57     'stl.trex_stl_lib.traceback': mock.MagicMock(),
58     'stl.trex_stl_lib.trex_stl_async_client': mock.MagicMock(),
59     'stl.trex_stl_lib.trex_stl_client': mock.MagicMock(),
60     'stl.trex_stl_lib.trex_stl_exceptions': mock.MagicMock(),
61     'stl.trex_stl_lib.trex_stl_ext': mock.MagicMock(),
62     'stl.trex_stl_lib.trex_stl_jsonrpc_client': mock.MagicMock(),
63     'stl.trex_stl_lib.trex_stl_packet_builder_interface': mock.MagicMock(),
64     'stl.trex_stl_lib.trex_stl_packet_builder_scapy': mock.MagicMock(),
65     'stl.trex_stl_lib.trex_stl_port': mock.MagicMock(),
66     'stl.trex_stl_lib.trex_stl_stats': mock.MagicMock(),
67     'stl.trex_stl_lib.trex_stl_streams': mock.MagicMock(),
68     'stl.trex_stl_lib.trex_stl_types': mock.MagicMock(),
69     'stl.trex_stl_lib.types': mock.MagicMock(),
70     'stl.trex_stl_lib.utils': mock.MagicMock(),
71     'stl.trex_stl_lib.utils.argparse': mock.MagicMock(),
72     'stl.trex_stl_lib.utils.collections': mock.MagicMock(),
73     'stl.trex_stl_lib.utils.common': mock.MagicMock(),
74     'stl.trex_stl_lib.utils.json': mock.MagicMock(),
75     'stl.trex_stl_lib.utils.os': mock.MagicMock(),
76     'stl.trex_stl_lib.utils.parsing_opts': mock.MagicMock(),
77     'stl.trex_stl_lib.utils.pwd': mock.MagicMock(),
78     'stl.trex_stl_lib.utils.random': mock.MagicMock(),
79     'stl.trex_stl_lib.utils.re': mock.MagicMock(),
80     'stl.trex_stl_lib.utils.string': mock.MagicMock(),
81     'stl.trex_stl_lib.utils.sys': mock.MagicMock(),
82     'stl.trex_stl_lib.utils.text_opts': mock.MagicMock(),
83     'stl.trex_stl_lib.utils.text_tables': mock.MagicMock(),
84     'stl.trex_stl_lib.utils.texttable': mock.MagicMock(),
85     'stl.trex_stl_lib.warnings': mock.MagicMock(),
86     'stl.trex_stl_lib.yaml': mock.MagicMock(),
87     'stl.trex_stl_lib.zlib': mock.MagicMock(),
88     'stl.trex_stl_lib.zmq': mock.MagicMock(),
89 }
90
91 STLClient = mock.MagicMock()
92 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
93 stl_patch.start()
94
95 if stl_patch:
96     from yardstick.network_services.vnf_generic.vnf.vpe_vnf import ConfigCreate
97     from yardstick.network_services.nfvi.resource import ResourceProfile
98     from yardstick.network_services.vnf_generic.vnf import vpe_vnf
99     from yardstick.network_services.vnf_generic.vnf.vpe_vnf import VpeApproxVnf
100
101 from tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath
102 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
103
104
105 TEST_FILE_YAML = 'nsb_test_case.yaml'
106
107 NAME = 'vnf_1'
108
109 PING_OUTPUT_1 = "Pkts in: 101\r\n\tPkts dropped by AH: 100\r\n\tPkts dropped by other: 100"
110
111 MODULE_PATH = FileAbsPath(__file__)
112 get_file_abspath = MODULE_PATH.get_path
113
114
115 class TestConfigCreate(unittest.TestCase):
116
117     def test___init__(self):
118         config_create = ConfigCreate([0], [1], 2)
119         self.assertEqual(config_create.priv_ports, [0])
120         self.assertEqual(config_create.pub_ports, [1])
121         self.assertEqual(config_create.socket, 2)
122
123     def test_vpe_initialize(self):
124         config_create = ConfigCreate([0], [1], 2)
125         config = configparser.ConfigParser()
126         config_create.vpe_initialize(config)
127         self.assertEqual(config.get('EAL', 'log_level'), '0')
128         self.assertEqual(config.get('PIPELINE0', 'type'), 'MASTER')
129         self.assertEqual(config.get('PIPELINE0', 'core'), 's2C0')
130         self.assertEqual(config.get('MEMPOOL0', 'pool_size'), '256K')
131         self.assertEqual(config.get('MEMPOOL1', 'pool_size'), '2M')
132
133     def test_vpe_rxq(self):
134         config_create = ConfigCreate([0], [1, 2], 3)
135         config = configparser.ConfigParser()
136         config_create.vpe_rxq(config)
137         self.assertEqual(config.get('RXQ1.0', 'mempool'), 'MEMPOOL1')
138         self.assertEqual(config.get('RXQ2.0', 'mempool'), 'MEMPOOL1')
139
140     def test_get_sink_swq(self):
141         config_create = ConfigCreate([0], [1], 2)
142         config = configparser.ConfigParser()
143         config.add_section('PIPELINE0')
144         config.set('PIPELINE0', 'key1', 'value1')
145         config.set('PIPELINE0', 'key2', 'value2 SINK')
146         config.set('PIPELINE0', 'key3', 'TM value3')
147         config.set('PIPELINE0', 'key4', 'value4')
148         config.set('PIPELINE0', 'key5', 'the SINK value5')
149
150         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key1', 5), 'SWQ-1')
151         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key2', 5), 'SWQ-1 SINK0')
152         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key3', 5), 'SWQ-1 TM5')
153         config_create.sw_q += 1
154         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key4', 5), 'SWQ0')
155         self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key5', 5), 'SWQ0 SINK1')
156
157     def test_generate_vpe_script(self):
158         vpe_config_vnf = ConfigCreate([0], [0], 0)
159         intf = [
160             {
161                 "virtual-interface": {
162                     "dst_ip": "1.1.1.1",
163                     "dst_mac": "00:00:00:00:00:00:02",
164                 },
165             },
166         ]
167         result = vpe_config_vnf.generate_vpe_script(intf)
168         self.assertIsInstance(result, str)
169         self.assertNotEqual(result, '')
170
171     def test_create_vpe_config(self):
172         priv_ports = [
173             {
174                 'index': 0,
175                 'dpdk_port_num': 1,
176                 'peer_intf': {
177                     'dpdk_port_num': 2,
178                     'index': 3,
179                 },
180             },
181         ]
182
183         pub_ports = [
184             {
185                 'index': 2,
186                 'dpdk_port_num': 3,
187                 'peer_intf': {
188                     'dpdk_port_num': 0,
189                     'index': 1,
190                 },
191             },
192         ]
193
194         config_create = ConfigCreate(priv_ports, pub_ports, 23)
195         curr_path = os.path.dirname(os.path.abspath(__file__))
196         vpe_cfg = "samples/vnf_samples/nsut/vpe/vpe_config"
197         vnf_cfg = os.path.join(curr_path, "../../../../..", vpe_cfg)
198         config_create.create_vpe_config(vnf_cfg)
199         os.system("git checkout -- %s" % vnf_cfg)
200
201
202 @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
203 class TestVpeApproxVnf(unittest.TestCase):
204
205     VNFD_0 = {
206         'short-name': 'VpeVnf',
207         'vdu': [
208             {
209                 'routing_table': [
210                     {
211                         'network': '152.16.100.20',
212                         'netmask': '255.255.255.0',
213                         'gateway': '152.16.100.20',
214                         'if': 'xe0',
215                     },
216                     {
217                         'network': '152.16.40.20',
218                         'netmask': '255.255.255.0',
219                         'gateway': '152.16.40.20',
220                         'if': 'xe1',
221                     },
222                 ],
223                 'description': 'VPE approximation using DPDK',
224                 'name': 'vpevnf-baremetal',
225                 'nd_route_tbl': [
226                     {
227                         'network': '0064:ff9b:0:0:0:0:9810:6414',
228                         'netmask': '112',
229                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
230                         'if': 'xe0',
231                     },
232                     {
233                         'network': '0064:ff9b:0:0:0:0:9810:2814',
234                         'netmask': '112',
235                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
236                         'if': 'xe1',
237                     },
238                 ],
239                 'id': 'vpevnf-baremetal',
240                 'external-interface': [
241                     {
242                         'virtual-interface': {
243                             'dst_mac': '00:00:00:00:00:04',
244                             'vpci': '0000:05:00.0',
245                             'local_ip': '152.16.100.19',
246                             'type': 'PCI-PASSTHROUGH',
247                             'vld_id': '',
248                             'netmask': '255.255.255.0',
249                             'dpdk_port_num': '0',
250                             'bandwidth': '10 Gbps',
251                             'driver': "i40e",
252                             'dst_ip': '152.16.100.20',
253                             'local_iface_name': 'xe0',
254                             'local_mac': '00:00:00:00:00:02',
255                         },
256                         'vnfd-connection-point-ref': 'xe0',
257                         'name': 'xe0',
258                     },
259                     {
260                         'virtual-interface': {
261                             'dst_mac': '00:00:00:00:00:03',
262                             'vpci': '0000:05:00.1',
263                             'local_ip': '152.16.40.19',
264                             'type': 'PCI-PASSTHROUGH',
265                             'vld_id': '',
266                             'driver': "i40e",
267                             'netmask': '255.255.255.0',
268                             'dpdk_port_num': '1',
269                             'bandwidth': '10 Gbps',
270                             'dst_ip': '152.16.40.20',
271                             'local_iface_name': 'xe1',
272                             'local_mac': '00:00:00:00:00:01',
273                         },
274                         'vnfd-connection-point-ref': 'xe1',
275                         'name': 'xe1',
276                     },
277                 ],
278             },
279         ],
280         'description': 'Vpe approximation using DPDK',
281         'mgmt-interface': {
282             'vdu-id': 'vpevnf-baremetal',
283             'host': '1.2.1.1',
284             'password': 'r00t',
285             'user': 'root',
286             'ip': '1.2.1.1',
287         },
288         'benchmark': {
289             'kpi': [
290                 'packets_in',
291                 'packets_fwd',
292                 'packets_dropped',
293             ],
294         },
295         'connection-point': [
296             {
297                 'type': 'VPORT',
298                 'name': 'xe0',
299             },
300             {
301                 'type': 'VPORT',
302                 'name': 'xe1',
303             },
304         ],
305         'id': 'VpeApproxVnf',
306         'name': 'VPEVnfSsh',
307     }
308
309     VNFD = {
310         'vnfd:vnfd-catalog': {
311             'vnfd': [
312                 VNFD_0,
313             ],
314         },
315     }
316
317     SCENARIO_CFG = {
318         'options': {
319             'packetsize': 64,
320             'traffic_type': 4 ,
321             'rfc2544': {
322                 'allowed_drop_rate': '0.8 - 1',
323             },
324             'vnf__1': {
325                 'cfg': 'acl_1rule.yaml',
326                 'vnf_config': {
327                     'lb_config': 'SW',
328                     'lb_count': 1,
329                     'worker_config':
330                     '1C/1T',
331                     'worker_threads': 1,
332                 },
333             }
334         },
335         'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
336         'tc': 'tc_ipv4_1Mflow_64B_packetsize',
337         'runner': {
338             'object': 'NetworkServiceTestCase',
339             'interval': 35,
340             'output_filename': '/tmp/yardstick.out',
341             'runner_id': 74476,
342             'duration': 400,
343             'type': 'Duration',
344         },
345         'traffic_profile': 'ipv4_throughput_vpe.yaml',
346         'traffic_options': {
347             'flow': 'ipv4_Packets_vpe.yaml',
348             'imix': 'imix_voice.yaml',
349         },
350         'type': 'ISB',
351         'nodes': {
352             'tg__2': 'trafficgen_2.yardstick',
353             'tg__1': 'trafficgen_1.yardstick',
354             'vnf__1': 'vnf.yardstick',
355         },
356         'topology': 'vpe-tg-topology-baremetal.yaml',
357     }
358
359     CONTEXT_CFG = {
360         'nodes': {
361             'tg__2': {
362                 'member-vnf-index': '3',
363                 'role': 'TrafficGen',
364                 'name': 'trafficgen_2.yardstick',
365                 'vnfd-id-ref': 'tg__2',
366                 'ip': '1.2.1.1',
367                 'interfaces': {
368                     'xe0': {
369                         'local_iface_name': 'ens513f0',
370                         'vld_id': 'public',
371                         'netmask': '255.255.255.0',
372                         'local_ip': '152.16.40.20',
373                         'dst_mac': '00:00:00:00:00:01',
374                         'local_mac': '00:00:00:00:00:03',
375                         'dst_ip': '152.16.40.19',
376                         'driver': 'ixgbe',
377                         'vpci': '0000:02:00.0',
378                         'dpdk_port_num': 0,
379                     },
380                     'xe1': {
381                         'local_iface_name': 'ens513f1',
382                         'netmask': '255.255.255.0',
383                         'network': '202.16.100.0',
384                         'local_ip': '202.16.100.20',
385                         'local_mac': '00:1e:67:d0:60:5d',
386                         'driver': 'ixgbe',
387                         'vpci': '0000:02:00.1',
388                         'dpdk_port_num': 1,
389                     },
390                 },
391                 'password': 'r00t',
392                 'VNF model': 'l3fwd_vnf.yaml',
393                 'user': 'root',
394             },
395             'tg__1': {
396                 'member-vnf-index': '1',
397                 'role': 'TrafficGen',
398                 'name': 'trafficgen_1.yardstick',
399                 'vnfd-id-ref': 'tg__1',
400                 'ip': '1.2.1.1',
401                 'interfaces': {
402                     'xe0': {
403                         'local_iface_name': 'ens785f0',
404                         'vld_id': 'private',
405                         'netmask': '255.255.255.0',
406                         'local_ip': '152.16.100.20',
407                         'dst_mac': '00:00:00:00:00:02',
408                         'local_mac': '00:00:00:00:00:04',
409                         'dst_ip': '152.16.100.19',
410                         'driver': 'i40e',
411                         'vpci': '0000:05:00.0',
412                         'dpdk_port_num': 0,
413                     },
414                     'xe1': {
415                         'local_iface_name': 'ens785f1',
416                         'netmask': '255.255.255.0',
417                         'local_ip': '152.16.100.21',
418                         'local_mac': '00:00:00:00:00:01',
419                         'driver': 'i40e',
420                         'vpci': '0000:05:00.1',
421                         'dpdk_port_num': 1,
422                     },
423                 },
424                 'password': 'r00t',
425                 'VNF model': 'tg_rfc2544_tpl.yaml',
426                 'user': 'root',
427             },
428             'vnf__1': {
429                 'name': 'vnf.yardstick',
430                 'vnfd-id-ref': 'vnf__1',
431                 'ip': '1.2.1.1',
432                 'interfaces': {
433                     'xe0': {
434                         'local_iface_name': 'ens786f0',
435                         'vld_id': 'private',
436                         'netmask': '255.255.255.0',
437                         'local_ip': '152.16.100.19',
438                         'dst_mac': '00:00:00:00:00:04',
439                         'local_mac': '00:00:00:00:00:02',
440                         'dst_ip': '152.16.100.20',
441                         'driver': 'i40e',
442                         'vpci': '0000:05:00.0',
443                         'dpdk_port_num': 0,
444                     },
445                     'xe1': {
446                         'local_iface_name': 'ens786f1',
447                         'vld_id': 'public',
448                         'netmask': '255.255.255.0',
449                         'local_ip': '152.16.40.19',
450                         'dst_mac': '00:00:00:00:00:03',
451                         'local_mac': '00:00:00:00:00:01',
452                         'dst_ip': '152.16.40.20',
453                         'driver': 'i40e',
454                         'vpci': '0000:05:00.1',
455                         'dpdk_port_num': 1,
456                     },
457                 },
458                 'routing_table': [
459                     {
460                         'netmask': '255.255.255.0',
461                         'gateway': '152.16.100.20',
462                         'network': '152.16.100.20',
463                         'if': 'xe0',
464                     },
465                     {
466                         'netmask': '255.255.255.0',
467                         'gateway': '152.16.40.20',
468                         'network': '152.16.40.20',
469                         'if': 'xe1',
470                     },
471                 ],
472                 'member-vnf-index': '2',
473                 'host': '1.2.1.1',
474                 'role': 'vnf',
475                 'user': 'root',
476                 'nd_route_tbl': [
477                     {
478                         'netmask': '112',
479                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
480                         'network': '0064:ff9b:0:0:0:0:9810:6414',
481                         'if': 'xe0',
482                     },
483                     {
484                         'netmask': '112',
485                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
486                         'network': '0064:ff9b:0:0:0:0:9810:2814',
487                         'if': 'xe1',
488                     },
489                 ],
490                 'password': 'r00t',
491                 'VNF model': 'vpe_vnf.yaml',
492             },
493         },
494     }
495
496     def test___init__(self, _):
497         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
498         self.assertIsNone(vpe_approx_vnf._vnf_process)
499
500     @mock.patch(SSH_HELPER)
501     def test_collect_kpi_sa_not_running(self, ssh, _):
502         mock_ssh(ssh)
503
504         resource = mock.Mock(autospec=ResourceProfile)
505         resource.check_if_sa_running.return_value = False, 'error'
506         resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
507
508         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
509         vpe_approx_vnf.q_in = mock.MagicMock()
510         vpe_approx_vnf.q_out = mock.MagicMock()
511         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
512         vpe_approx_vnf.resource_helper.resource = resource
513
514         expected = {
515             'pkt_in_down_stream': 0,
516             'pkt_in_up_stream': 0,
517             'pkt_drop_down_stream': 0,
518             'pkt_drop_up_stream': 0,
519             'collect_stats': {'core': {}},
520         }
521         self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
522
523     @mock.patch(SSH_HELPER)
524     def test_collect_kpi_sa_running(self, ssh, _):
525         mock_ssh(ssh)
526
527         resource = mock.Mock(autospec=ResourceProfile)
528         resource.check_if_sa_running.return_value = True, 'good'
529         resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
530
531         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
532         vpe_approx_vnf.q_in = mock.MagicMock()
533         vpe_approx_vnf.q_out = mock.MagicMock()
534         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
535         vpe_approx_vnf.resource_helper.resource = resource
536
537         expected = {
538             'pkt_in_down_stream': 0,
539             'pkt_in_up_stream': 0,
540             'pkt_drop_down_stream': 0,
541             'pkt_drop_up_stream': 0,
542             'collect_stats': {'core': {'foo': 234}},
543         }
544         self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
545
546     @mock.patch(SSH_HELPER)
547     def test_vnf_execute(self, ssh, _):
548         mock_ssh(ssh)
549         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
550         vpe_approx_vnf.q_in = mock.MagicMock()
551         vpe_approx_vnf.q_out = mock.MagicMock()
552         vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
553         self.assertEqual(vpe_approx_vnf.vnf_execute("quit", 0), '')
554
555     @mock.patch(SSH_HELPER)
556     def test_run_vpe(self, ssh, _):
557         mock_ssh(ssh)
558
559         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
560         vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML)
561         vpe_approx_vnf.generate_port_pairs = mock.Mock()
562         vpe_approx_vnf.tg_port_pairs = [[[0], [1]]]
563         vpe_approx_vnf.vnf_port_pairs = [[[0], [1]]]
564         vpe_approx_vnf.vnf_cfg = {
565             'lb_config': 'SW',
566             'lb_count': 1,
567             'worker_config': '1C/1T',
568             'worker_threads': 1,
569         }
570         vpe_approx_vnf.scenario_helper.scenario_cfg = {
571             'options': {
572                 NAME: {
573                     'traffic_type': '4',
574                     'topology': 'nsb_test_case.yaml',
575                 }
576             }
577         }
578         vpe_approx_vnf.topology = "nsb_test_case.yaml"
579         vpe_approx_vnf.nfvi_type = "baremetal"
580         vpe_approx_vnf._provide_config_file = mock.Mock()
581
582         self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock)
583         self.assertIsNone(vpe_approx_vnf._run())
584
585     @mock.patch(SSH_HELPER)
586     def test_wait_for_instantiate(self, ssh, _):
587         mock_ssh(ssh)
588
589         mock_process = mock.Mock(autospec=Process)
590         mock_process.is_alive.return_value = True
591         mock_process.exitcode = 432
592
593         mock_q_out = mock.Mock(autospec=Queue)
594         mock_q_out.get.side_effect = iter(["pipeline>"])
595         mock_q_out.qsize.side_effect = range(1, -1, -1)
596
597         mock_resource = mock.MagicMock()
598
599         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
600         vpe_approx_vnf._vnf_process = mock_process
601         vpe_approx_vnf.q_out = mock_q_out
602         vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
603         vpe_approx_vnf.resource_helper.resource = mock_resource
604
605         vpe_approx_vnf.q_out.put("pipeline>")
606         self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
607
608     @mock.patch(SSH_HELPER)
609     def test_wait_for_instantiate_fragmented(self, ssh, _):
610         mock_ssh(ssh)
611
612         mock_process = mock.Mock(autospec=Process)
613         mock_process.is_alive.return_value = True
614         mock_process.exitcode = 432
615
616         # test that fragmented pipeline prompt is recognized
617         mock_q_out = mock.Mock(autospec=Queue)
618         mock_q_out.get.side_effect = iter(["wow pipel", "ine>"])
619         mock_q_out.qsize.side_effect = range(2, -1, -1)
620
621         mock_resource = mock.MagicMock()
622
623         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
624         vpe_approx_vnf._vnf_process = mock_process
625         vpe_approx_vnf.q_out = mock_q_out
626         vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
627         vpe_approx_vnf.resource_helper.resource = mock_resource
628
629         self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
630
631     @mock.patch(SSH_HELPER)
632     def test_wait_for_instantiate_crash(self, ssh, _):
633         mock_ssh(ssh, exec_result=(1, "", ""))
634
635         mock_process = mock.Mock(autospec=Process)
636         mock_process.is_alive.return_value = False
637         mock_process.exitcode = 432
638
639         mock_resource = mock.MagicMock()
640
641         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
642         vpe_approx_vnf._vnf_process = mock_process
643         vpe_approx_vnf.resource_helper.resource = mock_resource
644
645         with self.assertRaises(RuntimeError) as raised:
646             vpe_approx_vnf.wait_for_instantiate()
647
648         self.assertIn('VNF process died', str(raised.exception))
649
650     @mock.patch(SSH_HELPER)
651     def test_wait_for_instantiate_panic(self, ssh, _):
652         mock_ssh(ssh, exec_result=(1, "", ""))
653
654         mock_process = mock.Mock(autospec=Process)
655         mock_process.is_alive.return_value = True
656         mock_process.exitcode = 432
657
658         mock_resource = mock.MagicMock()
659
660         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
661         vpe_approx_vnf._vnf_process = mock_process
662         vpe_approx_vnf.resource_helper.resource = mock_resource
663
664         vpe_approx_vnf.q_out.put("PANIC")
665         with self.assertRaises(RuntimeError) as raised:
666             vpe_approx_vnf.wait_for_instantiate()
667
668         self.assertIn('Error starting', str(raised.exception))
669
670     @mock.patch(SSH_HELPER)
671     def test_wait_for_instantiate_panic_fragmented(self, ssh, _):
672         mock_ssh(ssh, exec_result=(1, "", ""))
673
674         mock_process = mock.Mock(autospec=Process)
675         mock_process.is_alive.return_value = True
676         mock_process.exitcode = 432
677
678         # test that fragmented PANIC is recognized
679         mock_q_out = mock.Mock(autospec=Queue)
680         mock_q_out.get.side_effect = iter(["omg PA", "NIC this is bad"])
681         mock_q_out.qsize.side_effect = range(2, -1, -1)
682
683         mock_resource = mock.MagicMock()
684
685         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
686         vpe_approx_vnf._vnf_process = mock_process
687         vpe_approx_vnf.q_out = mock_q_out
688         vpe_approx_vnf.resource_helper.resource = mock_resource
689
690         with self.assertRaises(RuntimeError) as raised:
691             vpe_approx_vnf.wait_for_instantiate()
692
693         self.assertIn('Error starting', str(raised.exception))
694
695     def test_scale(self, _):
696         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
697         with self.assertRaises(NotImplementedError):
698             vpe_approx_vnf.scale('')
699
700     def test_terminate(self, _):
701         vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
702         vpe_approx_vnf.vnf_execute = mock.Mock()
703         vpe_approx_vnf._vnf_process = mock.MagicMock()
704         vpe_approx_vnf._vnf_process.terminate = mock.Mock()
705         vpe_approx_vnf._resource_collect_stop = mock.Mock()
706         vpe_approx_vnf.resource_helper = mock.MagicMock()
707         vpe_approx_vnf.ssh_helper = mock.MagicMock()
708
709         self.assertIsNone(vpe_approx_vnf.terminate())
710
711
712 if __name__ == '__main__':
713     unittest.main()