Example #1
0
def test_slice_simplified() -> None:
    assert_equal(
        Slice(
            Variable("Buffer"), First("Buffer"), Add(Last("Buffer"), Add(Number(21), Number(21))),
        ).simplified(),
        Slice(Variable("Buffer"), First("Buffer"), Add(Last("Buffer"), Number(42))),
    )
Example #2
0
def test_number_ge() -> None:
    # pylint: disable=unneeded-not
    assert not Number(1) >= Number(2)
    assert Number(2) >= Number(2)
    assert Number(3) >= Number(2)
    assert not Variable("X") >= Number(2)
    assert not Number(2) >= Variable("X")
Example #3
0
 def setter_postconditions(message: Message,
                           field: Field) -> Sequence[Expr]:
     return [
         *[
             Call("Invalid", [Variable("Ctx"),
                              Variable(p.affixed_name)])
             for p in message.successors(field) if p != FINAL
         ],
         *common.valid_path_to_next_field_condition(message, field),
         *[
             Equal(e, Old(e)) for e in [
                 Variable("Ctx.Buffer_First"),
                 Variable("Ctx.Buffer_Last"),
                 Variable("Ctx.First"),
                 Call("Predecessor",
                      [Variable("Ctx"),
                       Variable(field.affixed_name)]),
                 Call("Valid_Next",
                      [Variable("Ctx"),
                       Variable(field.affixed_name)]),
             ] + [
                 Call(f"Get_{p.name}", [Variable("Ctx")])
                 for p in message.definite_predecessors(field)
                 if isinstance(message.types[p], Scalar)
             ]
         ],
     ]
Example #4
0
def test_number_lt() -> None:
    # pylint: disable=unneeded-not
    assert Number(1) < Number(2)
    assert not Number(2) < Number(2)
    assert not Number(3) < Number(2)
    assert not Variable("X") < Number(2)
    assert not Number(2) < Variable("X")
Example #5
0
 def invalid_successors_invariant() -> Expr:
     return AndThen(
         *[
             If(
                 [
                     (
                         AndThen(
                             *[
                                 Call(
                                     "Invalid",
                                     [Indexed(Variable("Cursors"), Variable(p.affixed_name))],
                                 )
                                 for p in message.direct_predecessors(f)
                             ]
                         ),
                         Call(
                             "Invalid", [Indexed(Variable("Cursors"), Variable(f.affixed_name))],
                         ),
                     )
                 ]
             )
             for f in message.fields
             if f not in message.direct_successors(INITIAL)
         ]
     )
Example #6
0
 def assign(self, value: str, check: bool = True) -> None:
     prefixed_value = (
         ID(value) if value.startswith(str(self._type.package))
         or not self.__imported or self.__builtin else self._type.package *
         value)
     if Variable(prefixed_value) not in self.literals:
         raise KeyError(f"{value} is not a valid enum value")
     r = (And(*self._type.constraints(
         "__VALUE__", check, not self.__imported)).substituted(
             mapping={
                 **self.literals,
                 **{
                     Variable("__VALUE__"):
                     self._type.literals[prefixed_value.name]
                 },
                 **{
                     Length("__VALUE__"): self._type.size
                 },
             }).simplified())
     assert r == TRUE
     self._value = (
         str(prefixed_value) if self.__imported and not self.__builtin else
         str(prefixed_value.name),
         self._type.literals[prefixed_value.name],
     )
Example #7
0
 def test_pow_simplified(self) -> None:
     self.assertEqual(Pow(Variable("X"), Number(1)).simplified(), Pow(Variable("X"), Number(1)))
     self.assertEqual(
         Pow(Variable("X"), Add(Number(1), Number(1))).simplified(),
         Pow(Variable("X"), Number(2)),
     )
     self.assertEqual(Pow(Number(6), Number(2)).simplified(), Number(36))
Example #8
0
 def test_mod_simplified(self) -> None:
     self.assertEqual(Mod(Variable("X"), Number(1)).simplified(), Mod(Variable("X"), Number(1)))
     self.assertEqual(
         Mod(Variable("X"), Add(Number(1), Number(1))).simplified(),
         Mod(Variable("X"), Number(2)),
     )
     self.assertEqual(Mod(Number(6), Number(2)).simplified(), Number(0))
Example #9
0
def test_merge_message_simple_derived() -> None:
    assert_equal(
        deepcopy(M_SMPL_REF_DERI).merged(),
        UnprovenDerivedMessage(
            "P.Smpl_Ref_Deri",
            M_SMPL_REF,
            [
                Link(INITIAL, Field("NR_F1"), length=Number(16)),
                Link(Field("NR_F3"), FINAL,
                     Equal(Variable("NR_F3"), Variable("P.ONE"))),
                Link(Field("NR_F4"), FINAL),
                Link(Field("NR_F1"), Field("NR_F2")),
                Link(
                    Field("NR_F2"),
                    Field("NR_F3"),
                    LessEqual(Variable("NR_F2"), Number(100)),
                    first=First("NR_F2"),
                ),
                Link(
                    Field("NR_F2"),
                    Field("NR_F4"),
                    GreaterEqual(Variable("NR_F2"), Number(200)),
                    first=First("NR_F2"),
                ),
            ],
            {
                Field("NR_F1"): Opaque(),
                Field("NR_F2"): deepcopy(MODULAR_INTEGER),
                Field("NR_F3"): deepcopy(ENUMERATION),
                Field("NR_F4"): deepcopy(RANGE_INTEGER),
            },
        ),
    )
