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

Support for Primitive Proptests #1435

Conversation

YoshikiTakashima
Copy link
Contributor

@YoshikiTakashima YoshikiTakashima commented Aug 2, 2022

Description of changes:

Adds support for running proptests with primitive inputs using kani.

Resolved issues:

Resolves #1363

Call-outs:

  • Feature only runs with cargo kani.
  • Since we are only merging a small portion of proptest, we cannot support proptests like tests/cargo-kani/rectangle-example. This means we disable the proptest import in that test case.

Testing:

  • How is this change tested? tests/cargo-kani/proptest

  • Is this a refactor change? No.

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Yoshi Takashima added 30 commits July 1, 2022 15:30
Copy link
Contributor

@danielsn danielsn left a comment

Choose a reason for hiding this comment

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

Can you add some documentation on what you're doing in the proptest override? Maybe a README.md?

.cargo/config.toml Outdated Show resolved Hide resolved
docs/src/tutorial/first-steps-v1/Cargo.toml Show resolved Hide resolved
docs/src/tutorial/first-steps-v2/Cargo.toml Show resolved Hide resolved
kani-compiler/build.rs Outdated Show resolved Hide resolved
docs/src/tutorial/kinds-of-failure/Cargo.toml Show resolved Hide resolved
scripts/cargo-kani Outdated Show resolved Hide resolved
scripts/refresh-kani-proptest.sh Outdated Show resolved Hide resolved
scripts/refresh-kani-proptest.sh Show resolved Hide resolved
tests/cargo-kani/rectangle-example/Cargo.toml Show resolved Hide resolved
scripts/kani-regression.sh Outdated Show resolved Hide resolved
@danielsn
Copy link
Contributor

danielsn commented Aug 8, 2022

We now have a fork of propest. What's the best way to maintain this.

Copy link
Contributor

@celinval celinval left a comment

Choose a reason for hiding this comment

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

I don't think we should add the proptest code in our repository. We should probably do one of the following:

  1. Refactor the changes so we can extend proptest instead of forking from it.
  2. If we do need to fork proptest, we should create a separate repository with the fork. We should then add a submodule here to this fork.

Feel free to ping me offline if you want to discuss this further or if you have any suggestions.

library/kani/src/invariant.rs Outdated Show resolved Hide resolved
setup_lib(&out_dir, &lib_out, "kani");
setup_lib(&out_dir, &lib_out, "kani_macros");
setup_lib(&out_dir, &lib_out, "std");
println!("cargo:rustc-env=KANI_LIB_PATH={}", lib_out);
println!("cargo:rustc-env=TARGET={}", target);
println!(
"cargo:rustc-env=KANI_EXTERN_OUT_DIR={}",
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason why you are not using out_dir?

Copy link
Contributor Author

@YoshikiTakashima YoshikiTakashima Aug 9, 2022

Choose a reason for hiding this comment

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

cargo kani compiles to the directory with target/$ARCH/debug/deps automatically.

I've found the incremental build to be a bit more finichy when using target/debug/deps perhaps because cargo build --workspace will also compile to the same directory. I can give it a try if needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Yeah, that is a problem that we have with our libraries today. We are compiling them twice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is that one of the issues addressed in your linker update? If so, I can hold off on this one until that is in, and both std/proptest can take advantage.

@@ -80,10 +82,18 @@ impl KaniSession {
});
}

let mut symtabs = glob(&outdir.join("*.symtab.json"))?;
let mut metadata = glob(&outdir.join("*.kani-metadata.json"))?;
if std::env::var("IS_KANI_PROPTEST").is_ok() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I posted a comment in the issue you created. Can you please check?

@@ -80,10 +82,18 @@ impl KaniSession {
});
}

let mut symtabs = glob(&outdir.join("*.symtab.json"))?;
let mut metadata = glob(&outdir.join("*.kani-metadata.json"))?;
if std::env::var("IS_KANI_PROPTEST").is_ok() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we planning to enable this as a compilation flag or a runtime option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As of now, scripts/cargo-kani detects proptests automatically. I would be OK making it an argument, perhaps via -Z

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, it's probably better if the user has to opt-in at this point.

Copy link
Contributor

@celinval celinval left a comment

Choose a reason for hiding this comment

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

A few more comments. :)

@@ -19,4 +19,26 @@ then
fi
KANI_PATH=${KANI_CANDIDATES[0]}

# if the crate uses proptest, get ready to run that. Make sure local
# proptest import and kani's proptest does not clash.
function has-direct-proptest-import() {
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't add any logic to these scripts. They are meant to be a proxy that enables development and it will actually not run with our pre-build code.

Is there a reason why this is not inside kani-driver? We are already invoking cargo metadata there which already has this information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a reason why this is not inside kani-driver? We are already invoking cargo metadata there which already has this information.

If it already has Cargo.toml info, I'll move to that

# not support any integers, which crashes this test case. See
# https://github.com/model-checking/kani/issues/1473 for details.
# [dev-dependencies]
# proptest = "1.0.0"
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer if you add a runtime option for users to enable proptest analysis.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll resolve this along with the comment with IS_KANI_PROPTEST

@YoshikiTakashima
Copy link
Contributor Author

Until the ticket for approving the separate repository goes through, code review for proptests will be managed through the features/proptest branch. The proptest fork will be imported through submodules.

@YoshikiTakashima
Copy link
Contributor Author

YoshikiTakashima commented Aug 15, 2022

Closing in favor of the following approaches.

  1. The following proptest injection scheme works fine once proptest's kanilib dependency is under [target.'cfg(not(kani))'.dependencies] to avoid clash.
proptest = { path = "$PATH_TO/STUBBED/proptest"}
  1. Long-term, we probably can support injection done by appending the following to Cargo.toml. We cannot immidately use this b/c the patch feature requires that the offered features of the overriding library match up with the original library. While the override is cleaner, there is no good way to condition this on being specific to cfg(kani).
[patch.crates-io]
proptest = { path = "$PATH_TO/STUBBED/proptest"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Primitive Proptests
3 participants