This is an automated email from the ASF dual-hosted git repository.

russellspitzer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new 11e7230b67 API: Removes Explicit Parameterization of Schema Tests 
(#11444)
11e7230b67 is described below

commit 11e7230b678c1dd76993117c7470ce92b63709d7
Author: Russell Spitzer <[email protected]>
AuthorDate: Thu Nov 7 09:47:50 2024 -0600

    API: Removes Explicit Parameterization of Schema Tests (#11444)
---
 api/src/main/java/org/apache/iceberg/Schema.java   |   8 +-
 .../test/java/org/apache/iceberg/TestHelpers.java  |   3 +
 .../test/java/org/apache/iceberg/TestSchema.java   | 119 +++++++++++++++------
 3 files changed, 93 insertions(+), 37 deletions(-)

diff --git a/api/src/main/java/org/apache/iceberg/Schema.java 
b/api/src/main/java/org/apache/iceberg/Schema.java
index 44f65ff56a..a94e877187 100644
--- a/api/src/main/java/org/apache/iceberg/Schema.java
+++ b/api/src/main/java/org/apache/iceberg/Schema.java
@@ -28,6 +28,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
+import 
org.apache.iceberg.relocated.com.google.common.annotations.VisibleForTesting;
 import org.apache.iceberg.relocated.com.google.common.base.Joiner;
 import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
 import org.apache.iceberg.relocated.com.google.common.collect.BiMap;
@@ -54,8 +55,11 @@ public class Schema implements Serializable {
   private static final Joiner NEWLINE = Joiner.on('\n');
   private static final String ALL_COLUMNS = "*";
   private static final int DEFAULT_SCHEMA_ID = 0;
-  private static final int DEFAULT_VALUES_MIN_FORMAT_VERSION = 3;
-  private static final Map<Type.TypeID, Integer> MIN_FORMAT_VERSIONS =
+
+  @VisibleForTesting static final int DEFAULT_VALUES_MIN_FORMAT_VERSION = 3;
+
+  @VisibleForTesting
+  static final Map<Type.TypeID, Integer> MIN_FORMAT_VERSIONS =
       ImmutableMap.of(Type.TypeID.TIMESTAMP_NANO, 3);
 
   private final StructType struct;
diff --git a/api/src/test/java/org/apache/iceberg/TestHelpers.java 
b/api/src/test/java/org/apache/iceberg/TestHelpers.java
index ca3b1a908a..003e7835ed 100644
--- a/api/src/test/java/org/apache/iceberg/TestHelpers.java
+++ b/api/src/test/java/org/apache/iceberg/TestHelpers.java
@@ -53,6 +53,9 @@ public class TestHelpers {
 
   private TestHelpers() {}
 
+  public static final int MAX_FORMAT_VERSION = 3;
+  public static final int[] ALL_VERSIONS = IntStream.rangeClosed(1, 
MAX_FORMAT_VERSION).toArray();
+
   /** Wait in a tight check loop until system clock is past {@code 
timestampMillis} */
   public static long waitUntilAfter(long timestampMillis) {
     long current = System.currentTimeMillis();
diff --git a/api/src/test/java/org/apache/iceberg/TestSchema.java 
b/api/src/test/java/org/apache/iceberg/TestSchema.java
index fec7343c5c..e79adbd09f 100644
--- a/api/src/test/java/org/apache/iceberg/TestSchema.java
+++ b/api/src/test/java/org/apache/iceberg/TestSchema.java
@@ -18,32 +18,27 @@
  */
 package org.apache.iceberg;
 
+import static org.apache.iceberg.Schema.DEFAULT_VALUES_MIN_FORMAT_VERSION;
+import static org.apache.iceberg.Schema.MIN_FORMAT_VERSIONS;
+import static org.apache.iceberg.TestHelpers.MAX_FORMAT_VERSION;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.util.List;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import org.apache.iceberg.relocated.com.google.common.collect.ImmutableList;
+import org.apache.iceberg.types.Type;
 import org.apache.iceberg.types.Types;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.FieldSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 public class TestSchema {
-  private static final Schema TS_NANO_CASES =
-      new Schema(
-          Types.NestedField.required(1, "id", Types.LongType.get()),
-          Types.NestedField.optional(2, "ts", 
Types.TimestampNanoType.withZone()),
-          Types.NestedField.optional(
-              3, "arr", Types.ListType.ofRequired(4, 
Types.TimestampNanoType.withoutZone())),
-          Types.NestedField.required(
-              5,
-              "struct",
-              Types.StructType.of(
-                  Types.NestedField.optional(6, "inner_ts", 
Types.TimestampNanoType.withZone()),
-                  Types.NestedField.required(7, "data", 
Types.StringType.get()))),
-          Types.NestedField.optional(
-              8,
-              "struct_arr",
-              Types.StructType.of(
-                  Types.NestedField.optional(9, "ts", 
Types.TimestampNanoType.withoutZone()))));
+
+  private static final List<Type> TEST_TYPES =
+      ImmutableList.of(Types.TimestampNanoType.withoutZone(), 
Types.TimestampNanoType.withZone());
 
   private static final Schema INITIAL_DEFAULT_SCHEMA =
       new Schema(
@@ -64,27 +59,77 @@ public class TestSchema {
               .withWriteDefault("--")
               .build());
 
+  private Schema generateTypeSchema(Type type) {
+    return new Schema(
+        Types.NestedField.required(1, "id", Types.LongType.get()),
+        Types.NestedField.optional(2, "top", type),
+        Types.NestedField.optional(3, "arr", Types.ListType.ofRequired(4, 
type)),
+        Types.NestedField.required(
+            5,
+            "struct",
+            Types.StructType.of(
+                Types.NestedField.optional(6, "inner_op", type),
+                Types.NestedField.required(7, "inner_req", type),
+                Types.NestedField.optional(
+                    8,
+                    "struct_arr",
+                    Types.StructType.of(Types.NestedField.optional(9, "deep", 
type))))));
+  }
+
+  private static Stream<Arguments> unsupportedTypes() {
+    return TEST_TYPES.stream()
+        .flatMap(
+            type ->
+                IntStream.range(1, MIN_FORMAT_VERSIONS.get(type.typeId()))
+                    .mapToObj(unsupportedVersion -> Arguments.of(type, 
unsupportedVersion)));
+  }
+
   @ParameterizedTest
-  @ValueSource(ints = {1, 2})
-  public void testUnsupportedTimestampNano(int formatVersion) {
-    assertThatThrownBy(() -> Schema.checkCompatibility(TS_NANO_CASES, 
formatVersion))
+  @MethodSource("unsupportedTypes")
+  public void testUnsupportedTypes(Type type, int unsupportedVersion) {
+    assertThatThrownBy(
+            () -> Schema.checkCompatibility(generateTypeSchema(type), 
unsupportedVersion))
         .isInstanceOf(IllegalStateException.class)
         .hasMessage(
             "Invalid schema for v%s:\n"
-                + "- Invalid type for ts: timestamptz_ns is not supported 
until v3\n"
-                + "- Invalid type for arr.element: timestamp_ns is not 
supported until v3\n"
-                + "- Invalid type for struct.inner_ts: timestamptz_ns is not 
supported until v3\n"
-                + "- Invalid type for struct_arr.ts: timestamp_ns is not 
supported until v3",
-            formatVersion);
+                + "- Invalid type for top: %s is not supported until v%s\n"
+                + "- Invalid type for arr.element: %s is not supported until 
v%s\n"
+                + "- Invalid type for struct.inner_op: %s is not supported 
until v%s\n"
+                + "- Invalid type for struct.inner_req: %s is not supported 
until v%s\n"
+                + "- Invalid type for struct.struct_arr.deep: %s is not 
supported until v%s",
+            unsupportedVersion,
+            type,
+            MIN_FORMAT_VERSIONS.get(type.typeId()),
+            type,
+            MIN_FORMAT_VERSIONS.get(type.typeId()),
+            type,
+            MIN_FORMAT_VERSIONS.get(type.typeId()),
+            type,
+            MIN_FORMAT_VERSIONS.get(type.typeId()),
+            type,
+            MIN_FORMAT_VERSIONS.get(type.typeId()));
   }
 
-  @Test
-  public void testSupportedTimestampNano() {
-    assertThatCode(() -> Schema.checkCompatibility(TS_NANO_CASES, 
3)).doesNotThrowAnyException();
+  private static Stream<Arguments> supportedTypes() {
+    return TEST_TYPES.stream()
+        .flatMap(
+            type ->
+                IntStream.rangeClosed(MIN_FORMAT_VERSIONS.get(type.typeId()), 
MAX_FORMAT_VERSION)
+                    .mapToObj(supportedVersion -> Arguments.of(type, 
supportedVersion)));
   }
 
   @ParameterizedTest
-  @ValueSource(ints = {1, 2})
+  @MethodSource("supportedTypes")
+  public void testTypeSupported(Type type, int supportedVersion) {
+    assertThatCode(() -> Schema.checkCompatibility(generateTypeSchema(type), 
supportedVersion))
+        .doesNotThrowAnyException();
+  }
+
+  private static int[] unsupportedInitialDefault =
+      IntStream.range(1, DEFAULT_VALUES_MIN_FORMAT_VERSION).toArray();
+
+  @ParameterizedTest
+  @FieldSource("unsupportedInitialDefault")
   public void testUnsupportedInitialDefault(int formatVersion) {
     assertThatThrownBy(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, 
formatVersion))
         .isInstanceOf(IllegalStateException.class)
@@ -95,14 +140,18 @@ public class TestSchema {
             formatVersion);
   }
 
-  @Test
-  public void testSupportedInitialDefault() {
-    assertThatCode(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, 3))
+  private static int[] supportedInitialDefault =
+      IntStream.rangeClosed(DEFAULT_VALUES_MIN_FORMAT_VERSION, 
MAX_FORMAT_VERSION).toArray();
+
+  @ParameterizedTest
+  @FieldSource("supportedInitialDefault")
+  public void testSupportedInitialDefault(int formatVersion) {
+    assertThatCode(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, 
formatVersion))
         .doesNotThrowAnyException();
   }
 
   @ParameterizedTest
-  @ValueSource(ints = {1, 2, 3})
+  @FieldSource("org.apache.iceberg.TestHelpers#ALL_VERSIONS")
   public void testSupportedWriteDefault(int formatVersion) {
     // only the initial default is a forward-incompatible change
     assertThatCode(() -> Schema.checkCompatibility(WRITE_DEFAULT_SCHEMA, 
formatVersion))

Reply via email to