Skip to content

VRT tests: negative coverage for unsupported features (#2370)#2375

Open
brendancol wants to merge 4 commits into
mainfrom
issue-2370
Open

VRT tests: negative coverage for unsupported features (#2370)#2375
brendancol wants to merge 4 commits into
mainfrom
issue-2370

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

  • Negative tests that pin the rejection contract for VRT inputs the release does not promise to support.
  • Covers warped VRT, nested VRT, mixed source CRS, mixed dtype, mixed band count, complex mask source, and unsupported resample algorithm.
  • Each test checks the exception type and that the message names the unsupported feature, so users can fix the input.
  • Both read_vrt and open_geotiff(... .vrt ...) entry points are exercised.

Backend coverage

Test-only PR. The VRT read path is numpy-eager; backend dispatch is not in scope.

Coordination

PR 3 of epic #2342. Sibling PR 1 (#2329) is the centralized validate_vrt_capability. Where the current code already rejects a case (complex dtype #1783, non-nearest resample alg #1751, bad source band number), the test pins the existing behaviour. Where the rejection depends on #2329, the test is wrapped with pytest.xfail(reason="depends on centralized validate_vrt_capability (#2329)") so this PR can land on its own. Those tests will flip to passing once #2329 merges.

Test plan

  • pytest xrspatial/geotiff/tests/test_vrt_unsupported_2370.py: 9 passed, 8 xfailed
  • Adjacent VRT tests still pass (test_vrt_resample_alg_1751, test_vrt_dtype_1783)
  • All tmp filenames include 2370 to avoid collisions with parallel rockout worktrees

Closes #2370.

Lock in the rejection contract for VRT inputs the release does not
promise to support. The cases covered are:

- Warped VRT (subClass="VRTWarpedRasterBand" and GDALWarpOptions)
- Nested VRT (.vrt as <SourceFilename>)
- Mixed source CRS across band sources
- Mixed source dtype (complex dtype is already rejected; ambiguous
  cross-band widening is pinned for the validator PR)
- Mixed band count across sources
- Complex mask source semantics not representable in attrs
- Unsupported resample algorithm (already rejected -- locked in)

Each test checks the exception type and that the message names the
unsupported feature. Both read_vrt and open_geotiff entry points are
exercised. Cases that depend on the centralized validator from
sibling PR #2329 are wrapped with pytest.xfail so this PR lands
independently and starts passing once #2329 merges.

Sub-task of #2342.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 25, 2026
Copy link
Copy Markdown
Contributor Author

@brendancol brendancol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review: VRT tests: negative coverage for unsupported features (#2375)

Test-only PR. I read the new file xrspatial/geotiff/tests/test_vrt_unsupported_2370.py and ran the suite locally (9 passed, 8 xfailed, as advertised).

Blockers (must fix before merge)

None.

Suggestions (should fix, not blocking)

  • xrspatial/geotiff/tests/test_vrt_unsupported_2370.py:121: _assert_raises_or_xfail is defined under the "Group 1 -- Warped VRT" header but it is shared by every group. Move it above the Group 1 header (or put it under a dedicated "Helpers" header) so the section layout matches the code. Cosmetic, but it trips readers scanning the headers.
  • xrspatial/geotiff/tests/test_vrt_unsupported_2370.py:141: except BaseException is broader than needed and would swallow KeyboardInterrupt / SystemExit if one ever leaked out of XML setup. except Exception keeps the diagnostic xfail for genuine errors without masking interruption signals.

Nits (optional improvements)

  • xrspatial/geotiff/tests/test_vrt_unsupported_2370.py:79: _simple_source_xml accepts x_size, y_size, dst_x_size, dst_y_size, extra_inner parameters that no caller in this PR uses. Either drop them or note in the docstring that they are forward-compat for follow-up work.
  • The resample-alg tests overlap by design with test_vrt_resample_alg_1751.py. A one-line note in the module docstring explaining the split (this file is the rejection-contract anchor; the #1751 file is the regression anchor) would save a future reader from de-duping them.

What looks good

  • Every test checks both the exception type and that the message names the unsupported feature, matching the issue's acceptance criteria.
  • _assert_raises_or_xfail produces one consistent xfail reason naming PR #2329, so a reader who sees an xfail does not have to dig into the test to learn why.
  • Coverage spans read_vrt and open_geotiff for the cases where a regression at either entry point would leak past the contract (warped, nested, resample alg).
  • The supported-VRT anchor test prevents the file from quietly degrading if .vrt extension dispatch breaks.
  • All tmp filenames carry 2370, matching the project's collision-avoidance convention.
  • The two cases the current code already rejects (complex dtype CFloat32, non-nearest resample alg) lock in real messages with pytest.raises(..., match=...) rather than the looser xfail-friendly helper.

Checklist

  • Test-only change; correctness checks N/A for production code
  • Four-backend coverage N/A (VRT read path is numpy-eager today)
  • NaN handling N/A
  • Edge cases captured via crafted VRT XML
  • Dask chunk boundaries N/A
  • No performance-sensitive code changed
  • No README or docs update needed (test-only PR)
  • Docstrings present on every test
  • Closes #2370 in the PR body

- Move _assert_raises_or_xfail above the Group 1 header so it does
  not look like a Group 1 helper.
- Narrow the diagnostic catch from BaseException to Exception so
  KeyboardInterrupt and SystemExit still propagate.
- Drop unused parameters from _simple_source_xml and pin the helper
  to the 4x4 SrcRect/DstRect geometry every caller actually uses.
- Document the intentional resample-alg overlap with
  test_vrt_resample_alg_1751.py in the module docstring.
Copy link
Copy Markdown
Contributor Author

@brendancol brendancol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review (follow-up): commit 6f92559

Re-reviewed after the follow-up commit. All four findings from the first pass were addressed:

  • Helper moved above the Group 1 header into a dedicated Helpers section.
  • except BaseException narrowed to except Exception on the diagnostic branch, with a docstring note explaining why.
  • Unused parameters dropped from _simple_source_xml; the helper is now pinned to the 4x4 geometry every caller uses.
  • Module docstring now explains the intentional overlap with test_vrt_resample_alg_1751.py.

Re-ran the suite locally: 9 passed, 8 xfailed -- no change in disposition, which is the expected result for these refactors.

Blockers

None.

Suggestions

None.

Nits

None.

The PR is ready as far as the test contract goes. CI is the next gate.

PR1 (#2329) landed via main while this PR was in review. The
centralised validator now rejects unsupported resample algorithms at
parse time with VRTUnsupportedError (a ValueError subclass) before
the legacy resample-site NotImplementedError can fire. Broaden the
expected exception type in the open_geotiff test to accept either
rejection path so the contract test stays green under both code
paths. The read_vrt parametrised test still pins
NotImplementedError because that helper does not go through the new
validator yet.
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.

VRT tests: negative coverage for unsupported features (#2342 work item)

1 participant