Esempio n. 1
0
    class DemoStateMachine(stateful.RuleBasedStateMachine):
        Things = stateful.Bundle("things")
        Stuff = stateful.Bundle("stuff")
        StuffAndThings = Things | Stuff

        @stateful.rule(target=Things, name=st.text())
        def create_thing(self, name):
            return name

        @stateful.rule(target=Stuff, name=st.text())
        def create_stuff(self, name):
            return name

        @stateful.rule(item=StuffAndThings)
        def do(self, item):
            return
Esempio n. 2
0
class DemoStateMachine(stateful.RuleBasedStateMachine):
    Stuff = stateful.Bundle("stuff")

    @stateful.rule(target=Stuff, name=st.text())
    def create_stuff(self, name):
        return name

    @stateful.rule(item=Stuff)
    def do(self, item):
        return
Esempio n. 3
0
class PtrMixSM(stateful.RuleBasedStateMachine):
    def __init__(self):
        super().__init__()
        self._var = None
        self._contents = {}

    mixed_pointers = stateful.Bundle("mixed pointers")

    @stateful.initialize(target=mixed_pointers, a=pointers(), b=pointers())
    def mixptr(self, a, b):
        self._var = lib.mixptr(a, b)
        self._contents = {a: b, b: a}
        return stateful.multiple(a, b)

    @stateful.invariant()
    def equation(self):
        # nothing to check if called before initialization.
        if self._contents:
            # make it work if a == b and thus _contents has 1 entry
            contents = list(self._contents)
            a, b = contents[0], contents[-1]
            assert self._var.content == lib.mixptr(a, b).content

    @stateful.invariant()
    def unmixptr(self):
        for ptr in self._contents:
            assert lib.unmixptr(self._var, ptr) == self._contents[ptr]

    @stateful.rule(target=mixed_pointers,
                   a=stateful.consumes(mixed_pointers),
                   b=pointers())
    def remixptr(self, a, b):
        lib.remixptr(ffi.addressof(self._var), a, b)
        a = self._contents[a]
        self._contents = {a: b, b: a}
        return b
