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