3 # Copyright (c) 2016-2017 Intel Corporation
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 from __future__ import absolute_import
19 import six.moves.configparser as configparser
24 from multiprocessing import Process, Queue
26 from tests.unit import STL_MOCKS
27 from yardstick.network_services.vnf_generic.vnf.base import QueueFileWrapper
28 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
31 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
33 STLClient = mock.MagicMock()
34 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
38 from yardstick.network_services.vnf_generic.vnf.vpe_vnf import ConfigCreate
39 from yardstick.network_services.nfvi.resource import ResourceProfile
40 from yardstick.network_services.vnf_generic.vnf.vpe_vnf import \
41 VpeApproxVnf, VpeApproxSetupEnvHelper
43 from tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath
44 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
47 TEST_FILE_YAML = 'nsb_test_case.yaml'
51 PING_OUTPUT_1 = "Pkts in: 101\r\n\tPkts dropped by AH: 100\r\n\tPkts dropped by other: 100"
53 MODULE_PATH = FileAbsPath(__file__)
54 get_file_abspath = MODULE_PATH.get_path
57 class TestConfigCreate(unittest.TestCase):
60 'short-name': 'VpeVnf',
65 'network': '152.16.100.20',
66 'netmask': '255.255.255.0',
67 'gateway': '152.16.100.20',
71 'network': '152.16.40.20',
72 'netmask': '255.255.255.0',
73 'gateway': '152.16.40.20',
77 'description': 'VPE approximation using DPDK',
78 'name': 'vpevnf-baremetal',
81 'network': '0064:ff9b:0:0:0:0:9810:6414',
83 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
87 'network': '0064:ff9b:0:0:0:0:9810:2814',
89 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
93 'id': 'vpevnf-baremetal',
94 'external-interface': [
96 'virtual-interface': {
97 'dst_mac': '00:00:00:00:00:03',
98 'vpci': '0000:05:00.0',
99 'local_ip': '152.16.100.19',
100 'type': 'PCI-PASSTHROUGH',
101 'netmask': '255.255.255.0',
103 'bandwidth': '10 Gbps',
104 'dst_ip': '152.16.100.20',
105 'local_mac': '00:00:00:00:00:01',
106 'vld_id': 'uplink_0',
109 'vnfd-connection-point-ref': 'xe0',
113 'virtual-interface': {
114 'dst_mac': '00:00:00:00:00:04',
115 'vpci': '0000:05:00.1',
116 'local_ip': '152.16.40.19',
117 'type': 'PCI-PASSTHROUGH',
118 'netmask': '255.255.255.0',
120 'bandwidth': '10 Gbps',
121 'dst_ip': '152.16.40.20',
122 'local_mac': '00:00:00:00:00:02',
123 'vld_id': 'downlink_0',
126 'vnfd-connection-point-ref': 'xe1',
132 'description': 'Vpe approximation using DPDK',
134 'vdu-id': 'vpevnf-baremetal',
147 'connection-point': [
157 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
160 def test___init__(self):
161 vnfd_helper = VnfdHelper(self.VNFD_0)
162 config_create = ConfigCreate(vnfd_helper, 2)
163 self.assertEqual(config_create.uplink_ports, ['xe0'])
164 self.assertEqual(config_create.downlink_ports, ['xe1'])
165 self.assertEqual(config_create.socket, 2)
167 def test_vpe_initialize(self):
168 vnfd_helper = VnfdHelper(self.VNFD_0)
169 config_create = ConfigCreate(vnfd_helper, 2)
170 config = configparser.ConfigParser()
171 config_create.vpe_initialize(config)
172 self.assertEqual(config.get('EAL', 'log_level'), '0')
173 self.assertEqual(config.get('PIPELINE0', 'type'), 'MASTER')
174 self.assertEqual(config.get('PIPELINE0', 'core'), 's2C0')
175 self.assertEqual(config.get('MEMPOOL0', 'pool_size'), '256K')
176 self.assertEqual(config.get('MEMPOOL1', 'pool_size'), '2M')
178 def test_vpe_rxq(self):
179 vnfd_helper = VnfdHelper(self.VNFD_0)
180 config_create = ConfigCreate(vnfd_helper, 2)
181 config = configparser.ConfigParser()
182 config_create.downlink_ports = ['xe0']
183 config_create.vpe_rxq(config)
184 self.assertEqual(config.get('RXQ0.0', 'mempool'), 'MEMPOOL1')
186 def test_get_sink_swq(self):
187 vnfd_helper = VnfdHelper(self.VNFD_0)
188 config_create = ConfigCreate(vnfd_helper, 2)
189 config = configparser.ConfigParser()
190 config.add_section('PIPELINE0')
191 config.set('PIPELINE0', 'key1', 'value1')
192 config.set('PIPELINE0', 'key2', 'value2 SINK')
193 config.set('PIPELINE0', 'key3', 'TM value3')
194 config.set('PIPELINE0', 'key4', 'value4')
195 config.set('PIPELINE0', 'key5', 'the SINK value5')
197 self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key1', 5), 'SWQ-1')
198 self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key2', 5), 'SWQ-1 SINK0')
199 self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key3', 5), 'SWQ-1 TM5')
200 config_create.sw_q += 1
201 self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key4', 5), 'SWQ0')
202 self.assertEqual(config_create.get_sink_swq(config, 'PIPELINE0', 'key5', 5), 'SWQ0 SINK1')
204 def test_generate_vpe_script(self):
205 vnfd_helper = VnfdHelper(self.VNFD_0)
206 vpe_config_vnf = ConfigCreate(vnfd_helper, 2)
210 "virtual-interface": {
212 "dst_mac": "00:00:00:00:00:00:02",
217 "virtual-interface": {
219 "dst_mac": "00:00:00:00:00:00:02",
223 vpe_config_vnf.downlink_ports = ['xe1']
224 vpe_config_vnf.uplink_ports = ['xe2']
225 result = vpe_config_vnf.generate_vpe_script(intf)
226 self.assertIsInstance(result, str)
227 self.assertNotEqual(result, '')
229 def test_create_vpe_config(self):
252 vnfd_helper = VnfdHelper(self.VNFD_0)
253 config_create = ConfigCreate(vnfd_helper, 23)
254 config_create.downlink_ports = ['xe1']
255 config_create.uplink_ports = ['xe1']
256 curr_path = os.path.dirname(os.path.abspath(__file__))
257 vpe_cfg = "samples/vnf_samples/nsut/vpe/vpe_config"
258 vnf_cfg = os.path.join(curr_path, "../../../../..", vpe_cfg)
259 config_create.create_vpe_config(vnf_cfg)
260 os.system("git checkout -- %s" % vnf_cfg)
263 @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
264 class TestVpeApproxVnf(unittest.TestCase):
267 'short-name': 'VpeVnf',
272 'network': '152.16.100.20',
273 'netmask': '255.255.255.0',
274 'gateway': '152.16.100.20',
278 'network': '152.16.40.20',
279 'netmask': '255.255.255.0',
280 'gateway': '152.16.40.20',
284 'description': 'VPE approximation using DPDK',
285 'name': 'vpevnf-baremetal',
288 'network': '0064:ff9b:0:0:0:0:9810:6414',
290 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
294 'network': '0064:ff9b:0:0:0:0:9810:2814',
296 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
300 'id': 'vpevnf-baremetal',
301 'external-interface': [
303 'virtual-interface': {
304 'dst_mac': '00:00:00:00:00:04',
305 'vpci': '0000:05:00.0',
306 'local_ip': '152.16.100.19',
307 'type': 'PCI-PASSTHROUGH',
308 'netmask': '255.255.255.0',
310 'bandwidth': '10 Gbps',
312 'dst_ip': '152.16.100.20',
313 'local_iface_name': 'xe0',
314 'local_mac': '00:00:00:00:00:02',
315 'vld_id': 'uplink_0',
318 'vnfd-connection-point-ref': 'xe0',
322 'virtual-interface': {
323 'dst_mac': '00:00:00:00:00:03',
324 'vpci': '0000:05:00.1',
325 'local_ip': '152.16.40.19',
326 'type': 'PCI-PASSTHROUGH',
328 'netmask': '255.255.255.0',
330 'bandwidth': '10 Gbps',
331 'dst_ip': '152.16.40.20',
332 'local_iface_name': 'xe1',
333 'local_mac': '00:00:00:00:00:01',
334 'vld_id': 'downlink_0',
337 'vnfd-connection-point-ref': 'xe1',
343 'description': 'Vpe approximation using DPDK',
345 'vdu-id': 'vpevnf-baremetal',
358 'connection-point': [
368 'id': 'VpeApproxVnf',
373 'vnfd:vnfd-catalog': {
385 'allowed_drop_rate': '0.8 - 1',
388 'cfg': 'acl_1rule.yaml',
398 'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
399 'tc': 'tc_ipv4_1Mflow_64B_packetsize',
401 'object': 'NetworkServiceTestCase',
403 'output_filename': '/tmp/yardstick.out',
408 'traffic_profile': 'ipv4_throughput_vpe.yaml',
410 'flow': 'ipv4_Packets_vpe.yaml',
411 'imix': 'imix_voice.yaml',
415 'tg__2': 'trafficgen_2.yardstick',
416 'tg__1': 'trafficgen_1.yardstick',
417 'vnf__1': 'vnf.yardstick',
419 'topology': 'vpe-tg-topology-baremetal.yaml',
425 'member-vnf-index': '3',
426 'role': 'TrafficGen',
427 'name': 'trafficgen_2.yardstick',
428 'vnfd-id-ref': 'tg__2',
432 'local_iface_name': 'ens513f0',
433 'vld_id': VpeApproxVnf.DOWNLINK,
434 'netmask': '255.255.255.0',
435 'local_ip': '152.16.40.20',
436 'dst_mac': '00:00:00:00:00:01',
437 'local_mac': '00:00:00:00:00:03',
438 'dst_ip': '152.16.40.19',
440 'vpci': '0000:02:00.0',
444 'local_iface_name': 'ens513f1',
445 'netmask': '255.255.255.0',
446 'network': '202.16.100.0',
447 'local_ip': '202.16.100.20',
448 'local_mac': '00:1e:67:d0:60:5d',
450 'vpci': '0000:02:00.1',
455 'VNF model': 'l3fwd_vnf.yaml',
459 'member-vnf-index': '1',
460 'role': 'TrafficGen',
461 'name': 'trafficgen_1.yardstick',
462 'vnfd-id-ref': 'tg__1',
466 'local_iface_name': 'ens785f0',
467 'vld_id': VpeApproxVnf.UPLINK,
468 'netmask': '255.255.255.0',
469 'local_ip': '152.16.100.20',
470 'dst_mac': '00:00:00:00:00:02',
471 'local_mac': '00:00:00:00:00:04',
472 'dst_ip': '152.16.100.19',
474 'vpci': '0000:05:00.0',
478 'local_iface_name': 'ens785f1',
479 'netmask': '255.255.255.0',
480 'local_ip': '152.16.100.21',
481 'local_mac': '00:00:00:00:00:01',
483 'vpci': '0000:05:00.1',
488 'VNF model': 'tg_rfc2544_tpl.yaml',
492 'name': 'vnf.yardstick',
493 'vnfd-id-ref': 'vnf__1',
497 'local_iface_name': 'ens786f0',
498 'vld_id': VpeApproxVnf.UPLINK,
499 'netmask': '255.255.255.0',
500 'local_ip': '152.16.100.19',
501 'dst_mac': '00:00:00:00:00:04',
502 'local_mac': '00:00:00:00:00:02',
503 'dst_ip': '152.16.100.20',
505 'vpci': '0000:05:00.0',
509 'local_iface_name': 'ens786f1',
510 'vld_id': VpeApproxVnf.DOWNLINK,
511 'netmask': '255.255.255.0',
512 'local_ip': '152.16.40.19',
513 'dst_mac': '00:00:00:00:00:03',
514 'local_mac': '00:00:00:00:00:01',
515 'dst_ip': '152.16.40.20',
517 'vpci': '0000:05:00.1',
523 'netmask': '255.255.255.0',
524 'gateway': '152.16.100.20',
525 'network': '152.16.100.20',
529 'netmask': '255.255.255.0',
530 'gateway': '152.16.40.20',
531 'network': '152.16.40.20',
535 'member-vnf-index': '2',
542 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
543 'network': '0064:ff9b:0:0:0:0:9810:6414',
548 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
549 'network': '0064:ff9b:0:0:0:0:9810:2814',
554 'VNF model': 'vpe_vnf.yaml',
559 def test___init__(self, _):
560 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
561 self.assertIsNone(vpe_approx_vnf._vnf_process)
563 @mock.patch(SSH_HELPER)
564 def test_collect_kpi_sa_not_running(self, ssh, _):
567 resource = mock.Mock(autospec=ResourceProfile)
568 resource.check_if_sa_running.return_value = 1, ''
569 resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
570 resource.check_if_sa_running.return_value = (1, None)
572 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
573 vpe_approx_vnf.q_in = mock.MagicMock()
574 vpe_approx_vnf.q_out = mock.MagicMock()
575 vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
576 vpe_approx_vnf.resource_helper.resource = resource
579 'pkt_in_down_stream': 0,
580 'pkt_in_up_stream': 0,
581 'pkt_drop_down_stream': 0,
582 'pkt_drop_up_stream': 0,
583 'collect_stats': {'core': {}},
585 self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
587 @mock.patch(SSH_HELPER)
588 def test_collect_kpi_sa_running(self, ssh, _):
591 resource = mock.Mock(autospec=ResourceProfile)
592 resource.check_if_sa_running.return_value = 0, '1234'
593 resource.amqp_collect_nfvi_kpi.return_value = {'foo': 234}
595 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
596 vpe_approx_vnf.q_in = mock.MagicMock()
597 vpe_approx_vnf.q_out = mock.MagicMock()
598 vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
599 vpe_approx_vnf.resource_helper.resource = resource
602 'pkt_in_down_stream': 0,
603 'pkt_in_up_stream': 0,
604 'pkt_drop_down_stream': 0,
605 'pkt_drop_up_stream': 0,
606 'collect_stats': {'core': {'foo': 234}},
608 self.assertEqual(vpe_approx_vnf.collect_kpi(), expected)
610 @mock.patch(SSH_HELPER)
611 def test_vnf_execute(self, ssh, _):
613 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
614 vpe_approx_vnf.q_in = mock.MagicMock()
615 vpe_approx_vnf.q_out = mock.MagicMock()
616 vpe_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
617 self.assertEqual(vpe_approx_vnf.vnf_execute("quit", 0), '')
619 @mock.patch(SSH_HELPER)
620 def test_run_vpe(self, ssh, _):
623 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
624 vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML)
625 vpe_approx_vnf.vnf_cfg = {
628 'worker_config': '1C/1T',
631 vpe_approx_vnf.scenario_helper.scenario_cfg = {
635 'topology': 'nsb_test_case.yaml',
636 'vnf_config': 'vpe_config',
640 vpe_approx_vnf.topology = "nsb_test_case.yaml"
641 vpe_approx_vnf.nfvi_type = "baremetal"
642 vpe_approx_vnf._provide_config_file = mock.Mock()
643 vpe_approx_vnf._build_config = mock.MagicMock()
645 self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock)
646 self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock)
647 self.assertIsNone(vpe_approx_vnf._run())
649 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig")
650 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
651 @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.ConfigCreate")
652 @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.open")
653 @mock.patch(SSH_HELPER)
654 def test_build_config(self, mock_mul, mock_context, mock_config, mock_open, ssh, _):
656 vpe_approx_vnf = VpeApproxSetupEnvHelper(mock.MagicMock(),
657 mock.MagicMock, mock.MagicMock)
658 vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML)
659 vpe_approx_vnf.generate_port_pairs = mock.Mock()
660 vpe_approx_vnf.vnf_cfg = {
663 'worker_config': '1C/1T',
666 vpe_approx_vnf.scenario_helper.scenario_cfg = {
670 'topology': 'nsb_test_case.yaml',
671 'vnf_config': 'vpe_config',
675 vpe_approx_vnf.topology = "nsb_test_case.yaml"
676 vpe_approx_vnf.nfvi_type = "baremetal"
677 vpe_approx_vnf._provide_config_file = mock.Mock()
679 vpe_approx_vnf.ssh_helper = mock.MagicMock()
680 vpe_approx_vnf.scenario_helper = mock.MagicMock()
681 vpe_approx_vnf.ssh_helper.bin_path = mock.Mock()
682 vpe_approx_vnf.ssh_helper.upload_config_file = mock.MagicMock()
683 self.assertIsNone(vpe_approx_vnf._build_vnf_ports())
684 self.assertIsNotNone(vpe_approx_vnf.build_config())
686 @mock.patch(SSH_HELPER)
687 def test_wait_for_instantiate(self, ssh, _):
690 mock_process = mock.Mock(autospec=Process)
691 mock_process.is_alive.return_value = True
692 mock_process.exitcode = 432
694 mock_q_out = mock.Mock(autospec=Queue)
695 mock_q_out.get.side_effect = iter(["pipeline>"])
696 mock_q_out.qsize.side_effect = range(1, -1, -1)
698 mock_resource = mock.MagicMock()
700 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
701 vpe_approx_vnf._vnf_process = mock_process
702 vpe_approx_vnf.q_out = mock_q_out
703 vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
704 vpe_approx_vnf.resource_helper.resource = mock_resource
706 vpe_approx_vnf.q_out.put("pipeline>")
707 self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
709 @mock.patch(SSH_HELPER)
710 def test_wait_for_instantiate_fragmented(self, ssh, _):
713 mock_process = mock.Mock(autospec=Process)
714 mock_process.is_alive.return_value = True
715 mock_process.exitcode = 432
717 # test that fragmented pipeline prompt is recognized
718 mock_q_out = mock.Mock(autospec=Queue)
719 mock_q_out.get.side_effect = iter(["wow pipel", "ine>"])
720 mock_q_out.qsize.side_effect = range(2, -1, -1)
722 mock_resource = mock.MagicMock()
724 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
725 vpe_approx_vnf._vnf_process = mock_process
726 vpe_approx_vnf.q_out = mock_q_out
727 vpe_approx_vnf.queue_wrapper = mock.Mock(autospec=QueueFileWrapper)
728 vpe_approx_vnf.resource_helper.resource = mock_resource
730 self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432)
732 @mock.patch(SSH_HELPER)
733 def test_wait_for_instantiate_crash(self, ssh, _):
734 mock_ssh(ssh, exec_result=(1, "", ""))
736 mock_process = mock.Mock(autospec=Process)
737 mock_process.is_alive.return_value = False
738 mock_process.exitcode = 432
740 mock_resource = mock.MagicMock()
742 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
743 vpe_approx_vnf._vnf_process = mock_process
744 vpe_approx_vnf.resource_helper.resource = mock_resource
746 with self.assertRaises(RuntimeError) as raised:
747 vpe_approx_vnf.wait_for_instantiate()
749 self.assertIn('VNF process died', str(raised.exception))
751 @mock.patch(SSH_HELPER)
752 def test_wait_for_instantiate_panic(self, ssh, _):
753 mock_ssh(ssh, exec_result=(1, "", ""))
755 mock_process = mock.Mock(autospec=Process)
756 mock_process.is_alive.return_value = True
757 mock_process.exitcode = 432
759 mock_resource = mock.MagicMock()
761 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
762 vpe_approx_vnf._vnf_process = mock_process
763 vpe_approx_vnf.resource_helper.resource = mock_resource
765 vpe_approx_vnf.q_out.put("PANIC")
766 with self.assertRaises(RuntimeError) as raised:
767 vpe_approx_vnf.wait_for_instantiate()
769 self.assertIn('Error starting', str(raised.exception))
771 @mock.patch(SSH_HELPER)
772 def test_wait_for_instantiate_panic_fragmented(self, ssh, _):
773 mock_ssh(ssh, exec_result=(1, "", ""))
775 mock_process = mock.Mock(autospec=Process)
776 mock_process.is_alive.return_value = True
777 mock_process.exitcode = 432
779 # test that fragmented PANIC is recognized
780 mock_q_out = mock.Mock(autospec=Queue)
781 mock_q_out.get.side_effect = iter(["omg PA", "NIC this is bad"])
782 mock_q_out.qsize.side_effect = range(2, -1, -1)
784 mock_resource = mock.MagicMock()
786 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
787 vpe_approx_vnf._vnf_process = mock_process
788 vpe_approx_vnf.q_out = mock_q_out
789 vpe_approx_vnf.resource_helper.resource = mock_resource
791 with self.assertRaises(RuntimeError) as raised:
792 vpe_approx_vnf.wait_for_instantiate()
794 self.assertIn('Error starting', str(raised.exception))
796 def test_scale(self, _):
797 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
798 with self.assertRaises(NotImplementedError):
799 vpe_approx_vnf.scale('')
801 @mock.patch(SSH_HELPER)
802 def test_terminate(self, ssh, _):
805 vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0)
806 vpe_approx_vnf._vnf_process = mock.MagicMock()
807 vpe_approx_vnf._resource_collect_stop = mock.Mock()
808 vpe_approx_vnf.resource_helper = mock.MagicMock()
810 self.assertIsNone(vpe_approx_vnf.terminate())
813 if __name__ == '__main__':