Create Dockerfile to create a yardstick-image of docker
[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
1094 class TestRfc2544ResourceHelper(unittest.TestCase):
1095
1096     RFC2544_CFG_1 = {
1097         'latency': True,
1098         'correlated_traffic': True,
1099         'allowed_drop_rate': '0.1 - 0.15',
1100     }
1101
1102     RFC2544_CFG_2 = {
1103         'allowed_drop_rate': '  0.25    -   0.05  ',
1104     }
1105
1106     RFC2544_CFG_3 = {
1107         'allowed_drop_rate': '0.2',
1108     }
1109
1110     RFC2544_CFG_4 = {
1111         'latency': True,
1112     }
1113
1114     SCENARIO_CFG_1 = {
1115         'options': {
1116             'rfc2544': RFC2544_CFG_1,
1117         }
1118     }
1119
1120     SCENARIO_CFG_2 = {
1121         'options': {
1122             'rfc2544': RFC2544_CFG_2,
1123         }
1124     }
1125
1126     SCENARIO_CFG_3 = {
1127         'options': {
1128             'rfc2544': RFC2544_CFG_3,
1129         }
1130     }
1131
1132     SCENARIO_CFG_4 = {
1133         'options': {
1134             'rfc2544': RFC2544_CFG_4,
1135         }
1136     }
1137
1138     def test_property_rfc2544(self):
1139         scenario_helper = ScenarioHelper('name1')
1140         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1141         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1142
1143         self.assertIsNone(rfc2544_resource_helper._rfc2544)
1144         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1145         self.assertDictEqual(rfc2544_resource_helper._rfc2544, self.RFC2544_CFG_1)
1146         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1147         self.assertDictEqual(rfc2544_resource_helper.rfc2544, self.RFC2544_CFG_1)
1148
1149     def test_property_tolerance_high(self):
1150         scenario_helper = ScenarioHelper('name1')
1151         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1152         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1153
1154         self.assertIsNone(rfc2544_resource_helper._tolerance_high)
1155         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1156         self.assertEqual(rfc2544_resource_helper._tolerance_high, 0.15)
1157         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1158         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.15)
1159
1160     def test_property_tolerance_low(self):
1161         scenario_helper = ScenarioHelper('name1')
1162         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1163         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1164
1165         self.assertIsNone(rfc2544_resource_helper._tolerance_low)
1166         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1167         self.assertEqual(rfc2544_resource_helper._tolerance_low, 0.1)
1168         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1169         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.1)
1170
1171     def test_property_tolerance_high_range_swap(self):
1172         scenario_helper = ScenarioHelper('name1')
1173         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1174         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1175
1176         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.25)
1177
1178     def test_property_tolerance_low_range_swap(self):
1179         scenario_helper = ScenarioHelper('name1')
1180         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1181         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1182
1183         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.05)
1184
1185     def test_property_tolerance_high_not_range(self):
1186         scenario_helper = ScenarioHelper('name1')
1187         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1188         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1189
1190         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.2)
1191
1192     def test_property_tolerance_low_not_range(self):
1193         scenario_helper = ScenarioHelper('name1')
1194         scenario_helper.scenario_cfg = self.SCENARIO_CFG_3
1195         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1196
1197         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.2)
1198
1199     def test_property_tolerance_high_default(self):
1200         scenario_helper = ScenarioHelper('name1')
1201         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1202         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1203
1204         self.assertEqual(rfc2544_resource_helper.tolerance_high, 0.0001)
1205
1206     def test_property_tolerance_low_default(self):
1207         scenario_helper = ScenarioHelper('name1')
1208         scenario_helper.scenario_cfg = self.SCENARIO_CFG_4
1209         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1210
1211         self.assertEqual(rfc2544_resource_helper.tolerance_low, 0.0001)
1212
1213     def test_property_latency(self):
1214         scenario_helper = ScenarioHelper('name1')
1215         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1216         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1217
1218         self.assertIsNone(rfc2544_resource_helper._latency)
1219         self.assertTrue(rfc2544_resource_helper.latency)
1220         self.assertTrue(rfc2544_resource_helper._latency)
1221         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1222         self.assertTrue(rfc2544_resource_helper.latency)
1223
1224     def test_property_latency_default(self):
1225         scenario_helper = ScenarioHelper('name1')
1226         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1227         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1228
1229         self.assertFalse(rfc2544_resource_helper.latency)
1230
1231     def test_property_correlated_traffic(self):
1232         scenario_helper = ScenarioHelper('name1')
1233         scenario_helper.scenario_cfg = self.SCENARIO_CFG_1
1234         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1235
1236         self.assertIsNone(rfc2544_resource_helper._correlated_traffic)
1237         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1238         self.assertTrue(rfc2544_resource_helper._correlated_traffic)
1239         scenario_helper.scenario_cfg = {}  # ensure that resource_helper caches
1240         self.assertTrue(rfc2544_resource_helper.correlated_traffic)
1241
1242     def test_property_correlated_traffic_default(self):
1243         scenario_helper = ScenarioHelper('name1')
1244         scenario_helper.scenario_cfg = self.SCENARIO_CFG_2
1245         rfc2544_resource_helper = Rfc2544ResourceHelper(scenario_helper)
1246
1247         self.assertFalse(rfc2544_resource_helper.correlated_traffic)
1248
1249
1250 class TestSampleVNFDeployHelper(unittest.TestCase):
1251
1252     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1253     @mock.patch('subprocess.check_output')
1254     def test_deploy_vnfs_disabled(self, *_):
1255         vnfd_helper = mock.Mock()
1256         ssh_helper = mock.Mock()
1257         ssh_helper.join_bin_path.return_value = 'joined_path'
1258         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1259         ssh_helper.put.return_value = None
1260         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1261
1262         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1263         sample_vnf_deploy_helper.DISABLE_DEPLOY = True
1264         self.assertEqual(ssh_helper.execute.call_count, 5)
1265         ssh_helper.put.assert_called_once()
1266
1267     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
1268     @mock.patch('subprocess.check_output')
1269     def test_deploy_vnfs(self, *args):
1270         vnfd_helper = mock.Mock()
1271         ssh_helper = mock.Mock()
1272         ssh_helper.join_bin_path.return_value = 'joined_path'
1273         ssh_helper.execute.return_value = 1, 'bad output', 'error output'
1274         ssh_helper.put.return_value = None
1275         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1276         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1277
1278         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1279         self.assertEqual(ssh_helper.execute.call_count, 5)
1280         ssh_helper.put.assert_called_once()
1281
1282     @mock.patch('subprocess.check_output')
1283     def test_deploy_vnfs_early_success(self, *args):
1284         vnfd_helper = mock.Mock()
1285         ssh_helper = mock.Mock()
1286         ssh_helper.join_bin_path.return_value = 'joined_path'
1287         ssh_helper.execute.return_value = 0, 'output', ''
1288         ssh_helper.put.return_value = None
1289         sample_vnf_deploy_helper = SampleVNFDeployHelper(vnfd_helper, ssh_helper)
1290         sample_vnf_deploy_helper.DISABLE_DEPLOY = False
1291
1292         self.assertIsNone(sample_vnf_deploy_helper.deploy_vnfs('name1'))
1293         ssh_helper.execute.assert_called_once()
1294         ssh_helper.put.assert_not_called()
1295
1296
1297 class TestScenarioHelper(unittest.TestCase):
1298
1299     def test_property_task_path(self):
1300         scenario_helper = ScenarioHelper('name1')
1301         scenario_helper.scenario_cfg = {
1302             'task_path': 'my_path',
1303         }
1304
1305         self.assertEqual(scenario_helper.task_path, 'my_path')
1306
1307     def test_property_nodes(self):
1308         nodes = ['node1', 'node2']
1309         scenario_helper = ScenarioHelper('name1')
1310         scenario_helper.scenario_cfg = {
1311             'nodes': nodes,
1312         }
1313
1314         self.assertEqual(scenario_helper.nodes, nodes)
1315
1316     def test_property_all_options(self):
1317         data = {
1318             'name1': {
1319                 'key3': 'value3',
1320             },
1321             'name2': {}
1322         }
1323         scenario_helper = ScenarioHelper('name1')
1324         scenario_helper.scenario_cfg = {
1325             'options': data,
1326         }
1327
1328         self.assertDictEqual(scenario_helper.all_options, data)
1329
1330     def test_property_options(self):
1331         data = {
1332             'key1': 'value1',
1333             'key2': 'value2',
1334         }
1335         scenario_helper = ScenarioHelper('name1')
1336         scenario_helper.scenario_cfg = {
1337             'options': {
1338                 'name1': data,
1339             },
1340         }
1341
1342         self.assertDictEqual(scenario_helper.options, data)
1343
1344     def test_property_vnf_cfg(self):
1345         scenario_helper = ScenarioHelper('name1')
1346         scenario_helper.scenario_cfg = {
1347             'options': {
1348                 'name1': {
1349                     'vnf_config': 'my_config',
1350                 },
1351             },
1352         }
1353
1354         self.assertEqual(scenario_helper.vnf_cfg, 'my_config')
1355
1356     def test_property_vnf_cfg_default(self):
1357         scenario_helper = ScenarioHelper('name1')
1358         scenario_helper.scenario_cfg = {
1359             'options': {
1360                 'name1': {},
1361             },
1362         }
1363
1364         self.assertDictEqual(scenario_helper.vnf_cfg, ScenarioHelper.DEFAULT_VNF_CFG)
1365
1366     def test_property_topology(self):
1367         scenario_helper = ScenarioHelper('name1')
1368         scenario_helper.scenario_cfg = {
1369             'topology': 'my_topology',
1370         }
1371
1372         self.assertEqual(scenario_helper.topology, 'my_topology')
1373
1374
1375 class TestSampleVnf(unittest.TestCase):
1376
1377     VNFD_0 = {
1378         'short-name': 'VpeVnf',
1379         'vdu': [
1380             {
1381                 'routing_table': [
1382                     {
1383                         'network': '152.16.100.20',
1384                         'netmask': '255.255.255.0',
1385                         'gateway': '152.16.100.20',
1386                         'if': 'xe0'
1387                     },
1388                     {
1389                         'network': '152.16.40.20',
1390                         'netmask': '255.255.255.0',
1391                         'gateway': '152.16.40.20',
1392                         'if': 'xe1'
1393                     },
1394                 ],
1395                 'description': 'VPE approximation using DPDK',
1396                 'name': 'vpevnf-baremetal',
1397                 'nd_route_tbl': [
1398                     {
1399                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1400                         'netmask': '112',
1401                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1402                         'if': 'xe0'
1403                     },
1404                     {
1405                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1406                         'netmask': '112',
1407                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1408                         'if': 'xe1'
1409                     },
1410                 ],
1411                 'id': 'vpevnf-baremetal',
1412                 'external-interface': [
1413                     {
1414                         'virtual-interface': {
1415                             'dst_mac': '00:00:00:00:00:03',
1416                             'vpci': '0000:05:00.0',
1417                             'local_ip': '152.16.100.19',
1418                             'type': 'PCI-PASSTHROUGH',
1419                             'netmask': '255.255.255.0',
1420                             'dpdk_port_num': 0,
1421                             'bandwidth': '10 Gbps',
1422                             'dst_ip': '152.16.100.20',
1423                             'local_mac': '00:00:00:00:00:01'
1424                         },
1425                         'vnfd-connection-point-ref': 'xe0',
1426                         'name': 'xe0'
1427                     },
1428                     {
1429                         'virtual-interface': {
1430                             'dst_mac': '00:00:00:00:00:04',
1431                             'vpci': '0000:05:00.1',
1432                             'local_ip': '152.16.40.19',
1433                             'type': 'PCI-PASSTHROUGH',
1434                             'netmask': '255.255.255.0',
1435                             'dpdk_port_num': 1,
1436                             'bandwidth': '10 Gbps',
1437                             'dst_ip': '152.16.40.20',
1438                             'local_mac': '00:00:00:00:00:02'
1439                         },
1440                         'vnfd-connection-point-ref': 'xe1',
1441                         'name': 'xe1'
1442                     },
1443                 ],
1444             },
1445         ],
1446         'description': 'Vpe approximation using DPDK',
1447         'mgmt-interface': {
1448             'vdu-id': 'vpevnf-baremetal',
1449             'host': '1.1.1.1',
1450             'password': 'r00t',
1451             'user': 'root',
1452             'ip': '1.1.1.1'
1453         },
1454         'benchmark': {
1455             'kpi': [
1456                 'packets_in',
1457                 'packets_fwd',
1458                 'packets_dropped',
1459             ],
1460         },
1461         'connection-point': [
1462             {
1463                 'type': 'VPORT',
1464                 'name': 'xe0',
1465             },
1466             {
1467                 'type': 'VPORT',
1468                 'name': 'xe1',
1469             },
1470         ],
1471         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1472     }
1473
1474     VNFD = {
1475         'vnfd:vnfd-catalog': {
1476             'vnfd': [
1477                 VNFD_0,
1478             ]
1479         }
1480     }
1481
1482     TRAFFIC_PROFILE = {
1483         "schema": "isb:traffic_profile:0.1",
1484         "name": "fixed",
1485         "description": "Fixed traffic profile to run UDP traffic",
1486         "traffic_profile": {
1487             "traffic_type": "FixedTraffic",
1488             "frame_rate": 100,  # pps
1489             "flow_number": 10,
1490             "frame_size": 64,
1491         },
1492     }
1493
1494     def test___init__(self):
1495         sample_vnf = SampleVNF('vnf1', self.VNFD_0)
1496
1497         self.assertEqual(sample_vnf.name, 'vnf1')
1498         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1499
1500         # test the default setup helper is SetupEnvHelper, not subclass
1501         self.assertEqual(type(sample_vnf.setup_helper), SetupEnvHelper)
1502
1503         # test the default resource helper is ResourceHelper, not subclass
1504         self.assertEqual(type(sample_vnf.resource_helper), ResourceHelper)
1505
1506     def test___init___alt_types(self):
1507         class MySetupEnvHelper(SetupEnvHelper):
1508             pass
1509
1510         class MyResourceHelper(ResourceHelper):
1511             pass
1512
1513         sample_vnf = SampleVNF('vnf1', self.VNFD_0, MySetupEnvHelper, MyResourceHelper)
1514
1515         self.assertEqual(sample_vnf.name, 'vnf1')
1516         self.assertDictEqual(sample_vnf.vnfd_helper, self.VNFD_0)
1517
1518         # test the default setup helper is MySetupEnvHelper, not subclass
1519         self.assertEqual(type(sample_vnf.setup_helper), MySetupEnvHelper)
1520
1521         # test the default resource helper is MyResourceHelper, not subclass
1522         self.assertEqual(type(sample_vnf.resource_helper), MyResourceHelper)
1523
1524     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process')
1525     def test__start_vnf(self, *args):
1526         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1527         sample_vnf = SampleVNF('vnf1', vnfd)
1528         sample_vnf._run = mock.Mock()
1529
1530         self.assertIsNone(sample_vnf.queue_wrapper)
1531         self.assertIsNone(sample_vnf._vnf_process)
1532         self.assertIsNone(sample_vnf._start_vnf())
1533         self.assertIsNotNone(sample_vnf.queue_wrapper)
1534         self.assertIsNotNone(sample_vnf._vnf_process)
1535
1536     @mock.patch.object(ctx_base.Context, 'get_context_from_server', return_value='fake_context')
1537     @mock.patch("yardstick.ssh.SSH")
1538     def test_instantiate(self, ssh, *args):
1539         test_base.mock_ssh(ssh)
1540         nodes = {
1541             'vnf1': 'name1',
1542             'vnf2': 'name2',
1543         }
1544
1545         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1546         sample_vnf = SampleVNF('vnf1', vnfd)
1547         sample_vnf.scenario_helper.scenario_cfg = {
1548             'nodes': {sample_vnf.name: 'mock'}
1549         }
1550         sample_vnf.APP_NAME = 'sample1'
1551         sample_vnf._start_server = mock.Mock(return_value=0)
1552         sample_vnf._vnf_process = mock.MagicMock()
1553         sample_vnf._vnf_process._is_alive.return_value = 1
1554         sample_vnf.ssh_helper = mock.MagicMock()
1555         sample_vnf.deploy_helper = mock.MagicMock()
1556         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1557         scenario_cfg = {
1558             'nodes': nodes,
1559         }
1560
1561         self.assertIsNone(sample_vnf.instantiate(scenario_cfg, {}))
1562
1563     def test__update_collectd_options(self):
1564         scenario_cfg = {'options':
1565                             {'collectd':
1566                                  {'interval': 3,
1567                                   'plugins':
1568                                       {'plugin3': {'param': 3}}},
1569                              'vnf__0':
1570                                  {'collectd':
1571                                       {'interval': 2,
1572                                        'plugins':
1573                                            {'plugin3': {'param': 2},
1574                                             'plugin2': {'param': 2}}}}}}
1575         context_cfg = {'nodes':
1576                            {'vnf__0':
1577                                 {'collectd':
1578                                      {'interval': 1,
1579                                       'plugins':
1580                                           {'plugin3': {'param': 1},
1581                                            'plugin2': {'param': 1},
1582                                            'plugin1': {'param': 1}}}}}}
1583         expected = {'interval': 1,
1584                     'plugins':
1585                         {'plugin3': {'param': 1},
1586                          'plugin2': {'param': 1},
1587                          'plugin1': {'param': 1}}}
1588
1589         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1590         sample_vnf = SampleVNF('vnf__0', vnfd)
1591         sample_vnf._update_collectd_options(scenario_cfg, context_cfg)
1592         self.assertEqual(sample_vnf.setup_helper.collectd_options, expected)
1593
1594     def test__update_options(self):
1595         options1 = {'interval': 1,
1596                     'param1': 'value1',
1597                     'plugins':
1598                         {'plugin3': {'param': 3},
1599                          'plugin2': {'param': 1},
1600                          'plugin1': {'param': 1}}}
1601         options2 = {'interval': 2,
1602                     'param2': 'value2',
1603                     'plugins':
1604                         {'plugin4': {'param': 4},
1605                          'plugin2': {'param': 2},
1606                          'plugin1': {'param': 2}}}
1607         expected = {'interval': 1,
1608                     'param1': 'value1',
1609                     'param2': 'value2',
1610                     'plugins':
1611                         {'plugin4': {'param': 4},
1612                          'plugin3': {'param': 3},
1613                          'plugin2': {'param': 1},
1614                          'plugin1': {'param': 1}}}
1615
1616         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1617         sample_vnf = SampleVNF('vnf1', vnfd)
1618         sample_vnf._update_options(options2, options1)
1619         self.assertEqual(options2, expected)
1620
1621     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1622     @mock.patch("yardstick.ssh.SSH")
1623     def test_wait_for_instantiate_empty_queue(self, ssh, *args):
1624         test_base.mock_ssh(ssh, exec_result=(1, "", ""))
1625
1626         queue_size_list = [
1627             0,
1628             1,
1629             0,
1630             1,
1631         ]
1632
1633         queue_get_list = [
1634             'some output',
1635             'pipeline> ',
1636         ]
1637
1638         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1639         sample_vnf = SampleVNF('vnf1', vnfd)
1640         sample_vnf.APP_NAME = 'sample1'
1641         sample_vnf.WAIT_TIME_FOR_SCRIPT = 0
1642         sample_vnf._start_server = mock.Mock(return_value=0)
1643         sample_vnf._vnf_process = mock.MagicMock()
1644         sample_vnf._vnf_process.exitcode = 0
1645         sample_vnf._vnf_process._is_alive.return_value = 1
1646         sample_vnf.queue_wrapper = mock.Mock()
1647         sample_vnf.q_out = mock.Mock()
1648         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1649         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1650         sample_vnf.ssh_helper = mock.MagicMock()
1651         sample_vnf.resource_helper.ssh_helper = mock.MagicMock()
1652         sample_vnf.resource_helper.start_collect = mock.MagicMock()
1653
1654         self.assertEqual(sample_vnf.wait_for_instantiate(), 0)
1655
1656     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
1657     def test_vnf_execute_with_queue_data(self, *args):
1658         queue_size_list = [
1659             1,
1660             1,
1661             0,
1662         ]
1663
1664         queue_get_list = [
1665             'hello ',
1666             'world'
1667         ]
1668
1669         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1670         sample_vnf = SampleVNF('vnf1', vnfd)
1671         sample_vnf.APP_NAME = 'sample1'
1672         sample_vnf.q_out = mock.Mock()
1673         sample_vnf.q_out.qsize.side_effect = iter(queue_size_list)
1674         sample_vnf.q_out.get.side_effect = iter(queue_get_list)
1675
1676         self.assertEqual(sample_vnf.vnf_execute('my command'), 'hello world')
1677
1678     def test_terminate_without_vnf_process(self):
1679         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1680         sample_vnf = SampleVNF('vnf1', vnfd)
1681         sample_vnf.APP_NAME = 'sample1'
1682         sample_vnf.vnf_execute = mock.Mock()
1683         sample_vnf.ssh_helper = mock.Mock()
1684         sample_vnf._tear_down = mock.Mock()
1685         sample_vnf.resource_helper = mock.Mock()
1686
1687         self.assertIsNone(sample_vnf.terminate())
1688
1689     def test_get_stats(self):
1690         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1691         sample_vnf = SampleVNF('vnf1', vnfd)
1692         sample_vnf.APP_NAME = 'sample1'
1693         sample_vnf.APP_WORD = 'sample1'
1694         sample_vnf.vnf_execute = mock.Mock(return_value='the stats')
1695
1696         self.assertEqual(sample_vnf.get_stats(), 'the stats')
1697
1698     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
1699     def test_collect_kpi(self, *args):
1700         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1701         sample_vnf = SampleVNF('vnf1', vnfd)
1702         sample_vnf.scenario_helper.scenario_cfg = {
1703             'nodes': {sample_vnf.name: "mock"}
1704         }
1705         sample_vnf.APP_NAME = 'sample1'
1706         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1707         sample_vnf.COLLECT_MAP = {
1708             'k1': 3,
1709             'k2': 1,
1710             'k3': 2,
1711         }
1712         sample_vnf.get_stats = mock.Mock(return_value='index0: 34 -- 91, 27')
1713         sample_vnf.resource_helper = mock.Mock()
1714         sample_vnf.resource_helper.collect_kpi.return_value = {}
1715
1716         expected = {
1717             'k1': 27,
1718             'k2': 34,
1719             'k3': 91,
1720             'collect_stats': {},
1721             'physical_node': 'mock_node'
1722         }
1723         result = sample_vnf.collect_kpi()
1724         self.assertDictEqual(result, expected)
1725
1726     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
1727     def test_collect_kpi_default(self, *args):
1728         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1729         sample_vnf = SampleVNF('vnf1', vnfd)
1730         sample_vnf.scenario_helper.scenario_cfg = {
1731             'nodes': {sample_vnf.name: "mock"}
1732         }
1733         sample_vnf.APP_NAME = 'sample1'
1734         sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)'
1735         sample_vnf.get_stats = mock.Mock(return_value='')
1736
1737         expected = {
1738             'physical_node': 'mock_node',
1739             'packets_in': 0,
1740             'packets_fwd': 0,
1741             'packets_dropped': 0,
1742         }
1743         result = sample_vnf.collect_kpi()
1744         self.assertDictEqual(result, expected)
1745
1746     def test_scale(self):
1747         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1748         sample_vnf = SampleVNF('vnf1', vnfd)
1749         self.assertRaises(y_exceptions.FunctionNotImplemented,
1750                           sample_vnf.scale)
1751
1752     def test__run(self):
1753         test_cmd = 'test cmd'
1754         run_kwargs = {'arg1': 'val1', 'arg2': 'val2'}
1755         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
1756         sample_vnf = SampleVNF('vnf1', vnfd)
1757         sample_vnf.ssh_helper = mock.Mock()
1758         sample_vnf.setup_helper = mock.Mock()
1759         with mock.patch.object(sample_vnf, '_build_config',
1760                                return_value=test_cmd), \
1761                 mock.patch.object(sample_vnf, '_build_run_kwargs'):
1762             sample_vnf.run_kwargs = run_kwargs
1763             sample_vnf._run()
1764         sample_vnf.ssh_helper.drop_connection.assert_called_once()
1765         sample_vnf.ssh_helper.run.assert_called_once_with(test_cmd,
1766                                                           **run_kwargs)
1767         sample_vnf.setup_helper.kill_vnf.assert_called_once()
1768
1769
1770 class TestSampleVNFTrafficGen(unittest.TestCase):
1771
1772     VNFD_0 = {
1773         'short-name': 'VpeVnf',
1774         'vdu': [
1775             {
1776                 'routing_table': [
1777                     {
1778                         'network': '152.16.100.20',
1779                         'netmask': '255.255.255.0',
1780                         'gateway': '152.16.100.20',
1781                         'if': 'xe0'
1782                     },
1783                     {
1784                         'network': '152.16.40.20',
1785                         'netmask': '255.255.255.0',
1786                         'gateway': '152.16.40.20',
1787                         'if': 'xe1'
1788                     },
1789                 ],
1790                 'description': 'VPE approximation using DPDK',
1791                 'name': 'vpevnf-baremetal',
1792                 'nd_route_tbl': [
1793                     {
1794                         'network': '0064:ff9b:0:0:0:0:9810:6414',
1795                         'netmask': '112',
1796                         'gateway': '0064:ff9b:0:0:0:0:9810:6414',
1797                         'if': 'xe0'
1798                     },
1799                     {
1800                         'network': '0064:ff9b:0:0:0:0:9810:2814',
1801                         'netmask': '112',
1802                         'gateway': '0064:ff9b:0:0:0:0:9810:2814',
1803                         'if': 'xe1'
1804                     },
1805                 ],
1806                 'id': 'vpevnf-baremetal',
1807                 'external-interface': [
1808                     {
1809                         'virtual-interface': {
1810                             'dst_mac': '00:00:00:00:00:03',
1811                             'vpci': '0000:05:00.0',
1812                             'driver': 'i40e',
1813                             'local_ip': '152.16.100.19',
1814                             'type': 'PCI-PASSTHROUGH',
1815                             'netmask': '255.255.255.0',
1816                             'dpdk_port_num': 0,
1817                             'bandwidth': '10 Gbps',
1818                             'dst_ip': '152.16.100.20',
1819                             'local_mac': '00:00:00:00:00:01'
1820                         },
1821                         'vnfd-connection-point-ref': 'xe0',
1822                         'name': 'xe0'
1823                     },
1824                     {
1825                         'virtual-interface': {
1826                             'dst_mac': '00:00:00:00:00:04',
1827                             'vpci': '0000:05:00.1',
1828                             'driver': 'ixgbe',
1829                             'local_ip': '152.16.40.19',
1830                             'type': 'PCI-PASSTHROUGH',
1831                             'netmask': '255.255.255.0',
1832                             'dpdk_port_num': 1,
1833                             'bandwidth': '10 Gbps',
1834                             'dst_ip': '152.16.40.20',
1835                             'local_mac': '00:00:00:00:00:02'
1836                         },
1837                         'vnfd-connection-point-ref': 'xe1',
1838                         'name': 'xe1'
1839                     },
1840                 ],
1841             },
1842         ],
1843         'description': 'Vpe approximation using DPDK',
1844         'mgmt-interface': {
1845             'vdu-id': 'vpevnf-baremetal',
1846             'host': '1.1.1.1',
1847             'password': 'r00t',
1848             'user': 'root',
1849             'ip': '1.1.1.1'
1850         },
1851         'benchmark': {
1852             'kpi': [
1853                 'packets_in',
1854                 'packets_fwd',
1855                 'packets_dropped',
1856             ],
1857         },
1858         'connection-point': [
1859             {
1860                 'type': 'VPORT',
1861                 'name': 'xe0',
1862             },
1863             {
1864                 'type': 'VPORT',
1865                 'name': 'xe1',
1866             },
1867         ],
1868         'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
1869     }
1870
1871     VNFD = {
1872         'vnfd:vnfd-catalog': {
1873             'vnfd': [
1874                 VNFD_0,
1875             ],
1876         },
1877     }
1878
1879     TRAFFIC_PROFILE = {
1880         "schema": "isb:traffic_profile:0.1",
1881         "name": "fixed",
1882         "description": "Fixed traffic profile to run UDP traffic",
1883         "traffic_profile": {
1884             "traffic_type": "FixedTraffic",
1885             "frame_rate": 100,  # pps
1886             "flow_number": 10,
1887             "frame_size": 64,
1888         },
1889     }
1890
1891     def test__check_status(self):
1892         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1893
1894         with self.assertRaises(NotImplementedError):
1895             sample_vnf_tg._check_status()
1896
1897     def test_listen_traffic(self):
1898         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1899
1900         sample_vnf_tg.listen_traffic(mock.Mock())
1901
1902     def test_verify_traffic(self):
1903         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1904
1905         sample_vnf_tg.verify_traffic(mock.Mock())
1906
1907     def test_terminate(self):
1908         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1909         sample_vnf_tg._traffic_process = mock.Mock()
1910         sample_vnf_tg._tg_process = mock.Mock()
1911
1912         sample_vnf_tg.terminate()
1913
1914     def test__wait_for_process(self):
1915         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1916         with mock.patch.object(sample_vnf_tg, '_check_status',
1917                                return_value=0) as mock_status, \
1918                 mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
1919             mock_proc.is_alive.return_value = True
1920             mock_proc.exitcode = 234
1921             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
1922             mock_proc.is_alive.assert_called_once()
1923             mock_status.assert_called_once()
1924
1925     def test__wait_for_process_not_alive(self):
1926         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1927         with mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc:
1928             mock_proc.is_alive.return_value = False
1929             self.assertRaises(RuntimeError, sample_vnf_tg._wait_for_process)
1930             mock_proc.is_alive.assert_called_once()
1931
1932     def test__wait_for_process_delayed(self):
1933         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1934         with mock.patch.object(sample_vnf_tg, '_check_status',
1935                                side_effect=[1, 0]) as mock_status, \
1936                 mock.patch.object(sample_vnf_tg,
1937                                   '_tg_process') as mock_proc:
1938             mock_proc.is_alive.return_value = True
1939             mock_proc.exitcode = 234
1940             self.assertEqual(sample_vnf_tg._wait_for_process(), 234)
1941             mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()])
1942             mock_status.assert_has_calls([mock.call(), mock.call()])
1943
1944     def test_scale(self):
1945         sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0)
1946         self.assertRaises(y_exceptions.FunctionNotImplemented,
1947                           sample_vnf_tg.scale)