Skip to content

tests: improve unit test coverage and set threshold#296

Merged
pdp2121 merged 19 commits into
mainfrom
improve-unit-test
May 22, 2026
Merged

tests: improve unit test coverage and set threshold#296
pdp2121 merged 19 commits into
mainfrom
improve-unit-test

Conversation

@pdp2121

@pdp2121 pdp2121 commented May 4, 2026

Copy link
Copy Markdown
Collaborator

High Level Overview of Change

Brings xrpl-rust unit-test coverage in line with 85% line gate by adding ~120 unit tests to previously-untested or low-coverage files, and reframing what "unit-test coverage" measures.

Tests added

  • 29 request models — were all at 0%, now 84–100%
  • 3 pseudo-transactions (enable_amendment, set_fee, unl_modify) — 0% → 91–94%
  • xchain_add_claim_attestation (0% → 92%), xchain_commit (45% → 95%)
  • 3 ledger objects (bridge, xchain_owned_claim_id, objects/mod.rs) — 0% → 87–100%
  • utils/str_conversion and utils/get_xchain_claim_id — 0% → 98–100%
  • models/results/mod.rs dispatcher (17% → 58%), and low-coverage result types account_tx/ledger_entry/tx/nftoken — 0–34% → 98–100%
  • txn_parser internals (nodes, parser, utils/mod) — 51–62% → 97–100%
  • 6 lower-coverage transaction models (check_cancel, escrow_cancel, set_regular_key, ticket_create, payment_channel_fund, check_create) — 68–80% → 97%
  • transaction/mod.rs (calculate_fee_per_transaction_type) — 0% → 44%

