Hi folks,

I'm the maintainer of the GraalVM native build tools plugins for Maven and
Gradle. In the next release, we're moving to JUnit Platform 5.8, which now
integrates a "unique test id tracker", which before used to be implemented
in this plugin suite.

The goal of this ID tracker is to collect _unique_ test IDs for every test,
so that we can build a native image which would execute the same tests in
native mode. In other words, we first execute the tests in "JVM" mode,
using the surefire plugin, then there's a native image being built which
includes the tests and uses the information from the JVM execution to tell
which tests to execute in the native mode (that's because traditional test
discovery mechanisms don't work in a native executable).

Before JUnit 5.8, the listener which collects test ids used to live in the
"junit-platform-native" dependency, and because it did so, the sole fact of
adding this dependency was enough to trigger the listener. That was a
temporary solution until JUnit actually *bundles* this listener, and that's
where things get more complicated.

Starting with the 5.8 release, the listener is embedded into JUnit. This
means we can remove it from the "junit-platform-native" dependency [1].
However, it also means that there must be a way to opt-in, because most
users don't need this listener active. Therefore, JUnit requires the
"junit.platform.listeners.uid.tracking.enabled" system property to be set.

This means, in practice, that IF the native maven plugin is applied, THEN
the surefire mojo needs to be configured to set this property. It's an
implementation detail that users shouldn't have to worry about. For Gradle
this was trivial to implement because we can just react to the presence of
the native plugin and reconfigure the test task to add this system
property. For Maven, this proves quite challenging.

Currently, the only way I found is to have the user explicitly add this
system property to the surefire mojo:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M5</version>
    <configuration>
        <systemProperties>
            
<junit.platform.listeners.uid.tracking.enabled>true</junit.platform.listeners.uid.tracking.enabled>
        </systemProperties>
    </configuration>
</plugin>


This is certainly not nice, because as I said, the user shouldn't care:
because we apply the native plugin, we *know* that we need that listener.
Therefore I'm looking for ways to automatically alter the configuration of
the surefire plugin if the native plugin is applied. More importantly, this
is a breaking change since upgrading the plugin now requires a redundant
system property to be set.

I found that I could do this in the following situations:

- if my mojo runs _before_ the tests: this is not possible, since I need
the results of the test execution to get the list of tests
- using a lifecycle extension: it seems doable, but then I'm replacing one
problem with another: the user has to register the extension, either by
updating the POM file or adding it to their extensions. This, again, is a
no-go since we want this to be transparent.

Last but not least, I'm not mentioning that there's a 2d property which
would ideally need to be set too, which is the directory where those test
ids are dumped. By default it uses the target directory today, but this is
causing reliability issues, unless users do clean on every run. So it would
be great to be able to configure a *unique* directory per session. One
problem at a time, though.

All in all, is there any other way to do what I need that I'm missing?

Thanks for your help,

[1] https://github.com/graalvm/native-build-tools/issues/131

Reply via email to