Skip to content

Stream live test-progress from forked test JVMs to the mvnd client (mvnd-1.x)#1670

Open
ammachado wants to merge 7 commits into
apache:mvnd-1.xfrom
ammachado:feature/test-progress-feed-1x
Open

Stream live test-progress from forked test JVMs to the mvnd client (mvnd-1.x)#1670
ammachado wants to merge 7 commits into
apache:mvnd-1.xfrom
ammachado:feature/test-progress-feed-1x

Conversation

@ammachado

Copy link
Copy Markdown

Important

This PR is stacked on top of #1666 (feature/worker-line-display-1x). It should be reviewed and merged after #1666. Until #1666 merges, the diff here includes its commits as ancestors; the base will effectively rebase onto mvnd-1.x once #1666 lands.

What this adds

The test-progress feed for mvnd 1.x: a bridge that streams live JUnit/Surefire test progress from forked test JVMs back to the daemon and out to the client. This is the data source that PR #1666's worker-line suffix renders.

Highlights

  • -Dmvnd.testProgress flag (Environment) to opt into the feature, wired into bash completion.
  • mvnd-surefire-progress module providing a custom Surefire ForkNodeFactory (MvndForkNodeFactory) plus a TestProgressAccumulator that tallies per-fork test events.
  • Daemon-side wiring: MvndTestProgressLifecycleParticipant injects the fork-node factory into the Surefire mojo configuration, and the daemon dispatches accumulated progress to the client (ClientDispatcher, Server).
  • Plugin-realm fix: InvalidatingPluginRealmCache loads MvndForkNodeFactory in the Surefire plugin realm so the class resolves at fork time.
  • Integration test (TestProgressTest) driving a sample project end to end.

Files

21 files changed, ~1000 insertions across the common module, daemon, surefire-progress module, distribution, and integration tests.

🤖 Generated with Claude Code

ammachado and others added 7 commits July 3, 2026 00:44
…fix on mvnd-1.x

Reshape the live terminal display: a drawn progress bar with percent on the
status line, concise arrow-style worker lines (> :module goal (execution)),
and dimmed > IDLE slots for free threads. At addProjectLine, append a styled
live test-progress suffix (tests/failures/errors/skipped counts plus the
current test class#method) driven by the new PROJECT_TEST_PROGRESS message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the mvnd.testProgress opt-out flag (default on) and the
cross-realm MvndTestProgress bridge interface + static listener
registry that connects the Surefire plugin realm to the daemon realm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
New module contributing the Surefire plugin-realm pieces of the live
test-progress feed:
- TestProgressAccumulator: pure per-fork counter (unit-tested)
- MvndForkNodeFactory: decorates Surefire's EventHandler<Event>,
  accumulates counts, pushes through the MvndTestProgress bridge, and
  always delegates to the real handler (never breaks the test run)
- MvndSurefireProgressLocator: zero-dependency marker the daemon uses to
  locate this jar for plugin-realm injection

Verified compiling and testing against the real Surefire 3.5.x extensions SPI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
Adds ClientDispatcher.testProgress to enqueue PROJECT_TEST_PROGRESS
messages, and wires Server.handle to register an MvndTestProgress
listener (per build, when mvnd.testProgress is enabled) that forwards
fork events to the dispatcher; the listener is cleared in finally.
Also adds the daemon dependency on mvnd-surefire-progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
Wires the Maven 3.9 test-progress feed:
- DaemonMavenCli: export org.mvndaemon.mvnd.testprogress to the core realm
  so the bridge Class is shared with the surefire plugin realm
- MvndTestProgressLifecycleParticipant: afterProjectsRead injects
  <forkNode implementation=MvndForkNodeFactory><projectId>..> into
  surefire/failsafe config (the Maven 3.9-native mechanism)
- InvalidatingPluginRealmCache: addURL the mvnd-surefire-progress jar onto
  the surefire/failsafe plugin realm
- dist: bundle mvnd-surefire-progress; daemon: plexus-xml provided (Xpp3Dom)
- integration-tests: TestProgressTest + test-progress JUnit 5 project

Runtime validation of the mandatory 1.x spike (PROJECT_TEST_PROGRESS emitted
end-to-end) follows in a later commit. Running the integration tests requires
a full dist build first, since the harness spawns a real daemon against
dist/target/maven-mvnd-*.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
The 1.x spike (TestProgressTest) exposed a classloader bug that broke
every project running Surefire (e.g. UpgradesInBomTest, ExecOutputTest):

  Cannot load implementation hint MvndForkNodeFactory:
  NoClassDefFoundError: SurefireForkNodeFactory

Root cause: the factory lived under org.mvndaemon.mvnd.testprogress, the
package exported to the core realm for the shared MvndTestProgress bridge.
ClassWorlds package imports are hierarchical (prefix-based), so the export
also captured the factory's (sub)package; the surefire plugin realm
imported it from the core realm, which has no Surefire, so linking the
factory's SurefireForkNodeFactory superclass failed.

Fix:
- Move MvndForkNodeFactory / TestProgressAccumulator / locator to a sibling
  package org.mvndaemon.mvnd.forknode that is NOT under the exported prefix,
  so the plugin realm loads the factory from its own (addURL'd) jar and
  links against the plugin realm's Surefire. Bridge stays in the exported
  org.mvndaemon.mvnd.testprogress.
- Guard injection on Surefire >= 3.0.0-M5 (forkNode SPI floor) so older
  Surefire/Failsafe are never touched. Add supportsForkNode unit test.

Validated end-to-end on mvnd-1.x: TestProgressTest emits increasing
PROJECT_TEST_PROGRESS with correct class/counts, the opt-out emits none,
and ExecOutputTest / UpgradesInBomTest (Surefire 3.0.0-M8) pass unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
Regenerated completion list to include the new mvnd.testProgress property.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZU9mLBgwG78z2WeAi4z47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant