Skip to content

test(pyamber): add unit tests for Python AsyncRPCServer#6492

Open
eugenegujing wants to merge 1 commit into
apache:mainfrom
eugenegujing:test/async-rpc-server-spec
Open

test(pyamber): add unit tests for Python AsyncRPCServer#6492
eugenegujing wants to merge 1 commit into
apache:mainfrom
eugenegujing:test/async-rpc-server-spec

Conversation

@eugenegujing

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Adds test_async_rpc_server.py (new, 26 tests) for the Python worker's AsyncRPCServer (amber/src/main/python/core/architecture/rpc/async_rpc_server.py).

What the tests cover:

  • Handler map: method names are stored lowercased and looked up correctly.
  • Stream wrapper: the fake stream keeps returning the same request on every read, and keeps only the last message the handler sends.
  • Normal calls: a reply goes back with the right command id and return value, the handler gets the unwrapped request, lookup ignores case, and a missing request reaches the handler as None.
  • Errors: a handler that raises, and a call to an unknown method, both come back as a ControlError marked ErrorLanguage.PYTHON (including when the error has no message).
  • Fire-and-forget: a negative command id sends no reply (on success, error, and unknown-method paths), while command id 0 still replies.
  • Reply routing: the reply goes to the context's sender/receiver when both are set, otherwise it falls back to swapping the sender and receiver of the incoming channel; either way the reply channel is a control channel.

Any related issues, documentation, discussions?

Closes #6485

How was this PR tested?

cd amber/src/main/python
python -m pytest ../../test/python/core/architecture/rpc/ -v
# 41 passed (26 new AsyncRPCServer tests + 15 existing AsyncRPCClient tests)

Was this PR authored or co-authored using generative AI tooling?

Co-authored by: Claude Code (Fable 5)

Add the first direct unit tests for amber/src/main/python/core/architecture/rpc/async_rpc_server.py, previously only reached indirectly through MainLoop tests.

The 26 tests cover: handler-map construction (lowercased method names), the synthetic stream wrapper, success dispatch (command_id round-trip, unwrapped command, case-insensitive lookup), error wrapping into ControlError with ErrorLanguage.PYTHON (raising handler and unknown method), no-reply suppression for negative command ids, and reply routing (context-based with fallback to swapping the incoming channel).

Also pins two surprising current behaviors as characterization tests: a handler that returns no result (or a wrong-typed one) silently yields an empty ControlReturn, and unknown-method error messages carry str(KeyError) quotes.
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • No candidates found from git blame history.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.31%. Comparing base (e08b7f3) to head (bec15bf).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6492      +/-   ##
============================================
+ Coverage     70.28%   70.31%   +0.03%     
  Complexity     3397     3397              
============================================
  Files          1142     1142              
  Lines         44844    44844              
  Branches       4948     4948              
============================================
+ Hits          31517    31533      +16     
+ Misses        11682    11666      -16     
  Partials       1645     1645              
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø) Carriedforward from e08b7f3
agent-service 76.76% <ø> (ø) Carriedforward from e08b7f3
amber 66.66% <ø> (ø) Carriedforward from e08b7f3
computing-unit-managing-service 17.72% <ø> (ø) Carriedforward from e08b7f3
config-service 52.30% <ø> (ø) Carriedforward from e08b7f3
file-service 65.63% <ø> (ø) Carriedforward from e08b7f3
frontend 69.02% <ø> (ø) Carriedforward from e08b7f3
notebook-migration-service 78.94% <ø> (ø) Carriedforward from e08b7f3
pyamber 91.57% <ø> (+0.37%) ⬆️
workflow-compiling-service 55.14% <ø> (ø) Carriedforward from e08b7f3

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 4 better · 🔴 3 worse · ⚪ 8 noise (<±5%) · 0 without baseline

