Merge "Add new Kubernetes resource kind: "Network""
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_acl_vnf.py
1 # Copyright (c) 2016-2017 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
16 import unittest
17 import mock
18 import os
19 import re
20 import copy
21
22 from yardstick.tests import STL_MOCKS
23 from yardstick.tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
24 from yardstick.common import utils
25 from yardstick.common import exceptions
26 from yardstick.benchmark.contexts import base as ctx_base
27
28
29 STLClient = mock.MagicMock()
30 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
31 stl_patch.start()
32
33 if stl_patch:
34     from yardstick.network_services.vnf_generic.vnf import acl_vnf
35     from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
36     from yardstick.network_services.nfvi.resource import ResourceProfile
37     from yardstick.network_services.vnf_generic.vnf.acl_vnf import AclApproxSetupEnvSetupEnvHelper
38
39
40 TEST_FILE_YAML = 'nsb_test_case.yaml'
41 SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
42
43
44 name = 'vnf__1'
45
46
47 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Process")
48 class TestAclApproxVnf(unittest.TestCase):
49     VNFD = {'vnfd:vnfd-catalog':
50             {'vnfd':
51              [{'short-name': 'VpeVnf',
52                'vdu':
53                [{'routing_table':
54                  [{'network': '152.16.100.20',
55                    'netmask': '255.255.255.0',
56                    'gateway': '152.16.100.20',
57                    'if': 'xe0'},
58                   {'network': '152.16.40.20',
59                    'netmask': '255.255.255.0',
60                    'gateway': '152.16.40.20',
61                    'if': 'xe1'}],
62                  'description': 'VPE approximation using DPDK',
63                  'name': 'vpevnf-baremetal',
64                  'nd_route_tbl':
65                  [{'network': '0064:ff9b:0:0:0:0:9810:6414',
66                    'netmask': '112',
67                    'gateway': '0064:ff9b:0:0:0:0:9810:6414',
68                    'if': 'xe0'},
69                   {'network': '0064:ff9b:0:0:0:0:9810:2814',
70                    'netmask': '112',
71                    'gateway': '0064:ff9b:0:0:0:0:9810:2814',
72                    'if': 'xe1'}],
73                  'id': 'vpevnf-baremetal',
74                  'external-interface':
75                  [{'virtual-interface':
76                    {'dst_mac': '00:00:00:00:00:04',
77                     'vpci': '0000:05:00.0',
78                     'local_ip': '152.16.100.19',
79                     'type': 'PCI-PASSTHROUGH',
80                     'netmask': '255.255.255.0',
81                     'dpdk_port_num': 0,
82                     'bandwidth': '10 Gbps',
83                     'driver': "i40e",
84                     'dst_ip': '152.16.100.20',
85                     'local_iface_name': 'xe0',
86                     'local_mac': '00:00:00:00:00:02'},
87                    'vnfd-connection-point-ref': 'xe0',
88                    'name': 'xe0'},
89                   {'virtual-interface':
90                    {'dst_mac': '00:00:00:00:00:03',
91                     'vpci': '0000:05:00.1',
92                     'local_ip': '152.16.40.19',
93                     'type': 'PCI-PASSTHROUGH',
94                     'driver': "i40e",
95                     'netmask': '255.255.255.0',
96                     'dpdk_port_num': 1,
97                     'bandwidth': '10 Gbps',
98                     'dst_ip': '152.16.40.20',
99                     'local_iface_name': 'xe1',
100                     'local_mac': '00:00:00:00:00:01'},
101                    'vnfd-connection-point-ref': 'xe1',
102                    'name': 'xe1'}]}],
103                'description': 'Vpe approximation using DPDK',
104                'mgmt-interface':
105                    {'vdu-id': 'vpevnf-baremetal',
106                     'host': '1.2.1.1',
107                     'password': 'r00t',
108                     'user': 'root',
109                     'ip': '1.2.1.1'},
110                'benchmark':
111                    {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']},
112                'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
113                                     {'type': 'VPORT', 'name': 'xe1'}],
114                'id': 'AclApproxVnf', 'name': 'VPEVnfSsh'}]}}
115
116     scenario_cfg = {'options': {'packetsize': 64, 'traffic_type': 4,
117                                 'rfc2544': {'allowed_drop_rate': '0.8 - 1'},
118                                 'vnf__1': {'rules': 'acl_1rule.yaml',
119                                            'vnf_config': {'lb_config': 'SW',
120                                                           'lb_count': 1,
121                                                           'worker_config':
122                                                           '1C/1T',
123                                                           'worker_threads': 1}}
124                                 },
125                     'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
126                     'task_path': '/tmp',
127                     'tc': 'tc_ipv4_1Mflow_64B_packetsize',
128                     'runner': {'object': 'NetworkServiceTestCase',
129                                'interval': 35,
130                                'output_filename': '/tmp/yardstick.out',
131                                'runner_id': 74476, 'duration': 400,
132                                'type': 'Duration'},
133                     'traffic_profile': 'ipv4_throughput_acl.yaml',
134                     'traffic_options': {'flow': 'ipv4_Packets_acl.yaml',
135                                         'imix': 'imix_voice.yaml'},
136                     'type': 'ISB',
137                     'nodes': {'tg__2': 'trafficgen_2.yardstick',
138                               'tg__1': 'trafficgen_1.yardstick',
139                               'vnf__1': 'vnf.yardstick'},
140                     'topology': 'vpe-tg-topology-baremetal.yaml'}
141
142     context_cfg = {'nodes': {'tg__2':
143                              {'member-vnf-index': '3',
144                               'role': 'TrafficGen',
145                               'name': 'trafficgen_2.yardstick',
146                               'vnfd-id-ref': 'tg__2',
147                               'ip': '1.2.1.1',
148                               'interfaces':
149                               {'xe0': {'local_iface_name': 'ens513f0',
150                                        'vld_id': acl_vnf.AclApproxVnf.DOWNLINK,
151                                        'netmask': '255.255.255.0',
152                                        'local_ip': '152.16.40.20',
153                                        'dst_mac': '00:00:00:00:00:01',
154                                        'local_mac': '00:00:00:00:00:03',
155                                        'dst_ip': '152.16.40.19',
156                                        'driver': 'ixgbe',
157                                        'vpci': '0000:02:00.0',
158                                        'dpdk_port_num': 0},
159                                'xe1': {'local_iface_name': 'ens513f1',
160                                        'netmask': '255.255.255.0',
161                                        'network': '202.16.100.0',
162                                        'local_ip': '202.16.100.20',
163                                        'local_mac': '00:1e:67:d0:60:5d',
164                                        'driver': 'ixgbe',
165                                        'vpci': '0000:02:00.1',
166                                        'dpdk_port_num': 1}},
167                               'password': 'r00t',
168                               'VNF model': 'l3fwd_vnf.yaml',
169                               'user': 'root'},
170                              'tg__1':
171                              {'member-vnf-index': '1',
172                               'role': 'TrafficGen',
173                               'name': 'trafficgen_1.yardstick',
174                               'vnfd-id-ref': 'tg__1',
175                               'ip': '1.2.1.1',
176                               'interfaces':
177                               {'xe0': {'local_iface_name': 'ens785f0',
178                                        'vld_id': acl_vnf.AclApproxVnf.UPLINK,
179                                        'netmask': '255.255.255.0',
180                                        'local_ip': '152.16.100.20',
181                                        'dst_mac': '00:00:00:00:00:02',
182                                        'local_mac': '00:00:00:00:00:04',
183                                        'dst_ip': '152.16.100.19',
184                                        'driver': 'i40e',
185                                        'vpci': '0000:05:00.0',
186                                        'dpdk_port_num': 0},
187                                'xe1': {'local_iface_name': 'ens785f1',
188                                        'netmask': '255.255.255.0',
189                                        'local_ip': '152.16.100.21',
190                                        'local_mac': '00:00:00:00:00:01',
191                                        'driver': 'i40e',
192                                        'vpci': '0000:05:00.1',
193                                        'dpdk_port_num': 1}},
194                               'password': 'r00t',
195                               'VNF model': 'tg_rfc2544_tpl.yaml',
196                               'user': 'root'},
197                              'vnf__1':
198                              {'name': 'vnf.yardstick',
199                               'vnfd-id-ref': 'vnf__1',
200                               'ip': '1.2.1.1',
201                               'interfaces':
202                               {'xe0': {'local_iface_name': 'ens786f0',
203                                        'vld_id': acl_vnf.AclApproxVnf.UPLINK,
204                                        'netmask': '255.255.255.0',
205                                        'local_ip': '152.16.100.19',
206                                        'dst_mac': '00:00:00:00:00:04',
207                                        'local_mac': '00:00:00:00:00:02',
208                                        'dst_ip': '152.16.100.20',
209                                        'driver': 'i40e',
210                                        'vpci': '0000:05:00.0',
211                                        'dpdk_port_num': 0},
212                                'xe1': {'local_iface_name': 'ens786f1',
213                                        'vld_id': acl_vnf.AclApproxVnf.DOWNLINK,
214                                        'netmask': '255.255.255.0',
215                                        'local_ip': '152.16.40.19',
216                                        'dst_mac': '00:00:00:00:00:03',
217                                        'local_mac': '00:00:00:00:00:01',
218                                        'dst_ip': '152.16.40.20',
219                                        'driver': 'i40e',
220                                        'vpci': '0000:05:00.1',
221                                        'dpdk_port_num': 1}},
222                               'routing_table':
223                               [{'netmask': '255.255.255.0',
224                                 'gateway': '152.16.100.20',
225                                 'network': '152.16.100.20',
226                                 'if': 'xe0'},
227                                {'netmask': '255.255.255.0',
228                                 'gateway': '152.16.40.20',
229                                 'network': '152.16.40.20',
230                                 'if': 'xe1'}],
231                               'member-vnf-index': '2',
232                               'host': '1.2.1.1',
233                               'role': 'vnf',
234                               'user': 'root',
235                               'nd_route_tbl':
236                               [{'netmask': '112',
237                                 'gateway': '0064:ff9b:0:0:0:0:9810:6414',
238                                 'network': '0064:ff9b:0:0:0:0:9810:6414',
239                                 'if': 'xe0'},
240                                {'netmask': '112',
241                                 'gateway': '0064:ff9b:0:0:0:0:9810:2814',
242                                 'network': '0064:ff9b:0:0:0:0:9810:2814',
243                                 'if': 'xe1'}],
244                               'password': 'r00t',
245                               'VNF model': 'acl_vnf.yaml'}}}
246
247     def test___init__(self, *args):
248         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
249         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
250         self.assertIsNone(acl_approx_vnf._vnf_process)
251
252     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
253     @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node')
254     @mock.patch(SSH_HELPER)
255     def test_collect_kpi(self, ssh, *args):
256         mock_ssh(ssh)
257
258         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
259         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
260         acl_approx_vnf.scenario_helper.scenario_cfg = {
261             'nodes': {acl_approx_vnf.name: "mock"}
262         }
263         acl_approx_vnf.q_in = mock.MagicMock()
264         acl_approx_vnf.q_out = mock.MagicMock()
265         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
266         acl_approx_vnf.resource = mock.Mock(autospec=ResourceProfile)
267         acl_approx_vnf.vnf_execute = mock.Mock(return_value="")
268         result = {
269             'physical_node': 'mock_node',
270             'packets_dropped': 0,
271             'packets_fwd': 0,
272             'packets_in': 0
273         }
274         self.assertEqual(result, acl_approx_vnf.collect_kpi())
275
276     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
277     @mock.patch(SSH_HELPER)
278     def test_vnf_execute_command(self, ssh, *args):
279         mock_ssh(ssh)
280
281         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
282         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
283         acl_approx_vnf.q_in = mock.MagicMock()
284         acl_approx_vnf.q_out = mock.MagicMock()
285         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
286         cmd = "quit"
287         self.assertEqual("", acl_approx_vnf.vnf_execute(cmd))
288
289     @mock.patch(SSH_HELPER)
290     def test_get_stats(self, ssh, *args):
291         mock_ssh(ssh)
292
293         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
294         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
295         acl_approx_vnf.q_in = mock.MagicMock()
296         acl_approx_vnf.q_out = mock.MagicMock()
297         acl_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
298         result = "ACL TOTAL: pkts_processed: 100, pkts_drop: 0, spkts_received: 100"
299         acl_approx_vnf.vnf_execute = mock.Mock(return_value=result)
300         self.assertEqual(result, acl_approx_vnf.get_stats())
301
302     def _get_file_abspath(self, filename):
303         curr_path = os.path.dirname(os.path.abspath(__file__))
304         file_path = os.path.join(curr_path, filename)
305         return file_path
306
307     @mock.patch("yardstick.network_services.vnf_generic.vnf.acl_vnf.hex")
308     @mock.patch("yardstick.network_services.vnf_generic.vnf.acl_vnf.eval")
309     @mock.patch('yardstick.network_services.vnf_generic.vnf.acl_vnf.open')
310     @mock.patch(SSH_HELPER)
311     def test_run_acl(self, ssh, *args):
312         mock_ssh(ssh)
313
314         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
315         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
316         acl_approx_vnf._build_config = mock.MagicMock()
317         acl_approx_vnf.queue_wrapper = mock.MagicMock()
318         acl_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg
319         acl_approx_vnf.vnf_cfg = {'lb_config': 'SW',
320                                   'lb_count': 1,
321                                   'worker_config': '1C/1T',
322                                   'worker_threads': 1}
323         acl_approx_vnf.all_options = {'traffic_type': '4',
324                                       'topology': 'nsb_test_case.yaml'}
325         acl_approx_vnf._run()
326         acl_approx_vnf.ssh_helper.run.assert_called_once()
327
328     @mock.patch.object(utils, 'find_relative_file')
329     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
330     @mock.patch(SSH_HELPER)
331     def test_instantiate(self, ssh, *args):
332         mock_ssh(ssh)
333
334         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
335         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
336         acl_approx_vnf.deploy_helper = mock.MagicMock()
337         acl_approx_vnf.resource_helper = mock.MagicMock()
338         acl_approx_vnf._build_config = mock.MagicMock()
339         self.scenario_cfg['vnf_options'] = {'acl': {'cfg': "",
340                                                     'rules': ""}}
341         acl_approx_vnf.q_out.put("pipeline>")
342         acl_approx_vnf.WAIT_TIME = 0
343         self.scenario_cfg.update({"nodes": {"vnf__1": ""}})
344         self.assertIsNone(acl_approx_vnf.instantiate(self.scenario_cfg,
345                                                      self.context_cfg))
346
347     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
348     @mock.patch(SSH_HELPER)
349     def test_terminate(self, ssh, *args):
350         mock_ssh(ssh)
351
352         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
353         acl_approx_vnf = acl_vnf.AclApproxVnf(name, vnfd)
354         acl_approx_vnf._vnf_process = mock.MagicMock()
355         acl_approx_vnf._vnf_process.terminate = mock.Mock()
356         acl_approx_vnf.used_drivers = {"01:01.0": "i40e",
357                                        "01:01.1": "i40e"}
358         acl_approx_vnf.vnf_execute = mock.MagicMock()
359         acl_approx_vnf.dpdk_devbind = "dpdk-devbind.py"
360         acl_approx_vnf._resource_collect_stop = mock.Mock()
361         self.assertIsNone(acl_approx_vnf.terminate())
362
363
364 class TestAclApproxSetupEnvSetupEnvHelper(unittest.TestCase):
365
366     ACL_CONFIG = {"access-list-entries": [{
367                      "actions": [
368                        "count",
369                        {"fwd": {
370                            "port": 0
371                          }
372                        }
373                      ],
374                      "matches": {
375                        "destination-ipv4-network": "152.16.0.0/24",
376                        "destination-port-range": {
377                          "lower-port": 0,
378                          "upper-port": 65535
379                        },
380                        "source-ipv4-network": "0.0.0.0/0",
381                        "source-port-range": {
382                          "lower-port": 0,
383                          "upper-port": 65535
384                        },
385                        "protocol-mask": 255,
386                        "protocol": 127,
387                        "priority": 1
388                      },
389                      "rule-name": "rule1588"
390                    }
391                  ]}
392
393     def test_get_default_flows(self):
394         """Check if default ACL SampleVNF CLI commands are
395         generated correctly"""
396         ssh_helper = mock.Mock()
397         vnfd_helper = VnfdHelper({'vdu': [
398             {'external-interface': [
399                 {
400                     'virtual-interface': {
401                         'local_ip': '152.16.100.19',
402                         'netmask': '255.255.255.0',
403                         'dpdk_port_num': 0,
404                         'dst_ip': '152.16.100.20',
405                         'vld_id': 'uplink_0',
406                         'ifname': 'xe0',
407                     },
408                     'vnfd-connection-point-ref': 'xe0',
409                     'name': 'xe0'
410                 },
411                 {
412                     'virtual-interface': {
413                         'local_ip': '152.16.40.19',
414                         'netmask': '255.255.255.0',
415                         'dpdk_port_num': 1,
416                         'dst_ip': '152.16.40.20',
417                         'vld_id': 'downlink_0',
418                         'ifname': 'xe1',
419                     },
420                     'vnfd-connection-point-ref': 'xe1',
421                     'name': 'xe1'
422                 }
423             ]}
424         ]})
425         setup_helper = AclApproxSetupEnvSetupEnvHelper(vnfd_helper, ssh_helper, None)
426         self.check_acl_commands(setup_helper.get_flows_config(), [
427             # format: (<cli pattern>, <number of expected matches>)
428             ("^p action add [0-9]+ accept$", 2),
429             ("^p action add [0-9]+ count$", 2),
430             ("^p action add [0-9]+ fwd 1$", 1),
431             ("^p action add [0-9]+ fwd 0$", 1),
432             ("^p acl add 1 152.16.100.0 24 152.16.40.0 24 0 65535 0 65535 0 0 [0-9]+$", 1),
433             ("^p acl add 1 152.16.40.0 24 152.16.100.0 24 0 65535 0 65535 0 0 [0-9]+$", 1),
434             ("^p acl applyruleset$", 1)
435         ])
436
437     @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
438     def test_get_flows_config(self, get_default_flows):
439         """Check if provided ACL config can be converted to
440         ACL SampleVNF CLI commands correctly"""
441         ssh_helper = mock.Mock()
442         setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
443         get_default_flows.return_value = ({}, [])
444         self.check_acl_commands(setup_helper.get_flows_config(self.ACL_CONFIG), [
445             # format: (<cli pattern>, <number of expected matches>)
446             ("^p action add [0-9]+ count$", 1),
447             ("^p action add [0-9]+ fwd 0$", 1),
448             ("^p acl add 1 0.0.0.0 0 152.16.0.0 24 0 65535 0 65535 127 0 [0-9]+$", 1),
449             ("^p acl applyruleset$", 1)
450         ])
451
452     @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
453     def test_get_flows_config_invalid_action(self, get_default_flows):
454         """Check if incorrect ACL config fails to convert
455         to ACL SampleVNF CLI commands"""
456         ssh_helper = mock.Mock()
457         setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
458         get_default_flows.return_value = ({}, [])
459         # duplicate config and add invald action
460         acl_config = copy.deepcopy(self.ACL_CONFIG)
461         acl_config['access-list-entries'][0]["actions"].append({"xnat": {}})
462         self.assertRaises(exceptions.AclUknownActionTemplate,
463             setup_helper.get_flows_config, acl_config)
464
465     @mock.patch.object(AclApproxSetupEnvSetupEnvHelper, 'get_default_flows')
466     def test_get_flows_config_invalid_action_param(self, get_default_flows):
467         """Check if ACL config with invalid action parameter fails to convert
468         to ACL SampleVNF CLI commands"""
469         ssh_helper = mock.Mock()
470         setup_helper = AclApproxSetupEnvSetupEnvHelper(None, ssh_helper, None)
471         get_default_flows.return_value = ({}, [])
472         # duplicate config and add action with invalid parameter
473         acl_config = copy.deepcopy(self.ACL_CONFIG)
474         acl_config['access-list-entries'][0]["actions"].append(
475             {"nat": {"xport": 0}})
476         self.assertRaises(exceptions.AclMissingActionArguments,
477             setup_helper.get_flows_config, acl_config)
478
479     def check_acl_commands(self, config, expected_cli_patterns):
480         """Check if expected ACL CLI commands (given as a list of patterns,
481         `expected_cli_patterns` parameter) present in SampleVNF ACL
482         configuration (given as a multiline string, `config` parameter)"""
483         # Example of expected config:
484         # ---------------------------
485         # p action add 1 accept
486         # p action add 1 fwd 1
487         # p action add 2 accept
488         # p action add 2 count
489         # p action add 2 fwd 0
490         # p acl add 1 152.16.100.0 24 152.16.40.0 24 0 65535 0 65535 0 0 1
491         # p acl add 1 152.16.40.0 24 152.16.100.0 24 0 65535 0 65535 0 0 2
492         # p acl applyruleset
493         # ---------------------------
494         # NOTE: The config above consists of actions ids, which are actually
495         # unknown (generated at runtime), thus it's incorrect just to compare
496         # the example ACL config above with the configuration returned by
497         # get_flows_config() function. It's more correct to use CLI patterns
498         # (RE) to find the required SampleVNF CLI commands in the multiline
499         # string (SampleVNF ACL configuration).
500         for pattern, num_of_match in expected_cli_patterns:
501             # format: (<cli pattern>, <number of expected matches>)
502             result = re.findall(pattern, config, re.MULTILINE)
503             self.assertEqual(len(result), num_of_match)
504
505     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open')
506     @mock.patch.object(utils, 'find_relative_file')
507     @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig')
508     @mock.patch.object(utils, 'open_relative_file')
509     def test_build_config(self, *args):
510         vnfd_helper = mock.Mock()
511         ssh_helper = mock.Mock()
512         scenario_helper = mock.Mock()
513         scenario_helper.vnf_cfg = {'lb_config': 'HW'}
514         scenario_helper.options = {}
515         scenario_helper.all_options = {}
516
517         acl_approx_setup_helper = AclApproxSetupEnvSetupEnvHelper(vnfd_helper,
518                                                                   ssh_helper,
519                                                                   scenario_helper)
520
521         acl_approx_setup_helper.get_flows_config = mock.Mock()
522         acl_approx_setup_helper.ssh_helper.provision_tool = mock.Mock(return_value='tool_path')
523         acl_approx_setup_helper.ssh_helper.all_ports = mock.Mock()
524         acl_approx_setup_helper.vnfd_helper.port_nums = mock.Mock(return_value=[0, 1])
525         expected = 'sudo tool_path -p 0x3 -f /tmp/acl_config -s /tmp/acl_script  --hwlb 3'
526         self.assertEqual(acl_approx_setup_helper.build_config(), expected)
527         acl_approx_setup_helper.get_flows_config.assert_called_once()