Skip to content

A negated command only asserts in final position - #5

Merged
marcos-mendez merged 1 commit into
mainfrom
test/negations-that-assert
Sep 29, 2026
Merged

marcos-mendez merged 1 commit into
mainfrom
test/negations-that-assert

Conversation

@marcos-mendez

Copy link
Copy Markdown
Contributor

Every negation in these suites now asserts wherever it stands. Four did not assert at all, and they were the refutations this component exists to make.

Closes #4. 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

Where Was not asserting
conf.bats 253 that the bind fragment never says localhost. That is the exact line docs/traps.md records the PostgreSQL appliance getting wrong — "On Debian, localhost is not an IPv6 name" — and the test written to stop it happening again did not run.
conf.bats 263, 264 that the acl fragment declares no admin user and no requirepass. Those two are what make the duplicate user declaration impossible and keep the password off the disk at build time, which is the other docs/traps.md entry. Only the third refusal, +@all, ran.
unit.bats 77 that no requirepass line is anywhere in the shipped overlay. The comment above it calls this "the one property the whole design rests on".

Two traps had a test each, and in both cases the test was inert. That is the shape of this defect: the refutation is the part a reader trusts most and the part the shell runs least.

All four become run !, together with the six that were in final position and did assert: a line whose meaning depends on its position is the trap itself. tests/unit.bats gains the bats_require_minimum_version 1.5.0 declaration the other two files already had.

What was found

Nothing broken. Both fragments were rendered and read directly before the conversion: the bind fragment is bind ::1 127.0.0.1 and names no host, the acl fragment declares user default on nopass +info and nothing else, and the overlay carries no requirepass and no masterauth. The assertions were dead, not wrong.

Test plan

  • Both rendered fragments and the shipped overlay read directly, before the conversion.

  • shellcheck -f gcc --shell=bash --severity=error --include=SC2314 tests/*.bats reports nothing.

  • Every converted site audited for run clobbering $output/$status/$lines; none here does.

  • bats tests/*.bats green, 70 tests. No assertion changed its verdict.

  • tests/coverage.sh: 100.00 percent, threshold 100. Unchanged.

    100.00  31/31  35redispass
    100.00  56/56  redis.sh
    
  • Tests ship nothing, so 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.

Four negations here were inert, and they are the refutations this component
exists to make:

- conf.bats, the bind fragment: that it never says `localhost`. That is the
  exact line docs/traps.md records the PostgreSQL appliance getting wrong,
  and the test that was put there to stop it happening again did not run.
- conf.bats, the acl fragment: that it declares no `admin` user and no
  `requirepass`. Those two are what make the duplicate user declaration
  impossible and keep the password off the disk at build time; only the
  third refusal, `+@all`, ran.
- unit.bats, the shipped tree: that no `requirepass` line is anywhere in the
  overlay. The comment above it calls this "the one property the whole design
  rests on".

All of them become `run !`, together with the six that were in final position
and did assert, because a line whose meaning depends on its position is the
trap itself.

No assertion changed its verdict: the fragments and the overlay are as the
tests believed. Suite green, 70 tests. Coverage unchanged at 100.00 percent,
35redispass 31 of 31 lines and redis.sh 56 of 56, threshold 100.
@marcos-mendez

Copy link
Copy Markdown
Contributor Author

Reviewed: every converted refutation goes red when its property is broken; adding bind localhost to the bind fragment turns this branch red and leaves main green. Each fails with status 1. No changes needed.

@marcos-mendez
marcos-mendez merged commit 5a717d6 into main Sep 29, 2026
2 checks passed
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.

Four negations assert nothing, including the one guarding the localhost trap

1 participant