Пример #1
0
async def test_p2p_api_disconnect_fn(bob, alice):
    async with P2PAPI().as_behavior().apply(alice):
        async with P2PAPI().as_behavior().apply(bob):
            alice_p2p_api = alice.get_logic('p2p', P2PAPI)
            bob_p2p_api = bob.get_logic('p2p', P2PAPI)

            alice_p2p_api.disconnect(DisconnectReason.CLIENT_QUITTING)

            assert alice_p2p_api.local_disconnect_reason is DisconnectReason.CLIENT_QUITTING
            assert bob_p2p_api.local_disconnect_reason is None
Пример #2
0
async def test_p2p_api_disconnect_fn_nowait(bob, alice):
    async with P2PAPI().as_behavior().apply(alice):
        async with P2PAPI().as_behavior().apply(bob):
            alice_p2p_api = alice.get_logic('p2p', P2PAPI)
            bob_p2p_api = bob.get_logic('p2p', P2PAPI)

            alice_p2p_api.disconnect_nowait(DisconnectReason.CLIENT_QUITTING)
            await asyncio.wait_for(bob.events.cancelled.wait(), timeout=1)

            assert alice_p2p_api.remote_disconnect_reason is None
            assert alice_p2p_api.local_disconnect_reason is DisconnectReason.CLIENT_QUITTING

            assert bob_p2p_api.remote_disconnect_reason is DisconnectReason.CLIENT_QUITTING
            assert bob_p2p_api.local_disconnect_reason is None
Пример #3
0
    async def _run(self) -> None:
        async with AsyncExitStack() as stack:
            await stack.enter_async_context(P2PAPI().as_behavior().apply(
                self.connection))
            self.p2p_api = self.connection.get_logic('p2p', P2PAPI)

            for behavior in self.get_behaviors():
                if behavior.should_apply_to(self.connection):
                    await stack.enter_async_context(
                        behavior.apply(self.connection))

            # setup handler for protocol messages to pass messages to subscribers
            for protocol in self.connection.get_protocols():
                self.connection.add_protocol_handler(
                    type(protocol),
                    self._handle_subscriber_message,
                )

            self.setup_protocol_handlers()

            # The `boot` process is run in the background to allow the `run` loop
            # to continue so that all of the Peer APIs can be used within the
            # `boot` task.
            self.run_child_service(self.boot_manager)

            # Trigger the connection to start feeding messages though the handlers
            self.connection.start_protocol_streams()
            self.ready.set()

            await self.cancellation()
Пример #4
0
async def test_p2p_api_applies_DisconnectIfIdle(bob, alice):
    p2p_api = P2PAPI()
    for behavior in p2p_api._behaviors:
        if isinstance(behavior.logic, DisconnectIfIdle):
            break
    else:
        raise AssertionError("DisconnectIfIdle not among P2PAPI behaviors")
Пример #5
0
async def test_p2p_api_properties(bob, alice):
    async with P2PAPI().as_behavior().apply(alice):
        assert alice.has_logic('p2p')
        p2p_api = alice.get_logic('p2p', P2PAPI)

        assert p2p_api.client_version_string == 'bob'
        assert p2p_api.safe_client_version_string == 'bob'
Пример #6
0
async def test_p2p_api_triggers_cancellation_on_disconnect(bob, alice):
    async with P2PAPI().as_behavior().apply(alice):
        p2p_api = alice.get_logic('p2p', P2PAPI)
        bob.get_base_protocol().send_disconnect(DisconnectReason.client_quitting)
        await asyncio.wait_for(alice.events.cancelled.wait(), timeout=1)
        assert p2p_api.remote_disconnect_reason is DisconnectReason.client_quitting
        assert p2p_api.local_disconnect_reason is None
Пример #7
0
async def test_p2p_api_pongs_when_pinged(bob, alice):
    async with P2PAPI().as_behavior().apply(alice):
        got_pong = asyncio.Event()

        async def handle_pong(connection, msg):
            got_pong.set()
        bob.add_command_handler(Pong, handle_pong)
        bob.get_base_protocol().send_ping()
        await asyncio.wait_for(got_pong.wait(), timeout=1)
Пример #8
0
    async def run(self) -> None:
        self._start_time = time.monotonic()
        self.connection.add_command_handler(Disconnect, cast(HandlerFn, self._handle_disconnect))
        try:
            async with contextlib.AsyncExitStack() as stack:
                fut = await stack.enter_async_context(P2PAPI().as_behavior().apply(self.connection))
                futures = [fut]
                self.p2p_api = self.connection.get_logic('p2p', P2PAPI)

                for behavior in self.get_behaviors():
                    if behavior.should_apply_to(self.connection):
                        future = await stack.enter_async_context(behavior.apply(self.connection))
                        futures.append(future)

                self.connection.add_msg_handler(self._handle_subscriber_message)

                self.setup_protocol_handlers()

                # The `boot` process is run in the background to allow the `run` loop
                # to continue so that all of the Peer APIs can be used within the
                # `boot` task.
                self.manager.run_child_service(self.boot_manager)

                # Trigger the connection to start feeding messages though the handlers
                self.connection.start_protocol_streams()
                self.ready.set()

                try:
                    await wait_first(futures)
                except asyncio.CancelledError:
                    raise
                except BaseException:
                    self.logger.exception("Behavior finished before us, cancelling ourselves")
                    self.manager.cancel()
        finally:
            for callback in self._finished_callbacks:
                callback(self)
            if (self.p2p_api.local_disconnect_reason is None and
                    self.p2p_api.remote_disconnect_reason is None):
                self._send_disconnect(DisconnectReason.CLIENT_QUITTING)
            # We run as a child service of the connection, but we don't want to leave a connection
            # open if somebody cancels just us, so this ensures the connection gets closed as well.
            if not self.connection.get_manager().is_cancelled:
                self.logger.debug("Connection hasn't been cancelled yet, doing so now")
                self.connection.get_manager().cancel()
 def get_behaviors(self) -> Tuple[BehaviorAPI, ...]:
     return (P2PAPI().as_behavior(), )