This is an automated email from the ASF dual-hosted git repository.
laskoviymishka 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 b62009c2d7 Core: Add UTs for ManifestEntriesTableTaskParser class
(#18125)
b62009c2d7 is described below
commit b62009c2d78a16fa3fb2159e59d9645a8ed623ee
Author: Prashant Bajpai <[email protected]>
AuthorDate: Tue Oct 6 16:13:31 2026 +0530
Core: Add UTs for ManifestEntriesTableTaskParser class (#18125)
* Core: add tests for ManifestEntriesTableTaskParser
* PR Review suggestion by mkroll-db : Strengthen
ManifestEntriesTableTaskParser round-trip test
---------
Co-authored-by: Prashant Bajpai <[email protected]>
---
.../TestManifestEntriesTableTaskParser.java | 137 +++++++++++++++++++++
1 file changed, 137 insertions(+)
diff --git
a/core/src/test/java/org/apache/iceberg/TestManifestEntriesTableTaskParser.java
b/core/src/test/java/org/apache/iceberg/TestManifestEntriesTableTaskParser.java
new file mode 100644
index 0000000000..ca56f2ac2b
--- /dev/null
+++
b/core/src/test/java/org/apache/iceberg/TestManifestEntriesTableTaskParser.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iceberg;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Map;
+import org.apache.iceberg.expressions.Expressions;
+import org.apache.iceberg.hadoop.HadoopFileIO;
+import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
+import org.apache.iceberg.util.JsonUtil;
+import org.apache.iceberg.util.PartitionUtil;
+import org.junit.jupiter.api.Test;
+
+public class TestManifestEntriesTableTaskParser {
+ @Test
+ public void nullCheck() throws Exception {
+ StringWriter writer = new StringWriter();
+ try (JsonGenerator generator = JsonUtil.factory().createGenerator(writer))
{
+ assertThatThrownBy(() -> ManifestEntriesTableTaskParser.toJson(null,
generator))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Invalid manifest task: null");
+
+ assertThatThrownBy(() ->
ManifestEntriesTableTaskParser.toJson(createTask(), null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Invalid JSON generator: null");
+
+ assertThatThrownBy(() -> ManifestEntriesTableTaskParser.fromJson(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Invalid JSON node for manifest task: null");
+ }
+ }
+
+ @Test
+ public void invalidJsonNode() throws Exception {
+ String jsonStr = "{\"str\":\"1\", \"arr\":[]}";
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode rootNode = mapper.reader().readTree(jsonStr);
+
+ assertThatThrownBy(() ->
ManifestEntriesTableTaskParser.fromJson(rootNode.get("str")))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid JSON node for manifest task: non-object
");
+
+ assertThatThrownBy(() ->
ManifestEntriesTableTaskParser.fromJson(rootNode.get("arr")))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid JSON node for manifest task: non-object
");
+ }
+
+ @Test
+ public void testParser() {
+ BaseEntriesTable.ManifestReadTask task = createTask();
+ String jsonStr = ScanTaskParser.toJson(task);
+ assertThat(jsonStr).isEqualTo(taskJson());
+ BaseEntriesTable.ManifestReadTask deserializedTask =
+ (BaseEntriesTable.ManifestReadTask) ScanTaskParser.fromJson(jsonStr,
false);
+ assertTaskEquals(task, deserializedTask);
+ }
+
+ private BaseEntriesTable.ManifestReadTask createTask() {
+ Schema schema = TestBase.SCHEMA;
+ Schema projection = schema.select("data");
+ HadoopFileIO fileIO = new HadoopFileIO();
+ fileIO.initialize(ImmutableMap.of("k1", "v1", "k2", "v2"));
+ Map<Integer, PartitionSpec> specsById =
+ PartitionUtil.indexSpecs(
+ Arrays.asList(
+ PartitionSpec.builderFor(schema).bucket("data", 16).build(),
+ PartitionSpec.builderFor(schema).withSpecId(1).bucket("id",
4).build()));
+ ManifestFile manifestFile = TestManifestFileParser.createManifestFile();
+ return new BaseEntriesTable.ManifestReadTask(
+ schema, fileIO, specsById, manifestFile, projection,
Expressions.equal("id", 1));
+ }
+
+ private String taskJson() {
+ return "{\"task-type\":\"manifest-entries-task\","
+ + "\"schema\":{\"type\":\"struct\",\"schema-id\":0,\"fields\":[{"
+ + "\"id\":3,\"name\":\"id\",\"required\":true,\"type\":\"int\"},"
+ +
"{\"id\":4,\"name\":\"data\",\"required\":true,\"type\":\"string\"}]},"
+ +
"\"file-io\":{\"io-impl\":\"org.apache.iceberg.hadoop.HadoopFileIO\","
+ + "\"properties\":{\"k1\":\"v1\",\"k2\":\"v2\"}},"
+ + "\"partition-specs\":[{\"spec-id\":0,\"fields\":[{"
+ +
"\"name\":\"data_bucket\",\"transform\":\"bucket[16]\",\"source-id\":4,\"field-id\":1000}]},"
+ + "{\"spec-id\":1,\"fields\":[{"
+ +
"\"name\":\"id_bucket\",\"transform\":\"bucket[4]\",\"source-id\":3,\"field-id\":1000}]}],"
+ + "\"manifest-file\":{\"path\":\"/path/input.m0.avro\","
+ +
"\"length\":5878,\"partition-spec-id\":0,\"content\":0,\"sequence-number\":1,\"min-sequence-number\":2,"
+ + "\"added-snapshot-id\":12345678901234567,"
+ +
"\"added-files-count\":1,\"existing-files-count\":3,\"deleted-files-count\":0,"
+ +
"\"added-rows-count\":10,\"existing-rows-count\":30,\"deleted-rows-count\":0,"
+ +
"\"partition-field-summary\":[{\"contains-null\":true,\"contains-nan\":false,"
+ +
"\"lower-bound\":\"0A000000\",\"upper-bound\":\"64000000\"}],\"key-metadata\":\"DB030000\","
+ + "\"first-row-id\":10},"
+ + "\"projection\":{\"type\":\"struct\",\"schema-id\":0,\"fields\":[{"
+ +
"\"id\":4,\"name\":\"data\",\"required\":true,\"type\":\"string\"}]},"
+ + "\"residual-filter\":{\"type\":\"eq\",\"term\":\"id\",\"value\":1}}";
+ }
+
+ private void assertTaskEquals(
+ BaseEntriesTable.ManifestReadTask expected,
BaseEntriesTable.ManifestReadTask actual) {
+ assertThat(actual.dataTableSchema().asStruct())
+ .as("Data table schema should match")
+ .isEqualTo(expected.dataTableSchema().asStruct());
+ assertThat(actual.projection().asStruct())
+ .as("Projected schema should match")
+ .isEqualTo(expected.projection().asStruct());
+
+ HadoopFileIO expectedIO = (HadoopFileIO) expected.io();
+ HadoopFileIO actualIO = (HadoopFileIO) actual.io();
+ assertThat(actualIO.properties()).isEqualTo(expectedIO.properties());
+
+ assertThat(actual.specsById()).isEqualTo(expected.specsById());
+
assertThat(actual.residual().toString()).isEqualTo(expected.residual().toString());
+ assertThat(actual.manifest()).isEqualTo(expected.manifest());
+ }
+}