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: add JS fuzz/invariant integration tests #658

Merged
merged 6 commits into from
Sep 13, 2024

Conversation

agostbiro
Copy link
Member

Add JS fuzz/invariant integration tests and fix the following issues:

  • Make the failure persist dir optional for fuzz config as intended originally to be able to disable persisting results.
  • Disable collecting gas report samples during fuzz/invariant testing for performance as we don't yet support gas reports.
  • Remove unwrap on FuzzConfig::failure_persist_file. Instead reflect in the type system that it's not optional.
  • Mitigate leaking the fuzz failure persist path by making sure that one particular path is only leaked once.

Copy link

changeset-bot bot commented Sep 10, 2024

⚠️ No Changeset found

Latest commit: ab94d0b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@agostbiro agostbiro had a problem deploying to github-action-benchmark September 10, 2024 19:19 — with GitHub Actions Error
@agostbiro agostbiro had a problem deploying to github-action-benchmark September 10, 2024 19:19 — with GitHub Actions Error
@agostbiro agostbiro self-assigned this Sep 10, 2024
@agostbiro agostbiro added the no changeset needed This PR doesn't require a changeset label Sep 10, 2024
@agostbiro agostbiro added this to the Solidity tests, phase 2 milestone Sep 10, 2024
@agostbiro agostbiro force-pushed the test/fuzz-js-integration-tests branch from c848179 to 4da1eb1 Compare September 10, 2024 19:35
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 10, 2024 19:35 — with GitHub Actions Inactive
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 10, 2024 19:35 — with GitHub Actions Inactive
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 11, 2024 09:36 — with GitHub Actions Inactive
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 11, 2024 09:36 — with GitHub Actions Inactive
Copy link
Member

@Wodann Wodann left a comment

Choose a reason for hiding this comment

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

One concern w.r.t. the leaking of static strings. Otherwise LGTM!

.into_string()
.expect("path should be valid UTF-8");

// HACK: We need to leak the path as
Copy link
Member

Choose a reason for hiding this comment

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

For correctness, I believe we should still drop the leaked strings upon static deinitialization. That can be achieved by adding a local struct SomeName { inner: HashSet<&'static str> } which has a impl Drop. This destructor would be called when the static FAILURE_PATHS is dropped, guaranteeing that our application doesn't report any memory leaks in tooling.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey, I tried this out with LLVM leak sanitizer and it reports errors in the base branch, but not in this one, so I think it's ok as is.

Test command (tried on ARM linux in Docker): RUSTFLAGS="-Z sanitizer=leak" cargo +nightly test -p forge test_fuzz

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 couldn't get Miri working on the forge integration tests)

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for validating with leak sanitizer.

This is the reason why Leak Sanitizer would not be able to detect a "memory leak" of this kind. It depends on your definition of memory leak, though. Leak sanitizer doesn't consider it a leak because a static variable is still referring to the address of the originally allocated strings.

crates/foundry/forge/src/runner.rs Outdated Show resolved Hide resolved
@fvictorio fvictorio temporarily deployed to github-action-benchmark September 12, 2024 07:54 — with GitHub Actions Inactive
@fvictorio fvictorio temporarily deployed to github-action-benchmark September 12, 2024 07:54 — with GitHub Actions Inactive
@fvictorio
Copy link
Member

I pushed a commit removing chai-as-promised and checking if a directory exists using fs.existsSync.

The previous version wasn't bad or anything, but I've had so many bad experiences with chai-as-promised that I'd rather avoid it.

// One test as steps should be sequential
it("FailingInvariant", async function () {
const failureDir = testContext.invariantFailuresPersistDir;
const defaultConfig = {
Copy link
Member

Choose a reason for hiding this comment

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

I would rename this to invariantConfig

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, fixed in ab94d0b

// The invariant failure directory should still be there
assert.isTrue(existsSync(failureDir));
// The second run should be faster than the first because it should use the persisted failure.
assert.isBelow(secondDuration, firstDuration * 0.25);
Copy link
Member

Choose a reason for hiding this comment

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

I think there is a more robust way to check this. The TestResult objects have a kind.runs number for invariant tests which will be 1 when there is a cached seed, and it will almost surely be above 1 when there's not (and this can be done even more unlikely by changing the % 13 part of the solidity test to a bigger value).

The problem is that runTestsWithStats only returns the number of tests and failures. Maybe we can just add a testResults property to its returned value, that way there's no need to refactor all the existing usages of that helper.

This is just a suggestion btw, feel free to keep it as is if you think that this approach won't have frequent false positives or negatives.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, good idea, switched to checking runs. The assertion is that there are more than 1 runs on an uncached run and there is 1 run on a cached one. I didn't want to increase the 13 to a larger value to reduce the chance of the invariant testing not catching the bug.

ab94d0b

Base automatically changed from test/fail-test to feat/solidity-tests September 12, 2024 15:25
@agostbiro agostbiro force-pushed the test/fuzz-js-integration-tests branch from 020af16 to 7fe8315 Compare September 12, 2024 15:28
@agostbiro agostbiro had a problem deploying to github-action-benchmark September 12, 2024 15:28 — with GitHub Actions Error
@agostbiro agostbiro had a problem deploying to github-action-benchmark September 12, 2024 15:28 — with GitHub Actions Error
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 12, 2024 16:30 — with GitHub Actions Inactive
@agostbiro agostbiro temporarily deployed to github-action-benchmark September 12, 2024 16:30 — with GitHub Actions Inactive
@agostbiro agostbiro merged commit 660428c into feat/solidity-tests Sep 13, 2024
37 of 38 checks passed
@agostbiro agostbiro deleted the test/fuzz-js-integration-tests branch September 13, 2024 08:52
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
no changeset needed This PR doesn't require a changeset
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants