A bare ! in a bats body asserts nothing unless it is the last command: 57 dead assertions in 8 repositories #19
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Keel-Linux/tracker#19
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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
! cmdon its own line decides the test when it is the final command of the body and is inert everywhere else. The line looks like a refutation either way, and which one it is depends only on where it sits.Measured 2026-09-28 over every default branch in the organization that carries a bats file (19 of them):
57 inert negations in 8 repositories, beside 45 that are in final position and do assert. shellcheck grades the two apart,
error:for the inert ones andnote:for the rest, which is what makes the sweep exact.Clean, confirmed rather than assumed:
keel-postgresql,keel-transition,unit-mariadb,unit-postgresql,keel-core,keel,keel-redis,keel-lamp,keel-lapp,keel-apache-php,tkldev.keel-redisandkeel-lampwere already writtenrun !throughout, which is where the form comes from.The worst of them
inithookstests/test-ipconfig.bats, "ip6_syntax rejects what is not an IPv6 address": thirteen rejection cases, twelve inert, only the last deciding anything. An IPv6 validator's rejection set, in an IPv6-first distribution, in the repository whose hook writes the address.Closely followed by
keel-wordpress, where five of the six cases of "is_global_ipv6 refuses link local, loopback, multicast and IPv4" never ran, andunit-redis, where the refutation that the bind fragment never sayslocalhost— the one put there by thelocalhostentry indocs/traps.md— was itself inert.What was found by turning them on
Every predicate turned out to answer as its test believed, so nothing shipped broken. That is luck, not evidence.
One newly live assertion failed:
keel-nodebbtests/nodebb.bats, "proxy_conf without an address trusts nobody", asserted! grep -q set_real_ip_fromunanchored against a file whose own comment names the directive. It could never have passed, for any input, and nothing had ever run it. Anchored to^set_real_ip_from, which is the property meant.The fix and the gate
run ! cmd, withbats_require_minimum_version 1.5.0, which asserts wherever it stands. Every negation is converted, not only the inert ones: a file that mixes the two forms leaves a reader to work out which half is real.The gate is one step in
test-shell.ymlof the.githubrepository,Negations that assert (SC2314), rather than a copy in each repository: every repository with a bats suite already calls that workflow at@main, and "copying a test library instead of sharing it" is already indocs/traps.mdas a mistake this project made.Merge order matters. The
.githubpull request should merge last. It is@main, so the moment it lands every repository that still has an inert negation goes red.The pull requests
One per repository, each closing an issue in that repository. This issue is only the coordination.
The pull requests, one per repository, each closing an issue there.
docs/traps.mdentryKeel-Linux/.github#14 merges last. It is
@main, so the moment it lands every repository that still has an inert negation goes red.One newly live assertion failed, in keel-nodebb:
! grep -q set_real_ip_from, unanchored, against a file whose own comment names the directive. It could never have passed for any input. Anchored in Keel-Linux/keel-nodebb#16.Two gaps left open, neither in scope here:
keel-lampandkeel-lapphave bats suites and no workflows at all, so the gate will not reach them until they call it; andcommon'sCOVERAGE.mdsentence about these three negations also exists on the unmerged Keel-Linux/common#8, where it must be dropped on rebase.Fixed in the nine repositories (57 negations) and kept out by the gate in Keel-Linux/.github#14.