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
382 changes: 371 additions & 11 deletions test/check_ledger.tsv

Large diffs are not rendered by default.

187 changes: 185 additions & 2 deletions test/check_ledger_budget.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#
# Adding a check to a suite that is already covered does not move it, which is
# what makes it safe to bound.
suites_not_covered 102
suites_not_covered 93
#
# checks_never_observed_red -- A CENSUS. NOT a ceiling, and it must not become
# one.
Expand Down Expand Up @@ -5439,4 +5439,187 @@ suites_not_covered 102
# never 3883 + 1 = 3884
# dated 2282 + 4 = 2286
# 3884 + 2286 == 6170
checks_never_observed_red 3884
# #1341, iceberg_dv seeded, with its twin (OffgridwithJD): 3884 -> 3885, and
# suites_not_covered 102 -> 101. The suite had no rows. It enters with 26 checks from
# five-major runs (all green on each of 15-19, shell and twin alike), after two fixes.
# "a manifest/footer offset mismatch is refused (XX001)" read the SQLSTATE alone, and
# several guards here raise XX001: with the offset match removed a later XX001 refused
# the same file, and main's shell passed 26/26. Every refusal now reads its own guard's
# message. And the three "backend still up" checks read SELECT 1, which answers again
# after crash recovery: with the referenced_data_file check removed a backend died on
# the arm, and main passed the survival check. They now also read the server log's
# count of killed backends, and each refusal waits for the server first, so a crash
# reddens its own arm and its section's survival check and nothing else. 25 are dated by
# seventeen mutations, each reddening the same names in both twins. 1 arrives never:
# the survival check after the DV applications, which no mutation crashed.
#
# ledger rows 6170 + 26 = 6196
# never 3884 + 1 = 3885
# dated 2286 + 25 = 2311
# 3885 + 2311 == 6196
#
# #1341, logical_decoding_source seeded, with its twin (OffgridwithJD): 3885 -> 3897,
# and suites_not_covered 101 -> 100. The suite had no rows. It enters with its 12
# checks, all green on each of 15-19 in shell and twin alike. The missing-plugin name
# pgc_skip records is now a literal both twins share, but it is a skip, not a check, so
# it has no row: CI has test_decoding and never emits it. After one fix.
# The second slot had no heap control: created after the 5000-row insert, it decoded
# nothing, and "it too emits no decodable change" and "100x the rows does not give 100x
# the internal records" (0 < anything) both passed, 11/11 on main. A heap table now writes
# through that slot in the same window and must decode its 5000 inserts, and the ratio
# check refuses a slot that carried no internal records. Under that harness mutation both
# are red in both twins. No source mutation reddens a check: the claim is that pgcolumnar
# writes nothing logical decoding can read, and a default chunk group of 100 rows still
# keeps the internal records following groups (114 for 50 groups, under the 10x bound).
# 0 are dated. 12 arrive never.
#
# ledger rows 6196 + 12 = 6208
# never 3885 + 12 = 3897
# dated 2311 + 0 = 2311
# 3897 + 2311 == 6208
#
# #1341, iceberg_deletes seeded, with its twin (OffgridwithJD): 3897 -> 3903, and
# suites_not_covered 100 -> 99. The suite had no rows. It enters with 49 checks from
# five-major runs (all green on each of 15-19, shell and twin alike), after one fix.
# The six "backend still up" checks read SELECT 1, which answers again after crash
# recovery: with abort() in place of the null-pos refusal, or the partition spec's
# fields guard removed (a segfault), main's shell passed the survival check once
# recovery had finished. They now also read the server log's count of killed
# backends, and every reading waits for the server first, so a crash reddens its own
# arm and its section's survival check, not the two arms after it. Every refusal now
# also reads its own guard's message (XX001 and 22023 are shared), and the oracle
# comparisons refuse an empty side. 43 are dated by twenty-three mutations, each reddening
# the same names in both twins. The equal-sequence equality check is dated only by
# relaxing both of its layered guards: the per-file strict < alone passed, because the
# pre-skip at the oldest data file's sequence number already drops that delete.
# 6 arrive never.
#
# ledger rows 6208 + 49 = 6257
# never 3897 + 6 = 3903
# dated 2311 + 43 = 2354
# 3903 + 2354 == 6257
#
# #1341, logical_subscriber seeded, with its twin (OffgridwithJD): 3903 -> 3907,
# and suites_not_covered 99 -> 98. The suite had no rows. It enters with 20 checks
# from five-major runs (all green on each of 15-19, shell and twin alike), after four fixes.
# With the insert-only subscription disabled before its UPDATE, main's shell passed 20/20:
# "skipped by design" and "no apply errors" read after a fixed sleep, and nothing applied
# is nothing applied wrongly. An INSERT after the UPDATE must now arrive first. With no
# UPDATE sent, "does NOT say only 'row locking'" and "the wedge is real" passed; the first
# now needs the replication error in the log, the second reads publisher -> subscriber.
# With the lock statements failing on a missing table, the three "is not told about
# replication" checks passed; they now need the generic error first. And the second
# subscription's sync check lost its premise prefix: COPY failing in a logical worker
# reddens it. The lock loop is unrolled so the twin grader reads each name.
# 16 are dated by five mutations, each reddening the same names in both twins. 4
# arrive never.
#
# ledger rows 6257 + 20 = 6277
# never 3903 + 4 = 3907
# dated 2354 + 16 = 2370
# 3907 + 2370 == 6277
#
# #1341, logical_decoding_cdc_recipe seeded, with its twin (OffgridwithJD): 3907 -> 3936,
# and suites_not_covered 98 -> 97. The suite had no rows. It enters with its 36 checks from five-major
# runs (all green on each of 15-19, shell and twin alike), after two fixes. The
# missing-plugin name pgc_skip records is a skip, not a check, so it has no row: CI has
# test_decoding and never emits it. The rollback arm read the capture count
# and the row after ROLLBACK only, so a rolled-back INSERT that never ran passed both arms:
# with it made a duplicate key, main passed 35/35. A reading inside the transaction, before
# the rollback, now requires the row captured and present. And "it saw the same values the
# table holds" compared two readings with check, so with the server gone "" = "" passed; it
# is check_text. The recipe-contains premises are unrolled into literal names. Three
# table-AM mutations and two mutations of the guide's own recipe date checks, each red by the
# same names in both twins. 7 are dated. 29 arrive never.
#
# ledger rows 6277 + 36 = 6313
# never 3907 + 29 = 3936
# dated 2370 + 7 = 2377
# 3936 + 2377 == 6313
#
# #1341, iceberg_rest seeded, with its twin (OffgridwithJD): 3936 -> 3938, and
# suites_not_covered 97 -> 96. The suite had no rows. It enters with 14 checks from
# five-major runs (all green on each of 15-19, shell and twin alike), after two fixes.
# The 42501 arms read the SQLSTATE alone, and two guards raise 42501: with the allow-list
# refusing everything and the link-local refusal gone, "a link-local catalog host is
# refused" passed on the allow-list's 42501, and with every address read as link-local
# and the allow-list gone, "a catalog endpoint off the allow-list is refused" passed on
# the link-local guard's. Every refusal now reads its own guard's message. And "backend
# still up after the REST refusals" read SELECT 1, which answers again after crash
# recovery: with the backend aborting on the catalog's 404, main passed it. It now also
# reads the server log's count of killed backends. 12 are dated by eleven mutations,
# each reddening the same names in both twins. 2 arrive never: the two premises.
#
# ledger rows 6313 + 14 = 6327
# never 3936 + 2 = 3938
# dated 2377 + 12 = 2389
# 3938 + 2389 == 6327
#
# #1341, iceberg_rest_scan seeded, with its twin (OffgridwithJD): 3938 -> 3939, and
# suites_not_covered 96 -> 95. The suite had no rows. It enters with 9 checks from
# five-major runs (all green on each of 15-19, shell and twin alike), after one fix.
# "backend still up after the REST read" read SELECT 1, which answers again after crash
# recovery: with the backend aborting on the catalog's 404 and the probe 3s later, main
# passed it. It now also reads the server log's count of killed backends, and the
# not-found arm reads the catalog's own 404 message. 8 are dated by five mutations,
# each reddening the same names in both twins. 1 arrives never: the premise.
#
# ledger rows 6327 + 9 = 6336
# never 3938 + 1 = 3939
# dated 2389 + 8 = 2397
# 3939 + 2397 == 6336
#
# #1341, iceberg_rest_vended seeded, with its twin (OffgridwithJD): 3939 -> 3943, and
# suites_not_covered 95 -> 94. The suite had no rows. It enters with 10 checks from
# five-major runs (all green on each of 15-19, shell and twin alike), after three fixes.
# The longest-prefix arm passed with the storage-credentials array never read: the
# catalog's flat config carried the same right credentials, so the fixture's flat config
# is now wrong too. The wrong-secret arm read 28000 alone, which "no credentials" also
# raises: with vended credentials never built, it passed; it now needs the 403 message.
# The survival check read SELECT 1: with abort() in place of the 403 refusal it passed;
# it now also reads the server log's count of killed backends. 6 are dated by six
# mutations, each reddening the same names in both twins. 4 arrive never.
#
# ledger rows 6336 + 10 = 6346
# never 3939 + 4 = 3943
# dated 2397 + 6 = 2403
# 3943 + 2403 == 6346
#
# #1341, iceberg_rest_server's twin (OffgridwithJD): 3943 -> 3933. The suite
# already had its 29 rows; none is added. Four fixes in the shell, mirrored in
# the twin. "backend still up" read SELECT 1: with the half-credential guard removed
# (the backend segfaults) or abort() in place of the 401 refusal, it passed; it now
# also reads the server log's count of killed backends, and every reading waits for
# the server first. The two "accepted" arms read an empty SQLSTATE, which a stopped
# server also gives, so with the server stopped both passed; a statement that ran now
# reads "ok". "refused by the allow-list (42501)" read the SQLSTATE alone, and the
# link-local guard raises 42501 too: with the allow-list removed it passed. Every
# refusal now needs its own message, and the half-credential arm also counts the
# fixture's requests. 10 more rows are dated by five mutations, each reddening the
# same names in both twins.
#
# ledger rows 6346 + 0 = 6346
# never 3943 - 10 = 3933
# dated 2403 + 10 = 2413
# 3933 + 2413 == 6346
#
# #1341, hilbert_curve seeded, with its twin (OffgridwithJD): 3933 -> 3949, and
# suites_not_covered 94 -> 93. The suite had no rows. It enters with its 184
# checks from five-major runs, 184/184 in the shell and in the twin on each of 15-19.
# Seventeen mutations of src/columnar_curve.c each reddened checks in the shell on
# main, and between them every arm but the six premises and the ten INSTRUMENT
# controls, which link nothing from src/ by design. Two shell changes. The battery
# now fills every key buffer with 0xa5 before the pack writes it: under a memset one
# byte short, which goldens went red depended on what the previous call had left in
# the buffer (121 red on main, against a stable 124), and the first use of a buffer
# read uninitialized memory. And the two list-taking helpers are written out as loops
# at their call sites, so compare_to_bash reads the suite instead of refusing it,
# which it did as the tree's one refused suite. The seventeen date 168 rows, each
# reddening the same names in the shell and the twin. 16 arrive never: the six
# premises and the ten controls.
#
# ledger rows 6346 + 184 = 6530
# never 3933 + 16 = 3949
# dated 2413 + 168 = 2581
# 3949 + 2581 == 6530
checks_never_observed_red 3949
80 changes: 48 additions & 32 deletions test/hilbert_curve.sh
Original file line number Diff line number Diff line change
Expand Up @@ -335,20 +335,13 @@ battery_arm_names() {
}
BATTERY_ARMS="$(battery_arm_names)"

