ee881c963ab14ab4f78c144af8fd9bdf37cc1e4b
[yardstick.git] / tests / unit / network_services / vnf_generic / test_vnfdgen.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016-2017 Intel Corporation
4 #
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
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16 #
17
18 # Unittest for yardstick.network_services.vnf_generic.vnfdgen
19
20 from __future__ import absolute_import
21 import unittest
22 from six.moves import range
23
24 from yardstick.common.yaml_loader import yaml_load
25 from yardstick.network_services.vnf_generic import vnfdgen
26
27
28 UPLINK = "uplink"
29 DOWNLINK = "downlink"
30
31 TREX_VNFD_TEMPLATE = """
32 vnfd:vnfd-catalog:
33     vnfd:
34     -   id: TrexTrafficGen  # ISB class mapping
35         name: trexgen
36         short-name: trexgen
37         description: TRex stateless traffic generator for RFC2544
38         mgmt-interface:
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
43         connection-point:
44         -   name: xe0
45             type: VPORT
46         -   name: xe1
47             type: VPORT
48         vdu:
49         -   id: trexgen-baremetal
50             name: trexgen-baremetal
51             description: TRex stateless traffic generator for RFC2544
52             external-interface:
53             -   name: xe0
54                 virtual-interface:
55                     type: PCI-PASSTHROUGH
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 }}'
61                     bandwidth: 10 Gbps
62                 vnfd-connection-point-ref: xe0
63             -   name: xe1
64                 virtual-interface:
65                     type: PCI-PASSTHROUGH
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 }}'
71                     bandwidth: 10 Gbps
72                 vnfd-connection-point-ref: xe1
73             routing_table: {{ routing_table }}
74             nd_route_tbl: {{ nd_route_tbl }}
75
76         benchmark:
77             kpi:
78                 - rx_throughput_fps
79                 - tx_throughput_fps
80                 - tx_throughput_mbps
81                 - rx_throughput_mbps
82                 - tx_throughput_pc_linerate
83                 - rx_throughput_pc_linerate
84                 - min_latency
85                 - max_latency
86                 - avg_latency
87 """
88
89 COMPLETE_TREX_VNFD = \
90     {'vnfd:vnfd-catalog':
91      {'vnfd':
92       [{'benchmark':
93         {'kpi':
94          ['rx_throughput_fps',
95           'tx_throughput_fps',
96           'tx_throughput_mbps',
97           'rx_throughput_mbps',
98           'tx_throughput_pc_linerate',
99           'rx_throughput_pc_linerate',
100           'min_latency',
101           'max_latency',
102           'avg_latency']},
103         'connection-point': [{'name': 'xe0',
104                               'type': 'VPORT'},
105                              {'name': 'xe1',
106                               'type': 'VPORT'}],
107         'description': 'TRex stateless traffic generator for RFC2544',
108         'id': 'TrexTrafficGen',
109         'mgmt-interface': {'ip': '1.1.1.1',
110                            'password': 'berta',
111                            'user': 'berta',
112                            'vdu-id': 'trexgen-baremetal'},
113         'name': 'trexgen',
114         'short-name': 'trexgen',
115         'vdu': [{'description': 'TRex stateless traffic generator for RFC2544',
116                  'external-interface':
117                  [{'name': 'xe0',
118                    'virtual-interface': {'bandwidth': '10 Gbps',
119                                          'dst_ip': '1.1.1.1',
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'},
126                   {'name': 'xe1',
127                    'virtual-interface': {'bandwidth': '10 Gbps',
128                                          'dst_ip': '2.1.1.1',
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',
137                                    'if': 'xe0',
138                                    'netmask': '112',
139                                    'network': '0064:ff9b:0:0:0:0:9810:6414'},
140                                   {'gateway': '0064:ff9b:0:0:0:0:9810:2814',
141                                    'if': 'xe1',
142                                    'netmask': '112',
143                                    'network': '0064:ff9b:0:0:0:0:9810:2814'}],
144                  'routing_table': [{'gateway': '152.16.100.20',
145                                     'if': 'xe0',
146                                     'netmask': '255.255.255.0',
147                                     'network': '152.16.100.20'},
148                                    {'gateway': '152.16.40.20',
149                                     'if': 'xe1',
150                                     'netmask': '255.255.255.0',
151                                     'network': '152.16.40.20'}],
152                  'name': 'trexgen-baremetal'}]}]}}
153
154 NODE_CFG = {'ip': '1.1.1.1',
155             'name': 'demeter',
156             'password': 'berta',
157             'role': 'TrafficGen',
158             'user': 'berta',
159             'interfaces': {'xe0': {'dpdk_port_num': 1,
160                                    'dst_ip': '1.1.1.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,
166                                    'dst_ip': '2.1.1.1',
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',
172                               u'if': u'xe0',
173                               u'netmask': u'112',
174                               u'network': u'0064:ff9b:0:0:0:0:9810:6414'},
175                              {u'gateway': u'0064:ff9b:0:0:0:0:9810:2814',
176                               u'if': u'xe1',
177                               u'netmask': u'112',
178                               u'network': u'0064:ff9b:0:0:0:0:9810:2814'}],
179             'routing_table': [{u'gateway': u'152.16.100.20',
180                                u'if': u'xe0',
181                                u'netmask': u'255.255.255.0',
182                                u'network': u'152.16.100.20'},
183                               {u'gateway': u'152.16.40.20',
184                                u'if': u'xe1',
185                                u'netmask': u'255.255.255.0',
186                                u'network': u'152.16.40.20'}],
187             }
188
189
190 # need to template, but can't use {} so use %s
191 TRAFFIC_PROFILE_TPL = """
192 %(0)s:
193     - ipv4:
194         outer_l2:
195             framesize:
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) }}"
203 """ % {"0": UPLINK}
204
205 TRAFFIC_PROFILE = {
206     UPLINK: [{"ipv4": {"outer_l2":
207                           {"framesize": {"64B": '10', "128B": '10',
208                                          "256B": '10', "373B": '10',
209                                          "570B": '10', "1400B": '10',
210                                          "1518B": '40'}}}}]}
211
212
213 class TestRender(unittest.TestCase):
214
215     def test_render_none(self):
216
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)
220
221     def test_render_unicode_dict(self):
222
223         tmpl = "{{ routing_table }}"
224         self.assertEqual(yaml_load(vnfdgen.render(tmpl, **NODE_CFG)), NODE_CFG["routing_table"])
225
226
227 class TestVnfdGen(unittest.TestCase):
228     """ Class to verify VNFS testcases """
229
230     def test_generate_vnfd(self):
231         """ Function to verify vnfd generation based on template """
232         self.maxDiff = None
233         generated_vnfd = vnfdgen.generate_vnfd(TREX_VNFD_TEMPLATE, NODE_CFG)
234         self.assertDictEqual(COMPLETE_TREX_VNFD, generated_vnfd)
235
236     def test_generate_tp_no_vars(self):
237         """ Function to verify traffic profile generation without imix """
238
239         self.maxDiff = None
240         generated_tp = vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL, {"imix": {}})
241         self.assertDictEqual(TRAFFIC_PROFILE, generated_tp)
242
243     def test_deepgetitem(self):
244         d = {'a': 1, 'b': 2}
245         self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
246
247     def test_dict_flatten_int(self):
248         d = {'a': 1, 'b': 2}
249         self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
250
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)
254
255     def test_dict_flatten_int_key_fallback(self):
256         d = {0: 1, 'b': 2}
257         self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
258
259     def test_dict_flatten_list(self):
260         d = {'a': 1, 'b': list(range(2))}
261         self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
262
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)
266
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)
270
271
272     def test_generate_tp_single_var(self):
273         """ Function to verify traffic profile generation with imix """
274
275         generated_tp = \
276             vnfdgen.generate_vnfd(TRAFFIC_PROFILE_TPL,
277                                   {"imix": {UPLINK: {"imix_small": '20'}}})
278         self.maxDiff = None
279         tp2 = dict(TRAFFIC_PROFILE)
280         tp2[UPLINK][0]["ipv4"]["outer_l2"]["framesize"]["64B"] = '20'
281         self.assertDictEqual(tp2, generated_tp)