-
Notifications
You must be signed in to change notification settings - Fork 79
Allow the test classes directory to be configured for the NativeTestMojo #757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
<skip>false</skip> | ||
<imageName>${imageName}</imageName> | ||
<fallback>false</fallback> | ||
<testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if we can go without an extra parameter. How does the surefire
plugin know the test-classes path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surefire and Failsafe both assume that the tests are in the default locations. But both have an optional <testClassesDirectory>
configuration element that allows you to set a different location. In our case we have test modules where that only contain tests and the source is all under src/main/java
and gets compiled to target/classes
so we have to tell Surefire and Failsafe to use these directories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alvarosanchez @melix do you think we can extract this information from Surefire in our plugin, so we don't have to duplicate this entry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vjovanov Now I have had another look at how your plugin works you could indeed extract the value from the Surefire or Failsafe plugins. The problem here though is how you are doing this now for the system properties and environment variables does not always work. The current code assumes these things are in the <configuration>
section of the plugin XML, but that is not always the case. In our projects for example for plugins we use the <executions>
section to configure what the plugin does and inside an <execution>
is the <configuration>
for that execution (which I believe is combined with any global <configuration>
). The issue here though is working out which execution
you need to use because there could be multiple. Your plugin would need to know the phase that was being executed so that it could work out the right execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it might not be as hard as I thought. For Surefire you just need to find the <execution>
bound to the test
goal, and for Failsafe the <execution>
bound to the integration-test
and verfiy
goals.
I'm happy to try this out in my branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks okay to me (with few questions that I left). I will wait for @alvarosanchez or @melix approval because I don't know if this is potentially against some Maven policies or conventions (other than that, this looks like a reasonable feature).
</build> | ||
</profile> | ||
<profile> | ||
<id>shaded</id> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I missing something or this profile is not used in any test? If so, we should delete it.
</build> | ||
</profile> | ||
<profile> | ||
<id>test-variables</id> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is this profile ever used (same question for the profile below)?
@Override | ||
protected void populateApplicationClasspath() throws MojoExecutionException { | ||
super.populateApplicationClasspath(); | ||
imageClasspath.add(Paths.get(project.getBuild().getTestOutputDirectory())); | ||
imageClasspath.add(testClassesDirectory.toPath()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is not a default location, should we print some "warning" where the tests come from (if the location is not default)? Maybe with logger.debug
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could log it but the Surefire plugin does not specifically log config settings (Surefire is basically the functionality you are copying). If you run a Maven build with debug (i.e. -X
) then it logs all the plugin configs before they execute anyway.
I have been doing some more work on this based on @vjovanov comment about getting the test classes directory from the Surefire plugin. The way this plugin works currently, it merges in the system properties and environment variables from both the surefire and failsafe plugins if they are configured in the project. So it sounds like it should be simple to also pull in the test classes directory from those plugins but it starts to become a can of worms. If my pom.xml only contained is a simple surefire config like the one below then it is easy.
But we use executions in plugin configs like below, which your plugin does not support
I do not think this is too big an issue, you just need to search through any executions defined for the Surefire plugin to find the one with the The complications start when we have use both Surefire and Failsafe. As I said above, the plugin is currently merging system properties and environment variables from both Surefire and Failsafe and this might not be correct. Typically Surefire is for unit tests that execute all in a single JVM, which is how the native test plugin runs tests. Failsafe is typically used for integration tests where each test class runs in a forked JVM so tests are more isolated. I could have a pom.xml file like this:
Both Surefire and Failsafe set a value for the It would be reasonably simple if a mojo knew which phase was executing when I believe the way to fix this is to have two native test mojos, the current The bulk of the code would remain in the I had a go at writing the code for this, but I did not want to do too much in case there are big objections to it. |
OK, so maybe I shouldn't believe everything said on the web before looking at all the Maven code. You can determine things like the goal and phase in a mojo. One |
…Surefire or Failsafe depending on the goal being executed.
I have pushed new commits to this PR to fix the following issues.
With the current code in this PR it looks like the native plugin can now be used to run both unit and integration tests using both Surefire and Failsafe. Which is how I would think most project use these plugins. Even with these fixes though, we could not run integration tests in our project because we rely on Failsafe fork mode where every test class runs in a fork. I can see no way the native plugin can do this as it just uses Unit to run the tests and Unit does not support forks. You would end up duplicating a lot of what Falsafe/Surefire do to support forks, which is a massive job, or somehow being able to extend the functionality of Surefire/Failsafe so that when they execute a fork, they actually run a native image. Either way a big amount of work. |
</execution> | ||
</executions> | ||
<configuration> | ||
<buildArgs> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these two needed for the testing now that all is working? These are the flags to use for easier debugging.
@Override | ||
protected void populateApplicationClasspath() throws MojoExecutionException { | ||
super.populateApplicationClasspath(); | ||
imageClasspath.add(Paths.get(project.getBuild().getTestOutputDirectory())); | ||
imageClasspath.add(Path.of(testClassesDirectory)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@melix are we handling this case in Gradle properly, i.e. the testClassesDirs
?
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>3.0.0-M5</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use 3.5.3
consistently?
native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java
Outdated
Show resolved
Hide resolved
native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java
Outdated
Show resolved
Hide resolved
defaultPhase = LifecyclePhase.INTEGRATION_TEST, threadSafe = true, | ||
requiresDependencyResolution = ResolutionScope.TEST, | ||
requiresDependencyCollection = ResolutionScope.TEST) | ||
public class NativeIntegrationTestMojo extends NativeTestMojo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dnestoro do we need to document this? Also, could we execute only native integration tests (once the JUnit issues are fixed)? What would be the command for that?
Looks great from my side. Thank you very much for the contribution! Most of the remaining questions are now on the NBT reviewers to discuss and answer. |
…lways have a PluginExecution
Another commit to clean up some unused code paths. After a bit of testing I discovered that the |
One other thing to be aware of. When using the native plugin to execute tests it must run after the Surefire or Failsafe plugin otherwise the test id files do not exist and the build fails. I'm not sure whether this is in the doc or not and maybe it goes away if you sort out the double test execution thing anyway. The native plugin is typically bound to the same phase as the Surefire or Failsafe plugin, i.e. |
Ouch. Maybe we can handle this with a proper error message and documentation. @dnestoro @alvarosanchez can we do this to make it easier for the users? |
The
NativeTestMojo
hard codes the location of the test classes to be theproject.build.testOutputDirectory
. Some Maven projects have test classes in other locations, for example undersrc/main/java
which compiles them to theproject.build.outputDirectory
.This PR allows the test classes location to be configured for the
NativeTestMojo
in the same way that plugins such as Surefire and Failsafe do by setting the<testClassesDirectory>
element in the plugin configuration. The default is theproject.build.testOutputDirectory
.