Example #10
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)
Example #11
0
def test_dot_graph_with_double_edge() -> 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))),
            Link(Field("F1"), FINAL, Less(Variable("F1"), Number(50))),
        ],
        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, ⋆)"];
            F1 -> Final [xlabel="(F1 < 50, 0, ⋆)"];
            Final [fillcolor="#6f6f6f", label="", shape=circle, width="0.5"];
        }
        """

    assert_graph(Graph(m), expected)
Example #12
0
 def constraints(self, name: str, proof: bool = False) -> Expr:
     if proof:
         return And(
             And(*[Equal(Variable(l), v) for l, v in self.literals.items()]),
             Or(*[Equal(Variable(name), Variable(l)) for l in self.literals.keys()]),
         )
     return TRUE
Example #13
0
 def field_value(field: Field, field_type: Type) -> Expr:
     if isinstance(field_type, Enumeration):
         if public:
             return Call(
                 target_type, [Call("To_Base", [Call(f"Get_{field.name}", [Variable("Ctx")])])],
             )
         return Call(
             target_type,
             [
                 Selected(
                     Indexed(cursors, Variable(field.affixed_name)), f"Value.{field.name}_Value"
                 )
             ],
         )
     if isinstance(field_type, Scalar):
         if public:
             return Call(target_type, [Call(f"Get_{field.name}", [Variable("Ctx")])])
         return Call(
             target_type,
             [
                 Selected(
                     Indexed(cursors, Variable(field.affixed_name)), f"Value.{field.name}_Value"
                 )
             ],
         )
     if isinstance(field_type, Composite):
         return Variable(field.name)
     assert False, f'unexpected type "{type(field_type).__name__}"'
     return UNDEFINED
Example #14
0
    def create_structural_valid_function() -> UnitPart:
        specification = FunctionSpecification(
            "Structural_Valid",
            "Boolean",
            [Parameter(["Ctx"], "Context"),
             Parameter(["Fld"], "Field")],
        )

        return UnitPart(
            [SubprogramDeclaration(specification)],
            [
                ExpressionFunctionDeclaration(
                    specification,
                    And(
                        Or(*[
                            Equal(
                                Selected(
                                    Indexed(Variable("Ctx.Cursors"),
                                            Variable("Fld")), "State"),
                                Variable(s),
                            ) for s in ("S_Valid", "S_Structural_Valid")
                        ])),
                )
            ],
        )
Example #15
0
def test_exclusive_conflict() -> None:
    f1 = Field(ID("F1", Location((8, 4))))
    structure = [
        Link(INITIAL, f1),
        Link(f1,
             FINAL,
             condition=Greater(Variable("F1"), Number(50), Location((10, 5)))),
        Link(f1,
             Field("F2"),
             condition=Less(Variable("F1"), Number(80), Location((11, 7)))),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): RANGE_INTEGER,
        Field("F2"): RANGE_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:8:4: model: error: conflicting conditions for field "F1"\n'
        r"<stdin>:10:5: model: info: condition 0 [(]F1 -> Final[)]: F1 > 50\n"
        r"<stdin>:11:7: model: info: condition 1 [(]F1 -> F2[)]: F1 < 80"
        r"$",
    )
Example #16
0
def test_conditionally_unreachable_field_outgoing_multi() -> None:
    f2 = Field(ID("F2", Location((90, 12))))
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"), f2,
             LessEqual(Variable("F1"), Number(32), Location((66, 3)))),
        Link(Field("F1"), Field("F3"), Greater(Variable("F1"), Number(32))),
        Link(
            f2,
            Field("F3"),
            And(
                Greater(Variable("F1"), Number(32)),
                LessEqual(Variable("F1"), Number(48)),
                location=Location((22, 34)),
            ),
        ),
        Link(f2, FINAL, Greater(Variable("F1"), Number(48))),
        Link(Field("F3"), FINAL),
    ]
    types = {
        Field("F1"): MODULAR_INTEGER,
        Field("F2"): MODULAR_INTEGER,
        Field("F3"): MODULAR_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:90:12: model: error: unreachable field "F2" in "P.M"\n'
        r"<stdin>:90:12: model: info: path 0 [(]F1 -> F2[)]:\n"
        r'<stdin>:66:3: model: info: unsatisfied "F1 <= 32"\n'
        r'<stdin>:90:12: model: info: unsatisfied "[(]F1 > 32 and F1 <= 48[)] or F1 > 48"',
    )
Example #17
0
def test_no_path_to_final_transitive() -> None:
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"), Field("F2")),
        Link(Field("F2"), Field("F3"), Greater(Variable("F1"), Number(100))),
        Link(Field("F3"), FINAL),
        Link(Field("F2"), Field("F4"), LessEqual(Variable("F1"), Number(100))),
        Link(Field("F4"), Field("F5")),
        Link(Field("F5"), Field("F6")),
    ]

    types = {
        Field("F1"): MODULAR_INTEGER,
        Field("F2"): MODULAR_INTEGER,
        Field("F3"): MODULAR_INTEGER,
        Field("F4"): MODULAR_INTEGER,
        Field("F5"): MODULAR_INTEGER,
        Field("F6"): MODULAR_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'model: error: no path to FINAL for field "F4" in "P.M"\n'
        r'model: error: no path to FINAL for field "F5" in "P.M"\n'
        r'model: error: no path to FINAL for field "F6" in "P.M"'
        r"$",
    )
Example #18
0
def test_field_coverage_2(monkeypatch: Any) -> None:
    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"): MODULAR_INTEGER,
        Field("F2"): MODULAR_INTEGER,
        Field("F3"): MODULAR_INTEGER,
        Field("F4"): MODULAR_INTEGER,
    }
    monkeypatch.setattr(Message, "_AbstractMessage__verify_conditions",
                        lambda x: None)
    assert_message_model_error(
        structure,
        types,
        r"^"
        r"model: error: path does not cover whole message\n"
        r'model: info: on path: "F1"\n'
        r'model: info: on path: "F2"\n'
        r'model: info: on path: "F3"\n'
        r'model: info: on path: "F4"'
        r"$",
    )
Example #19
0
def test_no_contradiction_multi() -> None:
    structure = [
        Link(INITIAL, Field("F0")),
        Link(Field("F0"),
             Field("F1"),
             condition=Equal(Variable("F0"), Number(1))),
        Link(Field("F0"),
             Field("F2"),
             condition=Equal(Variable("F0"), Number(2))),
        Link(Field("F1"), Field("F3")),
        Link(Field("F2"), Field("F3")),
        Link(Field("F3"),
             Field("F4"),
             condition=Equal(Variable("F0"), Number(1))),
        Link(Field("F3"),
             Field("F5"),
             condition=Equal(Variable("F0"), Number(2))),
        Link(Field("F4"), FINAL),
        Link(Field("F5"), FINAL),
    ]
    types = {
        Field("F0"): RANGE_INTEGER,
        Field("F1"): RANGE_INTEGER,
        Field("F2"): RANGE_INTEGER,
        Field("F3"): RANGE_INTEGER,
        Field("F4"): RANGE_INTEGER,
        Field("F5"): RANGE_INTEGER,
    }
    Message("P.M", structure, types)
Example #20
0
 def test_term_simplified(self) -> None:
     self.assertEqual(
         Add(
             Mul(Number(1), Number(6)), Sub(Variable("X"), Number(10)), Add(Number(1), Number(3))
         ).simplified(),
         Variable("X"),
     )
Example #21
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]
    )
Example #22
0
    def create_verify_message_procedure(
            message: Message, context_invariant: Sequence[Expr]) -> UnitPart:
        specification = ProcedureSpecification(
            "Verify_Message", [InOutParameter(["Ctx"], "Context")])

        return UnitPart(
            [
                SubprogramDeclaration(
                    specification,
                    [
                        Postcondition(
                            And(
                                Equal(
                                    Call("Has_Buffer", [Variable("Ctx")]),
                                    Old(Call("Has_Buffer", [Variable("Ctx")])),
                                ),
                                *context_invariant,
                            )),
                    ],
                )
            ],
            [
                SubprogramBody(
                    specification,
                    [],
                    [
                        CallStatement(
                            "Verify",
                            [Variable("Ctx"),
                             Variable(f.affixed_name)]) for f in message.fields
                    ],
                )
            ],
        )
Example #23
0
def test_ass_expr_findall() -> None:
    assert_equal(
        And(Equal(Variable("X"), Number(1)), Variable("Y"), Number(2)).findall(
            lambda x: isinstance(x, Number)
        ),
        [Number(1), Number(2)],
    )
Example #24
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)
Example #25
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(),
            },
        )
Example #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
    )
Example #27
0
def test_value_enum(enum_value: EnumValue) -> None:
    assert enum_value.literals == {
        Variable("One"): Number(1),
        Variable("Test.One"): Number(1),
        Variable("Two"): Number(2),
        Variable("Test.Two"): Number(2),
    }
    assert not enum_value.initialized
Example #28
0
 def composite_setter_postconditions(self, message: Message,
                                     field: Field) -> Sequence[Expr]:
     return [
         Call("Has_Buffer", [Variable("Ctx")]),
         *self.setter_postconditions(message, field),
         Call("Structural_Valid",
              [Variable("Ctx"),
               Variable(field.affixed_name)]),
     ]
Example #29
0
 def field_length(field: Field) -> Expr:
     if public:
         return Call("Field_Length", [Variable("Ctx"), Variable(field.affixed_name)])
     return Add(
         Sub(
             Selected(Indexed(cursors, Variable(field.affixed_name)), "Last"),
             Selected(Indexed(cursors, Variable(field.affixed_name)), "First"),
         ),
         Number(1),
     )
Example #30
0
 def field_value(field: Field) -> Expr:
     if public:
         return Call(f"Get_{field.name}", [Variable("Ctx")])
     return Selected(
         Indexed(
             Variable("Ctx.Cursors" if not embedded else "Cursors"),
             Variable(field.affixed_name),
         ),
         f"Value.{field.name}_Value",
     )