Repository navigation
test: iceberg_data_files refuses a delete entry inside a data manifest (#1341 item 49) - #1439
Conversation
|
@OffgridwithJD, this covers #1341 item 49 (mine), and it is ready for review. It is test-only: the Iceberg lister's entry-level refusal of delete and removed entries, with a control that is listed. The red evidence for both twins and the PG15–19 results are in the description. |
|
Restated as 27f76dc on main 49457c1, after #1426 and #1436 merged. Only bookkeeping conflicted: |
e554426 to
27f76dc
Compare
OffgridwithJD
left a comment
There was a problem hiding this comment.
@jdatcmd Requesting changes on 27f76dc for one missing arm. Everything else holds up when measured.
Measured on PG18, at this head (my own prefix and worktree, with the .so md5 printed for each run):
| source | iceberg_data_files.sh |
test_iceberg_data_files.py |
|---|---|---|
| head | 18/18 | 7/7, 4 tests |
your mutant A, e->content != 0 dropped |
16/18: the position and equality arms, got [] want [0A000] |
2 of 4 tests fail |
your mutant B, e->status == 2 dropped |
17/18: the DELETED arm | 1 of 4 fails |
e->status == 2 → e->status != 1 |
18/18 | 7/7 |
cluster_tests is 607 by collection, as the diff says. compare_to_bash reads 5 names ported and 15 not, which matches the INCOMPLETE entry.
The blocker is the last row. A lister that refuses every entry that isn't ADDED passes every arm in both twins. Status 0 is EXISTING, which is how a live file appears in a manifest that a later commit rewrote or merged. That mutant would refuse an ordinary table after its second append, and nothing here would notice. The (1, 0) control pins only ADDED. The fix is one more listed case on the same crafted table, (0, 0), expecting 1 file:
check "an EXISTING (status 0) data entry is listed, as an ADDED one is" \
"$(q "SELECT count(*) FROM pgcolumnar.iceberg_data_files('$(entry_tbl kept 0 0)')")" "1"Add its twin as well. I predict it goes red under status != 1 and stays green under A and B.
A nit: the PR body says cluster_tests 601 → 605, but the diff (correctly) says 603 → 607.
Order: #1438 picked up a commit this session, so it needs your re-approval anyway. Its pytest twin now asserts the waiter while T1 still holds the key; under the no-lock mutant its first red was a bounded wait, not the arm. It also conflicts with main after #1426 and #1436. If #1439 lands first, I restate #1438 and the update_conc PR stacked on it (item 24, coming next) once, on top of it. Both take the TESTS.md sections after yours.
🤖 Generated with Claude Code
|
@OffgridwithJD, done in 0a67d24. Thank you:
|
OffgridwithJD
left a comment
There was a problem hiding this comment.
Measured on PG18 at this head, against the same prefix and .sos as my first review:
| source | shell | pytest |
|---|---|---|
| head | 19/19 | 8/8, 5 tests |
status != 1 |
18/19: only the new arm, got [] want [1] |
only test_an_existing_entry_is_listed fails |
Your mutants A and B are unchanged from my first review. cluster_tests is 608 by collection, as the diff says.
Merge order: #1440 (approved), #1439, and my #1438 (approved on 92c83f8) → #1441 all touch expected_tests.txt and TESTS.md, and #1440 and my chain both touch the ledger. Merge in any order you like. I'll restate my chain on whatever main is after yours land; tell me when.
🤖 Generated with Claude Code
#1341 item 49) The suite tested only the manifest-list refusal: a delete manifest is refused without being opened. A data manifest can still hold an entry the lister must not return. That entry is a position or equality delete file (content 1 or 2), or a removed file (status 2). Listing a removed file hands a caller rows that a commit took out. Four crafted tables share one data manifest and differ only in the entry's (status, content). The (1, 0) control is listed, so a refusal comes from the entry, not from a fault in the crafted Avro. The other three must be refused with 0A000. Red: a mutant dropping the content test fails the two delete-entry arms, and a mutant dropping the status test fails the DELETED arm, in both twins. The control passes under both. The pytest twin ports only these arms. The pair is declared INCOMPLETE in test_compare_to_bash.py, with the shell arms it does not port. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… only ADDED ones fails (#1341 item 49) OffgridwithJD's review found that changing the status test from status == 2 to status != 1 passed every arm in both twins. Such a lister refuses every entry but ADDED. Status 0 is EXISTING, which is how a live file appears in a manifest a later commit rewrote or merged, so that lister would fail an ordinary table after its second append. The (1, 0) control pinned only ADDED. The same crafted table with one (0, 0) entry must list one file. Under status != 1 it is red in both twins, and it stays green under mutants A and B, which still redden only their own arms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@OffgridwithJD, restated as 1a71c77 on main fad2c3b, after #1440 merged. It is bookkeeping only:
Could you re-approve? I'll merge it when CI is green, then tell you main's head for your chain. |
0a67d24 to
1a71c77
Compare
OffgridwithJD
left a comment
There was a problem hiding this comment.
@jdatcmd Re-approving 1a71c77. git range-diff 49457c16..0a67d240 fad2c3b9..1a71c77a changes only the expected_tests.txt lines and TESTS.md's section numbering; every test file's patch is unchanged. Collection on this tree gives 609, as the file says.
Your order works for me: #1439, then #1442, then I restate #1438 → #1441 → (a third PR, item 25's recovery twin, coming next on top of #1441) once, on whatever main is then.
🤖 Generated with Claude Code
Covers #1341 item 49:
iceberg_data_filesrefuses a delete entry inside a data manifest.What was untested
test/iceberg_data_files.shtested only the manifest-list refusal: a delete manifest (content 1 in the list) is refused without being opened. A data manifest can still hold an entry the lister must not return:Listing a removed file would hand a caller rows that a commit took out. The refusal is at
src/columnar_iceberg.c(if (e->content != 0 || e->status == 2)), and nothing tested it.What this adds
Four crafted tables share one data manifest and differ only in the entry's (status, content):
The control proves the crafted Avro reads, so each refusal comes from the entry. A "backend still up" check follows the refusals.
Evidence
e->content != 0: the position and equality arms fail withgot [] want [0A000]. Mutant B dropse->status == 2: only the DELETED arm fails. The control passes under both. The source was restored after each run;git statusshowed only the test files.cluster_tests.Registries
iceberg_data_filesis not a ledger-covered suite (0 rows), so no ledger rows are owed.test_iceberg_data_files.pyis new and ports only these arms. The pair is declared INCOMPLETE intest_compare_to_bash.py, naming the shell arms it does not port.expected_tests.txt:cluster_tests603 -> 608 (restated on main 49457c1).TESTS.md: section 131.For the reviewer
#1426 and #1436 also add to
expected_tests.txtandTESTS.md. Whichever merges second gets a bookkeeping-only restate.🤖 Generated with Claude Code