3 # Copyright (c) 2016-2017 Intel Corporation
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 # Unittest for yardstick.network_services.vnf_generic.vnfdgen
20 from __future__ import absolute_import
22 from six.moves import range
24 from yardstick.common.yaml_loader import yaml_load
25 from yardstick.network_services.vnf_generic import vnfdgen
31 TREX_VNFD_TEMPLATE = """
34 - id: TrexTrafficGen # ISB class mapping
37 description: TRex stateless traffic generator for RFC2544
39 vdu-id: trexgen-baremetal
40 user: {{user}} # Value filled by vnfdgen
41 password: {{password}} # Value filled by vnfdgen
42 ip: {{ip}} # Value filled by vnfdgen
49 - id: trexgen-baremetal
50 name: trexgen-baremetal
51 description: TRex stateless traffic generator for RFC2544
56 vpci: '{{ interfaces.xe0.vpci}}'
57 local_ip: '{{ interfaces.xe0.local_ip }}'
58 dst_ip: '{{ interfaces.xe0.dst_ip }}'
59 local_mac: '{{ interfaces.xe0.local_mac }}'
60 dst_mac: '{{ interfaces.xe0.dst_mac }}'
62 vnfd-connection-point-ref: xe0
66 vpci: '{{ interfaces.xe1.vpci }}'
67 local_ip: '{{ interfaces.xe1.local_ip }}'
68 dst_ip: '{{ interfaces.xe1.dst_ip }}'
69 local_mac: '{{ interfaces.xe1.local_mac }}'
70 dst_mac: '{{ interfaces.xe1.dst_mac }}'
72 vnfd-connection-point-ref: xe1
73 routing_table: {{ routing_table }}
74 nd_route_tbl: {{ nd_route_tbl }}
82 - tx_throughput_pc_linerate
83 - rx_throughput_pc_linerate
89 COMPLETE_TREX_VNFD = \
98 'tx_throughput_pc_linerate',
99 'rx_throughput_pc_linerate',
103 'connection-point': [{'name': 'xe0',
107 'description': 'TRex stateless traffic generator for RFC2544',
108 'id': 'TrexTrafficGen',
109 'mgmt-interface': {'ip': '1.1.1.1',
112 'vdu-id': 'trexgen-baremetal'},
114 'short-name': 'trexgen',
115 'vdu': [{'description': 'TRex stateless traffic generator for RFC2544',
116 'external-interface':
118 'virtual-interface': {'bandwidth': '10 Gbps',
120 'dst_mac': '00:01:02:03:04:05',
121 'local_ip': '1.1.1.2',
122 'local_mac': '00:01:02:03:05:05',
123 'type': 'PCI-PASSTHROUGH',
124 'vpci': '0000:00:10.2'},
125 'vnfd-connection-point-ref': 'xe0'},
127 'virtual-interface': {'bandwidth': '10 Gbps',
129 'dst_mac': '00:01:02:03:04:06',
130 'local_ip': '2.1.1.2',
131 'local_mac': '00:01:02:03:05:06',
132 'type': 'PCI-PASSTHROUGH',
133 'vpci': '0000:00:10.1'},
134 'vnfd-connection-point-ref': 'xe1'}],
135 'id': 'trexgen-baremetal',
136 'nd_route_tbl': [{'gateway': '0064:ff9b:0:0:0:0:9810:6414',
139 'network': '0064:ff9b:0:0:0:0:9810:6414'},
140 {'gateway': '0064:ff9b:0:0:0:0:9810:2814',
143 'network': '0064:ff9b:0:0:0:0:9810:2814'}],
144 'routing_table': [{'gateway': '152.16.100.20',
146 'netmask': '255.255.255.0',
147 'network': '152.16.100.20'},
148 {'gateway': '152.16.40.20',
150 'netmask': '255.255.255.0',
151 'network': '152.16.40.20'}],
152 'name': 'trexgen-baremetal'}]}]}}
154 NODE_CFG = {'ip': '1.1.1.1',
157 'role': 'TrafficGen',
159 'interfaces': {'xe0': {'dpdk_port_num': 1,
161 'dst_mac': '00:01:02:03:04:05',
162 'local_ip': '1.1.1.2',
163 'local_mac': '00:01:02:03:05:05',
164 'vpci': '0000:00:10.2'},
165 'xe1': {'dpdk_port_num': 0,
167 'dst_mac': '00:01:02:03:04:06',
168 'local_ip': '2.1.1.2',
169 'local_mac': '00:01:02:03:05:06',
170 'vpci': '0000:00:10.1'}},
171 'nd_route_tbl': [{u'gateway': u'0064:ff9b:0:0:0:0:9810:6414',
174 u'network': u'0064:ff9b:0:0:0:0:9810:6414'},
175 {u'gateway': u'0064:ff9b:0:0:0:0:9810:2814',
178 u'network': u'0064:ff9b:0:0:0:0:9810:2814'}],
179 'routing_table': [{u'gateway': u'152.16.100.20',
181 u'netmask': u'255.255.255.0',
182 u'network': u'152.16.100.20'},
183 {u'gateway': u'152.16.40.20',
185 u'netmask': u'255.255.255.0',
186 u'network': u'152.16.40.20'}],
190 # need to template, but can't use {} so use %s
191 TRAFFIC_PROFILE_TPL = """
196 64B: "{{ get(imix, '%(0)s.imix_small', 10) }}"
197 128B: "{{ get(imix, '%(0)s.imix_128B', 10) }}"
198 256B: "{{ get(imix, '%(0)s.imix_256B', 10) }}"
199 373B: "{{ get(imix, '%(0)s.imix_373B', 10) }}"
200 570B: "{{get(imix, '%(0)s.imix_570B', 10) }}"
201 1400B: "{{get(imix, '%(0)s.imix_1400B', 10) }}"
202 1518B: "{{get(imix, '%(0)s.imix_1500B', 40) }}"
206 UPLINK: [{"ipv4": {"outer_l2":
207 {"framesize": {"64B": '10', "128B": '10',
208 "256B": '10', "373B": '10',
209 "570B": '10', "1400B": '10',
213 class TestRender(unittest.TestCase):
215 def test_render_none(self):
217 tmpl = "{{ routing_table }}"
218 self.assertEqual(vnfdgen.render(tmpl, routing_table=None), u'~')
219 self.assertEqual(yaml_load(vnfdgen.render(tmpl, routing_table=None)), None)
221 def test_render_unicode_dict(self):
223 tmpl = "{{ routing_table }}"
224 self.assertEqual(yaml_load(vnfdgen.render(tmpl, **NODE_CFG)), NODE_CFG["routing_table"])
227 class TestVnfdGen(unittest.TestCase):
228 """ Class to verify VNFS testcases """
230 def test_generate_vnfd(self):
231 """ Function to verify vnfd generation based on template """
233 generated_vnfd = vnfdgen.generate_vnfd(TREX_VNFD_TEMPLATE, NODE_CFG)
234 self.assertDictEqual(COMPLETE_TREX_VNFD, generated_vnfd)
236 def test_generate_tp_no_vars(self):
237 """ Function to verify traffic profile generation without imix """
240 generated_tp = vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL, {"imix": {}})
241 self.assertDictEqual(TRAFFIC_PROFILE, generated_tp)
243 def test_deepgetitem(self):
245 self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
247 def test_dict_flatten_int(self):
249 self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
251 def test_dict_flatten_str_int_key_first(self):
252 d = {'0': 1, 0: 24, 'b': 2}
253 self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
255 def test_dict_flatten_int_key_fallback(self):
257 self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
259 def test_dict_flatten_list(self):
260 d = {'a': 1, 'b': list(range(2))}
261 self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
263 def test_dict_flatten_dict(self):
264 d = {'a': 1, 'b': {x: x for x in list(range(2))}}
265 self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
267 def test_dict_flatten_only_str_key(self):
268 d = {'0': 1, 0: 24, 'b': 2}
269 self.assertRaises(AttributeError, vnfdgen.deepgetitem, d, 0)
272 def test_generate_tp_single_var(self):
273 """ Function to verify traffic profile generation with imix """
276 vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL,
277 {"imix": {UPLINK: {"imix_small": '20'}}})
279 tp2 = dict(TRAFFIC_PROFILE)
280 tp2[UPLINK][0]["ipv4"]["outer_l2"]["framesize"]["64B"] = '20'
281 self.assertDictEqual(tp2, generated_tp)