clawhdf5: storage harness compares errors, not just failures

The facade equivalence harness turned every data-read error into "Err", so
it could not see File::open_storage failing differently from File::open
(a Storage or ContiguousStorageRequired error where the mmap path gives a
decode error, say).

- value() keeps the whole error. The only allowance is for a line on which
  File::open itself varies between opens — the chunk cache lists a damaged
  dataset's chunks in hash-map order, so which failing chunk a full read
  reports varies (cve-2025-2310.h5, the one corpus file where this shows):
  both sides must fail there, and a fresh File::open (up to 64) must
  reproduce the storage's exact error. Open errors were already compared
  in full; they still agree.
- The storage transcript may not contain ContiguousStorageRequired.
- More selections: a strided hyperslab (every third row) through
  read_f64_selection, and out-of-order points through read_selection and
  read_i64_selection.
- harness_compares_errors_not_just_failures checks the harness itself:
  two different errors are different values, and a difference File::open
  does not produce is reported.

With full errors the harness passes on the 61 fixtures and on the corpus
(701 files, 621 open).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 19:04:56 -05:00
co-authored by Claude Opus 5.5
parent 6185874f9c
commit 75444950f3
2 changed files with 126 additions and 20 deletions
+9 -1
View File
@@ -98,7 +98,15 @@
that open) through `File::open` and through `File::open_storage` over
`CountingStorage`: the tree, every attribute (all, and each by name),
every dataset's shape, types and values (all bytes, `f64`, `f32`,
`i64`, a hyperslab, strings, VL sequences) must be identical, and are.
`i64`, a box hyperslab, a strided one, out-of-order points, strings, VL
sequences) must be identical, and are — errors included, in full (open
errors and every read's). The one allowance is a line on which
`File::open` itself varies between two opens (the chunk cache lists a
damaged dataset's chunks in hash-map order, so which failing chunk a
full read reports varies: `cve-2025-2310.h5`), and then only if a fresh
`File::open` reproduces the storage's error. No storage read may answer
`ContiguousStorageRequired`. A storage that returns more bytes than
asked reads every fixture identically too.
It also counts what one pass — open, list, read every attribute and
every dataset once — asks of a storage with no cache: 176 092 `read_at`
calls and 208 MB for the 621 corpus files (254 MB of files); the most