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