def test_startsCurrentPeriod_endsCurrentPeriod_psiNotSatisfiable(self):
        """ Testing exit label 4 """
        chk1 = check(self.system.port) < 100
        chk2 = check(self.system.secondPort) == 5
        formula = tctl.EU(chk1, chk2)
        formula.interval > 2
        formula.interval < 6  # interval is completely in the period

        # prepare mocks
        mc = ModelChecker(self.ss)
        original_check = mc.check  # copy reference, so we can now safely mock the potentially recursive call
        mc.is_satisfiable = mock.MagicMock(name="is_satisfiable",
                                           return_value=False)
        self.ss.successors = mock.MagicMock(return_value=[
            mock.sentinel.successor, mock.sentinel.othersuccessor,
            mock.sentinel.thirdsuccessor
        ])
        mc.check = mock.MagicMock(name="check",
                                  side_effect=[False, [13, 22], False])

        # action
        result_trace = original_check(formula)

        # assert
        self.assertFalse(
            result_trace,
            "We correctly exited with False, since psi is not reachable and the interval ends before maxdt"
        )
        mc.check.assert_not_called()
Exemple #2
0
    def test_check_EU(self):
        tl = check(self.system.timer) < 5
        tvl = check(self.system.timer) <= 3
        formula = tctl.EU(tl, tvl)

        mc = PointwiseModelChecker(self.ss)

        # solution = mc.check(formula)
        # print(solution)
        crestKripke = mc.make_CREST_Kripke(formula)
        nodes = mc.is_satisfiable(formula, crestKripke)
    def test_startsCurrentPeriod_endsCurrentPeriod_psiSatisfiable_phiNOTValidUntilPsi(
            self):
        """ Testing exit label 9) """
        chk1 = check(self.system.port) < 100
        chk2 = check(self.system.secondPort) == 5
        formula = tctl.EU(chk1, chk2)
        formula.interval > 2
        formula.interval < 6  # interval ends after this period

        # prepare mocks
        self.ss.successors = mock.MagicMock(return_value=[
            mock.sentinel.successor, mock.sentinel.othersuccessor,
            mock.sentinel.thirdsuccessor
        ])
        mc = ModelChecker(self.ss)
        original_check = mc.check  # copy reference, so we can now safely mock the potentially recursive call
        mc.is_satisfiable = mock.MagicMock(
            name="is_satisfiable",
            return_value=[5])  # psi is satisfied after 5 units
        mc.is_valid = mock.MagicMock(name="is_valid", return_value=[
            3
        ])  # is valid produces a counter example (when it's invalid)

        # action
        result_trace = original_check(formula)

        # assert that the resulting trace is correct
        self.assertFalse(
            result_trace,
            "Assert that if the first formula is invalid in this period, the result is False"
        )

        # assert that is valid was called on the formula
        mc.is_valid.assert_called_once()
        (formula,
         systemstate), kwargs = mc.is_valid.call_args  # get the last callargs
        self.assertEqual(
            formula.interval.start, 0,
            "phi was checked for validity from the start of the period")
        self.assertEqual(
            formula.interval.end, 5,
            "The phi validity check was called with the correct interval end")
        self.assertEqual(
            systemstate, self.ss.graph["root"],
            "The phi validity check was called on the correct state")
    def test_startsCurrentPeriod_endsFuturePeriod_phiNotValid(self):
        """ Testing exit label 5 """
        chk1 = check(self.system.port) < 100
        chk2 = check(self.system.secondPort) == 5
        formula = tctl.EU(chk1, chk2)
        formula.interval > 2
        formula.interval < 23  # interval ends after this period

        # prepare mocks
        mc = ModelChecker(self.ss)
        original_check = mc.check  # copy reference, so we can now safely mock the potentially recursive call
        mc.is_satisfiable = mock.MagicMock(name="is_satisfiable",
                                           return_value=False)
        mc.is_valid = mock.MagicMock(name="is_valid", return_value=False)
        mc.check = mock.MagicMock(name="check")

        # action (on original check)
        result_trace = original_check(formula)

        # assert that the return value was correct
        self.assertFalse(
            result_trace,
            "Assert that if the first formula is invalid in this period, the result is False"
        )

        # assert that is_valid was called with the correct values
        mc.is_valid.assert_called_once()
        (formula,
         systemstate), kwargs = mc.is_valid.call_args  # get the last callargs
        self.assertEqual(
            formula.interval.end, 7,
            "The subformula validity check was called with the correct interval end"
        )
        self.assertEqual(
            systemstate, self.ss.graph["root"],
            "The subformula validity check was called on the correct state")

        # assert that the check was not called (we exited early)
        mc.check.assert_not_called()
