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