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