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

Run all proof harnesses by default #962

Merged
merged 24 commits into from
Mar 25, 2022

Conversation

tedinski
Copy link
Contributor

@tedinski tedinski commented Mar 18, 2022

Description of changes:

  1. Hide (but technically keep) --function in favor of --harness which must be #[kani::proof]. Updated all documentation accordingly.
  2. cargo-kani now parses and merges kani-metadata.json files, to support looking up proof harnesses.
    • Quick note: I changed dry-run output to report *.symtab.json instead of dry-run.symtab.json
  3. (Minor: I uh, altered --gen-c to print where the file was generated.)
  4. crate-type=lib is now unconditional and we (by documentation) require #[kani::proof]. Technically, --function can still specify anything but you need some method of ensuring the function gets code-gen'd.
  5. THE MEAT: cargo-kani and kani now default to running all proof harnesses found.
    • Switch to just one with --harness
    • Behavior is to run each one one after another until either one fails (and we stop) or all suceed and we print "All harnesses successfully verified."
  6. Added a new mode for cargo-kani mode tests. We can now add a plain expected file instead of function.expected and this will run cargo-kani without any --function flags.

phew

Resolved issues:

Resolves #464
Resolves #691

Contributes to #477 and #701

Call-outs:

Testing:

  • How is this change tested? 2 new tests cases, fairly basic. Plus existing whole test suite.

  • 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.

@tedinski tedinski requested a review from a team as a code owner March 18, 2022 22:31
@tedinski
Copy link
Contributor Author

oh, doh. I need to adapt bookrunner to work with needing #[kani::proof] annotations now. Welp, monday.

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.

Sweet! Mostly minor comments. I do think we should change the behaviour to run all harnesses before failing though.

src/cargo-kani/src/args.rs Show resolved Hide resolved
src/cargo-kani/src/call_goto_instrument.rs Outdated Show resolved Hide resolved
src/cargo-kani/src/main.rs Outdated Show resolved Hide resolved
drop(ctx);
std::process::exit(1);

let metadata = ctx.collect_kani_metadata(&[outputs.metadata])?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move the duplicated code to a separate function?

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've tried to avoid having any functions that are specific to kani or cargo-kani (except these two of course) because I think these are generally design errors. You'll notice that there are several small variations between these two functions, and trying to abstract those differences out will generally make the code worse, not better.

A small amount of not-really-duplication is better than trying to create a function with a half dozen parameters that only gets called 2 ways. The old python was full of that, and it's just code that only gets worse as people add to it.

That said, I think there IS a little bit I can factor out here, I just need to fix how we do report generation first since I actually broke that...

Copy link
Contributor

Choose a reason for hiding this comment

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

That makes sense. Thanks

