Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Removes Explicit Parameterization of Schema Tests #11444

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions api/src/main/java/org/apache/iceberg/Schema.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions api/src/test/java/org/apache/iceberg/TestHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class TestHelpers {

private TestHelpers() {}

public static final int MAX_FORMAT_VERSION = 3;

/** Wait in a tight check loop until system clock is past {@code timestampMillis} */
public static long waitUntilAfter(long timestampMillis) {
long current = System.currentTimeMillis();
Expand Down
122 changes: 87 additions & 35 deletions api/src/test/java/org/apache/iceberg/TestSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -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> TESTTYPES =
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
ImmutableList.of(Types.TimestampNanoType.withoutZone(), Types.TimestampNanoType.withZone());

private static final Schema INITIAL_DEFAULT_SCHEMA =
new Schema(
Expand All @@ -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> testTypeUnsupported() {
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
return TESTTYPES.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
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
public void testTypeUnsupported(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> testTypeSupported() {
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
return TESTTYPES.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
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
public void testTypeSupported(Type type, int supportedVersion) {
assertThatCode(() -> Schema.checkCompatibility(generateTypeSchema(type), supportedVersion))
.doesNotThrowAnyException();
}

private static int[] testUnsupportedInitialDefault =
IntStream.range(1, DEFAULT_VALUES_MIN_FORMAT_VERSION).toArray();

@ParameterizedTest
@FieldSource
public void testUnsupportedInitialDefault(int formatVersion) {
assertThatThrownBy(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, formatVersion))
.isInstanceOf(IllegalStateException.class)
Expand All @@ -95,14 +140,21 @@ public void testUnsupportedInitialDefault(int formatVersion) {
formatVersion);
}

@Test
public void testSupportedInitialDefault() {
assertThatCode(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, 3))
private static int[] testSupportedInitialDefault =
IntStream.rangeClosed(DEFAULT_VALUES_MIN_FORMAT_VERSION, MAX_FORMAT_VERSION).toArray();

@ParameterizedTest
@FieldSource
public void testSupportedInitialDefault(int formatVersion) {
assertThatCode(() -> Schema.checkCompatibility(INITIAL_DEFAULT_SCHEMA, formatVersion))
.doesNotThrowAnyException();
}

private static int[] testSupportedWriteDefault =
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
IntStream.rangeClosed(1, MAX_FORMAT_VERSION).toArray();

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
@FieldSource
RussellSpitzer marked this conversation as resolved.
Show resolved Hide resolved
public void testSupportedWriteDefault(int formatVersion) {
// only the initial default is a forward-incompatible change
assertThatCode(() -> Schema.checkCompatibility(WRITE_DEFAULT_SCHEMA, formatVersion))
Expand Down
Loading