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