ci: run the integration tests through failsafe and verify the shaded jar - #67
Open
LuciferYang wants to merge 5 commits into
Open
ci: run the integration tests through failsafe and verify the shaded jar#67LuciferYang wants to merge 5 commits into
LuciferYang wants to merge 5 commits into
Conversation
Contributor
Author
|
cc @fightBoxing |
LuciferYang
marked this pull request as draft
August 14, 2026 03:30
LuciferYang
marked this pull request as ready for review
August 14, 2026 03:45
LuciferYang
marked this pull request as draft
August 14, 2026 03:45
The three existing *ITCase classes had never run: no failsafe plugin was configured, and the names do not match surefire's default includes. Wire failsafe in and split the workflow so the unit-test matrix skips ITs while a narrower matrix runs them. failsafe has to target target/classes. shade replaces the main artifact at package time with a jar in which org.apache.arrow is relocated, and the tests are compiled against the plain Arrow packages, so running against the main artifact fails with NoSuchMethodError. That leaves the shaded jar itself unverified, hence LanceShadedJarITCase, which loads the jar in its own classloader and asserts the relocation held.
Three ways a green build could stop proving the integration tests ran: - Listing an <includes> pattern replaces failsafe's whole default set, and failIfNoTests defaults to false, so a pattern matching nothing exits 0. Restate the defaults and turn failIfNoTests on. The root aggregator has no test classes of its own, so failsafe now hangs off the three jar modules rather than the parent, which also stops it leaving a stray report dir there. - The shaded-jar check probed one class name. A per-package relocation carve-out (the usual fix when a JNI package breaks on being moved) leaves plain Arrow in the jar while that one class still resolves. Walk every jar entry instead. Verified: adding <exclude>org.apache.arrow.memory.**</exclude> to the relocation turns this red, where the single-class probe stayed green. - A missing jar was an assumeTrue, so it skipped. shade runs at package, before this phase, so if the build handed us the path the jar should be there. Assert.
LanceTimeTravelITCase (added by lance-format#56) writes real Arrow vectors, which reaches java.nio.Buffer.address by reflection. JDK 17 blocks that, so MemoryUtil's static initializer throws and three of its four cases error out with NoClassDefFoundError. JDK 11 only prints an illegal-reflective-access warning, which is why nothing noticed until failsafe started running *ITCase at all. Arrow's own poms carry the same add-opens for their test runs. Setting argLine as a property rather than inside surefire's config keeps jacoco working: prepare-agent appends its -javaagent to argLine instead of replacing it.
A separate IT job pays for a full build to buy 5 seconds of coverage. The unit-matrix job already compiles the reactor and shades the fat jar; -DskipITs only skips failsafe itself, which the CI log timestamps at 4.7s of an 86s job. So the two job types did the same work and diverged only at the end, and the duplication would grow with every unit test added. Dropping the split also widens IT coverage from 1.18/1.19/1.20 on JDK 17 to all eight Flink x JDK combinations, and the JDK axis is not idle here: the MemoryUtil add-opens failure this branch fixes reproduces on 17+ and only warns on 11.
The rest of the tree comments in English, including the Java files merged most recently. Also replaces an em dash in the LanceShadedJarITCase javadoc so the file stays ASCII.
LuciferYang
force-pushed
the
ci/failsafe-integration-tests
branch
from
August 17, 2026 17:13
f69d66f to
e5d0330
Compare
LuciferYang
marked this pull request as ready for review
August 18, 2026 00:03
Contributor
Author
|
cc @fightBoxing |
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.
What this does
The repo has five
*ITCaseclasses and none of them had ever run. There is nomaven-failsafe-pluginin the build, and*ITCasedoes not match surefire's default includes (*Test,*Tests,*TestCase), somvn verifywalked straight past them. #55 listed this as a follow-up; this is it.Four changes:
maven-failsafe-plugininto the three jar modules soverifyruns the ITs.LanceShadedJarITCase, for the reason in the next section.argLineso Arrow can allocate off-heap on JDK 17+, which is what turning the ITs on immediately exposed.mvncommand does not change:verifynow covers the ITs, so the existing 8-job matrix picks them up as it stands.Why failsafe has to target
target/classesmaven-shade-pluginrelocatesorg.apache.arrowtoorg.apache.flink.connector.lance.shaded.arrowatpackage, replacing the main artifact. failsafe defaults to that main artifact. The tests compile against plain Arrow, so running them against the shaded jar fails withNoSuchMethodError: the signatures moved.Hence
<classesDirectory>${project.build.outputDirectory}</classesDirectory>. The cost is that the shaded jar, which is what users actually deploy, then has no automated check at all. That is whatLanceShadedJarITCasecovers: it loads the jar in its own classloader and asserts that no plain-Arrow class is bundled, and that the connector's public signatures reference the relocated packages.Guarding against silent no-ops
Three ways a green build could have stopped proving the ITs ran, all closed here:
<includes>pattern replaces failsafe's whole default set, andfailIfNoTestsdefaults to false, so a pattern matching nothing exits 0. The defaults are restated andfailIfNoTestsis on.assumeTrue, so it skipped. shade runs atpackage, before this phase, so if the build handed us a path the jar should be there. It asserts now.failsafe hangs off the three jar modules rather than the root aggregator, since the root has no test classes of its own and
failIfNoTests=truewould fail it there.Why one matrix rather than separate IT jobs
Giving the ITs their own jobs is the obvious shape and it does not pay off here, because a job in the existing matrix already does everything the ITs need. Here is a
-DskipITsjob,Flink 1.18 / JDK 17, by phase:-DskipITsskips failsafe and nothing else. The reactor compile and the shade run either way, and failsafe's own 44 tests take 4.7 seconds. So a dedicated IT job would pay for a second full build to buy 4.7 seconds of coverage, and the overlap would grow with every unit test added.Keeping them in the existing matrix also widens IT coverage from one JDK to all eight Flink x JDK combinations. The JDK axis is not idle for ITs: the
MemoryUtilfailure below reproduces on 17+ and only warns on 11. The eight jobs on this branch run 57 to 77 seconds each.Test plan
mvn -am -pl lance-flink-<v> verifywas run locally for every Flink x JDK pair the matrix covers, and all eight report 44 ITs and 186 unit tests:44 =
LanceSqlITCase20 +LanceConnectorITCase15 +LanceTimeTravelITCase4 +LanceNamespaceCatalogITCase3 +LanceShadedJarITCase2. One of the time-travel cases is an opt-in export gated on$TT_EXPORT_DIRand reports as skipped, so a green run showsSkipped: 1.-DskipITsstill works for a local unit-only run, verified on 1.18/JDK 17 and 1.20/JDK 21.Both new checks were reverse-verified by breaking what they watch:
<relocations>andLanceShadedJarITCasegoes red (1 failure, 1 error).<exclude>org.apache.arrow.memory.**</exclude>to the relocation and the jar-walk assertion fails, listing the leakedorg/apache/arrow/memory/*.classentries. The single-class probe stayed green on this one, which is why it was replaced.-Dfailsafe.includesat a pattern matching nothing and the build fails, where beforefailIfNoTestsit exited 0.What the ITs found
LanceTimeTravelITCase, which came in with #56, errored on three of its four cases as soon as failsafe started running it:It writes real Arrow vectors, and Arrow reaches
java.nio.Buffer.addressby reflection. JDK 17 blocks that outright, soMemoryUtil's static initializer throws and the tests fail withNoClassDefFoundError. JDK 11 only prints an illegal-reflective-access warning, which is part of why this went unnoticed: nothing was running the class on any JDK.Fixed by setting
argLineas a root property. Arrow's own poms carry the same flag for their test runs. Keeping it a property rather than putting it inside surefire's<configuration>is what keeps jacoco working, sinceprepare-agentappends its-javaagenttoargLineinstead of replacing it. The build log confirms both survive: