Move arp route tbl to script and update defailt vnf config files
[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             'd1': ['0000:05:00.0'],
837             'd3': ['0000:05:01.0'],
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.client.get_stats.return_value = {
1140             0: {
1141                 'rx_pps': 5.5,
1142                 'tx_pps': 4.9,
1143                 'rx_bps': 234.78,
1144                 'tx_bps': 243.11,
1145                 'ipackets': 34251,
1146                 'opackets': 52342,
1147             },
1148             1: {
1149                 'tx_pps': 5.9,
1150                 'rx_bps': 434.78,
1151                 'opackets': 48791,
1152             },
1153         }
1154
1155         expected = {
1156             'xe0': {
1157                 "rx_throughput_fps": 5.5,
1158                 "tx_throughput_fps": 4.9,
1159                 "rx_throughput_mbps": 234.78,
1160                 "tx_throughput_mbps": 243.11,
1161                 "in_packets": 34251,
1162                 "out_packets": 52342,
1163             },
1164             'xe1': {
1165                 "rx_throughput_fps": 0.0,
1166                 "tx_throughput_fps": 5.9,
1167                 "rx_throughput_mbps": 434.78,
1168                 "tx_throughput_mbps": 0.0,
1169                 "in_packets": 0,
1170                 "out_packets": 48791,
1171             },
1172         }
1173         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1174         result = client_resource_helper.generate_samples(ports)
1175         self.assertDictEqual(result, expected)
1176
1177     def test_generate_samples_with_key(self):
1178         vnfd_helper = VnfdHelper(self.VNFD_0)
1179         ssh_helper = mock.Mock()
1180         scenario_helper = mock.Mock()
1181         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1182         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1183         client_resource_helper.client = mock.MagicMock()
1184         client_resource_helper.client.get_stats.return_value = {
1185             'key_name': 'key_value',
1186             0: {
1187                 'rx_pps': 5.5,
1188                 'tx_pps': 4.9,
1189                 'rx_bps': 234.78,
1190                 'tx_bps': 243.11,
1191                 'ipackets': 34251,
1192                 'opackets': 52342,
1193             },
1194             1: {
1195                 'tx_pps': 5.9,
1196                 'rx_bps': 434.78,
1197                 'opackets': 48791,
1198             },
1199         }
1200
1201         expected = {
1202             'xe0': {
1203                 'key_name': 'key_value',
1204                 "rx_throughput_fps": 5.5,
1205                 "tx_throughput_fps": 4.9,
1206                 "rx_throughput_mbps": 234.78,
1207                 "tx_throughput_mbps": 243.11,
1208                 "in_packets": 34251,
1209                 "out_packets": 52342,
1210             },
1211             'xe1': {
1212                 'key_name': 'key_value',
1213                 "rx_throughput_fps": 0.0,
1214                 "tx_throughput_fps": 5.9,
1215                 "rx_throughput_mbps": 434.78,
1216                 "tx_throughput_mbps": 0.0,
1217                 "in_packets": 0,
1218                 "out_packets": 48791,
1219             },
1220         }
1221         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1222         result = client_resource_helper.generate_samples(ports, 'key_name')
1223         self.assertDictEqual(result, expected)
1224
1225     def test_generate_samples_with_key_and_default(self):
1226         vnfd_helper = VnfdHelper(self.VNFD_0)
1227         ssh_helper = mock.Mock()
1228         scenario_helper = mock.Mock()
1229         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1230         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1231         client_resource_helper.client = mock.MagicMock()
1232         client_resource_helper.client.get_stats.return_value = {
1233             0: {
1234                 'rx_pps': 5.5,
1235                 'tx_pps': 4.9,
1236                 'rx_bps': 234.78,
1237                 'tx_bps': 243.11,
1238                 'ipackets': 34251,
1239                 'opackets': 52342,
1240             },
1241             1: {
1242                 'tx_pps': 5.9,
1243                 'rx_bps': 434.78,
1244                 'opackets': 48791,
1245             },
1246         }
1247
1248         expected = {
1249             'xe0': {
1250                 'key_name': 'default',
1251                 "rx_throughput_fps": 5.5,
1252                 "tx_throughput_fps": 4.9,
1253                 "rx_throughput_mbps": 234.78,
1254                 "tx_throughput_mbps": 243.11,
1255                 "in_packets": 34251,
1256                 "out_packets": 52342,
1257             },
1258             'xe1': {
1259                 'key_name': 'default',
1260                 "rx_throughput_fps": 0.0,
1261                 "tx_throughput_fps": 5.9,
1262                 "rx_throughput_mbps": 434.78,
1263                 "tx_throughput_mbps": 0.0,
1264                 "in_packets": 0,
1265                 "out_packets": 48791,
1266             },
1267         }
1268         ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports)
1269         result = client_resource_helper.generate_samples(ports, 'key_name', 'default')
1270         self.assertDictEqual(result, expected)
1271
1272     def test_clear_stats(self):
1273         vnfd_helper = VnfdHelper(self.VNFD_0)
1274         ssh_helper = mock.Mock()
1275         scenario_helper = mock.Mock()
1276         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1277         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1278         client_resource_helper.client = mock.Mock()
1279
1280         self.assertIsNone(client_resource_helper.clear_stats())
1281         self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
1282
1283     def test_clear_stats_of_ports(self):
1284         vnfd_helper = VnfdHelper(self.VNFD_0)
1285         ssh_helper = mock.Mock()
1286         scenario_helper = mock.Mock()
1287         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1288         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1289         client_resource_helper.client = mock.Mock()
1290
1291         self.assertIsNone(client_resource_helper.clear_stats([3, 4]))
1292         self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1)
1293
1294     def test_start(self):
1295         vnfd_helper = VnfdHelper(self.VNFD_0)
1296         ssh_helper = mock.Mock()
1297         scenario_helper = mock.Mock()
1298         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1299         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1300         client_resource_helper.client = mock.Mock()
1301
1302         self.assertIsNone(client_resource_helper.start())
1303         self.assertEqual(client_resource_helper.client.start.call_count, 1)
1304
1305     def test_start_ports(self):
1306         vnfd_helper = VnfdHelper(self.VNFD_0)
1307         ssh_helper = mock.Mock()
1308         scenario_helper = mock.Mock()
1309         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1310         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1311         client_resource_helper.client = mock.Mock()
1312
1313         self.assertIsNone(client_resource_helper.start([3, 4]))
1314         self.assertEqual(client_resource_helper.client.start.call_count, 1)
1315
1316     def test_collect_kpi_with_queue(self):
1317         vnfd_helper = VnfdHelper(self.VNFD_0)
1318         ssh_helper = mock.Mock()
1319         scenario_helper = mock.Mock()
1320         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1321         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1322         client_resource_helper._result = {'existing': 43, 'replaceable': 12}
1323         client_resource_helper._queue = mock.Mock()
1324         client_resource_helper._queue.empty.return_value = False
1325         client_resource_helper._queue.get.return_value = {'incoming': 34, 'replaceable': 99}
1326
1327         expected = {
1328             'existing': 43,
1329             'incoming': 34,
1330             'replaceable': 99,
1331         }
1332         result = client_resource_helper.collect_kpi()
1333         self.assertDictEqual(result, expected)
1334
1335     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1336     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
1337     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
1338                 new_callable=lambda: MockError)
1339     def test__connect_with_failures(self, mock_error, mock_logger, mock_time):
1340         vnfd_helper = VnfdHelper(self.VNFD_0)
1341         ssh_helper = mock.Mock()
1342         scenario_helper = mock.Mock()
1343         dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
1344         client_resource_helper = ClientResourceHelper(dpdk_setup_helper)
1345         client = mock.MagicMock()
1346         client.connect.side_effect = mock_error
1347
1348         self.assertIs(client_resource_helper._connect(client), client)
1349
1350
1351 class TestRfc2544ResourceHelper(unittest.TestCase):
1352
1353     RFC2544_CFG_1 = {
1354         'latency': True,
1355         'correlated_traffic': True,
1356         'allowed_drop_rate': '0.1 - 0.15',
1357     }
1358
1359     RFC2544_CFG_2 = {
1360         'allowed_drop_rate': '  0.25    -   0.05  ',
1361     }
1362
1363     RFC2544_CFG_3 = {
1364         'allowed_drop_rate': '0.2',
1365     }
1366
1367     RFC2544_CFG_4 = {
1368         'latency': True,
1369     }
1370
1371     SCENARIO_CFG_1 = {
1372         'options': {
1373             'rfc2544': RFC2544_CFG_1,
1374         }
1375     }
1376
1377     SCENARIO_CFG_2 = {
1378         'options': {
1379             'rfc2544': RFC2544_CFG_2,
1380         }
1381     }
1382
1383     SCENARIO_CFG_3 = {
1384         'options': {
1385             'rfc2544': RFC2544_CFG_3,
1386         }
1387     }
1388
1389     SCENARIO_CFG_4 = {
1390         'options': {
1391             'rfc2544': RFC2544_CFG_4,
1392         }
1393     }
1394
1395     def test_property_rfc2544(self):
1396         scenario_helper = ScenarioHelper('name1')
1397         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1398         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1399
1400         self.assertIsNone(rfc2544_resource_helper._rfc2544)
1401         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1402         self.assertDictEqual(rfc2544_resource_helper._rfc2544, self.RFC2544_CFG_1)
1403         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1404         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1405
1406     def test_property_tolerance_high(self):
1407         scenario_helper = ScenarioHelper('name1')
1408         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1409         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1410
1411         self.assertIsNone(rfc2544_resource_helper._tolerance_high)
1412         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1413         self.assertEqual(rfc2544_resource_helper._tolerance_high, 0.15)
1414         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1415         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1416
1417     def test_property_tolerance_low(self):
1418         scenario_helper = ScenarioHelper('name1')
1419         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1420         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1421
1422         self.assertIsNone(rfc2544_resource_helper._tolerance_low)
1423         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1424         self.assertEqual(rfc2544_resource_helper._tolerance_low, 0.1)
1425         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1426         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1427
1428     def test_property_tolerance_high_range_swap(self):
1429         scenario_helper = ScenarioHelper('name1')
1430         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1431         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1432
1433         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.25)
1434
1435     def test_property_tolerance_low_range_swap(self):
1436         scenario_helper = ScenarioHelper('name1')
1437         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1438         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1439
1440         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.05)
1441
1442     def test_property_tolerance_high_not_range(self):
1443         scenario_helper = ScenarioHelper('name1')
1444         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1445         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1446
1447         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.2)
1448
1449     def test_property_tolerance_low_not_range(self):
1450         scenario_helper = ScenarioHelper('name1')
1451         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1452         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1453
1454         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.2)
1455
1456     def test_property_tolerance_high_default(self):
1457         scenario_helper = ScenarioHelper('name1')
1458         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1459         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1460
1461         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.0001)
1462
1463     def test_property_tolerance_low_default(self):
1464         scenario_helper = ScenarioHelper('name1')
1465         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1466         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1467
1468         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.0001)
1469
1470     def test_property_latency(self):
1471         scenario_helper = ScenarioHelper('name1')
1472         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1473         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1474
1475         self.assertIsNone(rfc2544_resource_helper._latency)
1476         self.assertTrue(rfc2544_resource_helper.latency)
1477         self.assertTrue(rfc2544_resource_helper._latency)
1478         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1479         self.assertTrue(rfc2544_resource_helper.latency)
1480
1481     def test_property_latency_default(self):
1482         scenario_helper = ScenarioHelper('name1')
1483         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1484         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1485
1486         self.assertFalse(rfc2544_resource_helper.latency)
1487
1488     def test_property_correlated_traffic(self):
1489         scenario_helper = ScenarioHelper('name1')
1490         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1491         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1492
1493         self.assertIsNone(rfc2544_resource_helper._correlated_traffic)
1494         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1495         self.assertTrue(rfc2544_resource_helper._correlated_traffic)
1496         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1497         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1498
1499     def test_property_correlated_traffic_default(self):
1500         scenario_helper = ScenarioHelper('name1')
1501         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1502         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1503
1504         self.assertFalse(rfc2544_resource_helper.correlated_traffic)
1505
1506
1507 class TestSampleVNFDeployHelper(unittest.TestCase):
1508
1509     @mock.patch('subprocess.check_output')
1510     def test_deploy_vnfs_disabled(self, mock_check_output):
1511         vnfd_helper = mock.Mock()
1512         ssh_helper = mock.Mock()
1513         ssh_helper.join_bin_path.return_value = 'joined_path'
1514         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1515         ssh_helper.put.return_value = None
1516         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1517
1518         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1519         sample_vnf_deploy_helper.DISABLE_DEPLOY = True
1520         self.assertEqual(ssh_helper.execute.call_count, 5)
1521         self.assertEqual(ssh_helper.put.call_count, 1)
1522
1523     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1524     @mock.patch('subprocess.check_output')
1525     def test_deploy_vnfs(self, mock_check_output, mock_time):
1526         vnfd_helper = mock.Mock()
1527         ssh_helper = mock.Mock()
1528         ssh_helper.join_bin_path.return_value = 'joined_path'
1529         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1530         ssh_helper.put.return_value = None
1531         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1532         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1533
1534         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1535         self.assertEqual(ssh_helper.execute.call_count, 5)
1536         self.assertEqual(ssh_helper.put.call_count, 1)
1537
1538     @mock.patch('subprocess.check_output')
1539     def test_deploy_vnfs_early_success(self, mock_check_output):
1540         vnfd_helper = mock.Mock()
1541         ssh_helper = mock.Mock()
1542         ssh_helper.join_bin_path.return_value = 'joined_path'
1543         ssh_helper.execute.return_value = 0, 'output', ''
1544         ssh_helper.put.return_value = None
1545         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1546         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1547
1548         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1549         self.assertEqual(ssh_helper.execute.call_count, 1)
1550         self.assertEqual(ssh_helper.put.call_count, 0)
1551
1552
1553 class TestScenarioHelper(unittest.TestCase):
1554
1555     def test_property_task_path(self):
1556         scenario_helper = ScenarioHelper('name1')
1557         scenario_helper.scenario_cfg = {
1558             'task_path': 'my_path',
1559         }
1560
1561         self.assertEqual(scenario_helper.task_path, 'my_path')
1562
1563     def test_property_nodes(self):
1564         nodes = ['node1', 'node2']
1565         scenario_helper = ScenarioHelper('name1')
1566         scenario_helper.scenario_cfg = {
1567             'nodes': nodes,
1568         }
1569
1570         self.assertEqual(scenario_helper.nodes, nodes)
1571
1572     def test_property_all_options(self):
1573         data = {
1574             'name1': {
1575                 'key3': 'value3',
1576             },
1577             'name2': {}
1578         }
1579         scenario_helper = ScenarioHelper('name1')
1580         scenario_helper.scenario_cfg = {
1581             'options': data,
1582         }
1583
1584         self.assertDictEqual(scenario_helper.all_options, data)
1585
1586     def test_property_options(self):
1587         data = {
1588             'key1': 'value1',
1589             'key2': 'value2',
1590         }
1591         scenario_helper = ScenarioHelper('name1')
1592         scenario_helper.scenario_cfg = {
1593             'options': {
1594                 'name1': data,
1595             },
1596         }
1597
1598         self.assertDictEqual(scenario_helper.options, data)
1599
1600     def test_property_vnf_cfg(self):
1601         scenario_helper = ScenarioHelper('name1')
1602         scenario_helper.scenario_cfg = {
1603             'options': {
1604                 'name1': {
1605                     'vnf_config': 'my_config',
1606                 },
1607             },
1608         }
1609
1610         self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
1611
1612     def test_property_vnf_cfg_default(self):
1613         scenario_helper = ScenarioHelper('name1')
1614         scenario_helper.scenario_cfg = {
1615             'options': {
1616                 'name1': {},
1617             },
1618         }
1619
1620         self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
1621
1622     def test_property_topology(self):
1623         scenario_helper = ScenarioHelper('name1')
1624         scenario_helper.scenario_cfg = {
1625             'topology': 'my_topology',
1626         }
1627
1628         self.assertEqual(scenario_helper.topology, 'my_topology')
1629
1630
1631 class TestSampleVnf(unittest.TestCase):
1632
1633     VNFD_0 = {
1634         'short-name': 'VpeVnf',
1635         'vdu': [
1636             {
1637                 'routing_table': [
1638                     {
1639                         'network': '152.16.100.20',
1640                         'netmask': '255.255.255.0',
1641                         'gateway': '152.16.100.20',
1642                         'if': 'xe0'
1643                     },
1644                     {
1645                         'network': '152.16.40.20',
1646                         'netmask': '255.255.255.0',
1647                         'gateway': '152.16.40.20',
1648                         'if': 'xe1'
1649                     },
1650                 ],
1651                 'description': 'VPE approximation using DPDK',
1652                 'name': 'vpevnf-baremetal',
1653                 'nd_route_tbl': [
1654                     {
1655                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1656                         'netmask': '112',
1657                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1658                         'if': 'xe0'
1659                     },
1660                     {
1661                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1662                         'netmask': '112',
1663                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1664                         'if': 'xe1'
1665                     },
1666                 ],
1667                 'id': 'vpevnf-baremetal',
1668                 'external-interface': [
1669                     {
1670                         'virtual-interface': {
1671                             'dst_mac': '00:00:00:00:00:03',
1672                             'vpci': '0000:05:00.0',
1673                             'local_ip': '152.16.100.19',
1674                             'type': 'PCI-PASSTHROUGH',
1675                             'netmask': '255.255.255.0',
1676                             'dpdk_port_num': 0,
1677                             'bandwidth': '10 Gbps',
1678                             'dst_ip': '152.16.100.20',
1679                             'local_mac': '00:00:00:00:00:01'
1680                         },
1681                         'vnfd-connection-point-ref': 'xe0',
1682                         'name': 'xe0'
1683                     },
1684                     {
1685                         'virtual-interface': {
1686                             'dst_mac': '00:00:00:00:00:04',
1687                             'vpci': '0000:05:00.1',
1688                             'local_ip': '152.16.40.19',
1689                             'type': 'PCI-PASSTHROUGH',
1690                             'netmask': '255.255.255.0',
1691                             'dpdk_port_num': 1,
1692                             'bandwidth': '10 Gbps',
1693                             'dst_ip': '152.16.40.20',
1694                             'local_mac': '00:00:00:00:00:02'
1695                         },
1696                         'vnfd-connection-point-ref': 'xe1',
1697                         'name': 'xe1'
1698                     },
1699                 ],
1700             },
1701         ],
1702         'description': 'Vpe approximation using DPDK',
1703         'mgmt-interface': {
1704             'vdu-id': 'vpevnf-baremetal',
1705             'host': '1.1.1.1',
1706             'password': 'r00t',
1707             'user': 'root',
1708             'ip': '1.1.1.1'
1709         },
1710         'benchmark': {
1711             'kpi': [
1712                 'packets_in',
1713                 'packets_fwd',
1714                 'packets_dropped',
1715             ],
1716         },
1717         'connection-point': [
1718             {
1719                 'type': 'VPORT',
1720                 'name': 'xe0',
1721             },
1722             {
1723                 'type': 'VPORT',
1724                 'name': 'xe1',
1725             },
1726         ],
1727         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1728     }
1729
1730     VNFD = {
1731         'vnfd:vnfd-catalog': {
1732             'vnfd': [
1733                 VNFD_0,
1734             ]
1735         }
1736     }
1737
1738     TRAFFIC_PROFILE = {
1739         "schema": "isb:traffic_profile:0.1",
1740         "name": "fixed",
1741         "description": "Fixed traffic profile to run UDP traffic",
1742         "traffic_profile": {
1743             "traffic_type": "FixedTraffic",
1744             "frame_rate": 100,  # pps
1745             "flow_number": 10,
1746             "frame_size": 64,
1747         },
1748     }
1749
1750     def test___init__(self):
1751         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1752
1753         self.assertEqual(sample_vnf.name, 'vnf1')
1754         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1755
1756         # test the default setup helper is SetupEnvHelper, not subclass
1757         self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
1758
1759         # test the default resource helper is ResourceHelper, not subclass
1760         self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
1761
1762     def test___init___alt_types(self):
1763         class MySetupEnvHelper(SetupEnvHelper):
1764             pass
1765
1766         class MyResourceHelper(ResourceHelper):
1767             pass
1768
1769         sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
1770
1771         self.assertEqual(sample_vnf.name, 'vnf1')
1772         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1773
1774         # test the default setup helper is MySetupEnvHelper, not subclass
1775         self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
1776
1777         # test the default resource helper is MyResourceHelper, not subclass
1778         self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
1779
1780     def test__get_port0localip6(self):
1781         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1782         expected = '0064:ff9b:0:0:0:0:9810:6414'
1783         result = sample_vnf._get_port0localip6()
1784         self.assertEqual(result, expected)
1785
1786     def test__get_port1localip6(self):
1787         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1788         expected = '0064:ff9b:0:0:0:0:9810:2814'
1789         result = sample_vnf._get_port1localip6()
1790         self.assertEqual(result, expected)
1791
1792     def test__get_port0prefixip6(self):
1793         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1794         expected = '112'
1795         result = sample_vnf._get_port0prefixlen6()
1796         self.assertEqual(result, expected)
1797
1798     def test__get_port1prefixip6(self):
1799         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1800         expected = '112'
1801         result = sample_vnf._get_port1prefixlen6()
1802         self.assertEqual(result, expected)
1803
1804     def test__get_port0gateway6(self):
1805         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1806         expected = '0064:ff9b:0:0:0:0:9810:6414'
1807         result = sample_vnf._get_port0gateway6()
1808         self.assertEqual(result, expected)
1809
1810     def test__get_port1gateway6(self):
1811         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1812         expected = '0064:ff9b:0:0:0:0:9810:2814'
1813         result = sample_vnf._get_port1gateway6()
1814         self.assertEqual(result, expected)
1815
1816     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1817     def test__start_vnf(self, mock_process_type):
1818         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1819         sample_vnf = SampleVNF('vnf1', vnfd)
1820         sample_vnf._run = mock.Mock()
1821
1822         self.assertIsNone(sample_vnf.queue_wrapper)
1823         self.assertIsNone(sample_vnf._vnf_process)
1824         self.assertIsNone(sample_vnf._start_vnf())
1825         self.assertIsNotNone(sample_vnf.queue_wrapper)
1826         self.assertIsNotNone(sample_vnf._vnf_process)
1827
1828     @mock.patch("yardstick.ssh.SSH")
1829     def test_instantiate(self, ssh):
1830         mock_ssh(ssh)
1831
1832         nodes = {
1833             'vnf1': 'name1',
1834             'vnf2': 'name2',
1835         }
1836
1837         context1 = mock.Mock()
1838         context1._get_server.return_value = None
1839         context2 = mock.Mock()
1840         context2._get_server.return_value = context2
1841
1842         try:
1843             Context.list.clear()
1844         except AttributeError:
1845             # clear() but works in Py2.7
1846             Context.list[:] = []
1847
1848         Context.list.extend([
1849             context1,
1850             context2,
1851         ])
1852
1853         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1854         sample_vnf = SampleVNF('vnf1', vnfd)
1855         sample_vnf.APP_NAME = 'sample1'
1856         sample_vnf._start_server = mock.Mock(return_value=0)
1857         sample_vnf._vnf_process = mock.MagicMock()
1858         sample_vnf._vnf_process._is_alive.return_value = 1
1859         sample_vnf.ssh_helper = mock.MagicMock()
1860         sample_vnf.deploy_helper = mock.MagicMock()
1861         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1862         scenario_cfg = {
1863             'nodes': nodes,
1864         }
1865
1866         self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
1867         self.assertEqual(sample_vnf.nfvi_context, context2)
1868
1869     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1870     @mock.patch("yardstick.ssh.SSH")
1871     def test_wait_for_instantiate_empty_queue(self, ssh, mock_time):
1872         mock_ssh(ssh, exec_result=(1, "", ""))
1873
1874         queue_size_list = [
1875             0,
1876             1,
1877             0,
1878             1,
1879         ]
1880
1881         queue_get_list = [
1882             'some output',
1883             'pipeline> ',
1884         ]
1885
1886         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1887         sample_vnf = SampleVNF('vnf1', vnfd)
1888         sample_vnf.APP_NAME = 'sample1'
1889         sample_vnf.WAIT_TIME_FOR_SCRIPT = 0
1890         sample_vnf._start_server = mock.Mock(return_value=0)
1891         sample_vnf._vnf_process = mock.MagicMock()
1892         sample_vnf._vnf_process.exitcode = 0
1893         sample_vnf._vnf_process._is_alive.return_value = 1
1894         sample_vnf.queue_wrapper = mock.Mock()
1895         sample_vnf.q_out = mock.Mock()
1896         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1897         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1898         sample_vnf.ssh_helper = mock.MagicMock()
1899         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1900         sample_vnf.resource_helper.start_collect = mock.MagicMock()
1901
1902         self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
1903
1904     def test__build_ports(self):
1905         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1906         sample_vnf = SampleVNF('vnf1', vnfd)
1907
1908         self.assertIsNone(sample_vnf._build_ports())
1909         self.assertIsNotNone(sample_vnf.networks)
1910         self.assertIsNotNone(sample_vnf.uplink_ports)
1911         self.assertIsNotNone(sample_vnf.downlink_ports)
1912         self.assertIsNotNone(sample_vnf.my_ports)
1913
1914     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1915     def test_vnf_execute_with_queue_data(self, mock_time):
1916         queue_size_list = [
1917             1,
1918             1,
1919             0,
1920         ]
1921
1922         queue_get_list = [
1923             'hello ',
1924             'world'
1925         ]
1926
1927         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1928         sample_vnf = SampleVNF('vnf1', vnfd)
1929         sample_vnf.APP_NAME = 'sample1'
1930         sample_vnf.q_out = mock.Mock()
1931         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1932         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1933
1934         self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
1935
1936     def test_terminate_without_vnf_process(self):
1937         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1938         sample_vnf = SampleVNF('vnf1', vnfd)
1939         sample_vnf.APP_NAME = 'sample1'
1940         sample_vnf.vnf_execute = mock.Mock()
1941         sample_vnf.ssh_helper = mock.Mock()
1942         sample_vnf._tear_down = mock.Mock()
1943         sample_vnf.resource_helper = mock.Mock()
1944
1945         self.assertIsNone(sample_vnf.terminate())
1946
1947     def test_get_stats(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.APP_WORD = 'sample1'
1952         sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
1953
1954         self.assertEqual(sample_vnf.get_stats(), 'the stats')
1955
1956     def test_collect_kpi(self):
1957         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1958         sample_vnf = SampleVNF('vnf1', vnfd)
1959         sample_vnf.APP_NAME = 'sample1'
1960         sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
1961         sample_vnf.COLLECT_MAP = {
1962             'k1': 3,
1963             'k2': 1,
1964             'k3': 2,
1965         }
1966         sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1967         sample_vnf.resource_helper = mock.Mock()
1968         sample_vnf.resource_helper.collect_kpi.return_value = {}
1969
1970         expected = {
1971             'k1': 27,
1972             'k2': 34,
1973             'k3': 91,
1974             'collect_stats': {},
1975         }
1976         result = sample_vnf.collect_kpi()
1977         self.assertDictEqual(result, expected)
1978
1979     def test_collect_kpi_default(self):
1980         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1981         sample_vnf = SampleVNF('vnf1', vnfd)
1982         sample_vnf.APP_NAME = 'sample1'
1983         sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
1984         sample_vnf.get_stats = mock.Mock(return_value='')
1985
1986         expected = {
1987             'packets_in': 0,
1988             'packets_fwd': 0,
1989             'packets_dropped': 0,
1990         }
1991         result = sample_vnf.collect_kpi()
1992         self.assertDictEqual(result, expected)
1993
1994
1995 class TestSampleVNFTrafficGen(unittest.TestCase):
1996
1997     VNFD_0 = {
1998         'short-name': 'VpeVnf',
1999         'vdu': [
2000             {
2001                 'routing_table': [
2002                     {
2003                         'network': '152.16.100.20',
2004                         'netmask': '255.255.255.0',
2005                         'gateway': '152.16.100.20',
2006                         'if': 'xe0'
2007                     },
2008                     {
2009                         'network': '152.16.40.20',
2010                         'netmask': '255.255.255.0',
2011                         'gateway': '152.16.40.20',
2012                         'if': 'xe1'
2013                     },
2014                 ],
2015                 'description': 'VPE approximation using DPDK',
2016                 'name': 'vpevnf-baremetal',
2017                 'nd_route_tbl': [
2018                     {
2019                         'network': '0064:ff9b:0:0:0:0:9810:6414',
2020                         'netmask': '112',
2021                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
2022                         'if': 'xe0'
2023                     },
2024                     {
2025                         'network': '0064:ff9b:0:0:0:0:9810:2814',
2026                         'netmask': '112',
2027                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
2028                         'if': 'xe1'
2029                     },
2030                 ],
2031                 'id': 'vpevnf-baremetal',
2032                 'external-interface': [
2033                     {
2034                         'virtual-interface': {
2035                             'dst_mac': '00:00:00:00:00:03',
2036                             'vpci': '0000:05:00.0',
2037                             'driver': 'i40e',
2038                             'local_ip': '152.16.100.19',
2039                             'type': 'PCI-PASSTHROUGH',
2040                             'netmask': '255.255.255.0',
2041                             'dpdk_port_num': 0,
2042                             'bandwidth': '10 Gbps',
2043                             'dst_ip': '152.16.100.20',
2044                             'local_mac': '00:00:00:00:00:01'
2045                         },
2046                         'vnfd-connection-point-ref': 'xe0',
2047                         'name': 'xe0'
2048                     },
2049                     {
2050                         'virtual-interface': {
2051                             'dst_mac': '00:00:00:00:00:04',
2052                             'vpci': '0000:05:00.1',
2053                             'driver': 'ixgbe',
2054                             'local_ip': '152.16.40.19',
2055                             'type': 'PCI-PASSTHROUGH',
2056                             'netmask': '255.255.255.0',
2057                             'dpdk_port_num': 1,
2058                             'bandwidth': '10 Gbps',
2059                             'dst_ip': '152.16.40.20',
2060                             'local_mac': '00:00:00:00:00:02'
2061                         },
2062                         'vnfd-connection-point-ref': 'xe1',
2063                         'name': 'xe1'
2064                     },
2065                 ],
2066             },
2067         ],
2068         'description': 'Vpe approximation using DPDK',
2069         'mgmt-interface': {
2070             'vdu-id': 'vpevnf-baremetal',
2071             'host': '1.1.1.1',
2072             'password': 'r00t',
2073             'user': 'root',
2074             'ip': '1.1.1.1'
2075         },
2076         'benchmark': {
2077             'kpi': [
2078                 'packets_in',
2079                 'packets_fwd',
2080                 'packets_dropped',
2081             ],
2082         },
2083         'connection-point': [
2084             {
2085                 'type': 'VPORT',
2086                 'name': 'xe0',
2087             },
2088             {
2089                 'type': 'VPORT',
2090                 'name': 'xe1',
2091             },
2092         ],
2093         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
2094     }
2095
2096     VNFD = {
2097         'vnfd:vnfd-catalog': {
2098             'vnfd': [
2099                 VNFD_0,
2100             ],
2101         },
2102     }
2103
2104     TRAFFIC_PROFILE = {
2105         "schema": "isb:traffic_profile:0.1",
2106         "name": "fixed",
2107         "description": "Fixed traffic profile to run UDP traffic",
2108         "traffic_profile": {
2109             "traffic_type": "FixedTraffic",
2110             "frame_rate": 100,  # pps
2111             "flow_number": 10,
2112             "frame_size": 64,
2113         },
2114     }
2115
2116     def test__check_status(self):
2117         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2118
2119         with self.assertRaises(NotImplementedError):
2120             sample_vnf_tg._check_status()
2121
2122     def test_listen_traffic(self):
2123         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2124
2125         sample_vnf_tg.listen_traffic(mock.Mock())
2126
2127     def test_verify_traffic(self):
2128         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2129
2130         sample_vnf_tg.verify_traffic(mock.Mock())
2131
2132     def test_terminate(self):
2133         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2134         sample_vnf_tg._traffic_process = mock.Mock()
2135         sample_vnf_tg._tg_process = mock.Mock()
2136
2137         sample_vnf_tg.terminate()
2138
2139     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2140     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2141     def test_wait_for_instantiate(self, mock_logger, mock_time):
2142         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2143         sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
2144         sample_vnf_tg._tg_process = mock.Mock()
2145         sample_vnf_tg._tg_process.is_alive.return_value = True
2146         sample_vnf_tg._tg_process.exitcode = 234
2147
2148         self.assertEqual(sample_vnf_tg.wait_for_instantiate(), 234)
2149
2150     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2151     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2152     def test_wait_for_instantiate_not_alive(self, mock_logger, mock_time):
2153         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2154         sample_vnf_tg._check_status = mock.Mock(return_value=1)
2155         sample_vnf_tg._tg_process = mock.Mock()
2156         sample_vnf_tg._tg_process.is_alive.side_effect = iter([True, False])
2157         sample_vnf_tg._tg_process.exitcode = 234
2158
2159         with self.assertRaises(RuntimeError):
2160             sample_vnf_tg.wait_for_instantiate()
2161
2162     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2163     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2164     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
2165     def test_wait_for_instantiate_delayed(self, mock_process, mock_logger, mock_time):
2166         class MockClientStarted(mock.Mock):
2167
2168             def __init__(self, *args, **kwargs):
2169                 super(MockClientStarted, self).__init__(*args, **kwargs)
2170                 self.iter = iter([0, 0, 1])
2171
2172             @property
2173             def value(self):
2174                 return next(self.iter)
2175
2176         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
2177         mock_traffic_profile.get_traffic_definition.return_value = "64"
2178         mock_traffic_profile.execute_traffic.return_value = "64"
2179         mock_traffic_profile.params = self.TRAFFIC_PROFILE
2180
2181         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2182         sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
2183         sample_vnf_tg._tg_process = mock.Mock()
2184         sample_vnf_tg._tg_process.is_alive.return_value = True
2185         sample_vnf_tg._tg_process.exitcode = 234
2186         sample_vnf_tg.resource_helper = mock.Mock()
2187         sample_vnf_tg.resource_helper.client_started = MockClientStarted()
2188
2189         self.assertTrue(sample_vnf_tg.run_traffic(mock_traffic_profile))
2190         self.assertEqual(mock_time.sleep.call_count, 2)