| #!/usr/bin/env python |
| # Copyright 2013, Big Switch Networks, Inc. |
| # |
| # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with |
| # the following special exception: |
| # |
| # LOXI Exception |
| # |
| # As a special exception to the terms of the EPL, you may distribute libraries |
| # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided |
| # that copyright and licensing notices generated by LoxiGen are not altered or removed |
| # from the LoxiGen Libraries and the notice provided below is (i) included in |
| # the LoxiGen Libraries, if distributed in source code form and (ii) included in any |
| # documentation for the LoxiGen Libraries, if distributed in binary form. |
| # |
| # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler." |
| # |
| # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain |
| # a copy of the EPL at: |
| # |
| # http://www.eclipse.org/legal/epl-v10.html |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # EPL for the specific language governing permissions and limitations |
| # under the EPL. |
| |
| import sys |
| import os |
| import unittest |
| |
| from nose.tools import eq_, ok_, raises |
| |
| root_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..') |
| sys.path.insert(0, root_dir) |
| |
| import loxi_ir.ir as ir |
| import loxi_front_end.frontend_ir as fe |
| |
| class BuildIRTest(unittest.TestCase): |
| |
| def test_simple(self): |
| version = ir.OFVersion("1.0", 1) |
| input = fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass=None, |
| members=( |
| fe.OFDataMember(name='version', oftype='uint32_t'), |
| fe.OFLengthMember(name='length', oftype='uint16_t') |
| ), |
| virtual=False, |
| params={} |
| ), |
| ), |
| enums=() |
| ) |
| |
| p = ir.build_protocol(version, [ input ]) |
| eq_(1, len(p.classes)) |
| c = p.classes[0] |
| eq_("OFMessage", c.name) |
| eq_(None, c.superclass) |
| eq_(False, c.virtual) |
| eq_({}, c.params) |
| eq_(2, len(c.members)) |
| eq_(p, c.protocol) |
| |
| m1 = c.members[0] |
| ok_(isinstance(m1, ir.OFDataMember)) |
| eq_("version", m1.name) |
| eq_("uint32_t", m1.oftype) |
| eq_(4, m1.length) |
| eq_(True, m1.is_fixed_length) |
| eq_(0, m1.offset) |
| eq_(c, m1.of_class) |
| |
| m2 = c.members[1] |
| ok_(isinstance(m2, ir.OFLengthMember)) |
| eq_("length", m2.name) |
| eq_("uint16_t", m2.oftype) |
| eq_(2, m2.length) |
| eq_(True, m2.is_fixed_length) |
| eq_(4, m2.offset) |
| eq_(c, m2.of_class) |
| |
| eq_(True, c.is_fixed_length) |
| eq_(6, c.length) |
| |
| def test_resolve_superclass(self): |
| version = ir.OFVersion("1.0", 1) |
| input = fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass=None, |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| fe.OFClass(name="OFHello", |
| superclass="OFMessage", |
| members=(), |
| virtual=False, |
| params={} |
| ), |
| ), |
| enums=() |
| ) |
| p = ir.build_protocol(version, [ input ]) |
| eq_(2, len(p.classes)) |
| c, c2 = p.classes |
| eq_("OFMessage", c.name) |
| eq_(None, c.superclass) |
| eq_(True, c.virtual) |
| eq_("OFHello", c2.name) |
| eq_(c, c2.superclass) |
| eq_(False, c2.virtual) |
| |
| @raises(ir.ClassNotFoundException) |
| def test_resolve_superclass(self): |
| version = ir.OFVersion("1.0", 1) |
| input = fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass="NotFoundSuperClass", |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| ), |
| enums=() |
| ) |
| p = ir.build_protocol(version, [ input ]) |
| |
| |
| @raises(ir.DependencyCycleException) |
| def test_dependency_cycle(self): |
| version = ir.OFVersion("1.0", 1) |
| input = fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass="OFHeader", |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| fe.OFClass(name="OFHeader", |
| superclass="OFMessage", |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| ), |
| enums=() |
| ) |
| p = ir.build_protocol(version, [ input ]) |
| |
| @raises(ir.RedefinedException) |
| def test_class_redefined(self): |
| version = ir.OFVersion("1.0", 1) |
| inputs = ( |
| fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass=None, |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| ), |
| enums=(), |
| ), |
| fe.OFInput(filename="test2.dat", |
| wire_versions=(1,), |
| classes=( |
| fe.OFClass(name="OFMessage", |
| superclass=None, |
| members=(), |
| virtual=True, |
| params={} |
| ), |
| ), |
| enums=() |
| ) |
| ) |
| p = ir.build_protocol(version, inputs) |
| |
| |
| def test_enums(self): |
| version = ir.OFVersion("1.0", 1) |
| input = fe.OFInput(filename="test.dat", |
| wire_versions=(1,), |
| classes=(), |
| enums=( |
| fe.OFEnum(name='ofp_flow_wildcards', |
| entries=(fe.OFEnumEntry(name="OFPFW_IN_PORT", value=0x01, params={}), |
| fe.OFEnumEntry(name="OFPFW_DL_VLAN", value=0x2, params={})), |
| params = dict(wire_type="uint32_t", bitmask=True) |
| ), |
| fe.OFEnum(name='ofp_queue_properties', |
| entries=(fe.OFEnumEntry(name="OFPQT_NONE", value=0x00, params={}), |
| fe.OFEnumEntry(name="OFPQT_MIN_RATE", value=0x1, params={})), |
| params = dict(wire_type="uint32_t") |
| ), |
| ) |
| ) |
| |
| p = ir.build_protocol(version, [ input ]) |
| eq_(0, len(p.classes)) |
| eq_(2, len(p.enums)) |
| e = p.enums[0] |
| eq_("ofp_flow_wildcards", e.name) |
| eq_(True, e.is_bitmask) |
| eq_("uint32_t", e.wire_type) |
| eq_(ir.OFEnumEntry(name="OFPFW_IN_PORT", value=0x01, params={}), e.entries[0]) |
| eq_(ir.OFEnumEntry(name="OFPFW_DL_VLAN", value=0x02, params={}), e.entries[1]) |
| |
| e = p.enums[1] |
| eq_("ofp_queue_properties", e.name) |
| eq_(False, e.is_bitmask) |
| eq_("uint32_t", e.wire_type) |
| eq_(ir.OFEnumEntry(name="OFPQT_NONE", value=0x00, params={}), e.entries[0]) |
| eq_(ir.OFEnumEntry(name="OFPQT_MIN_RATE", value=0x01, params={}), e.entries[1]) |
| |
| if __name__ == '__main__': |
| unittest.main() |