Skip to content

geotiff: pin open_geotiff(max_cloud_bytes=...) dispatcher silent drop (#1974)#1977

Merged
brendancol merged 2 commits into
mainfrom
deep-sweep-test-coverage-geotiff-2026-05-15-1778875982
May 16, 2026
Merged

geotiff: pin open_geotiff(max_cloud_bytes=...) dispatcher silent drop (#1974)#1977
brendancol merged 2 commits into
mainfrom
deep-sweep-test-coverage-geotiff-2026-05-15-1778875982

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Test-coverage sweep pass 16 on the geotiff module. Closes a Cat 4 HIGH parameter-coverage gap on the open_geotiff dispatcher's max_cloud_bytes kwarg.

max_cloud_bytes was added in #1928 as an eager fsspec cloud-budget guard and re-ordered into the canonical reader signature by #1957. open_geotiff accepts the kwarg in its signature but only forwards it to _read_to_array on the eager non-VRT branch (xrspatial/geotiff/__init__.py:431). The GPU branch at line 410, the dask branch at line 422, and the VRT branch at line 362 never reference the kwarg, so:

open_geotiff(p, max_cloud_bytes=8, gpu=True)   # silently drops
open_geotiff(p, max_cloud_bytes=8, chunks=4)   # silently drops
open_geotiff(vrt, max_cloud_bytes=8)           # silently drops

Same class of dispatcher-silently-drops-backend-kwarg bug fixed by #1561, #1605, #1685, and #1810 for other backend-only kwargs. The two sibling kwargs on_gpu_failure (line 339) and missing_sources (line 355) already raise ValueError when used on a path where they do not apply.

Filed issue #1974 for the dispatcher fix. This sweep is test-only.

Tests

xrspatial/geotiff/tests/test_max_cloud_bytes_dispatcher_silent_drop_2026_05_15.py (11 tests, all behaving as designed locally):

  • 4 xfail(strict=True) pinning the fix surface (gpu, dask, vrt, dask+gpu). Flip to xpass (= test failure under strict=True) when the dispatcher fix lands.
  • 3 passing pins on the current silent-drop behaviour so the fix is visible as a diff.
  • 4 positive pins that the eager local + file-like paths accept the kwarg (the docstring no-op contract).

Test plan

  • All 11 tests pass / xfail as designed on the local host (pytest xrspatial/geotiff/tests/test_max_cloud_bytes_dispatcher_silent_drop_2026_05_15.py -v -> 7 passed, 4 xfailed).
  • CI to confirm parity (the dask+gpu xfail skips when cupy / CUDA is unavailable).

@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 15, 2026
@brendancol brendancol force-pushed the deep-sweep-test-coverage-geotiff-2026-05-15-1778875982 branch from 4250329 to 7eb1049 Compare May 16, 2026 01:03
…ispatcher silent drop (#1974)

Test-coverage sweep pass 16 (2026-05-15) on the geotiff module. Adds
xrspatial/geotiff/tests/test_max_cloud_bytes_dispatcher_silent_drop_2026_05_15.py
closing a Cat 4 HIGH parameter-coverage gap on the open_geotiff
dispatcher's max_cloud_bytes kwarg.

max_cloud_bytes was added in #1928 (eager fsspec budget) and
re-ordered into the canonical reader signature by #1957. open_geotiff
accepts the kwarg in its signature but only forwards it to
_read_to_array on the eager non-VRT branch
(xrspatial/geotiff/__init__.py:431). The GPU branch at line 410, the
dask branch at line 422, and the VRT branch at line 362 never
reference the kwarg, so open_geotiff(p, max_cloud_bytes=8, gpu=True),
open_geotiff(p, max_cloud_bytes=8, chunks=N), and open_geotiff(vrt,
max_cloud_bytes=8) all silently drop the budget. Same class of
dispatcher-silently-drops-backend-kwarg bug fixed by #1561, #1605,
#1685, and #1810 for other backend-only kwargs. The two sibling
kwargs on_gpu_failure (line 339) and missing_sources (line 355)
already raise ValueError when used on a path where they do not
apply.

11 tests, all behaving as designed:

* 4 xfail(strict=True) pinning the fix surface (gpu, dask, vrt,
  dask+gpu) -- flip to xpass (= test failure) when the dispatcher
  fix lands.
* 3 passing pins on the current silent-drop behaviour so the fix is
  visible as a diff.
* 4 positive pins that the eager local + file-like paths accept the
  kwarg (the docstring no-op contract).

Filed issue #1974 for the dispatcher fix; this sweep is test-only.

Updates .claude/sweep-test-coverage-state.csv with the pass 16 note.
@brendancol brendancol force-pushed the deep-sweep-test-coverage-geotiff-2026-05-15-1778875982 branch from 7eb1049 to 869b5ce Compare May 16, 2026 01:07
@brendancol
Copy link
Copy Markdown
Contributor Author

PR Review

What looks good

Suggestions

  • The cupy availability check is duplicated verbatim in test_dispatcher_dask_gpu_path_rejects_max_cloud_bytes (lines 209–217) and TestCurrentSilentDropPins.test_gpu_path_silently_accepts_today (lines 241–249). Worth a shared module-level fixture (or pytest.importorskip plus a cupy.cuda.is_available() skip) — twelve lines of boilerplate becomes one.
  • pytest.raises(ValueError, match=r"max_cloud_bytes") requires the fix author's error message to mention max_cloud_bytes literally. The sibling on_gpu_failure / missing_sources errors do follow that convention, so this is consistent — but worth flagging in geotiff: open_geotiff silently drops max_cloud_bytes on gpu / chunks / VRT paths #1974 so the fix author doesn't ship a message like "this kwarg only applies on the eager path" and trip the xpass.
  • _build_local_tif writes via the eager path, which after rebase routes through the writer's CRS validator (geotiff: reject bool and unresolvable EPSG in writer crs= (#1971) #1978). attrs={'crs': 4326} is fine, but if a future commit makes that attrs entry stricter (e.g. requires crs_wkt instead), this fixture quietly stops producing test inputs. Low risk, but the helper depends on a chunk of the write API that has been churning.

Nits

Checklist

  • Algorithm matches reference/paper — not applicable (test-coverage sweep)
  • All implemented backends covered — the four backend dispatch arms each have a xfail pin
  • NaN handling — not applicable
  • Edge cases covered — local vs. file-like vs. dask vs. gpu vs. vrt vs. dask+gpu
  • Dask chunk boundaries — not applicable
  • No premature materialisation in test fixtures
  • No benchmark required (test-only PR)
  • Docstrings present and accurate — module and class docstrings carry the fix-visibility contract

- extract cupy availability check into a shared helper to drop the duplicate at lines 209 and 241
- add class-level "# remove with #1974" marker on TestCurrentSilentDropPins so future cleanup is greppable
- explain max_cloud_bytes=8 in test_local_file_max_cloud_bytes_small_is_noop (small budget proves the local path ignores it)
@brendancol brendancol merged commit 6cf50e4 into main May 16, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant