Let make results seed a new test's first expected output - #121
Open
jnasbyupgrade wants to merge 3 commits into
Open
jnasbyupgrade wants to merge 3 commits into
jnasbyupgrade wants to merge 3 commits into
Conversation
`verify-results` blocked `make results` whenever `regression.diffs` existed at all. A test with no expected output file always lands in `regression.diffs` -- `base.mk` touches an empty `test/expected/<name>.out` for it, because `pg_regress` aborts outright on a missing one -- so seeding that first expected file was structurally impossible no matter how clean the new test's actual output was. `verify-results` now classifies each `regression.diffs` block by its hunk headers: a block whose hunks all read `@@ -0,0 +N,M @@` was diffed against that empty placeholder and is let through; anything else still blocks. A test whose output matched any expected file, `_N.out` alternates included, never appears in `regression.diffs` at all, so nothing here re-derives a pass/fail `pg_regress` already decided. One case is still blocked: an as-yet-unblessed file containing a SQL error. `ON_ERROR_STOP` aborts the script before pgtap emits `not ok` or its plan-mismatch line, so the scan above cannot see it, and blessing it would make the error the new baseline. Fixes Postgres-Extensions#119 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`print (cond ? a : b) "\t" c` sits next to awk's grouped-argument-list syntax; assigning the branch to a local first is unambiguous in every awk and reads better regardless. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An empty `regression.diffs` was treated as nothing to check. pg_regress writes the file at startup and only removes it again on the clean exit path, so every bail leaves a zero-byte one behind -- and `base.mk`'s `.IGNORE: installcheck` means `make results` still gets here. With `test/results/` holding an earlier run's output, that blessed stale results whenever pg_regress died before comparing anything. It is now a refusal of its own, with a message saying why rather than reporting failing tests it never saw. Unrecognized text was only caught when it was the *whole* file, so junk following an otherwise-blessable block was ignored. Any line fitting neither a header nor a diff body line now blocks the whole file. The SQL-error guard matched `ERROR:` anywhere, which blocked a passing test whose pgtap description merely quotes an error message. psql writes two spaces after the severity and puts it at the start of a line, or after a `psql:<file>:<line>: ` prefix when the statement came from an \i'd file -- matching that shape keeps both real renderings blocked without the false positive. Anchoring to the line start alone would have missed the prefixed form, which is what pgxntool's own setup.sql and finish.sql produce. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
verify-resultsblockedmake resultswheneverregression.diffsexisted at all, which made seeding the firsttest/expected/<name>.outfor a brand-new test structurally impossible.base.mktouches an empty expected file for anytest/sql/*.sqlthat lacks one (pg_regressaborts outright on a missing expected file), sopg_regressalways reports a difference against that placeholder — no matter how clean the new test's actual output is. Rerunning never helps; it is not a transient failure.verify-resultsnow classifies eachregression.diffsblock by its hunk headers: a block whose hunks all read@@ -0,0 +N,M @@was diffed against an empty expected file and is let through, and anything else still blocksmake resultsexactly as before.Also documents the behavior in
README.asc(and fixes a staletest/results/regression.diffspath in that same passage — the file is attest/regression.diffs), adds aHISTORY.ascentry, and appends #119 to the release's fixed-issues line.Fixes #119
Companion pgxntool-test PR: Postgres-Extensions/pgxntool-test#85
Behavior change worth calling out: an empty
regression.diffsis now its own refusalpg_regresstruncatesregression.diffsat startup and deletes it again only on the clean exit path when it has nothing to report, so every bail leaves a zero-byte file behind — unreachable server, interrupt,could not open file. Combined withbase.mk's.IGNORE: installcheck,make resultsreachesverify-resultsanyway, withtest/results/still holding whatever an earlier run left there.Blocking on the file's mere existence used to cover that case as a side effect. Classifying its contents does not, so it is now checked explicitly and reported as what it is:
Net effect versus before this PR: unchanged (still refuses), with a message that names the real cause instead of reporting failing tests it never saw.
Why this can't false-positive on alternate expected files
results_differ()inpg_regress.creturns early the moment any expected file matches — the default one or an_N.outalternate — and only appends a block toregression.diffswhen none matched. Verified empirically: withtest/expected/newtest_1.outmatching actual output andtest/expected/newtest.outstill the empty placeholder,pg_regressreportsok 3 - newtestand writes noregression.diffsat all. So a test that passed via an alternate never reaches this code, and nothing here re-derives a pass/failpg_regressalready decided.Classification keys on
^diffand^@@lines rather than the---/+++pair, because every content line in a unified diff carries a' '/'+'/'-'prefix but a deleted-- commentline renders as--- comment, which is indistinguishable from a from-file header. Anything matching neither a header nor a diff body line (' ','+','-','\', or empty) blocks the whole file rather than being skipped — so junk after an otherwise-blessable block can't slip through.\ No newline at end of fileis diff syntax, not junk, and is covered by a test.Empirical evidence
Real
regression.diffsfrom a template extension with a newtest/sql/newtest.sql(all pgtap assertions passing) and notest/expected/newtest.out, trimmed:Before:
make resultsrefused with "Tests are failing." After: it succeeds, printsNOTE: these tests have no expected output yet; 'make results' will create it:and seedstest/expected/newtest.out; the followingmake testpasses. Corrupting that now-real baseline makesmake resultsblock again.One case that is still blocked, and how it's matched
An as-yet-unblessed file whose output contains a SQL error.
ON_ERROR_STOPaborts the script at the error, so pgtap emits neithernot oknor its plan-mismatch line and the pgtap scan above sees nothing wrong — but blessing it would make the error the new baseline.The match has to fit psql's two real renderings, which were captured rather than assumed.
pg_regressfeeds psql on stdin (psql -X -a -q -d "%s" %s < "%s" > "%s" 2>&1,pg_regress_main.c), so a failing statement in the test file itself reports at column 0:while one inside an
\i'd file — which every pgxntool test has, viasetup.sql/finish.sql— carries a prefix:A column-anchored match would sail straight past the second. The guard is
grep -qE '(^|: )ERROR: ': either position, and psql's own two spaces after the severity (hardcoded in libpq's message formatting, and identical at default andverboseverbosity — both checked). That keeps a passing test whose pgtap description merely quotes an error message out of it, which an unanchored match did not — end-to-end, a new test assertingok 1 - ERROR: this description mentions ERROR: on purposenow gets its first expected output created instead of being permanently refused.PGXNTOOL_ENABLE_VERIFY_RESULTS=noremains the escape hatch if a test legitimately needs error output blessed;README.ascnow says so at that bullet.Scope notes
-C3context diffs, which have no@@hunk headers at all (pretty_diff_opts, checked acrossREL_11_STABLE/REL_12_STABLE/HEAD — 12 was the first with-U3). Every block there lands in the blocked pile, i.e. exactly the refusalmake resultsgave before any of this existed. Noted in the script; the CI matrix is 12-18.[ -r "$file" ]fails and the block is blocked), it isn't a hole.Known related gap, deliberately not addressed here
base.mk's otherverify-resultsbranch —PGXNTOOL_VERIFY_RESULTS_MODE=diffs, not the default — has the same class of bug: it fails unconditionally on anyregression.diffs, with nonot okscan at all, so it cannot seed a new test's first expected output either. Issue #119 is scoped toverify-results-pgtap.sh, so that branch is left alone;README.ascnow says so explicitly.Test plan
test/standard/verify-results-pgtap-script.bats(16 tests, no Make/PostgreSQL) plus an end-to-endmake resultstest inmake-test.bats.regression.diffsand junk-after-a-block fixtures exit 0 before (fail-open) and 1 after; theERROR:-in-a-description fixture exits 1 before (false positive) and 0 after.test-allagainst this branch with pgxntool PR Gate the main test suite on test-build; add build-results; require ON_ERROR_STOP in test/install #109 merged in locally: 273/273 pass, 0 skipped.masteralready carries check-stale-expected's installcheck dependency can run installcheck before install on a fresh tree #79's tests for PR Gate the main test suite on test-build; add build-results; require ON_ERROR_STOP in test/install #109, which is still open, so 14 tests fail against pgxntoolmasterregardless of this PR (the same 14 locally and on CI). It can't go green until Gate the main test suite on test-build; add build-results; require ON_ERROR_STOP in test/install #109 lands.