hudi-agent commented on code in PR #19399:
URL: https://github.com/apache/hudi/pull/19399#discussion_r3670736052


##########
hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/append/TestAppendWriteFunctionWithBufferSort.java:
##########
@@ -81,6 +100,114 @@ public void testCustomSortKeysOverrideDefault() {
     assertEquals(Arrays.asList("age", "name"), resolvedSortKeys);
   }
 
+  @Test
+  public void testEmptySortKeysAreRejected() {
+    conf.set(FlinkOptions.WRITE_BUFFER_SORT_KEYS, " , , ");
+
+    assertThrows(IllegalArgumentException.class, () -> 
AppendWriteFunctions.resolveSortKeys(conf));
+  }
+
+  @ParameterizedTest
+  @EnumSource(BufferType.class)
+  public void testFactorySelectsConfiguredBuffer(BufferType bufferType) {
+    conf.set(FlinkOptions.WRITE_BUFFER_TYPE, bufferType.name());
+    RowType rowType = TestConfigurations.ROW_TYPE;
+
+    AppendWriteFunction<RowData> function = AppendWriteFunctions.create(conf, 
rowType);
+
+    switch (bufferType) {
+      case CONTINUOUS_SORT:
+        assertInstanceOf(AppendWriteFunctionWithContinuousSort.class, 
function);
+        break;
+      case DISRUPTOR:
+        assertInstanceOf(AppendWriteFunctionWithDisruptorBufferSort.class, 
function);
+        break;
+      case BOUNDED_IN_MEMORY:
+        assertInstanceOf(AppendWriteFunctionWithBIMBufferSort.class, function);
+        break;
+      case NONE:
+        assertEquals(AppendWriteFunction.class, function.getClass());
+        break;
+      default:
+        throw new AssertionError("Unexpected buffer type " + bufferType);
+    }
+  }
+
+  @ParameterizedTest
+  @EnumSource(value = BufferType.class, names = {"CONTINUOUS_SORT", 
"DISRUPTOR", "BOUNDED_IN_MEMORY"})
+  public void testBufferedAppendFunctionsWriteAndFlushOnCheckpoint(BufferType 
bufferType) throws Exception {
+    Configuration writeConf = 
TestConfigurations.getDefaultConf(tempFile.getAbsolutePath());
+    writeConf.set(FlinkOptions.OPERATION, "insert");
+    writeConf.set(FlinkOptions.METADATA_ENABLED, false);
+    writeConf.set(FlinkOptions.WRITE_BUFFER_TYPE, bufferType.name());
+    writeConf.set(FlinkOptions.WRITE_BUFFER_SORT_KEYS, "name,age");
+    writeConf.set(FlinkOptions.WRITE_BUFFER_SIZE, 3L);
+    if (bufferType == BufferType.CONTINUOUS_SORT) {
+      writeConf.set(FlinkOptions.WRITE_BUFFER_SORT_CONTINUOUS_DRAIN_SIZE, 1);
+    } else if (bufferType == BufferType.DISRUPTOR) {
+      writeConf.set(FlinkOptions.WRITE_BUFFER_DISRUPTOR_RING_SIZE, 16);
+    }
+
+    TestWriteBase.TestHarness harness = TestWriteBase.TestHarness.instance()
+        .preparePipeline(tempFile, writeConf);
+    try {
+      harness
+          .consume(TestData.DATA_SET_INSERT)
+          .checkpoint(1)
+          .assertNextEvent(4, "par1,par2,par3,par4")
+          .checkpointComplete(1);
+    } finally {
+      harness.end();
+    }
+  }
+
+  @ParameterizedTest
+  @EnumSource(value = BufferType.class, names = {"CONTINUOUS_SORT", 
"DISRUPTOR", "BOUNDED_IN_MEMORY"})
+  public void testBufferedAppendFunctionsPersistRowsInSortOrder(BufferType 
bufferType) throws Exception {
+    Configuration writeConf = 
TestConfigurations.getDefaultConf(tempFile.getAbsolutePath());
+    writeConf.set(FlinkOptions.OPERATION, "insert");
+    writeConf.set(FlinkOptions.METADATA_ENABLED, false);
+    writeConf.set(FlinkOptions.WRITE_BUFFER_TYPE, bufferType.name());
+    writeConf.set(FlinkOptions.WRITE_BUFFER_SORT_KEYS, "name,age");
+    writeConf.set(FlinkOptions.WRITE_BUFFER_SIZE, 3L);
+    if (bufferType == BufferType.CONTINUOUS_SORT) {
+      writeConf.set(FlinkOptions.WRITE_BUFFER_SORT_CONTINUOUS_DRAIN_SIZE, 1);
+    } else if (bufferType == BufferType.DISRUPTOR) {
+      writeConf.set(FlinkOptions.WRITE_BUFFER_DISRUPTOR_RING_SIZE, 16);
+    }
+
+    List<RowData> inputData = Arrays.asList(
+        TestData.insertRow(StringData.fromString("uuid1"), 
StringData.fromString("Bob"), 30,
+            TimestampData.fromEpochMillis(1123), StringData.fromString("p1")),
+        TestData.insertRow(StringData.fromString("uuid2"), 
StringData.fromString("Alice"), 25,
+            TimestampData.fromEpochMillis(1124), StringData.fromString("p1")),
+        TestData.insertRow(StringData.fromString("uuid3"), 
StringData.fromString("Bob"), 21,
+            TimestampData.fromEpochMillis(31124), 
StringData.fromString("p1")));
+    List<String> expected = Arrays.asList(
+        "uuid2,Alice,25,1970-01-01 00:00:01.124,p1",
+        "uuid3,Bob,21,1970-01-01 00:00:31.124,p1",
+        "uuid1,Bob,30,1970-01-01 00:00:01.123,p1");
+
+    TestWriteBase.TestHarness harness = TestWriteBase.TestHarness.instance()
+        .preparePipeline(tempFile, writeConf);
+    try {
+      harness
+          .consume(inputData)
+          .checkpoint(1)
+          .assertNextEvent(1, "p1")
+          .checkpointComplete(1);
+
+      List<GenericRecord> persistedRows =
+          TestData.readAllData(new File(writeConf.get(FlinkOptions.PATH)), 
TestConfigurations.ROW_TYPE, 1);

Review Comment:
   🤖 nit: could you use `assertEquals(expected, actual)` directly instead of 
converting to arrays? It's more concise and JUnit's list diff in the failure 
message is easier to read than an array diff.
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



##########
hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/utils/InsertFunctionWrapper.java:
##########
@@ -209,9 +211,22 @@ public AbstractWriteFunction getWriteFunction() {
 
   @Override
   public void close() throws Exception {

Review Comment:
   🤖 nit: four levels of nested try-finally makes the teardown order hard to 
follow at a glance — have you considered collecting the closeables into a list 
and iterating, or using a small helper that closes each in sequence while 
suppressing earlier exceptions?
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



-- 
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]

Reply via email to