Run tests on the JUnit Platform (TestNG + Jupiter engines)#18781
Open
gortiz wants to merge 1 commit into
Open
Conversation
68b6492 to
38c0a24
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #18781 +/- ##
============================================
+ Coverage 64.67% 64.78% +0.10%
Complexity 1309 1309
============================================
Files 3381 3380 -1
Lines 209821 209630 -191
Branches 32805 32822 +17
============================================
+ Hits 135697 135802 +105
+ Misses 63230 62896 -334
- Partials 10894 10932 +38
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Move the test build onto the JUnit Platform so new JUnit 5/6 (Jupiter) tests can be written while the existing ~10k TestNG tests keep running unchanged via the TestNG engine for the JUnit Platform (org.junit.support:testng-engine). - Import the JUnit BOM (unified 6.x) and manage testng-engine in the root dependencyManagement, and drop the surefire-testng provider so Surefire auto-selects the junit-platform provider. - Engines + launcher must be on each module's *test* classpath (the launcher there overrides Surefire's bundled, incompatible one). The root POM may not declare dependencies (enforced by the dependency-verifier rule), so each testng-declaring module/parent now also declares testng-engine and junit-platform-launcher next to org.testng:testng; pinot-spi additionally declares junit-jupiter for new Jupiter tests. - The engine instantiates test classes during discovery, which runs in the main Maven JVM; add --add-opens=java.base/java.net to .mvn/jvm.config (discovery) and the surefire argLine (execution) so PluginManager's URLClassLoader.addURL reflection keeps working. - The engine does not support testng.xml suite files. Replace the controller statefull/stateless split and the custom-cluster integration suite with JUnit Platform tag / include filters; reuseForks=true on the controller executions preserves the shared-cluster setup; remove the now-dead ControllerTestSetup. - Add a Jupiter example test (BooleanUtilsTest) and docs/junit-migration.md.
38c0a24 to
a611cee
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run Pinot's tests on the JUnit Platform (TestNG + Jupiter side by side)
TL;DR
This moves the test build onto the JUnit Platform so we can write new tests with the
modern JUnit Jupiter API (we pin JUnit 6) — without rewriting any of the ~10,000
existing TestNG tests. They keep running, unchanged, through the TestNG engine for the
JUnit Platform. New and old tests run together
in a single Surefire execution.
This is intentionally a foundation-only PR: build wiring + the two unavoidable
suite-file translations + one example test + a short guide. No bulk migration.
Why
TestNG has served us well, but Jupiter is where the ecosystem and tooling have moved. The
JUnit Platform is engine-pluggable — JUnit Vintage runs JUnit 4, Jupiter runs JUnit 5/6, and
the TestNG engine runs TestNG — so adopting it is a build change, not a test rewrite.
Once we're on the platform, a lot of capability we don't have today becomes available
incrementally, test-by-test, at each author's discretion:
@ExtendWith/RegisterExtensionmodelreplaces today's deep
ControllerTest → ClusterTest → BaseClusterIntegrationTestbase-classchains with composable behavior. Cross-cutting setup (clusters, ZK, leak detection) becomes
a reusable extension rather than something every test must inherit.
@Nestedinner classes with their own@BeforeEach/@AfterEach. Group related caseswith scoped, layered setup instead of one giant flat test class.
@AutoClose(and@TempDir) — fields are closedautomatically after the test, removing hand-written teardown and a class of leaks.
@ParameterizedTestwith@ValueSource,@CsvSource,@MethodSource,@EnumSource. A cleaner, less boilerplate-heavy replacementfor
@DataProvider(and great for exhaustive type/null-handling coverage, which we careabout a lot).
@TestFactory) — generate cases at runtime, e.g. one test perquery file, per segment format, or per discovered fixture.
junit-platform.propertiesparallelism (permethod/class, with
@Execution/@ResourceLockfor safety) gives a standard knob forspeeding up suites, instead of TestNG's bespoke config.
example Fray, a concurrency-testing /
deterministic-scheduling framework that hunts for races and deadlocks. Pinot has a lot of
concurrency-heavy code (upsert metadata, consumer coordination, Helix state); a JUnit
Platform integration for that kind of tooling would be valuable and is only practical once
we're on the platform.
Crucially, none of this is forced. Existing tests stay as TestNG and keep their
org.testng.Assertsemantics. We adopt the new capabilities where they pay off.What's in this PR
pom.xml— import the JUnit 6 BOM (unified versioning) and managetestng-engineindependencyManagement; drop thesurefire-testngprovider so Surefireauto-selects its
junit-platformprovider.test classpath (the launcher there overrides Surefire's bundled, older one; a plugin-
section launcher does not work). The root POM may not declare
<dependencies>(enforced byPinot's dependency-verifier rule), so every module/parent that declares
org.testng:testngnow also declares
testng-engine+junit-platform-launchernext to it (versions managedcentrally).
pinot-spiadditionally declaresjunit-jupiterfor new Jupiter tests.--add-opens=java.base/java.netin both.mvn/jvm.configand the surefire argLine —the engine instantiates test classes during discovery (which runs in the main Maven JVM),
so
PluginManager'sURLClassLoader.addURLreflection needsjava.netopened in the mainJVM as well as the forked test JVM.
pinot-controller/pinot-integration-tests— the TestNG engine does not supporttestng.xmlsuite files (the only two in the build). TestNG@Test(groups=...)are exposedto the platform as tags, so the controller stateful/stateless split becomes two
tag-filtered Surefire executions, and the custom-cluster integration suite becomes an
include glob. The controller executions use
reuseForks=trueto preserve the shared-clustersetup the single-JVM suites relied on (verified: the second stateful class reuses the
cluster, starting zero new controllers). The now-dead
ControllerTestSetup(
@BeforeGroups/@AfterGroups, no@Test) is removed.BooleanUtilsTest— a small, real Jupiter test (adds genuine coverage) demonstrating@ParameterizedTestandassertThrows, running in the same module as 685 TestNG tests toprove coexistence.
docs/junit-migration.md— conventions for new Jupiter tests and a TestNG→Jupitermapping table.
Verification
pinot-spi: 685 existing TestNG tests pass under the new provider; 698 with the newJupiter test — both engines run together in one execution.
pinot-controller: both tag-filtered executions fire; group→tag mapping confirmed; theshared-cluster optimization is preserved.
@Listeners(e.g.NettyTestNGListenerfor Netty leak detection) is honored by the engine.@{argLine}(provider-agnostic), andsurefire-reportreads the standardTEST-*.xmlthe platform also emits.dependencyConvergence, spotless, checkstyle, and license all pass.Compatibility / risk
testng-engine1.1.0 is CI-tested against JUnit 6,supports TestNG ≥ 6.14.3 (we use 7.12.0), and needs Surefire ≥ 3.5.2 (we use 3.5.4).
coverage artifacts upload exactly as before.