Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,54 @@ true until the next version shipped.
KNOWN LIMIT, stated because it changes what a green CI check means here: at depth
1 with no tags every section arm is skipped, so CI cannot run any of this. It
runs locally and in the five-major release gate, which is where a release is cut.
- Eleven timeout paths printed a FAIL that nothing recorded, and the accounting
balanced at the wrong number (#965).

`concurrency.sh`, `unique_conc.sh` and `update_conc.sh` bound every wait. On a
timeout each printed `FAIL timeout waiting for ...`, set the suite-local `fail`
and returned -- touching neither `PGC_CHECKS` nor the record stream. The suite
still exited 1, so this was never a false green. What it was is worse than a
missing number:

main, with a timeout induced rc=1, CONCURRENCY TEST FAILED
human FAIL lines 1
RESULT records with FAIL 0
RESULT records total 7
checks run: 7

Records and total agree, so nothing refuses the log -- on a run that printed a
FAIL and exited 1. A missing figure can be noticed; one that reconciles cannot.

Each path now records through `pgc_record`. The same induced timeout:

this change rc=1, CONCURRENCY TEST FAILED
RESULT records with FAIL 2
RESULT records total 9
checks run: 9

THE NAME IS FIXED PER WAIT KIND, with the session and sentinel in the REASON
field. The ledger is keyed on (suite, part, name), so interpolating
`"$name/$label"` would mint rows nobody can enumerate and therefore nobody can
seed. Four kinds: a command's sentinel, a standalone sentinel, a session
blocking, a session reaching idle-in-transaction.

It cannot be proved by running the suite green -- not one of these lines
executes on a green run, so every count is identical whether the conversion is
right, wrong or absent. Proved by lowering all four wait bounds from 1200 to 1
in a scratch tree, with the rewritten count asserted before the run, and with
unmodified `main` as the control. Green runs are unchanged: 7 records and
`checks run: 7` before and after.

- Every record these three suites emitted named `major=unknown` (#965).

`pgc_record` reads `${PGC_MAJOR:-unknown}`, and `PGC_MAJOR` is set by
`pgc_setup`, which these three do not call -- they carry their own harness.
Measured on a green run before the fix: 7 of 7 records said `unknown`. A ledger
row claiming to hold on `unknown` matches no run, so none of these checks could
ever have been seeded, which is part of why `suites_not_covered` has a floor
here. One line each, from the `PG_CONFIG` they already resolve. All records now
carry the real major: `concurrency` 7, `unique_conc` 31, `update_conc` 25, every
one of them `18` on PG18, each reconciling with its own `checks run:`.

- Four secret-leak claims over the PG server log could pass having read nothing
(#1032).
Expand Down
41 changes: 33 additions & 8 deletions test/concurrency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,39 @@
# assignments and function definitions only, so sourcing it starts nothing.
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"

# A TIMEOUT IS A CHECK RESULT (#965). These paths printed `FAIL timeout waiting
# for ...`, set the suite-local `fail` and returned -- touching neither PGC_CHECKS
# nor the record stream. A failing run then reconciled as `N passed + 0 failed =
# N`: an aggregate that BALANCES while asserting zero failures on a run that
# failed. That is worse than invisibility, because a missing number can be noticed
# and a balancing one cannot. Induced and measured rather than argued.
#
# THE NAME IS FIXED PER WAIT KIND, with the session and sentinel in pgc_record's
# REASON field. The ledger is keyed on (suite, part, name), so interpolating
# "$name/$label" into the name would mint rows nobody can enumerate and therefore
# nobody can seed.
#
# NO GREEN RUN EXECUTES THIS. It records only on the timeout path, so a passing
# suite emits nothing here and the record stream is unchanged.
wait_timeout() { # wait_timeout FIXED-NAME DETAIL
pgc_record FAIL "$1" "FAIL $1 (timed out waiting for $2)" "$2"
fail=1
}


set -uo pipefail

PG_CONFIG="${1:-/usr/local/pg17/bin/pg_config}"
BINDIR="$("$PG_CONFIG" --bindir)"

# EVERY RECORD THIS SUITE EMITS CARRIED `major=unknown` (#965). `pgc_record` reads
# `${PGC_MAJOR:-unknown}`, and PGC_MAJOR is set by `pgc_setup` -- which this suite
# does not call, because it carries its own harness. So all of its rows named a
# major that is not a major, and a ledger keyed on (suite, part, name, majors)
# cannot seed them: the row would claim to hold on "unknown" and match no run.
# Measured before the fix, on a green run: 7 of 7 records said `unknown`.
PGC_MAJOR="$(pgc_major_of "$PG_CONFIG")"

SRCDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

WORKDIR="$(mktemp -d /tmp/pgcolumnar-conc.XXXXXX)"
Expand Down Expand Up @@ -239,8 +268,7 @@ send_wait() { # name label sql...
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label"
fail=1
wait_timeout "a bounded wait for a command's sentinel completed" "$name/$label"
return 1
fi
done
Expand All @@ -254,8 +282,7 @@ wait_sentinel() { # name label
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label sentinel"
fail=1
wait_timeout "a bounded wait for a standalone sentinel completed" "$name/$label"
return 1
fi
done
Expand All @@ -270,8 +297,7 @@ wait_blocked() { # application_name
[ "$n" = "1" ] && return 0
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $app to block"
fail=1
wait_timeout "a bounded wait for a session to block completed" "$app"
return 1
fi
done
Expand All @@ -285,8 +311,7 @@ wait_idle_intx() { # application_name
[ "$st" = "idle in transaction" ] && return 0
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $app to go idle-in-transaction"
fail=1
wait_timeout "a bounded wait for a session to reach idle-in-transaction completed" "$app"
return 1
fi
done
Expand Down
37 changes: 33 additions & 4 deletions test/unique_conc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,39 @@
# assignments and function definitions only, so sourcing it starts nothing.
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"

# A TIMEOUT IS A CHECK RESULT (#965). These paths printed `FAIL timeout waiting
# for ...`, set the suite-local `fail` and returned -- touching neither PGC_CHECKS
# nor the record stream. A failing run then reconciled as `N passed + 0 failed =
# N`: an aggregate that BALANCES while asserting zero failures on a run that
# failed. That is worse than invisibility, because a missing number can be noticed
# and a balancing one cannot. Induced and measured rather than argued.
#
# THE NAME IS FIXED PER WAIT KIND, with the session and sentinel in pgc_record's
# REASON field. The ledger is keyed on (suite, part, name), so interpolating
# "$name/$label" into the name would mint rows nobody can enumerate and therefore
# nobody can seed.
#
# NO GREEN RUN EXECUTES THIS. It records only on the timeout path, so a passing
# suite emits nothing here and the record stream is unchanged.
wait_timeout() { # wait_timeout FIXED-NAME DETAIL
pgc_record FAIL "$1" "FAIL $1 (timed out waiting for $2)" "$2"
fail=1
}


set -uo pipefail

PG_CONFIG="${1:-/usr/local/pg17/bin/pg_config}"
BINDIR="$("$PG_CONFIG" --bindir)"

# EVERY RECORD THIS SUITE EMITS CARRIED `major=unknown` (#965). `pgc_record` reads
# `${PGC_MAJOR:-unknown}`, and PGC_MAJOR is set by `pgc_setup` -- which this suite
# does not call, because it carries its own harness. So all of its rows named a
# major that is not a major, and a ledger keyed on (suite, part, name, majors)
# cannot seed them: the row would claim to hold on "unknown" and match no run.
# Measured before the fix, on a green run: 7 of 7 records said `unknown`.
PGC_MAJOR="$(pgc_major_of "$PG_CONFIG")"

SRCDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PG_MAJOR="$("$PG_CONFIG" --version | sed -E 's/^[^0-9]*([0-9]+).*/\1/')"

Expand Down Expand Up @@ -215,7 +244,7 @@ send_wait() { # name label sql...
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label"; fail=1; return 1
wait_timeout "a bounded wait for a command's sentinel completed" "$name/$label"; return 1
fi
done
return 0
Expand All @@ -226,7 +255,7 @@ wait_sentinel() { # name label
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label sentinel"; fail=1; return 1
wait_timeout "a bounded wait for a standalone sentinel completed" "$name/$label"; return 1
fi
done
return 0
Expand All @@ -238,7 +267,7 @@ wait_blocked() { # application_name
[ "$n" = "1" ] && return 0
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $app to block"; fail=1; return 1
wait_timeout "a bounded wait for a session to block completed" "$app"; return 1
fi
done
}
Expand All @@ -249,7 +278,7 @@ wait_idle_intx() { # application_name
[ "$st" = "idle in transaction" ] && return 0
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $app idle-in-transaction"; fail=1; return 1
wait_timeout "a bounded wait for a session to reach idle-in-transaction completed" "$app"; return 1
fi
done
}
Expand Down
35 changes: 32 additions & 3 deletions test/update_conc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,39 @@
# assignments and function definitions only, so sourcing it starts nothing.
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"

# A TIMEOUT IS A CHECK RESULT (#965). These paths printed `FAIL timeout waiting
# for ...`, set the suite-local `fail` and returned -- touching neither PGC_CHECKS
# nor the record stream. A failing run then reconciled as `N passed + 0 failed =
# N`: an aggregate that BALANCES while asserting zero failures on a run that
# failed. That is worse than invisibility, because a missing number can be noticed
# and a balancing one cannot. Induced and measured rather than argued.
#
# THE NAME IS FIXED PER WAIT KIND, with the session and sentinel in pgc_record's
# REASON field. The ledger is keyed on (suite, part, name), so interpolating
# "$name/$label" into the name would mint rows nobody can enumerate and therefore
# nobody can seed.
#
# NO GREEN RUN EXECUTES THIS. It records only on the timeout path, so a passing
# suite emits nothing here and the record stream is unchanged.
wait_timeout() { # wait_timeout FIXED-NAME DETAIL
pgc_record FAIL "$1" "FAIL $1 (timed out waiting for $2)" "$2"
fail=1
}


set -uo pipefail

PG_CONFIG="${1:-/usr/local/pg17/bin/pg_config}"
BINDIR="$("$PG_CONFIG" --bindir)"

# EVERY RECORD THIS SUITE EMITS CARRIED `major=unknown` (#965). `pgc_record` reads
# `${PGC_MAJOR:-unknown}`, and PGC_MAJOR is set by `pgc_setup` -- which this suite
# does not call, because it carries its own harness. So all of its rows named a
# major that is not a major, and a ledger keyed on (suite, part, name, majors)
# cannot seed them: the row would claim to hold on "unknown" and match no run.
# Measured before the fix, on a green run: 7 of 7 records said `unknown`.
PGC_MAJOR="$(pgc_major_of "$PG_CONFIG")"

SRCDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

WORKDIR="$(mktemp -d /tmp/pgcolumnar-upconc.XXXXXX)"
Expand Down Expand Up @@ -213,7 +242,7 @@ send_wait() { # name label sql...
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label"; fail=1; return 1
wait_timeout "a bounded wait for a command's sentinel completed" "$name/$label"; return 1
fi
done
return 0
Expand All @@ -224,7 +253,7 @@ wait_sentinel() { # name label
while ! grep -q "<<$label>>" "$outfile" 2>/dev/null; do
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $name/$label sentinel"; fail=1; return 1
wait_timeout "a bounded wait for a standalone sentinel completed" "$name/$label"; return 1
fi
done
return 0
Expand All @@ -236,7 +265,7 @@ wait_blocked() { # application_name
[ "$n" = "1" ] && return 0
sleep 0.05; i=$((i + 1))
if [ "$i" -ge 1200 ]; then
echo "FAIL timeout waiting for $app to block"; fail=1; return 1
wait_timeout "a bounded wait for a session to block completed" "$app"; return 1
fi
done
}
Expand Down
Loading