-
Notifications
You must be signed in to change notification settings - Fork 114
[router][test] Add unit tests to improve venice-router coverage #2481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[router][test] Add unit tests to improve venice-router coverage #2481
Conversation
Add 6 new test classes with 58 test methods to increase venice-router test coverage from 13.51% to 54%: - HealthCheckHandlerTest: Health check endpoint handler tests - RouterSslVerificationHandlerTest: SSL enforcement and metrics tests - RouterThrottleHandlerTest: Early throttling and quota enforcement tests - HelixGroupSelectorTest: Routing strategy selection tests - HttpClient5StorageNodeClientTest: HTTP/2 client lifecycle tests - ApacheHttpAsyncStorageNodeClientTest: Apache async client pool tests Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Code Review SummaryFiles reviewed: 6 Review DetailsAll 6 test files were reviewed for:
No actionable issues found. The test code follows established patterns:
Reviewed by Claude Code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds comprehensive unit test coverage for the Venice router module, increasing coverage from 13.51% to 54%. The PR introduces 6 new test classes with 58 test methods covering critical router components including request handlers (health check, SSL verification, throttling), HTTP clients (Apache async and HTTP/2), and routing strategies (Helix group selection).
Changes:
- Added unit tests for RouterThrottleHandler to verify early throttling logic, quota enforcement, and proper handling of single-get, batch-get, and compute requests
- Added unit tests for RouterSslVerificationHandler to ensure SSL enforcement, metrics tracking, and proper handling of SSL handshake events
- Added unit tests for HealthCheckHandler to validate health check endpoint behavior for OPTIONS and admin requests
- Added unit tests for HttpClient5StorageNodeClient and ApacheHttpAsyncStorageNodeClient to test client lifecycle, pool management, and configuration options
- Added unit tests for HelixGroupSelector to verify routing strategy selection (round-robin vs. least-loaded) and proper delegation to underlying components
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| HttpClient5StorageNodeClientTest.java | Tests HTTP/2 client construction, lifecycle (start/close), configuration variations (pool size, cipher checks), and SSL factory requirement |
| ApacheHttpAsyncStorageNodeClientTest.java | Tests Apache async client in pool and per-node modes, DNS caching, client selection, connection warming, and lifecycle management |
| HelixGroupSelectorTest.java | Tests routing strategy instantiation (round-robin, least-loaded), group selection logic, delegation to repository, and even distribution patterns |
| RouterThrottleHandlerTest.java | Tests early throttling enable/disable, request type handling (single-get, batch-get, compute, admin), quota enforcement, and 429 responses |
| RouterSslVerificationHandlerTest.java | Tests SSL handler detection in pipeline and parent pipeline, SSL requirement enforcement, handshake event handling, and metrics recording |
| HealthCheckHandlerTest.java | Tests OPTIONS request handling, admin endpoint health checks, pass-through for non-health-check requests, exception handling, and empty response bodies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Assert.assertEquals(response.status(), HttpResponseStatus.TOO_MANY_REQUESTS); | ||
| verify(routerStats, times(1)).recordRouterThrottledRequest(); | ||
| verify(ctx, never()).fireChannelRead(any()); |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FullHttpResponse object captured from the ArgumentCaptor is a Netty reference-counted object that must be explicitly released to prevent memory leaks. Wrap the assertions in a try-finally block and call response.release() in the finally block, following the pattern used consistently in HealthCheckHandlerTest.
| Assert.assertEquals(response.status(), HttpResponseStatus.TOO_MANY_REQUESTS); | |
| verify(routerStats, times(1)).recordRouterThrottledRequest(); | |
| verify(ctx, never()).fireChannelRead(any()); | |
| try { | |
| Assert.assertEquals(response.status(), HttpResponseStatus.TOO_MANY_REQUESTS); | |
| verify(routerStats, times(1)).recordRouterThrottledRequest(); | |
| verify(ctx, never()).fireChannelRead(any()); | |
| } finally { | |
| response.release(); | |
| } |
| FullHttpResponse response = (FullHttpResponse) captor.getValue(); | ||
| Assert.assertEquals(response.status(), HttpResponseStatus.INTERNAL_SERVER_ERROR); | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FullHttpResponse object captured from the ArgumentCaptor is a Netty reference-counted object that must be explicitly released to prevent memory leaks. Wrap the assertions in a try-finally block and call response.release() in the finally block, following the pattern used consistently in HealthCheckHandlerTest.
| FullHttpResponse response = (FullHttpResponse) captor.getValue(); | ||
| Assert.assertEquals(response.status(), HttpResponseStatus.TOO_MANY_REQUESTS); | ||
| verify(routerStats, times(1)).recordRouterThrottledRequest(); |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FullHttpResponse object captured from the ArgumentCaptor is a Netty reference-counted object that must be explicitly released to prevent memory leaks. Wrap the assertions in a try-finally block and call response.release() in the finally block, following the pattern used consistently in HealthCheckHandlerTest.
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); | ||
| verify(securityStats, times(1)).recordNonSslRequest(); | ||
| verify(ctx, times(1)).close(); | ||
| verify(ctx, never()).fireChannelRead(any()); |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FullHttpResponse object captured from the ArgumentCaptor is a Netty reference-counted object that must be explicitly released to prevent memory leaks. Wrap the assertions in a try-finally block and call response.release() in the finally block, following the pattern used consistently in HealthCheckHandlerTest.
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); | |
| verify(securityStats, times(1)).recordNonSslRequest(); | |
| verify(ctx, times(1)).close(); | |
| verify(ctx, never()).fireChannelRead(any()); | |
| try { | |
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); | |
| verify(securityStats, times(1)).recordNonSslRequest(); | |
| verify(ctx, times(1)).close(); | |
| verify(ctx, never()).fireChannelRead(any()); | |
| } finally { | |
| response.release(); | |
| } |
| verify(ctx).writeAndFlush(captor.capture()); | ||
|
|
||
| FullHttpResponse response = (FullHttpResponse) captor.getValue(); | ||
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FullHttpResponse object captured from the ArgumentCaptor is a Netty reference-counted object that must be explicitly released to prevent memory leaks. Wrap the assertions in a try-finally block and call response.release() in the finally block, following the pattern used consistently in HealthCheckHandlerTest.
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); | |
| try { | |
| Assert.assertEquals(response.status(), HttpResponseStatus.FORBIDDEN); | |
| } finally { | |
| response.release(); | |
| } |
Problem Statement
Venice-router module had very low test coverage (13.51%), with critical components like storage node clients, request handlers, and routing strategies having minimal or no unit tests.
Solution
Added 6 new test classes with 58 test methods to increase coverage from 13.51% to 54%:
Code changes
Concurrency-Specific Checks
How was this PR tested?
All 58 tests pass. Ran 3 consecutive times to verify no flakiness.
Does this PR introduce any user-facing or breaking changes?