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