1 # Copyright (c) 2016-2017 Intel Corporation
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 from copy import deepcopy
21 from tests.unit import STL_MOCKS
22 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
25 STLClient = mock.MagicMock()
26 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
30 from yardstick.network_services.vnf_generic.vnf.cgnapt_vnf import CgnaptApproxVnf, \
31 CgnaptApproxSetupEnvHelper
32 from yardstick.network_services.vnf_generic.vnf import cgnapt_vnf
33 from yardstick.network_services.nfvi.resource import ResourceProfile
35 TEST_FILE_YAML = 'nsb_test_case.yaml'
36 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
42 class TestCgnaptApproxSetupEnvHelper(unittest.TestCase):
44 def test__generate_ip_from_pool(self):
46 ip = CgnaptApproxSetupEnvHelper._generate_ip_from_pool("1.2.3.4")
47 self.assertEqual(next(ip), '1.2.3.4')
48 self.assertEqual(next(ip), '1.2.4.4')
49 self.assertEqual(next(ip), '1.2.5.4')
51 def test__update_cgnat_script_file(self):
54 # See the License for the specific language governing permissions and
55 # limitations under the License.
58 link 0 config {port0_local_ip} {port0_prefixlen}
61 link 1 config {port1_local_ip} {port1_prefixlen}
64 header = "This is a header"
66 out = CgnaptApproxSetupEnvHelper._update_cgnat_script_file(header, sample.splitlines())
67 self.assertNotIn("This is a header", out)
69 def test__get_cgnapt_config(self):
70 vnfd_helper = mock.MagicMock()
71 vnfd_helper.port_pairs.uplink_ports = [{"name": 'a'}, {"name": "b"}, {"name": "c"}]
73 helper = CgnaptApproxSetupEnvHelper(vnfd_helper, mock.Mock(), mock.Mock())
74 result = helper._get_cgnapt_config()
75 self.assertIsNotNone(result)
78 helper = CgnaptApproxSetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock())
79 with self.assertRaises(NotImplementedError):
83 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Process")
84 class TestCgnaptApproxVnf(unittest.TestCase):
85 VNFD = {'vnfd:vnfd-catalog':
87 [{'short-name': 'VpeVnf',
90 [{'network': '152.16.100.20',
91 'netmask': '255.255.255.0',
92 'gateway': '152.16.100.20',
94 {'network': '152.16.40.20',
95 'netmask': '255.255.255.0',
96 'gateway': '152.16.40.20',
98 'description': 'VPE approximation using DPDK',
99 'name': 'vpevnf-baremetal',
101 [{'network': '0064:ff9b:0:0:0:0:9810:6414',
103 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
105 {'network': '0064:ff9b:0:0:0:0:9810:2814',
107 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
109 'id': 'vpevnf-baremetal',
110 'external-interface':
111 [{'virtual-interface':
112 {'dst_mac': '00:00:00:00:00:04',
113 'vpci': '0000:05:00.0',
114 'local_ip': '152.16.100.19',
115 'type': 'PCI-PASSTHROUGH',
116 'netmask': '255.255.255.0',
118 'bandwidth': '10 Gbps',
120 'dst_ip': '152.16.100.20',
121 'local_iface_name': 'xe0',
122 'local_mac': '00:00:00:00:00:02'},
123 'vnfd-connection-point-ref': 'xe0',
125 {'virtual-interface':
126 {'dst_mac': '00:00:00:00:00:03',
127 'vpci': '0000:05:00.1',
128 'local_ip': '152.16.40.19',
129 'type': 'PCI-PASSTHROUGH',
131 'netmask': '255.255.255.0',
133 'bandwidth': '10 Gbps',
134 'dst_ip': '152.16.40.20',
135 'local_iface_name': 'xe1',
136 'local_mac': '00:00:00:00:00:01'},
137 'vnfd-connection-point-ref': 'xe1',
139 'description': 'Vpe approximation using DPDK',
141 {'vdu-id': 'vpevnf-baremetal',
147 {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']},
148 'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
149 {'type': 'VPORT', 'name': 'xe1'}],
150 'id': 'CgnaptApproxVnf', 'name': 'VPEVnfSsh'}]}}
157 'allowed_drop_rate': '0.8 - 1',
170 'dst_ip': [{'tg__1': 'xe0'}],
172 'src_ip': [{'tg__0': 'xe0'}]},
174 'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
176 'tc': 'tc_ipv4_1Mflow_64B_packetsize',
178 'object': 'NetworkServiceTestCase',
180 'output_filename': '/tmp/yardstick.out',
185 'traffic_profile': 'ipv4_throughput_acl.yaml',
188 'tg__1': 'trafficgen_1.yardstick',
189 'tg__0': 'trafficgen_0.yardstick',
190 'vnf__0': 'vnf.yardstick',
192 'topology': 'vpe-tg-topology-baremetal.yaml',
195 context_cfg = {'nodes': {'tg__2':
196 {'member-vnf-index': '3',
197 'role': 'TrafficGen',
198 'name': 'trafficgen_2.yardstick',
199 'vnfd-id-ref': 'tg__2',
202 {'xe0': {'local_iface_name': 'ens513f0',
203 'vld_id': CgnaptApproxVnf.DOWNLINK,
204 'netmask': '255.255.255.0',
205 'local_ip': '152.16.40.20',
206 'dst_mac': '00:00:00:00:00:01',
207 'local_mac': '00:00:00:00:00:03',
208 'dst_ip': '152.16.40.19',
210 'vpci': '0000:02:00.0',
212 'xe1': {'local_iface_name': 'ens513f1',
213 'netmask': '255.255.255.0',
214 'network': '202.16.100.0',
215 'local_ip': '202.16.100.20',
216 'local_mac': '00:1e:67:d0:60:5d',
218 'vpci': '0000:02:00.1',
219 'dpdk_port_num': 1}},
221 'VNF model': 'l3fwd_vnf.yaml',
224 {'member-vnf-index': '1',
225 'role': 'TrafficGen',
226 'name': 'trafficgen_1.yardstick',
227 'vnfd-id-ref': 'tg__1',
230 {'xe0': {'local_iface_name': 'ens785f0',
231 'vld_id': CgnaptApproxVnf.UPLINK,
232 'netmask': '255.255.255.0',
233 'local_ip': '152.16.100.20',
234 'dst_mac': '00:00:00:00:00:02',
235 'local_mac': '00:00:00:00:00:04',
236 'dst_ip': '152.16.100.19',
238 'vpci': '0000:05:00.0',
240 'xe1': {'local_iface_name': 'ens785f1',
241 'netmask': '255.255.255.0',
242 'local_ip': '152.16.100.21',
243 'local_mac': '00:00:00:00:00:01',
245 'vpci': '0000:05:00.1',
246 'dpdk_port_num': 1}},
248 'VNF model': 'tg_rfc2544_tpl.yaml',
251 {'name': 'vnf.yardstick',
252 'vnfd-id-ref': 'vnf__0',
255 {'xe0': {'local_iface_name': 'ens786f0',
256 'vld_id': CgnaptApproxVnf.UPLINK,
257 'netmask': '255.255.255.0',
258 'local_ip': '152.16.100.19',
259 'dst_mac': '00:00:00:00:00:04',
260 'local_mac': '00:00:00:00:00:02',
261 'dst_ip': '152.16.100.20',
263 'vpci': '0000:05:00.0',
265 'xe1': {'local_iface_name': 'ens786f1',
266 'vld_id': CgnaptApproxVnf.DOWNLINK,
267 'netmask': '255.255.255.0',
268 'local_ip': '152.16.40.19',
269 'dst_mac': '00:00:00:00:00:03',
270 'local_mac': '00:00:00:00:00:01',
271 'dst_ip': '152.16.40.20',
273 'vpci': '0000:05:00.1',
274 'dpdk_port_num': 1}},
276 [{'netmask': '255.255.255.0',
277 'gateway': '152.16.100.20',
278 'network': '152.16.100.20',
280 {'netmask': '255.255.255.0',
281 'gateway': '152.16.40.20',
282 'network': '152.16.40.20',
284 'member-vnf-index': '2',
290 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
291 'network': '0064:ff9b:0:0:0:0:9810:6414',
294 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
295 'network': '0064:ff9b:0:0:0:0:9810:2814',
298 'VNF model': 'cgnapt_vnf.yaml'}}}
301 self.scenario_cfg = deepcopy(self.SCENARIO_CFG)
303 def test___init__(self, *args):
304 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
305 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
306 self.assertIsNone(cgnapt_approx_vnf._vnf_process)
308 @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
309 @mock.patch(SSH_HELPER)
310 def test_collect_kpi(self, ssh, *args):
313 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
314 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
315 cgnapt_approx_vnf._vnf_process = mock.MagicMock(
316 **{"is_alive.return_value": True, "exitcode": None})
317 cgnapt_approx_vnf.q_in = mock.MagicMock()
318 cgnapt_approx_vnf.q_out = mock.MagicMock()
319 cgnapt_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
320 cgnapt_approx_vnf.resource = mock.Mock(autospec=ResourceProfile)
321 result = {'packets_dropped': 0, 'packets_fwd': 0, 'packets_in': 0}
322 self.assertEqual(result, cgnapt_approx_vnf.collect_kpi())
324 @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time')
325 @mock.patch(SSH_HELPER)
326 def test_vnf_execute_command(self, ssh, *args):
329 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
330 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
331 cgnapt_approx_vnf.q_in = mock.MagicMock()
332 cgnapt_approx_vnf.q_out = mock.MagicMock()
333 cgnapt_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
335 self.assertEqual("", cgnapt_approx_vnf.vnf_execute(cmd))
337 @mock.patch(SSH_HELPER)
338 def test_get_stats(self, ssh, *args):
341 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
342 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
343 cgnapt_approx_vnf.q_in = mock.MagicMock()
344 cgnapt_approx_vnf.q_out = mock.MagicMock()
345 cgnapt_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
347 "CG-NAPT(.*\n)*Received 100, Missed 0, Dropped 0,Translated 100,ingress"
348 cgnapt_approx_vnf.vnf_execute = mock.Mock(return_value=result)
349 self.assertListEqual(list(result), list(cgnapt_approx_vnf.get_stats()))
351 def _get_file_abspath(self, filename):
352 curr_path = os.path.dirname(os.path.abspath(__file__))
353 file_path = os.path.join(curr_path, filename)
356 @mock.patch("yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.hex")
357 @mock.patch("yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.eval")
358 @mock.patch('yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.open')
359 @mock.patch(SSH_HELPER)
360 def test_run_vcgnapt(self, ssh, *args):
363 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
364 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
365 cgnapt_approx_vnf._build_config = mock.MagicMock()
366 cgnapt_approx_vnf.queue_wrapper = mock.MagicMock()
367 cgnapt_approx_vnf.ssh_helper = mock.MagicMock()
368 cgnapt_approx_vnf.ssh_helper.run = mock.MagicMock()
369 cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
370 cgnapt_approx_vnf._run()
371 cgnapt_approx_vnf.ssh_helper.run.assert_called_once()
373 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
374 @mock.patch(SSH_HELPER)
375 def test_instantiate(self, ssh, *args):
378 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
379 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
380 cgnapt_approx_vnf.deploy_helper = mock.MagicMock()
381 cgnapt_approx_vnf.resource_helper = mock.MagicMock()
382 cgnapt_approx_vnf._build_config = mock.MagicMock()
383 self.scenario_cfg['vnf_options'] = {'acl': {'cfg': "",
385 cgnapt_approx_vnf.q_out.put("pipeline>")
386 cgnapt_vnf.WAIT_TIME = 3
387 self.scenario_cfg.update({"nodes": {"vnf__0": ""}})
388 self.assertIsNone(cgnapt_approx_vnf.instantiate(self.scenario_cfg,
391 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
392 @mock.patch(SSH_HELPER)
393 def test__vnf_up_post(self, ssh, *args):
396 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
397 self.scenario_cfg['options'][name]['napt'] = 'static'
399 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
400 cgnapt_approx_vnf._vnf_process = mock.MagicMock()
401 cgnapt_approx_vnf._vnf_process.terminate = mock.Mock()
402 cgnapt_approx_vnf.vnf_execute = mock.MagicMock()
403 cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
404 cgnapt_approx_vnf._resource_collect_stop = mock.Mock()
405 cgnapt_approx_vnf._vnf_up_post()
407 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
408 @mock.patch(SSH_HELPER)
409 def test__vnf_up_post_short(self, ssh, *args):
412 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
413 cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd)
414 cgnapt_approx_vnf._vnf_process = mock.MagicMock()
415 cgnapt_approx_vnf._vnf_process.terminate = mock.Mock()
416 cgnapt_approx_vnf.vnf_execute = mock.MagicMock()
417 cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
418 cgnapt_approx_vnf._resource_collect_stop = mock.Mock()
419 cgnapt_approx_vnf._vnf_up_post()