CI changes

  • Thresholds raised: lines 73 → 85, regions 75 → 85, functions 67 → 75
  • Excluded integration-territory files from the unit-test coverage report — CLI, async network clients (asynch/clients/**), sync wrappers around network calls (account/, ledger/, transaction/mod.rs), and the faucet client. These are exercised by the existing tests/integration/ suite (behind the integration feature flag) and would more naturally fit a separate integration-coverage gate.

Context of Change

xrpl-py is currently at 85% unit-test and 70% integration test coverage.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Test Plan

All CI tests pass.

Add integration test coverage threshold

@pdp2121 pdp2121 changed the title Improve unit test tests: improve unit test coverage and set threshold May 4, 2026
@pdp2121

pdp2121 commented May 4, 2026

Copy link
Copy Markdown
Collaborator Author

/ai-review

@pdp2121 pdp2121 requested a review from ckeshava May 4, 2026 22:21

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

kuan121
kuan121 previously approved these changes May 6, 2026
Comment thread src/models/requests/ripple_path_find.rs
Comment thread src/models/requests/no_ripple_check.rs
kuan121
kuan121 previously approved these changes May 12, 2026
Comment thread .github/workflows/unit_test.yml Outdated
Comment thread .github/workflows/unit_test.yml Outdated
Comment on lines +60 to +62
--fail-under-lines 85 \
--fail-under-regions 85 \
--fail-under-functions 75

@kuan121 kuan121 May 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there a way to fail the check when coverage for new or modified code introduced by a PR falls below a certain percentage?

I’m less concerned about the current coverage of existing code. If we want to maintain a high bar for test coverage, we should apply that standard to new code. Over time, that will naturally improve the overall coverage of the repo.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, patch coverage is possible to do, but would require Codecov (similar to the requirements for removing integration test regex) since cargo-llvm-cov alone would not suffice. Probably worth a follow-up PR since we continue to find more needs to integrate

@kuan121 kuan121 May 14, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you create a follow-up story to track this work so it doesn’t get lost?

I think enforcing patch coverage with a high threshold could be a better approach than setting a project-wide threshold, since it focuses on improving new and modified code without relying on broad exclusions. Over time, this should help gradually improve coverage in a repo with low overall coverage.

BTW, xrpl4j uses Codecov (see code). Example PR - XRPLF/xrpl4j#786

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Created the issue: #307

Nice! that means the setup for Codecov in XRPLF has already been done, making our task easier without the need for admin privilege

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Actually let me just add it directly into this PR since Codecov is enabled already in XRPLF so there's no actual blocker

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added in 22372c3

Comment thread .github/workflows/unit_test.yml
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@pdp2121 pdp2121 requested a review from kuan121 May 18, 2026 15:19
@pdp2121

pdp2121 commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

@kuan121 @ckeshava since this is the first PR that incorporate Codecov, the report will not be shown since there's no baseline yet (not yet merged to main). Subsequent PRs will have those checks.

ckeshava
ckeshava previously approved these changes May 18, 2026
Comment thread .github/workflows/unit_test.yml Outdated
Comment thread codecov.yml
Comment on lines +66 to +68
--fail-under-lines 83 \
--fail-under-regions 85 \
--fail-under-functions 73

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: the fail threshold parameters are redundant with the Codecov checks, because the latter also performs coverage checks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Only lines would be covered by codecov, not regions and functions. I would say let's just keep them for extra rigor

@ckeshava

Copy link
Copy Markdown
Collaborator

@pdp2121 you can cherry-pick this commit to update the integ tests docker mount path: ab11e85

@pdp2121

pdp2121 commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

@pdp2121 you can cherry-pick this commit to update the integ tests docker mount path: ab11e85

Thanks Chenna! Fixed and should be working now

@pdp2121 pdp2121 requested review from ckeshava and kuan121 May 21, 2026 15:46
@ckeshava

Copy link
Copy Markdown
Collaborator

@pdp2121 there seems to be a flaky test: https://github.com/XRPLF/xrpl-rust/actions/runs/26236700524/job/77211757936?pr=296#step:6:446. I suspect the error is due to the discrepancy in the LedgerEntry Response model.

@pdp2121

pdp2121 commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

@pdp2121 there seems to be a flaky test: https://github.com/XRPLF/xrpl-rust/actions/runs/26236700524/job/77211757936?pr=296#step:6:446. I suspect the error is due to the discrepancy in the LedgerEntry Response model.

Yea I noticed that. We need to either relax the current model (using serde_json::Value) or refactor it (larger scope)

kuan121
kuan121 previously approved these changes May 21, 2026
@pdp2121

pdp2121 commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

@ckeshava I implemented a patch fix (using serde_json::Value). We can tighten the model in a later PR.

@pdp2121 pdp2121 requested a review from kuan121 May 21, 2026 16:59
@pdp2121

pdp2121 commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

@ckeshava added a follow up ticket for ledger_entry #308

@pdp2121 pdp2121 merged commit c80d932 into main May 22, 2026
5 checks passed
@pdp2121 pdp2121 deleted the improve-unit-test branch May 22, 2026 20:11
ckeshava added a commit that referenced this pull request Jun 1, 2026
## High Level Overview of Change

Closes #297. The CI integration workflow now runs all five integration
test binaries (previously only `integration_test`) under
`cargo-llvm-cov` and enforces a 65% line-coverage gate scoped to
integration-territory files. Six commits add tests that lift integration
coverage from 44.52% → 70.30% to satisfy the gate.

Beyond the integration gate, this PR also adds `is_success()` unit tests
(`src/models/results/mod.rs`), splits the codecov patch gate into
per-flag sections (unit/integration), fixes
`get_latest_open_ledger_sequence` (it requested `ledger { ledger_index:
"open" }`, which rippled rejects), and documents both coverage flows in
`CONTRIBUTING.md`. (The unit thresholds — 83% lines / 85% regions / 73%
functions — were set earlier in #296 and are unchanged here.)

### Context of Change

The integration suite was running only `tests/integration_test.rs` (40
transaction tests, all routed through one `test_transaction` helper).
Several public APIs sat at 0% integration coverage: the sync wrappers in
`src/{account,ledger,transaction}/mod.rs`,
`asynch::transaction::submit_and_wait`'s poll loop, the WebSocket
request/response path, multisign, the sync faucet generator, and the
`clients::json_rpc::JsonRpcClient` sync facade. xrpl-py gates its
integration suite at 70%; this PR starts xrpl-rust at 65%, with room to
tighten as coverage grows.

### Type of Change

- [x] New feature (CI coverage gate)
- [x] Tests
- [x] Bug fix (`get_latest_open_ledger_sequence`)
- [x] Documentation (CONTRIBUTING coverage guide)

## Before / After

**Workflow.**
- **Before:** `cargo test --test integration_test …` — ran a single test
binary, no coverage measured.
- **After:** coverage runs in three steps:
1. `cargo llvm-cov --no-report … --test integration_test --test
cli_integration --test funding --test utils --test test_utils` —
collects coverage across all five integration binaries.
2. `cargo llvm-cov report --lcov --ignore-filename-regex
"$COVERAGE_IGNORE_REGEX"` — writes an lcov scoped to
integration-territory files.
3. That lcov is uploaded to codecov, which enforces the 65% gate
(`codecov.yml → project.integration`), and is also saved as a CI
artifact.

`COVERAGE_IGNORE_REGEX` is defined once (workflow `env`), so the scoped
report and the gate always use the same file list.

**Scoped coverage:** 44.52% lines → **70.30% lines**. Notable per-file
moves:

| File | Before | After |
|---|---|---|
| `account/mod.rs` (sync) | 0% | 100% |
| `ledger/mod.rs` (sync) | 47.37% | 100% |
| `transaction/mod.rs` (sync) | 0% | 100% |
| `wallet/faucet_generation.rs` | 0% | 100% |
| `asynch/ledger/mod.rs` | 62.50% | 94.64% |
| `asynch/account/mod.rs` | 55.17% | 95.40% |
| `asynch/clients/client.rs` | 0% | 91.67% |
| `asynch/clients/websocket/websocket_base.rs` | 12.73% | 78.18% |
| `asynch/transaction/submit_and_wait.rs` | 0% | 72.87% |

## Test Plan

All tests run against `rippleci/xrpld:develop` (CI's standalone rippled
image). New test files / functions:

- `tests/transactions/submit_and_wait.rs::test_submit_and_wait_payment`
— autofill, sign, submit, poll loop, with a background `ledger_accept`
driver.
- `tests/utils.rs` — three new WS tests: `server_info` round-trip +
close, `account_info` against genesis, three sequential requests on one
connection (exercises id-based message routing).
- `tests/transactions/sync_wrappers.rs` — 10 tests covering every sync
wrapper in `src/{account,ledger,transaction}/mod.rs`, plus
`clients::json_rpc::JsonRpcClient` and `wallet::faucet_generation`. Each
owns a `tokio::runtime::Runtime` + `EnterGuard` so `reqwest` can find
the reactor while `embassy_futures::block_on` parks the thread.
- `tests/transactions/multisign_payment.rs::test_multisign_payment` —
register a 2-of-2 signer list, autofill with `signers_count=2`, each
signer signs a copy, `multisign()` merges, `submit()` confirms
`tesSUCCESS`.

Verified locally by running the same `cargo llvm-cov` invocation CI
uses, with the same exclusion regex; the scoped report clears the 65%
gate.

---------

Co-authored-by: Phu Pham <ppham@ripple.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
realonbebeto pushed a commit to realonbebeto/xrpl-rust that referenced this pull request Jun 5, 2026
## High Level Overview of Change

<!--
Please include a summary/list of the changes.
If too broad, please consider splitting into multiple PRs.
If a relevant Asana task, please link it here.
-->
Brings xrpl-rust unit-test coverage in line with 85% line gate by adding
~120 unit tests to previously-untested or low-coverage files, and
reframing what "unit-test coverage" measures.

**Tests added**

- 29 request models — were all at 0%, now 84–100%
- 3 pseudo-transactions (`enable_amendment`, `set_fee`, `unl_modify`) —
0% → 91–94%
- `xchain_add_claim_attestation` (0% → 92%), `xchain_commit` (45% → 95%)
- 3 ledger objects (`bridge`, `xchain_owned_claim_id`, `objects/mod.rs`)
— 0% → 87–100%
- `utils/str_conversion` and `utils/get_xchain_claim_id` — 0% → 98–100%
- `models/results/mod.rs` dispatcher (17% → 58%), and low-coverage
result types `account_tx/ledger_entry/tx/nftoken` — 0–34% → 98–100%
- `txn_parser` internals (`nodes`, `parser`, `utils/mod`) — 51–62% →
97–100%
- 6 lower-coverage transaction models (`check_cancel`, `escrow_cancel`,
`set_regular_key`, `ticket_create`, `payment_channel_fund`,
`check_create`) — 68–80% → 97%
- `transaction/mod.rs` (`calculate_fee_per_transaction_type`) — 0% → 44%

**CI changes**

- Thresholds raised: lines 73 → 85, regions 75 → 85, functions 67 → 75
- Excluded integration-territory files from the unit-test coverage
report — CLI, async network clients (`asynch/clients/**`), sync wrappers
around network calls (`account/`, `ledger/`, `transaction/mod.rs`), and
the faucet client. These are exercised by the existing
tests/integration/ suite (behind the integration feature flag) and would
more naturally fit a separate integration-coverage gate.

### Context of Change

<!--
Please include the context of a change.
If a bug fix, when was the bug introduced? What was the behavior?
If a new feature, why was this architecture chosen? What were the
alternatives?
If a refactor, how is this better than the previous implementation?

If there is a design document for this feature, please link it here.
-->
[xrpl-py](https://github.com/XRPLF/xrpl-py) is currently at 85%
unit-test and 70% integration test coverage.

### Type of Change

<!--
Please check relevant options, delete irrelevant ones.
-->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Refactor (non-breaking change that only restructures code)
- [x] Tests (You added tests for code that already exists, or your new
feature included in this PR)
- [ ] Documentation Updates
- [ ] Release

## Test Plan

<!--
Please describe the tests that you ran to verify your changes and
provide instructions so that others can reproduce.
-->
All CI tests pass.

<!--
## Future Tasks
For future tasks related to PR.
-->
Add integration test coverage threshold
realonbebeto pushed a commit to realonbebeto/xrpl-rust that referenced this pull request Jun 5, 2026
## High Level Overview of Change

Closes XRPLF#297. The CI integration workflow now runs all five integration
test binaries (previously only `integration_test`) under
`cargo-llvm-cov` and enforces a 65% line-coverage gate scoped to
integration-territory files. Six commits add tests that lift integration
coverage from 44.52% → 70.30% to satisfy the gate.

Beyond the integration gate, this PR also adds `is_success()` unit tests
(`src/models/results/mod.rs`), splits the codecov patch gate into
per-flag sections (unit/integration), fixes
`get_latest_open_ledger_sequence` (it requested `ledger { ledger_index:
"open" }`, which rippled rejects), and documents both coverage flows in
`CONTRIBUTING.md`. (The unit thresholds — 83% lines / 85% regions / 73%
functions — were set earlier in XRPLF#296 and are unchanged here.)

### Context of Change

The integration suite was running only `tests/integration_test.rs` (40
transaction tests, all routed through one `test_transaction` helper).
Several public APIs sat at 0% integration coverage: the sync wrappers in
`src/{account,ledger,transaction}/mod.rs`,
`asynch::transaction::submit_and_wait`'s poll loop, the WebSocket
request/response path, multisign, the sync faucet generator, and the
`clients::json_rpc::JsonRpcClient` sync facade. xrpl-py gates its
integration suite at 70%; this PR starts xrpl-rust at 65%, with room to
tighten as coverage grows.

### Type of Change

- [x] New feature (CI coverage gate)
- [x] Tests
- [x] Bug fix (`get_latest_open_ledger_sequence`)
- [x] Documentation (CONTRIBUTING coverage guide)

## Before / After

**Workflow.**
- **Before:** `cargo test --test integration_test …` — ran a single test
binary, no coverage measured.
- **After:** coverage runs in three steps:
1. `cargo llvm-cov --no-report … --test integration_test --test
cli_integration --test funding --test utils --test test_utils` —
collects coverage across all five integration binaries.
2. `cargo llvm-cov report --lcov --ignore-filename-regex
"$COVERAGE_IGNORE_REGEX"` — writes an lcov scoped to
integration-territory files.
3. That lcov is uploaded to codecov, which enforces the 65% gate
(`codecov.yml → project.integration`), and is also saved as a CI
artifact.

`COVERAGE_IGNORE_REGEX` is defined once (workflow `env`), so the scoped
report and the gate always use the same file list.

**Scoped coverage:** 44.52% lines → **70.30% lines**. Notable per-file
moves:

| File | Before | After |
|---|---|---|
| `account/mod.rs` (sync) | 0% | 100% |
| `ledger/mod.rs` (sync) | 47.37% | 100% |
| `transaction/mod.rs` (sync) | 0% | 100% |
| `wallet/faucet_generation.rs` | 0% | 100% |
| `asynch/ledger/mod.rs` | 62.50% | 94.64% |
| `asynch/account/mod.rs` | 55.17% | 95.40% |
| `asynch/clients/client.rs` | 0% | 91.67% |
| `asynch/clients/websocket/websocket_base.rs` | 12.73% | 78.18% |
| `asynch/transaction/submit_and_wait.rs` | 0% | 72.87% |

## Test Plan

All tests run against `rippleci/xrpld:develop` (CI's standalone rippled
image). New test files / functions:

- `tests/transactions/submit_and_wait.rs::test_submit_and_wait_payment`
— autofill, sign, submit, poll loop, with a background `ledger_accept`
driver.
- `tests/utils.rs` — three new WS tests: `server_info` round-trip +
close, `account_info` against genesis, three sequential requests on one
connection (exercises id-based message routing).
- `tests/transactions/sync_wrappers.rs` — 10 tests covering every sync
wrapper in `src/{account,ledger,transaction}/mod.rs`, plus
`clients::json_rpc::JsonRpcClient` and `wallet::faucet_generation`. Each
owns a `tokio::runtime::Runtime` + `EnterGuard` so `reqwest` can find
the reactor while `embassy_futures::block_on` parks the thread.
- `tests/transactions/multisign_payment.rs::test_multisign_payment` —
register a 2-of-2 signer list, autofill with `signers_count=2`, each
signer signs a copy, `multisign()` merges, `submit()` confirms
`tesSUCCESS`.

Verified locally by running the same `cargo llvm-cov` invocation CI
uses, with the same exclusion regex; the scoped report clears the 65%
gate.

---------

Co-authored-by: Phu Pham <ppham@ripple.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants