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

github-merge-queue[bot] pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new a3743d7f52 [Test][Connector-V2] Read the XML file sink output back 
with the XML source (#12891)
a3743d7f52 is described below

commit a3743d7f52e9200a7733857ca813a0836bf66bba
Author: FatMan <[email protected]>
AuthorDate: Wed Nov 4 15:47:29 2026 +0000

    [Test][Connector-V2] Read the XML file sink output back with the XML source 
(#12891)
    
    Co-authored-by: chen <[email protected]>
---
 .../seatunnel/file/writer/XmlWriterTest.java       | 87 +++++++++++++++++++++-
 1 file changed, 86 insertions(+), 1 deletion(-)

diff --git 
a/seatunnel-connectors-v2/connector-file/connector-file-base/src/test/java/org/apache/seatunnel/connectors/seatunnel/file/writer/XmlWriterTest.java
 
b/seatunnel-connectors-v2/connector-file/connector-file-base/src/test/java/org/apache/seatunnel/connectors/seatunnel/file/writer/XmlWriterTest.java
index 24f82e83d0..422bb5af1a 100644
--- 
a/seatunnel-connectors-v2/connector-file/connector-file-base/src/test/java/org/apache/seatunnel/connectors/seatunnel/file/writer/XmlWriterTest.java
+++ 
b/seatunnel-connectors-v2/connector-file/connector-file-base/src/test/java/org/apache/seatunnel/connectors/seatunnel/file/writer/XmlWriterTest.java
@@ -17,6 +17,11 @@
 
 package org.apache.seatunnel.connectors.seatunnel.file.writer;
 
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
+
+import org.apache.seatunnel.api.source.Collector;
+import org.apache.seatunnel.api.table.catalog.CatalogTableUtil;
 import org.apache.seatunnel.api.table.type.BasicType;
 import org.apache.seatunnel.api.table.type.LocalTimeType;
 import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
@@ -27,19 +32,29 @@ import org.apache.seatunnel.common.utils.DateUtils;
 import org.apache.seatunnel.common.utils.TimeUtils;
 import 
org.apache.seatunnel.connectors.seatunnel.file.sink.config.FileSinkConfig;
 import org.apache.seatunnel.connectors.seatunnel.file.sink.util.XmlWriter;
+import 
org.apache.seatunnel.connectors.seatunnel.file.source.reader.XmlReadStrategy;
+import 
org.apache.seatunnel.connectors.seatunnel.file.source.split.FileSourceSplit;
+import org.apache.seatunnel.connectors.seatunnel.file.util.LocalFileSystemConf;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
+import static 
org.apache.hadoop.fs.CommonConfigurationKeysPublic.FS_DEFAULT_NAME_DEFAULT;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -131,11 +146,81 @@ public class XmlWriterTest {
                 xml.contains("<c_row>1,2026-01-02,10:13:00,2026-01-02 
10:13:00</c_row>"), xml);
     }
 
+    /**
+     * What the sink writes with its default formats is read back unchanged by 
the XML source with
+     * its default formats. Before the fix the source failed to parse {@code 
2026-01-02T10:13}.
+     */
+    @ParameterizedTest
+    @ValueSource(booleans = {false, true})
+    public void testDefaultFormatsRoundTripThroughXmlSource(boolean 
useAttrFormat)
+            throws IOException {
+        when(fileSinkConfig.getXmlUseAttrFormat()).thenReturn(useAttrFormat);
+        SeaTunnelRow secondRow =
+                new SeaTunnelRow(
+                        new Object[] {
+                            2,
+                            LocalDate.of(2026, 12, 31),
+                            LocalTime.of(23, 59, 59),
+                            LocalDateTime.of(2026, 12, 31, 23, 59, 59)
+                        });
+
+        List<SeaTunnelRow> rows = readBack(write(ROW, secondRow), 
useAttrFormat);
+
+        Assertions.assertEquals(2, rows.size());
+        Assertions.assertArrayEquals(ROW.getFields(), rows.get(0).getFields());
+        Assertions.assertArrayEquals(secondRow.getFields(), 
rows.get(1).getFields());
+    }
+
     private String write() throws IOException {
+        return write(ROW);
+    }
+
+    private String write(SeaTunnelRow... rows) throws IOException {
         XmlWriter writer = new XmlWriter(fileSinkConfig, Arrays.asList(0, 1, 
2, 3), ROW_TYPE);
-        writer.writeData(ROW);
+        for (SeaTunnelRow row : rows) {
+            writer.writeData(row);
+        }
         ByteArrayOutputStream output = new ByteArrayOutputStream();
         writer.flushAndCloseXmlWriter(output);
         return new String(output.toByteArray(), StandardCharsets.UTF_8);
     }
+
+    /** Reads the XML with the XML source, using the source defaults for all 
date/time formats. */
+    private static List<SeaTunnelRow> readBack(String xml, boolean 
useAttrFormat)
+            throws IOException {
+        Config pluginConfig =
+                ConfigFactory.parseString(
+                        "xml_row_tag = \"RECORD\"\n"
+                                + "xml_use_attr_format = "
+                                + useAttrFormat
+                                + "\n"
+                                + "schema { fields { id = int, c_date = date, 
c_time = time,"
+                                + " c_timestamp = timestamp } }");
+        XmlReadStrategy readStrategy = new XmlReadStrategy();
+        readStrategy.setPluginConfig(pluginConfig);
+        readStrategy.init(new 
LocalFileSystemConf.LocalConf(FS_DEFAULT_NAME_DEFAULT));
+        
readStrategy.setCatalogTable(CatalogTableUtil.buildWithConfig(pluginConfig));
+        RowCollector collector = new RowCollector();
+        readStrategy.readProcess(
+                new FileSourceSplit("xml", "round_trip.xml"),
+                collector,
+                new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)),
+                Collections.emptyMap(),
+                "round_trip.xml");
+        return collector.rows;
+    }
+
+    private static class RowCollector implements Collector<SeaTunnelRow> {
+        private final List<SeaTunnelRow> rows = new ArrayList<>();
+
+        @Override
+        public void collect(SeaTunnelRow record) {
+            rows.add(record);
+        }
+
+        @Override
+        public Object getCheckpointLock() {
+            return this;
+        }
+    }
 }

Reply via email to