async def test_inputoutput_module_test_to_friend_and_back(
            self, client, friend, input_name_from_test_client,
            output_name_to_test_client):
        limitations.skip_test_for(client,
                                  languages="c",
                                  transports=["amqp", "amqpws", "mqttws"])

        payload = sample_content.make_message_payload()
        payload_2 = sample_content.make_message_payload()

        await friend.enable_input_messages()
        await client.enable_input_messages()

        # BKTODO Node bug.  Can't have overlapped register ops with AMQP
        await asyncio.sleep(sleep_time_for_listener_start)

        test_input_future = asyncio.ensure_future(
            client.wait_for_input_event(input_name_from_friend))
        friend_input_future = asyncio.ensure_future(
            friend.wait_for_input_event(input_name_from_test_client))
        await asyncio.sleep(sleep_time_for_listener_start)

        await client.send_output_event(output_name_to_friend, payload)

        midpoint_message = await friend_input_future
        assert midpoint_message.body == payload

        await friend.send_output_event(output_name_to_test_client, payload_2)

        received_message = await test_input_future
        assert received_message.body == payload_2
예제 #2
0
    async def test_dropped_c2d_2nd_call(self, client, service, before_api_call,
                                        after_api_call):

        # 1st call
        payload = sample_content.make_message_payload()

        await client.enable_c2d()

        test_input_future = asyncio.ensure_future(
            client.wait_for_c2d_message())
        await service.send_c2d(client.device_id, payload)
        received_message = await test_input_future
        assert received_message.body == payload

        # 2nd call
        payload = sample_content.make_message_payload()

        await before_api_call()
        test_input_future = asyncio.ensure_future(
            client.wait_for_c2d_message())
        await after_api_call()

        await service.send_c2d(client.device_id, payload)

        logger("Awaiting input")
        received_message = await test_input_future
        assert received_message.body == payload
예제 #3
0
 async def send_operation(self, op_id):
     telemetry = make_message_payload()
     telemetry["op_id"] = op_id
     with self.op_id_list_lock:
         logger("setting op_id {} to not_received".format(op_id))
         self.op_id_list[op_id] = not_received
     await self.client.send_event(telemetry)
    async def test_perf_simple_throughput(self, client):
        """
        Send a large number of messsages all at once and measure how many messages
        can be sent per second.  This can be used to establish a theoretical maximum for
        our library, though the number of messages per second reported by this function
        is higher than typical because of burst effects.
        """
        count = 2500

        payloads = [sample_content.make_message_payload() for x in range(0, count)]

        start_time = datetime.datetime.now()
        await asyncio.gather(*[client.send_event(payload) for payload in payloads])
        duration = (datetime.datetime.now() - start_time).total_seconds()

        mps = math.floor(count / duration)

        logger(
            "{} messages were sent in {} seconds for {} messages/second".format(
                count, duration, mps
            )
        )

        # Arbitrary goal based on experimental evidence.  The goal of this assert is to
        # flag gigantic performance drops.  Experimentally, 46 is typical.  For this assert,
        # even 25 would be acceptable
        assert mps > 25
예제 #5
0
    async def test_regression_send_message_fails_with_corrupt_connection_string(
        self, client, field_name, new_field_value
    ):
        limitations.only_run_test_for(client, ["node", "pythonv2"])

        if not limitations.uses_shared_key_auth(client):
            pytest.skip("client is not using shared key auth")

        payload = sample_content.make_message_payload()

        cs_fields = connection_string.connection_string_to_dictionary(
            client.settings.connection_string
        )
        cs_fields[field_name] = new_field_value

        await client.destroy()
        await client.create_from_connection_string(
            client.settings.transport,
            connection_string.dictionary_to_connection_string(cs_fields),
            connections.get_ca_cert(client.settings),
        )

        with pytest.raises(Exception) as e:
            await client.send_event(payload)
        assert is_api_failure_exception(e._excinfo[1])
예제 #6
0
    async def test_regression_bad_connection_retry_second_send_event(
        self, system_control, client, drop_mechanism, eventhub
    ):
        limitations.only_run_test_for(client, ["node", "pythonv2"])
        limitations.skip_if_no_system_control()

        await client.connect2()
        await client.disconnect2()

        payload = sample_content.make_message_payload()

        await eventhub.connect()
        received_message_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id, expected=payload)
        )

        await system_control.disconnect_network(drop_mechanism)

        send_future = asyncio.ensure_future(client.send_event(payload))

        await asyncio.sleep(1)

        await system_control.reconnect_network()

        await send_future
        received_message = await received_message_future

        assert received_message
예제 #7
0
    async def test_regression_send_message_fails_with_message_over_256K(self, client):
        limitations.only_run_test_for(client, ["node", "pythonv2"])

        big_payload = sample_content.make_message_payload(size=257 * 1024)

        with pytest.raises(Exception) as e:
            await client.send_event(big_payload)
        assert is_api_failure_exception(e._excinfo[1])