Esempio n. 4
0
class ChatRules(sta.RuleBasedStateMachine):
    chat: Chat
    panels: OrderedDict[str, PanelSetting]
    custom_channels: OrderedDict[str, CustomChannelsSetting]
    colors: List[Color]

    def __init__(self) -> None:
        super(ChatRules, self).__init__()

        self.chat = Chat()

        self.panels = OrderedDict()
        self.custom_channels = OrderedDict()
        self.colors = parse_colors(default_colors)

    panel_refs = sta.Bundle("panels")
    custom_channel_refs = sta.Bundle("custom_channels")

    # Will be initialized once and stay fixed.
    standard_channel_refs = sta.Bundle("standard_channels")

    @sta.initialize(target=standard_channel_refs)
    def init_standard_channels(self) -> Any:
        return sta.multiple(*self.chat.standard_channels)

    # Panels

    @sta.invariant()
    def expected_number_of_panels(self) -> None:
        assert len(self.chat.panels) == len(self.panels)

    @sta.rule(target=panel_refs, name=valid_panel_name)
    def new_panel(self, name: str) -> Panel:
        name_lower = swtor_lower(name)
        assume(name_lower not in self.panels.keys())

        num = len(self.panels) + 1
        self.panels[name_lower] = PanelSetting(num, name, set())

        return self.chat.panel(name)

    @sta.rule(panel_c=panel_refs)
    def existing_panel(self, panel_c: Panel) -> None:
        with pytest.raises(ValueError):
            self.chat.panel(panel_c.name)
        with pytest.raises(ValueError):
            self.chat.panel(swtor_lower(panel_c.name))
        with pytest.raises(ValueError):
            self.chat.panel(swtor_upper(panel_c.name))

    # Custom channels

    @sta.invariant()
    def expected_number_of_custom_channels(self) -> None:
        assert len(self.chat.custom_channels) == len(self.custom_channels)
        assert len(self.chat.custom_channels) <= num_custom_channels

    @sta.precondition(lambda self: len(self.custom_channels) < num_custom_channels)
    @sta.rule(
        target=custom_channel_refs,
        name=valid_custom_channel_name,
        password=valid_custom_channel_password,
        id=valid_custom_channel_id,
    )
    def new_custom_channel(
        self, name: str, password: Optional[str], id: Optional[str]
    ) -> CustomChannel:
        name_lower = swtor_lower(name)
        assume(name_lower not in self.custom_channels)

        num = len(self.custom_channels) + 1
        self.custom_channels[name_lower] = CustomChannelsSetting(
            name,
            password if password is not None else "",
            num,
            id if id is not None else f"usr.{name_lower}",
        )

        return self.chat.custom_channel(name, password=password, id=id)

    @sta.precondition(lambda self: len(self.custom_channels) == num_custom_channels)
    @sta.rule(
        name=valid_custom_channel_name,
        password=valid_custom_channel_password,
        id=valid_custom_channel_id,
    )
    def new_custom_channel_too_many(
        self, name: str, password: Optional[str], id: Optional[str]
    ) -> None:
        name_lower = swtor_lower(name)
        assume(name_lower not in self.custom_channels)

        with pytest.raises(RuntimeError):
            self.chat.custom_channel(name, password=password, id=id)

    @sta.rule(custom_channel_c=custom_channel_refs)
    def existing_custom_channel(self, custom_channel_c: CustomChannel) -> None:
        with pytest.raises(ValueError):
            self.chat.custom_channel(custom_channel_c.name)
        with pytest.raises(ValueError):
            self.chat.custom_channel(swtor_lower(custom_channel_c.name))
        with pytest.raises(ValueError):
            self.chat.custom_channel(swtor_upper(custom_channel_c.name))

    # Displaying channels

    @sta.rule(
        panel_c=panel_refs,
        channels_c=st.lists(st.one_of(standard_channel_refs, custom_channel_refs)),
    )
    def panel_display_channel(
        self, panel_c: Panel, channels_c: Iterable[Channel]
    ) -> None:
        for channel_c in channels_c:
            self.panels[swtor_lower(panel_c.name)].channel_ixs.add(channel_c.ix)

        panel_c.display(*channels_c)

    # Setting colors

    @sta.rule(
        channel_c=st.one_of(standard_channel_refs, custom_channel_refs),
        color=valid_color,
    )
    def replace_channel_color(self, channel_c: Channel, color: Color) -> None:
        self.colors[channel_c.ix] = color
        channel_c.color = color

    @sta.rule(
        channel_c=st.one_of(standard_channel_refs, custom_channel_refs),
        color=valid_color,
    )
    def mutate_channel_color(self, channel_c: Channel, color: Color) -> None:
        self.colors[channel_c.ix].r = color.r
        self.colors[channel_c.ix].g = color.g
        self.colors[channel_c.ix].b = color.b
        channel_c.color.r = color.r
        channel_c.color.g = color.g
        channel_c.color.b = color.b

    @sta.rule(
        source_channel_c=st.one_of(standard_channel_refs, custom_channel_refs),
        target_channel_c=st.one_of(standard_channel_refs, custom_channel_refs),
    )
    def link_channel_color(
        self, source_channel_c: Channel, target_channel_c: Channel
    ) -> None:
        self.colors[target_channel_c.ix] = self.colors[source_channel_c.ix]
        target_channel_c.color = source_channel_c.color

    # Applying the settings

    @sta.invariant()
    def apply_applies_settings(self) -> None:
        settings = {"foo": "bar"}
        self.chat.apply(settings)

        assert set(settings.keys()) == {
            "foo",
            "ChatChannels",
            "Chat_Custom_Channels",
            "ChatColors",
        }

        parse_panels(settings["ChatChannels"])
        parse_custom_channels(settings["Chat_Custom_Channels"])
        parse_colors(settings["ChatColors"])

    # The panels setting (ChatChannels)

    @sta.precondition(lambda self: not self.panels)
    @sta.invariant()
    def channels_setting_has_a_default_panel(self) -> None:
        setting = self.chat.panels_setting()
        # note(f"panels_setting: {setting!r}")

        panels_s = parse_panels(setting)

        assert panels_s == [PanelSetting(1, "General", all_channel_ixs)]

    @sta.precondition(lambda self: self.panels)
    @sta.invariant()
    def channels_setting_is_correct(self) -> None:
        setting = self.chat.panels_setting()
        # note(f"channels_setting: {setting!r}")

        panels_s = parse_panels(setting)

        assert len(panels_s) == len(self.panels)

        displayed_ixs = set()
        for panel_s in panels_s:
            displayed_ixs |= panel_s.channel_ixs

        missing_ixs = all_channel_ixs - displayed_ixs
        extra_ixs = displayed_ixs - all_channel_ixs

        assert not missing_ixs, "A channel is not displayed in any panel"
        assert not extra_ixs, "An impossible channel is displayed in a panel"

        for (panel_s, panel) in zip(panels_s, self.panels.values()):
            assert panel_s.number == panel.number
            assert panel_s.name == panel.name

            missing_ixs = panel.channel_ixs - panel_s.channel_ixs
            extra_ixs = panel_s.channel_ixs - panel.channel_ixs

            assert not missing_ixs, "Fewer channels are displayed than expected"

            # The first panel should have the explicitly displayed channel
            # and possibly more. The other panels should only have the
            # explicitly displayed channels.
            if panel.number != 1:
                assert not extra_ixs, "More channels are displayed than expected"

    # The Chat_Custom_Channels setting

    @sta.invariant()
    def custom_channels_setting_is_correct(self) -> None:
        setting = self.chat.custom_channels_setting()
        # note(f"custom_channels_setting: {setting!r}")

        custom_channels_s = parse_custom_channels(setting)

        assert len(custom_channels_s) == len(self.custom_channels)

        for cc_s, cc in zip(custom_channels_s, self.custom_channels.values()):
            assert cc_s == cc

    # The ChatColors setting

    @sta.invariant()
    def colors_setting_is_correct(self) -> None:
        setting = self.chat.colors_setting()
        # note(f"colors_setting: {setting!r}")

        colors_s = parse_colors(setting)

        assert colors_s == self.colors
