コード例 #1
0
async def test_handle_talk():
    async with PubsubFactory.create_batch_with_floodsub(1) as pubsubs_fsub:
        sub = await pubsubs_fsub[0].subscribe(TESTING_TOPIC)
        msg_0 = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=[TESTING_TOPIC],
            data=b"1234",
            seqno=b"\x00" * 8,
        )
        pubsubs_fsub[0].notify_subscriptions(msg_0)
        msg_1 = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=["NOT_SUBSCRIBED"],
            data=b"1234",
            seqno=b"\x11" * 8,
        )
        pubsubs_fsub[0].notify_subscriptions(msg_1)
        assert (len(pubsubs_fsub[0].topic_ids) == 1 and sub
                == pubsubs_fsub[0].subscribed_topics_receive[TESTING_TOPIC])
        assert (await sub.get()) == msg_0
コード例 #2
0
async def test_strict_signing_failed_validation(monkeypatch):
    async with PubsubFactory.create_batch_with_floodsub(
            2, strict_signing=True) as pubsubs_fsub:
        msg = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=[TESTING_TOPIC],
            data=TESTING_DATA,
            seqno=b"\x00" * 8,
        )
        priv_key = pubsubs_fsub[0].sign_key
        signature = priv_key.sign(PUBSUB_SIGNING_PREFIX.encode() +
                                  msg.SerializeToString())

        event = trio.Event()

        def _is_msg_seen(msg):
            return False

        # Use router publish to check if `push_msg` succeed.
        async def router_publish(*args, **kwargs):
            await trio.hazmat.checkpoint()
            # The event will only be set if `push_msg` succeed.
            event.set()

        monkeypatch.setattr(pubsubs_fsub[0], "_is_msg_seen", _is_msg_seen)
        monkeypatch.setattr(pubsubs_fsub[0].router, "publish", router_publish)

        # Test: no signature attached in `msg`
        await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg)
        await trio.sleep(0.01)
        assert not event.is_set()

        # Test: `msg.key` does not match `msg.from_id`
        msg.key = pubsubs_fsub[1].host.get_public_key().serialize()
        msg.signature = signature
        await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg)
        await trio.sleep(0.01)
        assert not event.is_set()

        # Test: invalid signature
        msg.key = pubsubs_fsub[0].host.get_public_key().serialize()
        msg.signature = b"\x12" * 100
        await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg)
        await trio.sleep(0.01)
        assert not event.is_set()

        # Finally, assert the signature indeed will pass validation
        msg.key = pubsubs_fsub[0].host.get_public_key().serialize()
        msg.signature = signature
        await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg)
        await trio.sleep(0.01)
        assert event.is_set()
コード例 #3
0
async def test_handle_talk(pubsubs_fsub):
    sub = await pubsubs_fsub[0].subscribe(TESTING_TOPIC)
    msg_0 = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[TESTING_TOPIC],
        data=b"1234",
        seqno=b"\x00" * 8,
    )
    await pubsubs_fsub[0].handle_talk(msg_0)
    msg_1 = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=["NOT_SUBSCRIBED"],
        data=b"1234",
        seqno=b"\x11" * 8,
    )
    await pubsubs_fsub[0].handle_talk(msg_1)
    assert (
        len(pubsubs_fsub[0].my_topics) == 1
        and sub == pubsubs_fsub[0].my_topics[TESTING_TOPIC]
    )
    assert sub.qsize() == 1
    assert (await sub.get()) == msg_0
コード例 #4
0
async def test_validate_msg(is_topic_1_val_passed, is_topic_2_val_passed):
    async with PubsubFactory.create_batch_with_floodsub(1) as pubsubs_fsub:

        def passed_sync_validator(peer_id, msg):
            return True

        def failed_sync_validator(peer_id, msg):
            return False

        async def passed_async_validator(peer_id, msg):
            await trio.hazmat.checkpoint()
            return True

        async def failed_async_validator(peer_id, msg):
            await trio.hazmat.checkpoint()
            return False

        topic_1 = "TEST_SYNC_VALIDATOR"
        topic_2 = "TEST_ASYNC_VALIDATOR"

        if is_topic_1_val_passed:
            pubsubs_fsub[0].set_topic_validator(topic_1, passed_sync_validator,
                                                False)
        else:
            pubsubs_fsub[0].set_topic_validator(topic_1, failed_sync_validator,
                                                False)

        if is_topic_2_val_passed:
            pubsubs_fsub[0].set_topic_validator(topic_2,
                                                passed_async_validator, True)
        else:
            pubsubs_fsub[0].set_topic_validator(topic_2,
                                                failed_async_validator, True)

        msg = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=[topic_1, topic_2],
            data=b"1234",
            seqno=b"\x00" * 8,
        )

        if is_topic_1_val_passed and is_topic_2_val_passed:
            await pubsubs_fsub[0].validate_msg(pubsubs_fsub[0].my_id, msg)
        else:
            with pytest.raises(ValidationError):
                await pubsubs_fsub[0].validate_msg(pubsubs_fsub[0].my_id, msg)
コード例 #5
0
async def test_get_msg_validators():
    async with PubsubFactory.create_batch_with_floodsub(1) as pubsubs_fsub:
        times_sync_validator_called = 0

        def sync_validator(peer_id, msg):
            nonlocal times_sync_validator_called
            times_sync_validator_called += 1

        times_async_validator_called = 0

        async def async_validator(peer_id, msg):
            nonlocal times_async_validator_called
            times_async_validator_called += 1
            await trio.hazmat.checkpoint()

        topic_1 = "TEST_VALIDATOR_1"
        topic_2 = "TEST_VALIDATOR_2"
        topic_3 = "TEST_VALIDATOR_3"

        # Register sync validator for topic 1 and 2
        pubsubs_fsub[0].set_topic_validator(topic_1, sync_validator, False)
        pubsubs_fsub[0].set_topic_validator(topic_2, sync_validator, False)

        # Register async validator for topic 3
        pubsubs_fsub[0].set_topic_validator(topic_3, async_validator, True)

        msg = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=[topic_1, topic_2, topic_3],
            data=b"1234",
            seqno=b"\x00" * 8,
        )

        topic_validators = pubsubs_fsub[0].get_msg_validators(msg)
        for topic_validator in topic_validators:
            if topic_validator.is_async:
                await topic_validator.validator(peer_id=IDFactory(), msg="msg")
            else:
                topic_validator.validator(peer_id=IDFactory(), msg="msg")

        assert times_sync_validator_called == 2
        assert times_async_validator_called == 1
コード例 #6
0
async def test_get_msg_validators(pubsubs_fsub):

    times_sync_validator_called = 0

    def sync_validator(peer_id, msg):
        nonlocal times_sync_validator_called
        times_sync_validator_called += 1

    times_async_validator_called = 0

    async def async_validator(peer_id, msg):
        nonlocal times_async_validator_called
        times_async_validator_called += 1

    topic_1 = "TEST_VALIDATOR_1"
    topic_2 = "TEST_VALIDATOR_2"
    topic_3 = "TEST_VALIDATOR_3"

    # Register sync validator for topic 1 and 2
    pubsubs_fsub[0].set_topic_validator(topic_1, sync_validator, False)
    pubsubs_fsub[0].set_topic_validator(topic_2, sync_validator, False)

    # Register async validator for topic 3
    pubsubs_fsub[0].set_topic_validator(topic_3, async_validator, True)

    msg = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[topic_1, topic_2, topic_3],
        data=b"1234",
        seqno=b"\x00" * 8,
    )

    topic_validators = pubsubs_fsub[0].get_msg_validators(msg)
    for topic_validator in topic_validators:
        if topic_validator.is_async:
            await topic_validator.validator(peer_id=ID(b"peer"), msg="msg")
        else:
            topic_validator.validator(peer_id=ID(b"peer"), msg="msg")

    assert times_sync_validator_called == 2
    assert times_async_validator_called == 1
コード例 #7
0
async def test_validate_msg(pubsubs_fsub, is_topic_1_val_passed, is_topic_2_val_passed):
    def passed_sync_validator(peer_id, msg):
        return True

    def failed_sync_validator(peer_id, msg):
        return False

    async def passed_async_validator(peer_id, msg):
        return True

    async def failed_async_validator(peer_id, msg):
        return False

    topic_1 = "TEST_SYNC_VALIDATOR"
    topic_2 = "TEST_ASYNC_VALIDATOR"

    if is_topic_1_val_passed:
        pubsubs_fsub[0].set_topic_validator(topic_1, passed_sync_validator, False)
    else:
        pubsubs_fsub[0].set_topic_validator(topic_1, failed_sync_validator, False)

    if is_topic_2_val_passed:
        pubsubs_fsub[0].set_topic_validator(topic_2, passed_async_validator, True)
    else:
        pubsubs_fsub[0].set_topic_validator(topic_2, failed_async_validator, True)

    msg = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[topic_1, topic_2],
        data=b"1234",
        seqno=b"\x00" * 8,
    )

    if is_topic_1_val_passed and is_topic_2_val_passed:
        await pubsubs_fsub[0].validate_msg(pubsubs_fsub[0].my_id, msg)
    else:
        with pytest.raises(ValidationError):
            await pubsubs_fsub[0].validate_msg(pubsubs_fsub[0].my_id, msg)
コード例 #8
0
async def test_push_msg(pubsubs_fsub, monkeypatch):
    msg_0 = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[TESTING_TOPIC],
        data=TESTING_DATA,
        seqno=b"\x00" * 8,
    )

    event = asyncio.Event()

    async def router_publish(*args, **kwargs):
        event.set()

    monkeypatch.setattr(pubsubs_fsub[0].router, "publish", router_publish)

    # Test: `msg` is not seen before `push_msg`, and is seen after `push_msg`.
    assert not pubsubs_fsub[0]._is_msg_seen(msg_0)
    await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_0)
    assert pubsubs_fsub[0]._is_msg_seen(msg_0)
    # Test: Ensure `router.publish` is called in `push_msg`
    await asyncio.wait_for(event.wait(), timeout=0.1)

    # Test: `push_msg` the message again and it will be reject.
    #   `router_publish` is not called then.
    event.clear()
    await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_0)
    await asyncio.sleep(0.01)
    assert not event.is_set()

    sub = await pubsubs_fsub[0].subscribe(TESTING_TOPIC)
    # Test: `push_msg` succeeds with another unseen msg.
    msg_1 = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[TESTING_TOPIC],
        data=TESTING_DATA,
        seqno=b"\x11" * 8,
    )
    assert not pubsubs_fsub[0]._is_msg_seen(msg_1)
    await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_1)
    assert pubsubs_fsub[0]._is_msg_seen(msg_1)
    await asyncio.wait_for(event.wait(), timeout=0.1)
    # Test: Subscribers are notified when `push_msg` new messages.
    assert (await sub.get()) == msg_1

    # Test: add a topic validator and `push_msg` the message that
    # does not pass the validation.
    # `router_publish` is not called then.
    def failed_sync_validator(peer_id, msg):
        return False

    pubsubs_fsub[0].set_topic_validator(TESTING_TOPIC, failed_sync_validator, False)

    msg_2 = make_pubsub_msg(
        origin_id=pubsubs_fsub[0].my_id,
        topic_ids=[TESTING_TOPIC],
        data=TESTING_DATA,
        seqno=b"\x22" * 8,
    )

    event.clear()
    await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_2)
    await asyncio.sleep(0.01)
    assert not event.is_set()
コード例 #9
0
async def test_push_msg(monkeypatch):
    async with PubsubFactory.create_batch_with_floodsub(1) as pubsubs_fsub:
        msg_0 = make_pubsub_msg(
            origin_id=pubsubs_fsub[0].my_id,
            topic_ids=[TESTING_TOPIC],
            data=TESTING_DATA,
            seqno=b"\x00" * 8,
        )

        @contextmanager
        def mock_router_publish():

            event = trio.Event()

            async def router_publish(*args, **kwargs):
                event.set()
                await trio.hazmat.checkpoint()

            with monkeypatch.context() as m:
                m.setattr(pubsubs_fsub[0].router, "publish", router_publish)
                yield event

        with mock_router_publish() as event:
            # Test: `msg` is not seen before `push_msg`, and is seen after `push_msg`.
            assert not pubsubs_fsub[0]._is_msg_seen(msg_0)
            await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_0)
            assert pubsubs_fsub[0]._is_msg_seen(msg_0)
            # Test: Ensure `router.publish` is called in `push_msg`
            with trio.fail_after(0.1):
                await event.wait()

        with mock_router_publish() as event:
            # Test: `push_msg` the message again and it will be reject.
            #   `router_publish` is not called then.
            await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_0)
            await trio.sleep(0.01)
            assert not event.is_set()

            sub = await pubsubs_fsub[0].subscribe(TESTING_TOPIC)
            # Test: `push_msg` succeeds with another unseen msg.
            msg_1 = make_pubsub_msg(
                origin_id=pubsubs_fsub[0].my_id,
                topic_ids=[TESTING_TOPIC],
                data=TESTING_DATA,
                seqno=b"\x11" * 8,
            )
            assert not pubsubs_fsub[0]._is_msg_seen(msg_1)
            await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_1)
            assert pubsubs_fsub[0]._is_msg_seen(msg_1)
            with trio.fail_after(0.1):
                await event.wait()
            # Test: Subscribers are notified when `push_msg` new messages.
            assert (await sub.get()) == msg_1

        with mock_router_publish() as event:
            # Test: add a topic validator and `push_msg` the message that
            # does not pass the validation.
            # `router_publish` is not called then.
            def failed_sync_validator(peer_id, msg):
                return False

            pubsubs_fsub[0].set_topic_validator(TESTING_TOPIC,
                                                failed_sync_validator, False)

            msg_2 = make_pubsub_msg(
                origin_id=pubsubs_fsub[0].my_id,
                topic_ids=[TESTING_TOPIC],
                data=TESTING_DATA,
                seqno=b"\x22" * 8,
            )

            await pubsubs_fsub[0].push_msg(pubsubs_fsub[0].my_id, msg_2)
            await trio.sleep(0.01)
            assert not event.is_set()