예제 #8
0
    async def test_regression_send_message_big_message_doesnt_break_client(
            self, client, eventhub):
        limitations.only_run_test_for(client, ["node", "pythonv2"])

        big_payload = sample_content.make_message_payload(size=257 * 1024)
        small_payload = sample_content.make_message_payload()

        await eventhub.connect()

        received_message_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id,
                                         expected=small_payload))

        with pytest.raises(Exception):
            await client.send_event(big_payload)

        await client.send_event(small_payload)

        received_message = await received_message_future
        assert received_message is not None, "Message not received"
예제 #9
0
    async def test_device_receive_c2d(self, client, service):
        test_payload = sample_content.make_message_payload()

        await client.enable_c2d()
        test_input_future = asyncio.ensure_future(
            client.wait_for_c2d_message())
        await asyncio.sleep(2
                            )  # wait for receive pipeline to finish setting up

        await service.send_c2d(client.device_id, test_payload)

        received_message = await test_input_future
        assert received_message.body == test_payload
예제 #10
0
    async def test_regression_bad_connection_fail_first_send_event(
            self, system_control, client, drop_mechanism):
        limitations.only_run_test_for(client, ["node", "pythonv2"])
        limitations.skip_if_no_system_control()

        await system_control.disconnect_network(drop_mechanism)

        payload = sample_content.make_message_payload()

        with pytest.raises(Exception) as e:
            await client.send_event(payload)

        assert is_api_failure_exception(e._excinfo[1])
예제 #11
0
    async def test_regression_c2d_enable_twice(self, client, service):
        limitations.only_run_test_on_iothub_device(client)

        test_payload = sample_content.make_message_payload()

        await client.enable_c2d()
        await client.enable_c2d()
        test_input_future = asyncio.ensure_future(client.wait_for_c2d_message())
        await asyncio.sleep(2)  # wait for receive pipeline to finish setting up

        await service.send_c2d(client.device_id, test_payload)

        received_message = await test_input_future
        assert received_message.body == test_payload
 async def send_single():
     """
     Send a single event with latency measurement.  Fail if the latency is too high.
     """
     with message_counter:
         latency = MeasureLatency()
         with latency:
             logger("start send")
             await client.send_event(sample_content.make_message_payload())
             logger("end send")
         latency_reports.add_sample(latency.get_latency())
     if max_latency and latency.get_latency() > max_latency:
         raise Exception(
             "max latency exceeded: {}".format(latency.get_latency())
         )
    async def test_inputoutput_module_output_routed_upstream(
            self, client, eventhub):
        limitations.skip_test_for(client,
                                  languages="c",
                                  transports=["amqp", "amqpws"])

        payload = sample_content.make_message_payload()

        # start listening before we send
        await eventhub.connect()
        received_message_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id, expected=payload))

        await client.send_output_event(telemetry_output_name, payload)

        received_message = await received_message_future
        assert received_message is not None, "Message not received"
예제 #14
0
    async def do_test_telemetry(self, *, client, eventhub, count, time_limit):
        logger("testing telemetry with {} operations".format(count))

        payloads = [sample_content.make_message_payload() for x in range(0, count)]
        futures = []

        # start listening before we send
        await eventhub.connect()
        received_message_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id)
        )

        for payload in payloads:
            futures.append(asyncio.ensure_future(client.send_event(payload)))

        # wait for the send to complete, and verify that it arrvies
        await asyncio.gather(*futures)

        logger("All messages sent.  Awaiting reception")

        while len(payloads):
            received_message = await received_message_future

            if received_message in payloads:
                payloads.remove(received_message)
                logger(
                    "Received expected message: {},  {}/{} left".format(
                        received_message, len(payloads), count
                    )
                )
            else:
                logger("Received unexpected message: {}".format(received_message))

            if time_limit.is_test_done():
                await eventhub.disconnect()
                return

            if len(payloads):
                received_message_future = asyncio.ensure_future(
                    eventhub.wait_for_next_event(client.device_id)
                )

        await eventhub.disconnect()
예제 #15
0
    async def test_client_dropped_send_event(self, client, before_api_call,
                                             after_api_call, eventhub):
        test_payload = sample_content.make_message_payload()

        start_listening_time = datetime.datetime.utcnow() - datetime.timedelta(
            seconds=30)  # start listning early because of clock skew

        await before_api_call()
        send_future = asyncio.ensure_future(client.send_event(test_payload))
        await after_api_call()

        # wait for the send to complete, and verify that it arrvies
        await send_future

        await eventhub.connect(starting_position=start_listening_time)
        received_message_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id,
                                         expected=test_payload))
        received_message = await received_message_future
        assert received_message is not None, "Message not received"
예제 #16
0
    async def test_dropped_c2d_1st_call(self, client, service, before_api_call,
                                        after_api_call):
        payload = sample_content.make_message_payload()

        await client.enable_c2d()

        await before_api_call()
        test_input_future = asyncio.ensure_future(
            client.wait_for_c2d_message())
        await after_api_call()

        await asyncio.sleep(30)  # long time necessary to let subscribe happen
        logger("transport connected.  Sending C2D")

        await service.send_c2d(client.device_id, payload)

        logger("C2D sent.  Waiting for response")

        received_message = await test_input_future
        assert received_message.body == payload
예제 #17
0
    async def test_regression_autoconnect_without_calling_connect(
        self, system_control, client, drop_mechanism
    ):
        limitations.only_run_test_for(client, ["pythonv2"])
        limitations.skip_if_no_system_control()

        payload = sample_content.make_message_payload()
        await client.send_event(payload)

        status = await client.get_connection_status()
        assert status == "connected"

        await system_control.disconnect_network(drop_mechanism)

        await client.wait_for_connection_status_change("disconnected")

        await system_control.reconnect_network()

        await client.wait_for_connection_status_change("connected")
        assert status == "connected"
    async def test_inputoutput_module_to_friend_routing(
            self, client, friend, input_name_from_test_client):
        limitations.skip_test_for(client,
                                  languages="c",
                                  transports=["amqp", "amqpws"])
        payload = sample_content.make_message_payload()

        await friend.enable_input_messages()
        logger("messages enabled")

        friend_input_future = asyncio.ensure_future(
            friend.wait_for_input_event(input_name_from_test_client))
        await asyncio.sleep(sleep_time_for_listener_start)
        logger("friend future created")

        await client.send_output_event(output_name_to_friend, payload)
        logger("message sent")

        received_message = await friend_input_future
        logger("received message")
        assert received_message.body == payload
예제 #19
0
    async def test_dropped_send_output_5x(self, client, eventhub,
                                          before_api_call, after_api_call):
        start_listening_time = datetime.datetime.utcnow() - datetime.timedelta(
            seconds=30)  # start listning early because of clock skew
        payloads = [sample_content.make_message_payload() for x in range(0, 5)]
        futures = []

        await before_api_call()
        for payload in payloads:
            futures.append(
                asyncio.ensure_future(
                    client.send_output_event(telemetry_output_name, payload)))
        await after_api_call()

        # wait for the send to complete, and verify that it arrvies
        await asyncio.gather(*futures)

        logger("All messages sent.  Awaiting reception")

        logger("connecting eventhub")
        await eventhub.connect(starting_position=start_listening_time)
        receive_future = asyncio.ensure_future(
            eventhub.wait_for_next_event(client.device_id))

        while len(payloads):
            received_message = await receive_future

            if received_message in payloads:
                logger(
                    "Received expected message: {}, removing from list".format(
                        received_message))
                payloads.remove(received_message)
            else:
                logger(
                    "Received unexpected message: {}".format(received_message))

            if len(payloads):
                receive_future = asyncio.ensure_future(
                    eventhub.wait_for_next_event(client.device_id))
예제 #20
0
    async def test_dropped_send_output(
        self,
        client,
        friend,
        input_name_from_test_client,
        before_api_call,
        after_api_call,
    ):
        test_payload = sample_content.make_message_payload()

        friend_input_future = asyncio.ensure_future(
            friend.wait_for_input_event(input_name_from_test_client))

        await before_api_call()
        send_future = asyncio.ensure_future(
            client.send_output_event(output_name_to_friend, test_payload))
        await after_api_call()

        # wait for the send to complete, and verify that it arrvies
        await send_future
        received_message = await friend_input_future
        print("received message")
        assert received_message.body == test_payload
예제 #21
0
def ensure_send_telemetry_message(*, client, payloads, send_futures):
    payload = sample_content.make_message_payload()
    payloads.append(payload)
    send_futures.append(asyncio.ensure_future(client.send_event(payload)))
예제 #22
0
@pytest.fixture
async def system_control():
    adapter = getattr(settings.system_control, "adapter", None)
    try:
        yield adapter
    finally:
        if adapter:
            logger("system_control finalizer".center(132, "-"))
            await adapter.reconnect_network()


@pytest.fixture(
    scope="function",
    params=[
        pytest.param({}, id="empty object"),
        pytest.param(sample_content.make_message_payload(1),
                     id="smallest object"),
        pytest.param(sample_content.make_message_payload(40),
                     id="small object"),
        pytest.param(sample_content.make_message_payload(63 * 1024),
                     id="63K object"),
        pytest.param(sample_content.make_message_payload(127 * 1024),
                     id="127K object"),
        pytest.param(sample_content.make_message_payload(255 * 1024),
                     id="255K object"),
    ],
)
def telemetry_payload(request):
    return request.param