Ejemplo n.º 1
0
 async def restart_session(self):
     if self.last_final_future is None or self.last_final_future.done():
         raise PhotonsAppError(
             "The IO does not have a valid final future to restart the session from"
         )
     await self.shutting_down(Events.SHUTTING_DOWN(self.device))
     await self.start_session(self.last_final_future, self.parent_ts)
     await self.power_on(Events.POWER_ON(self.device))
Ejemplo n.º 2
0
    def received(self, *pkts, keep_duplicates=False):
        store = devices.store(self.fake_device)
        total = 0
        for pkt in pkts:
            nxt = store.count(
                Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=pkt)
            )
            assert nxt > 0, (pkt.__class__.__name__, repr(pkt), nxt)
            total += nxt

        if keep_duplicates or len(pkts) == 0:
            exists = store.count(
                Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=mock.ANY)
            )
            assert exists == len(pkts)
        store.clear()
Ejemplo n.º 3
0
    def assertIncoming(self, *expected, ignore=None, remove_duplicates=True):
        got = list(self.incoming(ignore=ignore))
        want = [
            Events.INCOMING(self.device, self.device.io["MEMORY"], pkt=pkt)
            for pkt in expected
        ]

        unmatched = []
        remaining = list(got)
        ww = list(want)
        while ww:
            w = ww.pop(0)
            found = False
            buf = []
            for f in remaining:
                if not found and f == w:
                    found = True
                else:
                    buf.append(f)

            if not found:
                unmatched.append(w)
            remaining = buf

        if remove_duplicates:
            remaining = [
                event for event in remaining
                if not any(event == w for w in want)
            ]

        if not unmatched and not remaining:
            return

        print("Wanted the following")
        for event in want:
            print(f" - {event}")
        print()

        print("Got the following")
        for event in got:
            print(f" - {event}")
        print()

        if unmatched:
            print("Following did not have matches")
            for event in unmatched:
                print(f" - {event}")
            print()

        if remaining:
            print("Following was found unexpectedly")
            for event in remaining:
                print(f" - {event}")
            print()

        assert False
Ejemplo n.º 4
0
    async def finish_session(self):
        if getattr(self, "final_future", None) is None:
            return

        ff = self.final_future

        try:
            await hp.wait_for_all_futures(
                self.parent_ts.add(
                    self.shutting_down(Events.SHUTTING_DOWN(self.device))),
                name="IO::finish_session[power_off]",
            )
            self.final_future.cancel()
            await self.ts.finish()
            await self.incoming.finish()
        finally:
            if ff:
                ff.cancel()
            self.final_future = None
Ejemplo n.º 5
0
    async def respond(self, event):
        if event | Events.SET_ZONES:
            changes = []
            for index, color in event.zones:
                if index >= len(self.device.attrs.zones):
                    continue
                changes.append(
                    self.device.attrs.attrs_path("zones",
                                                 index).changer_to(color))
            await self.device.attrs.attrs_apply(*changes, event=event)

        elif event | MultiZoneMessages.GetMultiZoneEffect:
            event.add_replies(
                self.state_for(MultiZoneMessages.StateMultiZoneEffect))

        elif event | MultiZoneMessages.GetColorZones:
            getter = self.state_for(GetZonesCallable())
            for state in getter(event.pkt.start_index, event.pkt.end_index):
                event.add_replies(state)

        elif event | MultiZoneMessages.SetMultiZoneEffect:
            state = self.state_for(MultiZoneMessages.StateMultiZoneEffect)
            await self.change_one("zones_effect", event.pkt.type, event=event)
            event.add_replies(state)

        elif event | MultiZoneMessages.SetColorZones:
            getter = self.state_for(GetZonesCallable())
            state = getter(event.pkt.start_index, event.pkt.end_index)
            event.add_replies(*state)

            zones = []
            color = hp.Color(event.pkt.hue, event.pkt.saturation,
                             event.pkt.brightness, event.pkt.kelvin)
            for i in range(event.pkt.start_index, event.pkt.end_index + 1):
                zones.append((i, color))
            await self.respond(Events.SET_ZONES(self.device, zones=zones))
Ejemplo n.º 6
0
                def setup(s, *a, **kw):
                    assert s.device is device
                    assert s.created == 56789
                    got.append((a, kw))

            e = MyEvent(device, 1, 2, one=3, four=9)
            ga = (1, 2)
            gkw = {"one": 3, "four": 9}
            assert e.created == 56789
            assert e.device is device
            assert e.log_args == ga
            assert e.log_kwargs == gkw
            assert got == [(ga, gkw)]

    it "can do comparisons with events", device:
        e = Events.POWER_OFF(device)
        assert e | Events.POWER_OFF
        assert not e | Events.OUTGOING

        e = Events.RESET(device, old_attrs={})
        assert e | Events.RESET
        assert not e | Events.POWER_OFF

    describe "formatting for the console":

        it "can format a simple event", device:
            assertConsoleOutput(
                Events.POWER_OFF(device),
                "2021-05-16 11:00:01.650000+1000 -> d073d5001337(LCM2_A19:2,80) POWER_OFF",
            )
Ejemplo n.º 7
0
        )

    async it "has set commands", devices, server:
        expected = {"results": {device.serial: "ok" for device in devices}}

        await server.assertCommand(
            "/v1/lifx/command",
            {"command": "set", "args": {"pkt_type": "SetPower", "pkt_args": {"level": 0}}},
            json_output=expected,
        )

        for device in devices:
            io = device.io["MEMORY"]
            assert (
                devices.store(device).count(
                    Events.INCOMING(device, io, pkt=DeviceMessages.SetPower(level=0))
                )
                == 1
            )
            devices.store(device).clear()

        # With an offline light
        bathroom_light = devices["d073d5000002"]
        async with bathroom_light.offline():
            expected["results"]["d073d5000002"] = {
                "error": {
                    "message": "Timed out. Waiting for reply to a packet",
                    "sent_pkt_type": 21,
                    "source": mock.ANY,
                    "sequence": mock.ANY,
                },
Ejemplo n.º 8
0
        tile = devices["tile"]
        io = tile.io["MEMORY"]
        store = devices.store(tile)
        store.clear()

        first_set_64 = tile.attrs.event_waiter.wait_for_incoming(io, Set64)

        # start
        got = await server.assertCommand(
            "/v1/lifx/command",
            {"command": "animation/start", "args": {"animations": [["balls", {"every": 3}]]}},
        )
        identity = got["started"]

        await first_set_64
        now = store.count(Events.INCOMING(tile, io, pkt=Set64))
        assert now > 0
        await m.add(5)
        now2 = store.count(Events.INCOMING(tile, io, pkt=Set64))
        assert now2 > now

        identity = got["started"]
        await m.add(5)
        assert store.count(Events.INCOMING(tile, io, pkt=Set64)) > now

        # pause
        await server.assertCommand(
            "/v1/lifx/command",
            {"command": "animation/pause", "args": {"pause": [identity]}},
        )
        await m.add(5)
Ejemplo n.º 9
0
                        "four",
                        from_zero=lambda event, options: 2,
                    ),
                ]

                async def reset(self, event):
                    got.append(("reset", event))
                    return await super().reset(event)

                async def respond(self, event):
                    got.append(("respond", event))
                    return await super().respond(event)

            device.options.append(Op(device))

            evtZerod = Events.RESET(device, zerod=True, old_attrs={})
            evtNormal = Events.RESET(device, zerod=False, old_attrs={})

            async with device.session(final_future):
                assertEvents(
                    got,
                    ("respond", (Events.SHUTTING_DOWN, device)),
                    ("respond", (Events.POWER_OFF, device)),
                    ("reset", evtNormal),
                    ("respond", (Events.ATTRIBUTE_CHANGE, device)),
                    ("respond", evtNormal),
                    ("respond", (Events.POWER_ON, device)),
                )
                assert device.attrs.three == 1
                assert device.attrs.four == 2
Ejemplo n.º 10
0
                async def _send_reply(s, send, give_reply, addr, *, replying_to):
                    got.append(("sent", send, give_reply, addr, replying_to))

            addr = mock.Mock(name="addr")
            give_reply = mock.Mock(name="give_reply")

            given1 = mock.Mock(name="given1")
            given2 = mock.Mock(name="given2")
            filtered1 = mock.Mock(name="filtered1")
            filtered2 = mock.Mock(name="filtered2")
            filtered3 = mock.Mock(name="filtered3")

            async with wrap_io(MyIO(device)) as io:
                pkt = DeviceMessages.GetPower()
                event = Events.INCOMING(device, io, pkt=pkt, addr=addr)

                class Instruction:
                    def __init__(s):
                        s.event = event

                    async def process(s):
                        got.append(("process", given1))
                        yield given1
                        got.append(("process", given2))
                        yield given2

                instruction = Instruction()

                async def outgoing(r, e):
                    got.append(("outgoing", r, e))
Ejemplo n.º 11
0
                got = []
                msg = DeviceMessages.SetPower(level=0)
                async with sender(msg, [V.device.serial, V.device2.serial]) as pkts:
                    async for pkt in pkts:
                        got.append(pkt)
                        raise pkts.StopPacketStream()

                assert len(got) == 1
                expected = (DeviceMessages.StatePower, {"level": 0})
                reply = expected[0].create(**expected[1])
                pytest.helpers.assertSamePackets(got, expected)

                device = V.device
                io = device.io["UDP"]
                assert devices.store(device) == [
                    Events.INCOMING(device, io, pkt=msg),
                    Events.ATTRIBUTE_CHANGE(device, [ChangeAttr.test("power", 0)], True),
                    Events.OUTGOING(
                        device, io, pkt=CoreMessages.Acknowledgement(), replying_to=msg
                    ),
                    Events.OUTGOING(device, io, pkt=reply, replying_to=msg),
                ]

                device2 = V.device2
                io2 = device2.io["UDP"]
                assert devices.store(device2) == [
                    Events.INCOMING(device2, io2, pkt=msg),
                    Events.ATTRIBUTE_CHANGE(device2, [ChangeAttr.test("power", 0)], True),
                    Events.OUTGOING(
                        device2, io2, pkt=CoreMessages.Acknowledgement(), replying_to=msg
                    ),
Ejemplo n.º 12
0
 def make_incoming(kls):
     return Events.INCOMING(
         device, io, pkt=kls(source=200, sequence=300, target=device.serial)
     )
Ejemplo n.º 13
0
def incoming_event(device, io):
    return Events.INCOMING(
        device, io, pkt=DeviceMessages.GetPower(source=20, sequence=34, target=device.serial)
    )
Ejemplo n.º 14
0
 def make_incoming(serial, kls=DeviceMessages.GetPower):
     return Events.INCOMING(device, io, pkt=kls(source=200, sequence=300, target=serial))
Ejemplo n.º 15
0
 def match(event):
     return event == Events.INCOMING(self.device, io, pkt=pkt)