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