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

Test reorg + various improvements #284

Merged
merged 31 commits into from
Jan 27, 2023
Merged

Test reorg + various improvements #284

merged 31 commits into from
Jan 27, 2023

Conversation

PaulRBerg
Copy link
Member

@PaulRBerg PaulRBerg commented Jan 21, 2023

This PR makes many improvements, most of them related to the tests.

Copy link
Member

@andreivladbrg andreivladbrg left a comment

Choose a reason for hiding this comment

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

Add {} brackets around Sablier contract names, functions, and events

I like these.

Commit a gas snapshot

Why is this useful?

Re-enables integration tests in CI. Hopefully #233 is fixed now after my foundry-rs/foundry-toolchain#19.

Unfortunately it doesn't. Tested locally and it took more than 15 minutes. Also a high number of requests.

Why do you want to run the e2e tests in the default foundry profile? I know you added a script in the json file for the yarn test CLI, but I think we should leave the basic forge test command to work without implementing an .env file.

I have a suggestion regarding the calculation functions from the Base_Test contract:

https://github.com/sablierhq/v2-core/blob/a99585a6e842d5156d34473ec9e31008231ff387/test/Base.t.sol#L147-L243

Let's add an abstract contract called Calculations in the helpers dir and move those there. Ofc it would inherit the Constants contract.

These should be also moved into the Constants contract.

https://github.com/sablierhq/v2-core/blob/a99585a6e842d5156d34473ec9e31008231ff387/test/Base.t.sol#L62-L67

Shouldn't we move the test/shared/helpers into a different path test/helpers?