Exemple #5
0
    def test_calling_correct_procedure(self):
        """
        This testroutine mocks the procedure implementations and
        verifies that the correct mock is called, depending on the formula.
        """
        mc = PointwiseModelChecker(self.ss)

        tl = check(self.system.timer) < 5
        tvl = check(self.system.timer) <= 3

        paramlist = {
            (tctl.EU(tl, tvl), "Sat_EU"),
            (tctl.EG(tl), "Sat_EG"),
            (tctl.EU(tl, tvl, tctl.Interval(end=25,
                                            end_op=operator.le)), "Sat_EUb"),
            (tctl.EU(tl, tvl, tctl.Interval(end=25,
                                            end_op=operator.lt)), "Sat_EUb"),
            (tctl.EU(tl, tvl, tctl.Interval(start=5,
                                            start_op=operator.ge)), "Sat_EUa"),
            (tctl.EU(tl, tvl, tctl.Interval(start=5,
                                            start_op=operator.gt)), "Sat_EUa"),
            (tctl.EU(
                tl, tvl,
                tctl.Interval(start=5,
                              start_op=operator.ge,
                              end=25,
                              end_op=operator.le)), "Sat_EUab"),
            (tctl.EU(
                tl, tvl,
                tctl.Interval(start=5,
                              start_op=operator.gt,
                              end=25,
                              end_op=operator.le)), "Sat_EUab"),
            (tctl.EU(
                tl, tvl,
                tctl.Interval(start=5,
                              start_op=operator.ge,
                              end=25,
                              end_op=operator.lt)), "Sat_EUab"),
            (tctl.EU(
                tl, tvl,
                tctl.Interval(start=5,
                              start_op=operator.gt,
                              end=25,
                              end_op=operator.lt)), "Sat_EUab"),
            (tctl.AU(
                tl, tvl,
                tctl.Interval(start=0,
                              start_op=operator.gt,
                              end=math.inf,
                              end_op=operator.lt)), "Sat_AU0"),
            (tctl.AU(
                tl, tvl,
                tctl.Interval(start=0,
                              start_op=operator.gt,
                              end=25,
                              end_op=operator.le)), "Sat_AU0"),
            (tctl.AU(
                tl, tvl,
                tctl.Interval(start=0,
                              start_op=operator.gt,
                              end=25,
                              end_op=operator.lt)), "Sat_AU0"),
        }

        for formula, method in paramlist:
            with self.subTest():
                setattr(mc, method, mock.MagicMock())
                res = mc.is_satisfiable(formula, None)
                getattr(mc, method).assert_called_once()
    def test_startsCurrentPeriod_endsFuturePeriod_secondSuccessorSatisfiable_doesNotCallThird(
            self):
        """ Testing exit label 6) """
        chk1 = check(self.system.port) < 100
        chk2 = check(self.system.secondPort) == 5
        formula = tctl.EU(chk1, chk2)
        formula.interval > 2
        formula.interval < 23  # interval ends after this period

        # prepare mocks
        self.ss.successors = mock.MagicMock(return_value=[
            mock.sentinel.successor, mock.sentinel.othersuccessor,
            mock.sentinel.thirdsuccessor
        ])
        mc = ModelChecker(self.ss)
        original_check = mc.check  # copy reference, so we can now safely mock the potentially recursive call
        mc.is_satisfiable = mock.MagicMock(name="is_satisfiable",
                                           return_value=False)
        mc.is_valid = mock.MagicMock(return_value=True)
        mc.check = mock.MagicMock(side_effect=[False, [13, 22], False])

        # action
        result_trace = original_check(formula)

        # assert that the resulting trace is correct
        self.assertEqual(
            result_trace, [7, 13, 22],
            "Assert that if the first formula is invalid in this period, the result is False"
        )

        # assert that is valid was called on the formula
        mc.is_valid.assert_called_once()
        (formula,
         systemstate), kwargs = mc.is_valid.call_args  # get the last callargs
        self.assertEqual(
            formula.interval.end, 7,
            "The subformula validity check was called with the correct interval end"
        )
        self.assertEqual(
            systemstate, self.ss.graph["root"],
            "The subformula validity check was called on the correct state")

        # assert that a modified version of the formula (-= maxdt) was called on each successor
        self.assertEqual(
            mc.check.call_count, 2,
            "Check recursed on each of the successors, because both returned False"
        )

        (formula, systemstate
         ), kwargs = mc.check.call_args_list[0]  # get the last callargs
        self.assertEqual(
            formula.interval.start, -5,
            "The recursion check was called with the correct interval start")
        self.assertEqual(
            formula.interval.end, 16,
            "The recursion check was called with the correct interval end")
        self.assertEqual(
            systemstate, mock.sentinel.successor,
            "The recursion check was called on the correct state")

        (formula, systemstate
         ), kwargs = mc.check.call_args_list[1]  # get the last callargs
        self.assertEqual(
            formula.interval.start, -5,
            "The recursion check was called with the correct interval start")
        self.assertEqual(
            formula.interval.end, 16,
            "The recursion check was called with the correct interval end")
        self.assertEqual(
            systemstate, mock.sentinel.othersuccessor,
            "The recursion check was called on the correct state")
Exemple #7
0
 def test_U_operators_filter_Boolean(self):
     eu = tctl.EU(True, False)
     self.assertCountEqual(eu.get_propositions(), [])
Exemple #8
0
    def test_U_operators(self):
        ap = tctl.AtomicProposition(None)
        ap2 = tctl.AtomicProposition(None)

        eu = tctl.EU(ap, ap2)
        self.assertCountEqual(eu.get_propositions(), [ap, ap2])