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