Merge "Install dependencies: bare-metal, standalone"
[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         self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
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         self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
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         self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
238         self.assertEqual(mock_provision_tool.call_count, 1)
239
240         ssh_helper.provision_tool(tool_file='my_tool.sh')
241         self.assertTrue(ssh_helper.is_connected)
242         self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
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         self.assertEqual(mock_paramiko.SSHClient.call_count, 1)
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.all_options = {}
576         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
577
578         dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
579         result = dpdk_setup_helper.build_config()
580         self.assertEqual(result, expected)
581         self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2)
582         self.assertGreaterEqual(mock_find.call_count, 1)
583         self.assertGreaterEqual(mock_multi_port_config.generate_config.call_count, 1)
584         self.assertGreaterEqual(mock_multi_port_config.generate_script.call_count, 1)
585
586         scenario_helper.vnf_cfg = {'file': 'fake_file'}
587         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
588         mock_open_rf.side_effect = mock.mock_open(read_data='fake_data')
589         dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command'
590
591         result = dpdk_setup_helper.build_config()
592
593         mock_open_rf.assert_called_once()
594         self.assertEqual(result, expected)
595         self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2)
596         self.assertGreaterEqual(mock_find.call_count, 1)
597         self.assertGreaterEqual(mock_multi_port_config.generate_config.call_count, 1)
598         self.assertGreaterEqual(mock_multi_port_config.generate_script.call_count, 1)
599
600     def test__build_pipeline_kwargs(self):
601         vnfd_helper = VnfdHelper(self.VNFD_0)
602         ssh_helper = mock.Mock()
603         ssh_helper.provision_tool.return_value = 'tool_path'
604         scenario_helper = mock.Mock()
605         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
606         dpdk_setup_helper.CFG_CONFIG = 'config'
607         dpdk_setup_helper.CFG_SCRIPT = 'script'
608         dpdk_setup_helper.pipeline_kwargs = {}
609         dpdk_setup_helper.all_ports = [0, 1, 2]
610         dpdk_setup_helper.scenario_helper.vnf_cfg = {'lb_config': 'HW',
611                                                      'worker_threads': 1}
612
613         expected = {
614             'cfg_file': 'config',
615             'script': 'script',
616             'port_mask_hex': '0x3',
617             'tool_path': 'tool_path',
618             'hwlb': ' --hwlb 1',
619         }
620         dpdk_setup_helper._build_pipeline_kwargs()
621         self.assertDictEqual(dpdk_setup_helper.pipeline_kwargs, expected)
622
623     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
624     @mock.patch('yardstick.ssh.SSH')
625     def test_setup_vnf_environment(self, *args):
626         def execute(cmd):
627             if cmd.startswith('which '):
628                 return exec_failure
629             return exec_success
630
631         exec_success = (0, 'good output', '')
632         exec_failure = (1, 'bad output', 'error output')
633
634         vnfd_helper = VnfdHelper(self.VNFD_0)
635         ssh_helper = mock.Mock()
636         ssh_helper.execute = execute
637
638         scenario_helper = mock.Mock()
639         scenario_helper.nodes = [None, None]
640         dpdk_vnf_setup_env_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
641         dpdk_vnf_setup_env_helper._validate_cpu_cfg = mock.Mock(return_value=[])
642
643         with mock.patch.object(dpdk_vnf_setup_env_helper, '_setup_dpdk'):
644             self.assertIsInstance(
645                 dpdk_vnf_setup_env_helper.setup_vnf_environment(),
646                 ResourceProfile)
647
648     def test__setup_dpdk(self):
649         ssh_helper = mock.Mock()
650         ssh_helper.execute = mock.Mock()
651         ssh_helper.execute.return_value = (0, 0, 0)
652         dpdk_setup_helper = DpdkVnfSetupEnvHelper(mock.ANY, ssh_helper, mock.ANY)
653         with mock.patch.object(dpdk_setup_helper, '_setup_hugepages') as \
654                 mock_setup_hp:
655             dpdk_setup_helper._setup_dpdk()
656         mock_setup_hp.assert_called_once()
657         ssh_helper.execute.assert_has_calls([
658             mock.call('sudo modprobe uio && sudo modprobe igb_uio'),
659             mock.call('lsmod | grep -i igb_uio')
660         ])
661
662     @mock.patch('yardstick.ssh.SSH')
663     def test__setup_resources(self, _):
664         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
665         ssh_helper = mock.Mock()
666         scenario_helper = mock.Mock()
667         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
668         dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
669
670         dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
671                                        vnfd_helper.interfaces]
672         result = dpdk_setup_helper._setup_resources()
673         self.assertIsInstance(result, ResourceProfile)
674         self.assertEqual(dpdk_setup_helper.socket, 0)
675
676     @mock.patch('yardstick.ssh.SSH')
677     def test__setup_resources_socket_1(self, _):
678         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
679         vnfd_helper.interfaces[0]['virtual-interface']['vpci'] = '0000:55:00.0'
680         vnfd_helper.interfaces[1]['virtual-interface']['vpci'] = '0000:35:00.0'
681         ssh_helper = mock.Mock()
682         scenario_helper = mock.Mock()
683         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
684         dpdk_setup_helper._validate_cpu_cfg = mock.Mock()
685
686         dpdk_setup_helper.bound_pci = [v['virtual-interface']["vpci"] for v in
687                                        vnfd_helper.interfaces]
688         result = dpdk_setup_helper._setup_resources()
689         self.assertIsInstance(result, ResourceProfile)
690         self.assertEqual(dpdk_setup_helper.socket, 1)
691
692     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
693     def test__detect_and_bind_drivers(self, *args):
694         vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0))
695         ssh_helper = mock.Mock()
696         # ssh_helper.execute = mock.Mock(return_value = (0, 'text', ''))
697         # ssh_helper.execute.return_value = 0, 'output', ''
698         scenario_helper = mock.Mock()
699         scenario_helper.nodes = [None, None]
700         rv = ['0000:05:00.1', '0000:05:00.0']
701
702         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
703         dpdk_setup_helper.dpdk_bind_helper._get_bound_pci_addresses = mock.Mock(return_value=rv)
704         dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
705         dpdk_setup_helper.dpdk_bind_helper.read_status = mock.Mock()
706
707         self.assertIsNone(dpdk_setup_helper._detect_and_bind_drivers())
708
709         intf_0 = vnfd_helper.vdu[0]['external-interface'][0]['virtual-interface']
710         intf_1 = vnfd_helper.vdu[0]['external-interface'][1]['virtual-interface']
711         self.assertEqual(0, intf_0['dpdk_port_num'])
712         self.assertEqual(1, intf_1['dpdk_port_num'])
713
714     def test_tear_down(self):
715         vnfd_helper = VnfdHelper(self.VNFD_0)
716         ssh_helper = mock.Mock()
717         scenario_helper = mock.Mock()
718         scenario_helper.nodes = [None, None]
719         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
720         dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock()
721         dpdk_setup_helper.dpdk_bind_helper.used_drivers = {
722             'd1': ['0000:05:00.0'],
723             'd3': ['0000:05:01.0'],
724         }
725
726         self.assertIsNone(dpdk_setup_helper.tear_down())
727         dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(['0000:05:00.0'], 'd1', True)
728         dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call(['0000:05:01.0'], 'd3', True)
729
730
731 class TestResourceHelper(unittest.TestCase):
732
733     VNFD_0 = {
734         'short-name': 'VpeVnf',
735         'vdu': [
736             {
737                 'routing_table': [
738                     {
739                         'network': '152.16.100.20',
740                         'netmask': '255.255.255.0',
741                         'gateway': '152.16.100.20',
742                         'if': 'xe0'
743                     },
744                     {
745                         'network': '152.16.40.20',
746                         'netmask': '255.255.255.0',
747                         'gateway': '152.16.40.20',
748                         'if': 'xe1'
749                     },
750                 ],
751                 'description': 'VPE approximation using DPDK',
752                 'name': 'vpevnf-baremetal',
753                 'nd_route_tbl': [
754                     {
755                         'network': '0064:ff9b:0:0:0:0:9810:6414',
756                         'netmask': '112',
757                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
758                         'if': 'xe0'
759                     },
760                     {
761                         'network': '0064:ff9b:0:0:0:0:9810:2814',
762                         'netmask': '112',
763                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
764                         'if': 'xe1'
765                     },
766                 ],
767                 'id': 'vpevnf-baremetal',
768                 'external-interface': [
769                     {
770                         'virtual-interface': {
771                             'dst_mac': '00:00:00:00:00:03',
772                             'vpci': '0000:05:00.0',
773                             'driver': 'i40e',
774                             'local_ip': '152.16.100.19',
775                             'type': 'PCI-PASSTHROUGH',
776                             'netmask': '255.255.255.0',
777                             'dpdk_port_num': 0,
778                             'bandwidth': '10 Gbps',
779                             'dst_ip': '152.16.100.20',
780                             'local_mac': '00:00:00:00:00:01'
781                         },
782                         'vnfd-connection-point-ref': 'xe0',
783                         'name': 'xe0'
784                     },
785                     {
786                         'virtual-interface': {
787                             'dst_mac': '00:00:00:00:00:04',
788                             'vpci': '0000:05:00.1',
789                             'driver': 'ixgbe',
790                             'local_ip': '152.16.40.19',
791                             'type': 'PCI-PASSTHROUGH',
792                             'netmask': '255.255.255.0',
793                             'dpdk_port_num': 1,
794                             'bandwidth': '10 Gbps',
795                             'dst_ip': '152.16.40.20',
796                             'local_mac': '00:00:00:00:00:02'
797                         },
798                         'vnfd-connection-point-ref': 'xe1',
799                         'name': 'xe1'
800                     },
801                 ],
802             },
803         ],
804         'description': 'Vpe approximation using DPDK',
805         'mgmt-interface': {
806             'vdu-id': 'vpevnf-baremetal',
807             'host': '1.1.1.1',
808             'password': 'r00t',
809             'user': 'root',
810             'ip': '1.1.1.1'
811         },
812         'benchmark': {
813             'kpi': [
814                 'packets_in',
815                 'packets_fwd',
816                 'packets_dropped',
817             ],
818         },
819         'connection-point': [
820             {
821                 'type': 'VPORT',
822                 'name': 'xe0',
823             },
824             {
825                 'type': 'VPORT',
826                 'name': 'xe1',
827             },
828         ],
829         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
830     }
831
832     def test_setup(self):
833         resource = object()
834         vnfd_helper = VnfdHelper(self.VNFD_0)
835         ssh_helper = mock.Mock()
836         scenario_helper = mock.Mock()
837         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
838         dpdk_setup_helper.setup_vnf_environment = mock.Mock(return_value=resource)
839         resource_helper = ResourceHelper(dpdk_setup_helper)
840
841         self.assertIsNone(resource_helper.setup())
842         self.assertIs(resource_helper.resource, resource)
843
844     def test_generate_cfg(self):
845         vnfd_helper = VnfdHelper(self.VNFD_0)
846         ssh_helper = mock.Mock()
847         scenario_helper = mock.Mock()
848         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
849         resource_helper = ResourceHelper(dpdk_setup_helper)
850
851         self.assertIsNone(resource_helper.generate_cfg())
852
853     def test_stop_collect(self):
854         vnfd_helper = VnfdHelper(self.VNFD_0)
855         ssh_helper = mock.Mock()
856         scenario_helper = mock.Mock()
857         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
858         resource_helper = ResourceHelper(dpdk_setup_helper)
859         resource_helper.resource = mock.Mock()
860
861         self.assertIsNone(resource_helper.stop_collect())
862
863     def test_stop_collect_none(self):
864         vnfd_helper = VnfdHelper(self.VNFD_0)
865         ssh_helper = mock.Mock()
866         scenario_helper = mock.Mock()
867         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
868         resource_helper = ResourceHelper(dpdk_setup_helper)
869         resource_helper.resource = None
870
871         self.assertIsNone(resource_helper.stop_collect())
872
873
874 class TestClientResourceHelper(unittest.TestCase):
875
876     VNFD_0 = {
877         'short-name': 'VpeVnf',
878         'vdu': [
879             {
880                 'routing_table': [
881                     {
882                         'network': '152.16.100.20',
883                         'netmask': '255.255.255.0',
884                         'gateway': '152.16.100.20',
885                         'if': 'xe0'
886                     },
887                     {
888                         'network': '152.16.40.20',
889                         'netmask': '255.255.255.0',
890                         'gateway': '152.16.40.20',
891                         'if': 'xe1'
892                     },
893                 ],
894                 'description': 'VPE approximation using DPDK',
895                 'name': 'vpevnf-baremetal',
896                 'nd_route_tbl': [
897                     {
898                         'network': '0064:ff9b:0:0:0:0:9810:6414',
899                         'netmask': '112',
900                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
901                         'if': 'xe0'
902                     },
903                     {
904                         'network': '0064:ff9b:0:0:0:0:9810:2814',
905                         'netmask': '112',
906                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
907                         'if': 'xe1'
908                     },
909                 ],
910                 'id': 'vpevnf-baremetal',
911                 'external-interface': [
912                     {
913                         'virtual-interface': {
914                             'dst_mac': '00:00:00:00:00:03',
915                             'vpci': '0000:05:00.0',
916                             'driver': 'i40e',
917                             'local_ip': '152.16.100.19',
918                             'type': 'PCI-PASSTHROUGH',
919                             'netmask': '255.255.255.0',
920                             'dpdk_port_num': 0,
921                             'bandwidth': '10 Gbps',
922                             'dst_ip': '152.16.100.20',
923                             'local_mac': '00:00:00:00:00:01',
924                             'vld_id': 'uplink_0',
925                             'ifname': 'xe0',
926                         },
927                         'vnfd-connection-point-ref': 'xe0',
928                         'name': 'xe0'
929                     },
930                     {
931                         'virtual-interface': {
932                             'dst_mac': '00:00:00:00:00:04',
933                             'vpci': '0000:05:00.1',
934                             'driver': 'ixgbe',
935                             'local_ip': '152.16.40.19',
936                             'type': 'PCI-PASSTHROUGH',
937                             'netmask': '255.255.255.0',
938                             'dpdk_port_num': 1,
939                             'bandwidth': '10 Gbps',
940                             'dst_ip': '152.16.40.20',
941                             'local_mac': '00:00:00:00:00:02',
942                             'vld_id': 'downlink_0',
943                             'ifname': 'xe1',
944                         },
945                         'vnfd-connection-point-ref': 'xe1',
946                         'name': 'xe1'
947                     },
948                     {
949                         'virtual-interface': {
950                             'dst_mac': '00:00:00:00:00:13',
951                             'vpci': '0000:05:00.2',
952                             'driver': 'ixgbe',
953                             'local_ip': '152.16.40.19',
954                             'type': 'PCI-PASSTHROUGH',
955                             'netmask': '255.255.255.0',
956                             'dpdk_port_num': 2,
957                             'bandwidth': '10 Gbps',
958                             'dst_ip': '152.16.40.30',
959                             'local_mac': '00:00:00:00:00:11'
960                         },
961                         'vnfd-connection-point-ref': 'xe2',
962                         'name': 'xe2'
963                     },
964                 ],
965             },
966         ],
967         'description': 'Vpe approximation using DPDK',
968         'mgmt-interface': {
969             'vdu-id': 'vpevnf-baremetal',
970             'host': '1.1.1.1',
971             'password': 'r00t',
972             'user': 'root',
973             'ip': '1.1.1.1'
974         },
975         'benchmark': {
976             'kpi': [
977                 'packets_in',
978                 'packets_fwd',
979                 'packets_dropped',
980             ],
981         },
982         'connection-point': [
983             {
984                 'type': 'VPORT',
985                 'name': 'xe0',
986             },
987             {
988                 'type': 'VPORT',
989                 'name': 'xe1',
990             },
991         ],
992         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
993     }
994
995     VNFD = {
996         'vnfd:vnfd-catalog': {
997             'vnfd': [
998                 VNFD_0,
999             ],
1000         },
1001     }
1002
1003     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
1004     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
1005                 new_callable=lambda: MockError)
1006     def test_get_stats_not_connected(self, mock_state_error, *args):
1007         vnfd_helper = VnfdHelper(self.VNFD_0)
1008         ssh_helper = mock.Mock()
1009         scenario_helper = mock.Mock()
1010         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1011         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1012         client_resource_helper.client = mock.MagicMock()
1013         client_resource_helper.client.get_stats.side_effect = mock_state_error
1014
1015         self.assertEqual(client_resource_helper.get_stats(), {})
1016         self.assertEqual(client_resource_helper.client.get_stats.call_count, 1)
1017
1018     def test_generate_samples(self):
1019         vnfd_helper = VnfdHelper(self.VNFD_0)
1020         ssh_helper = mock.Mock()
1021         scenario_helper = mock.Mock()
1022         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1023         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1024         client_resource_helper.client = mock.MagicMock()
1025         client_resource_helper.client.get_stats.return_value = {
1026             0: {
1027                 'rx_pps': 5.5,
1028                 'tx_pps': 4.9,
1029                 'rx_bps': 234.78,
1030                 'tx_bps': 243.11,
1031                 'ipackets': 34251,
1032                 'opackets': 52342,
1033             },
1034             1: {
1035                 'tx_pps': 5.9,
1036                 'rx_bps': 434.78,
1037                 'opackets': 48791,
1038             },
1039         }
1040
1041         expected = {
1042             'xe0': {
1043                 "rx_throughput_fps": 5.5,
1044                 "tx_throughput_fps": 4.9,
1045                 "rx_throughput_mbps": 234.78,
1046                 "tx_throughput_mbps": 243.11,
1047                 "in_packets": 34251,
1048                 "out_packets": 52342,
1049             },
1050             'xe1': {
1051                 "rx_throughput_fps": 0.0,
1052                 "tx_throughput_fps": 5.9,
1053                 "rx_throughput_mbps": 434.78,
1054                 "tx_throughput_mbps": 0.0,
1055                 "in_packets": 0,
1056                 "out_packets": 48791,
1057             },
1058         }
1059         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1060         result = client_resource_helper.generate_samples(ports)
1061         self.assertDictEqual(result, expected)
1062
1063     def test_generate_samples_with_key(self):
1064         vnfd_helper = VnfdHelper(self.VNFD_0)
1065         ssh_helper = mock.Mock()
1066         scenario_helper = mock.Mock()
1067         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1068         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1069         client_resource_helper.client = mock.MagicMock()
1070         client_resource_helper.client.get_stats.return_value = {
1071             'key_name': 'key_value',
1072             0: {
1073                 'rx_pps': 5.5,
1074                 'tx_pps': 4.9,
1075                 'rx_bps': 234.78,
1076                 'tx_bps': 243.11,
1077                 'ipackets': 34251,
1078                 'opackets': 52342,
1079             },
1080             1: {
1081                 'tx_pps': 5.9,
1082                 'rx_bps': 434.78,
1083                 'opackets': 48791,
1084             },
1085         }
1086
1087         expected = {
1088             'xe0': {
1089                 'key_name': 'key_value',
1090                 "rx_throughput_fps": 5.5,
1091                 "tx_throughput_fps": 4.9,
1092                 "rx_throughput_mbps": 234.78,
1093                 "tx_throughput_mbps": 243.11,
1094                 "in_packets": 34251,
1095                 "out_packets": 52342,
1096             },
1097             'xe1': {
1098                 'key_name': 'key_value',
1099                 "rx_throughput_fps": 0.0,
1100                 "tx_throughput_fps": 5.9,
1101                 "rx_throughput_mbps": 434.78,
1102                 "tx_throughput_mbps": 0.0,
1103                 "in_packets": 0,
1104                 "out_packets": 48791,
1105             },
1106         }
1107         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1108         result = client_resource_helper.generate_samples(ports, 'key_name')
1109         self.assertDictEqual(result, expected)
1110
1111     def test_generate_samples_with_key_and_default(self):
1112         vnfd_helper = VnfdHelper(self.VNFD_0)
1113         ssh_helper = mock.Mock()
1114         scenario_helper = mock.Mock()
1115         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1116         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1117         client_resource_helper.client = mock.MagicMock()
1118         client_resource_helper.client.get_stats.return_value = {
1119             0: {
1120                 'rx_pps': 5.5,
1121                 'tx_pps': 4.9,
1122                 'rx_bps': 234.78,
1123                 'tx_bps': 243.11,
1124                 'ipackets': 34251,
1125                 'opackets': 52342,
1126             },
1127             1: {
1128                 'tx_pps': 5.9,
1129                 'rx_bps': 434.78,
1130                 'opackets': 48791,
1131             },
1132         }
1133
1134         expected = {
1135             'xe0': {
1136                 'key_name': 'default',
1137                 "rx_throughput_fps": 5.5,
1138                 "tx_throughput_fps": 4.9,
1139                 "rx_throughput_mbps": 234.78,
1140                 "tx_throughput_mbps": 243.11,
1141                 "in_packets": 34251,
1142                 "out_packets": 52342,
1143             },
1144             'xe1': {
1145                 'key_name': 'default',
1146                 "rx_throughput_fps": 0.0,
1147                 "tx_throughput_fps": 5.9,
1148                 "rx_throughput_mbps": 434.78,
1149                 "tx_throughput_mbps": 0.0,
1150                 "in_packets": 0,
1151                 "out_packets": 48791,
1152             },
1153         }
1154         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1155         result = client_resource_helper.generate_samples(ports, 'key_name', 'default')
1156         self.assertDictEqual(result, expected)
1157
1158     def test_clear_stats(self):
1159         vnfd_helper = VnfdHelper(self.VNFD_0)
1160         ssh_helper = mock.Mock()
1161         scenario_helper = mock.Mock()
1162         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1163         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1164         client_resource_helper.client = mock.Mock()
1165
1166         self.assertIsNone(client_resource_helper.clear_stats())
1167         self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
1168
1169     def test_clear_stats_of_ports(self):
1170         vnfd_helper = VnfdHelper(self.VNFD_0)
1171         ssh_helper = mock.Mock()
1172         scenario_helper = mock.Mock()
1173         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1174         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1175         client_resource_helper.client = mock.Mock()
1176
1177         self.assertIsNone(client_resource_helper.clear_stats([3, 4]))
1178         self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
1179
1180     def test_start(self):
1181         vnfd_helper = VnfdHelper(self.VNFD_0)
1182         ssh_helper = mock.Mock()
1183         scenario_helper = mock.Mock()
1184         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1185         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1186         client_resource_helper.client = mock.Mock()
1187
1188         self.assertIsNone(client_resource_helper.start())
1189         self.assertEqual(client_resource_helper.client.start.call_count, 1)
1190
1191     def test_start_ports(self):
1192         vnfd_helper = VnfdHelper(self.VNFD_0)
1193         ssh_helper = mock.Mock()
1194         scenario_helper = mock.Mock()
1195         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1196         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1197         client_resource_helper.client = mock.Mock()
1198
1199         self.assertIsNone(client_resource_helper.start([3, 4]))
1200         self.assertEqual(client_resource_helper.client.start.call_count, 1)
1201
1202     def test_collect_kpi_with_queue(self):
1203         vnfd_helper = VnfdHelper(self.VNFD_0)
1204         ssh_helper = mock.Mock()
1205         scenario_helper = mock.Mock()
1206         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1207         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1208         client_resource_helper._result = {'existing': 43, 'replaceable': 12}
1209         client_resource_helper._queue = mock.Mock()
1210         client_resource_helper._queue.empty.return_value = False
1211         client_resource_helper._queue.get.return_value = {'incoming': 34, 'replaceable': 99}
1212
1213         expected = {
1214             'existing': 43,
1215             'incoming': 34,
1216             'replaceable': 99,
1217         }
1218         result = client_resource_helper.collect_kpi()
1219         self.assertDictEqual(result, expected)
1220
1221     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1222     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
1223     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
1224                 new_callable=lambda: MockError)
1225     def test__connect_with_failures(self, mock_error, *args):
1226         vnfd_helper = VnfdHelper(self.VNFD_0)
1227         ssh_helper = mock.Mock()
1228         scenario_helper = mock.Mock()
1229         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1230         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1231         client = mock.MagicMock()
1232         client.connect.side_effect = mock_error
1233
1234         self.assertIs(client_resource_helper._connect(client), client)
1235
1236
1237 class TestRfc2544ResourceHelper(unittest.TestCase):
1238
1239     RFC2544_CFG_1 = {
1240         'latency': True,
1241         'correlated_traffic': True,
1242         'allowed_drop_rate': '0.1 - 0.15',
1243     }
1244
1245     RFC2544_CFG_2 = {
1246         'allowed_drop_rate': '  0.25    -   0.05  ',
1247     }
1248
1249     RFC2544_CFG_3 = {
1250         'allowed_drop_rate': '0.2',
1251     }
1252
1253     RFC2544_CFG_4 = {
1254         'latency': True,
1255     }
1256
1257     SCENARIO_CFG_1 = {
1258         'options': {
1259             'rfc2544': RFC2544_CFG_1,
1260         }
1261     }
1262
1263     SCENARIO_CFG_2 = {
1264         'options': {
1265             'rfc2544': RFC2544_CFG_2,
1266         }
1267     }
1268
1269     SCENARIO_CFG_3 = {
1270         'options': {
1271             'rfc2544': RFC2544_CFG_3,
1272         }
1273     }
1274
1275     SCENARIO_CFG_4 = {
1276         'options': {
1277             'rfc2544': RFC2544_CFG_4,
1278         }
1279     }
1280
1281     def test_property_rfc2544(self):
1282         scenario_helper = ScenarioHelper('name1')
1283         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1284         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1285
1286         self.assertIsNone(rfc2544_resource_helper._rfc2544)
1287         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1288         self.assertDictEqual(rfc2544_resource_helper._rfc2544, self.RFC2544_CFG_1)
1289         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1290         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1291
1292     def test_property_tolerance_high(self):
1293         scenario_helper = ScenarioHelper('name1')
1294         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1295         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1296
1297         self.assertIsNone(rfc2544_resource_helper._tolerance_high)
1298         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1299         self.assertEqual(rfc2544_resource_helper._tolerance_high, 0.15)
1300         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1301         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1302
1303     def test_property_tolerance_low(self):
1304         scenario_helper = ScenarioHelper('name1')
1305         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1306         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1307
1308         self.assertIsNone(rfc2544_resource_helper._tolerance_low)
1309         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1310         self.assertEqual(rfc2544_resource_helper._tolerance_low, 0.1)
1311         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1312         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1313
1314     def test_property_tolerance_high_range_swap(self):
1315         scenario_helper = ScenarioHelper('name1')
1316         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1317         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1318
1319         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.25)
1320
1321     def test_property_tolerance_low_range_swap(self):
1322         scenario_helper = ScenarioHelper('name1')
1323         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1324         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1325
1326         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.05)
1327
1328     def test_property_tolerance_high_not_range(self):
1329         scenario_helper = ScenarioHelper('name1')
1330         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1331         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1332
1333         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.2)
1334
1335     def test_property_tolerance_low_not_range(self):
1336         scenario_helper = ScenarioHelper('name1')
1337         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1338         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1339
1340         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.2)
1341
1342     def test_property_tolerance_high_default(self):
1343         scenario_helper = ScenarioHelper('name1')
1344         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1345         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1346
1347         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.0001)
1348
1349     def test_property_tolerance_low_default(self):
1350         scenario_helper = ScenarioHelper('name1')
1351         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1352         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1353
1354         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.0001)
1355
1356     def test_property_latency(self):
1357         scenario_helper = ScenarioHelper('name1')
1358         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1359         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1360
1361         self.assertIsNone(rfc2544_resource_helper._latency)
1362         self.assertTrue(rfc2544_resource_helper.latency)
1363         self.assertTrue(rfc2544_resource_helper._latency)
1364         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1365         self.assertTrue(rfc2544_resource_helper.latency)
1366
1367     def test_property_latency_default(self):
1368         scenario_helper = ScenarioHelper('name1')
1369         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1370         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1371
1372         self.assertFalse(rfc2544_resource_helper.latency)
1373
1374     def test_property_correlated_traffic(self):
1375         scenario_helper = ScenarioHelper('name1')
1376         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1377         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1378
1379         self.assertIsNone(rfc2544_resource_helper._correlated_traffic)
1380         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1381         self.assertTrue(rfc2544_resource_helper._correlated_traffic)
1382         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1383         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1384
1385     def test_property_correlated_traffic_default(self):
1386         scenario_helper = ScenarioHelper('name1')
1387         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1388         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1389
1390         self.assertFalse(rfc2544_resource_helper.correlated_traffic)
1391
1392
1393 class TestSampleVNFDeployHelper(unittest.TestCase):
1394
1395     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1396     @mock.patch('subprocess.check_output')
1397     def test_deploy_vnfs_disabled(self, *_):
1398         vnfd_helper = mock.Mock()
1399         ssh_helper = mock.Mock()
1400         ssh_helper.join_bin_path.return_value = 'joined_path'
1401         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1402         ssh_helper.put.return_value = None
1403         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1404
1405         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1406         sample_vnf_deploy_helper.DISABLE_DEPLOY = True
1407         self.assertEqual(ssh_helper.execute.call_count, 5)
1408         self.assertEqual(ssh_helper.put.call_count, 1)
1409
1410     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1411     @mock.patch('subprocess.check_output')
1412     def test_deploy_vnfs(self, *args):
1413         vnfd_helper = mock.Mock()
1414         ssh_helper = mock.Mock()
1415         ssh_helper.join_bin_path.return_value = 'joined_path'
1416         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1417         ssh_helper.put.return_value = None
1418         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1419         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1420
1421         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1422         self.assertEqual(ssh_helper.execute.call_count, 5)
1423         self.assertEqual(ssh_helper.put.call_count, 1)
1424
1425     @mock.patch('subprocess.check_output')
1426     def test_deploy_vnfs_early_success(self, *args):
1427         vnfd_helper = mock.Mock()
1428         ssh_helper = mock.Mock()
1429         ssh_helper.join_bin_path.return_value = 'joined_path'
1430         ssh_helper.execute.return_value = 0, 'output', ''
1431         ssh_helper.put.return_value = None
1432         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1433         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1434
1435         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1436         self.assertEqual(ssh_helper.execute.call_count, 1)
1437         self.assertEqual(ssh_helper.put.call_count, 0)
1438
1439
1440 class TestScenarioHelper(unittest.TestCase):
1441
1442     def test_property_task_path(self):
1443         scenario_helper = ScenarioHelper('name1')
1444         scenario_helper.scenario_cfg = {
1445             'task_path': 'my_path',
1446         }
1447
1448         self.assertEqual(scenario_helper.task_path, 'my_path')
1449
1450     def test_property_nodes(self):
1451         nodes = ['node1', 'node2']
1452         scenario_helper = ScenarioHelper('name1')
1453         scenario_helper.scenario_cfg = {
1454             'nodes': nodes,
1455         }
1456
1457         self.assertEqual(scenario_helper.nodes, nodes)
1458
1459     def test_property_all_options(self):
1460         data = {
1461             'name1': {
1462                 'key3': 'value3',
1463             },
1464             'name2': {}
1465         }
1466         scenario_helper = ScenarioHelper('name1')
1467         scenario_helper.scenario_cfg = {
1468             'options': data,
1469         }
1470
1471         self.assertDictEqual(scenario_helper.all_options, data)
1472
1473     def test_property_options(self):
1474         data = {
1475             'key1': 'value1',
1476             'key2': 'value2',
1477         }
1478         scenario_helper = ScenarioHelper('name1')
1479         scenario_helper.scenario_cfg = {
1480             'options': {
1481                 'name1': data,
1482             },
1483         }
1484
1485         self.assertDictEqual(scenario_helper.options, data)
1486
1487     def test_property_vnf_cfg(self):
1488         scenario_helper = ScenarioHelper('name1')
1489         scenario_helper.scenario_cfg = {
1490             'options': {
1491                 'name1': {
1492                     'vnf_config': 'my_config',
1493                 },
1494             },
1495         }
1496
1497         self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
1498
1499     def test_property_vnf_cfg_default(self):
1500         scenario_helper = ScenarioHelper('name1')
1501         scenario_helper.scenario_cfg = {
1502             'options': {
1503                 'name1': {},
1504             },
1505         }
1506
1507         self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
1508
1509     def test_property_topology(self):
1510         scenario_helper = ScenarioHelper('name1')
1511         scenario_helper.scenario_cfg = {
1512             'topology': 'my_topology',
1513         }
1514
1515         self.assertEqual(scenario_helper.topology, 'my_topology')
1516
1517
1518 class TestSampleVnf(unittest.TestCase):
1519
1520     VNFD_0 = {
1521         'short-name': 'VpeVnf',
1522         'vdu': [
1523             {
1524                 'routing_table': [
1525                     {
1526                         'network': '152.16.100.20',
1527                         'netmask': '255.255.255.0',
1528                         'gateway': '152.16.100.20',
1529                         'if': 'xe0'
1530                     },
1531                     {
1532                         'network': '152.16.40.20',
1533                         'netmask': '255.255.255.0',
1534                         'gateway': '152.16.40.20',
1535                         'if': 'xe1'
1536                     },
1537                 ],
1538                 'description': 'VPE approximation using DPDK',
1539                 'name': 'vpevnf-baremetal',
1540                 'nd_route_tbl': [
1541                     {
1542                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1543                         'netmask': '112',
1544                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1545                         'if': 'xe0'
1546                     },
1547                     {
1548                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1549                         'netmask': '112',
1550                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1551                         'if': 'xe1'
1552                     },
1553                 ],
1554                 'id': 'vpevnf-baremetal',
1555                 'external-interface': [
1556                     {
1557                         'virtual-interface': {
1558                             'dst_mac': '00:00:00:00:00:03',
1559                             'vpci': '0000:05:00.0',
1560                             'local_ip': '152.16.100.19',
1561                             'type': 'PCI-PASSTHROUGH',
1562                             'netmask': '255.255.255.0',
1563                             'dpdk_port_num': 0,
1564                             'bandwidth': '10 Gbps',
1565                             'dst_ip': '152.16.100.20',
1566                             'local_mac': '00:00:00:00:00:01'
1567                         },
1568                         'vnfd-connection-point-ref': 'xe0',
1569                         'name': 'xe0'
1570                     },
1571                     {
1572                         'virtual-interface': {
1573                             'dst_mac': '00:00:00:00:00:04',
1574                             'vpci': '0000:05:00.1',
1575                             'local_ip': '152.16.40.19',
1576                             'type': 'PCI-PASSTHROUGH',
1577                             'netmask': '255.255.255.0',
1578                             'dpdk_port_num': 1,
1579                             'bandwidth': '10 Gbps',
1580                             'dst_ip': '152.16.40.20',
1581                             'local_mac': '00:00:00:00:00:02'
1582                         },
1583                         'vnfd-connection-point-ref': 'xe1',
1584                         'name': 'xe1'
1585                     },
1586                 ],
1587             },
1588         ],
1589         'description': 'Vpe approximation using DPDK',
1590         'mgmt-interface': {
1591             'vdu-id': 'vpevnf-baremetal',
1592             'host': '1.1.1.1',
1593             'password': 'r00t',
1594             'user': 'root',
1595             'ip': '1.1.1.1'
1596         },
1597         'benchmark': {
1598             'kpi': [
1599                 'packets_in',
1600                 'packets_fwd',
1601                 'packets_dropped',
1602             ],
1603         },
1604         'connection-point': [
1605             {
1606                 'type': 'VPORT',
1607                 'name': 'xe0',
1608             },
1609             {
1610                 'type': 'VPORT',
1611                 'name': 'xe1',
1612             },
1613         ],
1614         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1615     }
1616
1617     VNFD = {
1618         'vnfd:vnfd-catalog': {
1619             'vnfd': [
1620                 VNFD_0,
1621             ]
1622         }
1623     }
1624
1625     TRAFFIC_PROFILE = {
1626         "schema": "isb:traffic_profile:0.1",
1627         "name": "fixed",
1628         "description": "Fixed traffic profile to run UDP traffic",
1629         "traffic_profile": {
1630             "traffic_type": "FixedTraffic",
1631             "frame_rate": 100,  # pps
1632             "flow_number": 10,
1633             "frame_size": 64,
1634         },
1635     }
1636
1637     def test___init__(self):
1638         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1639
1640         self.assertEqual(sample_vnf.name, 'vnf1')
1641         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1642
1643         # test the default setup helper is SetupEnvHelper, not subclass
1644         self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
1645
1646         # test the default resource helper is ResourceHelper, not subclass
1647         self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
1648
1649     def test___init___alt_types(self):
1650         class MySetupEnvHelper(SetupEnvHelper):
1651             pass
1652
1653         class MyResourceHelper(ResourceHelper):
1654             pass
1655
1656         sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
1657
1658         self.assertEqual(sample_vnf.name, 'vnf1')
1659         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1660
1661         # test the default setup helper is MySetupEnvHelper, not subclass
1662         self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
1663
1664         # test the default resource helper is MyResourceHelper, not subclass
1665         self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
1666
1667     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1668     def test__start_vnf(self, *args):
1669         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1670         sample_vnf = SampleVNF('vnf1', vnfd)
1671         sample_vnf._run = mock.Mock()
1672
1673         self.assertIsNone(sample_vnf.queue_wrapper)
1674         self.assertIsNone(sample_vnf._vnf_process)
1675         self.assertIsNone(sample_vnf._start_vnf())
1676         self.assertIsNotNone(sample_vnf.queue_wrapper)
1677         self.assertIsNotNone(sample_vnf._vnf_process)
1678
1679     @mock.patch("yardstick.ssh.SSH")
1680     def test_instantiate(self, ssh):
1681         mock_ssh(ssh)
1682
1683         nodes = {
1684             'vnf1': 'name1',
1685             'vnf2': 'name2',
1686         }
1687
1688         context1 = mock.Mock()
1689         context1._get_server.return_value = None
1690         context2 = mock.Mock()
1691         context2._get_server.return_value = context2
1692
1693         try:
1694             Context.list.clear()
1695         except AttributeError:
1696             # clear() but works in Py2.7
1697             Context.list[:] = []
1698
1699         Context.list.extend([
1700             context1,
1701             context2,
1702         ])
1703
1704         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1705         sample_vnf = SampleVNF('vnf1', vnfd)
1706         sample_vnf.APP_NAME = 'sample1'
1707         sample_vnf._start_server = mock.Mock(return_value=0)
1708         sample_vnf._vnf_process = mock.MagicMock()
1709         sample_vnf._vnf_process._is_alive.return_value = 1
1710         sample_vnf.ssh_helper = mock.MagicMock()
1711         sample_vnf.deploy_helper = mock.MagicMock()
1712         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1713         scenario_cfg = {
1714             'nodes': nodes,
1715         }
1716
1717         self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
1718         self.assertEqual(sample_vnf.nfvi_context, context2)
1719
1720     def test__update_collectd_options(self):
1721         scenario_cfg = {'options':
1722                             {'collectd':
1723                                  {'interval': 3,
1724                                   'plugins':
1725                                       {'plugin3': {'param': 3}}},
1726                              'vnf__0':
1727                                  {'collectd':
1728                                       {'interval': 2,
1729                                        'plugins':
1730                                            {'plugin3': {'param': 2},
1731                                             'plugin2': {'param': 2}}}}}}
1732         context_cfg = {'nodes':
1733                            {'vnf__0':
1734                                 {'collectd':
1735                                      {'interval': 1,
1736                                       'plugins':
1737                                           {'plugin3': {'param': 1},
1738                                            'plugin2': {'param': 1},
1739                                            'plugin1': {'param': 1}}}}}}
1740         expected = {'interval': 1,
1741                     'plugins':
1742                         {'plugin3': {'param': 1},
1743                          'plugin2': {'param': 1},
1744                          'plugin1': {'param': 1}}}
1745
1746         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1747         sample_vnf = SampleVNF('vnf__0', vnfd)
1748         sample_vnf._update_collectd_options(scenario_cfg, context_cfg)
1749         self.assertEqual(sample_vnf.setup_helper.collectd_options, expected)
1750
1751     def test__update_options(self):
1752         options1 = {'interval': 1,
1753                     'param1': 'value1',
1754                     'plugins':
1755                         {'plugin3': {'param': 3},
1756                          'plugin2': {'param': 1},
1757                          'plugin1': {'param': 1}}}
1758         options2 = {'interval': 2,
1759                     'param2': 'value2',
1760                     'plugins':
1761                         {'plugin4': {'param': 4},
1762                          'plugin2': {'param': 2},
1763                          'plugin1': {'param': 2}}}
1764         expected = {'interval': 1,
1765                     'param1': 'value1',
1766                     'param2': 'value2',
1767                     'plugins':
1768                         {'plugin4': {'param': 4},
1769                          'plugin3': {'param': 3},
1770                          'plugin2': {'param': 1},
1771                          'plugin1': {'param': 1}}}
1772
1773         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1774         sample_vnf = SampleVNF('vnf1', vnfd)
1775         sample_vnf._update_options(options2, options1)
1776         self.assertEqual(options2, expected)
1777
1778     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1779     @mock.patch("yardstick.ssh.SSH")
1780     def test_wait_for_instantiate_empty_queue(self, ssh, *args):
1781         mock_ssh(ssh, exec_result=(1, "", ""))
1782
1783         queue_size_list = [
1784             0,
1785             1,
1786             0,
1787             1,
1788         ]
1789
1790         queue_get_list = [
1791             'some output',
1792             'pipeline> ',
1793         ]
1794
1795         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1796         sample_vnf = SampleVNF('vnf1', vnfd)
1797         sample_vnf.APP_NAME = 'sample1'
1798         sample_vnf.WAIT_TIME_FOR_SCRIPT = 0
1799         sample_vnf._start_server = mock.Mock(return_value=0)
1800         sample_vnf._vnf_process = mock.MagicMock()
1801         sample_vnf._vnf_process.exitcode = 0
1802         sample_vnf._vnf_process._is_alive.return_value = 1
1803         sample_vnf.queue_wrapper = mock.Mock()
1804         sample_vnf.q_out = mock.Mock()
1805         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1806         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1807         sample_vnf.ssh_helper = mock.MagicMock()
1808         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1809         sample_vnf.resource_helper.start_collect = mock.MagicMock()
1810
1811         self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
1812
1813     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1814     def test_vnf_execute_with_queue_data(self, *args):
1815         queue_size_list = [
1816             1,
1817             1,
1818             0,
1819         ]
1820
1821         queue_get_list = [
1822             'hello ',
1823             'world'
1824         ]
1825
1826         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1827         sample_vnf = SampleVNF('vnf1', vnfd)
1828         sample_vnf.APP_NAME = 'sample1'
1829         sample_vnf.q_out = mock.Mock()
1830         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1831         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1832
1833         self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
1834
1835     def test_terminate_without_vnf_process(self):
1836         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1837         sample_vnf = SampleVNF('vnf1', vnfd)
1838         sample_vnf.APP_NAME = 'sample1'
1839         sample_vnf.vnf_execute = mock.Mock()
1840         sample_vnf.ssh_helper = mock.Mock()
1841         sample_vnf._tear_down = mock.Mock()
1842         sample_vnf.resource_helper = mock.Mock()
1843
1844         self.assertIsNone(sample_vnf.terminate())
1845
1846     def test_get_stats(self):
1847         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1848         sample_vnf = SampleVNF('vnf1', vnfd)
1849         sample_vnf.APP_NAME = 'sample1'
1850         sample_vnf.APP_WORD = 'sample1'
1851         sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
1852
1853         self.assertEqual(sample_vnf.get_stats(), 'the stats')
1854
1855     def test_collect_kpi(self):
1856         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1857         sample_vnf = SampleVNF('vnf1', vnfd)
1858         sample_vnf.APP_NAME = 'sample1'
1859         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1860         sample_vnf.COLLECT_MAP = {
1861             'k1': 3,
1862             'k2': 1,
1863             'k3': 2,
1864         }
1865         sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1866         sample_vnf.resource_helper = mock.Mock()
1867         sample_vnf.resource_helper.collect_kpi.return_value = {}
1868
1869         expected = {
1870             'k1': 27,
1871             'k2': 34,
1872             'k3': 91,
1873             'collect_stats': {},
1874         }
1875         result = sample_vnf.collect_kpi()
1876         self.assertDictEqual(result, expected)
1877
1878     def test_collect_kpi_default(self):
1879         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1880         sample_vnf = SampleVNF('vnf1', vnfd)
1881         sample_vnf.APP_NAME = 'sample1'
1882         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1883         sample_vnf.get_stats = mock.Mock(return_value='')
1884
1885         expected = {
1886             'packets_in': 0,
1887             'packets_fwd': 0,
1888             'packets_dropped': 0,
1889         }
1890         result = sample_vnf.collect_kpi()
1891         self.assertDictEqual(result, expected)
1892
1893     def test_scale(self):
1894         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1895         sample_vnf = SampleVNF('vnf1', vnfd)
1896         self.assertRaises(y_exceptions.FunctionNotImplemented,
1897                           sample_vnf.scale)
1898
1899     def test__run(self):
1900         test_cmd = 'test cmd'
1901         run_kwargs = {'arg1': 'val1', 'arg2': 'val2'}
1902         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1903         sample_vnf = SampleVNF('vnf1', vnfd)
1904         sample_vnf.ssh_helper = mock.Mock()
1905         sample_vnf.setup_helper = mock.Mock()
1906         with mock.patch.object(sample_vnf, '_build_config',
1907                                return_value=test_cmd), \
1908                 mock.patch.object(sample_vnf, '_build_run_kwargs'):
1909             sample_vnf.run_kwargs = run_kwargs
1910             sample_vnf._run()
1911         sample_vnf.ssh_helper.drop_connection.assert_called_once()
1912         sample_vnf.ssh_helper.run.assert_called_once_with(test_cmd,
1913                                                           **run_kwargs)
1914         sample_vnf.setup_helper.kill_vnf.assert_called_once()
1915
1916
1917 class TestSampleVNFTrafficGen(unittest.TestCase):
1918
1919     VNFD_0 = {
1920         'short-name': 'VpeVnf',
1921         'vdu': [
1922             {
1923                 'routing_table': [
1924                     {
1925                         'network': '152.16.100.20',
1926                         'netmask': '255.255.255.0',
1927                         'gateway': '152.16.100.20',
1928                         'if': 'xe0'
1929                     },
1930                     {
1931                         'network': '152.16.40.20',
1932                         'netmask': '255.255.255.0',
1933                         'gateway': '152.16.40.20',
1934                         'if': 'xe1'
1935                     },
1936                 ],
1937                 'description': 'VPE approximation using DPDK',
1938                 'name': 'vpevnf-baremetal',
1939                 'nd_route_tbl': [
1940                     {
1941                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1942                         'netmask': '112',
1943                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1944                         'if': 'xe0'
1945                     },
1946                     {
1947                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1948                         'netmask': '112',
1949                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1950                         'if': 'xe1'
1951                     },
1952                 ],
1953                 'id': 'vpevnf-baremetal',
1954                 'external-interface': [
1955                     {
1956                         'virtual-interface': {
1957                             'dst_mac': '00:00:00:00:00:03',
1958                             'vpci': '0000:05:00.0',
1959                             'driver': 'i40e',
1960                             'local_ip': '152.16.100.19',
1961                             'type': 'PCI-PASSTHROUGH',
1962                             'netmask': '255.255.255.0',
1963                             'dpdk_port_num': 0,
1964                             'bandwidth': '10 Gbps',
1965                             'dst_ip': '152.16.100.20',
1966                             'local_mac': '00:00:00:00:00:01'
1967                         },
1968                         'vnfd-connection-point-ref': 'xe0',
1969                         'name': 'xe0'
1970                     },
1971                     {
1972                         'virtual-interface': {
1973                             'dst_mac': '00:00:00:00:00:04',
1974                             'vpci': '0000:05:00.1',
1975                             'driver': 'ixgbe',
1976                             'local_ip': '152.16.40.19',
1977                             'type': 'PCI-PASSTHROUGH',
1978                             'netmask': '255.255.255.0',
1979                             'dpdk_port_num': 1,
1980                             'bandwidth': '10 Gbps',
1981                             'dst_ip': '152.16.40.20',
1982                             'local_mac': '00:00:00:00:00:02'
1983                         },
1984                         'vnfd-connection-point-ref': 'xe1',
1985                         'name': 'xe1'
1986                     },
1987                 ],
1988             },
1989         ],
1990         'description': 'Vpe approximation using DPDK',
1991         'mgmt-interface': {
1992             'vdu-id': 'vpevnf-baremetal',
1993             'host': '1.1.1.1',
1994             'password': 'r00t',
1995             'user': 'root',
1996             'ip': '1.1.1.1'
1997         },
1998         'benchmark': {
1999             'kpi': [
2000                 'packets_in',
2001                 'packets_fwd',
2002                 'packets_dropped',
2003             ],
2004         },
2005         'connection-point': [
2006             {
2007                 'type': 'VPORT',
2008                 'name': 'xe0',
2009             },
2010             {
2011                 'type': 'VPORT',
2012                 'name': 'xe1',
2013             },
2014         ],
2015         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
2016     }
2017
2018     VNFD = {
2019         'vnfd:vnfd-catalog': {
2020             'vnfd': [
2021                 VNFD_0,
2022             ],
2023         },
2024     }
2025
2026     TRAFFIC_PROFILE = {
2027         "schema": "isb:traffic_profile:0.1",
2028         "name": "fixed",
2029         "description": "Fixed traffic profile to run UDP traffic",
2030         "traffic_profile": {
2031             "traffic_type": "FixedTraffic",
2032             "frame_rate": 100,  # pps
2033             "flow_number": 10,
2034             "frame_size": 64,
2035         },
2036     }
2037
2038     def test__check_status(self):
2039         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2040
2041         with self.assertRaises(NotImplementedError):
2042             sample_vnf_tg._check_status()
2043
2044     def test_listen_traffic(self):
2045         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2046
2047         sample_vnf_tg.listen_traffic(mock.Mock())
2048
2049     def test_verify_traffic(self):
2050         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2051
2052         sample_vnf_tg.verify_traffic(mock.Mock())
2053
2054     def test_terminate(self):
2055         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2056         sample_vnf_tg._traffic_process = mock.Mock()
2057         sample_vnf_tg._tg_process = mock.Mock()
2058
2059         sample_vnf_tg.terminate()
2060
2061     def test__wait_for_process(self):
2062         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2063         with mock.patch.object(sample_vnf_tg, '_check_status',
2064                                return_value=0) as mock_status, \
2065                 mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
2066             mock_proc.is_alive.return_value = True
2067             mock_proc.exitcode = 234
2068             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
2069             mock_proc.is_alive.assert_called_once()
2070             mock_status.assert_called_once()
2071
2072     def test__wait_for_process_not_alive(self):
2073         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2074         with mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
2075             mock_proc.is_alive.return_value = False
2076             self.assertRaises(RuntimeError, sample_vnf_tg._wait_for_process)
2077             mock_proc.is_alive.assert_called_once()
2078
2079     def test__wait_for_process_delayed(self):
2080         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2081         with mock.patch.object(sample_vnf_tg, '_check_status',
2082                                side_effect=[1, 0]) as mock_status, \
2083                 mock.patch.object(sample_vnf_tg,
2084                                   '_tg_process') as mock_proc:
2085             mock_proc.is_alive.return_value = True
2086             mock_proc.exitcode = 234
2087             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
2088             mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()])
2089             mock_status.assert_has_calls([mock.call(), mock.call()])
2090
2091     def test_scale(self):
2092         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2093         self.assertRaises(y_exceptions.FunctionNotImplemented,
2094                           sample_vnf_tg.scale)