test/fuzz/Fuzz.t.sol Outdated Show resolved Hide resolved
test/unit/Unit.t.sol Outdated Show resolved Hide resolved
test/Base.t.sol Outdated
initialAdmin: users.admin,
initialComptroller: comptroller,
maxFee: DEFAULT_MAX_FEE
});
pro = new SablierV2LockupPro({
pro = new DeployLockupPro().run({
Copy link
Member

Choose a reason for hiding this comment

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

Why do you deploy each of these when we can use DeployProtocol?

(comptroller, linear, pro) = new DeployProtocol().run({
                initialAdmin: users.admin,
                maxFee: DEFAULT_MAX_FEE,
                maxSegmentCount: DEFAULT_MAX_SEGMENT_COUNT
            });

Copy link
Member Author

Choose a reason for hiding this comment

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

The point is to test the scripts, as many as possible. We want to test the individual scripts because it gives us confidence that they work as expected.

Copy link
Member

Choose a reason for hiding this comment

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

There is absolutely no reason why would DeployProtocol work and DeployComptroller DeployLockupLinear DeployLockupPro won't.

DeployProtocol = DeployComptroller + DeployLockupLinear + DeployLockupPro

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm sorry, I don't understand what you mean. DeployProtocol does NOT import and does NOT use the other scripts.

However, this is an interesting idea. We could refactor the deployment scripts to do this, i.e. have DeployProtocol depend upon all the other scripts. If we do this, then we can use DeployProtocol in the tests, too.

test/Base.t.sol Outdated Show resolved Hide resolved
test/unit/Unit.t.sol Outdated Show resolved Hide resolved
test/unit/Unit.t.sol Outdated Show resolved Hide resolved
src/abstracts/SablierV2FlashLoan.sol Outdated Show resolved Hide resolved
@PaulRBerg
Copy link
Member Author

Thanks, @andreivladbrg.

Why is this useful?

Why not? It gives us - and any potential reader of the repo - an overview of the current gas costs for running tests. I think that you should start thinking about this repo as a public good that will eventually be seen by many people.

Unfortunately it doesn't. Tested locally and it took more than 15 minutes. Also a high number of requests.

I think that you have misunderstood my intention with #233 (I admit that the name of the title isn't great).

The idea wasn't to make the end-to-end tests as fast as the unit or the fuzz tests - that is just not possible, because even with the cache, the data has to be loaded from the file system, which takes more time than generating in-memory values.

In short, my intention was to make the RPC caching work (see my PRs in the foundry-toolchain repo), and also cache the fuzzing seed on a weekly basis.

Based on the latest CI runs, I think that I have succeeded in achieving the above. The fact that it took 15 minutes to run locally is good.

Why do you want to run the e2e tests in the default foundry profile?

We have talked about this already - we need to include the e2e tests in the default Foundry profile because the test config option is NOT a glob pattern. There's no way to go around that now because we have both unit and fuzz tests - we can't set a path that includes only test/unit and test/fuzz but not test/e2e`.

I know you added a script in the json file for the yarn test

Yup, you should get used to it.

I think we should leave the basic forge test command to work without implementing an .env file.

We can't, based on the explanation above.

However, what you can do is set FOUNDRY_PROFILE to lite on your local machne, which will compile the contracts without the traditional optimizer enabled, and it will fuzz only 50 times. With this profile, it takes ~30 seconds on my machine to run all tests, including e2e tests.

I recommend you install direnv and add this env var in a .envrc file.

@PaulRBerg
Copy link
Member Author

Let's add an abstract contract called Calculations in the helpers dir and move those there

I'm pretty agnostic about this - go for it if you wish.

These should be also moved into the Constants contract.

Fine, but make sure that they are initialized properly in the constructor of Constants.

Shouldn't we move the test/shared/helpers into a different path test/helpers?

That's where they used to be, and I moved them to test/shared/helpers in this commit:

8a84135

The rationale is the following - it's just easier to have only one "special" directory in test (i.e. shared) rather than two special directories (shared and helpers). The helpers are technically shared, so it made sense to me to place them under shared.

You will see that once I finish my work on invariants, it will look odd to have several tests and non-tests directories under test.

@PaulRBerg
Copy link
Member Author

Regarding your comments:

Let's move these in the Base_Test contract, they are used in both fuzz and unit tests.

I agree.

@andreivladbrg
Copy link
Member

an overview of the current gas costs for running tests. I think that you should start thinking about this repo as a public good that will eventually be seen by many people.

As discussed before, these gas costs are not accurate at all. I don't think it is in our favor, would be better to leave a screenshot of the --gas-report in the README file

I think that you have misunderstood my intention with #233 (I admit that the name of the title isn't great).

Yes, I did

we can't set a path that includes only test/unit and test/fuzz but not test/e2e`

Fair enough

However, what you can do is set FOUNDRY_PROFILE to lite on your local machne, which will compile the contracts without the traditional optimizer enabled, and it will fuzz only 50 times.

I personally know this, I was thinking more about a beginner who wants to just run the repo with the basic instructions given in the foundry book.

including e2e tests.

The e2e tests are not included in the yarn test CLI.
https://github.com/sablierhq/v2-core/blob/6eee3bc0b3a9a31a0dceaf74d564bcc56e05ecd7/package.json#L47

The rationale is the following - it's just easier to have only one "special" directory in test (i.e. shared) rather than two special directories (shared and helpers). The helpers are technically shared, so it made sense to me to place them under
shared

Fair enough.

build: upgrade to latest "forge-std"
ci: re-enable integration tests
style: format "foundry.toml" with Taplo
test: add "lite" profile for quick testing locally
test: fix integration tests
test: use "getTokenBalances" from "forge-std"
chore: add "snapshot" script in "package.json"
build: add "build:optimized" command in "package.json"
ci: rename "test" job to "build-and-test"
ci: say "Uploaded to Codecov" in coverage result
docs: document gas report and snapshot commands
docs: document "test:optimized" command
test:restrict gas reports to the Sablier contracts
ci: update paths to deployment scripts
ci: update workflow names to match contracts
refactor: sort struct imports alphabetically
test: add "DEFAULT_ASSET" and use it in stead of "dai"
test: add "err" argument to most struct comparison assertions
test: define "streamId" and load it in "setUp" function]
test: delete "asset" in flash loan tests
test: extend custom assertions with overloads that have "err" param
test: fuzz sender in create function tests
test: merge bottom leaves in all tests
test: test event emit in the same unit tests
test: use more named args
refactor: rename "admin" to "initialAdmin" in scripts
refactor: rename "comptroller" to "initialComptroller" in scripts
refactor: rename "approveSablierContracts" to "approveProtocol"
refactor: rename "deploySablierContracts" to "deployProtocol"
test: add "Deployers" struct
tets: use "vm.startPrank" instead of "changePrank" in "setUp"
test: add "_Integration" suffix to all integration test contracts
chore: set verbosity 4 in "test-optimized" Foundry profile
docs: update "Tests" section of the README
refactor: rename "FeeTooHigh" to "CalculatedFeeTooHigh"
refactor: transfer "senderAmount" before "recipientAmount"
test: add basic tests with harcoded values
test: define all shared linear tests in "Linear.t.sol"
test: define all shared pro tests in "Pro.t.sol"
test: define "MAX_SEGMENTS" in "BaseTest"
test: delete unused imports
test: dryify test leaves
test: ensure no same value for user addresses in integration tests
test: fix tests names (remove "Fuzz_" when no fuzzing)
test: fix typos in code comments
test: fuzz amounts in "SegmentAmountsSumOverflows" branch
test: import using relative paths (delete "test/=test/" remapping)
test: improve the inheritance structure in the shared tests
test: improve wording in test descriptions
test: move "calculateStreamedAmount" helpers in "BaseTest"
test: rename "DEFAULT_CREATE_AMOUNTS" to "DEFAULT_LOCKUP_CREATE_AMOUNTS"
test: rename "depositDelta" to "depositDiff"
test: restructure shared lockup tests
test: run all tests by default
test: test all statuses and withdrawn amounts in "withdrawMultiple" tests
test: unfuzz "eve" and "operator"
test: use default streams in "getStreamedAmount" and "getWithdrawableAmount"
test: use named args for "changePrank" util
test: use structs to fix StackTooDepp in "withdrawMultiple"
chore: pass "--no-match-path" to gas report and snapshot commands
docs: add "sablier-v2" keyword in "package.json"
ci: make "test" and "coverage" jobs need "lint" and "build" jobs
test: exclude end-to-end tests in "test:optimized" script
test: move "test/helpers/flash-loan" under "test/shared"
test: move "test/helpers/hooks" under "test/shared"
test: move "test/shared/hooks" under "test/shared/mockups"
@PaulRBerg
Copy link
Member Author

I don't think it is in our favor, would be better to leave a screenshot of the --gas-report in the README file

As discussed in person, we will keep the gas snapshot because it can be useful even if it's inaccurate.

I was thinking more about a beginner who wants to just run the repo with the basic instructions given in the foundry book.

Well, this is precisely why I have opened issue 3841 in the Foundry repo. It would be pretty cool to be able to set glob patterns as the value for the test option.

However, as a repo grows in complexity, it becomes impossible to stick with the default configs of any given open-source tool. The remedy for this is good developer documentation - which we will make sure to have.

The e2e tests are not included in the yarn test CLI.

I was referring to running forge test. It takes ~30 seconds to run all tests (including end-to-end) on my machine with the lite profile.

PaulRBerg and others added 2 commits January 27, 2023 16:41
chore: use "override" specifier in pro
chore: correct comment in flashloan contract
test: add a calculations helper contract
test: move logic from "Base_Test" to "Calculations"
test: move constants from "Base_Test" to "Constants"
test: move contracts that are used in both fuzz and unit test in the
"Base_Test"
test: label contracts in the "Base_Test"
test: remove unused imports
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants