Example #1
0
def test_buggy_done_handler_is_logged():
    def on_done(req):
        undefined_var

    with MyRPCProcessor() as rpc:
        # First for a request
        request = RPCRequestOut('add_async', [1], on_done)
        rpc.send_request(request)
        request.cancel()
        with rpc.expect_asyncio_log('Exception in callback'):
            rpc.yield_to_loop()

    with MyRPCProcessor() as rpc:
        # Now a request in a batch
        batch = RPCBatchOut()
        batch.add_request('add_async', [2], on_done)
        rpc.send_batch(batch)
        batch.items[0].cancel()
        with rpc.expect_asyncio_log('Exception in callback'):
            rpc.yield_to_loop()

    with MyRPCProcessor() as rpc:
        # Finally the batch itself
        batch = RPCBatchOut()
        batch.add_request('add_async', [1])
        rpc.send_batch(batch, on_done)
        batch.cancel()
        with rpc.expect_asyncio_log('Exception in callback'):
            rpc.yield_to_loop()
Example #2
0
 def send_batch():
     nonlocal batch_done, request_done
     batch_done = request_done = 0
     batch = RPCBatchOut()
     batch.add_request('add_async', [1], on_request_done)
     batch.add_request('add_async', [1], on_request_done)
     batch.add_notification('add_async', [])
     batch.add_request('add_async', [1], None)
     rpc.send_batch(batch, on_batch_done)
     return batch
Example #3
0
def test_all_notification_batch():
    with MyRPCProcessor() as rpc:
        batch = RPCBatchOut()
        batch.add_notification('echo', ["ping"])
        batch.add_notification('add')  # Erroneous; gets swallowed anyway
        rpc.send_batch(batch)
        # Fake reeiving it
        rpc.message_received(rpc.responses.pop())

        # Now process the request jobs, generating queued response messages
        rpc.process_all()

        # There is no response!
        assert rpc.all_done()
Example #4
0
 def send_batch():
     batch = RPCBatchOut()
     batch.add_request('add', [1, 5, 10], handler)
     batch.add_request('echo', ["ping"], handler)
     rpc.send_batch(batch)
     return batch
Example #5
0
def test_batch_round_trip():
    def handle_add(request):
        assert request.method in ('add', 'add_async')
        assert request.args == [1, 5, 10]
        assert request.result() == 16
        handled.append(request.method)

    def handle_echo(request):
        assert request.method == 'echo'
        assert request.result() == request.args[0]
        handled.append(request.method)

    def handle_bad_echo(request):
        assert request.method == 'echo'
        assert not request.args
        result = request.exception()
        assert isinstance(result, RPCError)
        assert result.code == rpc.protocol.INVALID_ARGS
        handled.append('bad_echo')

    with MyRPCProcessor() as rpc:
        handled = []
        batch_message = None

        batch = RPCBatchOut()
        batch.add_request('add', [1, 5, 10], handle_add)
        batch.add_request('add_async', [1, 5, 10], handle_add)
        batch.add_request('echo', [], handle_bad_echo)  # An erroneous request
        batch.add_notification('add')  # Erroneous; gets swallowed anyway
        batch.add_request('echo', ["ping"], handle_echo)
        rpc.send_batch(batch)
        assert rpc.sent_count == len(batch)
        batch_message = rpc.responses.pop()

        assert not rpc.debug_messages
        assert not rpc.error_messages
        # Fake receiving it.  This processes the request and sees invalid
        # requests, and creates jobs to process the valid requests
        rpc.message_received(batch_message)
        assert not rpc.all_done()

        # Now process the request jobs, generating queued response messages
        rpc.process_all()
        assert rpc.debug_message_count == 2  # Both notification and request
        assert not rpc.error_messages
        rpc.debug_clear()

        # Get the batch response and send it back to ourselves
        response, = rpc.consume_responses()
        assert rpc.all_done()

        # Process the batch response
        rpc.message_received(response)
        rpc.yield_to_loop()
        assert rpc.all_done()

        assert sorted(handled) == ['add', 'add_async', 'bad_echo', 'echo']

        assert rpc.error_message_count == 0
        assert rpc.debug_message_count == 1  # Only request
Example #6
0
def test_RPCBatchOut():
    with MyRPCProcessor() as rpc:
        batch = RPCBatchOut()
        assert isinstance(batch, RPCBatch)
        with pytest.raises(RuntimeError):
            rpc.send_batch(batch)

        batch.add_notification("method")
        batch.add_request("method")
        batch.add_request("method", [])
        batch.add_notification("method", [])
        batch.add_request("method", {})
        batch.add_notification("method", [])

        request_ids = batch.request_ids()
        assert len(batch) == 6
        assert len(request_ids) == 3
        low = min(request_ids)
        high = low + len(request_ids)
        assert request_ids == frozenset(range(low, high))
        # Simple send works
        rpc.send_batch(batch)
        assert request_ids in rpc.requests
Example #7
0
def test_outgoing_batch_request_cancellation_and_setting():
    '''Tests cancelling outgoing batch requests.'''
    batch_done = request_done = 0

    def on_batch_done(batch):
        assert isinstance(batch, RPCBatchOut)
        assert batch.done()
        nonlocal batch_done
        batch_done += 1

    def on_request_done(request):
        assert isinstance(request, RPCRequestOut)
        assert request.done()
        nonlocal request_done
        request_done += 1

    with MyRPCProcessor() as rpc:

        def send_batch():
            nonlocal batch_done, request_done
            batch_done = request_done = 0
            batch = RPCBatchOut()
            batch.add_request('add_async', [1], on_request_done)
            batch.add_request('add_async', [1], on_request_done)
            batch.add_notification('add_async', [])
            batch.add_request('add_async', [1], None)
            rpc.send_batch(batch, on_batch_done)
            return batch

        # First, cancel the bzatch
        batch = send_batch()
        batch.cancel()
        rpc.yield_to_loop()
        assert batch.cancelled()
        for request in batch.requests():
            assert request.cancelled()
        assert batch_done == 1
        assert request_done == 2
        assert not rpc.requests

        # Now set its result
        batch = send_batch()
        batch.set_result(1)
        rpc.yield_to_loop()
        assert batch.result() == 1
        for request in batch.requests():
            assert request.cancelled()
        assert batch_done == 1
        assert request_done == 2
        assert not rpc.requests

        # Now set its exception
        batch = send_batch()
        batch.set_exception(ValueError())
        rpc.yield_to_loop()
        with pytest.raises(ValueError):
            batch.result()
        for request in batch.requests():
            assert request.cancelled()
        assert batch_done == 1
        assert request_done == 2
        assert not rpc.requests

        # Now set one before cancelling
        batch = send_batch()
        batch.items[0].set_result(1)
        batch.cancel()
        rpc.yield_to_loop()
        assert batch.cancelled()
        assert batch.items[0].result() == 1
        assert batch.items[1].cancelled()
        assert batch_done == 1
        assert request_done == 2
        assert not rpc.requests

        # Now cancel all manually; check the batch is also flagged done
        batch = send_batch()
        for request in batch.requests():
            request.set_result(0)
        rpc.yield_to_loop()
        assert batch.done() and not batch.cancelled()
        assert len(list(batch.requests())) == 3
        for request in batch.requests():
            assert request.result() == 0
        assert batch_done == 1
        assert request_done == 2
        assert batch.result() is False
        assert not rpc.requests

        # Now send a notification batch.  Assert it is flagged done
        # automatically
        batch = RPCBatchOut()
        batch.add_notification('add_async', [1])
        rpc.send_batch(batch, on_batch_done)
        assert not rpc.requests
        assert batch.done()