# Report a whole group of arms in one state, so a run that could not build
# still lists what it did not measure.
arms_unrunnable() { # arms_unrunnable "LIST" REASON DETAIL
local _a
while IFS= read -r _a; do
[ -n "$_a" ] && check_unrunnable "$_a" "$2" "$3"
done <<< "$1"
}
arms_failed() { # arms_failed "LIST" DETAIL
local _a
while IFS= read -r _a; do
[ -n "$_a" ] && pgc_fail "$_a" "$2"
done <<< "$1"
}
# A run that could not build reports a whole group of arms in one state, so it
# still lists what it did not measure. The loops that do it are written out at each
# site rather than in a helper taking the list: a helper that reaches a recorder
# through a loop variable is a name slot compare_to_bash cannot resolve, and it
# refused this whole suite for that (#1341). At the top level the same loop is read
# as one unnamed call, which the grader drops, and the literal arms below are what
# it grades.

# A CC INHERITED FROM THE ENVIRONMENT IS NOT A COMPILER UNTIL IT COMPILES.
#
Expand Down Expand Up @@ -376,8 +369,9 @@ if [ "$cc_usable" != yes ]; then
sed 's/^/ /' "$WORK/smoke.log" 2>/dev/null
_why="CC=$CC cannot build C"
fi
arms_unrunnable "$CONTROL_ARMS" MISSING_DEPENDENCY "$_why"
arms_unrunnable "$BATTERY_ARMS" MISSING_DEPENDENCY "$_why"
while IFS= read -r _a; do
[ -n "$_a" ] && check_unrunnable "$_a" MISSING_DEPENDENCY "$_why"
done <<< "$CONTROL_ARMS"$'\n'"$BATTERY_ARMS"
pgc_summary
fi
echo "-- compiler: $CC ($("$CC" --version 2>/dev/null | head -1))"
Expand Down Expand Up @@ -1178,7 +1172,9 @@ if "$CC" -O2 -Wall -I"$WORK" -o "$WORK/controls" "$WORK/controls.c" >"$CTLLOG" 2
else
echo "---- the control program would not build or run ----"
sed 's/^/ /' "$CTLLOG"
arms_failed "$CONTROL_ARMS" "the control program would not build or run"
while IFS= read -r _a; do
[ -n "$_a" ] && pgc_fail "$_a" "the control program would not build or run"
done <<< "$CONTROL_ARMS"
fi
echo "-- instrument arms: $((PGC_CHECKS - _pre_checks)) reported" \
"($((PGC_PASSED - _pre_passed)) passed, $((PGC_FAILED - _pre_failed)) failed);" \
Expand Down Expand Up @@ -1214,6 +1210,22 @@ cat > "$WORK/battery.c" <<'CEOF'
static void (*const pin_transpose) (uint64 *, int) = cluster_hilbert_transpose;
static void (*const pin_pack) (const uint64 *, int, unsigned char *) = cluster_pack_interleave;

