Exemplo n.º 1
0
def test_write_specification_files_missing_deps(tmp_path: Path) -> None:
    s = ModularInteger("P::S", Number(65536))
    t = ModularInteger("P::T", Number(256))
    v = mty.Sequence("P::V", element_type=t)
    m = Message("P::M", [Link(INITIAL, Field("Foo")), Link(Field("Foo"), FINAL)], {Field("Foo"): t})
    Model([s, v, m]).write_specification_files(tmp_path)
    expected_path = tmp_path / Path("p.rflx")
    assert list(tmp_path.glob("*.rflx")) == [expected_path]
    assert expected_path.read_text() == textwrap.dedent(
        """\
        package P is

           type S is mod 65536;

           type T is mod 256;

           type V is sequence of P::T;

           type M is
              message
                 Foo : P::T;
              end message;

        end P;"""
    )
Exemplo n.º 2
0
def test_incongruent_overlay() -> None:
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"), Field("F2")),
        Link(Field("F2"), Field("F3"), first=First("F1")),
        Link(Field("F3"), Field("F4")),
        Link(Field("F4"), FINAL),
    ]
    u8 = ModularInteger("P.U8", Number(256))
    u16 = ModularInteger("P.U16", Number(65536))
    types = {
        Field("F1"): u8,
        Field("F2"): u8,
        Field("F3"): u16,
        Field("F4"): u16,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'model: error: field "F3" not congruent with overlaid field "F1"\n'
        r'model: info: unsatisfied "F1\'First = Message\'First"\n'
        r'model: info: unsatisfied "F1\'Last = [(][(]Message\'First [+] 8[)][)] - 1"\n'
        r'model: info: unsatisfied "[(][(]F1\'First [+] 16[)][)] - 1 = F1\'Last"'
        r"$",
    )