Compared against main f722c26 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 378 0.231 25,880/31,565/31,565 us 🔴 +17.2% / 🔴 +119.8%
🟢 bs=100 sw=10 sl=64 798 0.487 125,439/137,098/137,098 us 🟢 -8.5% / 🔴 +38.3%
bs=1000 sw=10 sl=64 914 0.558 1,095,829/1,122,216/1,122,216 us ⚪ within ±5% / 🔴 +20.4%
Baseline details

Latest main f722c26 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 378 tuples/sec 407 tuples/sec 831.47 tuples/sec -7.1% -54.5%
bs=10 sw=10 sl=64 MB/s 0.231 MB/s 0.249 MB/s 0.507 MB/s -7.2% -54.5%
bs=10 sw=10 sl=64 p50 25,880 us 22,075 us 11,844 us +17.2% +118.5%
bs=10 sw=10 sl=64 p95 31,565 us 35,454 us 14,359 us -11.0% +119.8%
bs=10 sw=10 sl=64 p99 31,565 us 35,454 us 18,888 us -11.0% +67.1%
bs=100 sw=10 sl=64 throughput 798 tuples/sec 809 tuples/sec 1,089 tuples/sec -1.4% -26.7%
bs=100 sw=10 sl=64 MB/s 0.487 MB/s 0.494 MB/s 0.665 MB/s -1.4% -26.7%
bs=100 sw=10 sl=64 p50 125,439 us 121,919 us 92,503 us +2.9% +35.6%
bs=100 sw=10 sl=64 p95 137,098 us 149,831 us 99,121 us -8.5% +38.3%
bs=100 sw=10 sl=64 p99 137,098 us 149,831 us 112,422 us -8.5% +21.9%
bs=1000 sw=10 sl=64 throughput 914 tuples/sec 919 tuples/sec 1,117 tuples/sec -0.5% -18.2%
bs=1000 sw=10 sl=64 MB/s 0.558 MB/s 0.561 MB/s 0.682 MB/s -0.5% -18.2%
bs=1000 sw=10 sl=64 p50 1,095,829 us 1,091,889 us 910,046 us +0.4% +20.4%
bs=1000 sw=10 sl=64 p95 1,122,216 us 1,114,478 us 950,716 us +0.7% +18.0%
bs=1000 sw=10 sl=64 p99 1,122,216 us 1,114,478 us 985,832 us +0.7% +13.8%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,529.03,200,128000,378,0.231,25879.56,31565.06,31565.06
1,100,10,64,20,2505.23,2000,1280000,798,0.487,125439.12,137097.54,137097.54
2,1000,10,64,20,21884.60,20000,12800000,914,0.558,1095829.23,1122216.08,1122216.08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds unit-test coverage for the Python worker’s AsyncRPCServer control-message dispatch logic by introducing a focused test suite under amber/src/test/python. This improves confidence in RPC handler dispatch, error wrapping, fire-and-forget semantics, and reply routing without needing to spin up the full worker context.

Changes:

  • Added a new test_async_rpc_server.py suite exercising handler-map normalization, stream wrapping, success/error paths, no-reply behavior, and reply routing.
  • Uses a stubbed AsyncRPCHandlerInitializer for __init__ coverage and a __new__-constructed server for receive()-path unit tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +45 to +53
def _make_handler(func) -> grpclib.const.Handler:
"""Builds a real grpclib Handler namedtuple around an async callable.

AsyncRPCServer only ever touches `.func`, but using the real namedtuple
keeps the stub shape identical to what AsyncRPCHandlerInitializer yields.
"""
return grpclib.const.Handler(
func, Cardinality.UNARY_UNARY, ControlRequest, ControlReturn
)
Comment on lines +69 to +71
def _make_invocation(
method_name: str, command_id: int, context: AsyncRpcContext = None
) -> ControlInvocation:
@eugenegujing eugenegujing changed the title test(amber): add unit tests for Python AsyncRPCServer test(pyamber): add unit tests for Python AsyncRPCServer Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add unit test coverage for Python AsyncRPCServer

3 participants