test(ledger-suite-orchestrator): migrate integration tests to PocketIC - #10949
test(ledger-suite-orchestrator): migrate integration tests to PocketIC#10949gregorydemay wants to merge 7 commits into
Conversation
Add a PocketIC-based test fixture (LedgerSuiteOrchestrator, AddErc20TokenFlow, ManagedCanistersAssert, UniversalCanister, new_pocket_ic()) alongside the existing StateMachine one in test_utils, and migrate tests/tests.rs to it. The StateMachine fixture stays untouched at its current paths since rs/ethereum/cketh still consumes it; it will be deleted once cketh migrates to PocketIC in a later PR of this stack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates the ledger-suite-orchestrator integration tests from the ic-state-machine-tests harness to PocketIC by introducing a parallel PocketIC-based fixture in test_utils and switching tests/tests.rs to use it, while leaving the existing StateMachine fixture in place for downstream users (e.g., ckETH) until later PRs in the stack.
Changes:
- Added a new PocketIC-based test fixture module (
test_utils/src/pocket_ic) including orchestrator setup, flows/assert helpers, and a PocketIC universal canister helper. - Migrated
rs/ethereum/ledger-suite-orchestrator/tests/tests.rsto use the new PocketIC fixture and PocketIC error types/APIs. - Updated Cargo/Bazel dependencies to include PocketIC and PocketIC-enabled metrics assertions, and wired PocketIC server binary into the Bazel
rust_ic_test.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| rs/ethereum/ledger-suite-orchestrator/tests/tests.rs | Migrates the integration tests to the new PocketIC fixture and updates calls/assertions accordingly. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/src/pocket_ic/mod.rs | Introduces the PocketIC-based LedgerSuiteOrchestrator fixture and PocketIC builder/helpers. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/src/pocket_ic/flow.rs | Adds PocketIC-based test flows and managed-canister assertions used by the migrated tests. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/src/pocket_ic/universal_canister.rs | Adds a PocketIC-based universal canister helper for management-canister interactions in tests. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/src/lib.rs | Exposes the new pocket_ic module alongside existing test utilities. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/Cargo.toml | Enables ic-metrics-assert PocketIC feature and adds a pocket-ic dependency. |
| rs/ethereum/ledger-suite-orchestrator/test_utils/BUILD.bazel | Switches to the PocketIC-enabled ic-metrics-assert Bazel target and adds //packages/pocket-ic. |
| rs/ethereum/ledger-suite-orchestrator/Cargo.toml | Drops ic-state-machine-tests from test deps and adds pocket-ic. |
| rs/ethereum/ledger-suite-orchestrator/BUILD.bazel | Adds PocketIC server binary + env wiring for the Bazel test target and updates deps accordingly. |
| Cargo.lock | Updates lockfile for the new pocket-ic dependency wiring. |
Comments suppressed due to low confidence (1)
rs/ethereum/ledger-suite-orchestrator/tests/tests.rs:93
- This expectation hardcodes a specific principal string for the index canister. To keep the test invariant across PocketIC ID allocation changes, assert the metadata equals the actual
index_idobtained fromManagedCanisterIds.
MetadataKey::parse(MetadataKey::ICRC106_INDEX_PRINCIPAL).unwrap(),
LedgerMetadataValue::from("xbze6-vd777-77777-aaaba-cai"),
),
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let index_id = managed_canisters_assert.canister_ids.index.unwrap(); | ||
| assert_eq!(index_id, "ryjl3-tyaaa-aaaaa-aaaba-cai".parse().unwrap()); | ||
| assert_eq!(index_id, "xbze6-vd777-77777-aaaba-cai".parse().unwrap()); |
There was a problem hiding this comment.
🤖 Leaving this as-is. The two literals are not vacuous: they are independently cross-checked against each other (the index_id returned by the orchestrator on line 46, and the ledger's own ICRC106_INDEX_PRINCIPAL metadata on line 91-93 must both equal this value), so the assertion still fails if the wiring is wrong even though the concrete text is PocketIC-version-dependent. This is the same fragility class as the StateMachine-era literal it replaces (ryjl3-tyaaa-aaaaa-aaaba-cai), and the migration plan for this PR stack explicitly accepts pocket-ic-server-version-dependent constants (see PR 3's derived-key-constant regeneration). Asserting against the live index_id instead would make the test tautological for that half of the check.
|
🤖🧐 VERDICT: CHANGES_REQUESTED — 0 blockers, 2 mediums, 6 nits; CI pending (22 pass / 7 pending / 0 red — Neither medium is a semantics problem: the port itself is faithful. Both are the same finding — two Review detailsVerified by running
(Plain Faithfulness of the port
Scope / boundary
Maintainability accounting
Test pyramidNot applicable as a coverage question — this is a harness migration with no production-behaviour change, so "a new test per behaviour change" is satisfied by the existing suite continuing to pass unmodified in content. |
LedgerSuiteOrchestrator and ManagedCanistersAssert each carried an AsRef<PocketIc> impl left over from porting the StateMachine fixture, where it satisfied `T: AsRef<StateMachine>` bounds on stop_canister/ out_of_band_upgrade and a manual CanisterHttpQuery impl. Those call sites now take `&PocketIc` directly and go through PocketIcHttpQuery, so neither impl has a caller left (G9/G12). Addresses review comments: #10949 (comment) #10949 (comment) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- mod.rs: replace 13 inline `crate::` paths (default_init_arg, the wasm
loaders, GIT_COMMIT_HASH, MAX_TICKS) with a single `use crate::{...}`
block, matching the plain `use crate::MINTER_PRINCIPAL;` style already used
in the sibling flow.rs. This also lets wait_for's panic message go back to
inline-capture ("...{MAX_TICKS} ticks...") instead of a positional arg.
- mod.rs: alias `ic_cdk::management_canister::CanisterStatusResult` as
`CdkCanisterStatusResult` to disambiguate it from the
`ic_management_canister_types::CanisterStatusResult` imported in the same
file, instead of spelling out the full path twice.
- flow.rs: import `ic_management_canister_types::CanisterId` instead of
fully qualifying it once, for the same reason mod.rs already imports it.
Addresses review comments:
#10949 (comment)
#10949 (comment)
#10949 (comment)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ledger_canister_status() returns an owned CanisterStatusResult temporary, so module_hash can be moved straight out of it instead of being cloned first (R3). Addresses review comment: #10949 (comment) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This comment was carried over verbatim from the StateMachine fixture and still referenced "10ms per transfer with state machine tests" inside the module that specifically does not use StateMachine (C2). Dropping the parenthetical rather than guessing a PocketIC-specific number. Addresses review comment: #10949 (comment) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
//:pocket-ic-server was listed in both `data` (needed for the $(rootpath //:pocket-ic-server) used by POCKET_IC_BIN) and `deps`. It's a runtime binary reached only through that env var, not linked, so `data` alone is the accurate declaration -- matching rs/ledger_suite/icp/BUILD.bazel (data only), as opposed to rs/bitcoin/checker and rs/dogecoin/ckdoge/minter (deps only, where the binary is invoked differently). Verified bazel test //rs/ethereum/ledger-suite-orchestrator:integration_tests still passes (POCKET_IC_BIN resolves fine from data alone). Addresses review comment: #10949 (comment) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🤖🧐 VERDICT: READY (re-review of Re-review detailsPer-finding resolution
Copilot's thread on Verified by running (on
|
| Command | Result |
|---|---|
bazel test //rs/ethereum/ledger-suite-orchestrator:integration_tests --nocache_test_results (dev container) |
PASSED in 15.2s, 1/1 |
cargo check --all-targets --all-features -p ic-ledger-suite-orchestrator-test-utils -p ic-ledger-suite-orchestrator |
clean, no warnings |
git diff --stat 522634fb44 de18dda2f9 |
10 files, all under rs/ethereum/ledger-suite-orchestrator/ + Cargo.lock — component boundary still respected |
| old-fixture check | test_utils/src/{flow,universal_canister}.rs still byte-identical to master; lib.rs still +1 line (pub mod pocket_ic;) |
Nothing new introduced
The five commits are strictly subtractive or rename-only — no call sites, senders, tick sequences, or assertions were touched. The faithfulness conclusions from the first pass (21/21 tests, identical function-name set, API mapping per spec, preserved tick semantics and assertion strength) still hold; the net effect on the diff is −14 lines.
One forward-looking note for PR 4: consolidating into a single use crate::{...} block makes the hoist easier than the scattered crate:: prefixes did — if pocket_ic/mod.rs is merged into lib.rs, that one import line is deleted rather than 13 path prefixes rewritten. No action needed here.
Outstanding
Only CI. Nothing is red, but Bazel Test All, Bazel Test arm64-{linux,darwin}, Cargo Build/Lint Linux, Build IC, Lock Generate, Candid compatibility checks, Autofix, Bazel Run Fuzzers and RBE / Infer Bazel Targets were still running when this verdict was written. Final approval and merge are the human's call.
…ty#10947) Adds a single end-to-end test proving the ckERC20 balance scan works against a real EVM, complementing the existing mock-based integration tests. The test drives the full production path — minter → **real EVM RPC canister** → Ethereum — with no JSON-RPC mocking: - A new PocketIC *live* harness in the cketh `test_utils` crate owns a local `anvil` node and installs the minter and the EVM RPC canister, configuring the latter with an `overrideProvider` that routes every provider to that node. In live mode the EVM RPC canister issues genuine HTTPS outcalls that reach anvil for real. The new harness is required because current integration tests infrastructure uses the `StateMachine` that cannot issue real HTTP request. Migrating the integration test infrastructure to PocketIC is deferred to DEFI-2262 (see dfinity#10949). - Supported tokens (ckUSDC, ckUSDT) are registered directly through the minter's `add_ckerc20_token` endpoint by pointing its orchestrator id at a principal the harness controls, so no real orchestrator or spawned ledgers are needed. - The harness places the two tokens at their real mainnet addresses on anvil (`anvil_setCode`) and credits the minter's derived deposit address above the candidate threshold (`anvil_setStorageAt`). The test then asserts the minter's periodic scan reads those real balances and flags the address as a deposit candidate for both tokens. Stacked on top of dfinity#10873. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: IDX GitHub Automation <infra+github-automation@dfinity.org>
The StateMachine fixture had to address the management canister itself to upgrade a canister as its controller. PocketIc exposes that directly and builds the very same install_code argument, down to the install mode, so call it instead of assembling the argument by hand. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Migrates the ledger-suite-orchestrator (LSO) integration tests from the internal
ic-state-machine-testsharness to PocketIC, following the pattern already used for the EVM-RPC canister (dfinity/evm-rpc-canister#294). This is DEFI-2262: a pure refactor of the test harness — same tests, same coverage, same semantics.CkErc20Setupinrs/ethereum/ckethembeds LSO's fixture and shares aStateMachinewith it, so flipping LSO's fixture in place would break cketh in the same commit. To keep this change single-component and the tree green, this PR adds a PocketIC fixture in LSO'stest_utilsalongside the existing StateMachine one (precedent:rs/ledger_suite/icp/test_utils'sstate_machine_helpers/pocket_ic_helperscoexisting) and migrates onlyledger-suite-orchestrator/tests/tests.rsto it. The StateMachine fixture stays untouched at its current paths and is still exercised bycketh; it is deleted only in the last PR of this stack, once cketh no longer needs it.Summary of changes
pocket_icmodule inledger-suite-orchestrator/test_utils(LedgerSuiteOrchestrator,AddErc20TokenFlow,ManagedCanistersAssert,UniversalCanister,new_pocket_ic()), mirroring the existing StateMachine-based types and method names one-for-one so later PRs in the stack only need to swap import paths.new_pocket_ic()builds a system subnet (LSO tests assert exact cycle balances, which only hold on a non-charging subnet) with canister-execution rate limiting disabled (LSO repeatedly installs/upgrades ledger, index and archive canisters).ic-metrics-assert'sPocketIcHttpQuery(featurepocket_ic) instead of a hand-rolledCanisterHttpQueryimpl.tests/tests.rsfully migrated to the new fixture.Cargo.toml/BUILD.bazelupdated accordingly;test_utilskeepsic-state-machine-testsfor now (still needed by the old fixture).Coverage
tests/tests.rsfully migrated, old fixture/paths untouched,ckethstill builds against the untouched fixture.📚 PR stack
🤖 Generated with Claude Code