stevenzwu commented on code in PR #16174:
URL: https://github.com/apache/iceberg/pull/16174#discussion_r3228905288


##########
core/src/test/java/org/apache/iceberg/util/TestLocationUtil.java:
##########
@@ -84,4 +84,103 @@ void testStripTrailingSlashForRootPathWithTrailingSlashes() 
{
         .as("Should be root path")
         .isEqualTo(rootPath);
   }
+
+  @Test
+  public void testResolveRelativeLocations() {
+    String tableLocation = "s3://bucket/table";
+
+    assertThat(LocationUtil.resolveLocation(tableLocation, 
"/metadata/file.parquet"))
+        .isEqualTo("s3://bucket/table/metadata/file.parquet");
+
+    assertThat(LocationUtil.resolveLocation(tableLocation, 
"/data/00000-0.parquet"))
+        .isEqualTo("s3://bucket/table/data/00000-0.parquet");
+  }
+
+  @Test
+  public void testResolveLocationsWithColonsInSegments() {
+    String tableLocation = "s3://bucket/table";
+
+    assertThat(
+            LocationUtil.resolveLocation(tableLocation, 
"/data/partition=key:value/file.parquet"))
+        .isEqualTo("s3://bucket/table/data/partition=key:value/file.parquet");
+
+    assertThat(LocationUtil.resolveLocation(tableLocation, 
"/metadata/snap-123:456.avro"))
+        .isEqualTo("s3://bucket/table/metadata/snap-123:456.avro");
+  }
+
+  @Test
+  public void testResolveAbsoluteLocationsUnchanged() {
+    String tableLocation = "s3://bucket/table";
+
+    assertThat(LocationUtil.resolveLocation(tableLocation, 
"s3://other-bucket/path/file.parquet"))
+        .isEqualTo("s3://other-bucket/path/file.parquet");
+
+    assertThat(LocationUtil.resolveLocation(tableLocation, 
"hdfs://namenode/path/file.parquet"))
+        .isEqualTo("hdfs://namenode/path/file.parquet");
+  }
+
+  @Test
+  public void testRelativize() {
+    String tableLocation = "s3://bucket/table";
+
+    assertThat(
+            LocationUtil.relativizeLocation(
+                tableLocation, "s3://bucket/table/metadata/file.parquet"))
+        .isEqualTo("/metadata/file.parquet");
+
+    assertThat(
+            LocationUtil.relativizeLocation(
+                tableLocation, "s3://bucket/table/data/00000-0.parquet"))
+        .isEqualTo("/data/00000-0.parquet");
+  }
+
+  @Test
+  public void testRelativizeLocationNotUnderTableLocation() {
+    String tableLocation = "s3://bucket/table";
+
+    // different bucket
+    assertThat(
+            LocationUtil.relativizeLocation(tableLocation, 
"s3://other-bucket/path/file.parquet"))
+        .isEqualTo("s3://other-bucket/path/file.parquet");
+
+    // same bucket, different path
+    assertThat(
+            LocationUtil.relativizeLocation(
+                tableLocation, "s3://bucket/other-table/data/file.parquet"))
+        .isEqualTo("s3://bucket/other-table/data/file.parquet");
+  }
+
+  @Test
+  public void testRelativizeLocationEqualToTableLocation() {
+    String tableLocation = "s3://bucket/table";
+
+    assertThat(LocationUtil.relativizeLocation(tableLocation, 
"s3://bucket/table")).isEqualTo("");
+  }
+
+  @Test
+  public void testRelativizeMismatchedFileSchemeNotRelativized() {
+    // mixed file: variants are NOT relativized. Consistent URI forms are the 
caller's
+    // responsibility
+    assertThat(
+            LocationUtil.relativizeLocation(
+                "file:/tmp/table", "file:///tmp/table/metadata/file.parquet"))
+        .isEqualTo("file:///tmp/table/metadata/file.parquet");
+
+    assertThat(
+            LocationUtil.relativizeLocation(
+                "file:///tmp/table", "file:/tmp/table/metadata/file.parquet"))
+        .isEqualTo("file:/tmp/table/metadata/file.parquet");
+  }
+
+  @Test
+  public void testRelativizeResolveRoundTrip() {
+    String tableLocation = "s3://bucket/table";
+    String absoluteLocation = 
"s3://bucket/table/metadata/root-manifest.parquet";
+
+    String relativized = LocationUtil.relativizeLocation(tableLocation, 
absoluteLocation);
+    assertThat(relativized).isEqualTo("/metadata/root-manifest.parquet");
+
+    String resolved = LocationUtil.resolveLocation(tableLocation, relativized);
+    assertThat(resolved).isEqualTo(absoluteLocation);

Review Comment:
   A few test-coverage gaps worth filling while you're here:
   
   1. **No test pins the `+`/`-`/`.` scheme support** that this PR explicitly 
added at line 82 of `LocationUtil.java`. Without one, a future "simplification" 
back to plain `isLetterOrDigit` would silently regress. A round-trip on 
something like `git+ssh://host/repo` (or `view-source:foo`, `coap-tcp://x`) 
would lock the new behavior.
   
   2. **Round-trip is only asserted for `s3://`.** The earlier revision had 
separate `…WithFileScheme` and `…WithHDFS` round-trip cases; they didn't 
survive the move into this file. They're cheap and they pin per-scheme behavior 
— worth restoring.
   
   3. **The empty-relative round-trip is asymmetric.** 
`testRelativizeLocationEqualToTableLocation` asserts 
`relativizeLocation(tableLoc, tableLoc) == ""`, but there's no companion 
asserting `resolveLocation(tableLoc, "") == tableLoc`. It works today (because 
`hasScheme("")` short-circuits), but the round-trip half is what makes the 
contract real.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to