blob: 5689a9441054b9181d7a3b5a92962fa7b1e4cfca [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
Rich Lane57026dc2013-05-01 10:13:16 -070032 from loxi.generic_util import OFReader
Rich Lane3f075972013-03-15 22:56:29 -070033except ImportError:
34 exit("loxi package not found. Try setting PYTHONPATH.")
35
36class TestImports(unittest.TestCase):
37 def test_toplevel(self):
38 import loxi
39 self.assertTrue(hasattr(loxi, "ProtocolError"))
Rich Lane00549ea2013-04-25 13:33:16 -070040 self.assertEquals(loxi.version_names[4], "1.3")
Rich Lane3f075972013-03-15 22:56:29 -070041 ofp = loxi.protocol(4)
42 self.assertEquals(ofp.OFP_VERSION, 4)
43 self.assertTrue(hasattr(ofp, "action"))
44 self.assertTrue(hasattr(ofp, "common"))
45 self.assertTrue(hasattr(ofp, "const"))
46 self.assertTrue(hasattr(ofp, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070047 self.assertTrue(hasattr(ofp, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070048
49 def test_version(self):
50 import loxi
51 self.assertTrue(hasattr(loxi.of13, "ProtocolError"))
52 self.assertTrue(hasattr(loxi.of13, "OFP_VERSION"))
53 self.assertEquals(loxi.of13.OFP_VERSION, 4)
54 self.assertTrue(hasattr(loxi.of13, "action"))
55 self.assertTrue(hasattr(loxi.of13, "common"))
56 self.assertTrue(hasattr(loxi.of13, "const"))
57 self.assertTrue(hasattr(loxi.of13, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070058 self.assertTrue(hasattr(loxi.of13, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070059
Rich Lanee90685c2013-04-05 17:27:41 -070060class TestCommon(unittest.TestCase):
61 sample_hello_elem_buf = ''.join([
62 '\x00\x01', # type
63 '\x00\x0c', # length
64 '\x01\x23\x45\x67', # bitmaps[0]
65 '\x89\xab\xcd\xef', # bitmaps[1]
66 ])
67
68 def test_hello_elem_versionbitmap_pack(self):
69 obj = ofp.hello_elem_versionbitmap(bitmaps=[ofp.uint32(0x01234567),ofp.uint32(0x89abcdef)])
70 self.assertEquals(self.sample_hello_elem_buf, obj.pack())
71
72 def test_hello_elem_versionbitmap_unpack(self):
73 obj = ofp.hello_elem_versionbitmap.unpack(self.sample_hello_elem_buf)
74 self.assertEquals(len(obj.bitmaps), 2)
75 self.assertEquals(obj.bitmaps[0], ofp.uint32(0x01234567))
76 self.assertEquals(obj.bitmaps[1], ofp.uint32(0x89abcdef))
77
78 def test_list_hello_elem_unpack(self):
79 buf = ''.join([
80 '\x00\x01\x00\x04', # versionbitmap
81 '\x00\x00\x00\x04', # unknown type
82 '\x00\x01\x00\x04', # versionbitmap
83 ])
Rich Lane57026dc2013-05-01 10:13:16 -070084 l = ofp.unpack_list_hello_elem(OFReader(buf))
Rich Lanee90685c2013-04-05 17:27:41 -070085 self.assertEquals(len(l), 2)
86 self.assertTrue(isinstance(l[0], ofp.hello_elem_versionbitmap))
87 self.assertTrue(isinstance(l[1], ofp.hello_elem_versionbitmap))
88
Rich Laneea693752013-03-18 11:05:45 -070089class TestOXM(unittest.TestCase):
90 def test_oxm_in_phy_port_pack(self):
91 import loxi.of13 as ofp
92 obj = ofp.oxm.in_phy_port(value=42)
93 expected = ''.join([
94 '\x80\x00', # class
95 '\x02', # type/masked
Rich Lane82e9f6e2013-04-25 17:32:22 -070096 '\x04', # length
Rich Laneea693752013-03-18 11:05:45 -070097 '\x00\x00\x00\x2a' # value
98 ])
99 self.assertEquals(expected, obj.pack())
100
101 def test_oxm_in_phy_port_masked_pack(self):
102 import loxi.of13 as ofp
103 obj = ofp.oxm.in_phy_port_masked(value=42, value_mask=0xaabbccdd)
104 expected = ''.join([
105 '\x80\x00', # class
106 '\x03', # type/masked
Rich Lane82e9f6e2013-04-25 17:32:22 -0700107 '\x08', # length
Rich Laneea693752013-03-18 11:05:45 -0700108 '\x00\x00\x00\x2a', # value
109 '\xaa\xbb\xcc\xdd' # mask
110 ])
111 self.assertEquals(expected, obj.pack())
112
Rich Lane41805642013-03-19 15:00:26 -0700113 def test_oxm_ipv6_dst_pack(self):
114 import loxi.of13 as ofp
115 obj = ofp.oxm.ipv6_dst(value='\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0d\x0f')
116 expected = ''.join([
117 '\x80\x00', # class
118 '\x36', # type/masked
Rich Lane82e9f6e2013-04-25 17:32:22 -0700119 '\x10', # length
Rich Lane41805642013-03-19 15:00:26 -0700120 '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0d\x0f', # value
121 ])
122 self.assertEquals(expected, obj.pack())
123
Rich Lane3f075972013-03-15 22:56:29 -0700124class TestAllOF13(unittest.TestCase):
125 """
126 Round-trips every class through serialization/deserialization.
127 Not a replacement for handcoded tests because it only uses the
128 default member values.
129 """
130
131 def setUp(self):
Rich Laneea693752013-03-18 11:05:45 -0700132 mods = [ofp.action,ofp.message,ofp.common,ofp.oxm]
Rich Lane3f075972013-03-15 22:56:29 -0700133 self.klasses = [klass for mod in mods
134 for klass in mod.__dict__.values()
135 if hasattr(klass, 'show')]
136 self.klasses.sort(key=lambda x: str(x))
137
138 def test_serialization(self):
139 expected_failures = [
Rich Lane3f075972013-03-15 22:56:29 -0700140 ofp.common.group_desc_stats_entry,
Rich Lane3f075972013-03-15 22:56:29 -0700141 ofp.message.group_desc_stats_reply,
142 ofp.message.group_mod,
143 ofp.message.group_stats_reply,
Rich Lane3f075972013-03-15 22:56:29 -0700144 ofp.message.meter_stats_reply,
Rich Lanea0186052013-05-01 14:18:39 -0700145 ofp.message.meter_features_stats_reply,
Rich Lane3f075972013-03-15 22:56:29 -0700146 ofp.message.table_features_stats_reply,
147 ofp.message.table_features_stats_request,
148 ]
149 for klass in self.klasses:
150 def fn():
151 obj = klass()
152 if hasattr(obj, "xid"): obj.xid = 42
153 buf = obj.pack()
154 obj2 = klass.unpack(buf)
155 self.assertEquals(obj, obj2)
156 if klass in expected_failures:
157 self.assertRaises(Exception, fn)
158 else:
159 fn()
160
161 def test_show(self):
Rich Lane8ca3b772013-04-30 13:36:55 -0700162 expected_failures = []
Rich Lane3f075972013-03-15 22:56:29 -0700163 for klass in self.klasses:
164 def fn():
165 obj = klass()
166 if hasattr(obj, "xid"): obj.xid = 42
167 obj.show()
168 if klass in expected_failures:
169 self.assertRaises(Exception, fn)
170 else:
171 fn()
172
173if __name__ == '__main__':
174 unittest.main()