blob: b6d87a331f4e87df62f82c612f4de19728064838 [file] [log] [blame]
Andreas Wundsamd30c1072013-11-15 13:36:57 -08001#!/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.
28
29import sys
30import os
31import unittest
32
33from nose.tools import eq_, ok_, raises
34
35root_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
36sys.path.insert(0, root_dir)
37
38import loxi_ir.ir as ir
39import loxi_front_end.frontend_ir as fe
40
41class BuildIRTest(unittest.TestCase):
42
43 def test_simple(self):
44 version = ir.OFVersion("1.0", 1)
45 input = fe.OFInput(filename="test.dat",
46 wire_versions=(1,),
47 classes=(
48 fe.OFClass(name="OFMessage",
49 superclass=None,
50 members=(
51 fe.OFDataMember(name='version', oftype='uint32_t'),
52 fe.OFLengthMember(name='length', oftype='uint16_t')
53 ),
54 virtual=False,
55 params={}
56 ),
57 ),
58 enums=()
59 )
60
61 p = ir.build_protocol(version, [ input ])
62 eq_(1, len(p.classes))
63 c = p.classes[0]
64 eq_("OFMessage", c.name)
65 eq_(None, c.superclass)
66 eq_(False, c.virtual)
67 eq_({}, c.params)
68 eq_(2, len(c.members))
69 eq_(p, c.protocol)
70
71 m1 = c.members[0]
72 ok_(isinstance(m1, ir.OFDataMember))
73 eq_("version", m1.name)
74 eq_("uint32_t", m1.oftype)
75 eq_(4, m1.length)
76 eq_(True, m1.is_fixed_length)
77 eq_(0, m1.offset)
78 eq_(c, m1.of_class)
79
80 m2 = c.members[1]
81 ok_(isinstance(m2, ir.OFLengthMember))
82 eq_("length", m2.name)
83 eq_("uint16_t", m2.oftype)
84 eq_(2, m2.length)
85 eq_(True, m2.is_fixed_length)
86 eq_(4, m2.offset)
87 eq_(c, m2.of_class)
88
89 eq_(True, c.is_fixed_length)
90 eq_(6, c.length)
91
92 def test_resolve_superclass(self):
93 version = ir.OFVersion("1.0", 1)
94 input = fe.OFInput(filename="test.dat",
95 wire_versions=(1,),
96 classes=(
97 fe.OFClass(name="OFMessage",
98 superclass=None,
99 members=(),
100 virtual=True,
101 params={}
102 ),
103 fe.OFClass(name="OFHello",
104 superclass="OFMessage",
105 members=(),
106 virtual=False,
107 params={}
108 ),
109 ),
110 enums=()
111 )
112 p = ir.build_protocol(version, [ input ])
113 eq_(2, len(p.classes))
114 c, c2 = p.classes
115 eq_("OFMessage", c.name)
116 eq_(None, c.superclass)
117 eq_(True, c.virtual)
118 eq_("OFHello", c2.name)
119 eq_(c, c2.superclass)
120 eq_(False, c2.virtual)
121
122 @raises(ir.ClassNotFoundException)
123 def test_resolve_superclass(self):
124 version = ir.OFVersion("1.0", 1)
125 input = fe.OFInput(filename="test.dat",
126 wire_versions=(1,),
127 classes=(
128 fe.OFClass(name="OFMessage",
129 superclass="NotFoundSuperClass",
130 members=(),
131 virtual=True,
132 params={}
133 ),
134 ),
135 enums=()
136 )
137 p = ir.build_protocol(version, [ input ])
138
139
140 @raises(ir.DependencyCycleException)
141 def test_dependency_cycle(self):
142 version = ir.OFVersion("1.0", 1)
143 input = fe.OFInput(filename="test.dat",
144 wire_versions=(1,),
145 classes=(
146 fe.OFClass(name="OFMessage",
147 superclass="OFHeader",
148 members=(),
149 virtual=True,
150 params={}
151 ),
152 fe.OFClass(name="OFHeader",
153 superclass="OFMessage",
154 members=(),
155 virtual=True,
156 params={}
157 ),
158 ),
159 enums=()
160 )
161 p = ir.build_protocol(version, [ input ])
162
163 @raises(ir.RedefinedException)
164 def test_class_redefined(self):
165 version = ir.OFVersion("1.0", 1)
166 inputs = (
167 fe.OFInput(filename="test.dat",
168 wire_versions=(1,),
169 classes=(
170 fe.OFClass(name="OFMessage",
171 superclass=None,
172 members=(),
173 virtual=True,
174 params={}
175 ),
176 ),
177 enums=(),
178 ),
179 fe.OFInput(filename="test2.dat",
180 wire_versions=(1,),
181 classes=(
182 fe.OFClass(name="OFMessage",
183 superclass=None,
184 members=(),
185 virtual=True,
186 params={}
187 ),
188 ),
189 enums=()
190 )
191 )
192 p = ir.build_protocol(version, inputs)
193
194
195 def test_enums(self):
196 version = ir.OFVersion("1.0", 1)
197 input = fe.OFInput(filename="test.dat",
198 wire_versions=(1,),
199 classes=(),
200 enums=(
201 fe.OFEnum(name='ofp_flow_wildcards',
202 entries=(fe.OFEnumEntry(name="OFPFW_IN_PORT", value=0x01, params={}),
203 fe.OFEnumEntry(name="OFPFW_DL_VLAN", value=0x2, params={})),
204 params = dict(wire_type="uint32_t", bitmask=True)
205 ),
206 fe.OFEnum(name='ofp_queue_properties',
207 entries=(fe.OFEnumEntry(name="OFPQT_NONE", value=0x00, params={}),
208 fe.OFEnumEntry(name="OFPQT_MIN_RATE", value=0x1, params={})),
209 params = dict(wire_type="uint32_t")
210 ),
211 )
212 )
213
214 p = ir.build_protocol(version, [ input ])
215 eq_(0, len(p.classes))
216 eq_(2, len(p.enums))
217 e = p.enums[0]
218 eq_("ofp_flow_wildcards", e.name)
219 eq_(True, e.is_bitmask)
220 eq_("uint32_t", e.wire_type)
221 eq_(ir.OFEnumEntry(name="OFPFW_IN_PORT", value=0x01, params={}), e.entries[0])
222 eq_(ir.OFEnumEntry(name="OFPFW_DL_VLAN", value=0x02, params={}), e.entries[1])
223
224 e = p.enums[1]
225 eq_("ofp_queue_properties", e.name)
226 eq_(False, e.is_bitmask)
227 eq_("uint32_t", e.wire_type)
228 eq_(ir.OFEnumEntry(name="OFPQT_NONE", value=0x00, params={}), e.entries[0])
229 eq_(ir.OFEnumEntry(name="OFPQT_MIN_RATE", value=0x01, params={}), e.entries[1])
230
231if __name__ == '__main__':
232 unittest.main()