src/cargo-kani/src/metadata.rs Outdated Show resolved Hide resolved
tests/expected/multiple-harnesses/expected Outdated Show resolved Hide resolved
tools/compiletest/src/runtest.rs Outdated Show resolved Hide resolved
Comment on lines +283 to +292
match self.props.kani_panic_step {
Some(KaniFailStep::Check) => {
self.check();
}
Some(KaniFailStep::Codegen) => {
self.codegen();
}
Some(KaniFailStep::Verify) | None => {
self.verify();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change is necessary since we now may run kani-compiler from kani with different flags that compiletest wasn't picking up. This change means we avoid doing redundant work, and these differences only matter for things that expected to fail to check or codegen (which wasn't any existing tests, thankfully)

Just thought I'd note this in the review here, since it got mixed up with a bunch of other changes to get tests working again after switching to using --harness

@tedinski
Copy link
Contributor Author

This should be ready to review again.

It now runs all proof harnesses even if one fails, and prints a summary at the end:

Complete - 2 successfully verified harnesses, 0 failures, 2 total.

Hmm. Possibly I should print which harnesses failed, so you don't have to scroll up to search for them... Let me know your thoughts.

We now also produce all reports with --visualize which required creating multiple directories, one for each harness:

$ cargo kani --visualize
$ ls -l target/
total 24
-rw-rw-r-- 1 ubuntu ubuntu  177 Mar 23 19:13 CACHEDIR.TAG
drwxrwxr-x 7 ubuntu ubuntu 4096 Mar 23 19:13 debug
drwxrwxr-x 4 ubuntu ubuntu 4096 Mar 23 19:22 report-proofs::check_trivial
drwxrwxr-x 4 ubuntu ubuntu 4096 Mar 23 19:22 report-proofs::failed_check
drwxrwxr-x 4 ubuntu ubuntu 4096 Mar 23 19:22 report-proofs::third_harness
drwxrwxr-x 3 ubuntu ubuntu 4096 Mar 23 19:13 x86_64-unknown-linux-gnu

I notice that the "pretty name" of function is fully qualified. I'm thinking about fixing that (advice?) but if we don't use the fully qualified names, there might be name collisions. (At the very least, colon isn't legal in filenames on windows, so we have to do something...)

@celinval
Copy link
Contributor

The way proof is implemented today by using no_mangle guarantees that you can't have name collision between harnesses. I believe if that happens, the compilation fails.

That said, can you replace the :: by .?

Copy link
Contributor

@zhassan-aws zhassan-aws left a comment

Choose a reason for hiding this comment

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

This is a huge step forward! Awesome work, @tedinski!

Just had a few minor comments.

docs/src/kani-single-file.md Outdated Show resolved Hide resolved
println!("Verification failed for - {}", harness.pretty_name);
}

println!(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we still print this summary line when self.args.quiet is true? cargo test prints the summary even with --quiet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe. In my experience, there is a contingent of "if I say quiet, actually print nothing, just give me a return value" software out there. But... maybe this isn't one that should be that way.

cargo test is a compelling point of comparison. Possibly we should do some output comparisons and decide differently later?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure.

src/cargo-kani/src/metadata.rs Outdated Show resolved Hide resolved
src/cargo-kani/src/metadata.rs Show resolved Hide resolved
@@ -1,8 +1,8 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// @expect verified
Copy link
Contributor

Choose a reason for hiding this comment

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

Is removing the SMACK annotations necessary? They're probably meant for the SMACK testing tool, but they may be useful for us to compare results.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No: I needed to quickly audit those files to fix a few things and I removed what I thought was unnecessary. I don't see how these would ever get used...

tools/bookrunner/src/util.rs Show resolved Hide resolved
@adpaco-aws adpaco-aws mentioned this pull request Mar 25, 2022
6 tasks
@tedinski tedinski dismissed celinval’s stale review March 25, 2022 16:23

Zyad took over

@tedinski tedinski merged commit 70e5a39 into model-checking:main Mar 25, 2022
@tedinski tedinski deleted the proof-harnesses branch March 25, 2022 19:36
tedinski added a commit to tedinski/rmc that referenced this pull request Apr 22, 2022
* Introduce --harness and parse kani-metadata.

* run all proof harnesses

* enable function-less 'expected' tests for cargo-kani in compiletest

* Only mention --harness not --function in docs

* use --harness instead of --function in tests, mostly.

* Run all harnesses, even if one fails. Also generate all reports in separate directories

* Output reports (and harness) with - not :: in file names

* Print all failed harnesses in a final summary

* Make harness search robust against possible future name collisions
tedinski added a commit to tedinski/rmc that referenced this pull request Apr 25, 2022
* Introduce --harness and parse kani-metadata.

* run all proof harnesses

* enable function-less 'expected' tests for cargo-kani in compiletest

* Only mention --harness not --function in docs

* use --harness instead of --function in tests, mostly.

* Run all harnesses, even if one fails. Also generate all reports in separate directories

* Output reports (and harness) with - not :: in file names

* Print all failed harnesses in a final summary

* Make harness search robust against possible future name collisions
tedinski added a commit to tedinski/rmc that referenced this pull request Apr 26, 2022
* Introduce --harness and parse kani-metadata.

* run all proof harnesses

* enable function-less 'expected' tests for cargo-kani in compiletest

* Only mention --harness not --function in docs

* use --harness instead of --function in tests, mostly.

* Run all harnesses, even if one fails. Also generate all reports in separate directories

* Output reports (and harness) with - not :: in file names

* Print all failed harnesses in a final summary

* Make harness search robust against possible future name collisions
tedinski added a commit that referenced this pull request Apr 27, 2022
* Introduce --harness and parse kani-metadata.

* run all proof harnesses

* enable function-less 'expected' tests for cargo-kani in compiletest

* Only mention --harness not --function in docs

* use --harness instead of --function in tests, mostly.

* Run all harnesses, even if one fails. Also generate all reports in separate directories

* Output reports (and harness) with - not :: in file names

* Print all failed harnesses in a final summary

* Make harness search robust against possible future name collisions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants