Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 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 ])
Example #4
0
 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 ])
Example #5
0
    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)
Example #6
0
    def build_id_class(orig_name, base_name):
        name = base_name + '_id' + orig_name[len(base_name):]
        if name in name_classes:
            return name_classes[name]
        orig_fe, _ = name_frontend_classes[orig_name]

        if orig_fe.superclass:
            superclass_name = base_name + '_id' + orig_fe.superclass[
                len(base_name):]
            superclass = build_id_class(orig_fe.superclass, base_name)
        else:
            superclass_name = None
            superclass = None

        ofc_members = []
        for m in orig_fe.members:
            if not isinstance(m, frontend_ir.OFDataMember) and not isinstance(
                    m, frontend_ir.OFPadMember):
                ofc_members.append(m)

        fe = frontend_ir.OFClass(name=name,
                                 superclass=superclass_name,
                                 members=ofc_members,
                                 virtual=orig_fe.virtual,
                                 params={})

        base_length, is_fixed_length, member_lengths = \
           ir_offset.calc_lengths(version, fe, name_classes, name_enums)
        assert fe.virtual or is_fixed_length

        members = []
        c = OFClass(name=fe.name,
                    superclass=superclass,
                    members=members,
                    virtual=fe.virtual,
                    params=fe.params,
                    is_fixed_length=is_fixed_length,
                    base_length=base_length)

        members.extend(
            build_member(c, fe_member, member_lengths[fe_member])
            for fe_member in fe.members)

        name_classes[name] = c
        return c
Example #7
0
def create_ofinput(filename, ast):
    """
    Create an OFInput from an AST

    @param ast An AST as returned by loxi_front_end.parser.parse

    @returns An OFInput object
    """
    ctx = FrontendCtx(set())
    ofinput = ir.OFInput(filename, wire_versions=set(), classes=[], enums=[])

    for decl_ast in ast:
        if decl_ast[0] == 'struct':
            # 0: "struct"
            # 1: name
            # 2: potentially list of [param_name, param_value]
            # 3: super_class or None
            # 4: list of members
            superclass = decl_ast[3]
            members = [create_member(m_ast, ctx) for m_ast in decl_ast[4]]

            discriminators = [
                m for m in members if isinstance(m, ir.OFDiscriminatorMember)
            ]
            if len(discriminators) > 1:
                raise InputError(
                    "%s: Cannot support more than one discriminator by class - got %s"
                    % (decl_ast[1], repr(discriminators)))
            ofclass = ir.OFClass(
                name=decl_ast[1],
                members=members,
                superclass=superclass,
                virtual=len(discriminators) > 0,
                params={param: value
                        for param, value in decl_ast[2]})
            ofinput.classes.append(ofclass)
        if decl_ast[0] == 'enum':
            # 0: "enum"
            # 1: name
            # 2: potentially list of [param_name, param_value]
            # 3: list of [constant_name, constant_value]+
            enum = ir.OFEnum(
                name=decl_ast[1],
                entries=[
                    ir.OFEnumEntry(
                        name=x[0],
                        value=x[2],
                        params={param: value
                                for param, value in x[1]}) for x in decl_ast[3]
                ],
                params={param: value
                        for param, value in decl_ast[2]})
            ofinput.enums.append(enum)
        elif decl_ast[0] == 'metadata':
            if decl_ast[1] == 'version':
                if decl_ast[2] == 'any':
                    ofinput.wire_versions.update(
                        v.wire_version
                        for v in loxi_globals.OFVersions.all_supported)
                elif int(decl_ast[2]
                         ) in loxi_globals.OFVersions.wire_version_map:
                    ofinput.wire_versions.add(int(decl_ast[2]))
                else:
                    raise InputError("Unrecognized wire protocol version %r" %
                                     decl_ast[2])
                found_wire_version = True

    if not ofinput.wire_versions:
        raise InputError("Missing #version metadata")

    return ofinput