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

Jackie-Jiang pushed a commit to branch codex/surefire-3.6-native-suites
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to 
refs/heads/codex/surefire-3.6-native-suites by this push:
     new 207a0702152 Fix native TestNG discovery and shared suite ordering
207a0702152 is described below

commit 207a0702152d301f59a4556c46b5303bfd1d2a76
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Tue Sep 22 16:03:18 2026 -0700

    Fix native TestNG discovery and shared suite ordering
---
 .mvn/jvm.config                                    |  3 +-
 pinot-common/pom.xml                               | 36 +++++++++-------
 ...NGSuiteTest.java => NativeTestNGSuiteTest.java} | 47 +++++++++++++++++----
 .../pinot/common/utils/OrderedTestNGSuite.java     | 49 ++++++++++++++++++++++
 pinot-controller/pom.xml                           |  9 ++--
 pinot-integration-tests/pom.xml                    |  9 ++--
 .../integration/tests/suites/KinesisSuite.java     |  6 ++-
 .../tests/suites/MultiNodesOfflineSuite.java       |  2 +
 .../tests/suites/SharedHybridSuite.java            |  6 ++-
 .../tests/suites/SharedKafkaRealtimeSuite.java     |  6 ++-
 pinot-segment-local/pom.xml                        |  6 ---
 pom.xml                                            | 37 ++++++++--------
 12 files changed, 156 insertions(+), 60 deletions(-)

diff --git a/.mvn/jvm.config b/.mvn/jvm.config
index d71cbc89466..981650a9b82 100644
--- a/.mvn/jvm.config
+++ b/.mvn/jvm.config
@@ -1,3 +1,4 @@
+--add-opens=java.base/java.net=ALL-UNNAMED
 --add-opens=java.base/java.nio=ALL-UNNAMED
 --add-opens=java.base/sun.nio.ch=ALL-UNNAMED
 --add-opens=java.base/java.lang=ALL-UNNAMED
@@ -5,4 +6,4 @@
 --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
 --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
 -Dio.netty.tryReflectionSetAccessible=true
--Dio.grpc.netty.shaded.io.netty.tryReflectionSetAccessible=true
\ No newline at end of file
+-Dio.grpc.netty.shaded.io.netty.tryReflectionSetAccessible=true
diff --git a/pinot-common/pom.xml b/pinot-common/pom.xml
index dc112eab5fb..bcd233c5698 100644
--- a/pinot-common/pom.xml
+++ b/pinot-common/pom.xml
@@ -346,22 +346,6 @@
     </dependency>
 
     <!-- Test -->
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-suite</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-launcher</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.support</groupId>
-      <artifactId>testng-engine</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
@@ -382,6 +366,26 @@
       <artifactId>assertj-core</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.platform</groupId>
+      <artifactId>junit-platform-suite</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.platform</groupId>
+      <artifactId>junit-platform-launcher</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.support</groupId>
+      <artifactId>testng-engine</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <profiles>
     <profile>
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/TestNGSuiteTest.java 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/NativeTestNGSuiteTest.java
similarity index 79%
rename from 
pinot-common/src/test/java/org/apache/pinot/common/utils/TestNGSuiteTest.java
rename to 
pinot-common/src/test/java/org/apache/pinot/common/utils/NativeTestNGSuiteTest.java
index 8ae9dd0f78c..7e1b756fd4b 100644
--- 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/TestNGSuiteTest.java
+++ 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/NativeTestNGSuiteTest.java
@@ -44,7 +44,7 @@ import static org.testng.Assert.fail;
 
 /// Verifies the native JUnit Platform suites used to group TestNG tests 
without XML suite files.
 /// Not thread-safe: the fixtures share lifecycle events and must execute 
