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()
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
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()
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
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
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
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()