7ee2005bafb8d23a50ef165768e216c43d7ec37f
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_sample_vnf.py
1 # Copyright (c) 2017-2018 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 copy import deepcopy
17
18 import unittest
19 import mock
20 import six
21
22 from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
23 from yardstick.tests import STL_MOCKS
24 from yardstick.benchmark.contexts.base import Context
25 from yardstick.common import exceptions as y_exceptions
26 from yardstick.common import utils
27 from yardstick.network_services.nfvi.resource import ResourceProfile
28 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
29
30
31 class MockError(BaseException):
32     pass
33
34
35 STLClient = mock.MagicMock()
36 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
37 stl_patch.start()
38
39 if stl_patch:
40     from yardstick.network_services.vnf_generic.vnf import sample_vnf
41     from yardstick.network_services.vnf_generic.vnf.vnf_ssh_helper import VnfSshHelper
42     from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFDeployHelper
43     from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper
44     from yardstick.network_services.vnf_generic.vnf.sample_vnf import ResourceHelper
45     from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
46     from yardstick.network_services.vnf_generic.vnf.sample_vnf import Rfc2544ResourceHelper
47     from yardstick.network_services.vnf_generic.vnf.sample_vnf import SetupEnvHelper
48     from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF
49     from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
50     from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
51
52
53 class TestVnfSshHelper(unittest.TestCase):
54
55     VNFD_0 = {
56         'short-name': 'VpeVnf',
57         'vdu': [
58             {
59                 'routing_table': [
60                     {
61                         'network': '152.16.100.20',
62                         'netmask': '255.255.255.0',
63                         'gateway': '152.16.100.20',
64                         'if': 'xe0'
65                     },
66                     {
67                         'network': '152.16.40.20',
68                         'netmask': '255.255.255.0',
69                         'gateway': '152.16.40.20',
70                         'if': 'xe1'
71                     },
72                 ],
73                 'description': 'VPE approximation using DPDK',
74                 'name': 'vpevnf-baremetal',
75                 'nd_route_tbl': [
76                     {
77                         'network': '0064:ff9b:0:0:0:0:9810:6414',
78                         'netmask': '112',
79                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
80                         'if': 'xe0'
81                     },
82                     {
83                         'network': '0064:ff9b:0:0:0:0:9810:2814',
84                         'netmask': '112',
85                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
86                         'if': 'xe1'
87                     },
88                 ],
89                 'id': 'vpevnf-baremetal',
90                 'external-interface': [
91                     {
92                         'virtual-interface': {
93                             'dst_mac': '00:00:00:00:00:03',
94                             'vpci': '0000:05:00.0',
95                             'local_ip': '152.16.100.19',
96                             'type': 'PCI-PASSTHROUGH',
97                             'netmask': '255.255.255.0',
98                             'dpdk_port_num': 0,
99                             'bandwidth': '10 Gbps',
100                             'dst_ip': '152.16.100.20',
101                             'local_mac': '00:00:00:00:00:01',
102                             'vld_id': 'uplink_0',
103                             'ifname': 'xe0',
104                         },
105                         'vnfd-connection-point-ref': 'xe0',
106                         'name': 'xe0'
107                     },
108                     {
109                         'virtual-interface': {
110                             'dst_mac': '00:00:00:00:00:04',
111                             'vpci': '0000:05:00.1',
112                             'local_ip': '152.16.40.19',
113                             'type': 'PCI-PASSTHROUGH',
114                             'netmask': '255.255.255.0',
115                             'dpdk_port_num': 1,
116                             'bandwidth': '10 Gbps',
117                             'dst_ip': '152.16.40.20',
118                             'local_mac': '00:00:00:00:00:02',
119                             'vld_id': 'downlink_0',
120                             'ifname': 'xe1',
121                         },
122                         'vnfd-connection-point-ref': 'xe1',
123                         'name': 'xe1'
124                     },
125                 ],
126             },
127         ],
128         'description': 'Vpe approximation using DPDK',
129         'mgmt-interface': {
130             'vdu-id': 'vpevnf-baremetal',
131             'host': '1.1.1.1',
132             'password': 'r00t',
133             'user': 'root',
134             'ip': '1.1.1.1'
135         },
136         'benchmark': {
137             'kpi': [
138                 'packets_in',
139                 'packets_fwd',
140                 'packets_dropped',
141             ],
142         },
143         'connection-point': [
144             {
145                 'type': 'VPORT',
146                 'name': 'xe0',
147             },
148             {
149                 'type': 'VPORT',
150                 'name': 'xe1',
151             },
152         ],
153         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
154     }
155
156     VNFD = {
157         'vnfd:vnfd-catalog': {
158             'vnfd': [
159                 VNFD_0,
160             ]
161         }
162     }
163
164     def assertAll(self, iterable, message=None):
165         self.assertTrue(all(iterable), message)
166
167     def test_get_class(self):
168         self.assertIs(VnfSshHelper.get_class(), VnfSshHelper)
169
170     @mock.patch('yardstick.ssh.paramiko')
171     def test_copy(self, _):
172         ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
173         ssh_helper._run = mock.Mock()
174
175         ssh_helper.execute('ls')
176         self.assertTrue(ssh_helper.is_connected)
177         result = ssh_helper.copy()
178         self.assertIsInstance(result, VnfSshHelper)
179         self.assertFalse(result.is_connected)
180         self.assertEqual(result.bin_path, ssh_helper.bin_path)
181         self.assertEqual(result.host, ssh_helper.host)
182         self.assertEqual(result.port, ssh_helper.port)
183         self.assertEqual(result.user, ssh_helper.user)
184         self.assertEqual(result.password, ssh_helper.password)
185         self.assertEqual(result.key_filename, ssh_helper.key_filename)
186
187     @mock.patch('yardstick.ssh.paramiko')
188     def test_upload_config_file(self, mock_paramiko):
189         ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
190         ssh_helper._run = mock.MagicMock()
191
192         self.assertFalse(ssh_helper.is_connected)
193         cfg_file = ssh_helper.upload_config_file('my/prefix', 'my content')
194         self.assertTrue(ssh_helper.is_connected)
195         mock_paramiko.SSHClient.assert_called_once()
196         self.assertTrue(cfg_file.startswith('/tmp'))
197
198         cfg_file = ssh_helper.upload_config_file('/my/prefix', 'my content')
199         self.assertTrue(ssh_helper.is_connected)
200         mock_paramiko.SSHClient.assert_called_once()
201         self.assertEqual(cfg_file, '/my/prefix')
202
203     def test_join_bin_path(self):
204         ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
205
206         expected_start = 'my'
207         expected_middle_list = ['bin']
208         expected_end = 'path'
209         result = ssh_helper.join_bin_path()
210         self.assertTrue(result.startswith(expected_start))
211         self.assertAll(middle in result for middle in expected_middle_list)
212         self.assertTrue(result.endswith(expected_end))
213
214         expected_middle_list.append(expected_end)
215         expected_end = 'some_file.sh'
216         result = ssh_helper.join_bin_path('some_file.sh')
217         self.assertTrue(result.startswith(expected_start))
218         self.assertAll(middle in result for middle in expected_middle_list)
219         self.assertTrue(result.endswith(expected_end))
220
221         expected_middle_list.append('some_dir')
222         expected_end = 'some_file.sh'
223         result = ssh_helper.join_bin_path('some_dir', 'some_file.sh')
224         self.assertTrue(result.startswith(expected_start))
225         self.assertAll(middle in result for middle in expected_middle_list)
226         self.assertTrue(result.endswith(expected_end))
227
228     @mock.patch('yardstick.ssh.paramiko')
229     @mock.patch('yardstick.ssh.provision_tool')
230     def test_provision_tool(self, mock_provision_tool, mock_paramiko):
231         ssh_helper = VnfSshHelper(self.VNFD_0['mgmt-interface'], 'my/bin/path')
232         ssh_helper._run = mock.MagicMock()
233
234         self.assertFalse(ssh_helper.is_connected)
235         ssh_helper.provision_tool()
236         self.assertTrue(ssh_helper.is_connected)
237         mock_paramiko.SSHClient.assert_called_once()
238         mock_provision_tool.assert_called_once()
239
240         ssh_helper.provision_tool(tool_file='my_tool.sh')
241         self.assertTrue(ssh_helper.is_connected)
242         mock_paramiko.SSHClient.assert_called_once()
243         self.assertEqual(mock_provision_tool.call_count, 2)
244
245         ssh_helper.provision_tool('tool_path', 'my_tool.sh')
246         self.assertTrue(ssh_helper.is_connected)
247         mock_paramiko.SSHClient.assert_called_once()
248         self.assertEqual(mock_provision_tool.call_count, 3)
249
250
251 class TestSetupEnvHelper(unittest.TestCase):
252
253     VNFD_0 = {
254         'short-name': 'VpeVnf',
255         'vdu': [
256             {
257                 'routing_table': [
258                     {
259                         'network': '152.16.100.20',
260                         'netmask': '255.255.255.0',
261                         'gateway': '152.16.100.20',
262                         'if': 'xe0'
263                     },
264                     {
265                         'network': '152.16.40.20',
266                         'netmask': '255.255.255.0',
267                         'gateway': '152.16.40.20',
268                         'if': 'xe1'
269                     },
270                 ],
271                 'description': 'VPE approximation using DPDK',
272                 'name': 'vpevnf-baremetal',
273                 'nd_route_tbl': [
274                     {
275                         'network': '0064:ff9b:0:0:0:0:9810:6414',
276                         'netmask': '112',
277                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
278                         'if': 'xe0'
279                     },
280                     {
281                         'network': '0064:ff9b:0:0:0:0:9810:2814',
282                         'netmask': '112',
283                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
284                         'if': 'xe1'
285                     },
286                 ],
287                 'id': 'vpevnf-baremetal',
288                 'external-interface': [
289                     {
290                         'virtual-interface': {
291                             'dst_mac': '00:00:00:00:00:03',
292                             'vpci': '0000:05:00.0',
293                             'local_ip': '152.16.100.19',
294                             'type': 'PCI-PASSTHROUGH',
295                             'netmask': '255.255.255.0',
296                             'dpdk_port_num': 0,
297                             'bandwidth': '10 Gbps',
298                             'dst_ip': '152.16.100.20',
299                             'local_mac': '00:00:00:00:00:01',
300                             'vld_id': 'uplink_0',
301                             'ifname': 'xe0',
302                         },
303                         'vnfd-connection-point-ref': 'xe0',
304                         'name': 'xe0'
305                     },
306                     {
307                         'virtual-interface': {
308                             'dst_mac': '00:00:00:00:00:04',
309                             'vpci': '0000:05:00.1',
310                             'local_ip': '152.16.40.19',
311                             'type': 'PCI-PASSTHROUGH',
312                             'netmask': '255.255.255.0',
313                             'dpdk_port_num': 1,
314                             'bandwidth': '10 Gbps',
315                             'dst_ip': '152.16.40.20',
316                             'local_mac': '00:00:00:00:00:02',
317                             'vld_id': 'downlink_0',
318                             'ifname': 'xe1',
319                         },
320                         'vnfd-connection-point-ref': 'xe1',
321                         'name': 'xe1'
322                     },
323                 ],
324             },
325         ],
326         'description': 'Vpe approximation using DPDK',
327         'mgmt-interface': {
328             'vdu-id': 'vpevnf-baremetal',
329             'host': '1.1.1.1',
330             'password': 'r00t',
331             'user': 'root',
332             'ip': '1.1.1.1'
333         },
334         'benchmark': {
335             'kpi': [
336                 'packets_in',
337                 'packets_fwd',
338                 'packets_dropped',
339             ],
340         },
341         'connection-point': [
342             {
343                 'type': 'VPORT',
344                 'name': 'xe0',
345             },
346             {
347                 'type': 'VPORT',
348                 'name': 'xe1',
349             },
350         ],
351         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
352     }
353
354     def test_build_config(self):
355         setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
356
357         with self.assertRaises(NotImplementedError):
358             setup_env_helper.build_config()
359
360     def test_setup_vnf_environment(self):
361         setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
362         self.assertIsNone(setup_env_helper.setup_vnf_environment())
363
364     def test_tear_down(self):
365         setup_env_helper = SetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
366
367         with self.assertRaises(NotImplementedError):
368             setup_env_helper.tear_down()
369
370
371 class TestDpdkVnfSetupEnvHelper(unittest.TestCase):
372
373     VNFD_0 = {
374         'short-name': 'VpeVnf',
375         'vdu': [
376             {
377                 'routing_table': [
378                     {
379                         'network': '152.16.100.20',
380                         'netmask': '255.255.255.0',
381                         'gateway': '152.16.100.20',
382                         'if': 'xe0'
383                     },
384                     {
385                         'network': '152.16.40.20',
386                         'netmask': '255.255.255.0',
387                         'gateway': '152.16.40.20',
388                         'if': 'xe1'
389                     },
390                 ],
391                 'description': 'VPE approximation using DPDK',
392                 'name': 'vpevnf-baremetal',
393                 'nd_route_tbl': [
394                     {
395                         'network': '0064:ff9b:0:0:0:0:9810:6414',
396                         'netmask': '112',
397                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
398                         'if': 'xe0'
399                     },
400                     {
401                         'network': '0064:ff9b:0:0:0:0:9810:2814',
402                         'netmask': '112',
403                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
404                         'if': 'xe1'
405                     },
406                 ],
407                 'id': 'vpevnf-baremetal',
408                 'external-interface': [
409                     {
410                         'virtual-interface': {
411                             'dst_mac': '00:00:00:00:00:03',
412                             'vpci': '0000:05:00.0',
413                             'dpdk_port_num': 0,
414                             'driver': 'i40e',
415                             'local_ip': '152.16.100.19',
416                             'type': 'PCI-PASSTHROUGH',
417                             'netmask': '255.255.255.0',
418                             'bandwidth': '10 Gbps',
419                             'dst_ip': '152.16.100.20',
420                             'local_mac': '00:00:00:00:00:01',
421                             'vld_id': 'uplink_0',
422                             'ifname': 'xe0',
423                         },
424                         'vnfd-connection-point-ref': 'xe0',
425                         'name': 'xe0'
426                     },
427                     {
428                         'virtual-interface': {
429                             'dst_mac': '00:00:00:00:00:04',
430                             'vpci': '0000:05:00.1',
431                             'dpdk_port_num': 1,
432                             'driver': 'ixgbe',
433                             'local_ip': '152.16.40.19',
434                             'type': 'PCI-PASSTHROUGH',
435                             'netmask': '255.255.255.0',
436                             'bandwidth': '10 Gbps',
437                             'dst_ip': '152.16.40.20',
438                             'local_mac': '00:00:00:00:00:02',
439                             'vld_id': 'downlink_0',
440                             'ifname': 'xe1',
441                         },
442                         'vnfd-connection-point-ref': 'xe1',
443                         'name': 'xe1'
444                     },
445                 ],
446             },
447         ],
448         'description': 'Vpe approximation using DPDK',
449         'mgmt-interface': {
450             'vdu-id': 'vpevnf-baremetal',
451             'host': '1.1.1.1',
452             'password': 'r00t',
453             'user': 'root',
454             'ip': '1.1.1.1'
455         },
456         'benchmark': {
457             'kpi': [
458                 'packets_in',
459                 'packets_fwd',
460                 'packets_dropped',
461             ],
462         },
463         'connection-point': [
464             {
465                 'type': 'VPORT',
466                 'name': 'xe0',
467             },
468             {
469                 'type': 'VPORT',
470                 'name': 'xe1',
471             },
472         ],
473         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
474     }
475
476     VNFD = {
477         'vnfd:vnfd-catalog': {
478             'vnfd': [
479                 VNFD_0,
480             ]
481         }
482     }
483
484     def test__update_packet_type(self):
485         ip_pipeline_cfg = 'pkt_type = ipv4'
486         pkt_type = {'pkt_type': '1'}
487
488         expected = "pkt_type = 1"
489         result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
490         self.assertEqual(result, expected)
491
492     def test__update_packet_type_no_op(self):
493         ip_pipeline_cfg = 'pkt_type = ipv6'
494         pkt_type = {'pkt_type': '1'}
495
496         expected = "pkt_type = ipv6"
497         result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
498         self.assertEqual(result, expected)
499
500     def test__update_packet_type_multi_op(self):
501         ip_pipeline_cfg = 'pkt_type = ipv4\npkt_type = 1\npkt_type = ipv4'
502         pkt_type = {'pkt_type': '1'}
503
504         expected = 'pkt_type = 1\npkt_type = 1\npkt_type = 1'
505         result = DpdkVnfSetupEnvHelper._update_packet_type(ip_pipeline_cfg, pkt_type)
506         self.assertEqual(result, expected)
507
508     def test__update_traffic_type(self):
509         ip_pipeline_cfg = 'pkt_type = ipv4'
510
511         traffic_options = {"vnf_type": DpdkVnfSetupEnvHelper.APP_NAME, 'traffic_type': 4}
512         expected = "pkt_type = ipv4"
513         result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
514         self.assertEqual(result, expected)
515
516     def test__update_traffic_type_ipv6(self):
517         ip_pipeline_cfg = 'pkt_type = ipv4'
518
519         traffic_options = {"vnf_type": DpdkVnfSetupEnvHelper.APP_NAME, 'traffic_type': 6}
520         expected = "pkt_type = ipv6"
521         result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
522         self.assertEqual(result, expected)
523
524     def test__update_traffic_type_not_app_name(self):
525         ip_pipeline_cfg = 'traffic_type = 4'
526
527         vnf_type = ''.join(["Not", DpdkVnfSetupEnvHelper.APP_NAME])
528         traffic_options = {"vnf_type": vnf_type, 'traffic_type': 8}
529         expected = "traffic_type = 8"
530         result = DpdkVnfSetupEnvHelper._update_traffic_type(ip_pipeline_cfg, traffic_options)
531         self.assertEqual(result, expected)
532
533     @mock.patch.object(six, 'BytesIO', return_value=six.BytesIO(b'100\n'))
534     @mock.patch.object(utils, 'read_meminfo',
535                        return_value={'Hugepagesize': '2048'})
536     def test__setup_hugepages_no_hugepages_defined(self, mock_meminfo, *args):
537         ssh_helper = mock.Mock()
538         scenario_helper = mock.Mock()
539         scenario_helper.all_options = {}
540         dpdk_setup_helper = DpdkVnfSetupEnvHelper(
541             mock.ANY, ssh_helper, scenario_helper)
542         with mock.patch.object(sample_vnf.LOG, 'info') as mock_info:
543             dpdk_setup_helper._setup_hugepages()
544             mock_info.assert_called_once_with(
545                 'Hugepages size (kB): %s, number claimed: %s, number set: '
546                 '%s', 2048, 8192, 100)
547         mock_meminfo.assert_called_once_with(ssh_helper)
548
549     @mock.patch.object(six, 'BytesIO', return_value=six.BytesIO(b'100\n'))
550     @mock.patch.object(utils, 'read_meminfo',
551                        return_value={'Hugepagesize': '1048576'})
552     def test__setup_hugepages_8gb_hugepages_defined(self, mock_meminfo, *args):
553         ssh_helper = mock.Mock()
554         scenario_helper = mock.Mock()
555         scenario_helper.all_options = {'hugepages_gb': 8}
556         dpdk_setup_helper = DpdkVnfSetupEnvHelper(
557             mock.ANY, ssh_helper, scenario_helper)
558         with mock.patch.object(sample_vnf.LOG, 'info') as mock_info:
559             dpdk_setup_helper._setup_hugepages()
560             mock_info.assert_called_once_with(
561                 'Hugepages size (kB): %s, number claimed: %s, number set: '
562                 '%s', 1048576, 8, 100)
563         mock_meminfo.assert_called_once_with(ssh_helper)
564
565     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open')
566     @mock.patch.object(utils, 'find_relative_file')
567     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig')
568     @mock.patch.object(utils, 'open_relative_file')
569     def test_build_config(self, mock_open_rf, mock_multi_port_config_class, mock_find, *args):
570         mock_multi_port_config = mock_multi_port_config_class()
571         vnfd_helper = VnfdHelper(self.VNFD_0)
572         ssh_helper = mock.Mock()
573         scenario_helper = mock.Mock()
574         scenario_helper.vnf_cfg = {}
575         scenario_helper.options = {}
576         scenario_helper.all_options = {}
577         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
578
579         dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
580         result = dpdk_setup_helper.build_config()
581         self.assertEqual(result, expected)
582         self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2)
583         mock_find.assert_called()
584         mock_multi_port_config.generate_config.assert_called()
585         mock_multi_port_config.generate_script.assert_called()
586
587         scenario_helper.options = {'rules': 'fake_file'}
588         scenario_helper.vnf_cfg = {'file': 'fake_file'}
589         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
590         mock_open_rf.side_effect = mock.mock_open(read_data='fake_data')
591         dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
592
593         result = dpdk_setup_helper.build_config()
594
595         mock_open_rf.assert_called()
596         self.assertEqual(result, expected)
597         self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2)
598         mock_find.assert_called()
599         mock_multi_port_config.generate_config.assert_called()
600         mock_multi_port_config.generate_script.assert_called()
601
602     def test__build_pipeline_kwargs(self):
603         vnfd_helper = VnfdHelper(self.VNFD_0)
604         ssh_helper = mock.Mock()
605         ssh_helper.provision_tool.return_value = 'tool_path'
606         scenario_helper = mock.Mock()
607         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
608         dpdk_setup_helper.CFG_CONFIG = 'config'
609         dpdk_setup_helper.CFG_SCRIPT = 'script'
610         dpdk_setup_helper.pipeline_kwargs = {}
611         dpdk_setup_helper.all_ports = [0, 1, 2]
612         dpdk_setup_helper.scenario_helper.vnf_cfg = {'lb_config': 'HW',
613                                                      'worker_threads': 1}
614
615         expected = {
616             'cfg_file': 'config',
617             'script': 'script',
618             'port_mask_hex': '0x3',
619             'tool_path': 'tool_path',
620             'hwlb': ' --hwlb 1',
621         }
622         dpdk_setup_helper._build_pipeline_kwargs()
623         self.assertDictEqual(dpdk_setup_helper.pipeline_kwargs, expected)
624
625     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
626     @mock.patch('yardstick.ssh.SSH')
627     def test_setup_vnf_environment(self, *args):
628         def execute(cmd):
629             if cmd.startswith('which '):
630                 return exec_failure
631             return exec_success
632
633         exec_success = (0, 'good output', '')
634         exec_failure = (1, 'bad output', 'error output')
635
636         vnfd_helper = VnfdHelper(self.VNFD_0)
637         ssh_helper = mock.Mock()
638         ssh_helper.execute = execute
639
640         scenario_helper = mock.Mock()
641         scenario_helper.nodes = [None, None]
642         dpdk_vnf_setup_env_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
643         dpdk_vnf_setup_env_helper._validate_cpu_cfg = mock.Mock(return_value=[])
644
645         with mock.patch.object(dpdk_vnf_setup_env_helper, '_setup_dpdk'):
646             self.assertIsInstance(
647                 dpdk_vnf_setup_env_helper.setup_vnf_environment(),
648                 ResourceProfile)
649
650     def test__setup_dpdk(self):
651         ssh_helper = mock.Mock()
652         ssh_helper.execute = mock.Mock()
653         ssh_helper.execute.return_value = (0, 0, 0)
654         dpdk_setup_helper = DpdkVnfSetupEnvHelper(mock.ANY, ssh_helper, mock.ANY)
655         with mock.patch.object(dpdk_setup_helper, '_setup_hugepages') as \
656                 mock_setup_hp:
657             dpdk_setup_helper._setup_dpdk()
658         mock_setup_hp.assert_called_once()
659         ssh_helper.execute.assert_has_calls([
660             mock.call('sudo modprobe uio && sudo modprobe igb_uio'),
661             mock.call('lsmod | grep -i igb_uio')
662         ])
663
664     @mock.patch('yardstick.ssh.SSH')
665     def test__setup_resources(self, _):
666         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
667         ssh_helper = mock.Mock()
668         scenario_helper = mock.Mock()
669         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
670         dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
671
672         dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
673                                        vnfd_helper.interfaces]
674         result = dpdk_setup_helper._setup_resources()
675         self.assertIsInstance(result, ResourceProfile)
676         self.assertEqual(dpdk_setup_helper.socket, 0)
677
678     @mock.patch('yardstick.ssh.SSH')
679     def test__setup_resources_socket_1(self, _):
680         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
681         vnfd_helper.interfaces[0]['virtual-interface']['vpci'] = '0000:55:00.0'
682         vnfd_helper.interfaces[1]['virtual-interface']['vpci'] = '0000:35:00.0'
683         ssh_helper = mock.Mock()
684         scenario_helper = mock.Mock()
685         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
686         dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
687
688         dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
689                                        vnfd_helper.interfaces]
690         result = dpdk_setup_helper._setup_resources()
691         self.assertIsInstance(result, ResourceProfile)
692         self.assertEqual(dpdk_setup_helper.socket, 1)
693
694     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
695     def test__detect_and_bind_drivers(self, *args):
696         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
697         ssh_helper = mock.Mock()
698         # ssh_helper.execute = mock.Mock(return_value = (0, 'text', ''))
699         # ssh_helper.execute.return_value = 0, 'output', ''
700         scenario_helper = mock.Mock()
701         scenario_helper.nodes = [None, None]
702         rv = ['0000:05:00.1', '0000:05:00.0']
703
704         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
705         dpdk_setup_helper.dpdk_bind_helper._get_bound_pci_addresses = mock.Mock(return_value=rv)
706         dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
707         dpdk_setup_helper.dpdk_bind_helper.read_status = mock.Mock()
708
709         self.assertIsNone(dpdk_setup_helper._detect_and_bind_drivers())
710
711         intf_0 = vnfd_helper.vdu[0]['external-interface'][0]['virtual-interface']
712         intf_1 = vnfd_helper.vdu[0]['external-interface'][1]['virtual-interface']
713         self.assertEqual(0, intf_0['dpdk_port_num'])
714         self.assertEqual(1, intf_1['dpdk_port_num'])
715
716     def test_tear_down(self):
717         vnfd_helper = VnfdHelper(self.VNFD_0)
718         ssh_helper = mock.Mock()
719         scenario_helper = mock.Mock()
720         scenario_helper.nodes = [None, None]
721         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
722         dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
723         dpdk_setup_helper.dpdk_bind_helper.used_drivers = {
724             'd1': ['0000:05:00.0'],
725             'd3': ['0000:05:01.0'],
726         }
727
728         self.assertIsNone(dpdk_setup_helper.tear_down())
729         dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(['0000:05:00.0'], 'd1', True)
730         dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(['0000:05:01.0'], 'd3', True)
731
732
733 class TestResourceHelper(unittest.TestCase):
734
735     VNFD_0 = {
736         'short-name': 'VpeVnf',
737         'vdu': [
738             {
739                 'routing_table': [
740                     {
741                         'network': '152.16.100.20',
742                         'netmask': '255.255.255.0',
743                         'gateway': '152.16.100.20',
744                         'if': 'xe0'
745                     },
746                     {
747                         'network': '152.16.40.20',
748                         'netmask': '255.255.255.0',
749                         'gateway': '152.16.40.20',
750                         'if': 'xe1'
751                     },
752                 ],
753                 'description': 'VPE approximation using DPDK',
754                 'name': 'vpevnf-baremetal',
755                 'nd_route_tbl': [
756                     {
757                         'network': '0064:ff9b:0:0:0:0:9810:6414',
758                         'netmask': '112',
759                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
760                         'if': 'xe0'
761                     },
762                     {
763                         'network': '0064:ff9b:0:0:0:0:9810:2814',
764                         'netmask': '112',
765                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
766                         'if': 'xe1'
767                     },
768                 ],
769                 'id': 'vpevnf-baremetal',
770                 'external-interface': [
771                     {
772                         'virtual-interface': {
773                             'dst_mac': '00:00:00:00:00:03',
774                             'vpci': '0000:05:00.0',
775                             'driver': 'i40e',
776                             'local_ip': '152.16.100.19',
777                             'type': 'PCI-PASSTHROUGH',
778                             'netmask': '255.255.255.0',
779                             'dpdk_port_num': 0,
780                             'bandwidth': '10 Gbps',
781                             'dst_ip': '152.16.100.20',
782                             'local_mac': '00:00:00:00:00:01'
783                         },
784                         'vnfd-connection-point-ref': 'xe0',
785                         'name': 'xe0'
786                     },
787                     {
788                         'virtual-interface': {
789                             'dst_mac': '00:00:00:00:00:04',
790                             'vpci': '0000:05:00.1',
791                             'driver': 'ixgbe',
792                             'local_ip': '152.16.40.19',
793                             'type': 'PCI-PASSTHROUGH',
794                             'netmask': '255.255.255.0',
795                             'dpdk_port_num': 1,
796                             'bandwidth': '10 Gbps',
797                             'dst_ip': '152.16.40.20',
798                             'local_mac': '00:00:00:00:00:02'
799                         },
800                         'vnfd-connection-point-ref': 'xe1',
801                         'name': 'xe1'
802                     },
803                 ],
804             },
805         ],
806         'description': 'Vpe approximation using DPDK',
807         'mgmt-interface': {
808             'vdu-id': 'vpevnf-baremetal',
809             'host': '1.1.1.1',
810             'password': 'r00t',
811             'user': 'root',
812             'ip': '1.1.1.1'
813         },
814         'benchmark': {
815             'kpi': [
816                 'packets_in',
817                 'packets_fwd',
818                 'packets_dropped',
819             ],
820         },
821         'connection-point': [
822             {
823                 'type': 'VPORT',
824                 'name': 'xe0',
825             },
826             {
827                 'type': 'VPORT',
828                 'name': 'xe1',
829             },
830         ],
831         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
832     }
833
834     def test_setup(self):
835         resource = object()
836         vnfd_helper = VnfdHelper(self.VNFD_0)
837         ssh_helper = mock.Mock()
838         scenario_helper = mock.Mock()
839         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
840         dpdk_setup_helper.setup_vnf_environment = mock.Mock(return_value=resource)
841         resource_helper = ResourceHelper(dpdk_setup_helper)
842
843         self.assertIsNone(resource_helper.setup())
844         self.assertIs(resource_helper.resource, resource)
845
846     def test_generate_cfg(self):
847         vnfd_helper = VnfdHelper(self.VNFD_0)
848         ssh_helper = mock.Mock()
849         scenario_helper = mock.Mock()
850         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
851         resource_helper = ResourceHelper(dpdk_setup_helper)
852
853         self.assertIsNone(resource_helper.generate_cfg())
854
855     def test_stop_collect(self):
856         vnfd_helper = VnfdHelper(self.VNFD_0)
857         ssh_helper = mock.Mock()
858         scenario_helper = mock.Mock()
859         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
860         resource_helper = ResourceHelper(dpdk_setup_helper)
861         resource_helper.resource = mock.Mock()
862
863         self.assertIsNone(resource_helper.stop_collect())
864
865     def test_stop_collect_none(self):
866         vnfd_helper = VnfdHelper(self.VNFD_0)
867         ssh_helper = mock.Mock()
868         scenario_helper = mock.Mock()
869         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
870         resource_helper = ResourceHelper(dpdk_setup_helper)
871         resource_helper.resource = None
872
873         self.assertIsNone(resource_helper.stop_collect())
874
875
876 class TestClientResourceHelper(unittest.TestCase):
877
878     VNFD_0 = {
879         'short-name': 'VpeVnf',
880         'vdu': [
881             {
882                 'routing_table': [
883                     {
884                         'network': '152.16.100.20',
885                         'netmask': '255.255.255.0',
886                         'gateway': '152.16.100.20',
887                         'if': 'xe0'
888                     },
889                     {
890                         'network': '152.16.40.20',
891                         'netmask': '255.255.255.0',
892                         'gateway': '152.16.40.20',
893                         'if': 'xe1'
894                     },
895                 ],
896                 'description': 'VPE approximation using DPDK',
897                 'name': 'vpevnf-baremetal',
898                 'nd_route_tbl': [
899                     {
900                         'network': '0064:ff9b:0:0:0:0:9810:6414',
901                         'netmask': '112',
902                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
903                         'if': 'xe0'
904                     },
905                     {
906                         'network': '0064:ff9b:0:0:0:0:9810:2814',
907                         'netmask': '112',
908                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
909                         'if': 'xe1'
910                     },
911                 ],
912                 'id': 'vpevnf-baremetal',
913                 'external-interface': [
914                     {
915                         'virtual-interface': {
916                             'dst_mac': '00:00:00:00:00:03',
917                             'vpci': '0000:05:00.0',
918                             'driver': 'i40e',
919                             'local_ip': '152.16.100.19',
920                             'type': 'PCI-PASSTHROUGH',
921                             'netmask': '255.255.255.0',
922                             'dpdk_port_num': 0,
923                             'bandwidth': '10 Gbps',
924                             'dst_ip': '152.16.100.20',
925                             'local_mac': '00:00:00:00:00:01',
926                             'vld_id': 'uplink_0',
927                             'ifname': 'xe0',
928                         },
929                         'vnfd-connection-point-ref': 'xe0',
930                         'name': 'xe0'
931                     },
932                     {
933                         'virtual-interface': {
934                             'dst_mac': '00:00:00:00:00:04',
935                             'vpci': '0000:05:00.1',
936                             'driver': 'ixgbe',
937                             'local_ip': '152.16.40.19',
938                             'type': 'PCI-PASSTHROUGH',
939                             'netmask': '255.255.255.0',
940                             'dpdk_port_num': 1,
941                             'bandwidth': '10 Gbps',
942                             'dst_ip': '152.16.40.20',
943                             'local_mac': '00:00:00:00:00:02',
944                             'vld_id': 'downlink_0',
945                             'ifname': 'xe1',
946                         },
947                         'vnfd-connection-point-ref': 'xe1',
948                         'name': 'xe1'
949                     },
950                     {
951                         'virtual-interface': {
952                             'dst_mac': '00:00:00:00:00:13',
953                             'vpci': '0000:05:00.2',
954                             'driver': 'ixgbe',
955                             'local_ip': '152.16.40.19',
956                             'type': 'PCI-PASSTHROUGH',
957                             'netmask': '255.255.255.0',
958                             'dpdk_port_num': 2,
959                             'bandwidth': '10 Gbps',
960                             'dst_ip': '152.16.40.30',
961                             'local_mac': '00:00:00:00:00:11'
962                         },
963                         'vnfd-connection-point-ref': 'xe2',
964                         'name': 'xe2'
965                     },
966                 ],
967             },
968         ],
969         'description': 'Vpe approximation using DPDK',
970         'mgmt-interface': {
971             'vdu-id': 'vpevnf-baremetal',
972             'host': '1.1.1.1',
973             'password': 'r00t',
974             'user': 'root',
975             'ip': '1.1.1.1'
976         },
977         'benchmark': {
978             'kpi': [
979                 'packets_in',
980                 'packets_fwd',
981                 'packets_dropped',
982             ],
983         },
984         'connection-point': [
985             {
986                 'type': 'VPORT',
987                 'name': 'xe0',
988             },
989             {
990                 'type': 'VPORT',
991                 'name': 'xe1',
992             },
993         ],
994         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
995     }
996
997     VNFD = {
998         'vnfd:vnfd-catalog': {
999             'vnfd': [
1000                 VNFD_0,
1001             ],
1002         },
1003     }
1004
1005     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
1006     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
1007                 new_callable=lambda: MockError)
1008     def test_get_stats_not_connected(self, mock_state_error, *args):
1009         vnfd_helper = VnfdHelper(self.VNFD_0)
1010         ssh_helper = mock.Mock()
1011         scenario_helper = mock.Mock()
1012         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1013         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1014         client_resource_helper.client = mock.MagicMock()
1015         client_resource_helper.client.get_stats.side_effect = mock_state_error
1016
1017         self.assertEqual(client_resource_helper.get_stats(), {})
1018         client_resource_helper.client.get_stats.assert_called_once()
1019
1020     def test_generate_samples(self):
1021         vnfd_helper = VnfdHelper(self.VNFD_0)
1022         ssh_helper = mock.Mock()
1023         scenario_helper = mock.Mock()
1024         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1025         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1026         client_resource_helper.client = mock.MagicMock()
1027         client_resource_helper.client.get_stats.return_value = {
1028             0: {
1029                 'rx_pps': 5.5,
1030                 'tx_pps': 4.9,
1031                 'rx_bps': 234.78,
1032                 'tx_bps': 243.11,
1033                 'ipackets': 34251,
1034                 'opackets': 52342,
1035             },
1036             1: {
1037                 'tx_pps': 5.9,
1038                 'rx_bps': 434.78,
1039                 'opackets': 48791,
1040             },
1041         }
1042
1043         expected = {
1044             'xe0': {
1045                 "rx_throughput_fps": 5.5,
1046                 "tx_throughput_fps": 4.9,
1047                 "rx_throughput_mbps": 234.78,
1048                 "tx_throughput_mbps": 243.11,
1049                 "in_packets": 34251,
1050                 "out_packets": 52342,
1051             },
1052             'xe1': {
1053                 "rx_throughput_fps": 0.0,
1054                 "tx_throughput_fps": 5.9,
1055                 "rx_throughput_mbps": 434.78,
1056                 "tx_throughput_mbps": 0.0,
1057                 "in_packets": 0,
1058                 "out_packets": 48791,
1059             },
1060         }
1061         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1062         result = client_resource_helper.generate_samples(ports)
1063         self.assertDictEqual(result, expected)
1064
1065     def test_generate_samples_with_key(self):
1066         vnfd_helper = VnfdHelper(self.VNFD_0)
1067         ssh_helper = mock.Mock()
1068         scenario_helper = mock.Mock()
1069         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1070         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1071         client_resource_helper.client = mock.MagicMock()
1072         client_resource_helper.client.get_stats.return_value = {
1073             'key_name': 'key_value',
1074             0: {
1075                 'rx_pps': 5.5,
1076                 'tx_pps': 4.9,
1077                 'rx_bps': 234.78,
1078                 'tx_bps': 243.11,
1079                 'ipackets': 34251,
1080                 'opackets': 52342,
1081             },
1082             1: {
1083                 'tx_pps': 5.9,
1084                 'rx_bps': 434.78,
1085                 'opackets': 48791,
1086             },
1087         }
1088
1089         expected = {
1090             'xe0': {
1091                 'key_name': 'key_value',
1092                 "rx_throughput_fps": 5.5,
1093                 "tx_throughput_fps": 4.9,
1094                 "rx_throughput_mbps": 234.78,
1095                 "tx_throughput_mbps": 243.11,
1096                 "in_packets": 34251,
1097                 "out_packets": 52342,
1098             },
1099             'xe1': {
1100                 'key_name': 'key_value',
1101                 "rx_throughput_fps": 0.0,
1102                 "tx_throughput_fps": 5.9,
1103                 "rx_throughput_mbps": 434.78,
1104                 "tx_throughput_mbps": 0.0,
1105                 "in_packets": 0,
1106                 "out_packets": 48791,
1107             },
1108         }
1109         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1110         result = client_resource_helper.generate_samples(ports, 'key_name')
1111         self.assertDictEqual(result, expected)
1112
1113     def test_generate_samples_with_key_and_default(self):
1114         vnfd_helper = VnfdHelper(self.VNFD_0)
1115         ssh_helper = mock.Mock()
1116         scenario_helper = mock.Mock()
1117         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1118         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1119         client_resource_helper.client = mock.MagicMock()
1120         client_resource_helper.client.get_stats.return_value = {
1121             0: {
1122                 'rx_pps': 5.5,
1123                 'tx_pps': 4.9,
1124                 'rx_bps': 234.78,
1125                 'tx_bps': 243.11,
1126                 'ipackets': 34251,
1127                 'opackets': 52342,
1128             },
1129             1: {
1130                 'tx_pps': 5.9,
1131                 'rx_bps': 434.78,
1132                 'opackets': 48791,
1133             },
1134         }
1135
1136         expected = {
1137             'xe0': {
1138                 'key_name': 'default',
1139                 "rx_throughput_fps": 5.5,
1140                 "tx_throughput_fps": 4.9,
1141                 "rx_throughput_mbps": 234.78,
1142                 "tx_throughput_mbps": 243.11,
1143                 "in_packets": 34251,
1144                 "out_packets": 52342,
1145             },
1146             'xe1': {
1147                 'key_name': 'default',
1148                 "rx_throughput_fps": 0.0,
1149                 "tx_throughput_fps": 5.9,
1150                 "rx_throughput_mbps": 434.78,
1151                 "tx_throughput_mbps": 0.0,
1152                 "in_packets": 0,
1153                 "out_packets": 48791,
1154             },
1155         }
1156         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1157         result = client_resource_helper.generate_samples(ports, 'key_name', 'default')
1158         self.assertDictEqual(result, expected)
1159
1160     def test_clear_stats(self):
1161         vnfd_helper = VnfdHelper(self.VNFD_0)
1162         ssh_helper = mock.Mock()
1163         scenario_helper = mock.Mock()
1164         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1165         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1166         client_resource_helper.client = mock.Mock()
1167
1168         self.assertIsNone(client_resource_helper.clear_stats())
1169         client_resource_helper.client.clear_stats.assert_called_once()
1170
1171     def test_clear_stats_of_ports(self):
1172         vnfd_helper = VnfdHelper(self.VNFD_0)
1173         ssh_helper = mock.Mock()
1174         scenario_helper = mock.Mock()
1175         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1176         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1177         client_resource_helper.client = mock.Mock()
1178
1179         self.assertIsNone(client_resource_helper.clear_stats([3, 4]))
1180         client_resource_helper.client.clear_stats.assert_called_once()
1181
1182     def test_start(self):
1183         vnfd_helper = VnfdHelper(self.VNFD_0)
1184         ssh_helper = mock.Mock()
1185         scenario_helper = mock.Mock()
1186         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1187         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1188         client_resource_helper.client = mock.Mock()
1189
1190         self.assertIsNone(client_resource_helper.start())
1191         client_resource_helper.client.start.assert_called_once()
1192
1193     def test_start_ports(self):
1194         vnfd_helper = VnfdHelper(self.VNFD_0)
1195         ssh_helper = mock.Mock()
1196         scenario_helper = mock.Mock()
1197         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1198         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1199         client_resource_helper.client = mock.Mock()
1200
1201         self.assertIsNone(client_resource_helper.start([3, 4]))
1202         client_resource_helper.client.start.assert_called_once()
1203
1204     def test_collect_kpi_with_queue(self):
1205         vnfd_helper = VnfdHelper(self.VNFD_0)
1206         ssh_helper = mock.Mock()
1207         scenario_helper = mock.Mock()
1208         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1209         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1210         client_resource_helper._result = {'existing': 43, 'replaceable': 12}
1211         client_resource_helper._queue = mock.Mock()
1212         client_resource_helper._queue.empty.return_value = False
1213         client_resource_helper._queue.get.return_value = {'incoming': 34, 'replaceable': 99}
1214
1215         expected = {
1216             'existing': 43,
1217             'incoming': 34,
1218             'replaceable': 99,
1219         }
1220         result = client_resource_helper.collect_kpi()
1221         self.assertDictEqual(result, expected)
1222
1223     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1224     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
1225     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
1226                 new_callable=lambda: MockError)
1227     def test__connect_with_failures(self, mock_error, *args):
1228         vnfd_helper = VnfdHelper(self.VNFD_0)
1229         ssh_helper = mock.Mock()
1230         scenario_helper = mock.Mock()
1231         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1232         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1233         client = mock.MagicMock()
1234         client.connect.side_effect = mock_error
1235
1236         self.assertIs(client_resource_helper._connect(client), client)
1237
1238
1239 class TestRfc2544ResourceHelper(unittest.TestCase):
1240
1241     RFC2544_CFG_1 = {
1242         'latency': True,
1243         'correlated_traffic': True,
1244         'allowed_drop_rate': '0.1 - 0.15',
1245     }
1246
1247     RFC2544_CFG_2 = {
1248         'allowed_drop_rate': '  0.25    -   0.05  ',
1249     }
1250
1251     RFC2544_CFG_3 = {
1252         'allowed_drop_rate': '0.2',
1253     }
1254
1255     RFC2544_CFG_4 = {
1256         'latency': True,
1257     }
1258
1259     SCENARIO_CFG_1 = {
1260         'options': {
1261             'rfc2544': RFC2544_CFG_1,
1262         }
1263     }
1264
1265     SCENARIO_CFG_2 = {
1266         'options': {
1267             'rfc2544': RFC2544_CFG_2,
1268         }
1269     }
1270
1271     SCENARIO_CFG_3 = {
1272         'options': {
1273             'rfc2544': RFC2544_CFG_3,
1274         }
1275     }
1276
1277     SCENARIO_CFG_4 = {
1278         'options': {
1279             'rfc2544': RFC2544_CFG_4,
1280         }
1281     }
1282
1283     def test_property_rfc2544(self):
1284         scenario_helper = ScenarioHelper('name1')
1285         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1286         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1287
1288         self.assertIsNone(rfc2544_resource_helper._rfc2544)
1289         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1290         self.assertDictEqual(rfc2544_resource_helper._rfc2544, self.RFC2544_CFG_1)
1291         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1292         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1293
1294     def test_property_tolerance_high(self):
1295         scenario_helper = ScenarioHelper('name1')
1296         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1297         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1298
1299         self.assertIsNone(rfc2544_resource_helper._tolerance_high)
1300         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1301         self.assertEqual(rfc2544_resource_helper._tolerance_high, 0.15)
1302         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1303         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1304
1305     def test_property_tolerance_low(self):
1306         scenario_helper = ScenarioHelper('name1')
1307         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1308         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1309
1310         self.assertIsNone(rfc2544_resource_helper._tolerance_low)
1311         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1312         self.assertEqual(rfc2544_resource_helper._tolerance_low, 0.1)
1313         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1314         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1315
1316     def test_property_tolerance_high_range_swap(self):
1317         scenario_helper = ScenarioHelper('name1')
1318         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1319         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1320
1321         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.25)
1322
1323     def test_property_tolerance_low_range_swap(self):
1324         scenario_helper = ScenarioHelper('name1')
1325         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1326         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1327
1328         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.05)
1329
1330     def test_property_tolerance_high_not_range(self):
1331         scenario_helper = ScenarioHelper('name1')
1332         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1333         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1334
1335         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.2)
1336
1337     def test_property_tolerance_low_not_range(self):
1338         scenario_helper = ScenarioHelper('name1')
1339         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1340         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1341
1342         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.2)
1343
1344     def test_property_tolerance_high_default(self):
1345         scenario_helper = ScenarioHelper('name1')
1346         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1347         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1348
1349         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.0001)
1350
1351     def test_property_tolerance_low_default(self):
1352         scenario_helper = ScenarioHelper('name1')
1353         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1354         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1355
1356         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.0001)
1357
1358     def test_property_latency(self):
1359         scenario_helper = ScenarioHelper('name1')
1360         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1361         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1362
1363         self.assertIsNone(rfc2544_resource_helper._latency)
1364         self.assertTrue(rfc2544_resource_helper.latency)
1365         self.assertTrue(rfc2544_resource_helper._latency)
1366         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1367         self.assertTrue(rfc2544_resource_helper.latency)
1368
1369     def test_property_latency_default(self):
1370         scenario_helper = ScenarioHelper('name1')
1371         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1372         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1373
1374         self.assertFalse(rfc2544_resource_helper.latency)
1375
1376     def test_property_correlated_traffic(self):
1377         scenario_helper = ScenarioHelper('name1')
1378         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1379         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1380
1381         self.assertIsNone(rfc2544_resource_helper._correlated_traffic)
1382         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1383         self.assertTrue(rfc2544_resource_helper._correlated_traffic)
1384         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1385         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1386
1387     def test_property_correlated_traffic_default(self):
1388         scenario_helper = ScenarioHelper('name1')
1389         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1390         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1391
1392         self.assertFalse(rfc2544_resource_helper.correlated_traffic)
1393
1394
1395 class TestSampleVNFDeployHelper(unittest.TestCase):
1396
1397     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1398     @mock.patch('subprocess.check_output')
1399     def test_deploy_vnfs_disabled(self, *_):
1400         vnfd_helper = mock.Mock()
1401         ssh_helper = mock.Mock()
1402         ssh_helper.join_bin_path.return_value = 'joined_path'
1403         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1404         ssh_helper.put.return_value = None
1405         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1406
1407         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1408         sample_vnf_deploy_helper.DISABLE_DEPLOY = True
1409         self.assertEqual(ssh_helper.execute.call_count, 5)
1410         ssh_helper.put.assert_called_once()
1411
1412     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1413     @mock.patch('subprocess.check_output')
1414     def test_deploy_vnfs(self, *args):
1415         vnfd_helper = mock.Mock()
1416         ssh_helper = mock.Mock()
1417         ssh_helper.join_bin_path.return_value = 'joined_path'
1418         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1419         ssh_helper.put.return_value = None
1420         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1421         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1422
1423         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1424         self.assertEqual(ssh_helper.execute.call_count, 5)
1425         ssh_helper.put.assert_called_once()
1426
1427     @mock.patch('subprocess.check_output')
1428     def test_deploy_vnfs_early_success(self, *args):
1429         vnfd_helper = mock.Mock()
1430         ssh_helper = mock.Mock()
1431         ssh_helper.join_bin_path.return_value = 'joined_path'
1432         ssh_helper.execute.return_value = 0, 'output', ''
1433         ssh_helper.put.return_value = None
1434         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1435         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1436
1437         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1438         ssh_helper.execute.assert_called_once()
1439         ssh_helper.put.assert_not_called()
1440
1441
1442 class TestScenarioHelper(unittest.TestCase):
1443
1444     def test_property_task_path(self):
1445         scenario_helper = ScenarioHelper('name1')
1446         scenario_helper.scenario_cfg = {
1447             'task_path': 'my_path',
1448         }
1449
1450         self.assertEqual(scenario_helper.task_path, 'my_path')
1451
1452     def test_property_nodes(self):
1453         nodes = ['node1', 'node2']
1454         scenario_helper = ScenarioHelper('name1')
1455         scenario_helper.scenario_cfg = {
1456             'nodes': nodes,
1457         }
1458
1459         self.assertEqual(scenario_helper.nodes, nodes)
1460
1461     def test_property_all_options(self):
1462         data = {
1463             'name1': {
1464                 'key3': 'value3',
1465             },
1466             'name2': {}
1467         }
1468         scenario_helper = ScenarioHelper('name1')
1469         scenario_helper.scenario_cfg = {
1470             'options': data,
1471         }
1472
1473         self.assertDictEqual(scenario_helper.all_options, data)
1474
1475     def test_property_options(self):
1476         data = {
1477             'key1': 'value1',
1478             'key2': 'value2',
1479         }
1480         scenario_helper = ScenarioHelper('name1')
1481         scenario_helper.scenario_cfg = {
1482             'options': {
1483                 'name1': data,
1484             },
1485         }
1486
1487         self.assertDictEqual(scenario_helper.options, data)
1488
1489     def test_property_vnf_cfg(self):
1490         scenario_helper = ScenarioHelper('name1')
1491         scenario_helper.scenario_cfg = {
1492             'options': {
1493                 'name1': {
1494                     'vnf_config': 'my_config',
1495                 },
1496             },
1497         }
1498
1499         self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
1500
1501     def test_property_vnf_cfg_default(self):
1502         scenario_helper = ScenarioHelper('name1')
1503         scenario_helper.scenario_cfg = {
1504             'options': {
1505                 'name1': {},
1506             },
1507         }
1508
1509         self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
1510
1511     def test_property_topology(self):
1512         scenario_helper = ScenarioHelper('name1')
1513         scenario_helper.scenario_cfg = {
1514             'topology': 'my_topology',
1515         }
1516
1517         self.assertEqual(scenario_helper.topology, 'my_topology')
1518
1519
1520 class TestSampleVnf(unittest.TestCase):
1521
1522     VNFD_0 = {
1523         'short-name': 'VpeVnf',
1524         'vdu': [
1525             {
1526                 'routing_table': [
1527                     {
1528                         'network': '152.16.100.20',
1529                         'netmask': '255.255.255.0',
1530                         'gateway': '152.16.100.20',
1531                         'if': 'xe0'
1532                     },
1533                     {
1534                         'network': '152.16.40.20',
1535                         'netmask': '255.255.255.0',
1536                         'gateway': '152.16.40.20',
1537                         'if': 'xe1'
1538                     },
1539                 ],
1540                 'description': 'VPE approximation using DPDK',
1541                 'name': 'vpevnf-baremetal',
1542                 'nd_route_tbl': [
1543                     {
1544                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1545                         'netmask': '112',
1546                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1547                         'if': 'xe0'
1548                     },
1549                     {
1550                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1551                         'netmask': '112',
1552                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1553                         'if': 'xe1'
1554                     },
1555                 ],
1556                 'id': 'vpevnf-baremetal',
1557                 'external-interface': [
1558                     {
1559                         'virtual-interface': {
1560                             'dst_mac': '00:00:00:00:00:03',
1561                             'vpci': '0000:05:00.0',
1562                             'local_ip': '152.16.100.19',
1563                             'type': 'PCI-PASSTHROUGH',
1564                             'netmask': '255.255.255.0',
1565                             'dpdk_port_num': 0,
1566                             'bandwidth': '10 Gbps',
1567                             'dst_ip': '152.16.100.20',
1568                             'local_mac': '00:00:00:00:00:01'
1569                         },
1570                         'vnfd-connection-point-ref': 'xe0',
1571                         'name': 'xe0'
1572                     },
1573                     {
1574                         'virtual-interface': {
1575                             'dst_mac': '00:00:00:00:00:04',
1576                             'vpci': '0000:05:00.1',
1577                             'local_ip': '152.16.40.19',
1578                             'type': 'PCI-PASSTHROUGH',
1579                             'netmask': '255.255.255.0',
1580                             'dpdk_port_num': 1,
1581                             'bandwidth': '10 Gbps',
1582                             'dst_ip': '152.16.40.20',
1583                             'local_mac': '00:00:00:00:00:02'
1584                         },
1585                         'vnfd-connection-point-ref': 'xe1',
1586                         'name': 'xe1'
1587                     },
1588                 ],
1589             },
1590         ],
1591         'description': 'Vpe approximation using DPDK',
1592         'mgmt-interface': {
1593             'vdu-id': 'vpevnf-baremetal',
1594             'host': '1.1.1.1',
1595             'password': 'r00t',
1596             'user': 'root',
1597             'ip': '1.1.1.1'
1598         },
1599         'benchmark': {
1600             'kpi': [
1601                 'packets_in',
1602                 'packets_fwd',
1603                 'packets_dropped',
1604             ],
1605         },
1606         'connection-point': [
1607             {
1608                 'type': 'VPORT',
1609                 'name': 'xe0',
1610             },
1611             {
1612                 'type': 'VPORT',
1613                 'name': 'xe1',
1614             },
1615         ],
1616         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1617     }
1618
1619     VNFD = {
1620         'vnfd:vnfd-catalog': {
1621             'vnfd': [
1622                 VNFD_0,
1623             ]
1624         }
1625     }
1626
1627     TRAFFIC_PROFILE = {
1628         "schema": "isb:traffic_profile:0.1",
1629         "name": "fixed",
1630         "description": "Fixed traffic profile to run UDP traffic",
1631         "traffic_profile": {
1632             "traffic_type": "FixedTraffic",
1633             "frame_rate": 100,  # pps
1634             "flow_number": 10,
1635             "frame_size": 64,
1636         },
1637     }
1638
1639     def test___init__(self):
1640         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1641
1642         self.assertEqual(sample_vnf.name, 'vnf1')
1643         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1644
1645         # test the default setup helper is SetupEnvHelper, not subclass
1646         self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
1647
1648         # test the default resource helper is ResourceHelper, not subclass
1649         self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
1650
1651     def test___init___alt_types(self):
1652         class MySetupEnvHelper(SetupEnvHelper):
1653             pass
1654
1655         class MyResourceHelper(ResourceHelper):
1656             pass
1657
1658         sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
1659
1660         self.assertEqual(sample_vnf.name, 'vnf1')
1661         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1662
1663         # test the default setup helper is MySetupEnvHelper, not subclass
1664         self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
1665
1666         # test the default resource helper is MyResourceHelper, not subclass
1667         self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
1668
1669     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1670     def test__start_vnf(self, *args):
1671         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1672         sample_vnf = SampleVNF('vnf1', vnfd)
1673         sample_vnf._run = mock.Mock()
1674
1675         self.assertIsNone(sample_vnf.queue_wrapper)
1676         self.assertIsNone(sample_vnf._vnf_process)
1677         self.assertIsNone(sample_vnf._start_vnf())
1678         self.assertIsNotNone(sample_vnf.queue_wrapper)
1679         self.assertIsNotNone(sample_vnf._vnf_process)
1680
1681     @mock.patch("yardstick.ssh.SSH")
1682     def test_instantiate(self, ssh):
1683         mock_ssh(ssh)
1684
1685         nodes = {
1686             'vnf1': 'name1',
1687             'vnf2': 'name2',
1688         }
1689
1690         context1 = mock.Mock()
1691         context1._get_server.return_value = None
1692         context2 = mock.Mock()
1693         context2._get_server.return_value = context2
1694
1695         try:
1696             Context.list.clear()
1697         except AttributeError:
1698             # clear() but works in Py2.7
1699             Context.list[:] = []
1700
1701         Context.list.extend([
1702             context1,
1703             context2,
1704         ])
1705
1706         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1707         sample_vnf = SampleVNF('vnf1', vnfd)
1708         sample_vnf.APP_NAME = 'sample1'
1709         sample_vnf._start_server = mock.Mock(return_value=0)
1710         sample_vnf._vnf_process = mock.MagicMock()
1711         sample_vnf._vnf_process._is_alive.return_value = 1
1712         sample_vnf.ssh_helper = mock.MagicMock()
1713         sample_vnf.deploy_helper = mock.MagicMock()
1714         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1715         scenario_cfg = {
1716             'nodes': nodes,
1717         }
1718
1719         self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
1720         self.assertEqual(sample_vnf.nfvi_context, context2)
1721
1722     def test__update_collectd_options(self):
1723         scenario_cfg = {'options':
1724                             {'collectd':
1725                                  {'interval': 3,
1726                                   'plugins':
1727                                       {'plugin3': {'param': 3}}},
1728                              'vnf__0':
1729                                  {'collectd':
1730                                       {'interval': 2,
1731                                        'plugins':
1732                                            {'plugin3': {'param': 2},
1733                                             'plugin2': {'param': 2}}}}}}
1734         context_cfg = {'nodes':
1735                            {'vnf__0':
1736                                 {'collectd':
1737                                      {'interval': 1,
1738                                       'plugins':
1739                                           {'plugin3': {'param': 1},
1740                                            'plugin2': {'param': 1},
1741                                            'plugin1': {'param': 1}}}}}}
1742         expected = {'interval': 1,
1743                     'plugins':
1744                         {'plugin3': {'param': 1},
1745                          'plugin2': {'param': 1},
1746                          'plugin1': {'param': 1}}}
1747
1748         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1749         sample_vnf = SampleVNF('vnf__0', vnfd)
1750         sample_vnf._update_collectd_options(scenario_cfg, context_cfg)
1751         self.assertEqual(sample_vnf.setup_helper.collectd_options, expected)
1752
1753     def test__update_options(self):
1754         options1 = {'interval': 1,
1755                     'param1': 'value1',
1756                     'plugins':
1757                         {'plugin3': {'param': 3},
1758                          'plugin2': {'param': 1},
1759                          'plugin1': {'param': 1}}}
1760         options2 = {'interval': 2,
1761                     'param2': 'value2',
1762                     'plugins':
1763                         {'plugin4': {'param': 4},
1764                          'plugin2': {'param': 2},
1765                          'plugin1': {'param': 2}}}
1766         expected = {'interval': 1,
1767                     'param1': 'value1',
1768                     'param2': 'value2',
1769                     'plugins':
1770                         {'plugin4': {'param': 4},
1771                          'plugin3': {'param': 3},
1772                          'plugin2': {'param': 1},
1773                          'plugin1': {'param': 1}}}
1774
1775         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1776         sample_vnf = SampleVNF('vnf1', vnfd)
1777         sample_vnf._update_options(options2, options1)
1778         self.assertEqual(options2, expected)
1779
1780     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1781     @mock.patch("yardstick.ssh.SSH")
1782     def test_wait_for_instantiate_empty_queue(self, ssh, *args):
1783         mock_ssh(ssh, exec_result=(1, "", ""))
1784
1785         queue_size_list = [
1786             0,
1787             1,
1788             0,
1789             1,
1790         ]
1791
1792         queue_get_list = [
1793             'some output',
1794             'pipeline> ',
1795         ]
1796
1797         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1798         sample_vnf = SampleVNF('vnf1', vnfd)
1799         sample_vnf.APP_NAME = 'sample1'
1800         sample_vnf.WAIT_TIME_FOR_SCRIPT = 0
1801         sample_vnf._start_server = mock.Mock(return_value=0)
1802         sample_vnf._vnf_process = mock.MagicMock()
1803         sample_vnf._vnf_process.exitcode = 0
1804         sample_vnf._vnf_process._is_alive.return_value = 1
1805         sample_vnf.queue_wrapper = mock.Mock()
1806         sample_vnf.q_out = mock.Mock()
1807         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1808         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1809         sample_vnf.ssh_helper = mock.MagicMock()
1810         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1811         sample_vnf.resource_helper.start_collect = mock.MagicMock()
1812
1813         self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
1814
1815     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1816     def test_vnf_execute_with_queue_data(self, *args):
1817         queue_size_list = [
1818             1,
1819             1,
1820             0,
1821         ]
1822
1823         queue_get_list = [
1824             'hello ',
1825             'world'
1826         ]
1827
1828         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1829         sample_vnf = SampleVNF('vnf1', vnfd)
1830         sample_vnf.APP_NAME = 'sample1'
1831         sample_vnf.q_out = mock.Mock()
1832         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1833         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1834
1835         self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
1836
1837     def test_terminate_without_vnf_process(self):
1838         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1839         sample_vnf = SampleVNF('vnf1', vnfd)
1840         sample_vnf.APP_NAME = 'sample1'
1841         sample_vnf.vnf_execute = mock.Mock()
1842         sample_vnf.ssh_helper = mock.Mock()
1843         sample_vnf._tear_down = mock.Mock()
1844         sample_vnf.resource_helper = mock.Mock()
1845
1846         self.assertIsNone(sample_vnf.terminate())
1847
1848     def test_get_stats(self):
1849         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1850         sample_vnf = SampleVNF('vnf1', vnfd)
1851         sample_vnf.APP_NAME = 'sample1'
1852         sample_vnf.APP_WORD = 'sample1'
1853         sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
1854
1855         self.assertEqual(sample_vnf.get_stats(), 'the stats')
1856
1857     def test_collect_kpi(self):
1858         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1859         sample_vnf = SampleVNF('vnf1', vnfd)
1860         sample_vnf.APP_NAME = 'sample1'
1861         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1862         sample_vnf.COLLECT_MAP = {
1863             'k1': 3,
1864             'k2': 1,
1865             'k3': 2,
1866         }
1867         sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1868         sample_vnf.resource_helper = mock.Mock()
1869         sample_vnf.resource_helper.collect_kpi.return_value = {}
1870
1871         expected = {
1872             'k1': 27,
1873             'k2': 34,
1874             'k3': 91,
1875             'collect_stats': {},
1876         }
1877         result = sample_vnf.collect_kpi()
1878         self.assertDictEqual(result, expected)
1879
1880     def test_collect_kpi_default(self):
1881         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1882         sample_vnf = SampleVNF('vnf1', vnfd)
1883         sample_vnf.APP_NAME = 'sample1'
1884         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1885         sample_vnf.get_stats = mock.Mock(return_value='')
1886
1887         expected = {
1888             'packets_in': 0,
1889             'packets_fwd': 0,
1890             'packets_dropped': 0,
1891         }
1892         result = sample_vnf.collect_kpi()
1893         self.assertDictEqual(result, expected)
1894
1895     def test_scale(self):
1896         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1897         sample_vnf = SampleVNF('vnf1', vnfd)
1898         self.assertRaises(y_exceptions.FunctionNotImplemented,
1899                           sample_vnf.scale)
1900
1901     def test__run(self):
1902         test_cmd = 'test cmd'
1903         run_kwargs = {'arg1': 'val1', 'arg2': 'val2'}
1904         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1905         sample_vnf = SampleVNF('vnf1', vnfd)
1906         sample_vnf.ssh_helper = mock.Mock()
1907         sample_vnf.setup_helper = mock.Mock()
1908         with mock.patch.object(sample_vnf, '_build_config',
1909                                return_value=test_cmd), \
1910                 mock.patch.object(sample_vnf, '_build_run_kwargs'):
1911             sample_vnf.run_kwargs = run_kwargs
1912             sample_vnf._run()
1913         sample_vnf.ssh_helper.drop_connection.assert_called_once()
1914         sample_vnf.ssh_helper.run.assert_called_once_with(test_cmd,
1915                                                           **run_kwargs)
1916         sample_vnf.setup_helper.kill_vnf.assert_called_once()
1917
1918
1919 class TestSampleVNFTrafficGen(unittest.TestCase):
1920
1921     VNFD_0 = {
1922         'short-name': 'VpeVnf',
1923         'vdu': [
1924             {
1925                 'routing_table': [
1926                     {
1927                         'network': '152.16.100.20',
1928                         'netmask': '255.255.255.0',
1929                         'gateway': '152.16.100.20',
1930                         'if': 'xe0'
1931                     },
1932                     {
1933                         'network': '152.16.40.20',
1934                         'netmask': '255.255.255.0',
1935                         'gateway': '152.16.40.20',
1936                         'if': 'xe1'
1937                     },
1938                 ],
1939                 'description': 'VPE approximation using DPDK',
1940                 'name': 'vpevnf-baremetal',
1941                 'nd_route_tbl': [
1942                     {
1943                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1944                         'netmask': '112',
1945                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1946                         'if': 'xe0'
1947                     },
1948                     {
1949                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1950                         'netmask': '112',
1951                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1952                         'if': 'xe1'
1953                     },
1954                 ],
1955                 'id': 'vpevnf-baremetal',
1956                 'external-interface': [
1957                     {
1958                         'virtual-interface': {
1959                             'dst_mac': '00:00:00:00:00:03',
1960                             'vpci': '0000:05:00.0',
1961                             'driver': 'i40e',
1962                             'local_ip': '152.16.100.19',
1963                             'type': 'PCI-PASSTHROUGH',
1964                             'netmask': '255.255.255.0',
1965                             'dpdk_port_num': 0,
1966                             'bandwidth': '10 Gbps',
1967                             'dst_ip': '152.16.100.20',
1968                             'local_mac': '00:00:00:00:00:01'
1969                         },
1970                         'vnfd-connection-point-ref': 'xe0',
1971                         'name': 'xe0'
1972                     },
1973                     {
1974                         'virtual-interface': {
1975                             'dst_mac': '00:00:00:00:00:04',
1976                             'vpci': '0000:05:00.1',
1977                             'driver': 'ixgbe',
1978                             'local_ip': '152.16.40.19',
1979                             'type': 'PCI-PASSTHROUGH',
1980                             'netmask': '255.255.255.0',
1981                             'dpdk_port_num': 1,
1982                             'bandwidth': '10 Gbps',
1983                             'dst_ip': '152.16.40.20',
1984                             'local_mac': '00:00:00:00:00:02'
1985                         },
1986                         'vnfd-connection-point-ref': 'xe1',
1987                         'name': 'xe1'
1988                     },
1989                 ],
1990             },
1991         ],
1992         'description': 'Vpe approximation using DPDK',
1993         'mgmt-interface': {
1994             'vdu-id': 'vpevnf-baremetal',
1995             'host': '1.1.1.1',
1996             'password': 'r00t',
1997             'user': 'root',
1998             'ip': '1.1.1.1'
1999         },
2000         'benchmark': {
2001             'kpi': [
2002                 'packets_in',
2003                 'packets_fwd',
2004                 'packets_dropped',
2005             ],
2006         },
2007         'connection-point': [
2008             {
2009                 'type': 'VPORT',
2010                 'name': 'xe0',
2011             },
2012             {
2013                 'type': 'VPORT',
2014                 'name': 'xe1',
2015             },
2016         ],
2017         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
2018     }
2019
2020     VNFD = {
2021         'vnfd:vnfd-catalog': {
2022             'vnfd': [
2023                 VNFD_0,
2024             ],
2025         },
2026     }
2027
2028     TRAFFIC_PROFILE = {
2029         "schema": "isb:traffic_profile:0.1",
2030         "name": "fixed",
2031         "description": "Fixed traffic profile to run UDP traffic",
2032         "traffic_profile": {
2033             "traffic_type": "FixedTraffic",
2034             "frame_rate": 100,  # pps
2035             "flow_number": 10,
2036             "frame_size": 64,
2037         },
2038     }
2039
2040     def test__check_status(self):
2041         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2042
2043         with self.assertRaises(NotImplementedError):
2044             sample_vnf_tg._check_status()
2045
2046     def test_listen_traffic(self):
2047         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2048
2049         sample_vnf_tg.listen_traffic(mock.Mock())
2050
2051     def test_verify_traffic(self):
2052         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2053
2054         sample_vnf_tg.verify_traffic(mock.Mock())
2055
2056     def test_terminate(self):
2057         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2058         sample_vnf_tg._traffic_process = mock.Mock()
2059         sample_vnf_tg._tg_process = mock.Mock()
2060
2061         sample_vnf_tg.terminate()
2062
2063     def test__wait_for_process(self):
2064         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2065         with mock.patch.object(sample_vnf_tg, '_check_status',
2066                                return_value=0) as mock_status, \
2067                 mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
2068             mock_proc.is_alive.return_value = True
2069             mock_proc.exitcode = 234
2070             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
2071             mock_proc.is_alive.assert_called_once()
2072             mock_status.assert_called_once()
2073
2074     def test__wait_for_process_not_alive(self):
2075         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2076         with mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
2077             mock_proc.is_alive.return_value = False
2078             self.assertRaises(RuntimeError, sample_vnf_tg._wait_for_process)
2079             mock_proc.is_alive.assert_called_once()
2080
2081     def test__wait_for_process_delayed(self):
2082         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2083         with mock.patch.object(sample_vnf_tg, '_check_status',
2084                                side_effect=[1, 0]) as mock_status, \
2085                 mock.patch.object(sample_vnf_tg,
2086                                   '_tg_process') as mock_proc:
2087             mock_proc.is_alive.return_value = True
2088             mock_proc.exitcode = 234
2089             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
2090             mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()])
2091             mock_status.assert_has_calls([mock.call(), mock.call()])
2092
2093     def test_scale(self):
2094         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2095         self.assertRaises(y_exceptions.FunctionNotImplemented,
2096                           sample_vnf_tg.scale)