Run tests on the JUnit Platform (TestNG + Jupiter engines)#18781
Open
gortiz wants to merge 1 commit into
Open
Conversation
Move the test build onto the JUnit Platform so new JUnit 5 (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), add testng-engine, junit-jupiter and junit-platform-launcher as inherited test dependencies, and drop the surefire-testng provider so Surefire auto-selects the junit-platform provider. The launcher is on the test classpath so it stays version-aligned with the engines in the forked JVM. - 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 (TestNG groups map to platform tags). Use reuseForks=true on the controller executions to keep the shared-cluster setup that the single-JVM suites relied on; remove the now-dead ControllerTestSetup (@BeforeGroups/@AfterGroups, no @test). - Add a Jupiter example test (BooleanUtilsTest) and docs/junit5-migration.md.
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% 100.00% +35.32%
+ Complexity 1309 6 -1303
==============================================
Files 3381 3 -3378
Lines 209821 6 -209815
Branches 32805 0 -32805
==============================================
- Hits 135697 6 -135691
+ Misses 63230 0 -63230
+ Partials 10894 0 -10894
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:
|
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), addtestng-engine,junit-jupiter, andjunit-platform-launcheras inherited test dependencies, and drop thesurefire-testngprovider so Surefire auto-selects itsjunit-platformprovider. Thelauncher is on the test classpath so it stays version-aligned with the engines in the
forked 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.