refactor(consensus): introduce a builder pattern for dependencies in consensus' unit tests - #11064
refactor(consensus): introduce a builder pattern for dependencies in consensus' unit tests#11064pierugo-dfinity wants to merge 29 commits into
Conversation
Adds a builder for the consensus test Dependencies fixture with three constructors: new(pool_config, nodes), single_subnet(pool_config, subnet_id, records) and multiple_subnets(pool_config, records) — the latter supporting multiple subnets in the registry, as needed by subnet-splitting tests. The state manager is mocked by default and can be opted out via without_mocked_state_manager(). The legacy dependencies* functions are retargeted as thin wrappers and will be removed once all call sites are migrated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sensus tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nsensus-mocks All call sites have been migrated to DependenciesBuilder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…_dkg_interval_length to consensus test Dependencies Dependencies now provides a bare RefMockPayloadBuilder and RefMockMessageRouting (no pre-armed expectations), so tests no longer need to construct these mocks themselves. DependenciesBuilder gains with_dkg_interval_length(u64), which sets the DKG interval length on every subnet record passed to the builder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ests Dependencies now carries the mocked payload builder and message routing, so the wrapper struct and its setup helpers are replaced by direct DependenciesBuilder chains plus a make_validator helper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h in ic-consensus tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h in ic-consensus-utils tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h in ic-consensus-dkg tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… tests Collapses the repeated build-deps / make_validator / destructure boilerplate at the 21 test sites that use the default 4-node subnet with DKG interval length 9. Non-default sites keep building their own dependencies and calling make_validator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t subnet records in ic-consensus tests Where tests pass custom SubnetRecords to DependenciesBuilder (non-default subnet id, registry version, or membership), setting the DKG interval length via the DependenciesBuilder would silently modify the records built just above. Keep it on the SubnetRecordBuilder there; only DependenciesBuilder::new sites use the builder-level setter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t subnet records in ic-consensus-dkg tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lder that forwards to DependenciesBuilder
…ngle_subnet sites in ic-consensus tests share_aggregator and block_maker built default records for subnet_test_id(0) at registry version 1 only to set the DKG interval length, which DependenciesBuilder::new supports directly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ngle_subnet sites in ic-consensus-dkg tests These sites passed a custom subnet id (222, 1) or initial registry version (10, 5) that the tests never rely on: the version is consumed only through registry.get_latest_version(), and the subnet id never reaches an assertion or registry key (no consensus code special-cases the root subnet). Normalize them to the DependenciesBuilder::new defaults. In test_validate_payload the ValidationContext registry version is updated together with the record version (5 -> 1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@frankdavid Maybe this PR could be of interest to you, following our discussion |
|
✅ No security or compliance issues detected. Reviewed everything up to ff2d309. Security Overview
Detected Code ChangesThe diff is too large to display a summary of code changes. |
There was a problem hiding this comment.
Pull request overview
This PR refactors consensus-related unit tests and benchmarks to replace a set of ad-hoc dependency-construction helpers from ic-consensus-mocks with a DependenciesBuilder (including support for common tweaks like DKG interval length and opting out of mocked state manager behavior). It also extends the shared Dependencies test fixture to bundle additional commonly-used mocks.
Changes:
- Introduces
DependenciesBuilderinic-consensus-mocksand removes the olddependencies*helper functions in favor of builder-based construction. - Updates consensus / idkg / dkg / https-outcalls tests and benches to build dependencies via
DependenciesBuilderAPIs. - Expands the shared
Dependenciesfixture to include reusablepayload_builderandmessage_routingmocks.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| rs/https_outcalls/consensus/src/pool_manager.rs | Updates unit tests to construct consensus mocks via DependenciesBuilder. |
| rs/https_outcalls/consensus/src/payload_builder/tests.rs | Replaces old dependency helpers with DependenciesBuilder::single_subnet(...).build(). |
| rs/https_outcalls/consensus/benches/payload_validation.rs | Migrates benchmark setup to use DependenciesBuilder. |
| rs/consensus/utils/src/pool_reader.rs | Refactors tests to use DependenciesBuilder and builder helpers (e.g. DKG interval). |
| rs/consensus/utils/src/lib.rs | Updates tests to use DependenciesBuilder instead of dependencies(...). |
| rs/consensus/src/consensus/validator.rs | Refactors extensive test harness to a local builder wrapping DependenciesBuilder and centralizes DKG interval constant. |
| rs/consensus/src/consensus/status.rs | Updates tests to use DependenciesBuilder::single_subnet(...).build(). |
| rs/consensus/src/consensus/share_aggregator.rs | Replaces old dependency helpers with DependenciesBuilder. |
| rs/consensus/src/consensus/random_tape_maker.rs | Updates tests to use DependenciesBuilder. |
| rs/consensus/src/consensus/random_beacon_maker.rs | Updates tests to use DependenciesBuilder. |
| rs/consensus/src/consensus/purger.rs | Updates tests to use DependenciesBuilder and shared message_routing mock from Dependencies. |
| rs/consensus/src/consensus/proptests.rs | Migrates proptests to builder-based dependency setup. |
| rs/consensus/src/consensus/priority.rs | Refactors tests to use DependenciesBuilder (including DKG interval customization). |
| rs/consensus/src/consensus/payload_builder.rs | Updates payload builder tests to use DependenciesBuilder. |
| rs/consensus/src/consensus/notary.rs | Migrates tests to DependenciesBuilder (including DKG interval customization). |
| rs/consensus/src/consensus/finalizer.rs | Updates tests to use DependenciesBuilder::new/single_subnet. |
| rs/consensus/src/consensus/catchup_package_maker.rs | Updates tests to use DependenciesBuilder, including .without_mocked_state_manager(). |
| rs/consensus/src/consensus/bounds.rs | Refactors pool-bounds test setup to use DependenciesBuilder. |
| rs/consensus/src/consensus/block_maker.rs | Updates tests to use DependenciesBuilder and the shared payload_builder from Dependencies. |
| rs/consensus/src/consensus.rs | Updates consensus tests to build dependencies via DependenciesBuilder::single_subnet(...).build(). |
| rs/consensus/mocks/src/lib.rs | Introduces DependenciesBuilder, removes old helper constructors, and extends Dependencies with shared mocks. |
| rs/consensus/mocks/Cargo.toml | Adds ic-interfaces-mocks dependency for shared message_routing mock wrapper. |
| rs/consensus/mocks/BUILD.bazel | Adds Bazel dep on //rs/interfaces/mocks for new mocks usage. |
| rs/consensus/idkg/src/utils.rs | Updates tests to use DependenciesBuilder. |
| rs/consensus/idkg/src/test_utils.rs | Updates test utility builders to use DependenciesBuilder. |
| rs/consensus/idkg/src/payload_builder/pre_signatures.rs | Migrates tests from dependencies(...) to DependenciesBuilder. |
| rs/consensus/idkg/src/payload_builder.rs | Updates tests to use DependenciesBuilder. |
| rs/consensus/idkg/src/lib.rs | Updates tests to use DependenciesBuilder. |
| rs/consensus/dkg/src/utils.rs | Refactors tests to use DependenciesBuilder and uses replica_config.subnet_id from built deps. |
| rs/consensus/dkg/src/payload_validator.rs | Updates tests to use DependenciesBuilder and align registry/subnet inputs accordingly. |
| rs/consensus/dkg/src/payload_builder.rs | Migrates tests to builder pattern, including raw state manager scenarios via .without_mocked_state_manager(). |
| rs/consensus/dkg/src/lib.rs | Updates tests to use DependenciesBuilder and removes old dependency helper usage. |
| rs/consensus/dkg/src/dkg_key_manager.rs | Migrates test dependency setup to DependenciesBuilder. |
| rs/consensus/chain_key/src/lib.rs | Updates tests to use DependenciesBuilder, including opting out of mocked state manager. |
| rs/consensus/certification/src/certifier.rs | Refactors certifier tests to use DependenciesBuilder. |
| Cargo.lock | Records new workspace dependency (ic-interfaces-mocks) for ic-consensus-mocks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Consensus' (fake) dependencies in unit tests are built with functions like
dependencies,dependencies_with_subnet_params, ordependencies_with_subnet_records_with_raw_state_managerthat live inic-consensus-mocks. Each time a developer wants to consistently modify a dependency, they should add such a function and then wire it through the others. This becomes hard to maintain and a Builder pattern is more than appropriate for this use-case. This PR removes these functions and replaces all call sites to build their dependencies through the builder. The relation is as follows:dependencies_with_subnet_params(...)becomesDependenciesBuilder::single_subnet(...).build()dependencies(...)becomesDependenciesBuilder::new(...).build(), which is a simple shortcut tosingle_subnetdependencies_with_subnet_records_with_raw_state_manager(...)becomesDependenciesBuilder::single_subnet(...).without_mocked_state_manager().build()The two above constructors then fall down to the
multiple_subnetsconstructor, which is for now otherwise unused (as Consensus usually stays scoped only to a single subnet) but will soon be for incoming subnet-splitting unit tests.One particularly frequent setup is
which uses
...with_subnet_paramsonly just to modify the DKG interval length.DependenciesBuilderthus provides.with_dkg_interval_lengthsuch that such a setup boils down to a simpleI replaced such setups with this even when the subnet was not
subnet_test_id(0)or the initial registry version was not 1 when it clearly did not matter. Otherwise, I kept them intact.