Skip to content

Report the failure exit code under --quiet - #4771

Open
ivmat wants to merge 2 commits into
model-checking:mainfrom
ivmat:fix-quiet-exit-code
Open

Report the failure exit code under --quiet#4771
ivmat wants to merge 2 commits into
model-checking:mainfrom
ivmat:fix-quiet-exit-code

Conversation

@ivmat

@ivmat ivmat commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Resolves #4745.

--quiet's help text promises "Produces no output, just an exit code and requested artifacts", but print_final_summary returned early under --quiet before reaching the exit(1) that reports failures, so a failing verification run exited 0. Nothing else set the failure exit code.

This suppresses only the summary output under --quiet: the failure counts are computed unconditionally and the exit code and error returns are kept identical to a non-quiet run. print_autoharness_summary takes a quiet flag so it still reports its failure count without printing — so this also fixes the same swallowed-exit-code bug for autoharness --quiet.

Behavior under --quiet, before → after

  • Failing manual run: exit 0 → exit 1 (the bug).
  • Failing autoharness run: exit 0 → exit 1 (same root cause).
  • Passing run: exit 0 → exit 0 (unchanged), still no output.
  • Zero-match --harness filter on a filter-skipping path: this now returns the no_harness_match_error (one line to stdout, exit non-zero) under --quiet as well, matching every other hard-error path — which already print and exit non-zero regardless of --quiet. Previously --quiet swallowed it into exit 0. (The common zero-match case is already handled earlier by determine_targets since Fail a zero-match harness filter before codegen and export #4743; this only affects the filter-skipping arm.)

Test

Extends tests/script-based-pre/check-quiet: it now runs a failing harness under --quiet and asserts exit 1, plus a passing-run control asserting exit 0. The previous test only ran passing harnesses and never inspected the exit code. The check captures both stdout and stderr, since the --quiet contract covers all output, not just stdout.

@ivmat
ivmat requested review from a team as code owners August 27, 2026 20:22
`--quiet`'s help text promises "no output, just an exit code and requested
artifacts", but `print_final_summary` returned early under `--quiet` before
reaching the `exit(1)` that reports failures, so a failing verification run
exited 0. Nothing else set the failure exit code.

Suppress only the summary output under `--quiet`: compute the failure counts
unconditionally and keep the exit code and error returns identical to a
non-quiet run. `print_autoharness_summary` takes a `quiet` flag so it still
reports its failure count without printing the summary; this also fixes the
same bug for `autoharness --quiet`, whose failure count previously never
reached the exit code.

Add a regression test that runs a failing harness under `--quiet` and asserts
exit 1, plus a passing-run control asserting exit 0 -- the existing check-quiet
test only ran passing harnesses and never inspected the exit code.

Resolves model-checking#4745
@ivmat
ivmat force-pushed the fix-quiet-exit-code branch from 0d20f68 to 7644203 Compare August 27, 2026 20:56
@ivmat

ivmat commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

earlier CI red was kani-fmt --check wanting a println! collapsed

@celinval celinval left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's a good catch. Thanks for taking the time.

Comment thread kani-driver/src/harness_runner.rs Outdated

let autoharness_failing = if self.autoharness_compiler_flags.is_some() {
self.print_autoharness_summary(automatic)?
self.print_autoharness_summary(automatic, quiet)?

@celinval celinval Aug 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd prefer if we split print_autoharness_summary. Something like:

// You can move the self.autoharness_compiler_flags.is_some() check to be inside self.autoharness_result.
let autoharness_result = self.autoharness_result(automatic);
if !quiet {
    self.print_autoharness_summary(autoharness_result);
}
if failing + autoharness_result.failing.len() {
 ...
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done (all), also ran tests locally on linux

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

...i spoke too soon

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

dont have same setup locally so missed the clippy test... will fix

Comment thread kani-driver/src/autoharness/mod.rs Outdated
pub fn print_autoharness_summary(
&self,
mut automatic: Vec<&HarnessResult<'_>>,
quiet: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I know that's not on you, but I think we should change this function should either return Result<()> or nothing, depends whether it fallible or not. It's a print function, it shouldn't really be returning any data.

Comment thread kani-driver/src/harness_runner.rs Outdated
if self.args.common_args.quiet {
return Ok(());
}
// `--quiet` promises "no output, just an exit code and requested artifacts". It must

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I don't think we need this comment.

Address review: separate the compute (partition into successes/failing,
now behind an autoharness_result() that folds in the
autoharness_compiler_flags.is_some() check) from the print
(print_autoharness_summary, now a pure void function with no quiet
param and no returned count). print_final_summary computes the
autoharness result unconditionally and gates only the print on
!quiet, then derives the exit code from failing + the computed
failing count, unchanged from before. Also drops the now-superfluous
comment block above print_final_summary.
@ivmat
ivmat force-pushed the fix-quiet-exit-code branch from acf1c4e to 0b39b0b Compare August 28, 2026 16:56
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.

not sure if issue, more a question, is this expected or not: --quiet makes a failing verification run exit 0

2 participants