-
Notifications
You must be signed in to change notification settings - Fork 1
Add regression tests for client module #274
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?
Conversation
|
@pott-cho Would you mind reviewing this PR? |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #274 +/- ##
==========================================
+ Coverage 10.96% 13.04% +2.07%
==========================================
Files 7 7
Lines 529 529
==========================================
+ Hits 58 69 +11
+ Misses 471 460 -11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
|
||
| // ========================================================================= | ||
| // Handshake Tests | ||
| // ========================================================================= |
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.
Since client.rs is a module responsible for generating certificates, testing handshake behavior in this location does not seem appropriate. Please remove the corresponding test.
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.
Thanks for the feedback. I see your point regarding the module's responsibility.
However, I'd like to clarify that client.rs is not responsible solely for certificate parsing; it also exports the config() function, which constructs the final quinn::Endpoint with a specific TLS configuration.
The intention behind these tests is to serve as regression tests for the config() logic itself. We need to verify that the generated Endpoint actually works with the provided certificate chains, and some issues (like chain ordering, missing SANs, or trust validation) can only be detected during an actual TLS handshake.
Since this crate (crusher) is structured as a binary crate without a lib.rs, moving those tests to the tests/ directory would require exposing internal modules or restructuring the project. Therefore, I placed them here to ensure the client configuration is validated within the module's scope.
Do you think we should keep this validation here to ensure reliability, or would you still prefer a different approach given the structure?
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.
I understand your reasoning. Given that the overall approach of the test code is to thoroughly cover as many cases as possible, having these tests located here also seems reasonable.
That said, there appears to be a significant amount of duplicated logic across the handshake tests. To improve readability and maintainability, it would be good to extract the shared parts into a helper function.
For example, you might consider factoring the common logic into a function like run_handshake.
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.
Thanks for your feedback!
I will split common logic.
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.
Done.
sophie-cluml
left a comment
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.
Since we should handle changes to the production code with great caution while adding tests, could you extract production code changes into a separate issue and handle it in a separate PR please?
9431d60 to
42fbbf2
Compare
Done. |
42fbbf2 to
d424a4c
Compare
|
@sophie-cluml I changed the visibility of Should I add a trivial test case verifying this constant to satisfy the checker, or would you prefer adjusting the CI threshold to allow for small drops? |
sophie-cluml
left a comment
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.
I noticed there are quite a few #[ignore] tests in this PR. Since they take up a significant number of lines, it can be distracting for reviewers to review code that isn't intended to be active yet. It also looks like some fixtures are only used by these ignored tests.
While there are several ways to handle this, I think the cleanest approach would be to remove the ignored tests and their associated fixtures from this PR entirely and track them in a separate issue. If that’s not feasible, completing the tests now or moving them into a separate commit would also work.
Personally, I don't think adding a trivial test is necessary, nor do we need to adjust the CI threshold. Maintainers evaluate these drops on a case-by-case basis to determine whether meaningful tests are actually missing or if the drop is acceptable in merging process. However, if the repository maintainer has a different view, please follow his guidance. cc @kimhanbeom |
d424a4c to
e580a53
Compare
|
Reply to #274 (review): I removed all pending tests and fixture only used by those tests. |
439f949 to
4c9c0f0
Compare
|
Following the review in #274 (review), I initially removed all functions and fixtures prefixed with However, after giving it some more thought, I've changed my mind. The reasons are as follows:
Does this sound reasonable to you? |
|
@JonghoKim-jj |
|
@pott-cho That makes sense to me. |
|
@JonghoKim-jj |
sophie-cluml
left a comment
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.
Thanks for the comprehensive test suite. Upon reviewing, I found a few points for your consideration:
-
CA loading in
to_ca_certs: It currently loads only the first certificate. I think we should eventually load the entire chain to support CA bundles. Could you please track this in a separate follow-up issue? -
Safety in
Certs::try_new:assert!can cause panics on invalid input, which contradicts our panic handling policy. Could you please address this hardening in a separate follow-up PR? -
(request for change)
CertHintForServercomments: Some comments seem to contradict the actual test logic. For example,fullchain_root_certacts as a Client CA in the code but is documented as a server issuer. Also, the namefullchain_root_certfeels a bit awkward to me, since a root certificate is a trust anchor, not a chain.
|
@sophie-cluml I've created 2 issues: #279 #280 |
|
Based on comment #274 (review),
|
- Define rstest fixtures - Add test cases for future implementation with prefix "pending_"
- CertHintForServer -> ServerCertSetup - hint -> cert_setup
248b211 to
5f63aef
Compare
Closes #263
Objective
This PR adds regression tests for the
clientmodule to verify current behavior and prepare for future security updates.What this PR introduces
1. Scenario-driven Regression Coverage
A comprehensive set of test cases mapping various TLS certificate states and edge cases.
This ensures that the module's behavior—especially regarding certificate bundle handling—is deterministic and verified.
2. Tests as "Executable Specifications"
We are introducing tests that define not just current behavior, but desired behavior.
3. Zero CI Noise (Stability by Design)
Tests for features/validations not yet implemented are marked with
#[ignore]and prefixed withpending_.Context & Rationale: Why is the test suite so large?
While
client.rsis currently concise (~90 lines), it manages security-sensitive invariants (TLS).The current implementation has minimal validation, which increases the risk of silent misconfiguration.
We invested in a comprehensive test suite (1000+ lines) to:
Lock in correct behavior before refactoring or expanding validation logic.
Make subtle correctness rules (e.g., CA mismatches, chain ordering) explicit in code rather than relying on tribal knowledge.
Implementation Notes:
rstestThis suite is implemented using the
rstestcrate as a lightweight way to express fixtures and parameterized cases in Rust. We chose it for:It allows us to cover the combinatorial explosion of TLS edge cases with minimal boilerplate. Adding new scenarios becomes a data-entry task rather than writing new functions.
rstestis widely adopted in the Rust community (55M+ downloads on Crates.io).rstestintegrates seamlessly withtokio::test, allowing us to write parameterized async tests without friction.Additionally,
googletest-rustexplicitly mentions interoperability withrstest, confirming it fits well with professional, async-heavy workflows.Future Work
clientmodule lacks specific validation functions. We need to discuss and design a proper validation layer to enforce the security rules defined in these tests.