Esempio n. 5
0
class VerificationStateMachine(stateful.RuleBasedStateMachine):
    """
    Verify the implementation of a timing wheel against the
    :py:class:`TimerHeap`.
    """
    scripts = stateful.Bundle("scripts")

    def make_epicycle(self):
        """
        Make a timing wheel instance to test.
        """
        raise NotImplementedError

    def assert_whens(self, wheel, heap):
        empty_raised = 'empty raised'
        try:
            wheel_when = wheel.when()
        except Empty:
            wheel_when = empty_raised

        try:
            heap_when = heap.when()
        except Empty:
            heap_when = empty_raised

        assert wheel_when == heap_when

    def play_script(self, script):
        wheel = self.make_epicycle()
        heap = TimerHeap()
        state = TimerState()
        for step in script:
            step(wheel, heap, state)

    no_empty_script = True

    @stateful.precondition(lambda self: self.no_empty_script)
    @stateful.rule(target=scripts)
    def inital_script(self):
        self.no_empty_script = False
        return pvector()

    @stateful.rule(interval=st.integers(min_value=0, max_value=16),
                   script=scripts,
                   target=scripts)
    def add(self, interval, script):
        def perform_add(wheel, heap, state):
            action = state.make_action()

            self.assert_whens(wheel, heap)
            wheel_request_id = wheel.add(interval, action.call_from_wheel)
            heap_request_id = heap.add(interval, action.call_from_heap)
            self.assert_whens(wheel, heap)

            assert wheel_request_id == heap_request_id
            state.record_action(wheel_request_id, action)

        script_with_add = script.append(perform_add)
        self.play_script(script_with_add)
        return script_with_add

    @stateful.rule(data=st.data(), script=scripts, target=scripts)
    def remove(self, data, script):
        def perform_remove(wheel, heap, state):
            if state.request_ids:
                request_id = data.draw(st.sampled_from(list(
                    state.request_ids)))
                state.request_ids.pop(request_id)

                self.assert_whens(wheel, heap)
                wheel.remove(request_id)
                heap.remove(request_id)
                self.assert_whens(wheel, heap)

        script_with_remove = script.append(perform_remove)
        self.play_script(script_with_remove)
        return script_with_remove

    @stateful.rule(ticks=st.integers(min_value=1, max_value=127),
                   script=scripts,
                   target=scripts)
    def tick(self, ticks, script):
        def perform_tick(wheel, heap, state):
            for _ in range(ticks):
                wheel.tick()
                heap.tick()
                for action in state.request_ids.values():
                    action.equivalent()

        script_with_tick = script.append(perform_tick)
        self.play_script(script_with_tick)
        return script_with_tick