This is an automated email from the ASF dual-hosted git repository. alexismanin pushed a commit to branch fix/geotiff-flaky-test in repository https://gitbox.apache.org/repos/asf/sis.git
commit ed5617b6a5554e329fed98637e50d29c49f45220 Author: Alexis Manin <[email protected]> AuthorDate: Thu May 21 09:53:55 2026 +0200 chore(Storage): improve GeoTiff tests to verify tiling of written files --- .../sis/storage/geotiff/GeoTiffStoreTest.java | 74 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/GeoTiffStoreTest.java b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/GeoTiffStoreTest.java index bf9a28ce47..e43a061cc4 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/GeoTiffStoreTest.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/GeoTiffStoreTest.java @@ -16,7 +16,6 @@ */ package org.apache.sis.storage.geotiff; -import java.io.IOException; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.nio.file.Path; @@ -46,6 +45,7 @@ import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.referencing.operation.matrix.Matrix4; // Test dependencies +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -156,6 +156,20 @@ public final class GeoTiffStoreTest extends TestCase { testWrite(new Rectangle(tileSize.width * 3, tileSize.height * 2), tileSize); } + /** + * Writes an image and compare with the {@code "tiled.tiff"} file. + * This test differs from {@link #testWriteTiled()} because it requests a tile size that is not accepted as is by + * geotiff. + * </br> + * The aim of this test is to ensure that Geotiff writer will adapt tile size according to the Tiff standard. + * It requests tiles of size 19, and expect the Geotiff writer to adapt request to write tiles of size 16 or 32. + */ + @Test + public void testWriteTiledAdapted() throws Exception { + final var tileSize = new Dimension(7, 7); + testWrite(new Rectangle(64, 64), tileSize); + } + /** * Implementation of {@link #testWriteUntiled()} and {@link #testWriteTiled()}. * @@ -215,7 +229,63 @@ public final class GeoTiffStoreTest extends TestCase { ) ); - assertPixelsEqual(coverage.render(null), null, coverageToValidate.render(null), null); + final var actualRendering = coverageToValidate.render(null); + assertPixelsEqual(coverage.render(null), null, actualRendering, null); + // If user requested a tiled dataset, we must ensure the written Geotiff file has been tiled + if (tileSize != null && (tileSize.getWidth() < bounds.getWidth() || tileSize.getHeight() < bounds.getHeight())) { + assertTiling(actualRendering, tileSize, 16); + } + } + } + + /** + * Represent the side of the tile being evaluated. Either width (X) or height (Y). + */ + private enum TileAxis { width, height } + + /** + * Verify that given image tiling respects user tiling request, modulo a given restriction. + * The restriction maps Tiff standard requirement for tile size to be multiple of a given factor. + * </br> + * It means that if user requests a tile size of 3, but the restriction factor is 2, + * then we expect the image to use a tile size of either 2 or 4, + * which are the nearest enclosing multiples of 2 for request 3. + * + * @param actualRendering The image to control tiling on. + * @param tileSize The tile size requested by user. + * @param tileSizeMultiple A factor to use to adapted requested tile size. + */ + private static void assertTiling(RenderedImage actualRendering, Dimension tileSize, int tileSizeMultiple) { + assertTileSize(TileAxis.width, actualRendering.getWidth(), actualRendering.getTileWidth(), tileSize.width, tileSizeMultiple); + assertTileSize(TileAxis.height, actualRendering.getHeight(), actualRendering.getTileHeight(), tileSize.height, tileSizeMultiple); + } + + /** + * Test a specific tile side according to requirements expressed by {@link #assertTiling(RenderedImage, Dimension, int)}. + * + * @param axis Which side of the tiling is being tested. Used for assertion error message formatting. + * @param imgSize The image actual size along tested side (its {@link RenderedImage#getWidth() width} or {@link RenderedImage#getHeight() height}). + * @param imgActualTileSize The image actual tile size along tested side (its {@link RenderedImage#getTileWidth() tile width} or {@link RenderedImage#getTileHeight() tile height}). + * @param requestedTileSize User request tile size along the side to test. + * @param tileSizeMultiple The restriction factor: actual tile size must be a multiple of this value, independently of the user request. + */ + private static void assertTileSize(TileAxis axis, int imgSize, int imgActualTileSize, int requestedTileSize, int tileSizeMultiple) { + if (imgSize > requestedTileSize) { + final int modulo = requestedTileSize % tileSizeMultiple; + if (modulo == 0) { + assertEquals(requestedTileSize, imgActualTileSize, () -> "Tile " + axis); + } else if (requestedTileSize < tileSizeMultiple) { + assertEquals(tileSizeMultiple, imgActualTileSize, () -> "Tile " + axis); + } else { + final var minTileSize = requestedTileSize - modulo; + final var maxTileSize = requestedTileSize + (tileSizeMultiple - modulo); + assertTrue(imgActualTileSize == minTileSize || imgActualTileSize == maxTileSize, + () -> String.format( + "Tile %s should be either %d or %d (because it must be a multiple of %d), but it is %d", + axis, minTileSize, maxTileSize, tileSizeMultiple, imgActualTileSize + ) + ); + } } } }
