You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2026/05/21 09:15:58 UTC
(sis) 05/06: chore(Storage): improve GeoTiff tests to verify tiling of written files
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 <al...@geomatys.com>
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
+ )
+ );
+ }
}
}
}