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