/*
* Every key buffer is filled with 0xa5 before the pack writes it. A byte the pack
* never establishes then reads 0xa5 -- the same in every run and in the pytest
* twin -- rather than whatever the previous key left there, or, on the first use of
* a buffer, uninitialized memory. Measured: under a pack whose memset stops one
* byte short, which goldens went red depended on what the previous call had left
* in that byte. The C5 extent arms below fill their own buffers with 0x00 and 0xff
* on purpose and call the pack directly; nothing else does.
*/
static void
pk(const uint64 *ord, int ncols, unsigned char *out)
{
memset(out, 0xa5, (size_t) ncols * 8);
cluster_pack_interleave(ord, ncols, out);
}

/* Deterministic, so two runs of this suite compare the same points. */
static unsigned rs = 987654321u;
static unsigned
Expand Down Expand Up @@ -1332,7 +1344,7 @@ enc_hilbert(const unsigned *c, int ncols, int b, unsigned char *key)
for (j = 0; j < ncols; j++)
X[j] = (uint64) c[j] << (64 - b);
cluster_hilbert_transpose(X, ncols);
cluster_pack_interleave(X, ncols, key);
pk(X, ncols, key);
}

int
Expand Down Expand Up @@ -1431,9 +1443,9 @@ main(void)
Xf[j] = Xb[j] | (rnd64() & ((((uint64) 1) << (64 - b)) - 1));
}
cluster_hilbert_transpose(Xb, ncols);
cluster_pack_interleave(Xb, ncols, kb);
pk(Xb, ncols, kb);
cluster_hilbert_transpose(Xf, ncols);
cluster_pack_interleave(Xf, ncols, kf);
pk(Xf, ncols, kf);
points += 1;
ixf = pgc_key_index(kf, ncols, b);
if (pgc_key_index(kb, ncols, b) != ixf)
Expand Down Expand Up @@ -1494,7 +1506,7 @@ main(void)
untranspose(A0, ncols, 0);
memcpy(B, A0, sizeof(uint64) * ncols);
cluster_hilbert_transpose(B, ncols);
cluster_pack_interleave(B, ncols, kk);
pk(B, ncols, kk);
trips++;
ok0 = (memcmp(kk, key, (size_t) ncols * 8) == 0);
if (!ok0)
Expand All @@ -1505,7 +1517,7 @@ main(void)
untranspose(A1, ncols, 1);
memcpy(B, A1, sizeof(uint64) * ncols);
cluster_hilbert_transpose(B, ncols);
cluster_pack_interleave(B, ncols, kk);
pk(B, ncols, kk);
if (memcmp(kk, key, (size_t) ncols * 8) != 0)
mutbad++;

