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 # Unittest for yardstick.network_services.vnf_generic.vnfdgen
18 from __future__ import absolute_import
20 from six.moves import range
22 from yardstick.common.yaml_loader import yaml_load
23 from yardstick.network_services.vnf_generic import vnfdgen
29 TREX_VNFD_TEMPLATE = """
32 - id: TrexTrafficGen # ISB class mapping
35 description: TRex stateless traffic generator for RFC2544
37 vdu-id: trexgen-baremetal
38 user: {{user}} # Value filled by vnfdgen
39 password: {{password}} # Value filled by vnfdgen
40 ip: {{ip}} # Value filled by vnfdgen
47 - id: trexgen-baremetal
48 name: trexgen-baremetal
49 description: TRex stateless traffic generator for RFC2544
54 vpci: '{{ interfaces.xe0.vpci}}'
55 local_ip: '{{ interfaces.xe0.local_ip }}'
56 dst_ip: '{{ interfaces.xe0.dst_ip }}'
57 local_mac: '{{ interfaces.xe0.local_mac }}'
58 dst_mac: '{{ interfaces.xe0.dst_mac }}'
60 vnfd-connection-point-ref: xe0
64 vpci: '{{ interfaces.xe1.vpci }}'
65 local_ip: '{{ interfaces.xe1.local_ip }}'
66 dst_ip: '{{ interfaces.xe1.dst_ip }}'
67 local_mac: '{{ interfaces.xe1.local_mac }}'
68 dst_mac: '{{ interfaces.xe1.dst_mac }}'
70 vnfd-connection-point-ref: xe1
71 routing_table: {{ routing_table }}
72 nd_route_tbl: {{ nd_route_tbl }}
80 - tx_throughput_pc_linerate
81 - rx_throughput_pc_linerate
87 COMPLETE_TREX_VNFD = \
96 'tx_throughput_pc_linerate',
97 'rx_throughput_pc_linerate',
101 'connection-point': [{'name': 'xe0',
105 'description': 'TRex stateless traffic generator for RFC2544',
106 'id': 'TrexTrafficGen',
107 'mgmt-interface': {'ip': '1.1.1.1',
110 'vdu-id': 'trexgen-baremetal'},
112 'short-name': 'trexgen',
113 'vdu': [{'description': 'TRex stateless traffic generator for RFC2544',
114 'external-interface':
116 'virtual-interface': {'bandwidth': '10 Gbps',
118 'dst_mac': '00:01:02:03:04:05',
119 'local_ip': '1.1.1.2',
120 'local_mac': '00:01:02:03:05:05',
121 'type': 'PCI-PASSTHROUGH',
122 'vpci': '0000:00:10.2'},
123 'vnfd-connection-point-ref': 'xe0'},
125 'virtual-interface': {'bandwidth': '10 Gbps',
127 'dst_mac': '00:01:02:03:04:06',
128 'local_ip': '2.1.1.2',
129 'local_mac': '00:01:02:03:05:06',
130 'type': 'PCI-PASSTHROUGH',
131 'vpci': '0000:00:10.1'},
132 'vnfd-connection-point-ref': 'xe1'}],
133 'id': 'trexgen-baremetal',
134 'nd_route_tbl': [{'gateway': '0064:ff9b:0:0:0:0:9810:6414',
137 'network': '0064:ff9b:0:0:0:0:9810:6414'},
138 {'gateway': '0064:ff9b:0:0:0:0:9810:2814',
141 'network': '0064:ff9b:0:0:0:0:9810:2814'}],
142 'routing_table': [{'gateway': '152.16.100.20',
144 'netmask': '255.255.255.0',
145 'network': '152.16.100.20'},
146 {'gateway': '152.16.40.20',
148 'netmask': '255.255.255.0',
149 'network': '152.16.40.20'}],
150 'name': 'trexgen-baremetal'}]}]}}
152 NODE_CFG = {'ip': '1.1.1.1',
155 'role': 'TrafficGen',
157 'interfaces': {'xe0': {'dpdk_port_num': 1,
159 'dst_mac': '00:01:02:03:04:05',
160 'local_ip': '1.1.1.2',
161 'local_mac': '00:01:02:03:05:05',
162 'vpci': '0000:00:10.2'},
163 'xe1': {'dpdk_port_num': 0,
165 'dst_mac': '00:01:02:03:04:06',
166 'local_ip': '2.1.1.2',
167 'local_mac': '00:01:02:03:05:06',
168 'vpci': '0000:00:10.1'}},
169 'nd_route_tbl': [{u'gateway': u'0064:ff9b:0:0:0:0:9810:6414',
172 u'network': u'0064:ff9b:0:0:0:0:9810:6414'},
173 {u'gateway': u'0064:ff9b:0:0:0:0:9810:2814',
176 u'network': u'0064:ff9b:0:0:0:0:9810:2814'}],
177 'routing_table': [{u'gateway': u'152.16.100.20',
179 u'netmask': u'255.255.255.0',
180 u'network': u'152.16.100.20'},
181 {u'gateway': u'152.16.40.20',
183 u'netmask': u'255.255.255.0',
184 u'network': u'152.16.40.20'}],
188 # need to template, but can't use {} so use %s
189 TRAFFIC_PROFILE_TPL = """
194 64B: "{{ get(imix, '%(0)s.imix_small', 10) }}"
195 128B: "{{ get(imix, '%(0)s.imix_128B', 10) }}"
196 256B: "{{ get(imix, '%(0)s.imix_256B', 10) }}"
197 373B: "{{ get(imix, '%(0)s.imix_373B', 10) }}"
198 570B: "{{get(imix, '%(0)s.imix_570B', 10) }}"
199 1400B: "{{get(imix, '%(0)s.imix_1400B', 10) }}"
200 1518B: "{{get(imix, '%(0)s.imix_1500B', 40) }}"
204 UPLINK: [{"ipv4": {"outer_l2":
205 {"framesize": {"64B": '10', "128B": '10',
206 "256B": '10', "373B": '10',
207 "570B": '10', "1400B": '10',
211 class TestRender(unittest.TestCase):
213 def test_render_none(self):
215 tmpl = "{{ routing_table }}"
216 self.assertEqual(vnfdgen.render(tmpl, routing_table=None), u'~')
217 self.assertEqual(yaml_load(vnfdgen.render(tmpl, routing_table=None)), None)
219 def test_render_unicode_dict(self):
221 tmpl = "{{ routing_table }}"
222 self.assertEqual(yaml_load(vnfdgen.render(tmpl, **NODE_CFG)), NODE_CFG["routing_table"])
225 class TestVnfdGen(unittest.TestCase):
226 """ Class to verify VNFS testcases """
228 def test_generate_vnfd(self):
229 """ Function to verify vnfd generation based on template """
231 generated_vnfd = vnfdgen.generate_vnfd(TREX_VNFD_TEMPLATE, NODE_CFG)
232 self.assertDictEqual(COMPLETE_TREX_VNFD, generated_vnfd)
234 def test_generate_tp_no_vars(self):
235 """ Function to verify traffic profile generation without imix """
238 generated_tp = vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL, {"imix": {}})
239 self.assertDictEqual(TRAFFIC_PROFILE, generated_tp)
241 def test_deepgetitem(self):
243 self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
245 def test_dict_flatten_int(self):
247 self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
249 def test_dict_flatten_str_int_key_first(self):
250 d = {'0': 1, 0: 24, 'b': 2}
251 self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
253 def test_dict_flatten_int_key_fallback(self):
255 self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
257 def test_dict_flatten_list(self):
258 d = {'a': 1, 'b': list(range(2))}
259 self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
261 def test_dict_flatten_dict(self):
262 d = {'a': 1, 'b': {x: x for x in list(range(2))}}
263 self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
265 def test_dict_flatten_only_str_key(self):
266 d = {'0': 1, 0: 24, 'b': 2}
267 self.assertRaises(AttributeError, vnfdgen.deepgetitem, d, 0)
270 def test_generate_tp_single_var(self):
271 """ Function to verify traffic profile generation with imix """
274 vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL,
275 {"imix": {UPLINK: {"imix_small": '20'}}})
277 tp2 = dict(TRAFFIC_PROFILE)
278 tp2[UPLINK][0]["ipv4"]["outer_l2"]["framesize"]["64B"] = '20'
279 self.assertDictEqual(tp2, generated_tp)