Skip to content

A negated command only asserts in final position - #10

Merged
marcos-mendez merged 3 commits into
19.xfrom
test/negations-that-assert
Sep 29, 2026
Merged

marcos-mendez merged 3 commits into
19.xfrom
test/negations-that-assert

Conversation

@marcos-mendez

Copy link
Copy Markdown
Collaborator

The three negations in tests/postfix-local.bats now assert wherever they stand. One of them did not assert at all.

Closes #9. Part of Keel-Linux/tracker#19, which has the organization-wide sweep.

Why a bare ! is inert

A bats test body has no assertions of its own: its verdict is the exit status of the last command it ran. Bash does not apply errexit to a negated command, so ! cmd decides the test in final position and is inert everywhere else. shellcheck grades the two apart, error: for the inert ones and note: for the rest:

shellcheck -f gcc --shell=bash tests/*.bats | grep SC2314

What was not being checked

Line 96, in "stops at the first failing postconf". The test is named for stopping at the first failure, and ! logged smtpd_banner is the assertion that says it stopped — a script that carried on past the failing postconf and set the banner anyway would have passed. Lines 66 and 97 are last in their bodies and did assert.

All three are run ! now, the two that already asserted included: a line whose meaning depends on its position is the trap itself.

The COVERAGE.md correction

COVERAGE.md on fix/keel-apt-identity (#8) states:

tests/postfix-local.bats still has three of them (lines 66, 96 and 97) and they are left for the pull request that owns that file.

That is wrong about two of the three: 66 and 97 are in final position and do assert. This PR puts the accurate statement on 19.x, in the same place, so the branch is the record:

tests/postfix-local.bats had three bare negations: line 96 was inert and lines 66 and 97 did assert, because they were last. All three are run ! now […]

That will conflict with #8, deliberately: the same paragraph in the same position, so whoever rebases #8 has to reconcile it rather than silently restore the wrong sentence. #8's version should be dropped on rebase.

Test plan

  • shellcheck -f gcc --shell=bash --severity=error --include=SC2314 tests/*.bats reports nothing.
  • bats tests/postfix-local.bats green, 7 tests, with the inert assertion live. No assertion changed its verdict.
  • tests/coverage.sh: postfix-local: 100.00 percent (17 of 17 lines) covered, threshold 100. Unchanged.
  • Tests and COVERAGE.md ship nothing, so package / changelog passes by reporting that nothing that ships changed. No changelog entry and no version bump.

`! cmd` on its own line asserts nothing in a bats body unless it happens to
be the last command of that body: bash does not apply errexit to a negated
command, so the verdict is the exit status of the final command and every
earlier `! cmd` is inert. shellcheck names the class SC2314 and grades the
two cases apart, error for the inert ones and note for the rest:

    shellcheck -f gcc --shell=bash tests/*.bats | grep SC2314

`tests/postfix-local.bats` has three bare negations. One is inert, line 96,
`! logged smtpd_banner` in "stops at the first failing postconf": that test
would pass on a script that carried on past the failing postconf and wrote
the banner anyway. The other two, lines 66 and 97, are last in their bodies
and do assert.

All three become `run !`, the form that asserts wherever it stands,
including the two that already did: a line whose meaning depends on its
position is the trap itself. That form needs bats 1.5.0, declared at the top
of the file as the other suites in the organization declare it.

No assertion changed its verdict; the suite is green with the inert one
live. Coverage unchanged: postfix-local 100.00 percent, 17 of 17 lines,
threshold 100.

COVERAGE.md records the rule, and corrects a statement made on
fix/keel-apt-identity that all three negations were inert.
@marcos-mendez

marcos-mendez commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Reviewed: the three refutations go red when postfix-local is made to carry on past the failing postconf, and each fails with status 1. Merged 19.x (#8 landed) and folded its paragraph on bare negations in COVERAGE.md into this one, so the file says it once (f858258).

navigator added 2 commits September 29, 2026 03:55
#8 landed on 19.x with its own paragraph on bare negations, which said the
inert one in tests/postfix-local.bats was left for the pull request that owns
that file. This is that pull request, and the merge kept both paragraphs.
The first one now ends with what this branch did, and the second is gone.
@marcos-mendez
marcos-mendez merged commit 7b72420 into 19.x Sep 29, 2026
1 check passed
marcos-mendez added a commit that referenced this pull request Sep 29, 2026
…ning

19.x gained #8 and #10, and tests/coverage.sh in #8's shape: one kcov run
per measured file, each with the suite that exercises it. This branch had
rewritten it into one run over a list; its files move into #8's shape as
targets (samba-rootpass, rootpass, webmin-enable, webmin-pam, each with its
own suite, all at 100), and the two suites that measure no file of their
own, before-firstboot.bats and pam-unix.bats, run after the loop so they
still gate. The changelog keeps both sides' entries; COVERAGE.md keeps this
branch's section under 19.x's baseline heading.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfWQScmDZ94KCS5DMYrfe6
marcos-mendez added a commit that referenced this pull request Sep 29, 2026
A negated command only asserts in final position
marcos-mendez added a commit that referenced this pull request Sep 29, 2026
…ning

19.x gained #8 and #10, and tests/coverage.sh in #8's shape: one kcov run
per measured file, each with the suite that exercises it. This branch had
rewritten it into one run over a list; its files move into #8's shape as
targets (samba-rootpass, rootpass, webmin-enable, webmin-pam, each with its
own suite, all at 100), and the two suites that measure no file of their
own, before-firstboot.bats and pam-unix.bats, run after the loop so they
still gate. The changelog keeps both sides' entries; COVERAGE.md keeps this
branch's section under 19.x's baseline heading.
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.

A negation in tests/postfix-local.bats asserts nothing, and COVERAGE.md is wrong about which ones do

1 participant