Expand Down Expand Up @@ -1547,7 +1559,7 @@ main(void)
*/
memcpy(B, A1, sizeof(uint64) * ncols);
cluster_hilbert_transpose(B, ncols);
cluster_pack_interleave(B, ncols, kk);
pk(B, ncols, kk);
ok1 = (memcmp(kk, key2, (size_t) ncols * 8) == 0);

adj++;
Expand Down Expand Up @@ -1599,7 +1611,7 @@ main(void)
pgc_makevec(k, ncols, X);
memcpy(Y, X, sizeof(uint64) * ncols);
cluster_hilbert_transpose(Y, ncols);
cluster_pack_interleave(Y, ncols, key);
pk(Y, ncols, key);
pgc_hex(key, ncols * 8, h);
printf("golden_n%d_%s=%s\n", ncols, pgc_vecname[k], h);
}
Expand All @@ -1609,12 +1621,12 @@ main(void)

v[0] = (uint64) 1 << 63;
v[1] = 0;
cluster_pack_interleave(v, 2, key);
pk(v, 2, key);
pgc_hex(key, 16, h);
printf("packpin_hi=%s\n", h);
v[0] = 0;
v[1] = (uint64) 1 << 63;
cluster_pack_interleave(v, 2, key);
pk(v, 2, key);
pgc_hex(key, 16, h);
printf("packpin_lo=%s\n", h);
}
Expand Down Expand Up @@ -1703,7 +1715,7 @@ main(void)
{
X[0] = vals[k];
cluster_hilbert_transpose(X, 1);
cluster_pack_interleave(X, 1, key);
pk(X, 1, key);
pgc_hex(key, 8, h);
printf("ident_n1_%s=%s\n", nm[k], h);
}
Expand All @@ -1728,9 +1740,9 @@ main(void)

X[0] = x;
cluster_hilbert_transpose(X, 1);
cluster_pack_interleave(X, 1, kh);
pk(X, 1, kh);
Y[0] = x;
cluster_pack_interleave(Y, 1, kz);
pk(Y, 1, kz);
for (q = 0; q < 8; q++)
be[q] = (unsigned char) (x >> (56 - 8 * q));
n6++;
Expand All @@ -1749,7 +1761,7 @@ main(void)
for (k = 0; k < PGC_NVEC; k++)
{
pgc_makevec(k, ncols, X);
cluster_pack_interleave(X, ncols, key);
pk(X, ncols, key);
pgc_hex(key, ncols * 8, h);
printf("zorder_n%d_%s=%s\n", ncols, pgc_vecname[k], h);
}
Expand All @@ -1766,7 +1778,9 @@ if [ ! -f "$CURVE_C" ] || [ ! -f "$CURVE_H" ]; then
[ -f "$CURVE_C" ] || _missing="$_missing src/columnar_curve.c"
[ -f "$CURVE_H" ] || _missing="$_missing src/columnar_curve.h"
echo "-- the code under test is absent:$_missing"
arms_failed "$BATTERY_ARMS" "the code under test is absent:$_missing"
while IFS= read -r _a; do
[ -n "$_a" ] && pgc_fail "$_a" "the code under test is absent:$_missing"
done <<< "$BATTERY_ARMS"
else
cp "$CURVE_C" "$CURVE_H" "$WORK/"
if "$CC" -O2 -Wall -Werror=incompatible-pointer-types -I"$WORK" \
Expand All @@ -1777,7 +1791,9 @@ else
else
echo "---- the battery would not build or run against $CURVE_C ----"
sed 's/^/ /' "$BATLOG" | head -40
arms_failed "$BATTERY_ARMS" "the battery would not build or run; see the log above"
while IFS= read -r _a; do
[ -n "$_a" ] && pgc_fail "$_a" "the battery would not build or run; see the log above"
done <<< "$BATTERY_ARMS"
fi
fi

Expand Down
Loading
Loading