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