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