Skip to content
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

refactor: integration tests #1223

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
Open

Conversation

0xClandestine
Copy link
Member

@0xClandestine 0xClandestine commented Mar 6, 2025

Motivation:

This PR refactors the integration test framework to improve performance, maintainability, and organization. The existing integration test structure had grown complex with multiple responsibilities mixed in different files, making it harder to understand and maintain. The goal is to create a more modular, better organized test framework with clear separation of concerns to make writing and maintaining integration tests easier.

Modifications:

  1. Created two new utility files to better organize the codebase:

    • IntegrationGetters.t.sol: Centralizes all state-fetching functionality, providing methods to get both current and previous state snapshots.
    • IntegrationUtils.t.sol: Contains helper functions for creating users, generating allocation parameters, and other common tasks.
  2. Restructured folder organization:

    • Moved deprecated interfaces from deprecatedInterfaces/ to deprecated/.
    • Relocated utility files from integration to /test/utils/ folder.
    • Moved mocks from integration/mocks/ to test/mocks/.
  3. Renamed test files to follow a more consistent naming convention:

    • e.g., ALM_RegisterAndModify.t.solDeposit_Delegate_Modify.t.sol.
  4. Refactored the TimeMachine.t.sol contract with improved functionality and moved it to utils/ folder to make it accessible beyond integration tests.

  5. Added a new Constants.t.sol file to centralize commonly used constants.

  6. Added a FOUNDRY_FUZZ_SEED to fork tests that updates weekly (this significantly reduces our RPC usage).

  7. Moved _init into setUp() (this means setup happens once per fuzz run, rather than once per test).

  8. Sort strategies array once, rather than JIT (sorting an array in place is time intensive).

  9. Refactored randomness sourcing to use Vm.

  • Previously, we were using a uint24 _random variable combined with hashing to generate subsequent random values.

  • While this pattern simplified test reruns (allowing the reuse of the same _random value for consistency), it has notable drawbacks. Randomness isn't unevenly distributed, leading to modulo bias, and the process is computationally expensive.

Additionally, the same functionality can now be easily achieved through Foundry flags.

Result:

After these changes, the integration test framework will be more modular with clear separation of concerns, making it easier to understand and maintain.

Integration CI times has decreased from 15-25mins -> 5-6mins.

NOTE: There's still quite a bit that could be done, don't want this PR getting too big.

@github-actions github-actions bot added 🧪 Test Test-related changes (unit, integration, etc.). ♻️ Refactor Code improvements without changing functionality. labels Mar 6, 2025
certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch 2 times, most recently from 6598f77 to b57fe21 Compare March 7, 2025 04:33

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

@Layr-Labs Layr-Labs deleted a comment from github-actions bot Mar 7, 2025
@Layr-Labs Layr-Labs deleted a comment from github-actions bot Mar 7, 2025
@github-actions github-actions bot added the 📖 Documentation Improvements or additions to documentation. label Mar 7, 2025

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

certora-run[bot]

This comment was marked as spam.

This comment was marked as spam.

@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch from 9c6a462 to 35dc373 Compare March 7, 2025 17:29
@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch from f4c049e to 966dfe4 Compare March 11, 2025 19:50
@0xClandestine 0xClandestine requested a review from ypatil12 March 12, 2025 14:47
@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch from 47b7a4c to 8f783e5 Compare March 12, 2025 15:32

// Ensure the staker has at least 64 ETH to deposit.
if (initTokenBalances[0] < 64 ether) {
initTokenBalances[0] = 64 ether;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think this should be initTokenBalances[0] = initTokenBalances[0] + 64 ether

IAllocationManagerTypes.SlashingParams memory slashingParams;
uint wadToSlash = _randWadToSlash();
slashingParams = avs.slashOperator(operator, operatorSet.id, strategies, wadToSlash.toArrayU256());
SlashingParams memory slashingParams = _genSlashing_Half(operator, operatorSet);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think _randWadToSlash() still has a place in some of these tests - I caught issues using it that I wouldn't have found with a flat half slash

Copy link
Member Author

Choose a reason for hiding this comment

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

Plan to revamp src/utils/Random.t.sol and use it for more varied randomness. I don't think we should be slashing by half anywhere really, originally we were using _randWadToSlash everywhere. Agree it provides better coverage.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Confused why we had to use a half slashing to get this test to pass with the new framework

Copy link
Member Author

Choose a reason for hiding this comment

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

Wanted to remove the single use of _randWadToSlash, could use _genSlashing_Rand instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Bump, we should use the random slash instead of half

Copy link
Collaborator

@ypatil12 ypatil12 left a comment

Choose a reason for hiding this comment

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

First pass, looking good

@@ -119,7 +108,11 @@ contract Integration_InitRegistered is Integration_ALMBase {
check_FullyDeallocated_State(operator, allocateParams, deallocateParams);
}

function testFuzz_deregister_allocate_waitAllocate_deallocate(uint24 _r) public rand(_r) {
function testFuzz_deposit_delegate_register_deregister_allocate_waitAllocate_deallocate(uint24) public {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where are we sourcing the randomness from?

Copy link
Member Author

Choose a reason for hiding this comment

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

We now source randomness from Foundry using cheats.randomUint(). The main reason we initially used the hash-based approach was to ensure test rerun-ability. For example, you could retrieve the uint24 randomness value from a failed test run and rerun the test with that fixed value. However, Foundry already supports this exact functionality through flags available for forge t (see --rerun --fuzz-seed etc.).

Copy link
Member Author

Choose a reason for hiding this comment

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

Also worth noting our original randomness had modulo bias.

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed cache/ from .gitignore, the last failing fuzz seed will always be added to cache/fuzz/failures. You can re-run failed tests using that seed with --fuzz-seed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add this process of using --fuzz-seed to the ReadME?

@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch 2 times, most recently from 2b1cf79 to 773acf4 Compare March 18, 2025 18:27
@github-actions github-actions bot added the ✨ Enhancement New feature or request. label Mar 18, 2025
@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch 4 times, most recently from cd7429d to 80f848e Compare March 24, 2025 14:46
@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch from a787772 to 288f866 Compare March 31, 2025 14:21
refactor: move time travel getters to separate file

chore: wand vacuum src/test/integration --delete

refactor: reorganize + rename `IntegrationCheckUtils` -> `IntegrationChecks`

chore: make fmt

refactor: fixed time machine + beacon chain addresses

fix: ci

refactor: remove old random getters

refactor: randomness

refactor: reorganize

chore: make fmt

fix: ci

perf: remove some vm.assumes

perf: remove unused user setup return params

chore: move `TimeMachine.t.sol` -> `src/test/utils`

chore: wand vacuum src/test/integration --delete

perf: optimize bitmap conversion + remove shuffle function

refactor: update randomization functions + add parsing methods

chore: remove unused imports

feat: add `Constants.t.sol`

refactor: use cheats alias

refactor: remove logger from `BeaconChainMock` and `TimeMachine`

refactor: renaming

refactor: integration deployer + logger

fix: ci

refactor: rename deprecatedInterfaces -> deprecated

refactor: move `src/test/integration/mocks` -> `src/test/mocks`

refactor: sort strategies once

chore: reduce fuzz runs for time intensive tests

chore: forge snapshot

refactor: condense storage

refactor: cleanup

refactor: check_Withdrawal_AsTokens_State

chore: weekly fuzz seed reduce rpc usage

fix: ci

chore: comment out failing tests

refactor: use new assertEq array fns

chore: make fmt

perf: _init is called in setUp (once per run)

chore: make fmt

chore: only use fuzz seed for fork testing

refactor: cleanup `IntegrationDeployer`

chore: remove gas snapshot

chore: make fmt

chore: remove vm.assumes

perf: alm multi single run (too expensive)

perf: test_multiple_deposits single run (too expensive)

perf(refactor): ALM_RegisterAndModify.t.sol

chore: make fmt

refactor: remove redundant checks

chore: make fmt

perf: single run for `test_completeCP_withNoAddedShares` (too expensive)

refactor: cleanup empty space

chore: mv `UpgradeTest` to `integration/tests/upgrade/`

chore: mv `TypeImporter` to `interfaces/ICore.sol`

chore: remove snapshots

fix: tests

test: compiles

fix: compile errors
**Motivation:**

We want to support Zeus config parsing to enable testing of queued
deployments. Our original deployment parser lacked the flexibility
needed to support Zeus without requiring changes to Zeus itself.
Additionally, the `User` and `AVS` contracts deployed by the
`IntegrationDeployer` aren't able to properly read config from
`IntegrationDeployer` leading to bandaid solutions.

**Modifications:**

- Removed `InitialDeploymentParser`: About 1k lines -> 100 for parsing.
- Added `ConfigParser`: A parser that supports both fast TOML parsing
and Zeus-style parsing.
- Added `ConfigGetters`: A abstraction that allows contracts deployed by
the `IntegrationDeployer` to easily access the current configuration.

**Result:**

Contracts deployed through the `IntegrationDeployer` can now reliably
access their configuration, and Zeus integration is possible without
needing to modify Zeus.
@0xClandestine 0xClandestine force-pushed the refactor/integration-tests branch from ad2983c to 1cc31b2 Compare April 8, 2025 15:46
Copy link
Collaborator

@ypatil12 ypatil12 left a comment

Choose a reason for hiding this comment

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

Solid refactor, had one question

"strategyFactoryImplementation": "0x8b1F09f8292fd658Da35b9b3b1d4F7d1C0F3F592",
"strategyManager": "0x70f8bC2Da145b434de66114ac539c9756eF64fb3",
"strategyManagerImplementation": "0x1562BfE7Cb4644ff030C1dE4aA5A9aBb88a61aeC",
"TestToken": "0xcae746B46013Bf4D43B8E2B9e98F9DBE2461532A",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any reason this is updated?

Copy link
Member Author

Choose a reason for hiding this comment

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

Some test is writing to this file, I fixed it. Will reset this file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📜 Chore Maintenance related changes (CI, QOL, etc.). 📖 Documentation Improvements or additions to documentation. ✨ Enhancement New feature or request. ♻️ Refactor Code improvements without changing functionality. 📜 Script Script-related changes (automation, tooling). 🧪 Test Test-related changes (unit, integration, etc.).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants