Example #1
0
    async def test_message_to_topic(self):
        """Test converting a message to a topic."""

        async with async_protocol_manager() as protocol:
            tests = await import_commands()

            for test_info in tests:
                self._topic = None
                address = repr(random_address())
                curr_test = tests[test_info]
                if curr_test.get("address") is not None:
                    curr_test["address"] = address
                msgs = [create_message(curr_test)]
                curr_topic = curr_test["topic"].format(address)
                subscribe_topic(self.capture_topic, curr_topic)
                send_data(msgs, protocol.read_queue)
                try:
                    await asyncio.sleep(0.1)
                    assert self._topic.name == curr_topic

                except asyncio.TimeoutError:
                    raise AssertionError(
                        "Failed timed out {} with test topic {}".format(
                            test_info, curr_test.get("topic")
                        )
                    )
                except (AssertionError, AttributeError):
                    raise AssertionError(
                        "Failed test {} with test topic {}".format(
                            test_info, curr_test.get("topic")
                        )
                    )
                finally:
                    unsubscribe_topic(self.capture_topic, curr_topic)
Example #2
0
    async def test_receive_on_msg(self):
        """Test receiving an ON message."""
        async with async_protocol_manager() as protocol:
            last_topic = None

            def topic_received(cmd1,
                               cmd2,
                               target,
                               user_data,
                               hops_left,
                               topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name

            address = random_address()
            byte_data = create_std_ext_msg(address,
                                           0x80,
                                           0x11,
                                           0xFF,
                                           target=Address("000001"))
            expected_topic = "{}.{}.on.broadcast".format(address.id, 1)
            pub.subscribe(topic_received, expected_topic)
            on_cmd = DataItem(byte_data, 0)
            data = [on_cmd]
            send_data(data, protocol.read_queue)
            await asyncio.sleep(0.05)
            assert last_topic == expected_topic
Example #3
0
    async def test_send_on_all_link_broadcast_topic(self):
        """Test sending the broadcast ON command."""
        from pyinsteon.handlers.to_device.on_level_all_link_broadcast import (
            OnLevelAllLinkBroadcastCommand, )

        topic_lock = asyncio.Lock()
        async with async_protocol_manager():
            last_topic = None

            def topic_received(cmd1, cmd2, user_data, topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            group = 3
            target = Address(bytearray([0x00, 0x00, group]))
            ack_topic = "ack.{}.on.all_link_broadcast".format(target.id)
            pub.subscribe(topic_received, ack_topic)
            cmd = OnLevelAllLinkBroadcastCommand(group=group)
            await topic_lock.acquire()
            await cmd.async_send()  # Mock transport auto sends ACK/NAK
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert last_topic == ack_topic
            except asyncio.TimeoutError:
                assert ack_topic is None
            if topic_lock.locked():
                topic_lock.release()
Example #4
0
    async def test_inbound(self):
        """Test direct command."""

        async with async_protocol_manager(auto_ack=False) as protocol:

            tests = await import_commands()
            subscribe_topic(self.async_validate_values, pub.ALL_TOPICS)

            for test_info in tests:
                self._current_test = test_info
                test_command = tests[test_info]
                cmd_class = test_command.get("command")
                params = test_command.get("params")
                inbound_message = test_command.get("message")
                if params.get("address") == "":
                    params["address"] = random_address()
                inbound_message["address"] = params["address"]
                self._assert_tests = test_command.get("assert_tests")
                obj = get_class_or_method(commands, cmd_class)
                cmd = obj(**params)
                inbound_data_item = create_message(inbound_message, 0)
                self._call_count = 0
                send_data([inbound_data_item], protocol.read_queue)
                await sleep(0.1)
                assert self._call_count == 1
                assert self._assert_result
Example #5
0
    async def test_send_on_topic(self):
        """Test sending the ON command."""
        async with async_protocol_manager():
            received_topic = ""

            def expected_topic_received(cmd1,
                                        cmd2,
                                        user_data,
                                        topic=pub.AUTO_TOPIC):
                nonlocal received_topic
                received_topic = topic.name

            address = random_address()
            on_topic = "send.{}.1.direct".format(ON)
            topics = [
                TopicItem(on_topic, {
                    "address": address,
                    "on_level": 0xFF,
                    "group": 0
                }, 0)
            ]

            self._last_topic = None
            expected_topic = "ack.{}.1.on.direct".format(address.id)
            pub.subscribe(expected_topic_received, expected_topic)
            send_topics(topics)
            await asyncio.sleep(0.05)
            assert received_topic == expected_topic
Example #6
0
 async def test_connected(self):
     """Test the connected property."""
     with patch("pyinsteon.protocol.protocol.publish_topic",
                self.mock_publish_topic):
         async with async_protocol_manager() as protocol:
             assert self.topic == "connection.made"
             assert protocol.connected
             protocol.close()
             assert not protocol.connected
             assert protocol.message_queue
Example #7
0
    async def test_device_commands(self):
        """Test sending a command from a device."""
        async with async_protocol_manager():
            tests = await import_commands()
            await sleep(0.1)

            for device_type in tests:  # ["SwitchedLightingControl_DinRail"]:
                test_configs = tests[device_type]
                for command in test_configs:
                    await self._execute_command(device_type, command,
                                                test_configs[command])
Example #8
0
 async def test_connection_failed(self):
     """Test the connected property."""
     with patch("pyinsteon.protocol.protocol.publish_topic",
                self.mock_publish_topic):
         try:
             async with async_protocol_manager(connect=False, retry=False):
                 await asyncio.sleep(0.1)
                 assert False
         except ConnectionError:
             await asyncio.sleep(0.1)
             assert self.topic == "connection.failed"
Example #9
0
    async def test_data_received(self):
        """Test the data_received method."""
        def dummy_nak_listener(*args, **kwargs):
            """Listen for NAK.

            This ensures we send the NAK rather than resend the message.
            """

        data = [
            {
                "data": "025003040506070809110b",
                "topic": "030405.1.on.direct"
            },
            {
                "data": "02500304050607",
                "topic": None
            },
            {
                "data": "0809130b",
                "topic": "030405.1.off.direct"
            },
        ]

        with patch("pyinsteon.protocol.protocol.publish_topic",
                   self.mock_publish_topic):
            async with async_protocol_manager(auto_ack=False) as protocol:
                for test in data:
                    self.topic = None
                    protocol.data_received(unhexlify(test["data"]))
                    await asyncio.sleep(0.1)
                    try:
                        assert self.topic == test["topic"]
                    except AssertionError:
                        raise AssertionError(
                            f"Failed with data {test['data']}: Topic: {self.topic}  Expected: {test['topic']}"
                        )

                # Test when the modem only responds with a NAK rather than the original message.
                nak_topic = "nak.0a0b0c.1.on.direct"
                pub.subscribe(dummy_nak_listener, nak_topic)
                protocol.write(unhexlify("02620a0b0c09110b"))
                await asyncio.sleep(0.1)
                self.topic = None
                protocol.data_received(unhexlify("15"))
                await asyncio.sleep(0.1)
                assert self.topic == nak_topic

                # Test that a NAK is resent rather than published as a topic.
                self.topic = None
                protocol.data_received(unhexlify("02620d0e0f09110b15"))
                await asyncio.sleep(0.1)
                assert self.topic is None
Example #10
0
    async def test_command(self):
        """Test direct command."""
        async with async_protocol_manager() as protocol:
            msgs = []

            def listen_for_ack():
                send_data(msgs, protocol.read_queue)

            tests = await import_commands()
            subscribe_topic(self.validate_values, pub.ALL_TOPICS)
            subscribe_topic(listen_for_ack, "ack")

            for test_info in tests:
                address = random_address()
                self._current_test = test_info
                test_command = tests[test_info]
                command = test_command.get("command")
                cmd_class = command.get("class")
                params = command.get("params")
                if params.get("address"):
                    params["address"] = address
                send_params = command.get("send_params")
                test_response = test_command.get("response")
                obj = get_class_or_method(commands, cmd_class)
                cmd = obj(**params)

                messages = test_command.get("messages")
                msgs = []
                for msg_dict in messages:
                    #msg_dict = messages[message]
                    msg_dict["address"] = address
                    msgs.append(create_message(msg_dict))
                self._assert_tests = test_command.get("assert_tests")

                self._call_count = 0
                try:
                    response = await cmd.async_send(**send_params)
                except Exception as ex:
                    raise Exception("Failed test {} with error: {}".format(
                        self._current_test, str(ex)))
                try:
                    if test_response:
                        assert int(response) == test_response
                    if self._assert_tests:
                        call_count = test_command.get("call_count", 1)
                        assert self._call_count == call_count
                except AssertionError:
                    raise AssertionError(
                        "Failed test: {} command response: {}  call count {}".
                        format(self._current_test, response, self._call_count))
                await sleep(0.1)
                assert self._assert_result
Example #11
0
 async def test_x10_commands(self):
     """Test X10 commands."""
     async with async_protocol_manager():
         x10_types = ["X10OnOff", "X10Dimmable"]
         for device_type in x10_types:
             device_class = getattr(device_types, device_type)
             device = device_class("A", 3)
             result = await device.async_on()
             assert int(result) == 1
             assert device.groups[1].value == 255
             result = await device.async_off()
             assert int(result) == 1
             assert device.groups[1].value == 0
Example #12
0
 async def test_connection_retry(self):
     """Test the connected property."""
     with patch("pyinsteon.protocol.protocol.publish_topic",
                self.mock_publish_topic):
         try:
             async with async_protocol_manager(connect=False,
                                               retry=True,
                                               retries=[1, 1]) as protocol:
                 await asyncio.sleep(0.1)
                 assert protocol.connected
                 assert self.topic == "connection.made"
         except ConnectionError:
             assert False
Example #13
0
    async def test_pause_resume_writer(self):
        """Test the pause_writer and resume_writer methods."""
        async with async_protocol_manager(auto_ack=False) as protocol:
            await asyncio.sleep(0.1)
            protocol.write(unhexlify("02620a0b0c09110b"))
            await asyncio.sleep(0.1)
            assert protocol.message_queue.empty()

            protocol.pause_writing()
            await asyncio.sleep(0.1)
            protocol.write(unhexlify("026201020309110b"))
            await asyncio.sleep(0.1)
            assert not protocol.message_queue.empty()

            protocol.resume_writing()
            await asyncio.sleep(0.1)
            assert protocol.message_queue.empty()
Example #14
0
    async def test_modem_inbound(self):
        """Test direct command."""
        async with async_protocol_manager(auto_ack=False) as protocol:

            tests = await import_modem_commands()
            pub.subscribe(self.validate_values, pub.ALL_TOPICS)

            for test_info in tests:
                self._current_test = test_info
                test_command = tests[test_info]
                command = test_command.get("command")
                cmd_class = command.get("class")
                inbound_message = command.get("inbound_message")["data"]
                self._assert_tests = test_command.get("assert_tests")
                obj = get_class_or_method(commands, cmd_class)
                cmd = obj()
                inbound_data = unhexlify(f"02{inbound_message}")
                ack_response_item = DataItem(inbound_data, 0)
                send_data([ack_response_item], protocol.read_queue)
                await sleep(0.1)
Example #15
0
    async def test_receive_on_msg(self):
        """Test receiving an ON message."""
        topic_lock = asyncio.Lock()
        async with async_protocol_manager() as protocol:
            last_topic = None

            def topic_received(cmd1,
                               cmd2,
                               target,
                               user_data,
                               hops_left,
                               topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            address = random_address()
            byte_data = create_std_ext_msg(address,
                                           0x80,
                                           0x11,
                                           0xFF,
                                           target=Address("000001"))
            expected_topic = "{}.{}.on.broadcast".format(address.id, 1)
            pub.subscribe(topic_received, expected_topic)
            on_cmd = DataItem(byte_data, 0)
            data = [on_cmd]
            await topic_lock.acquire()
            send_data(data, protocol.read_queue)
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert last_topic == expected_topic
            except asyncio.TimeoutError:
                assert expected_topic is None
            if topic_lock.locked():
                topic_lock.release()
Example #16
0
    async def test_send_on_topic(self):
        """Test sending the ON command."""
        topic_lock = asyncio.Lock()
        async with async_protocol_manager():
            received_topic = ""

            def expected_topic_received(cmd1,
                                        cmd2,
                                        user_data,
                                        topic=pub.AUTO_TOPIC):
                nonlocal received_topic
                received_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            address = random_address()
            on_topic = "send.{}.1.direct".format(ON)
            topics = [
                TopicItem(on_topic, {
                    "address": address,
                    "on_level": 0xFF,
                    "group": 0
                }, 0)
            ]

            self._last_topic = None
            expected_topic = "ack.{}.1.on.direct".format(address.id)
            pub.subscribe(expected_topic_received, expected_topic)
            await topic_lock.acquire()
            send_topics(topics)
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert received_topic == expected_topic
            except asyncio.TimeoutError:
                assert expected_topic is None
            if topic_lock.locked():
                topic_lock.release()