Exemplo n.º 3
0
def create_array_message() -> Message:
    length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8)))

    modular_type = ModularInteger("Arrays.Modular_Integer",
                                  Pow(Number(2), Number(16)))
    modular_vector_type = Array("Arrays.Modular_Vector", modular_type)

    range_type = RangeInteger("Arrays.Range_Integer", Number(1), Number(100),
                              Number(8))
    range_vector_type = Array("Arrays.Range_Vector", range_type)

    enum_type = Enumeration(
        "Arrays.Enumeration",
        {
            "ZERO": Number(0),
            "ONE": Number(1),
            "TWO": Number(2)
        },
        Number(8),
        False,
    )
    enum_vector_type = Array("Arrays.Enumeration_Vector", enum_type)

    av_enum_type = Enumeration(
        "Arrays.AV_Enumeration",
        {
            "AV_ZERO": Number(0),
            "AV_ONE": Number(1),
            "AV_TWO": Number(2)
        },
        Number(8),
        True,
    )
    av_enum_vector_type = Array("Arrays.AV_Enumeration_Vector", av_enum_type)

    structure = [
        Link(INITIAL, Field("Length")),
        Link(Field("Length"),
             Field("Modular_Vector"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Modular_Vector"), Field("Range_Vector"),
             length=Number(16)),
        Link(Field("Range_Vector"),
             Field("Enumeration_Vector"),
             length=Number(16)),
        Link(Field("Enumeration_Vector"),
             Field("AV_Enumeration_Vector"),
             length=Number(16)),
        Link(Field("AV_Enumeration_Vector"), FINAL),
    ]

    types = {
        Field("Length"): length_type,
        Field("Modular_Vector"): modular_vector_type,
        Field("Range_Vector"): range_vector_type,
        Field("Enumeration_Vector"): enum_vector_type,
        Field("AV_Enumeration_Vector"): av_enum_vector_type,
    }

    return Message("Arrays.Message", structure, types)
Exemplo n.º 4
0
def test_message_type_message() -> None:
    simple_structure = [
        Link(INITIAL, Field("Bar")),
        Link(Field("Bar"), Field("Baz")),
        Link(Field("Baz"), FINAL),
    ]

    simple_types = {
        Field("Bar"): ModularInteger("Message_Type.T", Number(256)),
        Field("Baz"): ModularInteger("Message_Type.T", Number(256)),
    }

    simple_message = Message("Message_Type.Simple_PDU", simple_structure, simple_types)

    structure = [
        Link(INITIAL, Field("Foo")),
        Link(Field("Foo"), Field("Bar"), LessEqual(Variable("Foo"), Number(30, 16))),
        Link(Field("Foo"), Field("Baz"), Greater(Variable("Foo"), Number(30, 16))),
        Link(Field("Bar"), Field("Baz")),
        Link(Field("Baz"), FINAL),
    ]

    types = {
        **simple_types,
        **{Field("Foo"): ModularInteger("Message_Type.T", Number(256))},
    }

    message = Message("Message_Type.PDU", structure, types)

    empty_message = Message("Message_Type.Empty_PDU", [], {})

    assert_messages_files(
        [f"{TESTDIR}/message_type.rflx"], [message, simple_message, empty_message]
    )
Exemplo n.º 5
0
 def test_type_name(self) -> None:
     t = ModularInteger("Package.Type_Name", Number(256))
     self.assertEqual(t.name, "Type_Name")
     self.assertEqual(t.package, "Package")
     with self.assertRaises(ModelError):
         ModularInteger("X", Number(256))
     with self.assertRaises(ModelError):
         ModularInteger("X.Y.Z", Number(256))
Exemplo n.º 6
0
def test_array_assign_incorrect_values(
    tlv: MessageValue, frame: MessageValue, array_type_foo: MessageValue, enum_value: EnumValue
) -> None:
    # pylint: disable=protected-access
    type_array = ArrayValue(Array("Test.Array", ModularInteger("Test.Mod_Int", Number(256))))
    msg_array = ArrayValue(Array("Test.MsgArray", tlv._type))

    intval = IntegerValue(ModularInteger("Test.Int", Number(256)))
    enum_value.assign("One")
    with pytest.raises(ValueError, match="cannot assign EnumValue to an array of ModularInteger"):
        type_array.assign([enum_value])

    tlv.set("Tag", "Msg_Data")
    with pytest.raises(
        ValueError,
        match='cannot assign message "Message" to array of messages: all messages must be valid',
    ):
        msg_array.assign([tlv])

    with pytest.raises(ValueError, match="cannot assign EnumValue to an array of Message"):
        msg_array.assign([enum_value])

    tlv.set("Tag", "Msg_Data")
    tlv.set("Length", 4)
    tlv.set("Value", b"\x00\x00\x00\x00")

    frame.set("Destination", 0)
    frame.set("Source", 0)
    frame.set("Type_Length_TPID", 47)
    frame.set("Type_Length", 1537)
    frame.set("Payload", bytes(46))

    with pytest.raises(ValueError, match='cannot assign "Frame" to an array of "Message"'):
        msg_array.assign([tlv, frame])

    with pytest.raises(
        ValueError,
        match="cannot parse nested messages in array of type TLV.Message: Error while setting "
        "value for field Tag: 'Number 0 is not a valid enum value'",
    ):
        msg_array.parse(Bitstring("0001111"))

    tlv.set("Tag", "Msg_Data")
    tlv._fields["Length"].typeval.assign(111111111111111, False)
    with pytest.raises(
        ValueError,
        match='cannot assign message "Message" to array of messages: all messages must be valid',
    ):
        msg_array.assign([tlv])
    assert msg_array.value == []

    intval.assign(5)
    array_type_foo.set("Length", 42)
    with pytest.raises(
        ValueError,
        match="invalid data length: input length is 8 while expected input length is 336",
    ):
        array_type_foo.set("Bytes", [intval])
Exemplo n.º 7
0
def test_array_preserve_value(enum_value: EnumValue) -> None:
    intval = IntegerValue(ModularInteger("Test.Int", Number(256)))
    intval.assign(1)
    enum_value.assign("One")
    type_array = ArrayValue(Array("Test.Array", ModularInteger("Test.Mod_Int", Number(256))))
    type_array.assign([intval])
    assert type_array.value == [intval]
    with pytest.raises(ValueError, match="cannot assign EnumValue to an array of ModularInteger"):
        type_array.assign([enum_value])
    assert type_array.value == [intval]
Exemplo n.º 8
0
def test_array_nested_values(array_type_foo: MessageValue) -> None:
    a = IntegerValue(ModularInteger("Array_Type.Byte_One", Number(256)))
    b = IntegerValue(ModularInteger("Array_Type.Byte_Two", Number(256)))
    c = IntegerValue(ModularInteger("Array_Type.Byte_Three", Number(256)))
    a.assign(5)
    b.assign(6)
    c.assign(7)
    byte_array = [a, b, c]
    array_type_foo.set("Length", 3)
    array_type_foo.set("Bytes", byte_array)
    assert array_type_foo.valid_message
    assert array_type_foo.bytestring == b"\x03\x05\x06\x07"
Exemplo n.º 9
0
def test_type_name() -> None:
    t = ModularInteger("Package.Type_Name", Number(256))
    assert t.name == "Type_Name"
    assert t.package == ID("Package")
    assert_type_error(
        ModularInteger("X", Number(256), Location((10, 20))),
        r'^<stdin>:10:20: model: error: unexpected format of type name "X"$',
    )
    assert_type_error(
        ModularInteger("X.Y.Z", Number(256), Location((10, 20))),
        '^<stdin>:10:20: model: error: unexpected format of type name "X.Y.Z"$',
    )
Exemplo n.º 10
0
def test_write_specification_file_multiple_packages_missing_deps(tmp_path: Path) -> None:
    t = ModularInteger("P::T", Number(256))
    u = mty.Sequence("R::U", element_type=t)
    u1 = mty.Sequence("Q::U1", element_type=t)
    v = ModularInteger("R::V", Number(65536))
    links = [
        Link(INITIAL, Field("Victor")),
        Link(Field("Victor"), Field("Uniform")),
        Link(Field("Uniform"), FINAL),
    ]
    fields = {Field("Victor"): v, Field("Uniform"): u}
    m = Message("R::M", links, fields)
    Model([u1, m, u, v]).write_specification_files(tmp_path)
    p_path, q_path, r_path = (tmp_path / Path(pkg + ".rflx") for pkg in ("p", "q", "r"))
    assert set(tmp_path.glob("*.rflx")) == {p_path, q_path, r_path}
    assert p_path.read_text() == textwrap.dedent(
        """\
        package P is

           type T is mod 256;

        end P;"""
    )
    assert q_path.read_text() == textwrap.dedent(
        """\
        with P;

        package Q is

           type U1 is sequence of P::T;

        end Q;"""
    )
    assert r_path.read_text() == textwrap.dedent(
        """\
        with P;

        package R is

           type V is mod 65536;

           type U is sequence of P::T;

           type M is
              message
                 Victor : R::V
                    then Uniform
                       with Size => Message'Last - Victor'Last;
                 Uniform : R::U;
              end message;

        end R;"""
    )
Exemplo n.º 11
0
    def test_pdu_fields_invalid_dupe(self) -> None:
        t1 = ModularInteger('T1', Number(2))
        t2 = ModularInteger('T2', Number(4))

        initial = InitialNode()
        n1 = Node('X', t1)
        n2 = Node('X', t2)

        initial.edges = [Edge(n1, TRUE)]
        n1.edges = [Edge(n2, TRUE)]
        n2.edges = [Edge(FINAL, TRUE)]

        with self.assertRaises(ModelError):
            PDU('Z', initial).fields()
Exemplo n.º 12
0
def test_array_type_spec() -> None:
    spec = {
        "Array_Type": Specification(
            ContextSpec([]),
            PackageSpec(
                "Array_Type",
                [
                    ModularInteger("__PACKAGE__.Byte", Number(256)),
                    ArraySpec("__PACKAGE__.Bytes", ReferenceSpec("__PACKAGE__.Byte")),
                    MessageSpec(
                        "__PACKAGE__.Foo",
                        [
                            Component(
                                "Length",
                                "Byte",
                                [Then("Bytes", UNDEFINED, Mul(Variable("Length"), Number(8)))],
                            ),
                            Component("Bytes", "Bytes"),
                        ],
                    ),
                    ArraySpec("__PACKAGE__.Bar", ReferenceSpec("__PACKAGE__.Foo")),
                ],
            ),
        )
    }
    assert_specifications_files([f"{TESTDIR}/array_type.rflx"], spec)
Exemplo n.º 13
0
def test_graph_object() -> None:
    f_type = ModularInteger("P::T", Pow(Number(2), Number(32)))
    m = Message(
        "P::M",
        structure=[Link(INITIAL, Field("X")),
                   Link(Field("X"), FINAL)],
        types={Field("X"): f_type},
    )
    g = create_message_graph(m)
    assert [(e.get_source(), e.get_destination()) for e in g.get_edges()] == [
        ("Initial", "intermediate_0"),
        ("intermediate_0", "X"),
        ("X", "intermediate_1"),
        ("intermediate_1", "Final"),
    ]
    assert [n.get_name() for n in g.get_nodes()] == [
        "graph",
        "edge",
        "node",
        "Initial",
        "X",
        "intermediate_0",
        "intermediate_1",
        "Final",
    ]
Exemplo n.º 14
0
def test_integer_type_spec() -> None:
    spec = {
        "Integer_Type": Specification(
            ContextSpec([]),
            PackageSpec(
                "Integer_Type",
                [
                    RangeInteger("__PACKAGE__.Page_Num", Number(1), Number(2000), Number(16)),
                    RangeInteger("__PACKAGE__.Line_Size", Number(0), Number(255), Number(8)),
                    ModularInteger("__PACKAGE__.Byte", Number(256)),
                    ModularInteger("__PACKAGE__.Hash_Index", Number(64)),
                ],
            ),
        )
    }
    assert_specifications_files([f"{TESTDIR}/integer_type.rflx"], spec)
Exemplo n.º 15
0
def test_aggregate_equal_array_invalid_length() -> None:
    magic = Field(ID("Magic", Location((3, 5))))
    structure = [
        Link(INITIAL, magic, length=Number(40, location=Location((19, 17)))),
        Link(
            magic,
            FINAL,
            condition=NotEqual(Variable("Magic"),
                               Aggregate(Number(1), Number(2)),
                               Location((17, 3))),
        ),
    ]
    types = {
        Field("Magic"):
        Array(
            "P.Arr",
            ModularInteger("P.Modular",
                           Number(128),
                           location=Location((66, 3)))),
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:17:3: model: error: contradicting condition in "P.M"\n'
        r'<stdin>:3:5: model: info: on path: "Magic"\n'
        r'<stdin>:17:3: model: info: unsatisfied "2 [*] Modular\'Length = Magic\'Length"\n'
        r'<stdin>:66:3: model: info: unsatisfied "Modular\'Length = 7"\n'
        r'<stdin>:19:17: model: info: unsatisfied "Magic\'Length = 40"',
    )
Exemplo n.º 16
0
def parse_type(string: str, location: int, tokens: ParseResults) -> Type:
    try:
        name = tokens[1]
        full_name = f"__PACKAGE__.{name}"
        if tokens[3] == "mod":
            return ModularInteger(full_name, *tokens[4:6])
        if tokens[3] == "range":
            tokens[6] = tokens[6]["size"]
            return RangeInteger(full_name, *tokens[4:7])
        if tokens[3] == "message":
            return MessageSpec(full_name, tokens[4])
        if tokens[3] == "null message":
            return MessageSpec(full_name, [])
        if tokens[3] == "(":
            elements = dict(tokens[4:-2])
            aspects = tokens[-1]
            if len(elements) < len(tokens[4:-2]):
                raise ModelError(f'"{name}" contains duplicate elements')
            if "always_valid" not in aspects:
                aspects["always_valid"] = False
            return Enumeration(full_name, elements, aspects["size"],
                               aspects["always_valid"])
        if tokens[3] == "new":
            return DerivationSpec(full_name, tokens[4])
        if tokens[3] == "array of":
            return Array(
                full_name,
                Reference(tokens[4] if "." in
                          tokens[4] else f"__PACKAGE__.{tokens[4]}"))
    except ModelError as e:
        raise ParseFatalException(string, location, e)
    raise ParseFatalException(string, location, "unexpected type")
Exemplo n.º 17
0
def create_tlv_message() -> Message:
    tag_type = Enumeration("TLV.Tag", {
        "Msg_Data": Number(1),
        "Msg_Error": Number(3)
    }, Number(2), False)
    length_type = ModularInteger("TLV.Length", Pow(Number(2), Number(14)))

    structure = [
        Link(INITIAL, Field("Tag")),
        Link(Field("Tag"), Field("Length"),
             Equal(Variable("Tag"), Variable("Msg_Data"))),
        Link(Field("Tag"), FINAL, Equal(Variable("Tag"),
                                        Variable("Msg_Error"))),
        Link(Field("Length"),
             Field("Value"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Value"), FINAL),
    ]

    types = {
        Field("Tag"): tag_type,
        Field("Length"): length_type,
        Field("Value"): Payload()
    }

    return Message("TLV.Message", structure, types)
Exemplo n.º 18
0
def test_dot_graph(tmp_path: Path) -> None:
    f_type = ModularInteger("P::T", Pow(Number(2), Number(32)))
    m = Message(
        "P::M",
        structure=[Link(INITIAL, Field("X")),
                   Link(Field("X"), FINAL)],
        types={Field("X"): f_type},
    )
    expected = """
        digraph "P::M" {
            graph [bgcolor="#00000000", pad="0.1", ranksep="0.1 equally", splines=true,
                   truecolor=true];
            edge [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", penwidth="2.5"];
            node [color="#6f6f6f", fillcolor="#009641", fontcolor="#ffffff", fontname=Arimo,
                  shape=box, style="rounded,filled", width="1.5"];
            Initial [fillcolor="#ffffff", label="", shape=circle, width="0.5"];
            X;
            intermediate_0 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0,
                            label="(⊤, 32, ⋆)", penwidth=0, style="", width=0];
            Initial -> intermediate_0 [arrowhead=none];
            intermediate_0 -> X [minlen=1];
            intermediate_1 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0,
                            label="(⊤, 0, ⋆)", penwidth=0, style="", width=0];
            X -> intermediate_1 [arrowhead=none];
            intermediate_1 -> Final [minlen=1];
            Final [fillcolor="#6f6f6f", label="", shape=circle, width="0.5"];
        }
        """

    assert_graph(create_message_graph(m), expected, tmp_path)
Exemplo n.º 19
0
def test_dot_graph_with_condition() -> None:
    f_type = ModularInteger("P.T", Pow(Number(2), Number(32)))
    m = Message(
        "P.M",
        structure=[
            Link(INITIAL, Field("F1")),
            Link(Field("F1"), FINAL, Greater(Variable("F1"), Number(100))),
        ],
        types={Field("F1"): f_type},
    )
    expected = """
        digraph "P.M" {
            graph [ranksep="0.8 equally", splines=ortho];
            edge [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code"];
            node [color="#6f6f6f", fillcolor="#009641", fontcolor="#ffffff", fontname=Arimo,
                  shape=box, style="rounded,filled", width="1.5"];
            Initial [fillcolor="#ffffff", label="", shape=circle, width="0.5"];
            F1;
            Initial -> F1 [xlabel="(⊤, 32, ⋆)"];
            F1 -> Final [xlabel="(F1 > 100, 0, ⋆)"];
            Final [fillcolor="#6f6f6f", label="", shape=circle, width="0.5"];
        }
        """

    assert_graph(Graph(m), expected)
Exemplo n.º 20
0
def test_message_multiple_duplicate_links() -> None:
    t = ModularInteger("P.T", Number(2))
    x = Field(ID("X", location=Location((1, 5))))
    y = Field(ID("Y", location=Location((2, 5))))

    structure = [
        Link(INITIAL, x),
        Link(x, y),
        Link(x, FINAL, location=Location((3, 16))),
        Link(x, FINAL, location=Location((4, 18))),
        Link(y, FINAL, location=Location((5, 20))),
        Link(y, FINAL, location=Location((6, 22))),
    ]

    types = {Field("X"): t, Field("Y"): t}

    assert_message_model_error(
        structure,
        types,
        f'^<stdin>:1:5: model: error: duplicate link from "X" to "{FINAL.name}"\n'
        f"<stdin>:3:16: model: info: duplicate link\n"
        f"<stdin>:4:18: model: info: duplicate link\n"
        f'<stdin>:2:5: model: error: duplicate link from "Y" to "{FINAL.name}"\n'
        f"<stdin>:5:20: model: info: duplicate link\n"
        f"<stdin>:6:22: model: info: duplicate link",
    )
Exemplo n.º 21
0
    def test_field_coverage_2(self) -> None:
        foo_type = ModularInteger("P.Foo", Pow(Number(2), Number(32)))
        structure = [
            Link(INITIAL, Field("F1")),
            Link(Field("F1"), Field("F2")),
            Link(Field("F2"), Field("F4"), Greater(Variable("F1"),
                                                   Number(100))),
            Link(
                Field("F2"),
                Field("F3"),
                LessEqual(Variable("F1"), Number(100)),
                first=Add(Last("F2"), Number(64)),
            ),
            Link(Field("F3"), Field("F4")),
            Link(Field("F4"), FINAL),
        ]

        types = {
            Field("F1"): foo_type,
            Field("F2"): foo_type,
            Field("F3"): foo_type,
            Field("F4"): foo_type,
        }
        with mock.patch("rflx.model.Message._Message__verify_conditions",
                        lambda x: None):
            with self.assertRaisesRegex(
                    ModelError,
                    "^path F1 -> F2 -> F3 -> F4 does not cover whole message"):
                Message("P.M", structure, types)
Exemplo n.º 22
0
def parse_type(string: str, location: int, tokens: list) -> Type:
    try:
        if tokens[3] == 'mod':
            return ModularInteger(tokens[1], *tokens[4:6])
        if tokens[3] == 'range':
            tokens[6] = tokens[6]['size']
            return RangeInteger(tokens[1], *tokens[4:7])
        if tokens[3] == 'message':
            return Message(tokens[1], tokens[4])
        if tokens[3] == '(':
            elements = dict(tokens[4:-2])
            aspects = tokens[-1]
            if len(elements) < len(tokens[4:-2]):
                raise ModelError(f'"{tokens[1]}" contains duplicate elements')
            if 'always_valid' not in aspects:
                aspects['always_valid'] = False
            return Enumeration(tokens[1], elements, aspects['size'],
                               aspects['always_valid'])
        if tokens[3] == 'new':
            if len(tokens) == 7:
                tokens.append(TRUE)
            return Refinement(tokens[1], *tokens[4:])
        if tokens[3] == 'array of':
            return Array(tokens[1], tokens[4])
    except ModelError as e:
        raise ParseFatalException(string, location, e)
    raise ParseFatalException(string, location, 'unexpected type')
Exemplo n.º 23
0
def test_type_derivation_spec() -> None:
    assert_specifications_string(
        """
            package Test is
               type T is mod 256;
               type Foo is
                  message
                     N : T;
                  end message;
               type Bar is new Foo;
            end Test;
        """,
        {
            "Test": Specification(
                ContextSpec([]),
                PackageSpec(
                    "Test",
                    [
                        ModularInteger("__PACKAGE__.T", Number(256)),
                        MessageSpec("__PACKAGE__.Foo", [Component("N", "T")]),
                        DerivationSpec("__PACKAGE__.Bar", "Foo"),
                    ],
                ),
            )
        },
    )
Exemplo n.º 24
0
def test_opaque_not_byte_aligned_dynamic() -> None:
    with pytest.raises(
            RecordFluxError,
            match=
            r'^<stdin>:44:3: model: error: opaque field "O2" not aligned to'
            r" 8 bit boundary [(]L1 -> O1 -> L2 -> O2[)]",
    ):
        o2 = Field(ID("O2", location=Location((44, 3))))
        Message(
            "P.M",
            [
                Link(INITIAL, Field("L1")),
                Link(
                    Field("L1"),
                    Field("O1"),
                    length=Variable("L1"),
                    condition=Equal(Mod(Variable("L1"), Number(8)), Number(0)),
                ),
                Link(Field("O1"), Field("L2")),
                Link(Field("L2"), o2, length=Number(128)),
                Link(o2, FINAL),
            ],
            {
                Field("L1"): MODULAR_INTEGER,
                Field("L2"): ModularInteger("P.T", Number(4)),
                Field("O1"): Opaque(),
                o2: Opaque(),
            },
        )
Exemplo n.º 25
0
def test_array_aggregate_out_of_range() -> None:
    array_type = Array("P.Array", ModularInteger("P.Element", Number(64)))

    f = Field("F")
    with pytest.raises(
            RecordFluxError,
            match=
            r"^<stdin>:44:3: model: error: aggregate element out of range 0 .. 63",
    ):
        Message(
            "P.M",
            [
                Link(INITIAL, f, length=Number(18)),
                Link(
                    f,
                    FINAL,
                    condition=Equal(
                        Variable("F"),
                        Aggregate(Number(1), Number(2),
                                  Number(64, location=Location((44, 3)))),
                    ),
                ),
            ],
            {Field("F"): array_type},
        )
Exemplo n.º 26
0
def test_type_refinement_spec() -> None:
    spec = {
        "Message_Type": Specification(
            ContextSpec([]),
            PackageSpec(
                "Message_Type",
                [
                    ModularInteger("__PACKAGE__.T", Number(256)),
                    MessageSpec(
                        "__PACKAGE__.PDU",
                        [
                            Component(
                                "Foo",
                                "T",
                                [
                                    Then(
                                        "Bar",
                                        UNDEFINED,
                                        UNDEFINED,
                                        LessEqual(Variable("Foo"), Number(30, 16)),
                                    ),
                                    Then(
                                        "Baz",
                                        UNDEFINED,
                                        UNDEFINED,
                                        Greater(Variable("Foo"), Number(30, 16)),
                                    ),
                                ],
                            ),
                            Component("Bar", "T"),
                            Component("Baz", "T"),
                        ],
                    ),
                    MessageSpec(
                        "__PACKAGE__.Simple_PDU", [Component("Bar", "T"), Component("Baz", "T")],
                    ),
                    MessageSpec("__PACKAGE__.Empty_PDU", []),
                ],
            ),
        ),
        "Type_Refinement": Specification(
            ContextSpec(["Message_Type"]),
            PackageSpec(
                "Type_Refinement",
                [
                    RefinementSpec(
                        "Message_Type.Simple_PDU",
                        "Bar",
                        "Message_Type.PDU",
                        Equal(Variable("Baz"), Number(42)),
                    ),
                    RefinementSpec("Message_Type.PDU", "Bar", "Message_Type.Simple_PDU"),
                ],
            ),
        ),
    }
    assert_specifications_files(
        [f"{TESTDIR}/message_type.rflx", f"{TESTDIR}/type_refinement.rflx"], spec
    )
Exemplo n.º 27
0
def modular_integers(
    draw: Draw,
    unique_identifiers: ty.Generator[ID, None, None],
    multiple_of_8: bool = False,
    align_to_8: int = 0,
) -> ModularInteger:
    return ModularInteger(
        next(unique_identifiers),
        expr.Pow(expr.Number(2), expr.Number(draw(sizes(multiple_of_8, align_to_8)))),
    )
Exemplo n.º 28
0
def test_name_conflict_between_literal_and_type() -> None:
    assert_model_error(
        [
            Enumeration(
                "P::T",
                [
                    (ID("FOO", Location((3, 27))), Number(1)),
                    (ID("BAR", Location((3, 32))), Number(2)),
                ],
                Number(1),
                always_valid=False,
            ),
            ModularInteger("P::Foo", Number(256), Location((4, 16))),
            ModularInteger("P::Bar", Number(256), Location((5, 16))),
        ],
        r'<stdin>:3:27: model: error: literal "FOO" conflicts with type declaration\n'
        r'<stdin>:4:16: model: info: conflicting type "P::Foo"\n'
        r'<stdin>:3:32: model: error: literal "BAR" conflicts with type declaration\n'
        r'<stdin>:5:16: model: info: conflicting type "P::Bar"',
    )
Exemplo n.º 29
0
def test_name_conflict_between_literal_and_type() -> None:
    assert_model_error(
        [
            Enumeration(
                "P.T",
                [
                    (ID("Foo", Location((3, 27))), Number(1)),
                    (ID("Bar", Location((3, 32))), Number(2)),
                ],
                Number(1),
                False,
            ),
            ModularInteger("T.Foo", Number(256), Location((4, 16))),
            ModularInteger("T.Bar", Number(256), Location((5, 16))),
        ],
        r'<stdin>:3:32: model: error: literal conflicts with type "Bar"\n'
        r"<stdin>:5:16: model: info: conflicting type declaration\n"
        r'<stdin>:3:27: model: error: literal conflicts with type "Foo"\n'
        r"<stdin>:4:16: model: info: conflicting type declaration",
    )
Exemplo n.º 30
0
    def test_message_superfluous_type(self) -> None:
        t = ModularInteger("P.T", Number(2))

        structure = [
            Link(INITIAL, Field("X")),
            Link(Field("X"), FINAL),
        ]

        types = {Field("X"): t, Field("Y"): t}

        with self.assertRaisesRegex(ModelError, '^superfluous field "Y" in field types of "P.M"$'):
            Message("P.M", structure, types)