1 # Copyright (c) 2017-2019 Intel Corporation
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 from copy import deepcopy
25 from yardstick.common import exceptions as y_exceptions
26 from yardstick.common import utils
27 from yardstick.network_services.nfvi import resource
28 from yardstick.network_services.vnf_generic.vnf import base
29 from yardstick.network_services.vnf_generic.vnf import sample_vnf
30 from yardstick.network_services.vnf_generic.vnf import vnf_ssh_helper
31 from yardstick import ssh
32 from yardstick.tests.unit.network_services.vnf_generic.vnf import test_base
33 from yardstick.benchmark.contexts import base as ctx_base
36 class MockError(Exception):
40 class TestVnfSshHelper(unittest.TestCase):
43 'short-name': 'VpeVnf',
48 'network': '152.16.100.20',
49 'netmask': '255.255.255.0',
50 'gateway': '152.16.100.20',
54 'network': '152.16.40.20',
55 'netmask': '255.255.255.0',
56 'gateway': '152.16.40.20',
60 'description': 'VPE approximation using DPDK',
61 'name': 'vpevnf-baremetal',
64 'network': '0064:ff9b:0:0:0:0:9810:6414',
66 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
70 'network': '0064:ff9b:0:0:0:0:9810:2814',
72 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
76 'id': 'vpevnf-baremetal',
77 'external-interface': [
79 'virtual-interface': {
80 'dst_mac': '00:00:00:00:00:03',
81 'vpci': '0000:05:00.0',
84 'local_ip': '152.16.100.19',
85 'type': 'PCI-PASSTHROUGH',
86 'netmask': '255.255.255.0',
87 'bandwidth': '10 Gbps',
88 'dst_ip': '152.16.100.20',
89 'local_mac': '00:00:00:00:00:01',
93 'vnfd-connection-point-ref': 'xe0',
97 'virtual-interface': {
98 'dst_mac': '00:00:00:00:00:04',
99 'vpci': '0000:05:00.1',
102 'local_ip': '152.16.40.19',
103 'type': 'PCI-PASSTHROUGH',
104 'netmask': '255.255.255.0',
105 'bandwidth': '10 Gbps',
106 'dst_ip': '152.16.40.20',
107 'local_mac': '00:00:00:00:00:02',
108 'vld_id': 'downlink_0',
111 'vnfd-connection-point-ref': 'xe1',
117 'description': 'Vpe approximation using DPDK',
119 'vdu-id': 'vpevnf-baremetal',
132 'connection-point': [
142 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
146 'vnfd:vnfd-catalog': {
154 self.ssh_helper = vnf_ssh_helper.VnfSshHelper(
155 self.VNFD_0['mgmt-interface'], 'my/bin/path')
156 self.ssh_helper._run = mock.Mock()
158 def assertAll(self, iterable, message=None):
159 self.assertTrue(all(iterable), message)
161 def test_get_class(self):
162 self.assertIs(vnf_ssh_helper.VnfSshHelper.get_class(),
163 vnf_ssh_helper.VnfSshHelper)
165 @mock.patch.object(ssh, 'paramiko')
166 def test_copy(self, _):
167 self.ssh_helper.execute('ls')
168 self.assertTrue(self.ssh_helper.is_connected)
169 result = self.ssh_helper.copy()
170 self.assertIsInstance(result, vnf_ssh_helper.VnfSshHelper)
171 self.assertFalse(result.is_connected)
172 self.assertEqual(result.bin_path, self.ssh_helper.bin_path)
173 self.assertEqual(result.host, self.ssh_helper.host)
174 self.assertEqual(result.port, self.ssh_helper.port)
175 self.assertEqual(result.user, self.ssh_helper.user)
176 self.assertEqual(result.password, self.ssh_helper.password)
177 self.assertEqual(result.key_filename, self.ssh_helper.key_filename)
179 @mock.patch.object(paramiko, 'SSHClient')
180 def test_upload_config_file(self, mock_paramiko):
181 self.assertFalse(self.ssh_helper.is_connected)
182 cfg_file = self.ssh_helper.upload_config_file('/my/prefix', 'my content')
183 self.assertTrue(self.ssh_helper.is_connected)
184 mock_paramiko.assert_called_once()
185 self.assertEqual(cfg_file, '/my/prefix')
187 @mock.patch.object(paramiko, 'SSHClient')
188 def test_upload_config_file_path_does_not_exist(self, mock_paramiko):
189 self.assertFalse(self.ssh_helper.is_connected)
190 cfg_file = self.ssh_helper.upload_config_file('my/prefix', 'my content')
191 self.assertTrue(self.ssh_helper.is_connected)
192 mock_paramiko.assert_called_once()
193 self.assertTrue(cfg_file.startswith('/tmp'))
195 def test_join_bin_path(self):
196 expected_start = 'my'
197 expected_middle_list = ['bin']
198 expected_end = 'path'
199 result = self.ssh_helper.join_bin_path()
200 self.assertTrue(result.startswith(expected_start))
201 self.assertAll(middle in result for middle in expected_middle_list)
202 self.assertTrue(result.endswith(expected_end))
204 expected_middle_list.append(expected_end)
205 expected_end = 'some_file.sh'
206 result = self.ssh_helper.join_bin_path('some_file.sh')
207 self.assertTrue(result.startswith(expected_start))
208 self.assertAll(middle in result for middle in expected_middle_list)
209 self.assertTrue(result.endswith(expected_end))
211 expected_middle_list.append('some_dir')
212 expected_end = 'some_file.sh'
213 result = self.ssh_helper.join_bin_path('some_dir', 'some_file.sh')
214 self.assertTrue(result.startswith(expected_start))
215 self.assertAll(middle in result for middle in expected_middle_list)
216 self.assertTrue(result.endswith(expected_end))
218 @mock.patch.object(paramiko, 'SSHClient')
219 @mock.patch.object(ssh, 'provision_tool')
220 def test_provision_tool(self, mock_provision_tool, mock_paramiko):
221 self.assertFalse(self.ssh_helper.is_connected)
222 self.ssh_helper.provision_tool()
223 self.assertTrue(self.ssh_helper.is_connected)
224 mock_paramiko.assert_called_once()
225 mock_provision_tool.assert_called_once()
227 self.ssh_helper.provision_tool(tool_file='my_tool.sh')
228 self.assertTrue(self.ssh_helper.is_connected)
229 mock_paramiko.assert_called_once()
230 self.assertEqual(mock_provision_tool.call_count, 2)
232 self.ssh_helper.provision_tool('tool_path', 'my_tool.sh')
233 self.assertTrue(self.ssh_helper.is_connected)
234 mock_paramiko.assert_called_once()
235 self.assertEqual(mock_provision_tool.call_count, 3)
238 class TestSetupEnvHelper(unittest.TestCase):
240 VNFD_0 = TestVnfSshHelper.VNFD_0
243 self.setup_env_helper = sample_vnf.SetupEnvHelper(
244 mock.Mock(), mock.Mock(), mock.Mock())
246 def test_build_config(self):
247 with self.assertRaises(NotImplementedError):
248 self.setup_env_helper.build_config()
250 def test_setup_vnf_environment(self):
251 self.assertIsNone(self.setup_env_helper.setup_vnf_environment())
253 def test_tear_down(self):
254 with self.assertRaises(NotImplementedError):
255 self.setup_env_helper.tear_down()
258 class TestDpdkVnfSetupEnvHelper(unittest.TestCase):
260 VNFD_0 = TestVnfSshHelper.VNFD_0
262 VNFD = TestVnfSshHelper.VNFD
265 self.vnfd_helper = base.VnfdHelper(deepcopy(self.VNFD_0))
266 self.scenario_helper = mock.Mock()
267 self.ssh_helper = mock.Mock()
268 self.dpdk_setup_helper = sample_vnf.DpdkVnfSetupEnvHelper(
269 self.vnfd_helper, self.ssh_helper, self.scenario_helper)
271 def test__update_packet_type(self):
272 ip_pipeline_cfg = 'pkt_type = ipv4'
273 pkt_type = {'pkt_type': '1'}
275 expected = "pkt_type = 1"
276 result = self.dpdk_setup_helper._update_packet_type(
277 ip_pipeline_cfg, pkt_type)
278 self.assertEqual(result, expected)
280 def test__update_packet_type_no_op(self):
281 ip_pipeline_cfg = 'pkt_type = ipv6'
282 pkt_type = {'pkt_type': '1'}
284 expected = "pkt_type = ipv6"
285 result = self.dpdk_setup_helper._update_packet_type(
286 ip_pipeline_cfg, pkt_type)
287 self.assertEqual(result, expected)
289 def test__update_packet_type_multi_op(self):
290 ip_pipeline_cfg = 'pkt_type = ipv4\npkt_type = 1\npkt_type = ipv4'
291 pkt_type = {'pkt_type': '1'}
292 expected = 'pkt_type = 1\npkt_type = 1\npkt_type = 1'
294 result = self.dpdk_setup_helper._update_packet_type(
295 ip_pipeline_cfg, pkt_type)
296 self.assertEqual(result, expected)
298 def test__update_traffic_type(self):
299 ip_pipeline_cfg = 'pkt_type = ipv4'
301 "vnf_type": sample_vnf.DpdkVnfSetupEnvHelper.APP_NAME,
303 expected = "pkt_type = ipv4"
305 result = self.dpdk_setup_helper._update_traffic_type(
306 ip_pipeline_cfg, traffic_options)
307 self.assertEqual(result, expected)
309 def test__update_traffic_type_ipv6(self):
310 ip_pipeline_cfg = 'pkt_type = ipv4'
312 "vnf_type": sample_vnf.DpdkVnfSetupEnvHelper.APP_NAME,
314 expected = "pkt_type = ipv6"
316 result = self.dpdk_setup_helper._update_traffic_type(
317 ip_pipeline_cfg, traffic_options)
318 self.assertEqual(result, expected)
320 def test__update_traffic_type_not_app_name(self):
321 ip_pipeline_cfg = 'traffic_type = 4'
322 vnf_type = ''.join(["Not", sample_vnf.DpdkVnfSetupEnvHelper.APP_NAME])
323 traffic_options = {"vnf_type": vnf_type, 'traffic_type': 8}
324 expected = "traffic_type = 8"
326 result = self.dpdk_setup_helper._update_traffic_type(
327 ip_pipeline_cfg, traffic_options)
328 self.assertEqual(result, expected)
330 @mock.patch.object(six.moves.builtins, 'open')
331 @mock.patch.object(utils, 'find_relative_file')
332 @mock.patch.object(sample_vnf, 'MultiPortConfig')
333 def test_build_config(self, mock_multi_port_config_class,
335 mock_multi_port_config = mock_multi_port_config_class()
336 self.scenario_helper.vnf_cfg = {}
337 self.scenario_helper.options = {}
338 self.scenario_helper.all_options = {}
340 self.dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
341 result = self.dpdk_setup_helper.build_config()
342 self.assertEqual(result, expected)
343 self.assertGreaterEqual(self.ssh_helper.upload_config_file.call_count, 2)
344 mock_find.assert_called()
345 mock_multi_port_config.generate_config.assert_called()
346 mock_multi_port_config.generate_script.assert_called()
348 @mock.patch.object(six.moves.builtins, 'open')
349 @mock.patch.object(utils, 'find_relative_file')
350 @mock.patch.object(sample_vnf, 'MultiPortConfig')
351 @mock.patch.object(utils, 'open_relative_file')
352 def test_build_config2(self, mock_open_rf, mock_multi_port_config_class,
354 mock_multi_port_config = mock_multi_port_config_class()
355 self.scenario_helper.options = {'rules': 'fake_file'}
356 self.scenario_helper.vnf_cfg = {'file': 'fake_file'}
357 self.scenario_helper.all_options = {}
358 mock_open_rf.side_effect = mock.mock_open(read_data='fake_data')
359 self.dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
361 result = self.dpdk_setup_helper.build_config()
363 mock_open_rf.assert_called()
364 self.assertEqual(result, expected)
365 self.assertGreaterEqual(self.ssh_helper.upload_config_file.call_count, 2)
366 mock_find.assert_called()
367 mock_multi_port_config.generate_config.assert_called()
368 mock_multi_port_config.generate_script.assert_called()
370 def test__build_pipeline_kwargs(self):
371 self.ssh_helper.provision_tool.return_value = 'tool_path'
372 self.dpdk_setup_helper.CFG_CONFIG = 'config'
373 self.dpdk_setup_helper.CFG_SCRIPT = 'script'
374 self.dpdk_setup_helper.pipeline_kwargs = {}
375 self.dpdk_setup_helper.all_ports = [0, 1, 2]
376 self.dpdk_setup_helper.scenario_helper.vnf_cfg = {'lb_config': 'HW',
380 'cfg_file': 'config',
382 'port_mask_hex': '0x3',
383 'tool_path': 'tool_path',
386 self.dpdk_setup_helper._build_pipeline_kwargs()
387 self.assertDictEqual(self.dpdk_setup_helper.pipeline_kwargs, expected)
389 @mock.patch.object(time, 'sleep')
390 @mock.patch.object(ssh, 'SSH')
391 def test_setup_vnf_environment(self, *args):
392 self.scenario_helper.nodes = [None, None]
395 if cmd.startswith('which '):
399 exec_success = (0, 'good output', '')
400 exec_failure = (1, 'bad output', 'error output')
401 self.ssh_helper.execute = execute
403 self.dpdk_setup_helper._validate_cpu_cfg = mock.Mock(return_value=[])
405 with mock.patch.object(self.dpdk_setup_helper, '_setup_dpdk'):
406 self.assertIsInstance(
407 self.dpdk_setup_helper.setup_vnf_environment(),
408 resource.ResourceProfile)
410 @mock.patch.object(utils, 'setup_hugepages')
411 def test__setup_dpdk(self, mock_setup_hugepages):
412 self.ssh_helper.execute = mock.Mock()
413 self.ssh_helper.execute.return_value = (0, 0, 0)
414 self.scenario_helper.all_options = {'hugepages_gb': 8}
415 self.dpdk_setup_helper._setup_dpdk()
416 mock_setup_hugepages.assert_called_once_with(
417 self.ssh_helper, 8*1024*1024)
418 self.ssh_helper.execute.assert_has_calls([
419 mock.call('sudo modprobe uio && sudo modprobe igb_uio'),
420 mock.call('lsmod | grep -i igb_uio')
423 @mock.patch.object(ssh, 'SSH')
424 def test__setup_resources(self, _):
425 self.dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
426 self.dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
427 self.vnfd_helper.interfaces]
428 result = self.dpdk_setup_helper._setup_resources()
429 self.assertIsInstance(result, resource.ResourceProfile)
430 self.assertEqual(self.dpdk_setup_helper.socket, 0)
432 @mock.patch.object(ssh, 'SSH')
433 def test__setup_resources_socket_1(self, _):
434 self.vnfd_helper.interfaces[0]['virtual-interface']['vpci'] = \
436 self.vnfd_helper.interfaces[1]['virtual-interface']['vpci'] = \
439 self.dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
440 self.dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
441 self.vnfd_helper.interfaces]
442 result = self.dpdk_setup_helper._setup_resources()
443 self.assertIsInstance(result, resource.ResourceProfile)
444 self.assertEqual(self.dpdk_setup_helper.socket, 1)
446 @mock.patch.object(time, 'sleep')
447 def test__detect_and_bind_drivers(self, *args):
448 self.scenario_helper.nodes = [None, None]
449 rv = ['0000:05:00.1', '0000:05:00.0']
451 self.dpdk_setup_helper.dpdk_bind_helper._get_bound_pci_addresses = \
452 mock.Mock(return_value=rv)
453 self.dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
454 self.dpdk_setup_helper.dpdk_bind_helper.read_status = mock.Mock()
456 self.assertIsNone(self.dpdk_setup_helper._detect_and_bind_drivers())
458 intf_0 = self.vnfd_helper.vdu[0]['external-interface'][0]['virtual-interface']
459 intf_1 = self.vnfd_helper.vdu[0]['external-interface'][1]['virtual-interface']
460 self.assertEqual(0, intf_0['dpdk_port_num'])
461 self.assertEqual(1, intf_1['dpdk_port_num'])
463 def test_tear_down(self):
464 self.scenario_helper.nodes = [None, None]
466 self.dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
467 self.dpdk_setup_helper.dpdk_bind_helper.used_drivers = {
468 'd1': ['0000:05:00.0'],
469 'd3': ['0000:05:01.0'],
472 self.assertIsNone(self.dpdk_setup_helper.tear_down())
473 self.dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(
474 ['0000:05:00.0'], 'd1', True)
475 self.dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(
476 ['0000:05:01.0'], 'd3', True)
479 class TestResourceHelper(unittest.TestCase):
482 'short-name': 'VpeVnf',
487 'network': '152.16.100.20',
488 'netmask': '255.255.255.0',
489 'gateway': '152.16.100.20',
493 'network': '152.16.40.20',
494 'netmask': '255.255.255.0',
495 'gateway': '152.16.40.20',
499 'description': 'VPE approximation using DPDK',
500 'name': 'vpevnf-baremetal',
503 'network': '0064:ff9b:0:0:0:0:9810:6414',
505 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
509 'network': '0064:ff9b:0:0:0:0:9810:2814',
511 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
515 'id': 'vpevnf-baremetal',
516 'external-interface': [
518 'virtual-interface': {
519 'dst_mac': '00:00:00:00:00:03',
520 'vpci': '0000:05:00.0',
522 'local_ip': '152.16.100.19',
523 'type': 'PCI-PASSTHROUGH',
524 'netmask': '255.255.255.0',
526 'bandwidth': '10 Gbps',
527 'dst_ip': '152.16.100.20',
528 'local_mac': '00:00:00:00:00:01'
530 'vnfd-connection-point-ref': 'xe0',
534 'virtual-interface': {
535 'dst_mac': '00:00:00:00:00:04',
536 'vpci': '0000:05:00.1',
538 'local_ip': '152.16.40.19',
539 'type': 'PCI-PASSTHROUGH',
540 'netmask': '255.255.255.0',
542 'bandwidth': '10 Gbps',
543 'dst_ip': '152.16.40.20',
544 'local_mac': '00:00:00:00:00:02'
546 'vnfd-connection-point-ref': 'xe1',
552 'description': 'Vpe approximation using DPDK',
554 'vdu-id': 'vpevnf-baremetal',
567 'connection-point': [
577 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
581 self.vnfd_helper = base.VnfdHelper(self.VNFD_0)
582 self.dpdk_setup_helper = sample_vnf.DpdkVnfSetupEnvHelper(
583 self.vnfd_helper, mock.Mock(), mock.Mock())
584 self.resource_helper = sample_vnf.ResourceHelper(self.dpdk_setup_helper)
586 def test_setup(self):
588 self.dpdk_setup_helper.setup_vnf_environment = (
589 mock.Mock(return_value=resource))
590 resource_helper = sample_vnf.ResourceHelper(self.dpdk_setup_helper)
592 self.assertIsNone(resource_helper.setup())
593 self.assertIs(resource_helper.resource, resource)
595 def test_generate_cfg(self):
596 self.assertIsNone(self.resource_helper.generate_cfg())
598 def test_stop_collect(self):
599 self.resource_helper.resource = mock.Mock()
601 self.assertIsNone(self.resource_helper.stop_collect())
603 def test_stop_collect_none(self):
604 self.resource_helper.resource = None
606 self.assertIsNone(self.resource_helper.stop_collect())
609 class TestClientResourceHelper(unittest.TestCase):
612 'short-name': 'VpeVnf',
617 'network': '152.16.100.20',
618 'netmask': '255.255.255.0',
619 'gateway': '152.16.100.20',
623 'network': '152.16.40.20',
624 'netmask': '255.255.255.0',
625 'gateway': '152.16.40.20',
629 'description': 'VPE approximation using DPDK',
630 'name': 'vpevnf-baremetal',
633 'network': '0064:ff9b:0:0:0:0:9810:6414',
635 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
639 'network': '0064:ff9b:0:0:0:0:9810:2814',
641 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
645 'id': 'vpevnf-baremetal',
646 'external-interface': [
648 'virtual-interface': {
649 'dst_mac': '00:00:00:00:00:03',
650 'vpci': '0000:05:00.0',
652 'local_ip': '152.16.100.19',
653 'type': 'PCI-PASSTHROUGH',
654 'netmask': '255.255.255.0',
656 'bandwidth': '10 Gbps',
657 'dst_ip': '152.16.100.20',
658 'local_mac': '00:00:00:00:00:01',
659 'vld_id': 'uplink_0',
662 'vnfd-connection-point-ref': 'xe0',
666 'virtual-interface': {
667 'dst_mac': '00:00:00:00:00:04',
668 'vpci': '0000:05:00.1',
670 'local_ip': '152.16.40.19',
671 'type': 'PCI-PASSTHROUGH',
672 'netmask': '255.255.255.0',
674 'bandwidth': '10 Gbps',
675 'dst_ip': '152.16.40.20',
676 'local_mac': '00:00:00:00:00:02',
677 'vld_id': 'downlink_0',
680 'vnfd-connection-point-ref': 'xe1',
684 'virtual-interface': {
685 'dst_mac': '00:00:00:00:00:13',
686 'vpci': '0000:05:00.2',
688 'local_ip': '152.16.40.19',
689 'type': 'PCI-PASSTHROUGH',
690 'netmask': '255.255.255.0',
692 'bandwidth': '10 Gbps',
693 'dst_ip': '152.16.40.30',
694 'local_mac': '00:00:00:00:00:11'
696 'vnfd-connection-point-ref': 'xe2',
702 'description': 'Vpe approximation using DPDK',
704 'vdu-id': 'vpevnf-baremetal',
717 'connection-point': [
727 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
731 'vnfd:vnfd-catalog': {
739 vnfd_helper = base.VnfdHelper(self.VNFD_0)
740 ssh_helper = mock.Mock()
741 scenario_helper = mock.Mock()
742 dpdk_setup_helper = sample_vnf.DpdkVnfSetupEnvHelper(
743 vnfd_helper, ssh_helper, scenario_helper)
744 self.client_resource_helper = (
745 sample_vnf.ClientResourceHelper(dpdk_setup_helper))
747 @mock.patch.object(sample_vnf, 'LOG')
748 @mock.patch.object(sample_vnf, 'STLError', new_callable=lambda: MockError)
749 def test_get_stats_not_connected(self, mock_stl_error, *args):
750 self.client_resource_helper.client = mock.Mock()
751 self.client_resource_helper.client.get_stats.side_effect = \
754 self.assertEqual(self.client_resource_helper.get_stats(), {})
755 self.client_resource_helper.client.get_stats.assert_called_once()
757 def test_clear_stats(self):
758 self.client_resource_helper.client = mock.Mock()
760 self.assertIsNone(self.client_resource_helper.clear_stats())
762 self.client_resource_helper.client.clear_stats.call_count, 1)
764 def test_clear_stats_of_ports(self):
765 self.client_resource_helper.client = mock.Mock()
767 self.assertIsNone(self.client_resource_helper.clear_stats([3, 4]))
768 self.client_resource_helper.client.clear_stats.assert_called_once()
770 def test_start(self):
771 self.client_resource_helper.client = mock.Mock()
773 self.assertIsNone(self.client_resource_helper.start())
774 self.client_resource_helper.client.start.assert_called_once()
776 def test_start_ports(self):
777 self.client_resource_helper.client = mock.Mock()
779 self.assertIsNone(self.client_resource_helper.start([3, 4]))
780 self.client_resource_helper.client.start.assert_called_once()
782 def test_collect_kpi_with_queue(self):
783 self.client_resource_helper._result = {
786 self.client_resource_helper._queue = mock.Mock()
787 self.client_resource_helper._queue.empty.return_value = False
788 self.client_resource_helper._queue.get.return_value = {
797 result = self.client_resource_helper.collect_kpi()
798 self.assertEqual(result, expected)
800 @mock.patch.object(time, 'sleep')
801 @mock.patch.object(sample_vnf, 'STLError')
802 def test__connect_with_failures(self, mock_stl_error, *args):
803 client = mock.MagicMock()
804 client.connect.side_effect = mock_stl_error(msg='msg')
806 self.assertIs(self.client_resource_helper._connect(client), client)
809 class TestRfc2544ResourceHelper(unittest.TestCase):
813 'correlated_traffic': True,
814 'allowed_drop_rate': '0.1 - 0.15',
818 'allowed_drop_rate': ' 0.25 - 0.05 ',
822 'allowed_drop_rate': '0.2',
831 'rfc2544': RFC2544_CFG_1,
837 'rfc2544': RFC2544_CFG_2,
843 'rfc2544': RFC2544_CFG_3,
849 'rfc2544': RFC2544_CFG_4,
854 self.scenario_helper = sample_vnf.ScenarioHelper('name1')
855 self.rfc2544_resource_helper = \
856 sample_vnf.Rfc2544ResourceHelper(self.scenario_helper)
858 def test_property_rfc2544(self):
859 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
861 self.assertIsNone(self.rfc2544_resource_helper._rfc2544)
862 self.assertEqual(self.rfc2544_resource_helper.rfc2544,
864 self.assertEqual(self.rfc2544_resource_helper._rfc2544,
866 # ensure that resource_helper caches
867 self.scenario_helper.scenario_cfg = {}
868 self.assertEqual(self.rfc2544_resource_helper.rfc2544,
871 def test_property_tolerance_high(self):
872 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
874 self.assertIsNone(self.rfc2544_resource_helper._tolerance_high)
875 self.assertEqual(self.rfc2544_resource_helper.tolerance_high, 0.15)
876 self.assertEqual(self.rfc2544_resource_helper._tolerance_high, 0.15)
877 self.assertEqual(self.rfc2544_resource_helper._tolerance_precision, 2)
878 # ensure that resource_helper caches
879 self.scenario_helper.scenario_cfg = {}
880 self.assertEqual(self.rfc2544_resource_helper.tolerance_high, 0.15)
882 def test_property_tolerance_low(self):
883 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
885 self.assertIsNone(self.rfc2544_resource_helper._tolerance_low)
886 self.assertEqual(self.rfc2544_resource_helper.tolerance_low, 0.1)
887 self.assertEqual(self.rfc2544_resource_helper._tolerance_low, 0.1)
888 # ensure that resource_helper caches
889 self.scenario_helper.scenario_cfg = {}
890 self.assertEqual(self.rfc2544_resource_helper.tolerance_low, 0.1)
892 def test_property_tolerance_high_range_swap(self):
893 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
895 self.assertEqual(self.rfc2544_resource_helper.tolerance_high, 0.25)
897 def test_property_tolerance_low_range_swap(self):
898 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
900 self.assertEqual(self.rfc2544_resource_helper.tolerance_low, 0.05)
902 def test_property_tolerance_high_not_range(self):
903 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
905 self.assertEqual(self.rfc2544_resource_helper.tolerance_high, 0.2)
906 self.assertEqual(self.rfc2544_resource_helper._tolerance_precision, 1)
908 def test_property_tolerance_low_not_range(self):
909 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
911 self.assertEqual(self.rfc2544_resource_helper.tolerance_low, 0.2)
913 def test_property_tolerance_high_default(self):
914 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
916 self.assertEqual(self.rfc2544_resource_helper.tolerance_high, 0.0001)
918 def test_property_tolerance_low_default(self):
919 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
921 self.assertEqual(self.rfc2544_resource_helper.tolerance_low, 0.0001)
923 def test_property_latency(self):
924 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
926 self.assertIsNone(self.rfc2544_resource_helper._latency)
927 self.assertTrue(self.rfc2544_resource_helper.latency)
928 self.assertTrue(self.rfc2544_resource_helper._latency)
929 # ensure that resource_helper caches
930 self.scenario_helper.scenario_cfg = {}
931 self.assertTrue(self.rfc2544_resource_helper.latency)
933 def test_property_latency_default(self):
934 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
936 self.assertFalse(self.rfc2544_resource_helper.latency)
938 def test_property_correlated_traffic(self):
939 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
941 self.assertIsNone(self.rfc2544_resource_helper._correlated_traffic)
942 self.assertTrue(self.rfc2544_resource_helper.correlated_traffic)
943 self.assertTrue(self.rfc2544_resource_helper._correlated_traffic)
944 # ensure that resource_helper caches
945 self.scenario_helper.scenario_cfg = {}
946 self.assertTrue(self.rfc2544_resource_helper.correlated_traffic)
948 def test_property_correlated_traffic_default(self):
949 self.scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
951 self.assertFalse(self.rfc2544_resource_helper.correlated_traffic)
954 class TestSampleVNFDeployHelper(unittest.TestCase):
957 self._mock_time_sleep = mock.patch.object(time, 'sleep')
958 self.mock_time_sleep = self._mock_time_sleep.start()
959 self._mock_check_output = mock.patch.object(subprocess, 'check_output')
960 self.mock_check_output = self._mock_check_output.start()
961 self.addCleanup(self._stop_mocks)
963 self.ssh_helper = mock.Mock()
964 self.sample_vnf_deploy_helper = sample_vnf.SampleVNFDeployHelper(
965 mock.Mock(), self.ssh_helper)
966 self.ssh_helper.join_bin_path.return_value = 'joined_path'
967 self.ssh_helper.put.return_value = None
969 def _stop_mocks(self):
970 self._mock_time_sleep.stop()
971 self._mock_check_output.stop()
973 def test_deploy_vnfs_disabled(self):
974 self.ssh_helper.execute.return_value = 1, 'bad output', 'error output'
976 self.sample_vnf_deploy_helper.deploy_vnfs('name1')
977 self.sample_vnf_deploy_helper.DISABLE_DEPLOY = True
978 self.assertEqual(self.ssh_helper.execute.call_count, 5)
979 self.ssh_helper.put.assert_called_once()
981 def test_deploy_vnfs(self):
982 self.ssh_helper.execute.return_value = 1, 'bad output', 'error output'
983 self.sample_vnf_deploy_helper.DISABLE_DEPLOY = False
985 self.sample_vnf_deploy_helper.deploy_vnfs('name1')
986 self.assertEqual(self.ssh_helper.execute.call_count, 5)
987 self.ssh_helper.put.assert_called_once()
989 def test_deploy_vnfs_early_success(self):
990 self.ssh_helper.execute.return_value = 0, 'output', ''
991 self.sample_vnf_deploy_helper.DISABLE_DEPLOY = False
993 self.sample_vnf_deploy_helper.deploy_vnfs('name1')
994 self.ssh_helper.execute.assert_called_once()
995 self.ssh_helper.put.assert_not_called()
998 class TestScenarioHelper(unittest.TestCase):
1001 self.scenario_helper = sample_vnf.ScenarioHelper('name1')
1003 def test_property_task_path(self):
1004 self.scenario_helper.scenario_cfg = {
1005 'task_path': 'my_path',
1008 self.assertEqual(self.scenario_helper.task_path, 'my_path')
1010 def test_property_nodes(self):
1011 nodes = ['node1', 'node2']
1012 self.scenario_helper.scenario_cfg = {
1016 self.assertEqual(self.scenario_helper.nodes, nodes)
1018 def test_property_all_options(self):
1025 self.scenario_helper.scenario_cfg = {
1029 self.assertDictEqual(self.scenario_helper.all_options, data)
1031 def test_property_options(self):
1036 self.scenario_helper.scenario_cfg = {
1042 self.assertDictEqual(self.scenario_helper.options, data)
1044 def test_property_vnf_cfg(self):
1045 self.scenario_helper.scenario_cfg = {
1048 'vnf_config': 'my_config',
1053 self.assertEqual(self.scenario_helper.vnf_cfg, 'my_config')
1055 def test_property_vnf_cfg_default(self):
1056 self.scenario_helper.scenario_cfg = {
1062 self.assertEqual(self.scenario_helper.vnf_cfg,
1063 sample_vnf.ScenarioHelper.DEFAULT_VNF_CFG)
1065 def test_property_topology(self):
1066 self.scenario_helper.scenario_cfg = {
1067 'topology': 'my_topology',
1070 self.assertEqual(self.scenario_helper.topology, 'my_topology')
1073 class TestSampleVnf(unittest.TestCase):
1076 'short-name': 'VpeVnf',
1081 'network': '152.16.100.20',
1082 'netmask': '255.255.255.0',
1083 'gateway': '152.16.100.20',
1087 'network': '152.16.40.20',
1088 'netmask': '255.255.255.0',
1089 'gateway': '152.16.40.20',
1093 'description': 'VPE approximation using DPDK',
1094 'name': 'vpevnf-baremetal',
1097 'network': '0064:ff9b:0:0:0:0:9810:6414',
1099 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1103 'network': '0064:ff9b:0:0:0:0:9810:2814',
1105 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1109 'id': 'vpevnf-baremetal',
1110 'external-interface': [
1112 'virtual-interface': {
1113 'dst_mac': '00:00:00:00:00:03',
1114 'vpci': '0000:05:00.0',
1115 'local_ip': '152.16.100.19',
1116 'type': 'PCI-PASSTHROUGH',
1117 'netmask': '255.255.255.0',
1119 'bandwidth': '10 Gbps',
1120 'dst_ip': '152.16.100.20',
1121 'local_mac': '00:00:00:00:00:01'
1123 'vnfd-connection-point-ref': 'xe0',
1127 'virtual-interface': {
1128 'dst_mac': '00:00:00:00:00:04',
1129 'vpci': '0000:05:00.1',
1130 'local_ip': '152.16.40.19',
1131 'type': 'PCI-PASSTHROUGH',
1132 'netmask': '255.255.255.0',
1134 'bandwidth': '10 Gbps',
1135 'dst_ip': '152.16.40.20',
1136 'local_mac': '00:00:00:00:00:02'
1138 'vnfd-connection-point-ref': 'xe1',
1144 'description': 'Vpe approximation using DPDK',
1146 'vdu-id': 'vpevnf-baremetal',
1159 'connection-point': [
1169 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1173 'vnfd:vnfd-catalog': {
1181 "schema": "isb:traffic_profile:0.1",
1183 "description": "Fixed traffic profile to run UDP traffic",
1184 "traffic_profile": {
1185 "traffic_type": "FixedTraffic",
1186 "frame_rate": 100, # pps
1192 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1193 self.vnf = sample_vnf.SampleVNF('vnf1', vnfd)
1194 self.vnf.APP_NAME = 'sample1'
1196 def test___init__(self):
1197 vnf = sample_vnf.SampleVNF('vnf1', self.VNFD_0)
1199 self.assertEqual(vnf.name, 'vnf1')
1200 self.assertDictEqual(vnf.vnfd_helper, self.VNFD_0)
1202 # test the default setup helper is SetupEnvHelper, not subclass
1203 self.assertEqual(type(vnf.setup_helper),
1204 sample_vnf.SetupEnvHelper)
1206 # test the default resource helper is ResourceHelper, not subclass
1207 self.assertEqual(type(vnf.resource_helper), sample_vnf.ResourceHelper)
1209 def test___init___alt_types(self):
1210 class MySetupEnvHelper(sample_vnf.SetupEnvHelper):
1213 class MyResourceHelper(sample_vnf.ResourceHelper):
1216 vnf = sample_vnf.SampleVNF('vnf1', self.VNFD_0,
1217 MySetupEnvHelper, MyResourceHelper)
1219 self.assertEqual(vnf.name, 'vnf1')
1220 self.assertDictEqual(vnf.vnfd_helper, self.VNFD_0)
1222 # test the default setup helper is MySetupEnvHelper, not subclass
1223 self.assertEqual(type(vnf.setup_helper), MySetupEnvHelper)
1225 # test the default resource helper is MyResourceHelper, not subclass
1226 self.assertEqual(type(vnf.resource_helper), MyResourceHelper)
1228 @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1229 def test__start_vnf(self, *args):
1230 self.vnf._run = mock.Mock()
1232 self.assertIsNone(self.vnf.queue_wrapper)
1233 self.assertIsNone(self.vnf._vnf_process)
1234 self.vnf._start_vnf()
1235 self.assertIsNotNone(self.vnf.queue_wrapper)
1236 self.assertIsNotNone(self.vnf._vnf_process)
1238 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
1239 return_value='fake_context')
1240 @mock.patch.object(ssh, "SSH")
1241 def test_instantiate(self, ssh, *args):
1242 test_base.mock_ssh(ssh)
1247 self.vnf._start_server = mock.Mock(return_value=0)
1248 self.vnf._vnf_process = mock.MagicMock()
1249 self.vnf._vnf_process._is_alive.return_value = 1
1250 self.vnf.ssh_helper = mock.MagicMock()
1251 self.vnf.deploy_helper = mock.MagicMock()
1252 self.vnf.resource_helper.ssh_helper = mock.MagicMock()
1257 self.assertIsNone(self.vnf.instantiate(scenario_cfg, {}))
1259 def test__update_collectd_options(self):
1260 scenario_cfg = {'options':
1264 {'plugin3': {'param': 3}}},
1269 {'plugin3': {'param': 2},
1270 'plugin2': {'param': 2}}}}}}
1271 context_cfg = {'nodes':
1276 {'plugin3': {'param': 1},
1277 'plugin2': {'param': 1},
1278 'plugin1': {'param': 1}}}}}}
1279 expected = {'interval': 1,
1281 {'plugin3': {'param': 1},
1282 'plugin2': {'param': 1},
1283 'plugin1': {'param': 1}}}
1285 self.vnf._update_collectd_options(scenario_cfg, context_cfg)
1286 self.assertEqual(self.vnf.setup_helper.collectd_options, expected)
1288 def test__update_options(self):
1289 options1 = {'interval': 1,
1292 {'plugin3': {'param': 3},
1293 'plugin2': {'param': 1},
1294 'plugin1': {'param': 1}}}
1295 options2 = {'interval': 2,
1298 {'plugin4': {'param': 4},
1299 'plugin2': {'param': 2},
1300 'plugin1': {'param': 2}}}
1301 expected = {'interval': 1,
1305 {'plugin4': {'param': 4},
1306 'plugin3': {'param': 3},
1307 'plugin2': {'param': 1},
1308 'plugin1': {'param': 1}}}
1310 self.vnf._update_options(options2, options1)
1311 self.assertEqual(options2, expected)
1313 @mock.patch.object(time, 'sleep')
1314 @mock.patch.object(ssh, 'SSH')
1315 def test_wait_for_instantiate_empty_queue(self, ssh, *args):
1316 test_base.mock_ssh(ssh, exec_result=(1, "", ""))
1330 self.vnf.WAIT_TIME_FOR_SCRIPT = 0
1331 self.vnf._start_server = mock.Mock(return_value=0)
1332 self.vnf._vnf_process = mock.MagicMock()
1333 self.vnf._vnf_process.exitcode = 0
1334 self.vnf._vnf_process._is_alive.return_value = 1
1335 self.vnf.queue_wrapper = mock.Mock()
1336 self.vnf.q_out = mock.Mock()
1337 self.vnf.q_out.qsize.side_effect = iter(queue_size_list)
1338 self.vnf.q_out.get.side_effect = iter(queue_get_list)
1339 self.vnf.ssh_helper = mock.MagicMock()
1340 self.vnf.resource_helper.ssh_helper = mock.MagicMock()
1341 self.vnf.resource_helper.start_collect = mock.MagicMock()
1343 self.assertEqual(self.vnf.wait_for_instantiate(), 0)
1345 @mock.patch.object(time, 'sleep')
1346 @mock.patch.object(ssh, 'SSH')
1347 def test_wait_for_initialize(self, ssh, *args):
1348 test_base.mock_ssh(ssh, exec_result=(1, "", ""))
1352 'run non_existent_script_name',
1353 'Cannot open file "non_existent_script_name"'
1357 len(queue_get_list[0]),
1359 len(queue_get_list[1]),
1360 len(queue_get_list[2]),
1362 len(queue_get_list[3])
1364 self.vnf.WAIT_TIME_FOR_SCRIPT = 0
1365 self.vnf._start_server = mock.Mock(return_value=0)
1366 self.vnf._vnf_process = mock.MagicMock()
1367 self.vnf._vnf_process.exitcode = 0
1368 self.vnf._vnf_process._is_alive.return_value = 1
1369 self.vnf.queue_wrapper = mock.Mock()
1370 self.vnf.q_out = mock.Mock()
1371 self.vnf.q_out.qsize.side_effect = iter(queue_size_list)
1372 self.vnf.q_out.get.side_effect = iter(queue_get_list)
1373 self.vnf.ssh_helper = mock.MagicMock()
1374 self.vnf.resource_helper.ssh_helper = mock.MagicMock()
1375 self.vnf.resource_helper.start_collect = mock.MagicMock()
1377 self.assertEqual(self.vnf.wait_for_initialize(), 0)
1379 @mock.patch.object(time, "sleep")
1380 def test_vnf_execute_with_queue_data(self, *args):
1391 self.vnf.q_out = mock.Mock()
1392 self.vnf.q_out.qsize.side_effect = iter(queue_size_list)
1393 self.vnf.q_out.get.side_effect = iter(queue_get_list)
1395 self.assertEqual(self.vnf.vnf_execute('my command'), 'hello world')
1397 def test_terminate_without_vnf_process(self):
1398 self.vnf.vnf_execute = mock.Mock()
1399 self.vnf.ssh_helper = mock.Mock()
1400 self.vnf._tear_down = mock.Mock()
1401 self.vnf.resource_helper = mock.Mock()
1403 self.assertIsNone(self.vnf.terminate())
1405 def test_get_stats(self):
1406 self.vnf.APP_WORD = 'sample1'
1407 self.vnf.vnf_execute = mock.Mock(return_value='the stats')
1409 self.assertEqual(self.vnf.get_stats(), 'the stats')
1411 @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server',
1412 return_value='mock_node')
1413 def test_collect_kpi(self, *args):
1414 self.vnf.scenario_helper.scenario_cfg = {
1415 'nodes': {self.vnf.name: "mock"}
1417 self.vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1418 self.vnf.COLLECT_MAP = {
1423 self.vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1424 self.vnf.resource_helper = mock.Mock()
1425 self.vnf.resource_helper.collect_kpi.return_value = {}
1431 'collect_stats': {},
1432 'physical_node': 'mock_node'
1434 result = self.vnf.collect_kpi()
1435 self.assertEqual(result, expected)
1437 @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server',
1438 return_value='mock_node')
1439 def test_collect_kpi_default(self, *args):
1440 self.vnf.scenario_helper.scenario_cfg = {
1441 'nodes': {self.vnf.name: "mock"}
1443 self.vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1444 self.vnf.get_stats = mock.Mock(return_value='')
1447 'physical_node': 'mock_node',
1450 'packets_dropped': 0,
1452 result = self.vnf.collect_kpi()
1453 self.assertEqual(result, expected)
1455 def test_scale(self):
1456 self.assertRaises(y_exceptions.FunctionNotImplemented, self.vnf.scale)
1458 def test__run(self):
1459 test_cmd = 'test cmd'
1460 run_kwargs = {'arg1': 'val1', 'arg2': 'val2'}
1461 self.vnf.ssh_helper = mock.Mock()
1462 self.vnf.setup_helper = mock.Mock()
1463 with mock.patch.object(self.vnf, '_build_config',
1464 return_value=test_cmd), \
1465 mock.patch.object(self.vnf, '_build_run_kwargs'):
1466 self.vnf.run_kwargs = run_kwargs
1468 self.vnf.ssh_helper.drop_connection.assert_called_once()
1469 self.vnf.ssh_helper.run.assert_called_once_with(test_cmd, **run_kwargs)
1470 self.vnf.setup_helper.kill_vnf.assert_called_once()
1473 class TestSampleVNFTrafficGen(unittest.TestCase):
1475 VNFD_0 = TestSampleVnf.VNFD_0
1476 VNFD = TestSampleVnf.VNFD
1478 TRAFFIC_PROFILE = TestSampleVnf.TRAFFIC_PROFILE
1481 self.sample_vnf_tg = sample_vnf.SampleVNFTrafficGen(
1484 def test__check_status(self):
1486 with self.assertRaises(NotImplementedError):
1487 self.sample_vnf_tg._check_status()
1489 def test_listen_traffic(self):
1490 self.sample_vnf_tg.listen_traffic(mock.Mock())
1492 def test_verify_traffic(self):
1493 self.sample_vnf_tg.verify_traffic(mock.Mock())
1495 def test_terminate(self):
1496 self.sample_vnf_tg._traffic_process = mock.Mock()
1497 self.sample_vnf_tg._tg_process = mock.Mock()
1499 self.sample_vnf_tg.terminate()
1501 @mock.patch.object(time, 'sleep')
1502 def test__wait_for_process(self, *args):
1503 with mock.patch.object(self.sample_vnf_tg, '_check_status',
1504 return_value=0) as mock_status, \
1505 mock.patch.object(self.sample_vnf_tg, '_tg_process') as mock_proc:
1506 mock_proc.is_alive.return_value = True
1507 mock_proc.exitcode = 234
1508 self.assertEqual(self.sample_vnf_tg._wait_for_process(), 234)
1509 mock_proc.is_alive.assert_called_once()
1510 mock_status.assert_called_once()
1512 def test__wait_for_process_not_alive(self):
1513 with mock.patch.object(self.sample_vnf_tg, '_tg_process') as mock_proc:
1514 mock_proc.is_alive.return_value = False
1515 self.assertRaises(RuntimeError, self.sample_vnf_tg._wait_for_process)
1516 mock_proc.is_alive.assert_called_once()
1518 @mock.patch.object(time, 'sleep')
1519 def test__wait_for_process_delayed(self, *args):
1520 with mock.patch.object(self.sample_vnf_tg, '_check_status',
1521 side_effect=[1, 0]) as mock_status, \
1522 mock.patch.object(self.sample_vnf_tg,
1523 '_tg_process') as mock_proc:
1524 mock_proc.is_alive.return_value = True
1525 mock_proc.exitcode = 234
1526 self.assertEqual(self.sample_vnf_tg._wait_for_process(), 234)
1527 mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()])
1528 mock_status.assert_has_calls([mock.call(), mock.call()])
1530 def test_scale(self):
1531 self.assertRaises(y_exceptions.FunctionNotImplemented,
1532 self.sample_vnf_tg.scale)