blob: 54a062970187b0acba48d1bd20d0da8e97d5c71c [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
Rich Lane1d5b0102013-05-10 16:28:17 -070029from testutil import test_serialization
Rich Lanec9fc57d2013-05-16 16:39:12 -070030from testutil import add_datafiles_tests
Rich Lane3f075972013-03-15 22:56:29 -070031
32try:
Rich Lane9d98adf2013-11-29 18:37:24 -080033 import loxi
Rich Lane3f075972013-03-15 22:56:29 -070034 import loxi.of13 as ofp
Rich Lane57026dc2013-05-01 10:13:16 -070035 from loxi.generic_util import OFReader
Rich Lane3f075972013-03-15 22:56:29 -070036except ImportError:
37 exit("loxi package not found. Try setting PYTHONPATH.")
38
39class TestImports(unittest.TestCase):
40 def test_toplevel(self):
41 import loxi
42 self.assertTrue(hasattr(loxi, "ProtocolError"))
Rich Lane00549ea2013-04-25 13:33:16 -070043 self.assertEquals(loxi.version_names[4], "1.3")
Rich Lane3f075972013-03-15 22:56:29 -070044 ofp = loxi.protocol(4)
45 self.assertEquals(ofp.OFP_VERSION, 4)
46 self.assertTrue(hasattr(ofp, "action"))
47 self.assertTrue(hasattr(ofp, "common"))
48 self.assertTrue(hasattr(ofp, "const"))
49 self.assertTrue(hasattr(ofp, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070050 self.assertTrue(hasattr(ofp, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070051
52 def test_version(self):
53 import loxi
54 self.assertTrue(hasattr(loxi.of13, "ProtocolError"))
55 self.assertTrue(hasattr(loxi.of13, "OFP_VERSION"))
56 self.assertEquals(loxi.of13.OFP_VERSION, 4)
57 self.assertTrue(hasattr(loxi.of13, "action"))
58 self.assertTrue(hasattr(loxi.of13, "common"))
59 self.assertTrue(hasattr(loxi.of13, "const"))
60 self.assertTrue(hasattr(loxi.of13, "message"))
Rich Lanea22233e2013-04-25 13:18:41 -070061 self.assertTrue(hasattr(loxi.of13, "oxm"))
Rich Lane3f075972013-03-15 22:56:29 -070062
Rich Lanee90685c2013-04-05 17:27:41 -070063class TestCommon(unittest.TestCase):
Rich Lanee90685c2013-04-05 17:27:41 -070064 def test_list_hello_elem_unpack(self):
65 buf = ''.join([
66 '\x00\x01\x00\x04', # versionbitmap
67 '\x00\x00\x00\x04', # unknown type
68 '\x00\x01\x00\x04', # versionbitmap
69 ])
Rich Laned50d9712013-11-29 19:40:28 -080070 l = ofp.util.unpack_list_hello_elem(OFReader(buf))
Rich Lanee90685c2013-04-05 17:27:41 -070071 self.assertEquals(len(l), 2)
72 self.assertTrue(isinstance(l[0], ofp.hello_elem_versionbitmap))
73 self.assertTrue(isinstance(l[1], ofp.hello_elem_versionbitmap))
74
Rich Lanec9fc57d2013-05-16 16:39:12 -070075# The majority of the serialization tests are created here using the files in
76# the test_data directory.
77class TestDataFiles(unittest.TestCase):
78 pass
79add_datafiles_tests(TestDataFiles, 'of13/', ofp)
Rich Lanee02314c2013-05-02 16:42:04 -070080
Rich Lane3f075972013-03-15 22:56:29 -070081class TestAllOF13(unittest.TestCase):
82 """
83 Round-trips every class through serialization/deserialization.
84 Not a replacement for handcoded tests because it only uses the
85 default member values.
86 """
87
88 def setUp(self):
Rich Laneea693752013-03-18 11:05:45 -070089 mods = [ofp.action,ofp.message,ofp.common,ofp.oxm]
Rich Lane3f075972013-03-15 22:56:29 -070090 self.klasses = [klass for mod in mods
91 for klass in mod.__dict__.values()
Rich Lane9d98adf2013-11-29 18:37:24 -080092 if isinstance(klass, type) and
93 issubclass(klass, loxi.OFObject) and
94 hasattr(klass, 'pack')]
Rich Lane3f075972013-03-15 22:56:29 -070095 self.klasses.sort(key=lambda x: str(x))
96
97 def test_serialization(self):
98 expected_failures = [
Rich Lanebe90eae2013-07-22 16:44:26 -070099 ofp.action.set_field, # field defaults to None
Rich Lane8692ecd2013-05-02 11:33:53 -0700100 ofp.common.table_feature_prop_apply_actions,
101 ofp.common.table_feature_prop_apply_actions_miss,
Rich Lane8692ecd2013-05-02 11:33:53 -0700102 ofp.common.table_feature_prop_write_actions,
103 ofp.common.table_feature_prop_write_actions_miss,
104 ofp.common.table_features,
Rich Lane3f075972013-03-15 22:56:29 -0700105 ofp.message.table_features_stats_reply,
106 ofp.message.table_features_stats_request,
107 ]
108 for klass in self.klasses:
109 def fn():
110 obj = klass()
111 if hasattr(obj, "xid"): obj.xid = 42
112 buf = obj.pack()
Rich Lane5b2745c2013-11-30 00:36:24 -0800113 obj2 = klass.unpack(OFReader(buf))
Rich Lane3f075972013-03-15 22:56:29 -0700114 self.assertEquals(obj, obj2)
115 if klass in expected_failures:
116 self.assertRaises(Exception, fn)
117 else:
118 fn()
119
Rich Lane65790d22013-06-14 00:08:52 -0700120 def test_parse_message(self):
121 expected_failures = [
Rich Lane65790d22013-06-14 00:08:52 -0700122 ofp.message.table_features_stats_reply,
123 ofp.message.table_features_stats_request,
Rich Lane65790d22013-06-14 00:08:52 -0700124 ]
125 for klass in self.klasses:
Rich Lane9d98adf2013-11-29 18:37:24 -0800126 if not issubclass(klass, ofp.message.message):
Rich Lane65790d22013-06-14 00:08:52 -0700127 continue
128 def fn():
129 obj = klass(xid=42)
130 buf = obj.pack()
131 obj2 = ofp.message.parse_message(buf)
132 self.assertEquals(obj, obj2)
133 if klass in expected_failures:
134 self.assertRaises(Exception, fn)
135 else:
136 fn()
137
Rich Lane3f075972013-03-15 22:56:29 -0700138 def test_show(self):
Rich Lane8ca3b772013-04-30 13:36:55 -0700139 expected_failures = []
Rich Lane3f075972013-03-15 22:56:29 -0700140 for klass in self.klasses:
141 def fn():
142 obj = klass()
143 if hasattr(obj, "xid"): obj.xid = 42
144 obj.show()
145 if klass in expected_failures:
146 self.assertRaises(Exception, fn)
147 else:
148 fn()
149
150if __name__ == '__main__':
151 unittest.main()