blob: 3a534e1cd60a8f1f4f81b2be557928821c0d1f39 [file] [log] [blame]
Rich Lane3f075972013-03-15 22:56:29 -07001#!/usr/bin/env python
2# Copyright 2013, Big Switch Networks, Inc.
3#
4# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
5# the following special exception:
6#
7# LOXI Exception
8#
9# As a special exception to the terms of the EPL, you may distribute libraries
10# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
11# that copyright and licensing notices generated by LoxiGen are not altered or removed
12# from the LoxiGen Libraries and the notice provided below is (i) included in
13# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
14# documentation for the LoxiGen Libraries, if distributed in binary form.
15#
16# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
17#
18# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
19# a copy of the EPL at:
20#
21# http://www.eclipse.org/legal/epl-v10.html
22#
23# Unless required by applicable law or agreed to in writing, software
24# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
26# EPL for the specific language governing permissions and limitations
27# under the EPL.
28import unittest
29
30try:
31 import loxi.of13 as ofp
32except ImportError:
33 exit("loxi package not found. Try setting PYTHONPATH.")
34
35class TestImports(unittest.TestCase):
36 def test_toplevel(self):
37 import loxi
38 self.assertTrue(hasattr(loxi, "ProtocolError"))
39 ofp = loxi.protocol(4)
40 self.assertEquals(ofp.OFP_VERSION, 4)
41 self.assertTrue(hasattr(ofp, "action"))
42 self.assertTrue(hasattr(ofp, "common"))
43 self.assertTrue(hasattr(ofp, "const"))
44 self.assertTrue(hasattr(ofp, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070045 self.assertTrue(hasattr(ofp, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070046
47 def test_version(self):
48 import loxi
49 self.assertTrue(hasattr(loxi.of13, "ProtocolError"))
50 self.assertTrue(hasattr(loxi.of13, "OFP_VERSION"))
51 self.assertEquals(loxi.of13.OFP_VERSION, 4)
52 self.assertTrue(hasattr(loxi.of13, "action"))
53 self.assertTrue(hasattr(loxi.of13, "common"))
54 self.assertTrue(hasattr(loxi.of13, "const"))
55 self.assertTrue(hasattr(loxi.of13, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070056 self.assertTrue(hasattr(loxi.of13, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070057
Rich Lanee90685c2013-04-05 17:27:41 -070058class TestCommon(unittest.TestCase):
59 sample_hello_elem_buf = ''.join([
60 '\x00\x01', # type
61 '\x00\x0c', # length
62 '\x01\x23\x45\x67', # bitmaps[0]
63 '\x89\xab\xcd\xef', # bitmaps[1]
64 ])
65
66 def test_hello_elem_versionbitmap_pack(self):
67 obj = ofp.hello_elem_versionbitmap(bitmaps=[ofp.uint32(0x01234567),ofp.uint32(0x89abcdef)])
68 self.assertEquals(self.sample_hello_elem_buf, obj.pack())
69
70 def test_hello_elem_versionbitmap_unpack(self):
71 obj = ofp.hello_elem_versionbitmap.unpack(self.sample_hello_elem_buf)
72 self.assertEquals(len(obj.bitmaps), 2)
73 self.assertEquals(obj.bitmaps[0], ofp.uint32(0x01234567))
74 self.assertEquals(obj.bitmaps[1], ofp.uint32(0x89abcdef))
75
76 def test_list_hello_elem_unpack(self):
77 buf = ''.join([
78 '\x00\x01\x00\x04', # versionbitmap
79 '\x00\x00\x00\x04', # unknown type
80 '\x00\x01\x00\x04', # versionbitmap
81 ])
82 l = ofp.unpack_list_hello_elem(buf)
83 self.assertEquals(len(l), 2)
84 self.assertTrue(isinstance(l[0], ofp.hello_elem_versionbitmap))
85 self.assertTrue(isinstance(l[1], ofp.hello_elem_versionbitmap))
86
Rich Laneea693752013-03-18 11:05:45 -070087class TestOXM(unittest.TestCase):
88 def test_oxm_in_phy_port_pack(self):
89 import loxi.of13 as ofp
90 obj = ofp.oxm.in_phy_port(value=42)
91 expected = ''.join([
92 '\x80\x00', # class
93 '\x02', # type/masked
94 '\x08', # length
95 '\x00\x00\x00\x2a' # value
96 ])
97 self.assertEquals(expected, obj.pack())
98
99 def test_oxm_in_phy_port_masked_pack(self):
100 import loxi.of13 as ofp
101 obj = ofp.oxm.in_phy_port_masked(value=42, value_mask=0xaabbccdd)
102 expected = ''.join([
103 '\x80\x00', # class
104 '\x03', # type/masked
105 '\x0c', # length
106 '\x00\x00\x00\x2a', # value
107 '\xaa\xbb\xcc\xdd' # mask
108 ])
109 self.assertEquals(expected, obj.pack())
110
Rich Lane41805642013-03-19 15:00:26 -0700111 def test_oxm_ipv6_dst_pack(self):
112 import loxi.of13 as ofp
113 obj = ofp.oxm.ipv6_dst(value='\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0d\x0f')
114 expected = ''.join([
115 '\x80\x00', # class
116 '\x36', # type/masked
117 '\x14', # length
118 '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0d\x0f', # value
119 ])
120 self.assertEquals(expected, obj.pack())
121
Rich Lane3f075972013-03-15 22:56:29 -0700122class TestAllOF13(unittest.TestCase):
123 """
124 Round-trips every class through serialization/deserialization.
125 Not a replacement for handcoded tests because it only uses the
126 default member values.
127 """
128
129 def setUp(self):
Rich Laneea693752013-03-18 11:05:45 -0700130 mods = [ofp.action,ofp.message,ofp.common,ofp.oxm]
Rich Lane3f075972013-03-15 22:56:29 -0700131 self.klasses = [klass for mod in mods
132 for klass in mod.__dict__.values()
133 if hasattr(klass, 'show')]
134 self.klasses.sort(key=lambda x: str(x))
135
136 def test_serialization(self):
137 expected_failures = [
138 ofp.common.action_id,
139 ofp.common.action_id_bsn_mirror,
140 ofp.common.action_id_bsn_set_tunnel_dst,
141 ofp.common.action_id_copy_ttl_in,
142 ofp.common.action_id_copy_ttl_out,
143 ofp.common.action_id_dec_mpls_ttl,
144 ofp.common.action_id_dec_nw_ttl,
145 ofp.common.action_id_experimenter,
146 ofp.common.action_id_group,
147 ofp.common.action_id_header,
148 ofp.common.action_id_nicira_dec_ttl,
149 ofp.common.action_id_output,
150 ofp.common.action_id_pop_mpls,
151 ofp.common.action_id_pop_pbb,
152 ofp.common.action_id_pop_vlan,
153 ofp.common.action_id_push_mpls,
154 ofp.common.action_id_push_pbb,
155 ofp.common.action_id_push_vlan,
156 ofp.common.action_id_set_field,
157 ofp.common.action_id_set_mpls_ttl,
158 ofp.common.action_id_set_nw_ttl,
159 ofp.common.action_id_set_queue,
160 ofp.common.flow_stats_entry,
161 ofp.common.group_desc_stats_entry,
Rich Lane3f075972013-03-15 22:56:29 -0700162 ofp.common.instruction,
163 ofp.common.instruction_apply_actions,
164 ofp.common.instruction_clear_actions,
165 ofp.common.instruction_experimenter,
166 ofp.common.instruction_goto_table,
167 ofp.common.instruction_header,
168 ofp.common.instruction_meter,
169 ofp.common.instruction_write_actions,
170 ofp.common.instruction_write_metadata,
171 ofp.common.match_v3,
172 ofp.common.meter_band,
173 ofp.common.meter_band_drop,
174 ofp.common.meter_band_dscp_remark,
175 ofp.common.meter_band_experimenter,
176 ofp.common.meter_band_header,
Rich Lane3f075972013-03-15 22:56:29 -0700177 ofp.common.table_feature_prop,
178 ofp.common.table_feature_prop_apply_actions,
179 ofp.common.table_feature_prop_apply_actions_miss,
180 ofp.common.table_feature_prop_apply_setfield,
181 ofp.common.table_feature_prop_apply_setfield_miss,
182 ofp.common.table_feature_prop_experimenter,
183 ofp.common.table_feature_prop_header,
184 ofp.common.table_feature_prop_instructions,
185 ofp.common.table_feature_prop_instructions_miss,
186 ofp.common.table_feature_prop_match,
187 ofp.common.table_feature_prop_next_tables,
188 ofp.common.table_feature_prop_next_tables_miss,
189 ofp.common.table_feature_prop_wildcards,
190 ofp.common.table_feature_prop_write_actions,
191 ofp.common.table_feature_prop_write_actions_miss,
192 ofp.common.table_feature_prop_write_setfield,
193 ofp.common.table_feature_prop_write_setfield_miss,
194 ofp.message.aggregate_stats_request,
195 ofp.message.flow_add,
196 ofp.message.flow_delete,
197 ofp.message.flow_delete_strict,
198 ofp.message.flow_modify,
199 ofp.message.flow_modify_strict,
200 ofp.message.flow_removed,
201 ofp.message.flow_stats_request,
202 ofp.message.group_desc_stats_reply,
203 ofp.message.group_mod,
204 ofp.message.group_stats_reply,
205 ofp.message.meter_features_stats_reply,
206 ofp.message.meter_stats_reply,
207 ofp.message.packet_in,
208 ofp.message.table_features_stats_reply,
209 ofp.message.table_features_stats_request,
210 ]
211 for klass in self.klasses:
212 def fn():
213 obj = klass()
214 if hasattr(obj, "xid"): obj.xid = 42
215 buf = obj.pack()
216 obj2 = klass.unpack(buf)
217 self.assertEquals(obj, obj2)
218 if klass in expected_failures:
219 self.assertRaises(Exception, fn)
220 else:
221 fn()
222
223 def test_show(self):
224 expected_failures = [
225 ofp.common.action_id,
226 ofp.common.action_id_bsn_mirror,
227 ofp.common.action_id_bsn_set_tunnel_dst,
228 ofp.common.action_id_copy_ttl_in,
229 ofp.common.action_id_copy_ttl_out,
230 ofp.common.action_id_dec_mpls_ttl,
231 ofp.common.action_id_dec_nw_ttl,
232 ofp.common.action_id_experimenter,
233 ofp.common.action_id_group,
234 ofp.common.action_id_header,
235 ofp.common.action_id_nicira_dec_ttl,
236 ofp.common.action_id_output,
237 ofp.common.action_id_pop_mpls,
238 ofp.common.action_id_pop_pbb,
239 ofp.common.action_id_pop_vlan,
240 ofp.common.action_id_push_mpls,
241 ofp.common.action_id_push_pbb,
242 ofp.common.action_id_push_vlan,
243 ofp.common.action_id_set_field,
244 ofp.common.action_id_set_mpls_ttl,
245 ofp.common.action_id_set_nw_ttl,
246 ofp.common.action_id_set_queue,
247 ofp.common.flow_stats_entry,
248 ofp.common.group_desc_stats_entry,
Rich Lane3f075972013-03-15 22:56:29 -0700249 ofp.common.instruction,
250 ofp.common.instruction_apply_actions,
251 ofp.common.instruction_clear_actions,
252 ofp.common.instruction_experimenter,
253 ofp.common.instruction_goto_table,
254 ofp.common.instruction_header,
255 ofp.common.instruction_meter,
256 ofp.common.instruction_write_actions,
257 ofp.common.instruction_write_metadata,
258 ofp.common.match_v3,
259 ofp.common.meter_band,
260 ofp.common.meter_band_drop,
261 ofp.common.meter_band_dscp_remark,
262 ofp.common.meter_band_experimenter,
263 ofp.common.meter_band_header,
Rich Lane3f075972013-03-15 22:56:29 -0700264 ofp.common.table_feature_prop,
265 ofp.common.table_feature_prop_apply_actions,
266 ofp.common.table_feature_prop_apply_actions_miss,
267 ofp.common.table_feature_prop_apply_setfield,
268 ofp.common.table_feature_prop_apply_setfield_miss,
269 ofp.common.table_feature_prop_experimenter,
270 ofp.common.table_feature_prop_header,
271 ofp.common.table_feature_prop_instructions,
272 ofp.common.table_feature_prop_instructions_miss,
273 ofp.common.table_feature_prop_match,
274 ofp.common.table_feature_prop_next_tables,
275 ofp.common.table_feature_prop_next_tables_miss,
276 ofp.common.table_feature_prop_wildcards,
277 ofp.common.table_feature_prop_write_actions,
278 ofp.common.table_feature_prop_write_actions_miss,
279 ofp.common.table_feature_prop_write_setfield,
280 ofp.common.table_feature_prop_write_setfield_miss,
281 ofp.message.aggregate_stats_request,
282 ofp.message.flow_add,
283 ofp.message.flow_delete,
284 ofp.message.flow_delete_strict,
285 ofp.message.flow_modify,
286 ofp.message.flow_modify_strict,
287 ofp.message.flow_removed,
288 ofp.message.flow_stats_request,
289 ofp.message.packet_in,
290 ]
291 for klass in self.klasses:
292 def fn():
293 obj = klass()
294 if hasattr(obj, "xid"): obj.xid = 42
295 obj.show()
296 if klass in expected_failures:
297 self.assertRaises(Exception, fn)
298 else:
299 fn()
300
301if __name__ == '__main__':
302 unittest.main()