sequentially.
-public class TestNGSuiteTest {
+public class NativeTestNGSuiteTest {
   private static final List<String> EVENTS = new ArrayList<>();
 
   @BeforeEach
@@ -56,8 +56,16 @@ public class TestNGSuiteTest {
   public void testSharedLifecycleAndClassOrder() {
     TestExecutionSummary summary = execute(SharedSuite.class);
     assertEquals(summary.getTotalFailureCount(), 0L, 
summary.getFailures().toString());
-    assertEquals(summary.getTestsSucceededCount(), 2L);
-    assertEquals(EVENTS, List.of("start", "first", "second", "finish"));
+    assertEquals(summary.getTestsSucceededCount(), 4L);
+    assertEquals(EVENTS, List.of("start", "first", "second", "third", "last", 
"finish"));
+  }
+
+  @Test
+  public void testReversedClassOrder() {
+    TestExecutionSummary summary = execute(ReversedSuite.class);
+    assertEquals(summary.getTotalFailureCount(), 0L, 
summary.getFailures().toString());
+    assertEquals(summary.getTestsSucceededCount(), 4L);
+    assertEquals(EVENTS, List.of("start", "last", "third", "second", "first", 
"finish"));
   }
 
   @Test
@@ -103,8 +111,19 @@ public class TestNGSuiteTest {
   /// Stateless suite declaration that preserves the shared lifecycle and 
class order.
   @Suite
   @IncludeEngines("testng")
-  @SelectClasses({ZFirstFixture.class, ASecondFixture.class})
-  public static class SharedSuite {
+  @SelectClasses({ZFirstFixture.class, ASecondFixture.class, 
MThirdFixture.class, BLastFixture.class})
+  @ConfigurationParameter(key = "testng.listeners",
+      value = 
"org.apache.pinot.common.utils.NativeTestNGSuiteTest$SharedSuite")
+  public static class SharedSuite extends OrderedTestNGSuite {
+  }
+
+  /// Reverses the same four fixtures so incidental HashSet iteration cannot 
satisfy both order assertions.
+  @Suite
+  @IncludeEngines("testng")
+  @SelectClasses({BLastFixture.class, MThirdFixture.class, 
ASecondFixture.class, ZFirstFixture.class})
+  @ConfigurationParameter(key = "testng.listeners",
+      value = 
"org.apache.pinot.common.utils.NativeTestNGSuiteTest$ReversedSuite")
+  public static class ReversedSuite extends OrderedTestNGSuite {
   }
 
   /// Stateless suite declaration excluding the stateless group.
@@ -155,7 +174,6 @@ public class TestNGSuiteTest {
   public static class ZFirstFixture extends SharedFixture {
     @org.testng.annotations.Test
     public void first() {
-      assertEquals(EVENTS, List.of("start"));
       EVENTS.add("first");
     }
   }
@@ -164,11 +182,26 @@ public class TestNGSuiteTest {
   public static class ASecondFixture extends SharedFixture {
     @org.testng.annotations.Test
     public void second() {
-      assertEquals(EVENTS, List.of("start", "first"));
       EVENTS.add("second");
     }
   }
 
+  /// Sequential fixture verifying a third nonalphabetical class selection.
+  public static class MThirdFixture extends SharedFixture {
+    @org.testng.annotations.Test
+    public void third() {
+      EVENTS.add("third");
+    }
+  }
+
+  /// Sequential fixture that must execute last, like the Kafka shutdown 
scenario.
+  public static class BLastFixture extends SharedFixture {
+    @org.testng.annotations.Test
+    public void last() {
+      EVENTS.add("last");
+    }
+  }
+
   /// Sequential fixture with distinct groups and repeated parameterized 
invocations.
   public static class GroupedFixture extends SharedFixture {
     @org.testng.annotations.Test
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/OrderedTestNGSuite.java
 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/OrderedTestNGSuite.java
new file mode 100644
index 00000000000..517e6e2cc59
--- /dev/null
+++ 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/OrderedTestNGSuite.java
@@ -0,0 +1,49 @@
+/**
+ * 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.pinot.common.utils;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import org.junit.platform.suite.api.SelectClasses;
+import org.testng.IAlterSuiteListener;
+import org.testng.xml.XmlClass;
+import org.testng.xml.XmlSuite;
+import org.testng.xml.XmlTest;
+
+
+/// Restores the declared class order after the TestNG engine converts class 
selectors to method selectors.
+/// TestNG collects those methods' classes in a HashSet, so preserveOrder 
alone cannot retain the selection order.
+/// Stateless and thread-safe; register the concrete @SelectClasses suite as a 
testng.listeners parameter.
+public abstract class OrderedTestNGSuite implements IAlterSuiteListener {
+  @Override
+  public final void alter(List<XmlSuite> suites) {
+    List<Class<?>> classOrder = 
Arrays.asList(getClass().getAnnotation(SelectClasses.class).value());
+    for (XmlSuite suite : suites) {
+      for (XmlTest test : suite.getTests()) {
+        List<XmlClass> classes = test.getXmlClasses();
+        classes.sort(Comparator.comparingInt(xmlClass -> 
classOrder.indexOf(xmlClass.getSupportClass())));
+        for (int i = 0; i < classes.size(); i++) {
+          classes.get(i).setIndex(i);
+        }
+        test.setPreserveOrder(true);
+      }
+    }
+  }
+}
diff --git a/pinot-controller/pom.xml b/pinot-controller/pom.xml
index 4f389082697..63047319a25 100644
--- a/pinot-controller/pom.xml
+++ b/pinot-controller/pom.xml
@@ -36,10 +36,6 @@
     <npmRepositoryUrl>https://registry.npmjs.org/npm/-/</npmRepositoryUrl>
   </properties>
   <dependencies>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-suite</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.apache.pinot</groupId>
       <artifactId>pinot-materialized-view</artifactId>
@@ -112,6 +108,11 @@
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.junit.platform</groupId>
+      <artifactId>junit-platform-suite</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <resources>
diff --git a/pinot-integration-tests/pom.xml b/pinot-integration-tests/pom.xml
index 9e2e2ff2125..bdfb27f58cc 100644
--- a/pinot-integration-tests/pom.xml
+++ b/pinot-integration-tests/pom.xml
@@ -532,10 +532,6 @@
   </profiles>
 
   <dependencies>
-    <dependency>
-      <groupId>org.junit.platform</groupId>
-      <artifactId>junit-platform-suite</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.apache.pinot</groupId>
       <artifactId>pinot-tools</artifactId>
@@ -705,5 +701,10 @@
       <artifactId>pinot-batch-ingestion-spark-3</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.junit.platform</groupId>
+      <artifactId>junit-platform-suite</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/KinesisSuite.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/KinesisSuite.java
index 3a97d7b00e8..17d4b843d93 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/KinesisSuite.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/KinesisSuite.java
@@ -18,8 +18,10 @@
  */
 package org.apache.pinot.integration.tests.suites;
 
+import org.apache.pinot.common.utils.OrderedTestNGSuite;
 import 
org.apache.pinot.integration.tests.realtime.ingestion.KinesisShardChangeTest;
 import 
org.apache.pinot.integration.tests.realtime.ingestion.RealtimeKinesisIntegrationTest;
+import org.junit.platform.suite.api.ConfigurationParameter;
 import org.junit.platform.suite.api.IncludeEngines;
 import org.junit.platform.suite.api.SelectClasses;
 import org.junit.platform.suite.api.Suite;
@@ -29,9 +31,11 @@ import org.junit.platform.suite.api.Suite;
 /// Stateless suite definition; the selected tests run sequentially in one 
fork.
 @Suite
 @IncludeEngines("testng")
+@ConfigurationParameter(key = "testng.listeners",
+    value = "org.apache.pinot.integration.tests.suites.KinesisSuite")
 @SelectClasses({
     RealtimeKinesisIntegrationTest.class,
     KinesisShardChangeTest.class
 })
-public class KinesisSuite {
+public class KinesisSuite extends OrderedTestNGSuite {
 }
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/MultiNodesOfflineSuite.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/MultiNodesOfflineSuite.java
index 36dff07553c..9e86c46eaa9 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/MultiNodesOfflineSuite.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/MultiNodesOfflineSuite.java
@@ -19,6 +19,7 @@
 package org.apache.pinot.integration.tests.suites;
 
 import 
org.apache.pinot.integration.tests.MultiNodesOfflineClusterIntegrationTest;
+import org.junit.platform.suite.api.ConfigurationParameter;
 import org.junit.platform.suite.api.IncludeEngines;
 import org.junit.platform.suite.api.SelectMethod;
 import org.junit.platform.suite.api.Suite;
@@ -28,6 +29,7 @@ import org.junit.platform.suite.api.Suite;
 /// Stateless suite definition; the selected tests run sequentially in one 
fork.
 @Suite
 @IncludeEngines("testng")
+@ConfigurationParameter(key = "testng.preserveOrder", value = "true")
 @SelectMethod(type = MultiNodesOfflineClusterIntegrationTest.class, name = 
"testUpdateBrokerResource")
 @SelectMethod(type = MultiNodesOfflineClusterIntegrationTest.class, name = 
"testServerHardFailure")
 @SelectMethod(type = MultiNodesOfflineClusterIntegrationTest.class, name = 
"testServerReturnFinalResult")
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedHybridSuite.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedHybridSuite.java
index 78391bc8980..60e5ae9f011 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedHybridSuite.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedHybridSuite.java
@@ -18,9 +18,11 @@
  */
 package org.apache.pinot.integration.tests.suites;
 
+import org.apache.pinot.common.utils.OrderedTestNGSuite;
 import 
org.apache.pinot.integration.tests.DateTimeFieldSpecHybridClusterIntegrationTest;
 import org.apache.pinot.integration.tests.HybridClusterIntegrationTest;
 import org.apache.pinot.integration.tests.IngestionConfigHybridIntegrationTest;
+import org.junit.platform.suite.api.ConfigurationParameter;
 import org.junit.platform.suite.api.IncludeEngines;
 import org.junit.platform.suite.api.SelectClasses;
 import org.junit.platform.suite.api.Suite;
@@ -30,10 +32,12 @@ import org.junit.platform.suite.api.Suite;
 /// Stateless suite definition; the selected tests run sequentially in one 
fork.
 @Suite
 @IncludeEngines("testng")
+@ConfigurationParameter(key = "testng.listeners",
+    value = "org.apache.pinot.integration.tests.suites.SharedHybridSuite")
 @SelectClasses({
     HybridClusterIntegrationTest.class,
     DateTimeFieldSpecHybridClusterIntegrationTest.class,
     IngestionConfigHybridIntegrationTest.class
 })
-public class SharedHybridSuite {
+public class SharedHybridSuite extends OrderedTestNGSuite {
 }
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedKafkaRealtimeSuite.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedKafkaRealtimeSuite.java
index fbadc604744..b0d4a8da063 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedKafkaRealtimeSuite.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/suites/SharedKafkaRealtimeSuite.java
@@ -18,10 +18,12 @@
  */
 package org.apache.pinot.integration.tests.suites;
 
+import org.apache.pinot.common.utils.OrderedTestNGSuite;
 import 
org.apache.pinot.integration.tests.ExactlyOnceKafkaRealtimeClusterIntegrationTest;
 import 
org.apache.pinot.integration.tests.KafkaConfluentSchemaRegistryAvroMessageDecoderRealtimeClusterIntegrationTest;
 import 
org.apache.pinot.integration.tests.KafkaConsumingSegmentToBeMovedSummaryIntegrationTest;
 import org.apache.pinot.integration.tests.LLCRealtimeClusterIntegrationTest;
+import org.junit.platform.suite.api.ConfigurationParameter;
 import org.junit.platform.suite.api.IncludeEngines;
 import org.junit.platform.suite.api.SelectClasses;
 import org.junit.platform.suite.api.Suite;
@@ -31,11 +33,13 @@ import org.junit.platform.suite.api.Suite;
 /// Stateless suite definition; the selected tests run sequentially in one 
fork.
 @Suite
 @IncludeEngines("testng")
+@ConfigurationParameter(key = "testng.listeners",
+    value = 
"org.apache.pinot.integration.tests.suites.SharedKafkaRealtimeSuite")
 @SelectClasses({
     LLCRealtimeClusterIntegrationTest.class,
     ExactlyOnceKafkaRealtimeClusterIntegrationTest.class,
     
KafkaConfluentSchemaRegistryAvroMessageDecoderRealtimeClusterIntegrationTest.class,
     KafkaConsumingSegmentToBeMovedSummaryIntegrationTest.class
 })
-public class SharedKafkaRealtimeSuite {
+public class SharedKafkaRealtimeSuite extends OrderedTestNGSuite {
 }
diff --git a/pinot-segment-local/pom.xml b/pinot-segment-local/pom.xml
index 85109fd8059..ac18a6da9bf 100644
--- a/pinot-segment-local/pom.xml
+++ b/pinot-segment-local/pom.xml
@@ -35,12 +35,6 @@
   </properties>
 
   <dependencies>
-    <!-- Required when javac reads zstd-jni's annotated signatures for 
deprecation diagnostics. -->
-    <dependency>
-      <groupId>org.jetbrains</groupId>
-      <artifactId>annotations</artifactId>
-      <scope>provided</scope>
-    </dependency>
     <dependency>
       <groupId>org.apache.pinot</groupId>
       <artifactId>pinot-common</artifactId>
diff --git a/pom.xml b/pom.xml
index 57d3bc1944f..a7421672e67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2042,25 +2042,6 @@
         <scope>test</scope>
       </dependency>
 
-      <dependency>
-        <groupId>org.junit.platform</groupId>
-        <artifactId>junit-platform-suite</artifactId>
-        <version>${junit-platform.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.junit.platform</groupId>
-        <artifactId>junit-platform-launcher</artifactId>
-        <version>${junit-platform.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.junit.support</groupId>
-        <artifactId>testng-engine</artifactId>
-        <version>${testng-engine.version}</version>
-        <scope>test</scope>
-      </dependency>
-
       <!-- mockito bom -->
       <dependency>
         <groupId>org.mockito</groupId>
@@ -2113,6 +2094,24 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-suite</artifactId>
+        <version>${junit-platform.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-launcher</artifactId>
+        <version>${junit-platform.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.support</groupId>
+        <artifactId>testng-engine</artifactId>
+        <version>${testng-engine.version}</version>
+        <scope>test</scope>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to