4d53f0989cbc6349751501edb412315a264a3738
[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         self.assertEqual(ssh_helper.execute.call_count, 0)
1520         self.assertEqual(ssh_helper.put.call_count, 0)
1521
1522     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1523     @mock.patch('subprocess.check_output')
1524     def test_deploy_vnfs(self, mock_check_output, mock_time):
1525         vnfd_helper = mock.Mock()
1526         ssh_helper = mock.Mock()
1527         ssh_helper.join_bin_path.return_value = 'joined_path'
1528         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1529         ssh_helper.put.return_value = None
1530         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1531         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1532
1533         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1534         self.assertEqual(ssh_helper.execute.call_count, 5)
1535         self.assertEqual(ssh_helper.put.call_count, 1)
1536
1537     @mock.patch('subprocess.check_output')
1538     def test_deploy_vnfs_early_success(self, mock_check_output):
1539         vnfd_helper = mock.Mock()
1540         ssh_helper = mock.Mock()
1541         ssh_helper.join_bin_path.return_value = 'joined_path'
1542         ssh_helper.execute.return_value = 0, 'output', ''
1543         ssh_helper.put.return_value = None
1544         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1545         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1546
1547         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1548         self.assertEqual(ssh_helper.execute.call_count, 1)
1549         self.assertEqual(ssh_helper.put.call_count, 0)
1550
1551
1552 class TestScenarioHelper(unittest.TestCase):
1553
1554     def test_property_task_path(self):
1555         scenario_helper = ScenarioHelper('name1')
1556         scenario_helper.scenario_cfg = {
1557             'task_path': 'my_path',
1558         }
1559
1560         self.assertEqual(scenario_helper.task_path, 'my_path')
1561
1562     def test_property_nodes(self):
1563         nodes = ['node1', 'node2']
1564         scenario_helper = ScenarioHelper('name1')
1565         scenario_helper.scenario_cfg = {
1566             'nodes': nodes,
1567         }
1568
1569         self.assertEqual(scenario_helper.nodes, nodes)
1570
1571     def test_property_all_options(self):
1572         data = {
1573             'name1': {
1574                 'key3': 'value3',
1575             },
1576             'name2': {}
1577         }
1578         scenario_helper = ScenarioHelper('name1')
1579         scenario_helper.scenario_cfg = {
1580             'options': data,
1581         }
1582
1583         self.assertDictEqual(scenario_helper.all_options, data)
1584
1585     def test_property_options(self):
1586         data = {
1587             'key1': 'value1',
1588             'key2': 'value2',
1589         }
1590         scenario_helper = ScenarioHelper('name1')
1591         scenario_helper.scenario_cfg = {
1592             'options': {
1593                 'name1': data,
1594             },
1595         }
1596
1597         self.assertDictEqual(scenario_helper.options, data)
1598
1599     def test_property_vnf_cfg(self):
1600         scenario_helper = ScenarioHelper('name1')
1601         scenario_helper.scenario_cfg = {
1602             'options': {
1603                 'name1': {
1604                     'vnf_config': 'my_config',
1605                 },
1606             },
1607         }
1608
1609         self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
1610
1611     def test_property_vnf_cfg_default(self):
1612         scenario_helper = ScenarioHelper('name1')
1613         scenario_helper.scenario_cfg = {
1614             'options': {
1615                 'name1': {},
1616             },
1617         }
1618
1619         self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
1620
1621     def test_property_topology(self):
1622         scenario_helper = ScenarioHelper('name1')
1623         scenario_helper.scenario_cfg = {
1624             'topology': 'my_topology',
1625         }
1626
1627         self.assertEqual(scenario_helper.topology, 'my_topology')
1628
1629
1630 class TestSampleVnf(unittest.TestCase):
1631
1632     VNFD_0 = {
1633         'short-name': 'VpeVnf',
1634         'vdu': [
1635             {
1636                 'routing_table': [
1637                     {
1638                         'network': '152.16.100.20',
1639                         'netmask': '255.255.255.0',
1640                         'gateway': '152.16.100.20',
1641                         'if': 'xe0'
1642                     },
1643                     {
1644                         'network': '152.16.40.20',
1645                         'netmask': '255.255.255.0',
1646                         'gateway': '152.16.40.20',
1647                         'if': 'xe1'
1648                     },
1649                 ],
1650                 'description': 'VPE approximation using DPDK',
1651                 'name': 'vpevnf-baremetal',
1652                 'nd_route_tbl': [
1653                     {
1654                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1655                         'netmask': '112',
1656                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1657                         'if': 'xe0'
1658                     },
1659                     {
1660                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1661                         'netmask': '112',
1662                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1663                         'if': 'xe1'
1664                     },
1665                 ],
1666                 'id': 'vpevnf-baremetal',
1667                 'external-interface': [
1668                     {
1669                         'virtual-interface': {
1670                             'dst_mac': '00:00:00:00:00:03',
1671                             'vpci': '0000:05:00.0',
1672                             'local_ip': '152.16.100.19',
1673                             'type': 'PCI-PASSTHROUGH',
1674                             'netmask': '255.255.255.0',
1675                             'dpdk_port_num': 0,
1676                             'bandwidth': '10 Gbps',
1677                             'dst_ip': '152.16.100.20',
1678                             'local_mac': '00:00:00:00:00:01'
1679                         },
1680                         'vnfd-connection-point-ref': 'xe0',
1681                         'name': 'xe0'
1682                     },
1683                     {
1684                         'virtual-interface': {
1685                             'dst_mac': '00:00:00:00:00:04',
1686                             'vpci': '0000:05:00.1',
1687                             'local_ip': '152.16.40.19',
1688                             'type': 'PCI-PASSTHROUGH',
1689                             'netmask': '255.255.255.0',
1690                             'dpdk_port_num': 1,
1691                             'bandwidth': '10 Gbps',
1692                             'dst_ip': '152.16.40.20',
1693                             'local_mac': '00:00:00:00:00:02'
1694                         },
1695                         'vnfd-connection-point-ref': 'xe1',
1696                         'name': 'xe1'
1697                     },
1698                 ],
1699             },
1700         ],
1701         'description': 'Vpe approximation using DPDK',
1702         'mgmt-interface': {
1703             'vdu-id': 'vpevnf-baremetal',
1704             'host': '1.1.1.1',
1705             'password': 'r00t',
1706             'user': 'root',
1707             'ip': '1.1.1.1'
1708         },
1709         'benchmark': {
1710             'kpi': [
1711                 'packets_in',
1712                 'packets_fwd',
1713                 'packets_dropped',
1714             ],
1715         },
1716         'connection-point': [
1717             {
1718                 'type': 'VPORT',
1719                 'name': 'xe0',
1720             },
1721             {
1722                 'type': 'VPORT',
1723                 'name': 'xe1',
1724             },
1725         ],
1726         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1727     }
1728
1729     VNFD = {
1730         'vnfd:vnfd-catalog': {
1731             'vnfd': [
1732                 VNFD_0,
1733             ]
1734         }
1735     }
1736
1737     TRAFFIC_PROFILE = {
1738         "schema": "isb:traffic_profile:0.1",
1739         "name": "fixed",
1740         "description": "Fixed traffic profile to run UDP traffic",
1741         "traffic_profile": {
1742             "traffic_type": "FixedTraffic",
1743             "frame_rate": 100,  # pps
1744             "flow_number": 10,
1745             "frame_size": 64,
1746         },
1747     }
1748
1749     def test___init__(self):
1750         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1751
1752         self.assertEqual(sample_vnf.name, 'vnf1')
1753         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1754
1755         # test the default setup helper is SetupEnvHelper, not subclass
1756         self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
1757
1758         # test the default resource helper is ResourceHelper, not subclass
1759         self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
1760
1761     def test___init___alt_types(self):
1762         class MySetupEnvHelper(SetupEnvHelper):
1763             pass
1764
1765         class MyResourceHelper(ResourceHelper):
1766             pass
1767
1768         sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
1769
1770         self.assertEqual(sample_vnf.name, 'vnf1')
1771         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1772
1773         # test the default setup helper is MySetupEnvHelper, not subclass
1774         self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
1775
1776         # test the default resource helper is MyResourceHelper, not subclass
1777         self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
1778
1779     def test__get_port0localip6(self):
1780         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1781         expected = '0064:ff9b:0:0:0:0:9810:6414'
1782         result = sample_vnf._get_port0localip6()
1783         self.assertEqual(result, expected)
1784
1785     def test__get_port1localip6(self):
1786         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1787         expected = '0064:ff9b:0:0:0:0:9810:2814'
1788         result = sample_vnf._get_port1localip6()
1789         self.assertEqual(result, expected)
1790
1791     def test__get_port0prefixip6(self):
1792         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1793         expected = '112'
1794         result = sample_vnf._get_port0prefixlen6()
1795         self.assertEqual(result, expected)
1796
1797     def test__get_port1prefixip6(self):
1798         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1799         expected = '112'
1800         result = sample_vnf._get_port1prefixlen6()
1801         self.assertEqual(result, expected)
1802
1803     def test__get_port0gateway6(self):
1804         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1805         expected = '0064:ff9b:0:0:0:0:9810:6414'
1806         result = sample_vnf._get_port0gateway6()
1807         self.assertEqual(result, expected)
1808
1809     def test__get_port1gateway6(self):
1810         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1811         expected = '0064:ff9b:0:0:0:0:9810:2814'
1812         result = sample_vnf._get_port1gateway6()
1813         self.assertEqual(result, expected)
1814
1815     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1816     def test__start_vnf(self, mock_process_type):
1817         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1818         sample_vnf = SampleVNF('vnf1', vnfd)
1819         sample_vnf._run = mock.Mock()
1820
1821         self.assertIsNone(sample_vnf.queue_wrapper)
1822         self.assertIsNone(sample_vnf._vnf_process)
1823         self.assertIsNone(sample_vnf._start_vnf())
1824         self.assertIsNotNone(sample_vnf.queue_wrapper)
1825         self.assertIsNotNone(sample_vnf._vnf_process)
1826
1827     @mock.patch("yardstick.ssh.SSH")
1828     def test_instantiate(self, ssh):
1829         mock_ssh(ssh)
1830
1831         nodes = {
1832             'vnf1': 'name1',
1833             'vnf2': 'name2',
1834         }
1835
1836         context1 = mock.Mock()
1837         context1._get_server.return_value = None
1838         context2 = mock.Mock()
1839         context2._get_server.return_value = context2
1840
1841         try:
1842             Context.list.clear()
1843         except AttributeError:
1844             # clear() but works in Py2.7
1845             Context.list[:] = []
1846
1847         Context.list.extend([
1848             context1,
1849             context2,
1850         ])
1851
1852         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1853         sample_vnf = SampleVNF('vnf1', vnfd)
1854         sample_vnf.APP_NAME = 'sample1'
1855         sample_vnf._start_server = mock.Mock(return_value=0)
1856         sample_vnf._vnf_process = mock.MagicMock()
1857         sample_vnf._vnf_process._is_alive.return_value = 1
1858         sample_vnf.ssh_helper = mock.MagicMock()
1859         sample_vnf.deploy_helper = mock.MagicMock()
1860         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1861         scenario_cfg = {
1862             'nodes': nodes,
1863         }
1864
1865         self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
1866         self.assertEqual(sample_vnf.nfvi_context, context2)
1867
1868     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1869     @mock.patch("yardstick.ssh.SSH")
1870     def test_wait_for_instantiate_empty_queue(self, ssh, mock_time):
1871         mock_ssh(ssh, exec_result=(1, "", ""))
1872
1873         queue_size_list = [
1874             0,
1875             1,
1876             0,
1877             1,
1878         ]
1879
1880         queue_get_list = [
1881             'some output',
1882             'pipeline> ',
1883         ]
1884
1885         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1886         sample_vnf = SampleVNF('vnf1', vnfd)
1887         sample_vnf.APP_NAME = 'sample1'
1888         sample_vnf._start_server = mock.Mock(return_value=0)
1889         sample_vnf._vnf_process = mock.MagicMock()
1890         sample_vnf._vnf_process.exitcode = 0
1891         sample_vnf._vnf_process._is_alive.return_value = 1
1892         sample_vnf.queue_wrapper = mock.Mock()
1893         sample_vnf.q_out = mock.Mock()
1894         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1895         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1896         sample_vnf.ssh_helper = mock.MagicMock()
1897         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1898         sample_vnf.resource_helper.start_collect = mock.MagicMock()
1899
1900         self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
1901
1902     def test__build_ports(self):
1903         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1904         sample_vnf = SampleVNF('vnf1', vnfd)
1905
1906         self.assertIsNone(sample_vnf._build_ports())
1907         self.assertIsNotNone(sample_vnf.networks)
1908         self.assertIsNotNone(sample_vnf.uplink_ports)
1909         self.assertIsNotNone(sample_vnf.downlink_ports)
1910         self.assertIsNotNone(sample_vnf.my_ports)
1911
1912     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1913     def test_vnf_execute_with_queue_data(self, mock_time):
1914         queue_size_list = [
1915             1,
1916             1,
1917             0,
1918         ]
1919
1920         queue_get_list = [
1921             'hello ',
1922             'world'
1923         ]
1924
1925         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1926         sample_vnf = SampleVNF('vnf1', vnfd)
1927         sample_vnf.APP_NAME = 'sample1'
1928         sample_vnf.q_out = mock.Mock()
1929         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1930         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1931
1932         self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
1933
1934     def test_terminate_without_vnf_process(self):
1935         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1936         sample_vnf = SampleVNF('vnf1', vnfd)
1937         sample_vnf.APP_NAME = 'sample1'
1938         sample_vnf.vnf_execute = mock.Mock()
1939         sample_vnf.ssh_helper = mock.Mock()
1940         sample_vnf._tear_down = mock.Mock()
1941         sample_vnf.resource_helper = mock.Mock()
1942
1943         self.assertIsNone(sample_vnf.terminate())
1944
1945     def test_get_stats(self):
1946         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1947         sample_vnf = SampleVNF('vnf1', vnfd)
1948         sample_vnf.APP_NAME = 'sample1'
1949         sample_vnf.APP_WORD = 'sample1'
1950         sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
1951
1952         self.assertEqual(sample_vnf.get_stats(), 'the stats')
1953
1954     def test_collect_kpi(self):
1955         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1956         sample_vnf = SampleVNF('vnf1', vnfd)
1957         sample_vnf.APP_NAME = 'sample1'
1958         sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
1959         sample_vnf.COLLECT_MAP = {
1960             'k1': 3,
1961             'k2': 1,
1962             'k3': 2,
1963         }
1964         sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1965         sample_vnf.resource_helper = mock.Mock()
1966         sample_vnf.resource_helper.collect_kpi.return_value = {}
1967
1968         expected = {
1969             'k1': 27,
1970             'k2': 34,
1971             'k3': 91,
1972             'collect_stats': {},
1973         }
1974         result = sample_vnf.collect_kpi()
1975         self.assertDictEqual(result, expected)
1976
1977     def test_collect_kpi_default(self):
1978         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1979         sample_vnf = SampleVNF('vnf1', vnfd)
1980         sample_vnf.APP_NAME = 'sample1'
1981         sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)'
1982         sample_vnf.get_stats = mock.Mock(return_value='')
1983
1984         expected = {
1985             'packets_in': 0,
1986             'packets_fwd': 0,
1987             'packets_dropped': 0,
1988         }
1989         result = sample_vnf.collect_kpi()
1990         self.assertDictEqual(result, expected)
1991
1992
1993 class TestSampleVNFTrafficGen(unittest.TestCase):
1994
1995     VNFD_0 = {
1996         'short-name': 'VpeVnf',
1997         'vdu': [
1998             {
1999                 'routing_table': [
2000                     {
2001                         'network': '152.16.100.20',
2002                         'netmask': '255.255.255.0',
2003                         'gateway': '152.16.100.20',
2004                         'if': 'xe0'
2005                     },
2006                     {
2007                         'network': '152.16.40.20',
2008                         'netmask': '255.255.255.0',
2009                         'gateway': '152.16.40.20',
2010                         'if': 'xe1'
2011                     },
2012                 ],
2013                 'description': 'VPE approximation using DPDK',
2014                 'name': 'vpevnf-baremetal',
2015                 'nd_route_tbl': [
2016                     {
2017                         'network': '0064:ff9b:0:0:0:0:9810:6414',
2018                         'netmask': '112',
2019                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
2020                         'if': 'xe0'
2021                     },
2022                     {
2023                         'network': '0064:ff9b:0:0:0:0:9810:2814',
2024                         'netmask': '112',
2025                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
2026                         'if': 'xe1'
2027                     },
2028                 ],
2029                 'id': 'vpevnf-baremetal',
2030                 'external-interface': [
2031                     {
2032                         'virtual-interface': {
2033                             'dst_mac': '00:00:00:00:00:03',
2034                             'vpci': '0000:05:00.0',
2035                             'driver': 'i40e',
2036                             'local_ip': '152.16.100.19',
2037                             'type': 'PCI-PASSTHROUGH',
2038                             'netmask': '255.255.255.0',
2039                             'dpdk_port_num': 0,
2040                             'bandwidth': '10 Gbps',
2041                             'dst_ip': '152.16.100.20',
2042                             'local_mac': '00:00:00:00:00:01'
2043                         },
2044                         'vnfd-connection-point-ref': 'xe0',
2045                         'name': 'xe0'
2046                     },
2047                     {
2048                         'virtual-interface': {
2049                             'dst_mac': '00:00:00:00:00:04',
2050                             'vpci': '0000:05:00.1',
2051                             'driver': 'ixgbe',
2052                             'local_ip': '152.16.40.19',
2053                             'type': 'PCI-PASSTHROUGH',
2054                             'netmask': '255.255.255.0',
2055                             'dpdk_port_num': 1,
2056                             'bandwidth': '10 Gbps',
2057                             'dst_ip': '152.16.40.20',
2058                             'local_mac': '00:00:00:00:00:02'
2059                         },
2060                         'vnfd-connection-point-ref': 'xe1',
2061                         'name': 'xe1'
2062                     },
2063                 ],
2064             },
2065         ],
2066         'description': 'Vpe approximation using DPDK',
2067         'mgmt-interface': {
2068             'vdu-id': 'vpevnf-baremetal',
2069             'host': '1.1.1.1',
2070             'password': 'r00t',
2071             'user': 'root',
2072             'ip': '1.1.1.1'
2073         },
2074         'benchmark': {
2075             'kpi': [
2076                 'packets_in',
2077                 'packets_fwd',
2078                 'packets_dropped',
2079             ],
2080         },
2081         'connection-point': [
2082             {
2083                 'type': 'VPORT',
2084                 'name': 'xe0',
2085             },
2086             {
2087                 'type': 'VPORT',
2088                 'name': 'xe1',
2089             },
2090         ],
2091         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
2092     }
2093
2094     VNFD = {
2095         'vnfd:vnfd-catalog': {
2096             'vnfd': [
2097                 VNFD_0,
2098             ],
2099         },
2100     }
2101
2102     TRAFFIC_PROFILE = {
2103         "schema": "isb:traffic_profile:0.1",
2104         "name": "fixed",
2105         "description": "Fixed traffic profile to run UDP traffic",
2106         "traffic_profile": {
2107             "traffic_type": "FixedTraffic",
2108             "frame_rate": 100,  # pps
2109             "flow_number": 10,
2110             "frame_size": 64,
2111         },
2112     }
2113
2114     def test__check_status(self):
2115         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2116
2117         with self.assertRaises(NotImplementedError):
2118             sample_vnf_tg._check_status()
2119
2120     def test_listen_traffic(self):
2121         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2122
2123         sample_vnf_tg.listen_traffic(mock.Mock())
2124
2125     def test_verify_traffic(self):
2126         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2127
2128         sample_vnf_tg.verify_traffic(mock.Mock())
2129
2130     def test_terminate(self):
2131         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2132         sample_vnf_tg._traffic_process = mock.Mock()
2133         sample_vnf_tg._tg_process = mock.Mock()
2134
2135         sample_vnf_tg.terminate()
2136
2137     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2138     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2139     def test_wait_for_instantiate(self, mock_logger, mock_time):
2140         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2141         sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
2142         sample_vnf_tg._tg_process = mock.Mock()
2143         sample_vnf_tg._tg_process.is_alive.return_value = True
2144         sample_vnf_tg._tg_process.exitcode = 234
2145
2146         self.assertEqual(sample_vnf_tg.wait_for_instantiate(), 234)
2147
2148     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2149     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2150     def test_wait_for_instantiate_not_alive(self, mock_logger, mock_time):
2151         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2152         sample_vnf_tg._check_status = mock.Mock(return_value=1)
2153         sample_vnf_tg._tg_process = mock.Mock()
2154         sample_vnf_tg._tg_process.is_alive.side_effect = iter([True, False])
2155         sample_vnf_tg._tg_process.exitcode = 234
2156
2157         with self.assertRaises(RuntimeError):
2158             sample_vnf_tg.wait_for_instantiate()
2159
2160     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
2161     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
2162     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
2163     def test_wait_for_instantiate_delayed(self, mock_process, mock_logger, mock_time):
2164         class MockClientStarted(mock.Mock):
2165
2166             def __init__(self, *args, **kwargs):
2167                 super(MockClientStarted, self).__init__(*args, **kwargs)
2168                 self.iter = iter([0, 0, 1])
2169
2170             @property
2171             def value(self):
2172                 return next(self.iter)
2173
2174         mock_traffic_profile = mock.Mock(autospec=TrafficProfile)
2175         mock_traffic_profile.get_traffic_definition.return_value = "64"
2176         mock_traffic_profile.execute_traffic.return_value = "64"
2177         mock_traffic_profile.params = self.TRAFFIC_PROFILE
2178
2179         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
2180         sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0]))
2181         sample_vnf_tg._tg_process = mock.Mock()
2182         sample_vnf_tg._tg_process.is_alive.return_value = True
2183         sample_vnf_tg._tg_process.exitcode = 234
2184         sample_vnf_tg.resource_helper = mock.Mock()
2185         sample_vnf_tg.resource_helper.client_started = MockClientStarted()
2186
2187         self.assertTrue(sample_vnf_tg.run_traffic(mock_traffic_profile))
2188         self.assertEqual(mock_time.sleep.call_count, 2)