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